we're sending now info about conquer using discord embed, change command syntax

This commit is contained in:
Dawid Wysokiński 2020-06-06 14:28:45 +02:00 committed by Kichiyaki
parent 0d4f3d4b3a
commit 85432c140a
10 changed files with 816 additions and 433 deletions

View File

@ -5,11 +5,14 @@ import (
"log" "log"
"time" "time"
shared_models "github.com/tribalwarshelp/shared/models"
"github.com/tribalwarshelp/golang-sdk/sdk" "github.com/tribalwarshelp/golang-sdk/sdk"
"github.com/tribalwarshelp/dcbot/discord" "github.com/tribalwarshelp/dcbot/discord"
"github.com/tribalwarshelp/dcbot/server" "github.com/tribalwarshelp/dcbot/server"
"github.com/tribalwarshelp/dcbot/tribe" "github.com/tribalwarshelp/dcbot/tribe"
"github.com/tribalwarshelp/dcbot/utils"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
) )
@ -31,7 +34,7 @@ type handler struct {
func AttachHandlers(c *cron.Cron, cfg Config) { func AttachHandlers(c *cron.Cron, cfg Config) {
h := &handler{ h := &handler{
since: time.Now(), since: time.Now().Add(-30 * time.Minute),
serverRepo: cfg.ServerRepo, serverRepo: cfg.ServerRepo,
tribeRepo: cfg.TribeRepo, tribeRepo: cfg.TribeRepo,
discord: cfg.Discord, discord: cfg.Discord,
@ -65,6 +68,32 @@ func (h *handler) loadEnnoblements(worlds []string) map[string]ennoblements {
return m return m
} }
func (h *handler) loadLangVersions(worlds []string) map[shared_models.LanguageTag]*shared_models.LangVersion {
languageTags := []shared_models.LanguageTag{}
cache := make(map[shared_models.LanguageTag]bool)
for _, world := range worlds {
languageTag := utils.LanguageCodeFromWorldName(world)
if languageTag.IsValid() && !cache[languageTag] {
cache[languageTag] = true
languageTags = append(languageTags, languageTag)
}
}
langVersions := make(map[shared_models.LanguageTag]*shared_models.LangVersion)
langVersionsList, err := h.api.LangVersions.Browse(&shared_models.LangVersionFilter{
Tag: languageTags,
})
if err == nil {
for _, langVersion := range langVersionsList.Items {
langVersions[langVersion.Tag] = langVersion
}
} else {
log.Printf("Cannot load lang versions: %s", err.Error())
}
return langVersions
}
func (h *handler) checkEnnoblements() { func (h *handler) checkEnnoblements() {
worlds, err := h.tribeRepo.FetchWorlds(context.Background()) worlds, err := h.tribeRepo.FetchWorlds(context.Background())
if err != nil { if err != nil {
@ -72,40 +101,71 @@ func (h *handler) checkEnnoblements() {
return return
} }
log.Print("checkEnnoblements: worlds: ", worlds) log.Print("checkEnnoblements: worlds: ", worlds)
servers, total, err := h.serverRepo.Fetch(context.Background(), nil) servers, total, err := h.serverRepo.Fetch(context.Background(), nil)
if err != nil { if err != nil {
log.Print("checkEnnoblements: " + err.Error()) log.Print("checkEnnoblements: " + err.Error())
return return
} }
log.Print("checkEnnoblements: total number of servers: ", total) log.Print("checkEnnoblements: total number of servers: ", total)
langVersions := h.loadLangVersions(worlds)
data := h.loadEnnoblements(worlds) data := h.loadEnnoblements(worlds)
h.since = time.Now() h.since = time.Now()
log.Print("checkEnnoblements: scrapped data: ", data) log.Print("checkEnnoblements: loaded ennoblements: ", len(data))
for _, server := range servers { for _, server := range servers {
if server.ConqueredVillagesChannelID == "" && server.LostVillagesChannelID == "" { if server.ConqueredVillagesChannelID == "" && server.LostVillagesChannelID == "" {
continue continue
} }
for _, tribe := range server.Tribes { for _, tribe := range server.Tribes {
es, ok := data[tribe.World] es, ok := data[tribe.World]
if ok { langVersion, ok2 := langVersions[utils.LanguageCodeFromWorldName(tribe.World)]
if ok && ok2 {
if server.LostVillagesChannelID != "" { if server.LostVillagesChannelID != "" {
for _, ennoblement := range es.tribeLostVillages(tribe.TribeID) { for _, ennoblement := range es.tribeLostVillages(tribe.TribeID) {
if !isPlayerTribeNil(ennoblement.NewOwner) && if !isPlayerTribeNil(ennoblement.NewOwner) &&
server.Tribes.Contains(tribe.World, ennoblement.NewOwner.Tribe.ID) { server.Tribes.Contains(tribe.World, ennoblement.NewOwner.Tribe.ID) {
continue continue
} }
msgData := newMessageData(tribe.World, ennoblement) newMsgDataConfig := newMessageDataConfig{
h.discord.SendMessage(server.LostVillagesChannelID, formatMsgAboutVillageLost(msgData)) host: langVersion.Host,
world: tribe.World,
ennoblement: ennoblement,
timezone: langVersion.Timezone,
}
msgData := newMessageData(newMsgDataConfig)
h.discord.SendEmbed(server.LostVillagesChannelID,
discord.
NewEmbed().
SetTitle("Stracona wioska").
SetTimestamp(msgData.date).
AddField(msgData.world, formatMsgAboutVillageLost(msgData)).
MessageEmbed)
} }
} }
if server.ConqueredVillagesChannelID != "" { if server.ConqueredVillagesChannelID != "" {
for _, ennoblement := range es.tribeConqueredVillages(tribe.TribeID) { for _, ennoblement := range es.tribeConqueredVillages(tribe.TribeID) {
if !isPlayerTribeNil(ennoblement.OldOwner) && if !isPlayerTribeNil(ennoblement.OldOwner) &&
server.Tribes.Contains(tribe.World, ennoblement.OldOwner.Tribe.ID) { server.Tribes.Contains(tribe.World, ennoblement.OldOwner.Tribe.ID) {
continue continue
} }
msgData := newMessageData(tribe.World, ennoblement) newMsgDataConfig := newMessageDataConfig{
h.discord.SendMessage(server.ConqueredVillagesChannelID, formatMsgAboutVillageConquest(msgData)) host: langVersion.Host,
world: tribe.World,
ennoblement: ennoblement,
timezone: langVersion.Timezone,
}
msgData := newMessageData(newMsgDataConfig)
h.discord.SendEmbed(server.ConqueredVillagesChannelID,
discord.
NewEmbed().
SetTitle("Podbita wioska").
AddField(msgData.world, formatMsgAboutVillageConquest(msgData)).
SetTimestamp(msgData.date).
MessageEmbed)
} }
} }
} }

View File

@ -30,5 +30,13 @@ func isVillageNil(village *shared_models.Village) bool {
} }
func formatDateOfConquest(loc *time.Location, t time.Time) string { func formatDateOfConquest(loc *time.Location, t time.Time) string {
return t.In(loc).Format("15:04:05") return t.In(loc).Format(time.RFC3339)
}
func getLocation(timezone string) *time.Location {
loc, err := time.LoadLocation(timezone)
if err != nil {
return time.UTC
}
return loc
} }

View File

@ -7,62 +7,91 @@ import (
shared_models "github.com/tribalwarshelp/shared/models" shared_models "github.com/tribalwarshelp/shared/models"
) )
const (
endpointTribeProfile = "/game.php?screen=info_ally&id=%d"
endpointPlayerProfile = "/game.php?screen=info_player&id=%d"
endpointVillageProfile = "/game.php?screen=info_village&id=%d"
)
type messageData struct { type messageData struct {
world string world string
date string date string
village string village string
villageURL string
oldOwnerName string oldOwnerName string
oldOwnerURL string
oldOwnerTribeURL string
oldOwnerTribeTag string oldOwnerTribeTag string
newOwnerURL string
newOwnerName string newOwnerName string
newOwnerTribeURL string
newOwnerTribeTag string newOwnerTribeTag string
} }
func newMessageData(world string, ennoblement *shared_models.Ennoblement) messageData { type newMessageDataConfig struct {
host string
world string
ennoblement *shared_models.Ennoblement
timezone string
}
func newMessageData(cfg newMessageDataConfig) messageData {
data := messageData{ data := messageData{
date: formatDateOfConquest(utils.GetLocation(utils.LanguageCodeFromWorldName(world)), ennoblement.EnnobledAt), date: formatDateOfConquest(getLocation(cfg.timezone), cfg.ennoblement.EnnobledAt),
world: world, world: cfg.world,
village: "-", village: "-",
oldOwnerName: "-", oldOwnerName: "-",
oldOwnerTribeTag: "-", oldOwnerTribeTag: "-",
newOwnerName: "-", newOwnerName: "-",
newOwnerTribeTag: "-", newOwnerTribeTag: "-",
} }
if !isVillageNil(ennoblement.Village) { if !isVillageNil(cfg.ennoblement.Village) {
data.village = fmt.Sprintf("%s (%d|%d)", ennoblement.Village.Name, ennoblement.Village.X, ennoblement.Village.Y) data.village = fmt.Sprintf("%s (%d|%d)",
cfg.ennoblement.Village.Name,
cfg.ennoblement.Village.X,
cfg.ennoblement.Village.Y)
data.villageURL = utils.FormatVillageURL(cfg.world, cfg.host, cfg.ennoblement.VillageID)
} }
if !isPlayerNil(ennoblement.OldOwner) { if !isPlayerNil(cfg.ennoblement.OldOwner) {
data.oldOwnerName = ennoblement.OldOwner.Name data.oldOwnerName = cfg.ennoblement.OldOwner.Name
data.oldOwnerURL = utils.FormatPlayerURL(cfg.world, cfg.host, cfg.ennoblement.OldOwner.ID)
} }
if !isPlayerTribeNil(ennoblement.OldOwner) { if !isPlayerTribeNil(cfg.ennoblement.OldOwner) {
data.oldOwnerTribeTag = ennoblement.OldOwner.Tribe.Tag data.oldOwnerTribeTag = cfg.ennoblement.OldOwner.Tribe.Tag
data.oldOwnerTribeURL = utils.FormatTribeURL(cfg.world, cfg.host, cfg.ennoblement.OldOwner.Tribe.ID)
} }
if !isPlayerNil(ennoblement.NewOwner) { if !isPlayerNil(cfg.ennoblement.NewOwner) {
data.newOwnerName = ennoblement.NewOwner.Name data.newOwnerName = cfg.ennoblement.NewOwner.Name
data.newOwnerURL = utils.FormatPlayerURL(cfg.world, cfg.host, cfg.ennoblement.NewOwner.ID)
} }
if !isPlayerTribeNil(ennoblement.NewOwner) { if !isPlayerTribeNil(cfg.ennoblement.NewOwner) {
data.newOwnerTribeTag = ennoblement.NewOwner.Tribe.Tag data.newOwnerTribeTag = cfg.ennoblement.NewOwner.Tribe.Tag
data.newOwnerTribeURL = utils.FormatTribeURL(cfg.world, cfg.host, cfg.ennoblement.NewOwner.Tribe.ID)
} }
return data return data
} }
func formatMsgLink(text string, url string) string {
if url == "" {
return text
}
return fmt.Sprintf("[%s](%s)", text, url)
}
func formatMsgAboutVillageLost(msgData messageData) string { func formatMsgAboutVillageLost(msgData messageData) string {
return fmt.Sprintf(`**%s** %s: Wioska **%s** gracza **%s** (**%s**) została stracona na rzecz **%s** (**%s**)`, return fmt.Sprintf(`Wioska %s gracza %s (%s) została stracona na rzecz %s (%s)`,
msgData.world, formatMsgLink(msgData.village, msgData.villageURL),
msgData.date, formatMsgLink(msgData.oldOwnerName, msgData.oldOwnerURL),
msgData.village, formatMsgLink(msgData.oldOwnerTribeTag, msgData.oldOwnerTribeURL),
msgData.oldOwnerName, formatMsgLink(msgData.newOwnerName, msgData.newOwnerURL),
msgData.oldOwnerTribeTag, formatMsgLink(msgData.newOwnerTribeTag, msgData.newOwnerTribeURL))
msgData.newOwnerName,
msgData.newOwnerTribeTag)
} }
func formatMsgAboutVillageConquest(msgData messageData) string { func formatMsgAboutVillageConquest(msgData messageData) string {
return fmt.Sprintf(`**%s** %s: Gracz **%s** (**%s**) podbił wioskę **%s** od gracza **%s** (**%s**)`, return fmt.Sprintf(`Gracz %s (%s) podbił wioskę %s od gracza %s (%s)`,
msgData.world, formatMsgLink(msgData.newOwnerName, msgData.newOwnerURL),
msgData.date, formatMsgLink(msgData.newOwnerTribeTag, msgData.newOwnerTribeURL),
msgData.newOwnerName, formatMsgLink(msgData.village, msgData.villageURL),
msgData.newOwnerTribeTag, formatMsgLink(msgData.oldOwnerName, msgData.oldOwnerURL),
msgData.village, formatMsgLink(msgData.oldOwnerTribeTag, msgData.oldOwnerTribeURL))
msgData.oldOwnerName,
msgData.oldOwnerTribeTag)
} }

View File

@ -1,14 +1,33 @@
package discord package discord
import (
"context"
"fmt"
"math"
"strconv"
shared_models "github.com/tribalwarshelp/shared/models"
"github.com/bwmarrin/discordgo"
"github.com/tribalwarshelp/dcbot/models"
"github.com/tribalwarshelp/dcbot/utils"
"github.com/tribalwarshelp/golang-sdk/sdk"
)
const (
TribesPerServer = 10
)
type Command string type Command string
var ( const (
HelpCommand Command = "help" HelpCommand Command = "help"
AddCommand Command = "add" AddCommand Command = "add"
ListCommand Command = "list" ListCommand Command = "list"
DeleteCommand Command = "delete" DeleteCommand Command = "delete"
LostVillagesCommand Command = "lostvillages" LostVillagesCommand Command = "lostvillages"
ConqueredVillagesCommand Command = "conqueredvillages" ConqueredVillagesCommand Command = "conqueredvillages"
TribeCommand Command = "tribe"
TopAttCommand Command = "topatt" TopAttCommand Command = "topatt"
TopDefCommand Command = "topdef" TopDefCommand Command = "topdef"
TopSuppCommand Command = "topsupp" TopSuppCommand Command = "topsupp"
@ -23,3 +42,342 @@ func (cmd Command) String() string {
func (cmd Command) WithPrefix(prefix string) string { func (cmd Command) WithPrefix(prefix string) string {
return prefix + cmd.String() return prefix + cmd.String()
} }
func (s *Session) handleHelpCommand(m *discordgo.MessageCreate) {
tribeCMDWithPrefix := TribeCommand.WithPrefix(s.cfg.CommandPrefix)
commandsForAll := fmt.Sprintf(`
- %s %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największym RA z plemion o podanych id
- %s %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największym RO z plemion o podanych id
- %s %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największym RW z plemion o podanych id
- %s %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największej liczbie pokonanych z plemion o podanych id
- %s %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największej liczbie punktów z plemion o podanych id
`,
tribeCMDWithPrefix,
TopAttCommand.String(),
tribeCMDWithPrefix,
TopDefCommand.String(),
tribeCMDWithPrefix,
TopSuppCommand.String(),
tribeCMDWithPrefix,
TopTotalCommand.String(),
tribeCMDWithPrefix,
TopPointsCommand.String())
commandsForGuildAdmins := fmt.Sprintf(`
- %s [świat] [id] - dodaje plemię z danego świata do obserwowanych
- %s - wyświetla wszystkie obserwowane plemiona
- %s [id z %s] - usuwa plemię z obserwowanych
- %s - ustawia kanał na którym będą wyświetlać się informacje o straconych wioskach
- %s - ustawia kanał na którym będą wyświetlać się informacje o podbitych wioskach
`,
AddCommand.WithPrefix(s.cfg.CommandPrefix),
ListCommand.WithPrefix(s.cfg.CommandPrefix),
DeleteCommand.WithPrefix(s.cfg.CommandPrefix),
ListCommand.WithPrefix(s.cfg.CommandPrefix),
LostVillagesCommand.WithPrefix(s.cfg.CommandPrefix),
ConqueredVillagesCommand.WithPrefix(s.cfg.CommandPrefix))
s.SendEmbed(m.ChannelID, NewEmbed().
SetTitle("Pomoc").
SetDescription("Komendy oferowane przez bota").
AddField("Dla wszystkich", commandsForAll).
AddField("Dla adminów", commandsForGuildAdmins).
MessageEmbed)
}
func (s *Session) handleTribeCommand(m *discordgo.MessageCreate, args ...string) {
argsLength := len(args)
if argsLength < 4 {
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s Niepoprawna komenda (sprawdź %s)",
m.Author.Mention(),
HelpCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
command := Command(args[0])
world := args[1]
page, err := strconv.Atoi(args[2])
if err != nil || page <= 0 {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s 3 argument musi być liczbą większą od 0.", m.Author.Mention()))
return
}
ids := []int{}
for _, arg := range args[3:argsLength] {
id, err := strconv.Atoi(arg)
if err != nil {
continue
}
ids = append(ids, id)
}
if len(ids) == 0 {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie wprowadziłeś ID plemion.", m.Author.Mention()))
return
}
exist := true
limit := 10
offset := (page - 1) * limit
filter := &shared_models.PlayerFilter{
Exist: &exist,
TribeID: ids,
Limit: limit,
Offset: offset,
}
title := ""
switch command {
case TopAttCommand:
filter.RankAttGTE = 1
filter.Sort = "rankAtt ASC"
title = "Top pokonani w ataku"
case TopDefCommand:
filter.RankDefGTE = 1
filter.Sort = "rankDef ASC"
title = "Top pokonani w obronie"
case TopSuppCommand:
filter.RankSupGTE = 1
filter.Sort = "rankSup ASC"
title = "Top pokonani jako wspierający"
case TopTotalCommand:
filter.RankTotalGTE = 1
filter.Sort = "rankTotal ASC"
title = "Top pokonani ogólnie"
case TopPointsCommand:
filter.Sort = "rank ASC"
title = "Najwięcej punktów"
default:
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s Nieznana komenda %s (sprawdź %s)",
m.Author.Mention(),
command.String(),
HelpCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
playersList, err := s.cfg.API.Players.Browse(world, filter, &sdk.PlayerInclude{
Tribe: true,
})
if err != nil {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie udało się wygenerować listy.", m.Author.Mention()))
return
}
if playersList.Total == 0 {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie znaleziono plemion o podanych ID.", m.Author.Mention()))
return
}
langVersion, err := s.cfg.API.LangVersions.Read(utils.LanguageCodeFromWorldName(world))
if err != nil {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie udało się wygenerować listy.", m.Author.Mention()))
return
}
msg := &EmbedMessage{}
for i, player := range playersList.Items {
rank := 0
score := 0
switch command {
case TopAttCommand:
rank = player.RankAtt
score = player.ScoreAtt
case TopDefCommand:
rank = player.RankDef
score = player.ScoreDef
case TopSuppCommand:
rank = player.RankSup
score = player.ScoreSup
case TopTotalCommand:
rank = player.RankTotal
score = player.ScoreTotal
case TopPointsCommand:
rank = player.Rank
score = player.Points
}
msg.Append(fmt.Sprintf("**%d**. [%s](%s) (Plemię: [%s](%s) | Ranking ogólny: **%d** | Wynik: **%d**)\n",
offset+i+1,
player.Name,
utils.FormatPlayerURL(world, langVersion.Host, player.ID),
player.Tribe.Tag,
utils.FormatTribeURL(world, langVersion.Host, player.Tribe.ID),
rank,
score))
}
totalPages := int(math.Round(float64(playersList.Total) / float64(limit)))
s.SendEmbed(m.ChannelID, NewEmbed().
SetTitle(title).
SetDescription("A oto lista!").
SetFields(msg.ToMessageEmbedFields()).
SetFooter(fmt.Sprintf("Strona %d z %d", page, totalPages)).
MessageEmbed)
}
func (s *Session) handleLostVillagesCommand(m *discordgo.MessageCreate) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
server := &models.Server{
ID: m.GuildID,
}
err := s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
return
}
server.LostVillagesChannelID = m.ChannelID
go s.cfg.ServerRepository.Update(context.Background(), server)
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s Pomyślnie zmieniono kanał na którym będą się wyświetlać informacje o straconych wioskach.", m.Author.Mention()))
}
func (s *Session) handleConqueredVillagesCommand(m *discordgo.MessageCreate) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
server := &models.Server{
ID: m.GuildID,
}
err := s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
return
}
server.ConqueredVillagesChannelID = m.ChannelID
go s.cfg.ServerRepository.Update(context.Background(), server)
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s Pomyślnie zmieniono kanał na którym będą się wyświetlać informacje o podbitych wioskach.", m.Author.Mention()))
}
func (s *Session) handleAddCommand(m *discordgo.MessageCreate, args ...string) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
argsLength := len(args)
if argsLength > 2 {
s.sendUnknownCommandError(m.Author.Mention(), m.ChannelID, args[2:argsLength]...)
return
} else if argsLength < 2 {
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s %s [świat] [id plemienia]",
m.Author.Mention(),
AddCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
world := args[0]
id, err := strconv.Atoi(args[1])
if err != nil {
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s %s [świat] [id plemienia]",
m.Author.Mention(),
AddCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
tribe, err := s.cfg.API.Tribes.Read(world, id)
if err != nil || tribe == nil {
s.SendMessage(m.ChannelID, m.Author.Mention()+fmt.Sprintf(` Plemię o ID: %d nie istnieje na świecie %s.`, id, world))
return
}
server := &models.Server{
ID: m.GuildID,
}
err = s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
s.SendMessage(m.ChannelID, m.Author.Mention()+` Nie udało się dodać plemienia do obserwowanych.`)
return
}
if len(server.Tribes) >= TribesPerServer {
s.SendMessage(m.ChannelID, m.Author.Mention()+fmt.Sprintf(` Osiągnięto limit plemion (%d/%d).`, TribesPerServer, TribesPerServer))
return
}
err = s.cfg.TribeRepository.Store(context.Background(), &models.Tribe{
World: world,
TribeID: id,
ServerID: server.ID,
})
if err != nil {
s.SendMessage(m.ChannelID, m.Author.Mention()+` Nie udało się dodać plemienia do obserwowanych.`)
return
}
s.SendMessage(m.ChannelID, m.Author.Mention()+` Dodano.`)
}
func (s *Session) handleDeleteCommand(m *discordgo.MessageCreate, args ...string) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
argsLength := len(args)
if argsLength > 1 {
s.sendUnknownCommandError(m.Author.Mention(), m.ChannelID, args[1:argsLength]...)
return
} else if argsLength < 1 {
s.SendMessage(m.ChannelID,
fmt.Sprintf(`%s %s [id z tw!list]`,
m.Author.Mention(),
DeleteCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
id, err := strconv.Atoi(args[0])
if err != nil {
s.SendMessage(m.ChannelID,
fmt.Sprintf(`%s %s [id z tw!list]`,
m.Author.Mention(),
DeleteCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
go s.cfg.TribeRepository.Delete(context.Background(), &models.TribeFilter{
ServerID: []string{m.GuildID},
ID: []int{id},
})
s.SendMessage(m.ChannelID, m.Author.Mention()+` Usunięto.`)
}
func (s *Session) handleListCommand(m *discordgo.MessageCreate) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
tribes, _, err := s.cfg.TribeRepository.Fetch(context.Background(), &models.TribeFilter{
ServerID: []string{m.GuildID},
})
if err != nil {
return
}
msg := ""
for i, tribe := range tribes {
msg += fmt.Sprintf("**%d**. %d - %s - %d\n", i+1, tribe.ID, tribe.World, tribe.TribeID)
}
s.SendEmbed(m.ChannelID, NewEmbed().
SetTitle("Lista obserwowanych plemion").
AddField("Indeks. ID - świat - ID plemienia", msg).
SetFooter("Strona 1 z 1").
MessageEmbed)
}

View File

@ -1,26 +1,16 @@
package discord package discord
import ( import (
"context"
"fmt" "fmt"
"math"
"strconv"
"strings" "strings"
"github.com/tribalwarshelp/dcbot/models"
"github.com/tribalwarshelp/dcbot/server" "github.com/tribalwarshelp/dcbot/server"
"github.com/tribalwarshelp/dcbot/tribe" "github.com/tribalwarshelp/dcbot/tribe"
"github.com/tribalwarshelp/golang-sdk/sdk" "github.com/tribalwarshelp/golang-sdk/sdk"
shared_models "github.com/tribalwarshelp/shared/models"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
) )
const (
TribesPerServer = 10
discordEmbedColor = 0x00ff00
)
type SessionConfig struct { type SessionConfig struct {
Token string Token string
CommandPrefix string CommandPrefix string
@ -64,6 +54,20 @@ func (s *Session) init() error {
return nil return nil
} }
func (s *Session) Close() error {
return s.dg.Close()
}
func (s *Session) SendMessage(channelID, message string) error {
_, err := s.dg.ChannelMessageSend(channelID, message)
return err
}
func (s *Session) SendEmbed(channelID string, message *discordgo.MessageEmbed) error {
_, err := s.dg.ChannelMessageSendEmbed(channelID, message)
return err
}
func (s *Session) handleNewMessage(_ *discordgo.Session, m *discordgo.MessageCreate) { func (s *Session) handleNewMessage(_ *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.ID == s.dg.State.User.ID || m.Author.Bot { if m.Author.ID == s.dg.State.User.ID || m.Author.Bot {
return return
@ -85,326 +89,11 @@ func (s *Session) handleNewMessage(_ *discordgo.Session, m *discordgo.MessageCre
s.handleLostVillagesCommand(m) s.handleLostVillagesCommand(m)
case ConqueredVillagesCommand.WithPrefix(s.cfg.CommandPrefix): case ConqueredVillagesCommand.WithPrefix(s.cfg.CommandPrefix):
s.handleConqueredVillagesCommand(m) s.handleConqueredVillagesCommand(m)
case TopAttCommand.WithPrefix(s.cfg.CommandPrefix): case TribeCommand.WithPrefix(s.cfg.CommandPrefix):
s.handleTopCommands(m, TopAttCommand, args...) s.handleTribeCommand(m, args...)
case TopDefCommand.WithPrefix(s.cfg.CommandPrefix):
s.handleTopCommands(m, TopDefCommand, args...)
case TopSuppCommand.WithPrefix(s.cfg.CommandPrefix):
s.handleTopCommands(m, TopSuppCommand, args...)
case TopTotalCommand.WithPrefix(s.cfg.CommandPrefix):
s.handleTopCommands(m, TopTotalCommand, args...)
case TopPointsCommand.WithPrefix(s.cfg.CommandPrefix):
s.handleTopCommands(m, TopPointsCommand, args...)
} }
} }
func (s *Session) handleHelpCommand(m *discordgo.MessageCreate) {
s.sendHelpMessage(m.ChannelID)
}
func (s *Session) handleTopCommands(m *discordgo.MessageCreate, command Command, args ...string) {
argsLength := len(args)
if argsLength < 3 {
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s %s [świat] [strona] [id...]",
m.Author.Mention(),
command.WithPrefix(s.cfg.CommandPrefix)))
return
}
world := args[0]
page, err := strconv.Atoi(args[1])
if err != nil || page <= 0 {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s 2 argument musi być liczbą większą od 0.", m.Author.Mention()))
return
}
ids := []int{}
for _, arg := range args[2:argsLength] {
id, err := strconv.Atoi(arg)
if err != nil {
continue
}
ids = append(ids, id)
}
if len(ids) == 0 {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie wprowadziłeś ID plemion.", m.Author.Mention()))
return
}
exist := true
limit := 10
offset := (page - 1) * limit
filter := &shared_models.PlayerFilter{
Exist: &exist,
TribeID: ids,
Limit: limit,
Offset: offset,
}
title := ""
switch command {
case TopAttCommand:
filter.RankAttGTE = 1
filter.Sort = "rankAtt ASC"
title = "Top pokonani w ataku"
case TopDefCommand:
filter.RankDefGTE = 1
filter.Sort = "rankDef ASC"
title = "Top pokonani w obronie"
case TopSuppCommand:
filter.RankSupGTE = 1
filter.Sort = "rankSup ASC"
title = "Top pokonani jako wspierający"
case TopTotalCommand:
filter.RankTotalGTE = 1
filter.Sort = "rankTotal ASC"
title = "Top pokonani ogólnie"
case TopPointsCommand:
filter.Sort = "rank ASC"
title = "Najwięcej punktów"
}
playersList, err := s.cfg.API.Players.Browse(world, filter, &sdk.PlayerInclude{
Tribe: true,
})
if err != nil {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie udało się wygenerować listy.", m.Author.Mention()))
return
}
if playersList.Total == 0 {
s.SendMessage(m.ChannelID, fmt.Sprintf("%s Nie znaleziono plemion o podanych ID.", m.Author.Mention()))
return
}
msg := ""
for i, player := range playersList.Items {
rank := 0
score := 0
switch command {
case TopAttCommand:
rank = player.RankAtt
score = player.ScoreAtt
case TopDefCommand:
rank = player.RankDef
score = player.ScoreDef
case TopSuppCommand:
rank = player.RankSup
score = player.ScoreSup
case TopTotalCommand:
rank = player.RankTotal
score = player.ScoreTotal
case TopPointsCommand:
rank = player.Rank
score = player.Points
}
msg += fmt.Sprintf("**%d**. **__%s__** (Plemię: **%s** | Ranking ogólny: **%d** | Wynik: **%d**)\n",
offset+i+1,
player.Name,
player.Tribe.Tag,
rank, score)
}
totalPages := int(math.Round(float64(playersList.Total) / float64(limit)))
s.dg.ChannelMessageSendEmbed(m.ChannelID, &discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{},
Color: discordEmbedColor,
Title: title,
Description: "A oto lista!",
Fields: []*discordgo.MessageEmbedField{
&discordgo.MessageEmbedField{
Name: "-",
Value: msg,
Inline: false,
},
},
Footer: &discordgo.MessageEmbedFooter{
Text: fmt.Sprintf("Strona %d z %d", page, totalPages),
},
})
}
func (s *Session) handleLostVillagesCommand(m *discordgo.MessageCreate) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
server := &models.Server{
ID: m.GuildID,
}
err := s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
return
}
server.LostVillagesChannelID = m.ChannelID
go s.cfg.ServerRepository.Update(context.Background(), server)
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s Pomyślnie zmieniono kanał na którym będą się wyświetlać informacje o straconych wioskach.", m.Author.Mention()))
}
func (s *Session) handleConqueredVillagesCommand(m *discordgo.MessageCreate) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
server := &models.Server{
ID: m.GuildID,
}
err := s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
return
}
server.ConqueredVillagesChannelID = m.ChannelID
go s.cfg.ServerRepository.Update(context.Background(), server)
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s Pomyślnie zmieniono kanał na którym będą się wyświetlać informacje o podbitych wioskach.", m.Author.Mention()))
}
func (s *Session) handleAddCommand(m *discordgo.MessageCreate, args ...string) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
argsLength := len(args)
if argsLength > 2 {
s.sendUnknownCommandError(m.Author.Mention(), m.ChannelID, args[2:argsLength]...)
return
} else if argsLength < 2 {
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s %s [świat] [id plemienia]",
m.Author.Mention(),
AddCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
world := args[0]
id, err := strconv.Atoi(args[1])
if err != nil {
s.SendMessage(m.ChannelID,
fmt.Sprintf("%s %s [świat] [id plemienia]",
m.Author.Mention(),
AddCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
tribe, err := s.cfg.API.Tribes.Read(world, id)
if err != nil || tribe == nil {
s.SendMessage(m.ChannelID, m.Author.Mention()+fmt.Sprintf(` Plemię o ID: %d nie istnieje na świecie %s.`, id, world))
return
}
server := &models.Server{
ID: m.GuildID,
}
err = s.cfg.ServerRepository.Store(context.Background(), server)
if err != nil {
s.SendMessage(m.ChannelID, m.Author.Mention()+` Nie udało się dodać plemienia do obserwowanych.`)
return
}
if len(server.Tribes) >= TribesPerServer {
s.SendMessage(m.ChannelID, m.Author.Mention()+fmt.Sprintf(` Osiągnięto limit plemion (%d/%d).`, TribesPerServer, TribesPerServer))
return
}
err = s.cfg.TribeRepository.Store(context.Background(), &models.Tribe{
World: world,
TribeID: id,
ServerID: server.ID,
})
if err != nil {
s.SendMessage(m.ChannelID, m.Author.Mention()+` Nie udało się dodać plemienia do obserwowanych.`)
return
}
s.SendMessage(m.ChannelID, m.Author.Mention()+` Dodano.`)
}
func (s *Session) handleDeleteCommand(m *discordgo.MessageCreate, args ...string) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
argsLength := len(args)
if argsLength > 1 {
s.sendUnknownCommandError(m.Author.Mention(), m.ChannelID, args[1:argsLength]...)
return
} else if argsLength < 1 {
s.SendMessage(m.ChannelID,
fmt.Sprintf(`%s %s [id z tw!list]`,
m.Author.Mention(),
DeleteCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
id, err := strconv.Atoi(args[0])
if err != nil {
s.SendMessage(m.ChannelID,
fmt.Sprintf(`%s %s [id z tw!list]`,
m.Author.Mention(),
DeleteCommand.WithPrefix(s.cfg.CommandPrefix)))
return
}
go s.cfg.TribeRepository.Delete(context.Background(), &models.TribeFilter{
ServerID: []string{m.GuildID},
ID: []int{id},
})
s.SendMessage(m.ChannelID, m.Author.Mention()+` Usunięto.`)
}
func (s *Session) handleListCommand(m *discordgo.MessageCreate) {
if m.GuildID == "" {
return
}
if has, err := s.memberHasPermission(m.GuildID, m.Author.ID, discordgo.PermissionAdministrator); err != nil || !has {
return
}
tribes, _, err := s.cfg.TribeRepository.Fetch(context.Background(), &models.TribeFilter{
ServerID: []string{m.GuildID},
})
if err != nil {
return
}
msg := ""
for i, tribe := range tribes {
msg += fmt.Sprintf("**%d**. %d - %s - %d\n", i+1, tribe.ID, tribe.World, tribe.TribeID)
}
s.dg.ChannelMessageSendEmbed(m.ChannelID, &discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{},
Title: "Lista obserwowanych plemion",
Color: discordEmbedColor,
Fields: []*discordgo.MessageEmbedField{
&discordgo.MessageEmbedField{
Name: "Indeks. ID - świat - ID plemienia",
Value: msg,
},
},
Footer: &discordgo.MessageEmbedFooter{
Text: "Strona 1 z 1",
},
})
}
func (s *Session) Close() error {
return s.dg.Close()
}
func (s *Session) memberHasPermission(guildID string, userID string, permission int) (bool, error) { func (s *Session) memberHasPermission(guildID string, userID string, permission int) (bool, error) {
guild, err := s.dg.State.Guild(guildID) guild, err := s.dg.State.Guild(guildID)
if err != nil { if err != nil {
@ -438,58 +127,6 @@ func (s *Session) memberHasPermission(guildID string, userID string, permission
return false, nil return false, nil
} }
func (s *Session) sendHelpMessage(channelID string) {
embed := &discordgo.MessageEmbed{
Author: &discordgo.MessageEmbedAuthor{},
Color: discordEmbedColor,
Title: "Pomoc",
Description: "Komendy oferowane przez bota",
Fields: []*discordgo.MessageEmbedField{
&discordgo.MessageEmbedField{
Name: "Dla wszystkich",
Value: fmt.Sprintf(`
- %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największym RA z plemion o podanych id
- %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największym RO z plemion o podanych id
- %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największym RW z plemion o podanych id
- %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największej liczbie pokonanych z plemion o podanych id
- %s [serwer] [strona] [id1] [id2] [id3] [n id] - wyświetla graczy o największej liczbie punktów z plemion o podanych id
`,
TopAttCommand.WithPrefix(s.cfg.CommandPrefix),
TopDefCommand.WithPrefix(s.cfg.CommandPrefix),
TopSuppCommand.WithPrefix(s.cfg.CommandPrefix),
TopTotalCommand.WithPrefix(s.cfg.CommandPrefix),
TopPointsCommand.WithPrefix(s.cfg.CommandPrefix)),
Inline: false,
},
&discordgo.MessageEmbedField{
Name: "Dla adminów",
Value: fmt.Sprintf(`
- %s [świat] [id] - dodaje plemię z danego świata do obserwowanych
- %s - wyświetla wszystkie obserwowane plemiona
- %s [id z %s] - usuwa plemię z obserwowanych
- %s - ustawia kanał na którym będą wyświetlać się informacje o straconych wioskach
- %s - ustawia kanał na którym będą wyświetlać się informacje o podbitych wioskach
`,
AddCommand.WithPrefix(s.cfg.CommandPrefix),
ListCommand.WithPrefix(s.cfg.CommandPrefix),
DeleteCommand.WithPrefix(s.cfg.CommandPrefix),
ListCommand.WithPrefix(s.cfg.CommandPrefix),
LostVillagesCommand.WithPrefix(s.cfg.CommandPrefix),
ConqueredVillagesCommand.WithPrefix(s.cfg.CommandPrefix)),
Inline: false,
},
},
Footer: &discordgo.MessageEmbedFooter{
Text: "https://dawid-wysokinski.pl/",
},
}
s.dg.ChannelMessageSendEmbed(channelID, embed)
}
func (s *Session) sendUnknownCommandError(mention, channelID string, command ...string) { func (s *Session) sendUnknownCommandError(mention, channelID string, command ...string) {
s.SendMessage(channelID, mention+` Nieznana komenda: `+strings.Join(command, " ")) s.SendMessage(channelID, mention+` Nieznana komenda: `+strings.Join(command, " "))
} }
func (s *Session) SendMessage(channelID, message string) {
s.dg.ChannelMessageSend(channelID, message)
}

279
discord/embed.go Normal file
View File

@ -0,0 +1,279 @@
package discord
import "github.com/bwmarrin/discordgo"
// Constants for message embed character limits
const (
discordEmbedColor = 0x00ff00
EmbedLimitTitle = 256
EmbedLimitDescription = 2048
EmbedLimitFieldValue = 1024
EmbedLimitFieldName = 256
EmbedLimitField = 25
EmbedLimitFooter = 2048
EmbedLimit = 4000
)
type Embed struct {
*discordgo.MessageEmbed
}
//NewEmbed returns a new embed object
func NewEmbed() *Embed {
return &Embed{&discordgo.MessageEmbed{
Color: discordEmbedColor,
}}
}
//SetTitle ...
func (e *Embed) SetTitle(name string) *Embed {
e.Title = name
return e
}
func (e *Embed) SetTimestamp(timestamp string) *Embed {
e.Timestamp = timestamp
return e
}
//SetDescription [desc]
func (e *Embed) SetDescription(description string) *Embed {
if len(description) > EmbedLimitDescription {
description = description[:EmbedLimitDescription]
}
e.Description = description
return e
}
//AddField [name] [value]
func (e *Embed) AddField(name, value string) *Embed {
if len(value) > EmbedLimitFieldValue {
value = value[:EmbedLimitFieldValue]
}
if len(name) > EmbedLimitFieldName {
name = name[:EmbedLimitFieldName]
}
e.Fields = append(e.Fields, &discordgo.MessageEmbedField{
Name: name,
Value: value,
})
return e
}
func (e *Embed) SetFields(fields []*discordgo.MessageEmbedField) *Embed {
e.Fields = fields
return e
}
//SetFooter [Text] [iconURL]
func (e *Embed) SetFooter(args ...string) *Embed {
iconURL := ""
text := ""
proxyURL := ""
switch {
case len(args) > 2:
proxyURL = args[2]
fallthrough
case len(args) > 1:
iconURL = args[1]
fallthrough
case len(args) > 0:
text = args[0]
case len(args) == 0:
return e
}
e.Footer = &discordgo.MessageEmbedFooter{
IconURL: iconURL,
Text: text,
ProxyIconURL: proxyURL,
}
return e
}
//SetImage ...
func (e *Embed) SetImage(args ...string) *Embed {
var URL string
var proxyURL string
if len(args) == 0 {
return e
}
if len(args) > 0 {
URL = args[0]
}
if len(args) > 1 {
proxyURL = args[1]
}
e.Image = &discordgo.MessageEmbedImage{
URL: URL,
ProxyURL: proxyURL,
}
return e
}
//SetThumbnail ...
func (e *Embed) SetThumbnail(args ...string) *Embed {
var URL string
var proxyURL string
if len(args) == 0 {
return e
}
if len(args) > 0 {
URL = args[0]
}
if len(args) > 1 {
proxyURL = args[1]
}
e.Thumbnail = &discordgo.MessageEmbedThumbnail{
URL: URL,
ProxyURL: proxyURL,
}
return e
}
//SetAuthor ...
func (e *Embed) SetAuthor(args ...string) *Embed {
var (
name string
iconURL string
URL string
proxyURL string
)
if len(args) == 0 {
return e
}
if len(args) > 0 {
name = args[0]
}
if len(args) > 1 {
iconURL = args[1]
}
if len(args) > 2 {
URL = args[2]
}
if len(args) > 3 {
proxyURL = args[3]
}
e.Author = &discordgo.MessageEmbedAuthor{
Name: name,
IconURL: iconURL,
URL: URL,
ProxyIconURL: proxyURL,
}
return e
}
//SetURL ...
func (e *Embed) SetURL(URL string) *Embed {
e.URL = URL
return e
}
//SetColor ...
func (e *Embed) SetColor(clr int) *Embed {
e.Color = clr
return e
}
// InlineAllFields sets all fields in the embed to be inline
func (e *Embed) InlineAllFields() *Embed {
for _, v := range e.Fields {
v.Inline = true
}
return e
}
// Truncate truncates any embed value over the character limit.
func (e *Embed) Truncate() *Embed {
e.TruncateDescription()
e.TruncateFields()
e.TruncateFooter()
e.TruncateTitle()
return e
}
// TruncateFields truncates fields that are too long
func (e *Embed) TruncateFields() *Embed {
if len(e.Fields) > 25 {
e.Fields = e.Fields[:EmbedLimitField]
}
for _, v := range e.Fields {
if len(v.Name) > EmbedLimitFieldName {
v.Name = v.Name[:EmbedLimitFieldName]
}
if len(v.Value) > EmbedLimitFieldValue {
v.Value = v.Value[:EmbedLimitFieldValue]
}
}
return e
}
// TruncateDescription ...
func (e *Embed) TruncateDescription() *Embed {
if len(e.Description) > EmbedLimitDescription {
e.Description = e.Description[:EmbedLimitDescription]
}
return e
}
// TruncateTitle ...
func (e *Embed) TruncateTitle() *Embed {
if len(e.Title) > EmbedLimitTitle {
e.Title = e.Title[:EmbedLimitTitle]
}
return e
}
// TruncateFooter ...
func (e *Embed) TruncateFooter() *Embed {
if e.Footer != nil && len(e.Footer.Text) > EmbedLimitFooter {
e.Footer.Text = e.Footer.Text[:EmbedLimitFooter]
}
return e
}
type EmbedMessage struct {
Chunks []string
Index int
}
func (msg *EmbedMessage) Append(m string) {
if len(msg.Chunks) < msg.Index+1 {
msg.Chunks = append(msg.Chunks, "")
}
if len(m)+len(msg.Chunks[msg.Index]) > EmbedLimitFieldValue {
msg.Chunks = append(msg.Chunks, m)
msg.Index++
return
}
msg.Chunks[msg.Index] += m
}
func (msg *EmbedMessage) ToMessageEmbedFields() []*discordgo.MessageEmbedField {
fields := []*discordgo.MessageEmbedField{}
for _, chunk := range msg.Chunks {
fields = append(fields, &discordgo.MessageEmbedField{
Name: "-",
Value: chunk,
})
}
return fields
}

View File

@ -29,7 +29,7 @@ func init() {
} }
func main() { func main() {
api := sdk.New(os.Getenv("API_URI")) api := sdk.New(os.Getenv("API_URL"))
//postgres //postgres
db := pg.Connect(&pg.Options{ db := pg.Connect(&pg.Options{
User: os.Getenv("DB_USER"), User: os.Getenv("DB_USER"),

View File

@ -0,0 +1,21 @@
package utils
import "fmt"
const (
endpointTribeProfile = "/game.php?screen=info_ally&id=%d"
endpointPlayerProfile = "/game.php?screen=info_player&id=%d"
endpointVillageProfile = "/game.php?screen=info_village&id=%d"
)
func FormatVillageURL(world, host string, id int) string {
return fmt.Sprintf("https://%s.%s"+endpointVillageProfile, world, host, id)
}
func FormatTribeURL(world, host string, id int) string {
return fmt.Sprintf("https://%s.%s"+endpointTribeProfile, world, host, id)
}
func FormatPlayerURL(world, host string, id int) string {
return fmt.Sprintf("https://%s.%s"+endpointPlayerProfile, world, host, id)
}

View File

@ -1,8 +1,12 @@
package utils package utils
func LanguageCodeFromWorldName(world string) string { import (
"github.com/tribalwarshelp/shared/models"
)
func LanguageCodeFromWorldName(world string) models.LanguageTag {
if len(world) < 2 { if len(world) < 2 {
return "" return ""
} }
return world[0:2] return models.LanguageTag(world[0:2])
} }

View File

@ -1,13 +0,0 @@
package utils
import "time"
func GetLocation(lang string) *time.Location {
switch lang {
case "pl":
loc, _ := time.LoadLocation("Europe/Warsaw")
return loc
default:
return time.UTC
}
}