Compare commits
No commits in common. "master" and "master" have entirely different histories.
13
README.md
13
README.md
|
|
@ -13,21 +13,14 @@ go-xmpp4steam is a XMPP/Steam gateway.
|
||||||
* [cfg](https://github.com/jimlawless/cfg) for the configuration file.
|
* [cfg](https://github.com/jimlawless/cfg) for the configuration file.
|
||||||
|
|
||||||
|
|
||||||
### Build and run
|
Download the CA at [https://kingpenguin.tk/ressources/cacert.pem](https://kingpenguin.tk/ressources/cacert.pem), then install it on your operating system.
|
||||||
You must first [install go environment](https://golang.org/doc/install) on your system.
|
Once installed, go into your $GOPATH directory and go get the source code.
|
||||||
Then, go into your $GOPATH directory and go get the source code (This will download the source code and the dependencies).
|
|
||||||
```sh
|
```sh
|
||||||
go get git.kingpenguin.tk/chteufleur/go-xmpp4steam.git
|
go get git.kingpenguin.tk/chteufleur/go-xmpp4steam.git
|
||||||
```
|
```
|
||||||
|
|
||||||
First, you need to go into directory ``$GOPATH/src/chteufleur/go-xmpp4steam.git``.
|
|
||||||
Then, you can run the project directly by using command ``go run main.go``.
|
|
||||||
Or, in order to build the project you can run the command ``go build main.go``.
|
|
||||||
It will generate a binary that you can run as any binary file.
|
|
||||||
|
|
||||||
### Configure
|
### Configure
|
||||||
Configure the gateway by editing the ``xmpp4steam.conf`` file in order to give all XMPP component information. This configuration file has to be placed following the [XDG specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) (example ``/etc/xdg/http-auth/xmpp4steam.conf``).
|
Configure the gateway by editing the ``xmpp4steam.cfg`` file in order to give all XMPP component information.
|
||||||
An example of the config file can be found in [the repos](https://git.kingpenguin.tk/chteufleur/HTTPAuthentificationOverXMPP/src/master/xmpp4steam.conf).
|
|
||||||
|
|
||||||
### Utilization
|
### Utilization
|
||||||
To register, you have to send an Ad-Hoc command to the gateway in order to give your Steam login information.
|
To register, you have to send an Ad-Hoc command to the gateway in order to give your Steam login information.
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
package configuration
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/gateway"
|
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
|
|
||||||
"github.com/jimlawless/cfg"
|
|
||||||
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
XdgDirectoryName = "xmpp4steam"
|
|
||||||
configurationFilePath = "xmpp4steam/xmpp4steam.conf"
|
|
||||||
|
|
||||||
PathConfEnvVariable = "XDG_CONFIG_DIRS"
|
|
||||||
DefaultXdgConfigDirs = "/etc/xdg"
|
|
||||||
|
|
||||||
PathDataEnvVariable = "XDG_DATA_DIRS"
|
|
||||||
DefaultXdgDataDirs = "/usr/local/share/:/usr/share/"
|
|
||||||
PreferedPathDataDir = "/usr/local/share"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
MapConfig = make(map[string]string)
|
|
||||||
)
|
|
||||||
|
|
||||||
func Init() {
|
|
||||||
loadConfigFile()
|
|
||||||
|
|
||||||
dataPathDir := locateDataDirPath()
|
|
||||||
database.DatabaseFile = dataPathDir + "/" + database.DatabaseFileName
|
|
||||||
database.Init()
|
|
||||||
|
|
||||||
gateway.ServerAddrs = dataPathDir + "/" + gateway.ServerAddrs
|
|
||||||
gateway.SentryDirectory = dataPathDir + "/" + gateway.SentryDirectory
|
|
||||||
os.MkdirAll(gateway.SentryDirectory, 0700)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadConfigFile() bool {
|
|
||||||
ret := false
|
|
||||||
envVariable := os.Getenv(PathConfEnvVariable)
|
|
||||||
if envVariable == "" {
|
|
||||||
envVariable = DefaultXdgConfigDirs
|
|
||||||
}
|
|
||||||
for _, path := range strings.Split(envVariable, ":") {
|
|
||||||
logger.Debug.Println("Try to find configuration file into " + path)
|
|
||||||
configFile := path + "/" + configurationFilePath
|
|
||||||
if _, err := os.Stat(configFile); err == nil {
|
|
||||||
// The config file exist
|
|
||||||
if cfg.Load(configFile, MapConfig) == nil {
|
|
||||||
// And has been loaded successfully
|
|
||||||
logger.Info.Println("Find configuration file at " + configFile)
|
|
||||||
ret = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func locateDataDirPath() string {
|
|
||||||
ret := ""
|
|
||||||
isDirFound := false
|
|
||||||
envVariable := os.Getenv(PathDataEnvVariable)
|
|
||||||
if envVariable == "" {
|
|
||||||
envVariable = DefaultXdgDataDirs
|
|
||||||
}
|
|
||||||
for _, path := range strings.Split(envVariable, ":") {
|
|
||||||
logger.Debug.Printf("Try to find data base directory into " + path)
|
|
||||||
dbDir := path + "/" + XdgDirectoryName
|
|
||||||
if fi, err := os.Stat(dbDir); err == nil && fi.IsDir() {
|
|
||||||
// The database file exist
|
|
||||||
logger.Info.Printf("Find data base directory at " + dbDir)
|
|
||||||
isDirFound = true
|
|
||||||
ret = dbDir
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !isDirFound {
|
|
||||||
if strings.Contains(envVariable, PreferedPathDataDir) {
|
|
||||||
ret = PreferedPathDataDir + "/" + XdgDirectoryName
|
|
||||||
} else {
|
|
||||||
ret = strings.Split(envVariable, ":")[0] + "/" + XdgDirectoryName
|
|
||||||
}
|
|
||||||
|
|
||||||
if os.MkdirAll(ret, 0700) == nil {
|
|
||||||
logger.Info.Printf("Creating new data base directory at " + ret)
|
|
||||||
} else {
|
|
||||||
logger.Error.Printf("Fail to create data base directory at " + ret)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
@ -2,19 +2,22 @@ package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DatabaseFileName = "go_xmpp4steam.db"
|
databaseFile = "go_xmpp4steam.db"
|
||||||
|
|
||||||
createDatabaseStmt = "create table if not exists users (jid text not null primary key, steamLogin text, steamPwd text, debug int);"
|
createDatabaseStmt = "create table if not exists users (jid text not null primary key, steamLogin text, steamPwd text, debug int);"
|
||||||
insertDatabaseStmt = "insert into users (jid, steamLogin, steamPwd, debug) values(?, ?, ?, ?)"
|
insertDatabaseStmt = "insert into users (jid, steamLogin, steamPwd, debug) values(?, ?, ?, ?)"
|
||||||
deleteDatabaseStmt = "delete from users where jid=?"
|
deleteDatabaseStmt = "delete from users where jid=?"
|
||||||
selectDatabaseStmt = "select jid, steamLogin, steamPwd, debug from users where jid=?"
|
selectDatabaseStmt = "select jid, steamLogin, steamPwd, debug from users where jid=?"
|
||||||
selectAllDatabaseStmt = "select jid, steamLogin, steamPwd, debug from users"
|
updateDatabaseStmt = "update users set steamLogin=?, steamPwd=?, debug=? where jid=?"
|
||||||
updateDatabaseStmt = "update users set steamLogin=?, steamPwd=?, debug=? where jid=?"
|
|
||||||
|
LogInfo = "\t[SQLITE INFO]\t"
|
||||||
|
LogError = "\t[SQLITE ERROR]\t"
|
||||||
|
LogDebug = "\t[SQLITE DEBUG]\t"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DatabaseLine struct {
|
type DatabaseLine struct {
|
||||||
|
|
@ -25,24 +28,19 @@ type DatabaseLine struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db = new(sql.DB)
|
db = new(sql.DB)
|
||||||
DatabaseFile = ""
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
}
|
d, err := sql.Open("sqlite3", databaseFile)
|
||||||
|
|
||||||
func Init() {
|
|
||||||
logger.Info.Printf("Init database (file %s)", DatabaseFile)
|
|
||||||
d, err := sql.Open("sqlite3", DatabaseFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on openning database : %v", err)
|
log.Printf("%sError on openning database", LogError, err)
|
||||||
}
|
}
|
||||||
db = d
|
db = d
|
||||||
|
|
||||||
_, err = db.Exec(createDatabaseStmt)
|
_, err = db.Exec(createDatabaseStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Failed to create table : %v", err)
|
log.Printf("%sFailed to create table", LogError, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +49,7 @@ func Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (newLine *DatabaseLine) AddLine() bool {
|
func (newLine *DatabaseLine) AddLine() bool {
|
||||||
logger.Info.Printf("Add new line %v", newLine)
|
log.Printf("%sAdd new line %v", LogInfo, newLine)
|
||||||
|
|
||||||
isUserRegistred := getLine(newLine.Jid) != nil
|
isUserRegistred := getLine(newLine.Jid) != nil
|
||||||
if isUserRegistred {
|
if isUserRegistred {
|
||||||
|
|
@ -60,7 +58,7 @@ func (newLine *DatabaseLine) AddLine() bool {
|
||||||
|
|
||||||
stmt, err := db.Prepare(insertDatabaseStmt)
|
stmt, err := db.Prepare(insertDatabaseStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on insert jid %s : %v", newLine.Jid, err)
|
log.Printf("%sError on insert jid %s", LogError, newLine.Jid, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
@ -70,7 +68,7 @@ func (newLine *DatabaseLine) AddLine() bool {
|
||||||
}
|
}
|
||||||
_, err = stmt.Exec(newLine.Jid, newLine.SteamLogin, newLine.SteamPwd, debug)
|
_, err = stmt.Exec(newLine.Jid, newLine.SteamLogin, newLine.SteamPwd, debug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on creating SQL statement : %v", err)
|
log.Printf("%sError on creating SQL statement", LogError, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,10 +76,10 @@ func (newLine *DatabaseLine) AddLine() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (newLine *DatabaseLine) UpdateLine() bool {
|
func (newLine *DatabaseLine) UpdateLine() bool {
|
||||||
logger.Info.Printf("Update line %s", newLine.Jid)
|
log.Printf("%sUpdate line %s", LogInfo, newLine.Jid)
|
||||||
stmt, err := db.Prepare(updateDatabaseStmt)
|
stmt, err := db.Prepare(updateDatabaseStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on update : %v", err)
|
log.Printf("%sError on update ", LogError, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
|
|
@ -89,32 +87,15 @@ func (newLine *DatabaseLine) UpdateLine() bool {
|
||||||
if newLine.Debug {
|
if newLine.Debug {
|
||||||
debug = 1
|
debug = 1
|
||||||
}
|
}
|
||||||
if newLine.SteamPwd == "" {
|
|
||||||
oldLine := GetLine(newLine.Jid)
|
|
||||||
if oldLine != nil {
|
|
||||||
newLine.SteamPwd = oldLine.SteamPwd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = stmt.Exec(newLine.SteamLogin, newLine.SteamPwd, debug, newLine.Jid)
|
_, err = stmt.Exec(newLine.SteamLogin, newLine.SteamPwd, debug, newLine.Jid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on updating SQL statement : %v", err)
|
log.Printf("%sError on updating SQL statement", LogError, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbUser *DatabaseLine) UpdateUser() bool {
|
|
||||||
isUserRegistred := GetLine(dbUser.Jid) != nil
|
|
||||||
var isSqlSuccess bool
|
|
||||||
if isUserRegistred {
|
|
||||||
isSqlSuccess = dbUser.UpdateLine()
|
|
||||||
} else {
|
|
||||||
isSqlSuccess = dbUser.AddLine()
|
|
||||||
}
|
|
||||||
return isSqlSuccess
|
|
||||||
}
|
|
||||||
|
|
||||||
func RemoveLine(jid string) bool {
|
func RemoveLine(jid string) bool {
|
||||||
// Update Steam login and password to blank before deleting,
|
// Update Steam login and password to blank before deleting,
|
||||||
// because it is not really deleted in the SQLite file.
|
// because it is not really deleted in the SQLite file.
|
||||||
|
|
@ -122,26 +103,26 @@ func RemoveLine(jid string) bool {
|
||||||
line.Jid = jid
|
line.Jid = jid
|
||||||
line.UpdateLine()
|
line.UpdateLine()
|
||||||
|
|
||||||
logger.Info.Printf("Remove line %s", jid)
|
log.Printf("%sRemove line %s", LogInfo, jid)
|
||||||
stmt, err := db.Prepare(deleteDatabaseStmt)
|
stmt, err := db.Prepare(deleteDatabaseStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on delete jid %s : %v", jid, err)
|
log.Printf("%sError on delete jid %s", LogError, jid, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
res, err := stmt.Exec(jid)
|
res, err := stmt.Exec(jid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on delete SQL statement : %v", err)
|
log.Printf("%sError on delete SQL statement", LogError, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
affect, err := res.RowsAffected()
|
affect, err := res.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on delete SQL statement : %v", err)
|
log.Printf("%sError on delete SQL statement", LogError, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if affect == 0 {
|
if affect == 0 {
|
||||||
logger.Debug.Printf("No line affected")
|
log.Printf("%sNo line affected", LogDebug)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,7 +133,7 @@ func GetLine(jid string) *DatabaseLine {
|
||||||
ret := getLine(jid)
|
ret := getLine(jid)
|
||||||
|
|
||||||
if ret == nil || ret.SteamLogin == "" {
|
if ret == nil || ret.SteamLogin == "" {
|
||||||
logger.Debug.Printf("Line empty")
|
log.Printf("%sLine empty", LogDebug)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,19 +141,19 @@ func GetLine(jid string) *DatabaseLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLine(jid string) *DatabaseLine {
|
func getLine(jid string) *DatabaseLine {
|
||||||
logger.Info.Printf("Get line %s", jid)
|
log.Printf("%sGet line %s", LogInfo, jid)
|
||||||
ret := new(DatabaseLine)
|
ret := new(DatabaseLine)
|
||||||
|
|
||||||
stmt, err := db.Prepare(selectDatabaseStmt)
|
stmt, err := db.Prepare(selectDatabaseStmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on select line : %v", err)
|
log.Printf("%sError on select line", LogError, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
defer stmt.Close()
|
defer stmt.Close()
|
||||||
debug := 0
|
debug := 0
|
||||||
err = stmt.QueryRow(jid).Scan(&ret.Jid, &ret.SteamLogin, &ret.SteamPwd, &debug)
|
err = stmt.QueryRow(jid).Scan(&ret.Jid, &ret.SteamLogin, &ret.SteamPwd, &debug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on select scan : %v", err)
|
log.Printf("%sError on select scan", LogError, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if debug == 1 {
|
if debug == 1 {
|
||||||
|
|
@ -185,24 +166,18 @@ func getLine(jid string) *DatabaseLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllLines() []DatabaseLine {
|
func GetAllLines() []DatabaseLine {
|
||||||
logger.Info.Printf("Get all lines")
|
log.Printf("%sGet all lines", LogInfo)
|
||||||
var ret []DatabaseLine
|
var ret []DatabaseLine
|
||||||
|
|
||||||
rows, err := db.Query(selectAllDatabaseStmt)
|
rows, err := db.Query("select jid, steamLogin, steamPwd from users")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error.Printf("Error on select query : %v", err)
|
log.Printf("%sError on select query", LogError, err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
user := new(DatabaseLine)
|
user := new(DatabaseLine)
|
||||||
debug := 0
|
rows.Scan(&user.Jid, &user.SteamLogin, &user.SteamPwd)
|
||||||
rows.Scan(&user.Jid, &user.SteamLogin, &user.SteamPwd, &debug)
|
|
||||||
if user.SteamLogin != "" {
|
if user.SteamLogin != "" {
|
||||||
if debug == 1 {
|
|
||||||
user.Debug = true
|
|
||||||
} else {
|
|
||||||
user.Debug = false
|
|
||||||
}
|
|
||||||
ret = append(ret, *user)
|
ret = append(ret, *user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,12 @@
|
||||||
package gateway
|
package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/Philipp15b/go-steam"
|
"github.com/Philipp15b/go-steam"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
resource = "go-xmpp4steam"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
SentryDirectory = "sentries/"
|
SentryDirectory = "sentries/"
|
||||||
XmppGroupUser = "Steam"
|
resource = "go-xmpp4steam"
|
||||||
|
|
||||||
RemoteRosterRequestPermission = "remote-roster-request-permission"
|
|
||||||
RemoteRosterRequestRoster = "remote-roster-request-roster"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type GatewayInfo struct {
|
type GatewayInfo struct {
|
||||||
|
|
@ -25,33 +16,15 @@ type GatewayInfo struct {
|
||||||
SteamLoginInfo *steam.LogOnDetails
|
SteamLoginInfo *steam.LogOnDetails
|
||||||
SteamClient *steam.Client
|
SteamClient *steam.Client
|
||||||
SentryFile string
|
SentryFile string
|
||||||
friendSteamId *FriendSteam
|
FriendSteamId map[string]*StatusSteamFriend
|
||||||
SteamConnecting bool
|
SteamConnecting bool
|
||||||
Deleting bool
|
Deleting bool
|
||||||
|
|
||||||
// XMPP
|
// XMPP
|
||||||
XMPP_JID_Client string
|
XMPP_JID_Client string
|
||||||
XMPP_Out chan interface{}
|
XMPP_Out chan interface{}
|
||||||
xmpp_Connected_Client *XmppConnectedClient
|
XMPP_Connected_Client map[string]bool
|
||||||
DebugMessage bool
|
DebugMessage bool
|
||||||
xmpp_IQ_RemoteRoster_Request *XmppRemoteRosterRequest
|
|
||||||
AllowEditRoster bool
|
|
||||||
ChatstateNotificationData chan string
|
|
||||||
}
|
|
||||||
|
|
||||||
type FriendSteam struct {
|
|
||||||
steamId map[string]*StatusSteamFriend
|
|
||||||
sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
type XmppConnectedClient struct {
|
|
||||||
client map[string]bool
|
|
||||||
sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
type XmppRemoteRosterRequest struct {
|
|
||||||
request map[string]string
|
|
||||||
sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusSteamFriend struct {
|
type StatusSteamFriend struct {
|
||||||
|
|
@ -63,7 +36,6 @@ type StatusSteamFriend struct {
|
||||||
|
|
||||||
func (g *GatewayInfo) Run() {
|
func (g *GatewayInfo) Run() {
|
||||||
go g.SteamRun()
|
go g.SteamRun()
|
||||||
go g.chatstatesNotification()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) SetSteamAuthCode(authCode string) {
|
func (g *GatewayInfo) SetSteamAuthCode(authCode string) {
|
||||||
|
|
@ -71,96 +43,11 @@ func (g *GatewayInfo) SetSteamAuthCode(authCode string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) Disconnect() {
|
func (g *GatewayInfo) Disconnect() {
|
||||||
go g.XMPP_Disconnect()
|
g.XMPP_Disconnect()
|
||||||
go g.SteamDisconnect()
|
go g.SteamDisconnect()
|
||||||
g.SteamConnecting = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) Delete() {
|
func (g *GatewayInfo) Delete() {
|
||||||
g.Deleting = true
|
g.Deleting = true
|
||||||
|
|
||||||
if g.AllowEditRoster {
|
|
||||||
g.removeAllUserFromRoster()
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Disconnect()
|
g.Disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *GatewayInfo) CreateSteamIds() {
|
|
||||||
s.friendSteamId = &FriendSteam{steamId: make(map[string]*StatusSteamFriend)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) GetFriendSteamId(steamId string) *StatusSteamFriend {
|
|
||||||
s.friendSteamId.RLock()
|
|
||||||
defer s.friendSteamId.RUnlock()
|
|
||||||
return s.friendSteamId.steamId[steamId]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) GetAllFriendSteamId() []string {
|
|
||||||
s.friendSteamId.RLock()
|
|
||||||
defer s.friendSteamId.RUnlock()
|
|
||||||
allSteamIds := make([]string, len(s.friendSteamId.steamId))
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for steamId := range s.friendSteamId.steamId {
|
|
||||||
allSteamIds[i] = steamId
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
return allSteamIds
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) SetFriendSteamId(steamId string, status *StatusSteamFriend) {
|
|
||||||
s.friendSteamId.Lock()
|
|
||||||
s.friendSteamId.steamId[steamId] = status
|
|
||||||
s.friendSteamId.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) RemoveFriendSteamId(steamId string) {
|
|
||||||
s.friendSteamId.Lock()
|
|
||||||
delete(s.friendSteamId.steamId, steamId)
|
|
||||||
s.friendSteamId.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) CreateXmppConnectedClient() {
|
|
||||||
s.xmpp_Connected_Client = &XmppConnectedClient{client: make(map[string]bool)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) SetXmppConnectedClient(jid string) {
|
|
||||||
s.xmpp_Connected_Client.Lock()
|
|
||||||
s.xmpp_Connected_Client.client[jid] = true
|
|
||||||
s.xmpp_Connected_Client.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) RemoveXmppConnectedClient(jid string) {
|
|
||||||
s.xmpp_Connected_Client.Lock()
|
|
||||||
delete(s.xmpp_Connected_Client.client, jid)
|
|
||||||
s.xmpp_Connected_Client.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) GetLenXmppConnectedClient() int {
|
|
||||||
s.xmpp_Connected_Client.RLock()
|
|
||||||
defer s.xmpp_Connected_Client.RUnlock()
|
|
||||||
return len(s.xmpp_Connected_Client.client)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) CreateXmppRemoteRosterRequest() {
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request = &XmppRemoteRosterRequest{request: make(map[string]string)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) SetXmppRemoteRosterRequest(iqId, value string) {
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request.Lock()
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request.request[iqId] = value
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) RemoveXmppRemoteRosterRequest(iqId string) {
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request.Lock()
|
|
||||||
delete(s.xmpp_IQ_RemoteRoster_Request.request, iqId)
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *GatewayInfo) GetXmppRemoteRosterRequest(iqId string) string {
|
|
||||||
s.xmpp_IQ_RemoteRoster_Request.RLock()
|
|
||||||
defer s.xmpp_IQ_RemoteRoster_Request.RUnlock()
|
|
||||||
return s.xmpp_IQ_RemoteRoster_Request.request[iqId]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
160
gateway/steam.go
160
gateway/steam.go
|
|
@ -1,18 +1,20 @@
|
||||||
package gateway
|
package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
"github.com/Philipp15b/go-steam"
|
"github.com/Philipp15b/go-steam"
|
||||||
"github.com/Philipp15b/go-steam/protocol/steamlang"
|
"github.com/Philipp15b/go-steam/protocol/steamlang"
|
||||||
"github.com/Philipp15b/go-steam/steamid"
|
"github.com/Philipp15b/go-steam/steamid"
|
||||||
|
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
serverAddrs = "servers.addr"
|
||||||
|
|
||||||
State_Offline = steamlang.EPersonaState_Offline
|
State_Offline = steamlang.EPersonaState_Offline
|
||||||
State_Online = steamlang.EPersonaState_Online
|
State_Online = steamlang.EPersonaState_Online
|
||||||
State_Busy = steamlang.EPersonaState_Busy
|
State_Busy = steamlang.EPersonaState_Busy
|
||||||
|
|
@ -21,30 +23,28 @@ const (
|
||||||
State_LookingToTrade = steamlang.EPersonaState_LookingToTrade
|
State_LookingToTrade = steamlang.EPersonaState_LookingToTrade
|
||||||
State_LookingToPlay = steamlang.EPersonaState_LookingToPlay
|
State_LookingToPlay = steamlang.EPersonaState_LookingToPlay
|
||||||
State_Max = steamlang.EPersonaState_Max
|
State_Max = steamlang.EPersonaState_Max
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
LogSteamInfo = "\t[STEAM INFO]\t"
|
||||||
ServerAddrs = "servers.addr"
|
LogSteamError = "\t[STEAM ERROR]\t"
|
||||||
|
LogSteamDebug = "\t[STEAM DEBUG]\t"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *GatewayInfo) SteamRun() {
|
func (g *GatewayInfo) SteamRun() {
|
||||||
if g.Deleting {
|
if g.Deleting {
|
||||||
logger.Info.Printf("[%s] Deleting gateway", g.XMPP_JID_Client)
|
log.Printf("%sDeleting gateway", LogSteamInfo)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info.Printf("[%s] Running", g.XMPP_JID_Client)
|
log.Printf("%sRunning", LogSteamInfo)
|
||||||
steam.InitializeSteamDirectory()
|
|
||||||
g.setLoginInfos()
|
g.setLoginInfos()
|
||||||
if g.SteamClient == nil {
|
g.SteamClient = steam.NewClient()
|
||||||
g.SteamClient = steam.NewClient()
|
|
||||||
}
|
|
||||||
g.SteamConnecting = false
|
g.SteamConnecting = false
|
||||||
g.SteamClient.ConnectionTimeout = 10 * time.Second
|
g.SteamClient.ConnectionTimeout = 10 * time.Second
|
||||||
|
|
||||||
g.mainSteam()
|
g.mainSteam()
|
||||||
|
|
||||||
logger.Info.Printf("[%s] Reach main method's end", g.XMPP_JID_Client)
|
log.Printf("%sReach main method's end", LogSteamInfo)
|
||||||
|
go g.SteamRun()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) mainSteam() {
|
func (g *GatewayInfo) mainSteam() {
|
||||||
|
|
@ -53,7 +53,7 @@ func (g *GatewayInfo) mainSteam() {
|
||||||
case *steam.ConnectedEvent:
|
case *steam.ConnectedEvent:
|
||||||
// Connected on server
|
// Connected on server
|
||||||
g.SteamConnecting = false
|
g.SteamConnecting = false
|
||||||
logger.Debug.Printf("[%s] Connected on Steam serveur", g.XMPP_JID_Client)
|
log.Printf("%sConnected on Steam serveur", LogSteamDebug)
|
||||||
g.SteamClient.Auth.LogOn(g.SteamLoginInfo)
|
g.SteamClient.Auth.LogOn(g.SteamLoginInfo)
|
||||||
|
|
||||||
case *steam.MachineAuthUpdateEvent:
|
case *steam.MachineAuthUpdateEvent:
|
||||||
|
|
@ -65,45 +65,27 @@ func (g *GatewayInfo) mainSteam() {
|
||||||
g.SendSteamPresence(steamlang.EPersonaState_Online)
|
g.SendSteamPresence(steamlang.EPersonaState_Online)
|
||||||
g.SendXmppMessage(XmppJidComponent, "", "Connected on Steam network")
|
g.SendXmppMessage(XmppJidComponent, "", "Connected on Steam network")
|
||||||
|
|
||||||
case *steam.LoggedOffEvent:
|
|
||||||
logger.Error.Printf("[%s] LoggedOffEvent: %v", g.XMPP_JID_Client, e)
|
|
||||||
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Disconnected of Steam network (%v)", e))
|
|
||||||
g.SteamConnecting = false
|
|
||||||
|
|
||||||
case steam.FatalErrorEvent:
|
case steam.FatalErrorEvent:
|
||||||
logger.Error.Printf("[%s] FatalError: %v", g.XMPP_JID_Client, e)
|
log.Printf("%sFatalError: ", LogSteamError, e)
|
||||||
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Steam Fatal Error : %v", e))
|
g.SendXmppMessage(XmppJidComponent, "", "Steam Fatal Error : "+e.Error())
|
||||||
g.DisconnectAllSteamFriend()
|
g.DisconnectAllSteamFriend()
|
||||||
g.SteamConnecting = false
|
return
|
||||||
|
|
||||||
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:
|
case error:
|
||||||
logger.Error.Printf("[%s] error: %v", g.XMPP_JID_Client, e)
|
log.Printf("%s", LogSteamError, e)
|
||||||
g.SendXmppMessage(XmppJidComponent, "", "Steam Error : "+e.Error())
|
g.SendXmppMessage(XmppJidComponent, "", "Steam Error : "+e.Error())
|
||||||
|
|
||||||
case *steam.LogOnFailedEvent:
|
|
||||||
logger.Error.Printf("[%s] Login failed: %v", g.XMPP_JID_Client, e)
|
|
||||||
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Login failed : %v", e.Result))
|
|
||||||
g.SteamConnecting = false
|
|
||||||
|
|
||||||
case *steam.ClientCMListEvent:
|
case *steam.ClientCMListEvent:
|
||||||
// Doing nothing with server list
|
// 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:
|
case *steam.PersonaStateEvent:
|
||||||
logger.Debug.Printf("[%s] Received PersonaStateEvent: %v", g.XMPP_JID_Client, e)
|
|
||||||
// Presenc received
|
// 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()
|
steamId := e.FriendId.ToString()
|
||||||
name := e.Name
|
name := e.Name
|
||||||
gameName := e.GameName
|
gameName := e.GameName
|
||||||
|
|
@ -127,42 +109,24 @@ func (g *GatewayInfo) mainSteam() {
|
||||||
status = Status_extended_away
|
status = Status_extended_away
|
||||||
tpye = Type_available
|
tpye = Type_available
|
||||||
}
|
}
|
||||||
steamFriendId := g.GetFriendSteamId(steamId)
|
if _, ok := g.FriendSteamId[steamId]; !ok {
|
||||||
if steamFriendId == nil {
|
|
||||||
// Send subscribsion
|
// Send subscribsion
|
||||||
g.SendXmppPresence(status, Type_subscribe, "", steamId+"@"+XmppJidComponent, gameName, name)
|
g.SendXmppPresence(status, Type_subscribe, "", steamId+"@"+XmppJidComponent, gameName, name)
|
||||||
g.SetFriendSteamId(steamId, &StatusSteamFriend{XMPP_Status: status, XMPP_Type: tpye})
|
g.FriendSteamId[steamId] = &StatusSteamFriend{XMPP_Status: status, XMPP_Type: tpye}
|
||||||
} else {
|
} else {
|
||||||
steamFriendId.XMPP_Status = status
|
g.FriendSteamId[steamId].XMPP_Status = status
|
||||||
steamFriendId.XMPP_Type = tpye
|
g.FriendSteamId[steamId].XMPP_Type = tpye
|
||||||
steamFriendId.SteamGameName = gameName
|
g.FriendSteamId[steamId].SteamGameName = gameName
|
||||||
steamFriendId.SteamName = name
|
g.FriendSteamId[steamId].SteamName = name
|
||||||
}
|
}
|
||||||
g.SendXmppPresence(status, tpye, "", steamId+"@"+XmppJidComponent, gameName, name)
|
g.SendXmppPresence(status, tpye, "", steamId+"@"+XmppJidComponent, gameName, name)
|
||||||
|
|
||||||
case *steam.ChatMsgEvent:
|
case *steam.ChatMsgEvent:
|
||||||
logger.Debug.Printf("[%s] Received ChatMsgEvent: %v", g.XMPP_JID_Client, e)
|
|
||||||
// Message received
|
// Message received
|
||||||
from := e.ChatterId.ToString() + "@" + XmppJidComponent
|
g.SendXmppMessage(e.ChatterId.ToString()+"@"+XmppJidComponent, "", e.Message)
|
||||||
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:
|
default:
|
||||||
logger.Debug.Printf("[%s] Steam unmatch event (Type: %T): %v", g.XMPP_JID_Client, e, e)
|
log.Printf("%s", LogSteamDebug, e)
|
||||||
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Steam unmatch event (Type: %T): %v", e, e))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -178,7 +142,7 @@ func (g *GatewayInfo) setLoginInfos() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
g.SteamLoginInfo.SentryFileHash = sentryHash
|
g.SteamLoginInfo.SentryFileHash = sentryHash
|
||||||
}
|
}
|
||||||
logger.Debug.Printf("Authentification of (%s, %s)", g.XMPP_JID_Client, g.SteamLoginInfo.Username)
|
log.Printf("%sAuthentification of (%s, %s)", LogSteamDebug, g.XMPP_JID_Client, g.SteamLoginInfo.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) IsSteamConnected() bool {
|
func (g *GatewayInfo) IsSteamConnected() bool {
|
||||||
|
|
@ -189,36 +153,43 @@ func (g *GatewayInfo) IsSteamConnected() bool {
|
||||||
ret = g.SteamClient.Connected()
|
ret = g.SteamClient.Connected()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Debug.Printf("[%s] Is Steam connected (Connected: %v)", g.XMPP_JID_Client, ret)
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) SteamConnect() {
|
func (g *GatewayInfo) SteamConnect() {
|
||||||
if g.IsSteamConnected() {
|
if g.IsSteamConnected() {
|
||||||
logger.Debug.Printf("[%s] Try to connect, but already connected", g.XMPP_JID_Client)
|
log.Printf("%sTry to connect, but already connected", LogSteamDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if g.SteamConnecting {
|
if g.SteamConnecting {
|
||||||
logger.Debug.Printf("[%s] Try to connect, but currently connecting…", g.XMPP_JID_Client)
|
log.Printf("%sTry to connect, but currently connecting…", LogSteamDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
g.SteamConnecting = true
|
g.SteamConnecting = true
|
||||||
go func() {
|
b, err := ioutil.ReadFile(serverAddrs)
|
||||||
logger.Info.Printf("[%s] Connecting...", g.XMPP_JID_Client)
|
if err == nil {
|
||||||
g.SendXmppMessage(XmppJidComponent, "", "Connecting...")
|
var toList steam.ClientCMListEvent
|
||||||
addr := g.SteamClient.Connect()
|
err := json.Unmarshal(b, &toList)
|
||||||
logger.Info.Printf("[%s] Connected on %v", g.XMPP_JID_Client, addr)
|
if err != nil {
|
||||||
g.SendXmppMessage(XmppJidComponent, "", fmt.Sprintf("Connected on %v", addr))
|
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() {
|
func (g *GatewayInfo) SteamDisconnect() {
|
||||||
if !g.IsSteamConnected() {
|
if !g.IsSteamConnected() {
|
||||||
logger.Debug.Printf("[%s] Try to disconnect, but already disconnected", g.XMPP_JID_Client)
|
log.Printf("%sTry to disconnect, but already disconnected", LogSteamDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Info.Printf("[%s] Steam disconnect", g.XMPP_JID_Client)
|
log.Printf("%sSteam disconnect", LogSteamInfo)
|
||||||
|
|
||||||
g.XMPP_Disconnect()
|
g.XMPP_Disconnect()
|
||||||
g.DisconnectAllSteamFriend()
|
g.DisconnectAllSteamFriend()
|
||||||
|
|
@ -226,45 +197,30 @@ func (g *GatewayInfo) SteamDisconnect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) DisconnectAllSteamFriend() {
|
func (g *GatewayInfo) DisconnectAllSteamFriend() {
|
||||||
logger.Debug.Printf("[%s] Disconnect all Steam friend", g.XMPP_JID_Client)
|
for sid, _ := range g.FriendSteamId {
|
||||||
for _, sid := range g.GetAllFriendSteamId() {
|
|
||||||
g.SendXmppPresence(Status_offline, Type_unavailable, "", sid+"@"+XmppJidComponent, "", "")
|
g.SendXmppPresence(Status_offline, Type_unavailable, "", sid+"@"+XmppJidComponent, "", "")
|
||||||
g.RemoveFriendSteamId(sid)
|
delete(g.FriendSteamId, sid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) SendSteamMessage(steamId, message string) {
|
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() {
|
if !g.IsSteamConnected() {
|
||||||
logger.Debug.Printf("[%s] Try to send message, but disconnected", g.XMPP_JID_Client)
|
log.Printf("%sTry to send message, but disconnected", LogSteamDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
steamIdUint64, err := strconv.ParseUint(steamId, 10, 64)
|
steamIdUint64, err := strconv.ParseUint(steamId, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
logger.Debug.Printf("[%s] Send message to %v", g.XMPP_JID_Client, steamIdUint64)
|
g.SteamClient.Social.SendMessage(steamid.SteamId(steamIdUint64), steamlang.EChatEntryType_ChatMsg, message)
|
||||||
g.SteamClient.Social.SendMessage(steamid.SteamId(steamIdUint64), chatEntryType, message)
|
|
||||||
} else {
|
} else {
|
||||||
logger.Error.Printf("[%s] Failed to get SteamId from %s", g.XMPP_JID_Client, steamId)
|
log.Printf("%sFailed to get SteamId from %s", LogSteamError, steamId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) SendSteamPresence(status steamlang.EPersonaState) {
|
func (g *GatewayInfo) SendSteamPresence(status steamlang.EPersonaState) {
|
||||||
if !g.IsSteamConnected() {
|
if !g.IsSteamConnected() {
|
||||||
logger.Debug.Printf("[%s] Try to send presence, but disconnected", g.XMPP_JID_Client)
|
log.Printf("%sTry to send presence, but disconnected", LogSteamDebug)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Debug.Printf("[%s] Send presence (Status: %v)", g.XMPP_JID_Client, status)
|
|
||||||
g.SteamClient.Social.SetPersonaState(status)
|
g.SteamClient.Social.SetPersonaState(status)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
251
gateway/xmpp.go
251
gateway/xmpp.go
|
|
@ -2,12 +2,10 @@ package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
"github.com/Philipp15b/go-steam/protocol/steamlang"
|
"github.com/Philipp15b/go-steam/protocol/steamlang"
|
||||||
|
|
||||||
"strconv"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -30,20 +28,16 @@ const (
|
||||||
ActionConnexion = "action_xmpp_connexion"
|
ActionConnexion = "action_xmpp_connexion"
|
||||||
ActionDeconnexion = "action_xmpp_deconnexion"
|
ActionDeconnexion = "action_xmpp_deconnexion"
|
||||||
ActionMainMethodEnded = "action_xmpp_main_method_ended"
|
ActionMainMethodEnded = "action_xmpp_main_method_ended"
|
||||||
|
|
||||||
|
LogXmppInfo = "\t[XMPP INFO]\t"
|
||||||
|
LogXmppError = "\t[XMPP ERROR]\t"
|
||||||
|
LogXmppDebug = "\t[XMPP DEBUG]\t"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
XmppJidComponent = ""
|
XmppJidComponent = ""
|
||||||
|
|
||||||
iqId = uint64(0)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NextIqId() string {
|
|
||||||
iqId += 1
|
|
||||||
ret := strconv.FormatUint(iqId, 10)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) ReceivedXMPP_Presence(presence *xmpp.Presence) {
|
func (g *GatewayInfo) ReceivedXMPP_Presence(presence *xmpp.Presence) {
|
||||||
if presence.Type == Type_error {
|
if presence.Type == Type_error {
|
||||||
return
|
return
|
||||||
|
|
@ -56,14 +50,14 @@ func (g *GatewayInfo) ReceivedXMPP_Presence(presence *xmpp.Presence) {
|
||||||
if len(jid) == 2 {
|
if len(jid) == 2 {
|
||||||
// Resource exist —> client speaking
|
// Resource exist —> client speaking
|
||||||
if presence.Type == Type_available {
|
if presence.Type == Type_available {
|
||||||
g.SetXmppConnectedClient(presence.From)
|
g.XMPP_Connected_Client[presence.From] = true
|
||||||
} else if presence.Type == Type_unavailable {
|
} else if presence.Type == Type_unavailable {
|
||||||
g.RemoveXmppConnectedClient(presence.From)
|
delete(g.XMPP_Connected_Client, presence.From)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if presence.Type == Type_probe {
|
if presence.Type == Type_probe {
|
||||||
steamFriendStatus := g.GetFriendSteamId(steamJid[0])
|
steamFriendStatus := g.FriendSteamId[steamJid[0]]
|
||||||
if steamFriendStatus != nil {
|
if steamFriendStatus != nil {
|
||||||
g.SendXmppPresence(steamFriendStatus.XMPP_Status, steamFriendStatus.XMPP_Type, "", steamJid[0]+"@"+XmppJidComponent, steamFriendStatus.SteamGameName, steamFriendStatus.SteamName)
|
g.SendXmppPresence(steamFriendStatus.XMPP_Status, steamFriendStatus.XMPP_Type, "", steamJid[0]+"@"+XmppJidComponent, steamFriendStatus.SteamGameName, steamFriendStatus.SteamName)
|
||||||
}
|
}
|
||||||
|
|
@ -79,13 +73,22 @@ func (g *GatewayInfo) ReceivedXMPP_Presence(presence *xmpp.Presence) {
|
||||||
// Destination is gateway itself
|
// Destination is gateway itself
|
||||||
if presence.Type == Type_unavailable {
|
if presence.Type == Type_unavailable {
|
||||||
// Disconnect
|
// Disconnect
|
||||||
if g.GetLenXmppConnectedClient() <= 0 {
|
if len(g.XMPP_Connected_Client) <= 0 {
|
||||||
g.Disconnect()
|
g.Disconnect()
|
||||||
}
|
}
|
||||||
} else {
|
} else if presence.Type == Type_available {
|
||||||
if presence.Type == Type_available {
|
go g.SteamConnect()
|
||||||
g.addUserIntoRoster(presence.To, "xmpp4steam gateway")
|
transfertPresence = true
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Destination is Steam user
|
||||||
|
if presence.Type == Type_unavailable {
|
||||||
|
// Disconnect
|
||||||
|
if len(g.XMPP_Connected_Client) <= 0 {
|
||||||
|
g.Disconnect()
|
||||||
}
|
}
|
||||||
|
} else if presence.Type == Type_available {
|
||||||
go g.SteamConnect()
|
go g.SteamConnect()
|
||||||
transfertPresence = true
|
transfertPresence = true
|
||||||
}
|
}
|
||||||
|
|
@ -114,73 +117,14 @@ func (g *GatewayInfo) ReceivedXMPP_Presence(presence *xmpp.Presence) {
|
||||||
|
|
||||||
if g.IsSteamConnected() {
|
if g.IsSteamConnected() {
|
||||||
g.SendSteamPresence(steamStatus)
|
g.SendSteamPresence(steamStatus)
|
||||||
g.SendXmppPresence(presence.Show, presence.Type, "", "", presence.Status, "")
|
g.SendXmppPresence(presence.Show, presence.Type, presence.From, "", presence.Status, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) ReceivedXMPP_Message(message *xmpp.Message) {
|
func (g *GatewayInfo) ReceivedXMPP_Message(message *xmpp.Message) {
|
||||||
steamID := strings.SplitN(message.To, "@", 2)[0]
|
steamID := strings.SplitN(message.To, "@", 2)[0]
|
||||||
if message.Composing != nil {
|
g.SendSteamMessage(steamID, message.Body)
|
||||||
g.SendSteamMessageComposing(steamID)
|
|
||||||
} else if message.Paused != nil {
|
|
||||||
return
|
|
||||||
} else if message.Inactive != nil {
|
|
||||||
return
|
|
||||||
} else if message.Gone != nil {
|
|
||||||
g.SendSteamMessageLeaveConversation(steamID)
|
|
||||||
} else {
|
|
||||||
if message.Body != nil && len(message.Body) != 0 {
|
|
||||||
g.SendSteamMessage(steamID, message.Body[0].Value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) ReceivedXMPP_IQ(iq *xmpp.IQ) bool {
|
|
||||||
ret := false
|
|
||||||
remoteRosterRequestValue := g.GetXmppRemoteRosterRequest(iq.ID)
|
|
||||||
if remoteRosterRequestValue == RemoteRosterRequestPermission {
|
|
||||||
g.RemoveXmppRemoteRosterRequest(iq.ID)
|
|
||||||
|
|
||||||
if iq.Type == xmpp.IQTypeError && iq.Error.Condition() == xmpp.ErrorForbidden {
|
|
||||||
g.AllowEditRoster = false
|
|
||||||
logger.Info.Printf("Set allow roster edition to %v", g.AllowEditRoster)
|
|
||||||
} else if iq.Type == xmpp.IQTypeSet && iq.PayloadName().Space == xmpp.NSRemoteRosterManager {
|
|
||||||
remoteRosterQuery := &xmpp.RemoteRosterManagerQuery{}
|
|
||||||
iq.PayloadDecode(remoteRosterQuery)
|
|
||||||
if remoteRosterQuery.Type == xmpp.RemoteRosterManagerTypeAllowed {
|
|
||||||
g.AllowEditRoster = true
|
|
||||||
} else if remoteRosterQuery.Type == xmpp.RemoteRosterManagerTypeRejected {
|
|
||||||
g.AllowEditRoster = false
|
|
||||||
} else {
|
|
||||||
g.AllowEditRoster = false
|
|
||||||
}
|
|
||||||
logger.Info.Printf("Set allow roster edition to %v", g.AllowEditRoster)
|
|
||||||
g.SendXmppMessage(XmppJidComponent, "", "Set allow roster edition to "+strconv.FormatBool(g.AllowEditRoster))
|
|
||||||
} else {
|
|
||||||
logger.Info.Printf("Check roster edition authorisation by querying roster's user")
|
|
||||||
// Remote roster namespace may not be supported (like prosody), so we send a roster query
|
|
||||||
iqId := NextIqId()
|
|
||||||
g.SetXmppRemoteRosterRequest(iqId, RemoteRosterRequestRoster)
|
|
||||||
iqSend := &xmpp.IQ{ID: iqId, Type: xmpp.IQTypeGet, From: iq.To, To: iq.From}
|
|
||||||
iqSend.PayloadEncode(&xmpp.RosterQuery{})
|
|
||||||
g.XMPP_Out <- iqSend
|
|
||||||
}
|
|
||||||
ret = true
|
|
||||||
|
|
||||||
} else if remoteRosterRequestValue == RemoteRosterRequestRoster {
|
|
||||||
g.RemoveXmppRemoteRosterRequest(iq.ID)
|
|
||||||
if iq.Type == xmpp.IQTypeResult && iq.PayloadName().Space == xmpp.NSRoster {
|
|
||||||
g.AllowEditRoster = true
|
|
||||||
} else {
|
|
||||||
g.AllowEditRoster = false
|
|
||||||
}
|
|
||||||
logger.Info.Printf("Set allow roster edition to %v", g.AllowEditRoster)
|
|
||||||
g.SendXmppMessage(XmppJidComponent, "", "Set allow roster edition to "+strconv.FormatBool(g.AllowEditRoster))
|
|
||||||
ret = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) XMPP_Disconnect() {
|
func (g *GatewayInfo) XMPP_Disconnect() {
|
||||||
|
|
@ -208,164 +152,25 @@ func (g *GatewayInfo) SendXmppPresence(status, tpye, to, from, message, nick str
|
||||||
p.To = to
|
p.To = to
|
||||||
}
|
}
|
||||||
if from == "" {
|
if from == "" {
|
||||||
|
// TODO add an option to allow message comming directly from the gateway
|
||||||
p.From = XmppJidComponent + "/" + resource
|
p.From = XmppJidComponent + "/" + resource
|
||||||
} else {
|
} else {
|
||||||
p.From = from + "/" + resource
|
p.From = from + "/" + resource
|
||||||
}
|
}
|
||||||
|
|
||||||
if tpye == Type_subscribe && g.AllowEditRoster {
|
log.Printf("%sSend presence %v", LogXmppInfo, p)
|
||||||
g.addUserIntoRoster(from, nick)
|
g.XMPP_Out <- p
|
||||||
} else {
|
|
||||||
logger.Info.Printf("Send presence %v", p)
|
|
||||||
g.XMPP_Out <- p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) addUserIntoRoster(jid, nick string) {
|
|
||||||
iq := xmpp.IQ{To: g.XMPP_JID_Client, Type: xmpp.IQTypeSet, ID: NextIqId()}
|
|
||||||
query := &xmpp.RosterQuery{}
|
|
||||||
queryItem := &xmpp.RosterItem{JID: jid, Name: nick, Subscription: xmpp.RosterSubscriptionBoth}
|
|
||||||
queryItem.Groupes = append(queryItem.Groupes, XmppGroupUser)
|
|
||||||
query.Items = append(query.Items, *queryItem)
|
|
||||||
iq.PayloadEncode(query)
|
|
||||||
logger.Info.Printf("Add user into roster %v", iq)
|
|
||||||
g.XMPP_Out <- iq
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) removeAllUserFromRoster() {
|
|
||||||
// Friends
|
|
||||||
for steamId := range g.SteamClient.Social.Friends.GetCopy() {
|
|
||||||
iq := xmpp.IQ{To: g.XMPP_JID_Client, Type: xmpp.IQTypeSet, ID: NextIqId()}
|
|
||||||
query := &xmpp.RosterQuery{}
|
|
||||||
query.Items = append(query.Items, *&xmpp.RosterItem{JID: steamId.ToString() + "@" + XmppJidComponent, Subscription: xmpp.RosterSubscriptionRemove})
|
|
||||||
iq.PayloadEncode(query)
|
|
||||||
logger.Info.Printf("Remove steam user roster")
|
|
||||||
g.XMPP_Out <- iq
|
|
||||||
}
|
|
||||||
// Myself
|
|
||||||
iq := xmpp.IQ{To: g.XMPP_JID_Client, Type: xmpp.IQTypeSet, ID: NextIqId()}
|
|
||||||
query := &xmpp.RosterQuery{}
|
|
||||||
query.Items = append(query.Items, *&xmpp.RosterItem{JID: g.SteamClient.SteamId().ToString() + "@" + XmppJidComponent, Subscription: xmpp.RosterSubscriptionRemove})
|
|
||||||
iq.PayloadEncode(query)
|
|
||||||
logger.Info.Printf("Remove steam user roster")
|
|
||||||
g.XMPP_Out <- iq
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GatewayInfo) SendXmppMessage(from, subject, message string) {
|
func (g *GatewayInfo) SendXmppMessage(from, subject, message string) {
|
||||||
g.sendXmppMessage(from, subject, message, &xmpp.Active{})
|
|
||||||
g.ChatstateNotificationData <- from
|
|
||||||
g.ChatstateNotificationData <- "stop"
|
|
||||||
g.ChatstateNotificationData <- from
|
|
||||||
g.ChatstateNotificationData <- "inactive"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) SendXmppMessageLeaveConversation(from string) {
|
|
||||||
g.sendXmppMessage(from, "", "", &xmpp.Gone{})
|
|
||||||
g.ChatstateNotificationData <- from
|
|
||||||
g.ChatstateNotificationData <- "stop"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) SendXmppMessageComposing(from string) {
|
|
||||||
g.sendXmppMessage(from, "", "", &xmpp.Composing{})
|
|
||||||
g.ChatstateNotificationData <- from
|
|
||||||
g.ChatstateNotificationData <- "paused"
|
|
||||||
g.ChatstateNotificationData <- from
|
|
||||||
g.ChatstateNotificationData <- "inactive"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) chatstatesNotification() {
|
|
||||||
inactiveTimers := make(map[string]*time.Timer)
|
|
||||||
pausedTimers := make(map[string]*time.Timer)
|
|
||||||
g.ChatstateNotificationData = make(chan string)
|
|
||||||
|
|
||||||
for {
|
|
||||||
jid := <-g.ChatstateNotificationData
|
|
||||||
chatstate := <-g.ChatstateNotificationData
|
|
||||||
|
|
||||||
timerInactive, okInactive := inactiveTimers[jid]
|
|
||||||
timerPaused, okPaused := pausedTimers[jid]
|
|
||||||
|
|
||||||
switch chatstate {
|
|
||||||
case "stop":
|
|
||||||
if okInactive {
|
|
||||||
if timerInactive != nil {
|
|
||||||
if !timerInactive.Stop() {
|
|
||||||
<-timerInactive.C
|
|
||||||
}
|
|
||||||
delete(inactiveTimers, jid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if okPaused {
|
|
||||||
if timerPaused != nil {
|
|
||||||
if !timerPaused.Stop() {
|
|
||||||
<-timerPaused.C
|
|
||||||
}
|
|
||||||
delete(pausedTimers, jid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case "paused":
|
|
||||||
if okInactive {
|
|
||||||
if timerPaused != nil {
|
|
||||||
if !timerPaused.Stop() {
|
|
||||||
<-timerPaused.C
|
|
||||||
}
|
|
||||||
timerPaused.Reset(20 * time.Second)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
timerPaused = time.AfterFunc(20*time.Second, func() {
|
|
||||||
g.sendXmppMessage(jid, "", "", &xmpp.Paused{})
|
|
||||||
delete(pausedTimers, jid)
|
|
||||||
})
|
|
||||||
pausedTimers[jid] = timerPaused
|
|
||||||
}
|
|
||||||
|
|
||||||
case "inactive":
|
|
||||||
if okInactive {
|
|
||||||
if timerInactive != nil {
|
|
||||||
if !timerInactive.Stop() {
|
|
||||||
<-timerInactive.C
|
|
||||||
}
|
|
||||||
timerInactive.Reset(120 * time.Second)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
timerInactive = time.AfterFunc(120*time.Second, func() {
|
|
||||||
g.sendXmppMessage(jid, "", "", &xmpp.Inactive{})
|
|
||||||
delete(inactiveTimers, jid)
|
|
||||||
})
|
|
||||||
inactiveTimers[jid] = timerInactive
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GatewayInfo) sendXmppMessage(from, subject, message string, chatState interface{}) {
|
|
||||||
if from != XmppJidComponent || from == XmppJidComponent && g.DebugMessage {
|
if from != XmppJidComponent || from == XmppJidComponent && g.DebugMessage {
|
||||||
m := xmpp.Message{To: g.XMPP_JID_Client, From: from, Type: "chat"}
|
m := xmpp.Message{To: g.XMPP_JID_Client, From: from, Body: message, Type: "chat"}
|
||||||
mBody := xmpp.MessageBody{Value: message}
|
|
||||||
m.Body = append(m.Body, mBody)
|
|
||||||
|
|
||||||
if subject != "" {
|
if subject != "" {
|
||||||
m.Subject = subject
|
m.Subject = subject
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v := chatState.(type) {
|
log.Printf("%sSend message %v", LogXmppInfo, m)
|
||||||
case *xmpp.Active:
|
|
||||||
m.Active = v
|
|
||||||
case *xmpp.Composing:
|
|
||||||
m.Composing = v
|
|
||||||
case *xmpp.Paused:
|
|
||||||
m.Paused = v
|
|
||||||
case *xmpp.Inactive:
|
|
||||||
m.Inactive = v
|
|
||||||
case *xmpp.Gone:
|
|
||||||
m.Gone = v
|
|
||||||
default:
|
|
||||||
m.Active = &xmpp.Active{}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info.Printf("Send message %v", m)
|
|
||||||
g.XMPP_Out <- m
|
g.XMPP_Out <- m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package logger
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Info *log.Logger
|
|
||||||
Debug *log.Logger
|
|
||||||
Error *log.Logger
|
|
||||||
)
|
|
||||||
|
|
||||||
func Init(infoHandle io.Writer, warningHandle io.Writer, errorHandle io.Writer) {
|
|
||||||
Info = log.New(infoHandle, "INFO : ", log.Ldate|log.Ltime|log.Lshortfile)
|
|
||||||
Debug = log.New(warningHandle, "DEBUG : ", log.Ldate|log.Ltime|log.Lshortfile)
|
|
||||||
Error = log.New(errorHandle, "ERROR : ", log.Ldate|log.Ltime|log.Lshortfile)
|
|
||||||
}
|
|
||||||
40
main.go
40
main.go
|
|
@ -1,51 +1,49 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/configuration"
|
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/gateway"
|
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/gateway"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/xmpp"
|
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/xmpp"
|
||||||
|
|
||||||
|
"github.com/jimlawless/cfg"
|
||||||
|
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "v1.1"
|
Version = "v1.0"
|
||||||
|
configurationFilePath = "xmpp4steam.cfg"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
mapConfig = make(map[string]string)
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
logger.Init(os.Stdout, os.Stdout, os.Stderr)
|
|
||||||
configuration.Init()
|
|
||||||
logger.Info.Println("Running go-xmpp4steam " + Version)
|
|
||||||
xmpp.SoftVersion = Version
|
xmpp.SoftVersion = Version
|
||||||
|
err := cfg.Load(configurationFilePath, mapConfig)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Failed to load configuration file.", err)
|
||||||
|
}
|
||||||
|
|
||||||
// XMPP config
|
// XMPP config
|
||||||
xmpp.Addr = configuration.MapConfig["xmpp_server_address"] + ":" + configuration.MapConfig["xmpp_server_port"]
|
xmpp.Addr = mapConfig["xmpp_server_address"] + ":" + mapConfig["xmpp_server_port"]
|
||||||
xmpp.JidStr = configuration.MapConfig["xmpp_hostname"]
|
xmpp.JidStr = mapConfig["xmpp_hostname"]
|
||||||
xmpp.Secret = configuration.MapConfig["xmpp_secret"]
|
xmpp.Secret = mapConfig["xmpp_secret"]
|
||||||
xmpp.Debug = configuration.MapConfig["xmpp_debug"] == "true"
|
xmpp.Debug = mapConfig["xmpp_debug"] == "true"
|
||||||
if configuration.MapConfig["xmpp_group"] != "" {
|
|
||||||
gateway.XmppGroupUser = configuration.MapConfig["xmpp_group"]
|
|
||||||
}
|
|
||||||
gateway.XmppJidComponent = xmpp.JidStr
|
gateway.XmppJidComponent = xmpp.JidStr
|
||||||
|
|
||||||
for _, admin := range strings.Split(configuration.MapConfig["xmpp_admins"], ";") {
|
|
||||||
xmpp.AdminUsers[admin] = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
go xmpp.Run()
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
allDbUsers := database.GetAllLines()
|
allDbUsers := database.GetAllLines()
|
||||||
for _, dbUser := range allDbUsers {
|
for _, dbUser := range allDbUsers {
|
||||||
xmpp.AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug)
|
xmpp.AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug)
|
||||||
}
|
}
|
||||||
|
go xmpp.Run()
|
||||||
|
|
||||||
sigchan := make(chan os.Signal, 1)
|
sigchan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigchan, os.Interrupt)
|
signal.Notify(sigchan, os.Interrupt)
|
||||||
|
|
@ -55,6 +53,6 @@ func main() {
|
||||||
|
|
||||||
xmpp.Disconnect()
|
xmpp.Disconnect()
|
||||||
|
|
||||||
logger.Info.Println("Exit main()")
|
log.Println("Exit main()")
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"Addresses":[{"IP":"162.254.197.41","Port":27018},{"IP":"162.254.197.40","Port":27018},{"IP":"146.66.152.10","Port":27017},{"IP":"146.66.152.10","Port":27020},{"IP":"146.66.152.11","Port":27017},{"IP":"162.254.197.42","Port":27017},{"IP":"162.254.197.41","Port":27021},{"IP":"162.254.197.40","Port":27020},{"IP":"146.66.152.11","Port":27020},{"IP":"162.254.197.42","Port":27019},{"IP":"146.66.152.10","Port":27019},{"IP":"162.254.197.41","Port":27020},{"IP":"146.66.152.11","Port":27019},{"IP":"162.254.197.41","Port":27019},{"IP":"146.66.152.11","Port":27018},{"IP":"162.254.197.41","Port":27017},{"IP":"146.66.152.10","Port":27018},{"IP":"162.254.197.42","Port":27021},{"IP":"162.254.197.40","Port":27021},{"IP":"162.254.197.42","Port":27018},{"IP":"162.254.197.42","Port":27020},{"IP":"162.254.197.40","Port":27019},{"IP":"162.254.196.41","Port":27017},{"IP":"162.254.196.41","Port":27021},{"IP":"162.254.196.43","Port":27017},{"IP":"162.254.196.41","Port":27019},{"IP":"162.254.196.41","Port":27020},{"IP":"162.254.196.43","Port":27019},{"IP":"162.254.196.42","Port":27019},{"IP":"162.254.196.41","Port":27018},{"IP":"162.254.196.43","Port":27018},{"IP":"162.254.196.42","Port":27020},{"IP":"162.254.196.42","Port":27018},{"IP":"162.254.196.40","Port":27019},{"IP":"162.254.196.40","Port":27017},{"IP":"162.254.197.40","Port":27017},{"IP":"162.254.196.42","Port":27017},{"IP":"162.254.196.40","Port":27020},{"IP":"162.254.196.40","Port":27021},{"IP":"162.254.196.40","Port":27018},{"IP":"162.254.196.42","Port":27021},{"IP":"162.254.196.43","Port":27020},{"IP":"162.254.196.43","Port":27021},{"IP":"146.66.155.8","Port":27017},{"IP":"185.25.182.10","Port":27020},{"IP":"146.66.155.8","Port":27018},{"IP":"146.66.155.8","Port":27019},{"IP":"185.25.182.10","Port":27018},{"IP":"185.25.182.10","Port":27019},{"IP":"146.66.155.8","Port":27020},{"IP":"185.25.182.10","Port":27017},{"IP":"185.25.180.14","Port":27020},{"IP":"185.25.180.14","Port":27019},{"IP":"185.25.180.14","Port":27018},{"IP":"155.133.242.8","Port":27017},{"IP":"155.133.242.9","Port":27020},{"IP":"155.133.242.8","Port":27018},{"IP":"155.133.242.9","Port":27017},{"IP":"185.25.180.14","Port":27017},{"IP":"155.133.242.9","Port":27019},{"IP":"185.25.180.15","Port":27020},{"IP":"155.133.242.8","Port":27020},{"IP":"155.133.242.8","Port":27019},{"IP":"185.25.180.15","Port":27019},{"IP":"155.133.242.9","Port":27018},{"IP":"185.25.180.15","Port":27017},{"IP":"185.25.180.15","Port":27018},{"IP":"208.78.164.13","Port":27019},{"IP":"208.78.164.12","Port":27019},{"IP":"208.78.164.12","Port":27018},{"IP":"208.78.164.10","Port":27017},{"IP":"208.78.164.14","Port":27017},{"IP":"208.78.164.10","Port":27018},{"IP":"208.78.164.13","Port":27017},{"IP":"208.78.164.13","Port":27018},{"IP":"208.78.164.10","Port":27019},{"IP":"208.78.164.12","Port":27017},{"IP":"208.78.164.14","Port":27018},{"IP":"208.78.164.14","Port":27019},{"IP":"162.254.195.46","Port":27020}]}
|
{"Addresses":[{"IP":"146.66.152.11","Port":27020},{"IP":"162.254.197.42","Port":27020},{"IP":"146.66.152.10","Port":27020},{"IP":"146.66.152.10","Port":27017},{"IP":"162.254.197.40","Port":27018},{"IP":"146.66.152.10","Port":27018},{"IP":"162.254.197.40","Port":27019},{"IP":"162.254.197.41","Port":27017},{"IP":"162.254.197.41","Port":27020},{"IP":"162.254.197.40","Port":27020},{"IP":"146.66.152.10","Port":27019},{"IP":"162.254.197.42","Port":27019},{"IP":"162.254.197.41","Port":27021},{"IP":"162.254.197.42","Port":27018},{"IP":"162.254.197.42","Port":27017},{"IP":"162.254.197.42","Port":27021},{"IP":"162.254.197.41","Port":27019},{"IP":"162.254.197.41","Port":27018},{"IP":"162.254.196.40","Port":27020},{"IP":"146.66.152.11","Port":27018},{"IP":"162.254.197.40","Port":27021},{"IP":"162.254.196.43","Port":27019},{"IP":"162.254.196.43","Port":27018},{"IP":"162.254.196.42","Port":27021},{"IP":"146.66.152.11","Port":27017},{"IP":"162.254.196.41","Port":27018},{"IP":"162.254.196.41","Port":27019},{"IP":"162.254.196.42","Port":27017},{"IP":"162.254.196.43","Port":27021},{"IP":"162.254.196.40","Port":27018},{"IP":"162.254.196.40","Port":27017},{"IP":"162.254.196.42","Port":27020},{"IP":"162.254.196.41","Port":27020},{"IP":"162.254.196.41","Port":27021},{"IP":"162.254.196.41","Port":27017},{"IP":"162.254.196.42","Port":27018},{"IP":"162.254.197.40","Port":27017},{"IP":"162.254.196.40","Port":27019},{"IP":"146.66.152.11","Port":27019},{"IP":"162.254.196.43","Port":27017},{"IP":"162.254.196.43","Port":27020},{"IP":"162.254.196.40","Port":27021},{"IP":"162.254.196.42","Port":27019},{"IP":"146.66.155.8","Port":27020},{"IP":"155.133.242.9","Port":27019},{"IP":"146.66.155.8","Port":27019},{"IP":"155.133.242.8","Port":27020},{"IP":"185.25.180.15","Port":27020},{"IP":"155.133.242.8","Port":27018},{"IP":"146.66.155.8","Port":27017},{"IP":"185.25.182.10","Port":27020},{"IP":"185.25.182.10","Port":27017},{"IP":"185.25.182.10","Port":27018},{"IP":"185.25.182.10","Port":27019},{"IP":"155.133.242.8","Port":27019},{"IP":"155.133.242.9","Port":27020},{"IP":"185.25.180.14","Port":27019},{"IP":"146.66.155.8","Port":27018},{"IP":"185.25.180.14","Port":27020},{"IP":"185.25.180.15","Port":27018},{"IP":"185.25.180.14","Port":27017},{"IP":"155.133.242.9","Port":27018},{"IP":"185.25.180.15","Port":27019},{"IP":"185.25.180.14","Port":27018},{"IP":"155.133.242.9","Port":27017},{"IP":"155.133.242.8","Port":27017},{"IP":"185.25.180.15","Port":27017},{"IP":"208.78.164.11","Port":27018},{"IP":"208.78.164.14","Port":27018},{"IP":"208.78.164.13","Port":27019},{"IP":"208.78.164.11","Port":27019},{"IP":"208.78.164.9","Port":27019},{"IP":"208.78.164.13","Port":27018},{"IP":"208.78.164.12","Port":27019},{"IP":"208.78.164.13","Port":27017},{"IP":"208.78.164.9","Port":27017},{"IP":"208.78.164.10","Port":27018},{"IP":"208.78.164.14","Port":27017},{"IP":"208.78.164.12","Port":27018},{"IP":"208.78.164.10","Port":27019}]}
|
||||||
257
xmpp/commands.go
257
xmpp/commands.go
|
|
@ -3,11 +3,9 @@ package xmpp
|
||||||
import (
|
import (
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
|
|
||||||
"fmt"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -16,109 +14,47 @@ const (
|
||||||
CommandDisconnectSteam = "disconnectSteam"
|
CommandDisconnectSteam = "disconnectSteam"
|
||||||
CommandRemoveRegistration = "removeRegistration"
|
CommandRemoveRegistration = "removeRegistration"
|
||||||
CommandToggleDebugMode = "toggleDebugMode"
|
CommandToggleDebugMode = "toggleDebugMode"
|
||||||
CommandUptimeMode = "uptime"
|
|
||||||
CommandMessageBroadcast = "messageBroadcast"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ChanAuthCode = make(chan string)
|
ChanAuthCode = make(chan string)
|
||||||
identityGateway = &xmpp.DiscoIdentity{Category: "gateway", Type: "steam", Name: "Steam Gateway"}
|
|
||||||
identityClients = &xmpp.DiscoIdentity{Category: "client", Type: "pc", Name: "Steam client"}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func execDiscoCommand(iq *xmpp.IQ) {
|
func execDiscoCommand(iq *xmpp.Iq) {
|
||||||
logger.Info.Printf("Ad-Hoc Command")
|
log.Printf("%sDiscovery item iq received", LogInfo)
|
||||||
|
|
||||||
// Disco Ad-Hoc
|
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
reply := iq.Response(xmpp.IQTypeResult)
|
||||||
discoItem := &xmpp.DiscoItems{Node: xmpp.NodeAdHocCommand}
|
discoItem := &xmpp.DiscoItems{Node: xmpp.NodeAdHocCommand}
|
||||||
|
|
||||||
jidBareFrom := strings.SplitN(iq.From, "/", 2)[0]
|
jidBare := strings.SplitN(iq.From, "/", 2)[0]
|
||||||
jidBareTo := strings.SplitN(iq.To, "/", 2)[0]
|
dbUser := database.GetLine(jidBare)
|
||||||
dbUser := database.GetLine(jidBareFrom)
|
|
||||||
|
|
||||||
if jidBareTo == jid.Domain {
|
// Add available commands
|
||||||
// Ad-Hoc command only on gateway
|
if dbUser == nil {
|
||||||
// Add available commands
|
discoI := &xmpp.DiscoItem{JID: jid.Domain, Node: CommandGetIdentifiants, Name: "Steam registration"}
|
||||||
if dbUser == nil {
|
discoItem.Item = append(discoItem.Item, *discoI)
|
||||||
discoI := &xmpp.DiscoItem{JID: jid.Domain, Node: CommandGetIdentifiants, Name: "Steam registration"}
|
} else {
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
// Add only if user is registered
|
||||||
} else {
|
discoI := &xmpp.DiscoItem{JID: jid.Domain, Node: CommandAuthcode, Name: "Add Steam Auth Code"}
|
||||||
// Add only if user is registered
|
discoItem.Item = append(discoItem.Item, *discoI)
|
||||||
discoI := &xmpp.DiscoItem{JID: jid.Domain, Node: CommandAuthcode, Name: "Add Steam Auth Code"}
|
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandDisconnectSteam, Name: "Force Steam deconnexion"}
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
discoItem.Item = append(discoItem.Item, *discoI)
|
||||||
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandDisconnectSteam, Name: "Force Steam deconnexion"}
|
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandRemoveRegistration, Name: "Remove registration"}
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
discoItem.Item = append(discoItem.Item, *discoI)
|
||||||
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandRemoveRegistration, Name: "Remove registration"}
|
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandToggleDebugMode, Name: "Toggle debug mode"}
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
discoItem.Item = append(discoItem.Item, *discoI)
|
||||||
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandToggleDebugMode, Name: "Toggle debug mode"}
|
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
|
||||||
discoI = &xmpp.DiscoItem{JID: jid.Domain, Node: CommandUptimeMode, Name: "Uptime"}
|
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
|
||||||
}
|
|
||||||
|
|
||||||
if AdminUsers[jidBareFrom] {
|
|
||||||
discoI := &xmpp.DiscoItem{JID: jid.Domain, Node: CommandMessageBroadcast, Name: "Broadcast a message"}
|
|
||||||
discoItem.Item = append(discoItem.Item, *discoI)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.PayloadEncode(discoItem)
|
reply.PayloadEncode(discoItem)
|
||||||
comp.Out <- reply
|
comp.Out <- reply
|
||||||
}
|
}
|
||||||
|
|
||||||
func execDisco(iq *xmpp.IQ) {
|
func execCommandAdHoc(iq *xmpp.Iq) {
|
||||||
logger.Info.Printf("Disco Feature")
|
|
||||||
jidBareTo := strings.SplitN(iq.To, "/", 2)[0]
|
|
||||||
|
|
||||||
discoInfoReceived := &xmpp.DiscoItems{}
|
|
||||||
iq.PayloadDecode(discoInfoReceived)
|
|
||||||
|
|
||||||
switch iq.PayloadName().Space {
|
|
||||||
case xmpp.NSDiscoInfo:
|
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
|
||||||
|
|
||||||
discoInfo := &xmpp.DiscoInfo{}
|
|
||||||
if jidBareTo == jid.Domain {
|
|
||||||
// Only gateway
|
|
||||||
discoInfo.Identity = append(discoInfo.Identity, *identityGateway)
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NodeAdHocCommand})
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSJabberClient})
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSRegister})
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSPing})
|
|
||||||
} else {
|
|
||||||
// Only steam users
|
|
||||||
discoInfo.Identity = append(discoInfo.Identity, *identityClients)
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSChatStatesNotification})
|
|
||||||
}
|
|
||||||
// Both
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSDiscoInfo})
|
|
||||||
discoInfo.Feature = append(discoInfo.Feature, xmpp.DiscoFeature{Var: xmpp.NSDiscoItems})
|
|
||||||
|
|
||||||
reply.PayloadEncode(discoInfo)
|
|
||||||
comp.Out <- reply
|
|
||||||
|
|
||||||
case xmpp.NSDiscoItems:
|
|
||||||
if discoInfoReceived.Node == xmpp.NodeAdHocCommand {
|
|
||||||
// Ad-Hoc command
|
|
||||||
execDiscoCommand(iq)
|
|
||||||
} else {
|
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
|
||||||
discoItems := &xmpp.DiscoItems{}
|
|
||||||
reply.PayloadEncode(discoItems)
|
|
||||||
comp.Out <- reply
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func execCommandAdHoc(iq *xmpp.IQ) {
|
|
||||||
adHoc := &xmpp.AdHocCommand{}
|
adHoc := &xmpp.AdHocCommand{}
|
||||||
iq.PayloadDecode(adHoc)
|
iq.PayloadDecode(adHoc)
|
||||||
jidBareFrom := strings.SplitN(iq.From, "/", 2)[0]
|
|
||||||
|
|
||||||
if adHoc.SessionID == "" && adHoc.Action == xmpp.ActionAdHocExecute {
|
if adHoc.SessionID == "" && adHoc.Action == xmpp.ActionAdHocExecute {
|
||||||
// First step in the command
|
// First step in the command
|
||||||
logger.Info.Printf("Ad-Hoc command (Node : %s). First step.", adHoc.Node)
|
log.Printf("%sAd-Hoc command (Node : %s). First step.", LogInfo, adHoc.Node)
|
||||||
|
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
reply := iq.Response(xmpp.IQTypeResult)
|
||||||
cmd := &xmpp.AdHocCommand{Node: adHoc.Node, Status: xmpp.StatusAdHocExecute, SessionID: xmpp.SessionID()}
|
cmd := &xmpp.AdHocCommand{Node: adHoc.Node, Status: xmpp.StatusAdHocExecute, SessionID: xmpp.SessionID()}
|
||||||
|
|
@ -132,17 +68,24 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
|
|
||||||
} else if adHoc.Node == CommandGetIdentifiants {
|
} else if adHoc.Node == CommandGetIdentifiants {
|
||||||
// Command Auth Code
|
// Command Auth Code
|
||||||
cmdXForm := getXFormRegistration("")
|
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocForm, Title: "Steam Account Info", Instructions: "Please provide your Steam login and password."}
|
||||||
cmd.XForm = *cmdXForm
|
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo, Value: "Please, be aware that the given Steam account information will be saved into an un-encrypted SQLite database."}
|
||||||
|
|
||||||
|
field := &xmpp.AdHocField{Var: "login", Label: "Steam Login", Type: xmpp.TypeAdHocFieldTextSingle}
|
||||||
|
cmdXForm.Fields = append(cmdXForm.Fields, *field)
|
||||||
|
field = &xmpp.AdHocField{Var: "password", Label: "Steam Password", Type: xmpp.TypeAdHocFieldTextPrivate}
|
||||||
|
cmdXForm.Fields = append(cmdXForm.Fields, *field)
|
||||||
|
|
||||||
|
cmd.XForm = *cmdXForm
|
||||||
|
cmd.Note = *note
|
||||||
} else if adHoc.Node == CommandDisconnectSteam {
|
} else if adHoc.Node == CommandDisconnectSteam {
|
||||||
// Command steam deconnection
|
|
||||||
cmd.Status = xmpp.StatusAdHocCompleted
|
cmd.Status = xmpp.StatusAdHocCompleted
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Force Steam deconnexion"}
|
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Force Steam deconnexion"}
|
||||||
cmd.XForm = *cmdXForm
|
cmd.XForm = *cmdXForm
|
||||||
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
||||||
|
|
||||||
g := MapGatewayInfo[jidBareFrom]
|
jidBare := strings.SplitN(iq.From, "/", 2)[0]
|
||||||
|
g := MapGatewayInfo[jidBare]
|
||||||
if g != nil {
|
if g != nil {
|
||||||
g.Disconnect()
|
g.Disconnect()
|
||||||
note.Value = "Send deconnexion on Steam network"
|
note.Value = "Send deconnexion on Steam network"
|
||||||
|
|
@ -151,13 +94,13 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
}
|
}
|
||||||
cmd.Note = *note
|
cmd.Note = *note
|
||||||
} else if adHoc.Node == CommandRemoveRegistration {
|
} else if adHoc.Node == CommandRemoveRegistration {
|
||||||
// Command remove registration
|
|
||||||
cmd.Status = xmpp.StatusAdHocCompleted
|
cmd.Status = xmpp.StatusAdHocCompleted
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Remove registration"}
|
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Remove registration"}
|
||||||
cmd.XForm = *cmdXForm
|
cmd.XForm = *cmdXForm
|
||||||
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
||||||
|
|
||||||
if RemoveUser(jidBareFrom) {
|
jidBare := strings.SplitN(iq.From, "/", 2)[0]
|
||||||
|
if RemoveUser(jidBare) {
|
||||||
note.Value = "Remove registration success."
|
note.Value = "Remove registration success."
|
||||||
} else {
|
} else {
|
||||||
note.Value = "Failed to remove your registration."
|
note.Value = "Failed to remove your registration."
|
||||||
|
|
@ -165,16 +108,16 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
|
|
||||||
cmd.Note = *note
|
cmd.Note = *note
|
||||||
} else if adHoc.Node == CommandToggleDebugMode {
|
} else if adHoc.Node == CommandToggleDebugMode {
|
||||||
// Command toggle debug mode
|
|
||||||
cmd.Status = xmpp.StatusAdHocCompleted
|
cmd.Status = xmpp.StatusAdHocCompleted
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Toggle debug mode"}
|
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Toggle debug mode"}
|
||||||
cmd.XForm = *cmdXForm
|
cmd.XForm = *cmdXForm
|
||||||
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
||||||
|
|
||||||
dbUser := database.GetLine(jidBareFrom)
|
jidBare := strings.SplitN(iq.From, "/", 2)[0]
|
||||||
|
dbUser := database.GetLine(jidBare)
|
||||||
if dbUser != nil {
|
if dbUser != nil {
|
||||||
dbUser.Debug = !dbUser.Debug
|
dbUser.Debug = !dbUser.Debug
|
||||||
g := MapGatewayInfo[jidBareFrom]
|
g := MapGatewayInfo[jidBare]
|
||||||
ok := dbUser.UpdateLine()
|
ok := dbUser.UpdateLine()
|
||||||
if ok && g != nil {
|
if ok && g != nil {
|
||||||
g.DebugMessage = dbUser.Debug
|
g.DebugMessage = dbUser.Debug
|
||||||
|
|
@ -191,29 +134,12 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Note = *note
|
cmd.Note = *note
|
||||||
} else if adHoc.Node == CommandUptimeMode {
|
|
||||||
// Command get uptime
|
|
||||||
cmd.Status = xmpp.StatusAdHocCompleted
|
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Uptime"}
|
|
||||||
cmd.XForm = *cmdXForm
|
|
||||||
deltaT := time.Since(startTime)
|
|
||||||
val := fmt.Sprintf("%dj %dh %dm %ds", int64(deltaT.Hours()/24), int64(deltaT.Hours())%24, int64(deltaT.Minutes())%60, int64(deltaT.Seconds())%60)
|
|
||||||
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo, Value: val}
|
|
||||||
|
|
||||||
cmd.Note = *note
|
|
||||||
} else if adHoc.Node == CommandMessageBroadcast && AdminUsers[jidBareFrom] {
|
|
||||||
// Command send broadcast message
|
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocForm, Title: "Broadcast a message", Instructions: "Message to broadcast to all user."}
|
|
||||||
|
|
||||||
field := &xmpp.AdHocField{Var: "message", Label: "Message", Type: xmpp.TypeAdHocFieldTextSingle}
|
|
||||||
cmdXForm.Fields = append(cmdXForm.Fields, *field)
|
|
||||||
cmd.XForm = *cmdXForm
|
|
||||||
}
|
}
|
||||||
reply.PayloadEncode(cmd)
|
reply.PayloadEncode(cmd)
|
||||||
comp.Out <- reply
|
comp.Out <- reply
|
||||||
} else if adHoc.Action == xmpp.ActionAdHocExecute || adHoc.Action == xmpp.ActionAdHocNext {
|
} else if adHoc.Action == xmpp.ActionAdHocExecute || adHoc.Action == xmpp.ActionAdHocNext {
|
||||||
// Last step in the command
|
// Last step in the command
|
||||||
logger.Info.Printf("Ad-Hoc command (Node : %s). Last step.", adHoc.Node)
|
log.Printf("%sAd-Hoc command (Node : %s). Last step.", LogInfo, adHoc.Node)
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
reply := iq.Response(xmpp.IQTypeResult)
|
||||||
cmd := &xmpp.AdHocCommand{Node: adHoc.Node, Status: xmpp.StatusAdHocCompleted, SessionID: adHoc.SessionID}
|
cmd := &xmpp.AdHocCommand{Node: adHoc.Node, Status: xmpp.StatusAdHocCompleted, SessionID: adHoc.SessionID}
|
||||||
|
|
||||||
|
|
@ -232,11 +158,12 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if authCode != "" {
|
if authCode != "" {
|
||||||
// Succeeded
|
// Succeded
|
||||||
g := MapGatewayInfo[jidBareFrom]
|
jidBare := strings.SplitN(iq.From, "/", 2)[0]
|
||||||
|
g := MapGatewayInfo[jidBare]
|
||||||
if g != nil {
|
if g != nil {
|
||||||
g.SetSteamAuthCode(authCode)
|
g.SetSteamAuthCode(authCode)
|
||||||
note.Value = "Command succeeded !"
|
note.Value = "Command succeded !"
|
||||||
} else {
|
} else {
|
||||||
note.Value = "Your are not registred. Please, register before sending Steam auth code."
|
note.Value = "Your are not registred. Please, register before sending Steam auth code."
|
||||||
}
|
}
|
||||||
|
|
@ -252,11 +179,35 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
||||||
|
|
||||||
// Command Auth Code
|
// Command Auth Code
|
||||||
dbUser := getUser(adHoc.XForm.Fields, iq)
|
steamLogin := ""
|
||||||
if dbUser != nil {
|
steamPwd := ""
|
||||||
if dbUser.UpdateUser() {
|
fields := adHoc.XForm.Fields
|
||||||
|
for _, field := range fields {
|
||||||
|
if field.Var == "login" {
|
||||||
|
steamLogin = field.Value
|
||||||
|
} else if field.Var == "password" {
|
||||||
|
steamPwd = field.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if steamLogin != "" && steamPwd != "" {
|
||||||
|
// Succeded
|
||||||
|
jidBare := strings.SplitN(iq.From, "/", 2)[0]
|
||||||
|
dbUser := new(database.DatabaseLine)
|
||||||
|
dbUser.Jid = jidBare
|
||||||
|
dbUser.SteamLogin = steamLogin
|
||||||
|
dbUser.SteamPwd = steamPwd
|
||||||
|
dbUser.Debug = false
|
||||||
|
|
||||||
|
isUserRegistred := database.GetLine(dbUser.Jid) != nil
|
||||||
|
var isSqlSuccess bool
|
||||||
|
if isUserRegistred {
|
||||||
|
isSqlSuccess = dbUser.UpdateLine()
|
||||||
|
} else {
|
||||||
|
isSqlSuccess = dbUser.AddLine()
|
||||||
|
}
|
||||||
|
if isSqlSuccess {
|
||||||
AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug)
|
AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug)
|
||||||
note.Value = "Command succeeded !"
|
note.Value = "Command succeded !"
|
||||||
} else {
|
} else {
|
||||||
note.Value = "Error append while executing command"
|
note.Value = "Error append while executing command"
|
||||||
}
|
}
|
||||||
|
|
@ -265,80 +216,16 @@ func execCommandAdHoc(iq *xmpp.IQ) {
|
||||||
note.Value = "Failed because Steam login or Steam password is empty."
|
note.Value = "Failed because Steam login or Steam password is empty."
|
||||||
}
|
}
|
||||||
cmd.Note = *note
|
cmd.Note = *note
|
||||||
|
|
||||||
} else if adHoc.Node == CommandMessageBroadcast && AdminUsers[jidBareFrom] {
|
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocResult, Title: "Broadcast a message"}
|
|
||||||
cmd.XForm = *cmdXForm
|
|
||||||
note := &xmpp.AdHocNote{Type: xmpp.TypeAdHocNoteInfo}
|
|
||||||
|
|
||||||
// Command Auth Code
|
|
||||||
message := ""
|
|
||||||
fields := adHoc.XForm.Fields
|
|
||||||
for _, field := range fields {
|
|
||||||
if field.Var == "message" {
|
|
||||||
message = field.Value
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if message != "" {
|
|
||||||
// Succeeded
|
|
||||||
for userJID := range MapGatewayInfo {
|
|
||||||
SendMessage(userJID, "", message)
|
|
||||||
}
|
|
||||||
note.Value = "Message sended to all registered users"
|
|
||||||
} else {
|
|
||||||
// Failed
|
|
||||||
note.Value = "There is no message to send"
|
|
||||||
}
|
|
||||||
cmd.Note = *note
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.PayloadEncode(cmd)
|
reply.PayloadEncode(cmd)
|
||||||
comp.Out <- reply
|
comp.Out <- reply
|
||||||
} else if adHoc.Action == xmpp.ActionAdHocCancel {
|
} else if adHoc.Action == xmpp.ActionAdHocCancel {
|
||||||
// command canceled
|
// command canceled
|
||||||
logger.Info.Printf("Ad-Hoc command (Node : %s). Command canceled.", adHoc.Node)
|
log.Printf("%sAd-Hoc command (Node : %s). Command canceled.", LogInfo, adHoc.Node)
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
reply := iq.Response(xmpp.IQTypeResult)
|
||||||
cmd := &xmpp.AdHocCommand{Node: adHoc.Node, Status: xmpp.StatusAdHocCanceled, SessionID: adHoc.SessionID}
|
cmd := &xmpp.AdHocCommand{Node: adHoc.Node, Status: xmpp.StatusAdHocCanceled, SessionID: adHoc.SessionID}
|
||||||
reply.PayloadEncode(cmd)
|
reply.PayloadEncode(cmd)
|
||||||
comp.Out <- reply
|
comp.Out <- reply
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getXFormRegistration(steamLogin string) *xmpp.AdHocXForm {
|
|
||||||
cmdXForm := &xmpp.AdHocXForm{Type: xmpp.TypeAdHocForm, Title: "Steam Account Info", Instructions: "Please provide your Steam login and password (Please, be aware that the given Steam account information will be saved into an un-encrypted SQLite database)."}
|
|
||||||
|
|
||||||
field := &xmpp.AdHocField{Var: "login", Label: "Steam Login", Type: xmpp.TypeAdHocFieldTextSingle}
|
|
||||||
field.Value = steamLogin
|
|
||||||
cmdXForm.Fields = append(cmdXForm.Fields, *field)
|
|
||||||
field = &xmpp.AdHocField{Var: "password", Label: "Steam Password", Type: xmpp.TypeAdHocFieldTextPrivate}
|
|
||||||
cmdXForm.Fields = append(cmdXForm.Fields, *field)
|
|
||||||
|
|
||||||
return cmdXForm
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUser(fields []xmpp.AdHocField, iq *xmpp.IQ) *database.DatabaseLine {
|
|
||||||
// Command Auth Code
|
|
||||||
steamLogin := ""
|
|
||||||
steamPwd := ""
|
|
||||||
for _, field := range fields {
|
|
||||||
if field.Var == "login" {
|
|
||||||
steamLogin = field.Value
|
|
||||||
} else if field.Var == "password" {
|
|
||||||
steamPwd = field.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if steamLogin != "" {
|
|
||||||
// Succeeded
|
|
||||||
jidBareFrom := strings.SplitN(iq.From, "/", 2)[0]
|
|
||||||
dbUser := new(database.DatabaseLine)
|
|
||||||
dbUser.Jid = jidBareFrom
|
|
||||||
dbUser.SteamLogin = steamLogin
|
|
||||||
dbUser.SteamPwd = steamPwd
|
|
||||||
dbUser.Debug = false
|
|
||||||
|
|
||||||
return dbUser
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
231
xmpp/xmpp.go
231
xmpp/xmpp.go
|
|
@ -4,17 +4,19 @@ import (
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/database"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/gateway"
|
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/gateway"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp4steam.git/logger"
|
|
||||||
|
|
||||||
"os"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ActionConnexion = "action_xmpp_connexion"
|
ActionConnexion = "action_xmpp_connexion"
|
||||||
ActionDeconnexion = "action_xmpp_deconnexion"
|
ActionDeconnexion = "action_xmpp_deconnexion"
|
||||||
ActionMainMethodEnded = "action_xmpp_main_method_ended"
|
ActionMainMethodEnded = "action_xmpp_main_method_ended"
|
||||||
|
|
||||||
|
LogInfo = "\t[XMPP COMPONENT INFO]\t"
|
||||||
|
LogError = "\t[XMPP COMPONENT ERROR]\t"
|
||||||
|
LogDebug = "\t[XMPP COMPONENT DEBUG]\t"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -33,25 +35,21 @@ var (
|
||||||
Debug = true
|
Debug = true
|
||||||
|
|
||||||
MapGatewayInfo = make(map[string]*gateway.GatewayInfo)
|
MapGatewayInfo = make(map[string]*gateway.GatewayInfo)
|
||||||
AdminUsers = make(map[string]bool)
|
|
||||||
startTime = time.Now()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run() {
|
func Run() {
|
||||||
logger.Info.Printf("Running")
|
log.Printf("%sRunning", LogInfo)
|
||||||
// Create stream and configure it as a component connection.
|
// Create stream and configure it as a component connection.
|
||||||
jid = must(xmpp.ParseJID(JidStr)).(xmpp.JID)
|
jid = must(xmpp.ParseJID(JidStr)).(xmpp.JID)
|
||||||
stream = must(xmpp.NewStream(Addr, &xmpp.StreamConfig{LogStanzas: Debug})).(*xmpp.Stream)
|
stream = must(xmpp.NewStream(Addr, &xmpp.StreamConfig{LogStanzas: Debug})).(*xmpp.Stream)
|
||||||
comp = must(xmpp.NewComponentXMPP(stream, jid, Secret)).(*xmpp.XMPP)
|
comp = must(xmpp.NewComponentXMPP(stream, jid, Secret)).(*xmpp.XMPP)
|
||||||
|
|
||||||
mainXMPP()
|
mainXMPP()
|
||||||
time.Sleep(1 * time.Second)
|
log.Printf("%sReach main method's end", LogInfo)
|
||||||
logger.Info.Printf("Reach XMPP Run method's end")
|
|
||||||
go Run()
|
go Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func mainXMPP() {
|
func mainXMPP() {
|
||||||
defer logger.Info.Printf("Reach main method's end")
|
|
||||||
// Define xmpp out for all users
|
// Define xmpp out for all users
|
||||||
for _, u := range MapGatewayInfo {
|
for _, u := range MapGatewayInfo {
|
||||||
u.XMPP_Out = comp.Out
|
u.XMPP_Out = comp.Out
|
||||||
|
|
@ -60,15 +58,11 @@ func mainXMPP() {
|
||||||
for x := range comp.In {
|
for x := range comp.In {
|
||||||
switch v := x.(type) {
|
switch v := x.(type) {
|
||||||
case *xmpp.Presence:
|
case *xmpp.Presence:
|
||||||
jidBareFrom := strings.SplitN(v.From, "/", 2)[0]
|
jidBare := strings.SplitN(v.From, "/", 2)[0]
|
||||||
jidBareTo := strings.SplitN(v.To, "/", 2)[0]
|
g := MapGatewayInfo[jidBare]
|
||||||
g := MapGatewayInfo[jidBareFrom]
|
|
||||||
if g != nil {
|
if g != nil {
|
||||||
if jidBareTo == jid.Domain || v.Type == gateway.Type_probe {
|
log.Printf("%sPresence transfered to %s", LogDebug, jidBare)
|
||||||
// Forward only if presence is for component or is type probe, in order not to spam set presence on Steam
|
g.ReceivedXMPP_Presence(v)
|
||||||
logger.Debug.Printf("Presence transferred to %s", jidBareFrom)
|
|
||||||
go g.ReceivedXMPP_Presence(v)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if v.Type != gateway.Type_error && v.Type != gateway.Type_probe {
|
if v.Type != gateway.Type_error && v.Type != gateway.Type_probe {
|
||||||
SendPresence(gateway.Status_offline, gateway.Type_unavailable, jid.Domain, v.From, "Your are not registred", "")
|
SendPresence(gateway.Status_offline, gateway.Type_unavailable, jid.Domain, v.From, "Your are not registred", "")
|
||||||
|
|
@ -76,157 +70,83 @@ func mainXMPP() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case *xmpp.Message:
|
case *xmpp.Message:
|
||||||
jidBareFrom := strings.SplitN(v.From, "/", 2)[0]
|
jidBare := strings.SplitN(v.From, "/", 2)[0]
|
||||||
g := MapGatewayInfo[jidBareFrom]
|
g := MapGatewayInfo[jidBare]
|
||||||
if g != nil {
|
if g != nil {
|
||||||
logger.Debug.Printf("Message transferred to %s", jidBareFrom)
|
log.Printf("%sMessage transfered to %s", LogDebug, jidBare)
|
||||||
go g.ReceivedXMPP_Message(v)
|
g.ReceivedXMPP_Message(v)
|
||||||
} else {
|
} else {
|
||||||
SendMessage(v.From, "", "Your are not registred. If you want to register, please, send an Ad-Hoc command.")
|
SendMessage(v.From, "", "Your are not registred. If you want to register, please, send an Ad-Hoc command.")
|
||||||
}
|
}
|
||||||
|
|
||||||
case *xmpp.IQ:
|
case *xmpp.Iq:
|
||||||
jidBareFrom := strings.SplitN(v.From, "/", 2)[0]
|
jidBare := strings.SplitN(v.To, "/", 2)[0]
|
||||||
jidBareTo := strings.SplitN(v.To, "/", 2)[0]
|
|
||||||
|
|
||||||
g := MapGatewayInfo[jidBareFrom]
|
switch v.PayloadName().Space {
|
||||||
iqTreated := false
|
case xmpp.NSDiscoItems:
|
||||||
if g != nil {
|
if jidBare == jid.Domain {
|
||||||
logger.Debug.Printf("Iq transferred to %s", jidBareFrom)
|
execDiscoCommand(v)
|
||||||
iqTreated = g.ReceivedXMPP_IQ(v)
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
if !iqTreated {
|
|
||||||
switch v.PayloadName().Space {
|
|
||||||
case xmpp.NSDiscoInfo:
|
|
||||||
execDisco(v)
|
|
||||||
|
|
||||||
case xmpp.NSDiscoItems:
|
|
||||||
execDisco(v)
|
|
||||||
|
|
||||||
case xmpp.NodeAdHocCommand:
|
|
||||||
if jidBareTo == jid.Domain {
|
|
||||||
execCommandAdHoc(v)
|
|
||||||
} else {
|
|
||||||
sendNotSupportedFeature(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
case xmpp.NSVCardTemp:
|
|
||||||
if jidBareTo == jid.Domain {
|
|
||||||
reply := v.Response(xmpp.IQTypeResult)
|
|
||||||
vcard := &xmpp.VCard{}
|
|
||||||
reply.PayloadEncode(vcard)
|
|
||||||
comp.Out <- reply
|
|
||||||
} else {
|
|
||||||
sendNotSupportedFeature(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
case xmpp.NSJabberClient:
|
|
||||||
if jidBareTo == jid.Domain {
|
|
||||||
reply := v.Response(xmpp.IQTypeResult)
|
|
||||||
reply.PayloadEncode(&xmpp.SoftwareVersion{Name: "go-xmpp4steam", Version: SoftVersion})
|
|
||||||
comp.Out <- reply
|
|
||||||
} else {
|
|
||||||
sendNotSupportedFeature(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
case xmpp.NSRegister:
|
|
||||||
if jidBareTo == jid.Domain {
|
|
||||||
treatmentNSRegister(v)
|
|
||||||
} else {
|
|
||||||
sendNotSupportedFeature(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
case xmpp.NSRoster:
|
|
||||||
// Do nothing
|
|
||||||
|
|
||||||
case xmpp.NSPing:
|
|
||||||
if jidBareTo == jid.Domain {
|
|
||||||
treatmentNSPing(v)
|
|
||||||
} else {
|
|
||||||
sendNotSupportedFeature(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
sendNotSupportedFeature(v)
|
sendNotSupportedFeature(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case xmpp.NodeAdHocCommand:
|
||||||
|
if jidBare == jid.Domain {
|
||||||
|
execCommandAdHoc(v)
|
||||||
|
} else {
|
||||||
|
sendNotSupportedFeature(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
case xmpp.NSVCardTemp:
|
||||||
|
if jidBare == jid.Domain {
|
||||||
|
reply := v.Response(xmpp.IQTypeResult)
|
||||||
|
vcard := &xmpp.VCard{}
|
||||||
|
reply.PayloadEncode(vcard)
|
||||||
|
comp.Out <- reply
|
||||||
|
} else {
|
||||||
|
sendNotSupportedFeature(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
case xmpp.NSJabberClient:
|
||||||
|
if jidBare == jid.Domain {
|
||||||
|
reply := v.Response(xmpp.IQTypeResult)
|
||||||
|
reply.PayloadEncode(&xmpp.SoftwareVersion{Name: "go-xmpp4steam", Version: SoftVersion})
|
||||||
|
comp.Out <- reply
|
||||||
|
} else {
|
||||||
|
sendNotSupportedFeature(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
sendNotSupportedFeature(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logger.Debug.Printf("recv: %v", x)
|
log.Printf("%srecv: %v", LogDebug, x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send deconnexion
|
||||||
|
SendPresence(gateway.Status_offline, gateway.Type_unavailable, "", "", "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func must(v interface{}, err error) interface{} {
|
func must(v interface{}, err error) interface{} {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Debug.Printf("%v", err)
|
log.Fatal(LogError, err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func treatmentNSRegister(iq *xmpp.IQ) {
|
func sendNotSupportedFeature(iq *xmpp.Iq) {
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
reply := iq.Response(xmpp.IQTypeError)
|
||||||
jidBareFrom := strings.SplitN(iq.From, "/", 2)[0]
|
reply.PayloadEncode(xmpp.NewError("cancel", xmpp.FeatureNotImplemented, ""))
|
||||||
registerQuery := &xmpp.RegisterQuery{}
|
|
||||||
|
|
||||||
if iq.Type == xmpp.IQTypeGet {
|
|
||||||
registerQuery.Instructions = "Please provide your Steam login and password (Please, be aware that the given Steam account information will be saved into an un-encrypted SQLite database)."
|
|
||||||
|
|
||||||
dbUser := database.GetLine(jidBareFrom)
|
|
||||||
if dbUser != nil {
|
|
||||||
// User already registered
|
|
||||||
registerQuery.Registered = &xmpp.RegisterRegistered{}
|
|
||||||
registerQuery.Username = dbUser.SteamLogin
|
|
||||||
registerQuery.XForm = *getXFormRegistration(dbUser.SteamLogin)
|
|
||||||
} else {
|
|
||||||
registerQuery.XForm = *getXFormRegistration("")
|
|
||||||
}
|
|
||||||
reply.PayloadEncode(registerQuery)
|
|
||||||
|
|
||||||
} else if iq.Type == xmpp.IQTypeSet {
|
|
||||||
iq.PayloadDecode(registerQuery)
|
|
||||||
|
|
||||||
if registerQuery.Remove != nil {
|
|
||||||
RemoveUser(jidBareFrom)
|
|
||||||
} else {
|
|
||||||
dbUser := getUser(registerQuery.XForm.Fields, iq)
|
|
||||||
if dbUser != nil {
|
|
||||||
if dbUser.UpdateUser() {
|
|
||||||
AddNewUser(dbUser.Jid, dbUser.SteamLogin, dbUser.SteamPwd, dbUser.Debug)
|
|
||||||
} else {
|
|
||||||
reply.Type = xmpp.IQTypeError
|
|
||||||
reply.Error = xmpp.NewErrorWithCode("406", "modify", xmpp.ErrorNotAcceptable, "")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reply.Type = xmpp.IQTypeError
|
|
||||||
reply.Error = xmpp.NewErrorWithCode("409", "cancel", xmpp.ErrorConflict, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
comp.Out <- reply
|
comp.Out <- reply
|
||||||
}
|
}
|
||||||
|
|
||||||
func treatmentNSPing(iq *xmpp.IQ) {
|
|
||||||
reply := iq.Response(xmpp.IQTypeResult)
|
|
||||||
comp.Out <- reply
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendNotSupportedFeature(iq *xmpp.IQ) {
|
|
||||||
if iq.Type != xmpp.IQTypeError && iq.Type != xmpp.IQTypeResult {
|
|
||||||
reply := iq.Response(xmpp.IQTypeError)
|
|
||||||
reply.PayloadEncode(xmpp.NewError("cancel", xmpp.ErrorFeatureNotImplemented, ""))
|
|
||||||
comp.Out <- reply
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Disconnect() {
|
func Disconnect() {
|
||||||
logger.Info.Printf("XMPP disconnect")
|
log.Printf("%sXMPP disconnect", LogInfo)
|
||||||
for _, u := range MapGatewayInfo {
|
for _, u := range MapGatewayInfo {
|
||||||
u.SteamDisconnect()
|
u.SteamDisconnect()
|
||||||
}
|
}
|
||||||
comp.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendPresence(status, tpye, from, to, message, nick string) {
|
func SendPresence(status, tpye, from, to, message, nick string) {
|
||||||
|
|
@ -257,46 +177,33 @@ func SendPresence(status, tpye, from, to, message, nick string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendMessage(to, subject, message string) {
|
func SendMessage(to, subject, message string) {
|
||||||
m := xmpp.Message{From: jid.Domain, To: to, Type: "chat"}
|
m := xmpp.Message{From: jid.Domain, To: to, Body: message, Type: "chat"}
|
||||||
mBody := xmpp.MessageBody{Value: message}
|
|
||||||
m.Body = append(m.Body, mBody)
|
|
||||||
|
|
||||||
if subject != "" {
|
if subject != "" {
|
||||||
m.Subject = subject
|
m.Subject = subject
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info.Printf("Senp message %v", m)
|
log.Printf("%sSenp message %v", LogInfo, m)
|
||||||
comp.Out <- m
|
comp.Out <- m
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddNewUser(jidUser, steamLogin, steamPwd string, debugMessage bool) {
|
func AddNewUser(jid, steamLogin, steamPwd string, debugMessage bool) {
|
||||||
logger.Info.Printf("Add user %s to the map (debug mode set to %v)", jidUser, debugMessage)
|
log.Printf("%sAdd user %s to the map", LogInfo, jid)
|
||||||
|
|
||||||
g := new(gateway.GatewayInfo)
|
g := new(gateway.GatewayInfo)
|
||||||
g.SteamLogin = steamLogin
|
g.SteamLogin = steamLogin
|
||||||
g.SteamPassword = steamPwd
|
g.SteamPassword = steamPwd
|
||||||
g.XMPP_JID_Client = jidUser
|
g.XMPP_JID_Client = jid
|
||||||
g.SentryFile = gateway.SentryDirectory + jidUser
|
g.SentryFile = gateway.SentryDirectory + jid
|
||||||
g.CreateSteamIds()
|
g.FriendSteamId = make(map[string]*gateway.StatusSteamFriend)
|
||||||
g.Deleting = false
|
g.Deleting = false
|
||||||
|
|
||||||
g.XMPP_Out = comp.Out
|
g.XMPP_Out = comp.Out
|
||||||
g.CreateXmppConnectedClient()
|
g.XMPP_Connected_Client = make(map[string]bool)
|
||||||
g.DebugMessage = debugMessage
|
g.DebugMessage = debugMessage
|
||||||
g.CreateXmppRemoteRosterRequest()
|
|
||||||
g.AllowEditRoster = false
|
|
||||||
|
|
||||||
MapGatewayInfo[jidUser] = g
|
MapGatewayInfo[jid] = g
|
||||||
go g.Run()
|
go g.Run()
|
||||||
|
|
||||||
logger.Info.Printf("Check roster edition by asking with remote roster manager namespace")
|
|
||||||
// Ask if remote roster is allow
|
|
||||||
iqId := gateway.NextIqId()
|
|
||||||
g.SetXmppRemoteRosterRequest(iqId, gateway.RemoteRosterRequestPermission)
|
|
||||||
iq := xmpp.IQ{To: jidUser, From: jid.Domain, Type: xmpp.IQTypeGet, ID: iqId}
|
|
||||||
// iq.PayloadEncode(&xmpp.RosterQuery{})
|
|
||||||
iq.PayloadEncode(&xmpp.RemoteRosterManagerQuery{Reason: "Manage contacts in the Steam contact list", Type: xmpp.RemoteRosterManagerTypeRequest})
|
|
||||||
comp.Out <- iq
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveUser(jidBare string) bool {
|
func RemoveUser(jidBare string) bool {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue