feat: enable/disable notifications about internals/barbarians

This commit is contained in:
Dawid Wysokiński 2022-10-28 12:07:58 +02:00
parent 3fcf38f5c7
commit 7ec1f80e72
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
9 changed files with 146 additions and 21 deletions

View File

@ -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().

View File

@ -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)
})
}

View File

@ -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,

View File

@ -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
})
})
}

View File

@ -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{

View File

@ -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

View File

@ -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())
})
}
}

View File

@ -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)
})

View File

@ -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 {