Skip to content

Commit 0507f48

Browse files
feat: discord: redesign connected players panel with embeds and Steam Community links
- Implement styled embed display for connected players - Add clickable Steam Community profile links for each player - Send initial panel on bot startup with proper message cleanup - Fix message editing to properly update embeds
1 parent 796e05c commit 0507f48

2 files changed

Lines changed: 86 additions & 36 deletions

File tree

src/discordbot/connectedplayers.go

Lines changed: 83 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,77 +8,126 @@ import (
88

99
"github.com/JacksonTheMaster/StationeersServerUI/v5/src/config"
1010
"github.com/JacksonTheMaster/StationeersServerUI/v5/src/logger"
11+
"github.com/bwmarrin/discordgo"
1112
)
1213

1314
var (
1415
connectedPlayersMessageID string // connectedPlayersMessageID tracks the message ID for editing the connected players message
1516
playersMutex sync.Mutex
1617
)
1718

19+
// sendConnectedPlayersPanel sends the initial "no players" embed on startup
20+
func sendConnectedPlayersPanel() {
21+
if !config.GetIsDiscordEnabled() {
22+
return
23+
}
24+
25+
channelID := config.GetConnectionListChannelID()
26+
if channelID == "" {
27+
logger.Discord.Debug("Connection list channel ID not configured, skipping panel")
28+
return
29+
}
30+
31+
embed := buildConnectedPlayersEmbed(nil)
32+
sendOrEditConnectedPlayersEmbed(channelID, embed)
33+
clearMessagesAboveLastN(channelID, 1)
34+
logger.Discord.Info("Connected players panel sent successfully")
35+
}
36+
1837
func AddToConnectedPlayers(username, steamID string, connectionTime time.Time, players map[string]string) {
1938
if !config.GetIsDiscordEnabled() || config.DiscordSession == nil {
2039
logger.Discord.Debug("Discord not enabled or session not initialized")
2140
return
2241
}
23-
content := formatConnectedPlayers(players)
24-
sendAndEditMessageInConnectedPlayersChannel(config.GetConnectionListChannelID(), content)
42+
channelID := config.GetConnectionListChannelID()
43+
if channelID == "" {
44+
return
45+
}
46+
embed := buildConnectedPlayersEmbed(players)
47+
sendOrEditConnectedPlayersEmbed(channelID, embed)
2548
}
2649

2750
func RemoveFromConnectedPlayers(steamID string, players map[string]string) {
2851
if !config.GetIsDiscordEnabled() || config.DiscordSession == nil {
2952
logger.Discord.Debug("Discord not enabled or session not initialized")
3053
return
3154
}
32-
content := formatConnectedPlayers(players)
33-
sendAndEditMessageInConnectedPlayersChannel(config.GetConnectionListChannelID(), content)
55+
channelID := config.GetConnectionListChannelID()
56+
if channelID == "" {
57+
return
58+
}
59+
embed := buildConnectedPlayersEmbed(players)
60+
sendOrEditConnectedPlayersEmbed(channelID, embed)
61+
}
62+
63+
// buildConnectedPlayersEmbed creates a Discord embed for the connected players panel
64+
func buildConnectedPlayersEmbed(players map[string]string) *discordgo.MessageEmbed {
65+
embed := &discordgo.MessageEmbed{
66+
Title: "👥 Connected Players",
67+
Timestamp: time.Now().Format(time.RFC3339),
68+
Footer: &discordgo.MessageEmbedFooter{
69+
Text: "Last updated",
70+
},
71+
}
72+
73+
if len(players) == 0 {
74+
embed.Description = "No players are currently connected."
75+
embed.Color = 0x95A5A6 // Grey
76+
return embed
77+
}
78+
79+
embed.Color = 0x2ECC71 // Green
80+
81+
// Build a clean row-based player list in the description
82+
var lines strings.Builder
83+
fmt.Fprintf(&lines, "**%d** player(s) online, click opens Steam profile\n\n", len(players))
84+
for steamID, username := range players {
85+
fmt.Fprintf(&lines, "👤 [%s](https://steamcommunity.com/profiles/%s/)\n", username, steamID)
86+
}
87+
embed.Description = lines.String()
88+
89+
return embed
3490
}
3591

36-
func sendAndEditMessageInConnectedPlayersChannel(channelID, message string) {
92+
// sendOrEditConnectedPlayersEmbed sends a new embed or edits the existing one
93+
func sendOrEditConnectedPlayersEmbed(channelID string, embed *discordgo.MessageEmbed) {
3794
playersMutex.Lock()
3895
defer playersMutex.Unlock()
3996

4097
if connectedPlayersMessageID == "" {
41-
// Send a new message if there's no existing one
42-
msg, err := config.DiscordSession.ChannelMessageSend(channelID, message)
98+
// Send a new message with embed
99+
msg, err := config.DiscordSession.ChannelMessageSendComplex(channelID, &discordgo.MessageSend{
100+
Embeds: []*discordgo.MessageEmbed{embed},
101+
})
43102
if err != nil {
44-
logger.Discord.Error("Error sending message to channel " + channelID + ": " + err.Error())
103+
logger.Discord.Error("Error sending connected players embed to channel " + channelID + ": " + err.Error())
45104
return
46105
}
47106
connectedPlayersMessageID = msg.ID
48-
logger.Discord.Debug("Sent new message to channel " + channelID)
107+
logger.Discord.Debug("Sent connected players embed to channel " + channelID)
49108
} else {
50-
// Edit the existing message
51-
_, err := config.DiscordSession.ChannelMessageEdit(channelID, connectedPlayersMessageID, message)
109+
// Edit the existing message with the updated embed
110+
embeds := []*discordgo.MessageEmbed{embed}
111+
content := ""
112+
_, err := config.DiscordSession.ChannelMessageEditComplex(&discordgo.MessageEdit{
113+
Channel: channelID,
114+
ID: connectedPlayersMessageID,
115+
Content: &content,
116+
Embeds: &embeds,
117+
})
52118
if err != nil {
53-
logger.Discord.Error("Error editing message in channel " + channelID + ": " + err.Error())
119+
logger.Discord.Error("Error editing connected players embed in channel " + channelID + ": " + err.Error())
54120
// If editing fails (e.g., message deleted), reset and try sending a new one
55121
connectedPlayersMessageID = ""
56-
msg, err := config.DiscordSession.ChannelMessageSend(channelID, message)
122+
msg, err := config.DiscordSession.ChannelMessageSendComplex(channelID, &discordgo.MessageSend{
123+
Embeds: []*discordgo.MessageEmbed{embed},
124+
})
57125
if err != nil {
58-
logger.Discord.Error("Error sending fallback message to channel " + channelID + ": " + err.Error())
126+
logger.Discord.Error("Error sending fallback connected players embed to channel " + channelID + ": " + err.Error())
59127
} else {
60128
connectedPlayersMessageID = msg.ID
61-
logger.Discord.Debug("Sent new message after edit failure to channel " + channelID)
129+
logger.Discord.Debug("Sent new connected players embed after edit failure to channel " + channelID)
62130
}
63131
}
64132
}
65133
}
66-
67-
func formatConnectedPlayers(players map[string]string) string {
68-
if len(players) == 0 {
69-
return "No players are currently connected."
70-
}
71-
72-
var sb strings.Builder
73-
sb.WriteString("Connected Players:\n")
74-
sb.WriteString("```\n")
75-
sb.WriteString("Username | Steam ID\n")
76-
sb.WriteString("----------------------|------------------------\n")
77-
78-
for steamID, username := range players {
79-
sb.WriteString(fmt.Sprintf("%-20s | %s\n", username, steamID))
80-
}
81-
82-
sb.WriteString("```")
83-
return sb.String()
84-
}

src/discordbot/interface.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ func InitializeDiscordBot() {
5656

5757
logger.Discord.Info("Bot is now running.")
5858
SendMessageToStatusChannel("🤖 SSUI Version " + config.GetVersion() + " connected to Discord.")
59-
sendControlPanel() // Send control panel message to Discord
60-
sendServerInfoPanel() // Send server info panel with buttons to Discord
59+
sendControlPanel() // Send control panel message to Discord
60+
sendServerInfoPanel() // Send server info panel with buttons to Discord
61+
sendConnectedPlayersPanel() // Send connected players panel to Discord
6162
UpdateBotStatusWithMessage("StationeersServerUI v" + config.GetVersion())
6263
// Start buffer flush ticker
6364
BufferFlushTicker = time.NewTicker(5 * time.Second)

0 commit comments

Comments
 (0)