Фраги приходят в одно сообщение и добавляют цифру, если это тот же тип фрага. Сообщения не удаляются дольше, если недавно был сделан такой же фраг
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing

This commit is contained in:
smsteel 2021-06-24 17:56:49 +03:00
parent 70594a62d2
commit 90a86fc18b
5 changed files with 156 additions and 15 deletions

View File

@ -2,9 +2,10 @@ package main
import (
"context"
"github.com/sirupsen/logrus"
"os"
"github.com/sirupsen/logrus"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)
@ -19,6 +20,7 @@ const (
ctxKeyMessageCleaner
ctxKeyDataBase
ctxKeyPlayersBoard
ctxKeyFragMessages
)
func createLogger(debug bool) *logrus.Logger {
@ -42,7 +44,7 @@ func createLogger(debug bool) *logrus.Logger {
}
}
func createContext(config *Config, bot *tgbotapi.BotAPI, mc *messageCleaner, ch *commandHandler, db *dbLayer, pb *playersBoard) (context.Context, func()) {
func createContext(config *Config, bot *tgbotapi.BotAPI, mc *messageCleaner, ch *commandHandler, db *dbLayer, pb *playersBoard, fms *fragMessages) (context.Context, func()) {
ctx, cancelFunc := context.WithCancel(context.Background())
ctx = context.WithValue(ctx, ctxKeyLogger, createLogger(true))
@ -52,6 +54,7 @@ func createContext(config *Config, bot *tgbotapi.BotAPI, mc *messageCleaner, ch
ctx = context.WithValue(ctx, ctxKeyCommandHandler, ch)
ctx = context.WithValue(ctx, ctxKeyDataBase, db)
ctx = context.WithValue(ctx, ctxKeyPlayersBoard, pb)
ctx = context.WithValue(ctx, ctxKeyFragMessages, fms)
return ctx, cancelFunc
}
@ -118,3 +121,12 @@ func getDPlayersBoard(ctx context.Context) *playersBoard {
panic("Failed to get players board from ctx")
}
func getFragMessages(ctx context.Context) *fragMessages {
v := ctx.Value(ctxKeyFragMessages)
if fms, ok := v.(*fragMessages); ok {
return fms
}
panic("Failed to get frag messages from ctx")
}

79
fragMessages.go Normal file
View File

@ -0,0 +1,79 @@
package main
import (
"context"
"fmt"
"sync"
"time"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)
type fragMessage struct {
playerName string
entityName string
chatID int64
messageID int
fragCount int
latestFragTime time.Time
}
type fragMessages struct {
mx sync.Mutex
messages []*fragMessage
}
func (f *fragMessage) increaseFrag() *fragMessage {
f.fragCount += 1
f.latestFragTime = time.Now()
return f
}
func newFragMessages() *fragMessages {
return &fragMessages{
messages: make([]*fragMessage, 0),
}
}
func (fms *fragMessages) addFrag(ctx context.Context, playerName string, entityName string) error {
botApi := getBotApi(ctx)
cfg := getConfig(ctx)
mc := getMessageCleaner(ctx)
fms.mx.Lock()
defer fms.mx.Unlock()
for _, fm := range fms.messages {
if fm.playerName == playerName && fm.entityName == entityName {
mc.resetTimer(fm.messageID, fm.chatID, time.Second*30)
fm.increaseFrag()
mess := tgbotapi.NewEditMessageText(fm.chatID, fm.messageID, fmt.Sprintf("%s убил %s x *%d*", fm.playerName, fm.entityName, fm.fragCount))
_, err := botApi.Send(mess)
if err != nil {
return err
}
return nil
}
}
mess := tgbotapi.NewMessage(cfg.ChatID, fmt.Sprintf("%s убил %s", playerName, entityName))
m, err := botApi.Send(mess)
if err != nil {
return err
}
mc.add(ctx, m.MessageID, cfg.ChatID, time.Second*30)
fm := &fragMessage{
playerName: playerName,
entityName: entityName,
chatID: cfg.ChatID,
messageID: m.MessageID,
fragCount: 0,
latestFragTime: time.Now(),
}
fms.messages = append(fms.messages, fm)
return nil
}

View File

@ -165,19 +165,15 @@ type killCommand struct {
}
func (c *killCommand) run(ctx context.Context) {
botApi := getBotApi(ctx)
cfg := getConfig(ctx)
mc := getMessageCleaner(ctx)
db := getDB(ctx)
log := getLogger(ctx)
pb := getDPlayersBoard(ctx)
fms := getFragMessages(ctx)
mess := tgbotapi.NewMessage(cfg.ChatID, fmt.Sprintf("%s убил %s", c.name, c.entity))
m, err := botApi.Send(mess)
err := fms.addFrag(ctx, c.name, c.entity)
if err != nil {
log.Error(err)
} else {
mc.add(ctx, m.MessageID, cfg.ChatID, time.Second*30)
return
}
p, err := db.getPlayerByName(ctx, c.name)

View File

@ -61,7 +61,9 @@ func main() {
pb := newPlayersBoard()
ctx, cancelFunc := createContext(&cfg, bot, mc, ch, db, pb)
fms := newFragMessages()
ctx, cancelFunc := createContext(&cfg, bot, mc, ch, db, pb, fms)
getLogger(ctx).Infof("Run...")

View File

@ -8,32 +8,84 @@ import (
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)
type messageToClean struct {
messID int
chatID int64
timer *time.Timer
}
type messageCleaner struct {
botApi *tgbotapi.BotAPI
wg *sync.WaitGroup
botApi *tgbotapi.BotAPI
wg *sync.WaitGroup
messages []*messageToClean
mx sync.Mutex
}
func newMessageCleaner(bot *tgbotapi.BotAPI, wg *sync.WaitGroup) *messageCleaner {
return &messageCleaner{
botApi: bot,
wg: wg,
botApi: bot,
wg: wg,
messages: make([]*messageToClean, 0),
}
}
func (m *messageCleaner) add(ctx context.Context, messID int, chatID int64, d time.Duration) {
m.mx.Lock()
defer m.mx.Unlock()
for _, ms := range m.messages {
if ms.chatID == chatID && ms.messID == messID {
return
}
}
m.wg.Add(1)
go func() {
defer m.wg.Done()
ms := &messageToClean{
messID: messID,
chatID: chatID,
timer: time.NewTimer(d),
}
m.messages = append(m.messages, ms)
select {
case <-time.NewTimer(d).C:
case <-ms.timer.C:
case <-ctx.Done():
}
m.remove(messID, chatID)
_, _ = m.botApi.DeleteMessage(tgbotapi.DeleteMessageConfig{
MessageID: messID,
ChatID: chatID,
})
}()
}
func (m *messageCleaner) remove(messID int, chatID int64) {
m.mx.Lock()
defer m.mx.Unlock()
for i, ms := range m.messages {
if ms.chatID == chatID && ms.messID == messID {
m.messages = append(m.messages[:i], m.messages[i+1:]...)
return
}
}
}
func (m *messageCleaner) resetTimer(messID int, chatID int64, d time.Duration) {
m.mx.Lock()
defer m.mx.Unlock()
for _, ms := range m.messages {
if ms.chatID == chatID && ms.messID == messID {
ms.timer.Reset(d)
return
}
}
}