Files
Erupe/server/channelserver/handlers_discord.go
2023-11-27 03:23:30 -05:00

135 lines
3.3 KiB
Go

package channelserver
import (
"fmt"
"github.com/bwmarrin/discordgo"
"golang.org/x/crypto/bcrypt"
"sort"
"strings"
"unicode"
)
type Player struct {
CharName string
QuestID int
}
func getPlayerSlice(s *Server) []Player {
var p []Player
var questIndex int
for _, channel := range s.Channels {
for _, stage := range channel.stages {
if len(stage.clients) == 0 {
continue
}
questID := 0
if stage.isQuest() {
questIndex++
questID = questIndex
}
for client := range stage.clients {
p = append(p, Player{
CharName: client.Name,
QuestID: questID,
})
}
}
}
return p
}
func getCharacterList(s *Server) string {
questEmojis := []string{
":person_in_lotus_position:",
":white_circle:",
":red_circle:",
":blue_circle:",
":brown_circle:",
":green_circle:",
":purple_circle:",
":yellow_circle:",
":orange_circle:",
":black_circle:",
}
playerSlice := getPlayerSlice(s)
sort.SliceStable(playerSlice, func(i, j int) bool {
return playerSlice[i].QuestID < playerSlice[j].QuestID
})
message := fmt.Sprintf("===== Online: %d =====\n", len(playerSlice))
for _, player := range playerSlice {
message += fmt.Sprintf("%s %s", questEmojis[player.QuestID], player.CharName)
}
return message
}
// onInteraction handles slash commands
func (s *Server) onInteraction(ds *discordgo.Session, i *discordgo.InteractionCreate) {
switch i.Interaction.ApplicationCommandData().Name {
case "verify":
_, err := s.db.Exec("UPDATE users SET discord_id = $1 WHERE discord_token = $2", i.Member.User.ID, i.ApplicationCommandData().Options[0].StringValue())
if err != nil {
return
}
err = ds.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "Erupe account successfully linked to Discord account.",
Flags: discordgo.MessageFlagsEphemeral,
},
})
if err != nil {
return
}
break
case "password":
password, _ := bcrypt.GenerateFromPassword([]byte(i.ApplicationCommandData().Options[0].StringValue()), 10)
_, err := s.db.Exec("UPDATE users SET password = $1 WHERE discord_id = $2", password, i.Member.User.ID)
if err != nil {
s.logger.Error(fmt.Sprint(err))
return
}
err = ds.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "Password has been reset, you may login now.",
Flags: discordgo.MessageFlagsEphemeral,
},
})
if err != nil {
return
}
break
}
}
// onDiscordMessage handles receiving messages from discord and forwarding them ingame.
func (s *Server) onDiscordMessage(ds *discordgo.Session, m *discordgo.MessageCreate) {
// Ignore messages from our bot, or ones that are not in the correct channel.
if m.Author.Bot || m.ChannelID != s.erupeConfig.Discord.RealTimeChannel.RealtimeChannelID {
return
}
paddedName := strings.TrimSpace(strings.Map(func(r rune) rune {
if r > unicode.MaxASCII {
return -1
}
return r
}, m.Author.Username))
for i := 0; i < 8-len(m.Author.Username); i++ {
paddedName += " "
}
message := fmt.Sprintf("[D] %s > %s", paddedName, m.Content)
s.BroadcastChatMessage(s.discordBot.NormalizeDiscordMessage(message))
}