summaryrefslogtreecommitdiffstats
path: root/bridge/steam
diff options
context:
space:
mode:
authorWim <wim@42.be>2017-06-22 01:02:05 +0200
committerWim <wim@42.be>2017-06-22 01:02:05 +0200
commit276ac840aacf01532ef33f0d461775daacb23880 (patch)
tree6047f397f28eb2080aca3e96d9631a37be914c44 /bridge/steam
parent1f914618538920db4bfec7b106ee97038b157c9b (diff)
downloadmatterbridge-msglm-276ac840aacf01532ef33f0d461775daacb23880.tar.gz
matterbridge-msglm-276ac840aacf01532ef33f0d461775daacb23880.tar.bz2
matterbridge-msglm-276ac840aacf01532ef33f0d461775daacb23880.zip
Add initial steam support
Diffstat (limited to 'bridge/steam')
-rw-r--r--bridge/steam/steam.go158
1 files changed, 158 insertions, 0 deletions
diff --git a/bridge/steam/steam.go b/bridge/steam/steam.go
new file mode 100644
index 00000000..491612d1
--- /dev/null
+++ b/bridge/steam/steam.go
@@ -0,0 +1,158 @@
+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 string) error {
+ id, err := steamid.NewId(channel)
+ if err != nil {
+ return err
+ }
+ b.c.Social.JoinChat(id)
+ return nil
+}
+
+func (b *Bsteam) Send(msg config.Message) error {
+ 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)
+ msg := config.Message{Username: b.getNick(e.ChatterId), Text: e.Message, Channel: strconv.FormatInt(int64(e.ChatRoomId), 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: ", 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)
+ }
+ }
+}