mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-11-14 03:50:26 +00:00
ed01820722
Currently fully support mattermost,slack and discord. Message deleted on the bridge or received from other bridges will be deleted. Partially support for Gitter. Gitter bridge will delete messages received from other bridges. But if you delete a message on gitter, this deletion will not be sent to other bridges (this is a gitter API limitation, it doesn't propogate edits or deletes via the API)
165 lines
4.1 KiB
Go
165 lines
4.1 KiB
Go
package bsteam
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/42wim/matterbridge/bridge/config"
|
|
"github.com/Philipp15b/go-steam"
|
|
"github.com/Philipp15b/go-steam/protocol/steamlang"
|
|
"github.com/Philipp15b/go-steam/steamid"
|
|
log "github.com/Sirupsen/logrus"
|
|
//"io/ioutil"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type Bsteam struct {
|
|
c *steam.Client
|
|
connected chan struct{}
|
|
Config *config.Protocol
|
|
Remote chan config.Message
|
|
Account string
|
|
userMap map[steamid.SteamId]string
|
|
sync.RWMutex
|
|
}
|
|
|
|
var flog *log.Entry
|
|
var protocol = "steam"
|
|
|
|
func init() {
|
|
flog = log.WithFields(log.Fields{"module": protocol})
|
|
}
|
|
|
|
func New(cfg config.Protocol, account string, c chan config.Message) *Bsteam {
|
|
b := &Bsteam{}
|
|
b.Config = &cfg
|
|
b.Remote = c
|
|
b.Account = account
|
|
b.userMap = make(map[steamid.SteamId]string)
|
|
b.connected = make(chan struct{})
|
|
return b
|
|
}
|
|
|
|
func (b *Bsteam) Connect() error {
|
|
flog.Info("Connecting")
|
|
b.c = steam.NewClient()
|
|
go b.handleEvents()
|
|
go b.c.Connect()
|
|
select {
|
|
case <-b.connected:
|
|
flog.Info("Connection succeeded")
|
|
case <-time.After(time.Second * 30):
|
|
return fmt.Errorf("connection timed out")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *Bsteam) Disconnect() error {
|
|
b.c.Disconnect()
|
|
return nil
|
|
|
|
}
|
|
|
|
func (b *Bsteam) JoinChannel(channel config.ChannelInfo) error {
|
|
id, err := steamid.NewId(channel.Name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
b.c.Social.JoinChat(id)
|
|
return nil
|
|
}
|
|
|
|
func (b *Bsteam) Send(msg config.Message) (string, error) {
|
|
// ignore delete messages
|
|
if msg.Event == config.EVENT_MSG_DELETE {
|
|
return "", nil
|
|
}
|
|
id, err := steamid.NewId(msg.Channel)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
b.c.Social.SendMessage(id, steamlang.EChatEntryType_ChatMsg, msg.Username+msg.Text)
|
|
return "", nil
|
|
}
|
|
|
|
func (b *Bsteam) getNick(id steamid.SteamId) string {
|
|
b.RLock()
|
|
defer b.RUnlock()
|
|
if name, ok := b.userMap[id]; ok {
|
|
return name
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
func (b *Bsteam) handleEvents() {
|
|
myLoginInfo := new(steam.LogOnDetails)
|
|
myLoginInfo.Username = b.Config.Login
|
|
myLoginInfo.Password = b.Config.Password
|
|
myLoginInfo.AuthCode = b.Config.AuthCode
|
|
// Attempt to read existing auth hash to avoid steam guard.
|
|
// Maybe works
|
|
//myLoginInfo.SentryFileHash, _ = ioutil.ReadFile("sentry")
|
|
for event := range b.c.Events() {
|
|
//flog.Info(event)
|
|
switch e := event.(type) {
|
|
case *steam.ChatMsgEvent:
|
|
flog.Debugf("Receiving ChatMsgEvent: %#v", e)
|
|
flog.Debugf("Sending message from %s on %s to gateway", b.getNick(e.ChatterId), b.Account)
|
|
// for some reason we have to remove 0x18000000000000
|
|
channel := int64(e.ChatRoomId) - 0x18000000000000
|
|
msg := config.Message{Username: b.getNick(e.ChatterId), Text: e.Message, Channel: strconv.FormatInt(channel, 10), Account: b.Account, UserID: strconv.FormatInt(int64(e.ChatterId), 10)}
|
|
b.Remote <- msg
|
|
case *steam.PersonaStateEvent:
|
|
flog.Debugf("PersonaStateEvent: %#v\n", e)
|
|
b.Lock()
|
|
b.userMap[e.FriendId] = e.Name
|
|
b.Unlock()
|
|
case *steam.ConnectedEvent:
|
|
b.c.Auth.LogOn(myLoginInfo)
|
|
case *steam.MachineAuthUpdateEvent:
|
|
/*
|
|
flog.Info("authupdate", e)
|
|
flog.Info("hash", e.Hash)
|
|
ioutil.WriteFile("sentry", e.Hash, 0666)
|
|
*/
|
|
case *steam.LogOnFailedEvent:
|
|
flog.Info("Logon failed", e)
|
|
switch e.Result {
|
|
case steamlang.EResult_AccountLogonDeniedNeedTwoFactorCode:
|
|
{
|
|
flog.Info("Steam guard isn't letting me in! Enter 2FA code:")
|
|
var code string
|
|
fmt.Scanf("%s", &code)
|
|
myLoginInfo.TwoFactorCode = code
|
|
}
|
|
case steamlang.EResult_AccountLogonDenied:
|
|
{
|
|
flog.Info("Steam guard isn't letting me in! Enter auth code:")
|
|
var code string
|
|
fmt.Scanf("%s", &code)
|
|
myLoginInfo.AuthCode = code
|
|
}
|
|
default:
|
|
log.Errorf("LogOnFailedEvent: %#v ", e.Result)
|
|
// TODO: Handle EResult_InvalidLoginAuthCode
|
|
return
|
|
}
|
|
case *steam.LoggedOnEvent:
|
|
flog.Debugf("LoggedOnEvent: %#v", e)
|
|
b.connected <- struct{}{}
|
|
flog.Debugf("setting online")
|
|
b.c.Social.SetPersonaState(steamlang.EPersonaState_Online)
|
|
case *steam.DisconnectedEvent:
|
|
flog.Info("Disconnected")
|
|
flog.Info("Attempting to reconnect...")
|
|
b.c.Connect()
|
|
case steam.FatalErrorEvent:
|
|
flog.Error(e)
|
|
case error:
|
|
flog.Error(e)
|
|
default:
|
|
flog.Debugf("unknown event %#v", e)
|
|
}
|
|
}
|
|
}
|