mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-11-22 16:20:26 +00:00
Add initial steam support
This commit is contained in:
parent
1f91461853
commit
276ac840aa
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/42wim/matterbridge/bridge/mattermost"
|
"github.com/42wim/matterbridge/bridge/mattermost"
|
||||||
"github.com/42wim/matterbridge/bridge/rocketchat"
|
"github.com/42wim/matterbridge/bridge/rocketchat"
|
||||||
"github.com/42wim/matterbridge/bridge/slack"
|
"github.com/42wim/matterbridge/bridge/slack"
|
||||||
|
"github.com/42wim/matterbridge/bridge/steam"
|
||||||
"github.com/42wim/matterbridge/bridge/telegram"
|
"github.com/42wim/matterbridge/bridge/telegram"
|
||||||
"github.com/42wim/matterbridge/bridge/xmpp"
|
"github.com/42wim/matterbridge/bridge/xmpp"
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
@ -75,6 +76,9 @@ func New(cfg *config.Config, bridge *config.Bridge, c chan config.Message) *Brid
|
|||||||
case "matrix":
|
case "matrix":
|
||||||
b.Config = cfg.Matrix[name]
|
b.Config = cfg.Matrix[name]
|
||||||
b.Bridger = bmatrix.New(cfg.Matrix[name], bridge.Account, c)
|
b.Bridger = bmatrix.New(cfg.Matrix[name], bridge.Account, c)
|
||||||
|
case "steam":
|
||||||
|
b.Config = cfg.Steam[name]
|
||||||
|
b.Bridger = bsteam.New(cfg.Steam[name], bridge.Account, c)
|
||||||
case "api":
|
case "api":
|
||||||
b.Config = cfg.Api[name]
|
b.Config = cfg.Api[name]
|
||||||
b.Bridger = api.New(cfg.Api[name], bridge.Account, c)
|
b.Bridger = api.New(cfg.Api[name], bridge.Account, c)
|
||||||
|
@ -39,6 +39,7 @@ type ChannelInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Protocol struct {
|
type Protocol struct {
|
||||||
|
AuthCode string // steam
|
||||||
BindAddress string // mattermost, slack
|
BindAddress string // mattermost, slack
|
||||||
Buffer int // api
|
Buffer int // api
|
||||||
EditSuffix string // mattermost, slack, discord, telegram, gitter
|
EditSuffix string // mattermost, slack, discord, telegram, gitter
|
||||||
@ -109,6 +110,7 @@ type Config struct {
|
|||||||
Mattermost map[string]Protocol
|
Mattermost map[string]Protocol
|
||||||
Matrix map[string]Protocol
|
Matrix map[string]Protocol
|
||||||
Slack map[string]Protocol
|
Slack map[string]Protocol
|
||||||
|
Steam map[string]Protocol
|
||||||
Gitter map[string]Protocol
|
Gitter map[string]Protocol
|
||||||
Xmpp map[string]Protocol
|
Xmpp map[string]Protocol
|
||||||
Discord map[string]Protocol
|
Discord map[string]Protocol
|
||||||
|
158
bridge/steam/steam.go
Normal file
158
bridge/steam/steam.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -656,6 +656,55 @@ RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
|
|||||||
#OPTIONAL (default false)
|
#OPTIONAL (default false)
|
||||||
ShowJoinPart=false
|
ShowJoinPart=false
|
||||||
|
|
||||||
|
###################################################################
|
||||||
|
#steam section
|
||||||
|
###################################################################
|
||||||
|
[steam]
|
||||||
|
#You can configure multiple servers "[steam.name]" or "[steam.name2]"
|
||||||
|
#In this example we use [steam.gamechat]
|
||||||
|
#REQUIRED
|
||||||
|
|
||||||
|
[matrix.gamechat]
|
||||||
|
#login/pass of your bot.
|
||||||
|
#Use a dedicated user for this and not your own account!
|
||||||
|
#REQUIRED
|
||||||
|
Login="yourlogin"
|
||||||
|
Password="yourpass"
|
||||||
|
|
||||||
|
#steamguard mail authcode (not the 2FA code)
|
||||||
|
#OPTIONAL
|
||||||
|
Authcode="ABCE12"
|
||||||
|
|
||||||
|
#Whether to prefix messages from other bridges to matrix with the sender's nick.
|
||||||
|
#Useful if username overrides for incoming webhooks isn't enabled on the
|
||||||
|
#matrix server. If you set PrefixMessagesWithNick to true, each message
|
||||||
|
#from bridge to matrix will by default be prefixed by the RemoteNickFormat setting. i
|
||||||
|
#OPTIONAL (default false)
|
||||||
|
PrefixMessagesWithNick=false
|
||||||
|
|
||||||
|
#Nicks you want to ignore.
|
||||||
|
#Messages from those users will not be sent to other bridges.
|
||||||
|
#OPTIONAL
|
||||||
|
IgnoreNicks="spammer1 spammer2"
|
||||||
|
|
||||||
|
#Messages you want to ignore.
|
||||||
|
#Messages matching these regexp will be ignored and not sent to other bridges
|
||||||
|
#See https://regex-golang.appspot.com/assets/html/index.html for more regex info
|
||||||
|
#OPTIONAL (example below ignores messages starting with ~~ or messages containing badword
|
||||||
|
IgnoreMessages="^~~ badword"
|
||||||
|
|
||||||
|
#RemoteNickFormat defines how remote users appear on this bridge
|
||||||
|
#The string "{NICK}" (case sensitive) will be replaced by the actual nick / username.
|
||||||
|
#The string "{BRIDGE}" (case sensitive) will be replaced by the sending bridge
|
||||||
|
#The string "{PROTOCOL}" (case sensitive) will be replaced by the protocol used by the bridge
|
||||||
|
#OPTIONAL (default empty)
|
||||||
|
RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
|
||||||
|
|
||||||
|
#Enable to show users joins/parts from other bridges
|
||||||
|
#Only works hiding/show messages from irc and mattermost bridge for now
|
||||||
|
#OPTIONAL (default false)
|
||||||
|
ShowJoinPart=false
|
||||||
|
|
||||||
|
|
||||||
###################################################################
|
###################################################################
|
||||||
#API
|
#API
|
||||||
@ -744,6 +793,9 @@ enable=true
|
|||||||
#rocketchat - #channel (# is required (also needed for private channels!)
|
#rocketchat - #channel (# is required (also needed for private channels!)
|
||||||
#matrix - #channel:server (eg #yourchannel:matrix.org)
|
#matrix - #channel:server (eg #yourchannel:matrix.org)
|
||||||
# - encrypted rooms are not supported in matrix
|
# - encrypted rooms are not supported in matrix
|
||||||
|
#steam - chatid (a large number).
|
||||||
|
# The number in the URL when you click "enter chat room" in the browser
|
||||||
|
#
|
||||||
#REQUIRED
|
#REQUIRED
|
||||||
channel="#testing"
|
channel="#testing"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user