mirror of
https://github.com/aramperes/ts-activity.git
synced 2025-09-08 05:48:31 -04:00
Spotlight feature
This commit is contained in:
parent
9fbbd2cd22
commit
abfc92385a
1 changed files with 129 additions and 14 deletions
143
cmd.go
143
cmd.go
|
@ -5,7 +5,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gtuk/discordwebhook"
|
"github.com/gtuk/discordwebhook"
|
||||||
"github.com/multiplay/go-ts3"
|
"github.com/multiplay/go-ts3"
|
||||||
|
@ -13,13 +15,15 @@ import (
|
||||||
|
|
||||||
// App holds the configuration
|
// App holds the configuration
|
||||||
type App struct {
|
type App struct {
|
||||||
discordURL string
|
discordURL string
|
||||||
discordUsername string
|
discordUsername string
|
||||||
discordAvatarURL *string
|
discordAvatarURL *string
|
||||||
tsQueryAddr string
|
tsQueryAddr string
|
||||||
tsQueryUser string
|
tsQueryUser string
|
||||||
tsQueryPass string
|
tsQueryPass string
|
||||||
tsQueryServerID int
|
tsQueryServerID int
|
||||||
|
spotLightGfxFormat string
|
||||||
|
spotLightIDMap map[string]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func appFromEnv() (*App, error) {
|
func appFromEnv() (*App, error) {
|
||||||
|
@ -58,15 +62,33 @@ func appFromEnv() (*App, error) {
|
||||||
return nil, errors.New("invalid TS_QUERY_SERVER_ID, must be int")
|
return nil, errors.New("invalid TS_QUERY_SERVER_ID, must be int")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spotLightGfxFormat := os.Getenv("TS_SPOTLIGHT_GFX_FMT")
|
||||||
|
|
||||||
|
// TODO: Load from environment variable
|
||||||
|
spotLightIDMap := make(map[string]int)
|
||||||
|
spotLightIDMap["rb+mT/4bh37gHzQYqTgBiEHG2IA="] = 0
|
||||||
|
spotLightIDMap["sA3fHhvqmlSuFYtMoVYseRQI2DE="] = 0
|
||||||
|
spotLightIDMap["9K6JV7kWaRU+4HFRkXrBZNjSmRA="] = 1
|
||||||
|
spotLightIDMap["pFclzBx0w2UmwPd91VvaXJjYCYA="] = 2
|
||||||
|
spotLightIDMap["tvjlpKqvcyQSCCVkT0TJ28uwdaQ="] = 3
|
||||||
|
spotLightIDMap["SLLvtjVBmSoIzpMhlxnLa9CWoOU="] = 4
|
||||||
|
spotLightIDMap["7EU/Up++D9+8SQk0sNchEuKPufw="] = 5
|
||||||
|
spotLightIDMap["SyldxnLYWHJOUj3HnEsXGF6B0T4="] = 5
|
||||||
|
spotLightIDMap["Mc/TdoNhddKdGtB55DSZrYk3NWc="] = 6
|
||||||
|
spotLightIDMap["xOWMWG/TpkbV8XjahqqoQLsHHpA="] = 7
|
||||||
|
spotLightIDMap["G4kg1LKJElM5LIpoeA6gN7DMl0c="] = 7
|
||||||
|
spotLightIDMap["wuQ907NtzqL4uxhLk3P/TCpkXF0="] = 8
|
||||||
|
|
||||||
return &App{
|
return &App{
|
||||||
discordURL: discordURL,
|
discordURL: discordURL,
|
||||||
discordUsername: discordUsername,
|
discordUsername: discordUsername,
|
||||||
discordAvatarURL: discordAvatarURL,
|
discordAvatarURL: discordAvatarURL,
|
||||||
tsQueryAddr: tsQueryAddr,
|
tsQueryAddr: tsQueryAddr,
|
||||||
tsQueryUser: tsQueryUser,
|
tsQueryUser: tsQueryUser,
|
||||||
tsQueryPass: tsQueryPass,
|
tsQueryPass: tsQueryPass,
|
||||||
tsQueryServerID: tsQueryServerID,
|
tsQueryServerID: tsQueryServerID,
|
||||||
|
spotLightGfxFormat: spotLightGfxFormat,
|
||||||
|
spotLightIDMap: spotLightIDMap,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +131,8 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
clientMap := make(map[string]string)
|
clientMap := make(map[string]string)
|
||||||
|
clientDatabaseIDs := make(map[string]string)
|
||||||
|
clientUniqueIDs := make(map[string]string)
|
||||||
|
|
||||||
log.Println("Online clients:")
|
log.Println("Online clients:")
|
||||||
for _, client := range cl {
|
for _, client := range cl {
|
||||||
|
@ -117,8 +141,20 @@ func main() {
|
||||||
}
|
}
|
||||||
log.Println("-", client)
|
log.Println("-", client)
|
||||||
clientMap[strconv.Itoa(client.ID)] = client.Nickname
|
clientMap[strconv.Itoa(client.ID)] = client.Nickname
|
||||||
|
clientDatabaseIDs[strconv.Itoa(client.ID)] = strconv.Itoa(client.DatabaseID)
|
||||||
|
|
||||||
|
uid, err := getClientUniqueId(c, strconv.Itoa(client.DatabaseID))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientUniqueIDs[strconv.Itoa(client.ID)] = uid
|
||||||
|
log.Println(" - UID:", uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the banner on startup with the currently online users.
|
||||||
|
app.updateSpotLight(c, mapValues(clientUniqueIDs))
|
||||||
|
|
||||||
// Listen for client updates
|
// Listen for client updates
|
||||||
notifs := c.Notifications()
|
notifs := c.Notifications()
|
||||||
|
|
||||||
|
@ -136,6 +172,12 @@ func main() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientDBID, ok := event.Data["client_database_id"]
|
||||||
|
if !ok {
|
||||||
|
log.Println("User has no client database id", event.Data)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
clientNick, ok := event.Data["client_nickname"]
|
clientNick, ok := event.Data["client_nickname"]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Println("User has no nickname:", clientID)
|
log.Println("User has no nickname:", clientID)
|
||||||
|
@ -147,6 +189,16 @@ func main() {
|
||||||
|
|
||||||
if !previous {
|
if !previous {
|
||||||
app.clientConnected(clientNick)
|
app.clientConnected(clientNick)
|
||||||
|
|
||||||
|
clientDatabaseIDs[clientID] = clientDBID
|
||||||
|
uid, err := getClientUniqueId(c, clientDBID)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clientUniqueIDs[clientID] = uid
|
||||||
|
|
||||||
|
app.updateSpotLight(c, mapValues(clientUniqueIDs))
|
||||||
}
|
}
|
||||||
} else if event.Type == "clientleftview" {
|
} else if event.Type == "clientleftview" {
|
||||||
clientID, ok := event.Data["clid"]
|
clientID, ok := event.Data["clid"]
|
||||||
|
@ -162,6 +214,9 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(clientMap, clientID)
|
delete(clientMap, clientID)
|
||||||
|
delete(clientDatabaseIDs, clientID)
|
||||||
|
delete(clientUniqueIDs, clientID)
|
||||||
|
app.updateSpotLight(c, mapValues(clientUniqueIDs))
|
||||||
app.clientDisconnected(clientNick)
|
app.clientDisconnected(clientNick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,3 +243,63 @@ func (app *App) clientDisconnected(nick string) {
|
||||||
content := fmt.Sprintf("Client disconnected: %s", nick)
|
content := fmt.Sprintf("Client disconnected: %s", nick)
|
||||||
app.sendWebhook(content)
|
app.sendWebhook(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *App) updateSpotLight(c *ts3.Client, connectedUIDs []string) {
|
||||||
|
if app.spotLightGfxFormat == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
spotLightIDs := make([]int, 0)
|
||||||
|
for _, uid := range connectedUIDs {
|
||||||
|
spotLightID, ok := app.spotLightIDMap[uid]
|
||||||
|
if ok {
|
||||||
|
spotLightIDs = append(spotLightIDs, spotLightID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(spotLightIDs) == 0 {
|
||||||
|
updateBanner(c, fmt.Sprintf(app.spotLightGfxFormat, "empty"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.Sort(spotLightIDs)
|
||||||
|
slices.Compact(spotLightIDs)
|
||||||
|
|
||||||
|
spotLightIDStrings := make([]string, len(spotLightIDs))
|
||||||
|
for idx, id := range spotLightIDs {
|
||||||
|
spotLightIDStrings[idx] = strconv.Itoa(id)
|
||||||
|
}
|
||||||
|
joined := strings.Join(spotLightIDStrings, "_")
|
||||||
|
|
||||||
|
updateBanner(c, fmt.Sprintf(app.spotLightGfxFormat, joined))
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateBanner(c *ts3.Client, gfx string) {
|
||||||
|
err := c.Server.Edit(ts3.NewArg("virtualserver_hostbanner_gfx_url", gfx))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to update banner:", gfx, err)
|
||||||
|
} else {
|
||||||
|
log.Println("Updated banner:", gfx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getClientUniqueId(c *ts3.Client, dbID string) (string, error) {
|
||||||
|
var uid = struct {
|
||||||
|
UID string `ms:"cluid"`
|
||||||
|
}{}
|
||||||
|
_, err := c.ExecCmd(ts3.NewCmd("clientgetnamefromdbid").WithArgs(ts3.NewArg("cldbid", dbID)).WithResponse(&uid))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return uid.UID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapValues(m map[string]string) []string {
|
||||||
|
v := make([]string, 0, len(m))
|
||||||
|
for _, val := range m {
|
||||||
|
v = append(v, val)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue