diff --git a/internal/bundb/group.go b/internal/bundb/group.go index 38312a7..863a47a 100644 --- a/internal/bundb/group.go +++ b/internal/bundb/group.go @@ -27,6 +27,8 @@ func (g *Group) Create(ctx context.Context, params domain.CreateGroupParams) (do ChannelGains: params.ChannelGains(), ChannelLosses: params.ChannelLosses(), ServerKey: params.ServerKey(), + Barbarians: params.Barbarians(), + Internals: params.Internals(), } if _, err := g.db.NewInsert(). diff --git a/internal/bundb/group_test.go b/internal/bundb/group_test.go index be9a99a..08a8f3c 100644 --- a/internal/bundb/group_test.go +++ b/internal/bundb/group_test.go @@ -28,6 +28,8 @@ func TestGroup_Create(t *testing.T) { "en113", "1234", "1235", + true, + true, ) require.NoError(t, err) @@ -40,6 +42,8 @@ func TestGroup_Create(t *testing.T) { assert.Equal(t, params.VersionCode(), group.VersionCode) assert.Equal(t, params.ChannelGains(), group.ChannelGains) assert.Equal(t, params.ChannelLosses(), group.ChannelLosses) + assert.Equal(t, params.Barbarians(), group.Barbarians) + assert.Equal(t, params.Internals(), group.Internals) assert.WithinDuration(t, time.Now(), group.CreatedAt, 1*time.Second) }) } diff --git a/internal/bundb/internal/model/group.go b/internal/bundb/internal/model/group.go index 7a48c87..ca02388 100644 --- a/internal/bundb/internal/model/group.go +++ b/internal/bundb/internal/model/group.go @@ -15,6 +15,8 @@ type Group struct { ServerID string `bun:"server_id,type:varchar(100),notnull"` ChannelGains string `bun:"channel_gains,type:varchar(100),nullzero"` ChannelLosses string `bun:"channel_losses,type:varchar(100),nullzero"` + Internals bool `bun:"internals,default:false"` + Barbarians bool `bun:"barbarians,default:false"` ServerKey string `bun:"server_key,type:varchar(50),notnull"` VersionCode string `bun:"version_code,type:varchar(6),notnull"` CreatedAt time.Time `bun:"created_at,nullzero,notnull,default:current_timestamp"` @@ -26,6 +28,8 @@ func (g Group) ToDomain() domain.Group { ServerID: g.ServerID, ChannelGains: g.ChannelGains, ChannelLosses: g.ChannelLosses, + Internals: g.Internals, + Barbarians: g.Barbarians, ServerKey: g.ServerKey, VersionCode: g.VersionCode, CreatedAt: g.CreatedAt, diff --git a/internal/bundb/migrations/20221028073839_groups_add_two_columns.go b/internal/bundb/migrations/20221028073839_groups_add_two_columns.go new file mode 100644 index 0000000..27d4eeb --- /dev/null +++ b/internal/bundb/migrations/20221028073839_groups_add_two_columns.go @@ -0,0 +1,47 @@ +package migrations + +import ( + "context" + "database/sql" + "fmt" + + "gitea.dwysokinski.me/twhelp/dcbot/internal/bundb/internal/model" + "github.com/uptrace/bun" +) + +func init() { + Migrations.MustRegister(func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error { + columns := []string{ + "internals", + "barbarians", + } + for _, c := range columns { + if _, err := tx.NewAddColumn(). + Model(&model.Group{}). + ColumnExpr("? boolean default false", bun.Safe(c)). + IfNotExists(). + Exec(ctx); err != nil { + return fmt.Errorf("couldn't add the %s column: %w", c, err) + } + } + return nil + }) + }, func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, &sql.TxOptions{}, func(ctx context.Context, tx bun.Tx) error { + columns := []string{ + "internals", + "barbarians", + } + for _, c := range columns { + if _, err := tx.NewDropColumn(). + Model(&model.Group{}). + Column(c). + Exec(ctx); err != nil { + return fmt.Errorf("couldn't drop the %s column: %w", c, err) + } + } + return nil + }) + }) +} diff --git a/internal/discord/command_group.go b/internal/discord/command_group.go index d5d5256..1690f7d 100644 --- a/internal/discord/command_group.go +++ b/internal/discord/command_group.go @@ -61,6 +61,18 @@ func (c *groupCommand) create(s *discordgo.Session) error { Type: discordgo.ApplicationCommandOptionString, Required: true, }, + { + Name: "internals", + Description: "Show conquers in the same group", + Type: discordgo.ApplicationCommandOptionBoolean, + Required: true, + }, + { + Name: "barbarians", + Description: "Show barbarian conquers", + Type: discordgo.ApplicationCommandOptionBoolean, + Required: true, + }, { Name: "channel-gains", Description: "Specifies on which channel notifications of gained villages will appear", @@ -243,10 +255,9 @@ func (c *groupCommand) handleCreate(s *discordgo.Session, i *discordgo.Interacti server := "" channelGains := "" channelLosses := "" + internals := false + barbarians := false for _, opt := range i.ApplicationCommandData().Options[0].Options { - if opt == nil { - continue - } switch opt.Name { case "version": version = opt.StringValue() @@ -256,6 +267,10 @@ func (c *groupCommand) handleCreate(s *discordgo.Session, i *discordgo.Interacti channelGains = opt.ChannelValue(s).ID case "channel-losses": channelLosses = opt.ChannelValue(s).ID + case "internals": + internals = opt.BoolValue() + case "barbarians": + barbarians = opt.BoolValue() } } @@ -265,6 +280,8 @@ func (c *groupCommand) handleCreate(s *discordgo.Session, i *discordgo.Interacti server, channelGains, channelLosses, + barbarians, + internals, ) if err != nil { _ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ diff --git a/internal/domain/group.go b/internal/domain/group.go index 390453d..baf7aad 100644 --- a/internal/domain/group.go +++ b/internal/domain/group.go @@ -10,6 +10,8 @@ type Group struct { ServerID string // Discord server ID ChannelGains string ChannelLosses string + Internals bool // Show conquers in the same group + Barbarians bool // Show barbarian conquers ServerKey string // Tribal Wars server key VersionCode string CreatedAt time.Time @@ -21,9 +23,14 @@ type CreateGroupParams struct { versionCode string channelGains string channelLosses string + barbarians bool + internals bool } -func NewCreateGroupParams(serverID, versionCode, serverKey, channelGains, channelLosses string) (CreateGroupParams, error) { +func NewCreateGroupParams( + serverID, versionCode, serverKey, channelGains, channelLosses string, + barbarians, internals bool, +) (CreateGroupParams, error) { if serverID == "" { return CreateGroupParams{}, ValidationError{ Field: "ServerID", @@ -51,6 +58,8 @@ func NewCreateGroupParams(serverID, versionCode, serverKey, channelGains, channe versionCode: versionCode, channelGains: channelGains, channelLosses: channelLosses, + barbarians: barbarians, + internals: internals, }, nil } @@ -74,6 +83,14 @@ func (c CreateGroupParams) ChannelLosses() string { return c.channelLosses } +func (c CreateGroupParams) Barbarians() bool { + return c.barbarians +} + +func (c CreateGroupParams) Internals() bool { + return c.internals +} + type UpdateGroupParams struct { ChannelGains NullString ChannelLosses NullString diff --git a/internal/domain/group_test.go b/internal/domain/group_test.go index c1b2c4c..0d2dce1 100644 --- a/internal/domain/group_test.go +++ b/internal/domain/group_test.go @@ -19,6 +19,8 @@ func TestNewCreateGroupParams(t *testing.T) { serverKey string channelGains string channelLosses string + barbarians bool + internals bool err error }{ { @@ -28,6 +30,8 @@ func TestNewCreateGroupParams(t *testing.T) { serverKey: "en113", channelGains: "1234", channelLosses: "1234", + barbarians: true, + internals: true, err: nil, }, { @@ -72,6 +76,8 @@ func TestNewCreateGroupParams(t *testing.T) { tt.serverKey, tt.channelGains, tt.channelLosses, + tt.barbarians, + tt.internals, ) if tt.err != nil { assert.ErrorIs(t, err, tt.err) @@ -84,6 +90,8 @@ func TestNewCreateGroupParams(t *testing.T) { assert.Equal(t, tt.versionCode, res.VersionCode()) assert.Equal(t, tt.channelGains, res.ChannelGains()) assert.Equal(t, tt.channelLosses, res.ChannelLosses()) + assert.Equal(t, tt.barbarians, res.Barbarians()) + assert.Equal(t, tt.internals, res.Internals()) }) } } diff --git a/internal/service/group_test.go b/internal/service/group_test.go index 49935d3..d890bb1 100644 --- a/internal/service/group_test.go +++ b/internal/service/group_test.go @@ -24,6 +24,8 @@ func TestGroup_Create(t *testing.T) { "en113", "1234", "1235", + true, + true, ) require.NoError(t, err) @@ -37,6 +39,8 @@ func TestGroup_Create(t *testing.T) { ServerID: p.ServerID(), ChannelGains: p.ChannelGains(), ChannelLosses: p.ChannelLosses(), + Barbarians: p.Barbarians(), + Internals: p.Internals(), ServerKey: p.ServerKey(), VersionCode: p.VersionCode(), CreatedAt: time.Now(), @@ -61,6 +65,8 @@ func TestGroup_Create(t *testing.T) { assert.Equal(t, params.VersionCode(), g.VersionCode) assert.Equal(t, params.ChannelGains(), g.ChannelGains) assert.Equal(t, params.ChannelLosses(), g.ChannelLosses) + assert.Equal(t, params.Barbarians(), g.Barbarians) + assert.Equal(t, params.Internals(), g.Barbarians) assert.NotEmpty(t, g.CreatedAt) }) diff --git a/internal/service/monitor.go b/internal/service/monitor.go index 00f3386..a2777a2 100644 --- a/internal/service/monitor.go +++ b/internal/service/monitor.go @@ -202,16 +202,12 @@ func (m *Monitor) Execute(ctx context.Context) ([]domain.EnnoblementNotification //nolint:prealloc var notifications []domain.EnnoblementNotification - for _, r := range res { - for _, g := range groups { + for _, g := range groups { + for _, r := range res { if g.ServerKey != r.serverKey || g.VersionCode != r.versionCode { continue } - if g.ChannelGains == "" && g.ChannelLosses == "" { - continue - } - ns, err := m.executeGroup(ctx, g, r.ennoblements) if err != nil { // TODO: log this error @@ -237,11 +233,7 @@ func (m *Monitor) executeGroup( //nolint:prealloc var notifications []domain.EnnoblementNotification for _, e := range ennoblements { - if isInternal(e, monitors) { - continue - } - - if g.ChannelGains != "" && isGain(e, monitors) { + if canSendEnnoblementNotificationTypeGain(g, e, monitors) { notifications = append(notifications, domain.EnnoblementNotification{ Type: domain.EnnoblementNotificationTypeGain, ServerID: g.ServerID, @@ -250,7 +242,7 @@ func (m *Monitor) executeGroup( }) } - if g.ChannelLosses != "" && isLoss(e, monitors) { + if canSendEnnoblementNotificationTypeLoss(g, e, monitors) { notifications = append(notifications, domain.EnnoblementNotification{ Type: domain.EnnoblementNotificationTypeLoss, ServerID: g.ServerID, @@ -286,10 +278,6 @@ func (m *Monitor) fetchEnnoblements(ctx context.Context, groups []domain.Group) skip := make(map[string]struct{}, len(ennoblementsSince)) for _, g := range groups { - if g.ChannelGains == "" && g.ChannelLosses == "" { - continue - } - key := g.VersionCode + ":" + g.ServerKey if _, ok := skip[key]; ok { @@ -299,7 +287,7 @@ func (m *Monitor) fetchEnnoblements(ctx context.Context, groups []domain.Group) since := ennoblementsSince[key] if since.IsZero() { - since = time.Now().Add(-1 * time.Minute) + since = time.Now().Add(-1 * time.Hour) } wg.Add(1) @@ -356,6 +344,34 @@ func (m *Monitor) fetchEnnoblements(ctx context.Context, groups []domain.Group) return results, nil } +func canSendEnnoblementNotificationTypeGain(g domain.Group, e twhelp.Ennoblement, monitors []domain.Monitor) bool { + if g.ChannelGains == "" { + return false + } + + if !g.Barbarians && isBarbarian(e) { + return false + } + + if !g.Internals && isInternal(e, monitors) { + return false + } + + return isGain(e, monitors) +} + +func canSendEnnoblementNotificationTypeLoss(g domain.Group, e twhelp.Ennoblement, monitors []domain.Monitor) bool { + if g.ChannelLosses == "" { + return false + } + + if !g.Internals && isInternal(e, monitors) { + return false + } + + return isLoss(e, monitors) +} + func isInternal(e twhelp.Ennoblement, monitors []domain.Monitor) bool { var n, o bool for _, m := range monitors { @@ -369,6 +385,10 @@ func isInternal(e twhelp.Ennoblement, monitors []domain.Monitor) bool { return n && o } +func isBarbarian(e twhelp.Ennoblement) bool { + return !e.OldOwner.Valid +} + func isGain(e twhelp.Ennoblement, monitors []domain.Monitor) bool { var n bool for _, m := range monitors {