227 lines
6.1 KiB
Go
227 lines
6.1 KiB
Go
package gateway
|
|
|
|
import (
|
|
"github.com/Philipp15b/go-steam"
|
|
"github.com/Philipp15b/go-steam/protocol/steamlang"
|
|
"github.com/Philipp15b/go-steam/steamid"
|
|
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
serverAddrs = "servers.addr"
|
|
|
|
State_Offline = steamlang.EPersonaState_Offline
|
|
State_Online = steamlang.EPersonaState_Online
|
|
State_Busy = steamlang.EPersonaState_Busy
|
|
State_Away = steamlang.EPersonaState_Away
|
|
State_Snooze = steamlang.EPersonaState_Snooze
|
|
State_LookingToTrade = steamlang.EPersonaState_LookingToTrade
|
|
State_LookingToPlay = steamlang.EPersonaState_LookingToPlay
|
|
State_Max = steamlang.EPersonaState_Max
|
|
|
|
LogSteamInfo = "\t[STEAM INFO]\t"
|
|
LogSteamError = "\t[STEAM ERROR]\t"
|
|
LogSteamDebug = "\t[STEAM DEBUG]\t"
|
|
)
|
|
|
|
func (g *GatewayInfo) SteamRun() {
|
|
if g.Deleting {
|
|
log.Printf("%sDeleting gateway", LogSteamInfo)
|
|
return
|
|
}
|
|
|
|
log.Printf("%sRunning", LogSteamInfo)
|
|
g.setLoginInfos()
|
|
g.SteamClient = steam.NewClient()
|
|
g.SteamConnecting = false
|
|
g.SteamClient.ConnectionTimeout = 10 * time.Second
|
|
|
|
g.mainSteam()
|
|
|
|
log.Printf("%sReach main method's end", LogSteamInfo)
|
|
go g.SteamRun()
|
|
}
|
|
|
|
func (g *GatewayInfo) mainSteam() {
|
|
for event := range g.SteamClient.Events() {
|
|
switch e := event.(type) {
|
|
case *steam.ConnectedEvent:
|
|
// Connected on server
|
|
g.SteamConnecting = false
|
|
log.Printf("%sConnected on Steam serveur", LogSteamDebug)
|
|
g.SteamClient.Auth.LogOn(g.SteamLoginInfo)
|
|
|
|
case *steam.MachineAuthUpdateEvent:
|
|
// Received sentry file
|
|
ioutil.WriteFile(g.SentryFile, e.Hash, 0666)
|
|
|
|
case *steam.LoggedOnEvent:
|
|
// Logged on
|
|
g.SendSteamPresence(steamlang.EPersonaState_Online)
|
|
g.SendXmppMessage(XmppJidComponent, "", "Connected on Steam network")
|
|
|
|
case steam.FatalErrorEvent:
|
|
log.Printf("%sFatalError: ", LogSteamError, e)
|
|
g.SendXmppMessage(XmppJidComponent, "", "Steam Fatal Error : "+e.Error())
|
|
g.DisconnectAllSteamFriend()
|
|
return
|
|
|
|
case error:
|
|
log.Printf("%s", LogSteamError, e)
|
|
g.SendXmppMessage(XmppJidComponent, "", "Steam Error : "+e.Error())
|
|
|
|
case *steam.ClientCMListEvent:
|
|
// Save servers addresses
|
|
b, err := json.Marshal(*e)
|
|
if err != nil {
|
|
log.Printf("%sFailed to json.Marshal() servers list", LogSteamError)
|
|
} else {
|
|
ioutil.WriteFile(serverAddrs, b, 0666)
|
|
}
|
|
|
|
case *steam.PersonaStateEvent:
|
|
// Presenc received
|
|
steamId := e.FriendId.ToString()
|
|
name := e.Name
|
|
gameName := e.GameName
|
|
|
|
var status string
|
|
var tpye string
|
|
switch e.State {
|
|
case State_Offline:
|
|
status = Status_offline
|
|
tpye = Type_unavailable
|
|
case State_Online:
|
|
status = Status_online
|
|
tpye = Type_available
|
|
case State_Busy:
|
|
status = Status_do_not_disturb
|
|
tpye = Type_available
|
|
case State_Away:
|
|
status = Status_away
|
|
tpye = Type_available
|
|
case State_Snooze:
|
|
status = Status_extended_away
|
|
tpye = Type_available
|
|
}
|
|
if _, ok := g.FriendSteamId[steamId]; !ok {
|
|
// Send subscribsion
|
|
g.SendXmppPresence(status, Type_subscribe, "", steamId+"@"+XmppJidComponent, gameName, name)
|
|
g.FriendSteamId[steamId] = &StatusSteamFriend{XMPP_Status: status, XMPP_Type: tpye}
|
|
} else {
|
|
g.FriendSteamId[steamId].XMPP_Status = status
|
|
g.FriendSteamId[steamId].XMPP_Type = tpye
|
|
g.FriendSteamId[steamId].SteamGameName = gameName
|
|
g.FriendSteamId[steamId].SteamName = name
|
|
}
|
|
g.SendXmppPresence(status, tpye, "", steamId+"@"+XmppJidComponent, gameName, name)
|
|
|
|
case *steam.ChatMsgEvent:
|
|
// Message received
|
|
g.SendXmppMessage(e.ChatterId.ToString()+"@"+XmppJidComponent, "", e.Message)
|
|
|
|
default:
|
|
log.Printf("%s", LogSteamDebug, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (g *GatewayInfo) setLoginInfos() {
|
|
var sentryHash steam.SentryHash
|
|
sentryHash, err := ioutil.ReadFile(g.SentryFile)
|
|
|
|
g.SteamLoginInfo = new(steam.LogOnDetails)
|
|
g.SteamLoginInfo.Username = g.SteamLogin
|
|
g.SteamLoginInfo.Password = g.SteamPassword
|
|
|
|
if err == nil {
|
|
g.SteamLoginInfo.SentryFileHash = sentryHash
|
|
}
|
|
log.Printf("%sAuthentification of (%s, %s)", LogSteamDebug, g.XMPP_JID_Client, g.SteamLoginInfo.Username)
|
|
}
|
|
|
|
func (g *GatewayInfo) IsSteamConnected() bool {
|
|
ret := g != nil
|
|
if ret {
|
|
ret = g.SteamClient != nil
|
|
if ret {
|
|
ret = g.SteamClient.Connected()
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (g *GatewayInfo) SteamConnect() {
|
|
if g.IsSteamConnected() {
|
|
log.Printf("%sTry to connect, but already connected", LogSteamDebug)
|
|
return
|
|
}
|
|
if g.SteamConnecting {
|
|
log.Printf("%sTry to connect, but currently connecting…", LogSteamDebug)
|
|
return
|
|
}
|
|
|
|
g.SteamConnecting = true
|
|
b, err := ioutil.ReadFile(serverAddrs)
|
|
if err == nil {
|
|
var toList steam.ClientCMListEvent
|
|
err := json.Unmarshal(b, &toList)
|
|
if err != nil {
|
|
log.Printf("%sFailed to json.Unmarshal() servers list", LogSteamError)
|
|
} else {
|
|
log.Printf("%sConnecting...", LogSteamInfo, toList.Addresses[0])
|
|
g.SteamClient.ConnectTo(toList.Addresses[0])
|
|
}
|
|
} else {
|
|
log.Printf("%sFailed to read servers list file", LogSteamError)
|
|
log.Printf("%sConnecting...", LogSteamInfo)
|
|
g.SteamClient.Connect()
|
|
}
|
|
}
|
|
|
|
func (g *GatewayInfo) SteamDisconnect() {
|
|
if !g.IsSteamConnected() {
|
|
log.Printf("%sTry to disconnect, but already disconnected", LogSteamDebug)
|
|
return
|
|
}
|
|
log.Printf("%sSteam disconnect", LogSteamInfo)
|
|
|
|
g.XMPP_Disconnect()
|
|
g.DisconnectAllSteamFriend()
|
|
go g.SteamClient.Disconnect()
|
|
}
|
|
|
|
func (g *GatewayInfo) DisconnectAllSteamFriend() {
|
|
for sid, _ := range g.FriendSteamId {
|
|
g.SendXmppPresence(Status_offline, Type_unavailable, "", sid+"@"+XmppJidComponent, "", "")
|
|
delete(g.FriendSteamId, sid)
|
|
}
|
|
}
|
|
|
|
func (g *GatewayInfo) SendSteamMessage(steamId, message string) {
|
|
if !g.IsSteamConnected() {
|
|
log.Printf("%sTry to send message, but disconnected", LogSteamDebug)
|
|
return
|
|
}
|
|
|
|
steamIdUint64, err := strconv.ParseUint(steamId, 10, 64)
|
|
if err == nil {
|
|
g.SteamClient.Social.SendMessage(steamid.SteamId(steamIdUint64), steamlang.EChatEntryType_ChatMsg, message)
|
|
} else {
|
|
log.Printf("%sFailed to get SteamId from %s", LogSteamError, steamId)
|
|
}
|
|
}
|
|
|
|
func (g *GatewayInfo) SendSteamPresence(status steamlang.EPersonaState) {
|
|
if !g.IsSteamConnected() {
|
|
log.Printf("%sTry to send presence, but disconnected", LogSteamDebug)
|
|
return
|
|
}
|
|
g.SteamClient.Social.SetPersonaState(status)
|
|
}
|