go-xmpp4steam/gateway/steam.go

270 lines
8.6 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package gateway
import (
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
"github.com/Philipp15b/go-steam"
"github.com/Philipp15b/go-steam/protocol/steamlang"
"github.com/Philipp15b/go-steam/steamid"
"fmt"
"io/ioutil"
"strconv"
"time"
)
const (
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
)
var (
ServerAddrs = "servers.addr"
)
func (g *GatewayInfo) SteamRun() {
if g.Deleting {
logger.Info.Printf("[%s] Deleting gateway", g.XMPP_JID_Client)
return
}
logger.Info.Printf("[%s] Running", g.XMPP_JID_Client)
steam.InitializeSteamDirectory()
g.setLoginInfos()
if g.SteamClient == nil {
g.SteamClient = steam.NewClient()
}
g.SteamConnecting = false
g.SteamClient.ConnectionTimeout = 10 * time.Second
g.mainSteam()
logger.Info.Printf("[%s] Reach main method's end", g.XMPP_JID_Client)
}
func (g *GatewayInfo) mainSteam() {
for event := range g.SteamClient.Events() {
switch e := event.(type) {
case *steam.ConnectedEvent:
// Connected on server
g.SteamConnecting = false
logger.Debug.Printf("[%s] Connected on Steam serveur", g.XMPP_JID_Client)
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.LoggedOffEvent:
logger.Error.Printf("[%s] LoggedOffEvent: ", g.XMPP_JID_Client, e)
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Disconnected of Steam network (%v)", e))
g.SteamConnecting = false
case steam.FatalErrorEvent:
logger.Error.Printf("[%s] FatalError: ", g.XMPP_JID_Client, e)
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Steam Fatal Error : %v", e))
g.DisconnectAllSteamFriend()
g.SteamConnecting = false
case *steam.DisconnectedEvent:
logger.Info.Printf("[%s] Disconnected event", g.XMPP_JID_Client)
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Steam Error : %v", e))
g.DisconnectAllSteamFriend()
g.SteamConnecting = false
case error:
logger.Error.Printf("[%s] ", g.XMPP_JID_Client, e)
g.SendXmppMessage(XmppJidComponent, "", "Steam Error : "+e.Error())
case *steam.LogOnFailedEvent:
logger.Error.Printf("[%s] Login failed", g.XMPP_JID_Client, e)
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Login failed : %v", e.Result))
g.SteamConnecting = false
case *steam.ClientCMListEvent:
// Doing nothing with server list
case *steam.PersonaStateEvent:
logger.Debug.Printf("[%s] Received PersonaStateEvent: %v", g.XMPP_JID_Client, e)
// Presenc received
if _, ok := g.SteamClient.Social.Friends.GetCopy()[e.FriendId]; !ok {
// Is not in friend list
// Exepte for myself
if g.SteamClient.SteamId() != e.FriendId {
continue
}
}
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:
logger.Debug.Printf("[%s] Received ChatMsgEvent: %v", g.XMPP_JID_Client, e)
// Message received
from := e.ChatterId.ToString() + "@" + XmppJidComponent
if e.EntryType == steamlang.EChatEntryType_Typing {
g.SendXmppMessageComposing(from)
} else if e.EntryType == steamlang.EChatEntryType_LeftConversation {
g.SendXmppMessageLeaveConversation(from)
} else {
g.SendXmppMessage(from, "", e.Message)
}
case *steam.ChatInviteEvent:
logger.Debug.Printf("[%s] Received ChatInviteEvent: %v", g.XMPP_JID_Client, e)
// Invitation to play
if fromFriend, ok := g.SteamClient.Social.Friends.GetCopy()[e.FriendChatId]; ok {
messageToSend := fmt.Sprintf("Currently playing to « %s », would you like to join ?", fromFriend.GameName)
g.SendXmppMessage(e.FriendChatId.ToString()+"@"+XmppJidComponent, "", messageToSend)
}
default:
logger.Debug.Printf("[%s] Steam unmatch event (Type: %T): %v", g.XMPP_JID_Client, e, e)
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Steam unmatch event (Type: %T): %v", e, 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
}
logger.Debug.Printf("Authentification of (%s, %s)", 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()
}
}
logger.Debug.Printf("[%s] Is Steam connected (Connected: %v)", g.XMPP_JID_Client, ret)
return ret
}
func (g *GatewayInfo) SteamConnect() {
if g.IsSteamConnected() {
logger.Debug.Printf("[%s] Try to connect, but already connected", g.XMPP_JID_Client)
return
}
if g.SteamConnecting {
logger.Debug.Printf("[%s] Try to connect, but currently connecting…", g.XMPP_JID_Client)
return
}
g.SteamConnecting = true
go func() {
logger.Info.Printf("[%s] Connecting...", g.XMPP_JID_Client)
g.SendXmppMessage(XmppJidComponent, "", "Connecting...")
addr := g.SteamClient.Connect()
logger.Info.Printf("[%s] Connected on %v", g.XMPP_JID_Client, addr)
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Connected on %v", addr))
}()
}
func (g *GatewayInfo) SteamDisconnect() {
if !g.IsSteamConnected() {
logger.Debug.Printf("[%s] Try to disconnect, but already disconnected", g.XMPP_JID_Client)
return
}
logger.Info.Printf("[%s] Steam disconnect", g.XMPP_JID_Client)
g.XMPP_Disconnect()
g.DisconnectAllSteamFriend()
go g.SteamClient.Disconnect()
}
func (g *GatewayInfo) DisconnectAllSteamFriend() {
logger.Debug.Printf("[%s] Disconnect all Steam friend", g.XMPP_JID_Client)
for sid := range g.FriendSteamId {
g.SendXmppPresence(Status_offline, Type_unavailable, "", sid+"@"+XmppJidComponent, "", "")
delete(g.FriendSteamId, sid)
}
}
func (g *GatewayInfo) SendSteamMessage(steamId, message string) {
g.sendSteamMessage(steamId, message, steamlang.EChatEntryType_ChatMsg)
}
func (g *GatewayInfo) SendSteamMessageComposing(steamId string) {
g.sendSteamMessage(steamId, "", steamlang.EChatEntryType_Typing)
}
func (g *GatewayInfo) SendSteamMessageLeaveConversation(steamId string) {
g.sendSteamMessage(steamId, "", steamlang.EChatEntryType_LeftConversation)
}
func (g *GatewayInfo) sendSteamMessage(steamId, message string, chatEntryType steamlang.EChatEntryType) {
if !g.IsSteamConnected() {
logger.Debug.Printf("[%s] Try to send message, but disconnected", g.XMPP_JID_Client)
return
}
steamIdUint64, err := strconv.ParseUint(steamId, 10, 64)
if err == nil {
logger.Debug.Printf("[%s] Send message to %v", g.XMPP_JID_Client, steamIdUint64)
g.SteamClient.Social.SendMessage(steamid.SteamId(steamIdUint64), chatEntryType, message)
} else {
logger.Error.Printf("[%s] Failed to get SteamId from %s", g.XMPP_JID_Client, steamId)
}
}
func (g *GatewayInfo) SendSteamPresence(status steamlang.EPersonaState) {
if !g.IsSteamConnected() {
logger.Debug.Printf("[%s] Try to send presence, but disconnected", g.XMPP_JID_Client)
return
}
logger.Debug.Printf("[%s] Send presence (Status: %v)", g.XMPP_JID_Client, status)
g.SteamClient.Social.SetPersonaState(status)
}