2020-06-07 15:49:33 +00:00
|
|
|
package cron
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-07-27 15:54:51 +00:00
|
|
|
"fmt"
|
2020-06-07 15:49:33 +00:00
|
|
|
"time"
|
|
|
|
|
2020-10-31 11:16:21 +00:00
|
|
|
"github.com/tribalwarshelp/shared/tw"
|
2020-10-24 18:38:11 +00:00
|
|
|
|
2020-07-19 14:21:32 +00:00
|
|
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
|
|
|
"github.com/tribalwarshelp/dcbot/message"
|
|
|
|
|
2020-07-09 11:30:02 +00:00
|
|
|
"github.com/pkg/errors"
|
2020-07-21 13:14:29 +00:00
|
|
|
"github.com/tribalwarshelp/shared/mode"
|
2020-06-07 15:49:33 +00:00
|
|
|
shared_models "github.com/tribalwarshelp/shared/models"
|
|
|
|
|
|
|
|
"github.com/tribalwarshelp/dcbot/discord"
|
2020-06-26 18:30:25 +00:00
|
|
|
"github.com/tribalwarshelp/dcbot/group"
|
2020-06-18 12:51:31 +00:00
|
|
|
"github.com/tribalwarshelp/dcbot/models"
|
|
|
|
"github.com/tribalwarshelp/dcbot/observation"
|
2020-06-07 15:49:33 +00:00
|
|
|
"github.com/tribalwarshelp/dcbot/server"
|
|
|
|
"github.com/tribalwarshelp/dcbot/utils"
|
|
|
|
"github.com/tribalwarshelp/golang-sdk/sdk"
|
|
|
|
)
|
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
type handler struct {
|
2020-06-24 14:50:29 +00:00
|
|
|
lastEnnoblementAt map[string]time.Time
|
|
|
|
serverRepo server.Repository
|
|
|
|
observationRepo observation.Repository
|
2020-06-26 18:30:25 +00:00
|
|
|
groupRepo group.Repository
|
2020-06-24 14:50:29 +00:00
|
|
|
discord *discord.Session
|
|
|
|
api *sdk.SDK
|
2020-07-15 10:03:43 +00:00
|
|
|
status string
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
func (h *handler) loadEnnoblements(servers []string) (map[string]ennoblements, error) {
|
2020-06-07 15:49:33 +00:00
|
|
|
m := make(map[string]ennoblements)
|
|
|
|
|
2020-10-14 03:45:31 +00:00
|
|
|
if len(servers) == 0 {
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
2020-07-27 15:54:51 +00:00
|
|
|
query := ""
|
|
|
|
|
2021-01-15 18:32:36 +00:00
|
|
|
for _, server := range servers {
|
|
|
|
lastEnnoblementAt, ok := h.lastEnnoblementAt[server]
|
|
|
|
if !ok {
|
|
|
|
lastEnnoblementAt = time.Now().Add(-1 * time.Minute)
|
2021-01-16 21:24:11 +00:00
|
|
|
h.lastEnnoblementAt[server] = lastEnnoblementAt
|
2021-01-15 18:32:36 +00:00
|
|
|
}
|
|
|
|
if mode.Get() == mode.DevelopmentMode {
|
|
|
|
lastEnnoblementAt = time.Now().Add(-1 * time.Hour * 2)
|
|
|
|
}
|
|
|
|
lastEnnoblementAtJSON, err := lastEnnoblementAt.MarshalJSON()
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
2020-07-27 15:54:51 +00:00
|
|
|
query += fmt.Sprintf(`
|
2021-01-15 18:32:36 +00:00
|
|
|
%s: ennoblements(server: "%s", filter: { ennobledAtGT: %s }) {
|
|
|
|
items {
|
|
|
|
%s
|
|
|
|
ennobledAt
|
|
|
|
}
|
2020-07-27 15:54:51 +00:00
|
|
|
}
|
2021-01-15 18:32:36 +00:00
|
|
|
`, server,
|
|
|
|
server,
|
|
|
|
string(lastEnnoblementAtJSON),
|
|
|
|
sdk.EnnoblementInclude{
|
|
|
|
NewOwner: true,
|
|
|
|
Village: true,
|
|
|
|
NewOwnerInclude: sdk.PlayerInclude{
|
|
|
|
Tribe: true,
|
|
|
|
},
|
|
|
|
OldOwner: true,
|
|
|
|
OldOwnerInclude: sdk.PlayerInclude{
|
|
|
|
Tribe: true,
|
|
|
|
},
|
|
|
|
}.String())
|
2020-07-27 15:54:51 +00:00
|
|
|
}
|
|
|
|
|
2021-01-15 18:32:36 +00:00
|
|
|
resp := make(map[string]*sdk.EnnoblementList)
|
2020-10-24 18:38:11 +00:00
|
|
|
if err := h.api.Post(fmt.Sprintf(`query { %s }`, query), &resp); err != nil {
|
2020-07-27 15:54:51 +00:00
|
|
|
return m, errors.Wrap(err, "loadEnnoblements")
|
|
|
|
}
|
|
|
|
|
2021-01-15 18:32:36 +00:00
|
|
|
for server, singleServerResp := range resp {
|
|
|
|
if singleServerResp == nil {
|
|
|
|
continue
|
2020-07-21 13:14:29 +00:00
|
|
|
}
|
2021-01-15 18:32:36 +00:00
|
|
|
m[server] = ennoblements(singleServerResp.Items)
|
2020-07-27 15:54:51 +00:00
|
|
|
lastEnnoblement := m[server].getLastEnnoblement()
|
2020-06-12 16:28:07 +00:00
|
|
|
if lastEnnoblement != nil {
|
2021-01-15 18:32:36 +00:00
|
|
|
h.lastEnnoblementAt[server] = lastEnnoblement.EnnobledAt
|
2020-06-12 16:28:07 +00:00
|
|
|
}
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 15:54:51 +00:00
|
|
|
return m, nil
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
|
2020-11-06 19:37:49 +00:00
|
|
|
func (h *handler) loadVersions(servers []string) ([]*shared_models.Version, error) {
|
|
|
|
versionCodes := []shared_models.VersionCode{}
|
|
|
|
cache := make(map[shared_models.VersionCode]bool)
|
2020-06-27 16:48:33 +00:00
|
|
|
for _, server := range servers {
|
2020-11-06 19:37:49 +00:00
|
|
|
languageTag := tw.VersionCodeFromServerKey(server)
|
2020-06-07 15:49:33 +00:00
|
|
|
if languageTag.IsValid() && !cache[languageTag] {
|
|
|
|
cache[languageTag] = true
|
2020-11-06 19:37:49 +00:00
|
|
|
versionCodes = append(versionCodes, languageTag)
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-06 19:37:49 +00:00
|
|
|
if len(versionCodes) == 0 {
|
|
|
|
return []*shared_models.Version{}, nil
|
2020-10-24 18:38:11 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 12:13:29 +00:00
|
|
|
versionList, err := h.api.Version.Browse(0, 0, []string{"code ASC"}, &shared_models.VersionFilter{
|
2020-11-06 19:37:49 +00:00
|
|
|
Code: versionCodes,
|
2020-06-07 15:49:33 +00:00
|
|
|
})
|
2020-07-09 11:30:02 +00:00
|
|
|
if err != nil {
|
2021-01-13 19:24:52 +00:00
|
|
|
return nil, errors.Wrap(err, "cannot load versions")
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
|
2020-11-06 19:37:49 +00:00
|
|
|
return versionList.Items, nil
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
func (h *handler) checkEnnoblements() {
|
|
|
|
servers, err := h.observationRepo.FetchServers(context.Background())
|
2020-06-07 15:49:33 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Errorln("checkEnnoblements:", err.Error())
|
2020-06-07 15:49:33 +00:00
|
|
|
return
|
|
|
|
}
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
|
|
|
WithField("servers", servers).
|
2020-10-24 18:38:11 +00:00
|
|
|
Info("checkEnnoblements: loaded servers")
|
2020-06-07 15:49:33 +00:00
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
groups, total, err := h.groupRepo.Fetch(context.Background(), nil)
|
2020-06-07 15:49:33 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Errorln("checkEnnoblements:", err.Error())
|
2020-06-07 15:49:33 +00:00
|
|
|
return
|
|
|
|
}
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
|
|
|
WithField("numberOfGroups", total).
|
2021-01-13 19:03:50 +00:00
|
|
|
Info("checkEnnoblements: loaded groups")
|
2020-06-07 15:49:33 +00:00
|
|
|
|
2020-11-06 19:37:49 +00:00
|
|
|
versions, err := h.loadVersions(servers)
|
2020-07-09 11:30:02 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Errorln("checkEnnoblements:", err)
|
2020-07-09 11:30:02 +00:00
|
|
|
return
|
|
|
|
}
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
2020-11-06 19:37:49 +00:00
|
|
|
WithField("numberOfVersions", len(versions)).
|
2021-01-13 19:03:50 +00:00
|
|
|
Info("checkEnnoblements: loaded versions")
|
2020-10-24 06:17:52 +00:00
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
ennoblementsByServerKey, err := h.loadEnnoblements(servers)
|
2020-07-27 15:54:51 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Errorln("checkEnnoblements:", err)
|
2020-07-27 15:54:51 +00:00
|
|
|
}
|
2021-01-13 19:03:50 +00:00
|
|
|
log.Info("checkEnnoblements: loaded ennoblements")
|
2020-06-07 15:49:33 +00:00
|
|
|
|
2020-06-26 18:30:25 +00:00
|
|
|
for _, group := range groups {
|
|
|
|
if group.ConqueredVillagesChannelID == "" && group.LostVillagesChannelID == "" {
|
2020-06-07 15:49:33 +00:00
|
|
|
continue
|
|
|
|
}
|
2020-07-19 14:21:32 +00:00
|
|
|
localizer := message.NewLocalizer(group.Server.Lang)
|
2020-10-17 06:47:39 +00:00
|
|
|
lostVillagesMsg := &discord.MessageEmbed{}
|
|
|
|
conqueredVillagesMsg := &discord.MessageEmbed{}
|
2020-06-26 18:30:25 +00:00
|
|
|
for _, observation := range group.Observations {
|
|
|
|
ennoblements, ok := ennoblementsByServerKey[observation.Server]
|
2020-11-06 19:37:49 +00:00
|
|
|
version := utils.FindVersionByCode(versions, tw.VersionCodeFromServerKey(observation.Server))
|
|
|
|
if ok && version != nil && version.Host != "" {
|
2020-06-26 18:30:25 +00:00
|
|
|
if group.LostVillagesChannelID != "" {
|
|
|
|
for _, ennoblement := range ennoblements.getLostVillagesByTribe(observation.TribeID) {
|
2020-08-09 15:20:23 +00:00
|
|
|
if !utils.IsPlayerTribeNil(ennoblement.NewOwner) &&
|
2020-06-26 18:30:25 +00:00
|
|
|
group.Observations.Contains(observation.Server, ennoblement.NewOwner.Tribe.ID) {
|
2020-06-07 15:49:33 +00:00
|
|
|
continue
|
|
|
|
}
|
2020-06-27 16:48:33 +00:00
|
|
|
newMsgDataConfig := newMessageConfig{
|
2020-11-06 19:37:49 +00:00
|
|
|
host: version.Host,
|
2020-06-27 16:48:33 +00:00
|
|
|
server: observation.Server,
|
2020-06-07 15:49:33 +00:00
|
|
|
ennoblement: ennoblement,
|
2020-06-27 16:48:33 +00:00
|
|
|
t: messageTypeLost,
|
2020-07-19 14:21:32 +00:00
|
|
|
localizer: localizer,
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
2020-07-15 12:46:18 +00:00
|
|
|
lostVillagesMsg.Append(newMessage(newMsgDataConfig).String())
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-26 18:30:25 +00:00
|
|
|
if group.ConqueredVillagesChannelID != "" {
|
2020-07-27 15:54:51 +00:00
|
|
|
for _, ennoblement := range ennoblements.getConqueredVillagesByTribe(observation.TribeID, group.ShowInternals) {
|
2020-08-09 15:20:23 +00:00
|
|
|
isInTheSameGroup := !utils.IsPlayerTribeNil(ennoblement.OldOwner) &&
|
2020-07-21 12:01:08 +00:00
|
|
|
group.Observations.Contains(observation.Server, ennoblement.OldOwner.Tribe.ID)
|
2020-07-27 15:54:51 +00:00
|
|
|
if (!group.ShowInternals && isInTheSameGroup) ||
|
2020-07-22 13:46:10 +00:00
|
|
|
(!group.ShowEnnobledBarbarians && isBarbarian(ennoblement.OldOwner)) {
|
2020-06-07 15:49:33 +00:00
|
|
|
continue
|
|
|
|
}
|
2020-07-21 09:51:58 +00:00
|
|
|
|
2020-06-27 16:48:33 +00:00
|
|
|
newMsgDataConfig := newMessageConfig{
|
2020-11-06 19:37:49 +00:00
|
|
|
host: version.Host,
|
2020-06-27 16:48:33 +00:00
|
|
|
server: observation.Server,
|
2020-06-07 15:49:33 +00:00
|
|
|
ennoblement: ennoblement,
|
2020-06-27 16:48:33 +00:00
|
|
|
t: messageTypeConquer,
|
2020-07-19 14:21:32 +00:00
|
|
|
localizer: localizer,
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
2020-07-15 12:46:18 +00:00
|
|
|
conqueredVillagesMsg.Append(newMessage(newMsgDataConfig).String())
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-15 12:46:18 +00:00
|
|
|
|
2021-01-13 19:03:50 +00:00
|
|
|
timestamp := time.Now().Format(time.RFC3339)
|
2020-07-15 12:46:18 +00:00
|
|
|
if group.ConqueredVillagesChannelID != "" && !conqueredVillagesMsg.IsEmpty() {
|
2020-07-21 13:14:29 +00:00
|
|
|
title := localizer.MustLocalize(&i18n.LocalizeConfig{
|
2020-10-17 10:43:27 +00:00
|
|
|
MessageID: message.CronConqueredVillagesTitle,
|
|
|
|
DefaultMessage: message.FallbackMsg(message.CronConqueredVillagesTitle,
|
2020-07-21 13:14:29 +00:00
|
|
|
"Conquered villages"),
|
|
|
|
})
|
2020-10-24 18:38:11 +00:00
|
|
|
go h.discord.SendEmbed(group.ConqueredVillagesChannelID,
|
2020-07-22 13:46:10 +00:00
|
|
|
discord.
|
|
|
|
NewEmbed().
|
|
|
|
SetTitle(title).
|
2020-08-08 12:02:32 +00:00
|
|
|
SetColor(colorConqueredVillages).
|
2020-07-22 13:46:10 +00:00
|
|
|
SetFields(conqueredVillagesMsg.ToMessageEmbedFields()).
|
2021-01-13 19:03:50 +00:00
|
|
|
SetTimestamp(timestamp).
|
2020-07-22 13:46:10 +00:00
|
|
|
MessageEmbed)
|
2020-07-15 12:46:18 +00:00
|
|
|
}
|
2020-07-21 09:51:58 +00:00
|
|
|
|
2020-07-15 12:46:18 +00:00
|
|
|
if group.LostVillagesChannelID != "" && !lostVillagesMsg.IsEmpty() {
|
2020-07-21 13:14:29 +00:00
|
|
|
title := localizer.MustLocalize(&i18n.LocalizeConfig{
|
2020-10-17 10:43:27 +00:00
|
|
|
MessageID: message.CronLostVillagesTitle,
|
|
|
|
DefaultMessage: message.FallbackMsg(message.CronLostVillagesTitle,
|
2020-07-21 13:14:29 +00:00
|
|
|
"Lost villages"),
|
|
|
|
})
|
2020-10-24 18:38:11 +00:00
|
|
|
go h.discord.SendEmbed(group.LostVillagesChannelID,
|
2020-07-22 13:46:10 +00:00
|
|
|
discord.
|
|
|
|
NewEmbed().
|
|
|
|
SetTitle(title).
|
2020-08-08 12:02:32 +00:00
|
|
|
SetColor(colorLostVillages).
|
2020-07-22 13:46:10 +00:00
|
|
|
SetFields(lostVillagesMsg.ToMessageEmbedFields()).
|
2021-01-13 19:03:50 +00:00
|
|
|
SetTimestamp(timestamp).
|
2020-07-22 13:46:10 +00:00
|
|
|
MessageEmbed)
|
2020-07-15 12:46:18 +00:00
|
|
|
}
|
2020-06-07 15:49:33 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-18 12:51:31 +00:00
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
func (h *handler) checkBotServers() {
|
|
|
|
servers, total, err := h.serverRepo.Fetch(context.Background(), nil)
|
2020-06-18 12:51:31 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Error("checkBotServers: " + err.Error())
|
2020-06-18 12:51:31 +00:00
|
|
|
return
|
|
|
|
}
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
|
|
|
WithField("numberOfServers", total).
|
|
|
|
Info("checkBotServers: loaded servers")
|
2020-06-18 12:51:31 +00:00
|
|
|
|
|
|
|
idsToDelete := []string{}
|
|
|
|
for _, server := range servers {
|
2020-10-24 18:38:11 +00:00
|
|
|
if isGuildMember, _ := h.discord.IsGuildMember(server.ID); !isGuildMember {
|
2020-06-18 12:51:31 +00:00
|
|
|
idsToDelete = append(idsToDelete, server.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(idsToDelete) > 0 {
|
2020-10-24 18:38:11 +00:00
|
|
|
deleted, err := h.serverRepo.Delete(context.Background(), &models.ServerFilter{
|
2020-06-18 12:51:31 +00:00
|
|
|
ID: idsToDelete,
|
|
|
|
})
|
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Error("checkBotServers: " + err.Error())
|
2020-06-18 12:51:31 +00:00
|
|
|
} else {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
|
|
|
WithField("numberOfDeletedServers", len(deleted)).
|
|
|
|
Info("checkBotServers: deleted servers")
|
2020-06-18 12:51:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
func (h *handler) deleteClosedTribalWarsServers() {
|
|
|
|
servers, err := h.observationRepo.FetchServers(context.Background())
|
2020-06-18 12:51:31 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Error("deleteClosedTribalWarsServers: " + err.Error())
|
2020-06-18 12:51:31 +00:00
|
|
|
return
|
|
|
|
}
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
|
|
|
WithField("servers", servers).
|
|
|
|
Info("deleteClosedTribalWarsServers: loaded servers")
|
2020-06-18 12:51:31 +00:00
|
|
|
|
2020-11-21 12:13:29 +00:00
|
|
|
list, err := h.api.Server.Browse(0, 0, []string{"key ASC"}, &shared_models.ServerFilter{
|
2020-06-24 14:50:29 +00:00
|
|
|
Key: servers,
|
2020-06-18 12:51:31 +00:00
|
|
|
Status: []shared_models.ServerStatus{shared_models.ServerStatusClosed},
|
2020-06-18 15:52:16 +00:00
|
|
|
}, nil)
|
2020-06-18 12:51:31 +00:00
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Errorln("deleteClosedTribalWarsServers: " + err.Error())
|
2020-06-18 12:51:31 +00:00
|
|
|
return
|
|
|
|
}
|
2020-06-25 14:29:18 +00:00
|
|
|
if list == nil || list.Items == nil {
|
|
|
|
return
|
|
|
|
}
|
2020-06-18 12:51:31 +00:00
|
|
|
|
|
|
|
keys := []string{}
|
|
|
|
for _, server := range list.Items {
|
|
|
|
keys = append(keys, server.Key)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(keys) > 0 {
|
2020-10-24 18:38:11 +00:00
|
|
|
deleted, err := h.observationRepo.Delete(context.Background(), &models.ObservationFilter{
|
2020-06-26 18:30:25 +00:00
|
|
|
Server: keys,
|
2020-06-18 12:51:31 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Errorln("deleteClosedTribalWarsServers: " + err.Error())
|
2020-06-18 12:51:31 +00:00
|
|
|
} else {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.
|
|
|
|
WithField("numberOfDeletedObservations", len(deleted)).
|
|
|
|
Infof("deleteClosedTribalWarsServers: deleted observations")
|
2020-06-18 12:51:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-15 10:03:43 +00:00
|
|
|
|
2020-10-24 18:38:11 +00:00
|
|
|
func (h *handler) updateBotStatus() {
|
|
|
|
if err := h.discord.UpdateStatus(h.status); err != nil {
|
2020-10-24 06:17:52 +00:00
|
|
|
log.Error("updateBotStatus: " + err.Error())
|
2020-07-15 10:03:43 +00:00
|
|
|
}
|
|
|
|
}
|