From 90a86fc18bb5836931a1ce11b0a7a97666489e42 Mon Sep 17 00:00:00 2001 From: smsteel Date: Thu, 24 Jun 2021 17:56:49 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=A4=D1=80=D0=B0=D0=B3=D0=B8=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D1=85=D0=BE=D0=B4=D1=8F=D1=82=20=D0=B2=20=D0=BE?= =?UTF-8?q?=D0=B4=D0=BD=D0=BE=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D1=8F=D1=8E=D1=82=20=D1=86=D0=B8=D1=84=D1=80=D1=83,=20=D0=B5?= =?UTF-8?q?=D1=81=D0=BB=D0=B8=20=D1=8D=D1=82=D0=BE=20=D1=82=D0=BE=D1=82=20?= =?UTF-8?q?=D0=B6=D0=B5=20=D1=82=D0=B8=D0=BF=20=D1=84=D1=80=D0=B0=D0=B3?= =?UTF-8?q?=D0=B0.=20=D0=A1=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BD=D0=B5=20=D1=83=D0=B4=D0=B0=D0=BB=D1=8F=D1=8E?= =?UTF-8?q?=D1=82=D1=81=D1=8F=20=D0=B4=D0=BE=D0=BB=D1=8C=D1=88=D0=B5,=20?= =?UTF-8?q?=D0=B5=D1=81=D0=BB=D0=B8=20=D0=BD=D0=B5=D0=B4=D0=B0=D0=B2=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=B1=D1=8B=D0=BB=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=20=D1=82=D0=B0=D0=BA=D0=BE=D0=B9=20=D0=B6=D0=B5=20=D1=84?= =?UTF-8?q?=D1=80=D0=B0=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- context.go | 16 ++++++++-- fragMessages.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++ handlers.go | 10 ++---- main.go | 4 ++- messageCleaner.go | 62 ++++++++++++++++++++++++++++++++++--- 5 files changed, 156 insertions(+), 15 deletions(-) create mode 100644 fragMessages.go diff --git a/context.go b/context.go index eb4fd73..ddf6c68 100644 --- a/context.go +++ b/context.go @@ -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") +} diff --git a/fragMessages.go b/fragMessages.go new file mode 100644 index 0000000..7ab0706 --- /dev/null +++ b/fragMessages.go @@ -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 +} diff --git a/handlers.go b/handlers.go index e650db3..0d844fe 100644 --- a/handlers.go +++ b/handlers.go @@ -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) diff --git a/main.go b/main.go index d01b95b..145f755 100644 --- a/main.go +++ b/main.go @@ -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...") diff --git a/messageCleaner.go b/messageCleaner.go index ecfcef4..9b0f882 100644 --- a/messageCleaner.go +++ b/messageCleaner.go @@ -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 + } + } +} From 36055c61a8ec6b54fb2dda06ffdb2aba9ece4406 Mon Sep 17 00:00:00 2001 From: smsteel Date: Thu, 24 Jun 2021 18:56:43 +0300 Subject: [PATCH 2/2] fix drone CI, fix markdown in kill message --- .drone.yml | 6 ++++++ fragMessages.go | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 0877b95..ca1a0eb 100644 --- a/.drone.yml +++ b/.drone.yml @@ -15,7 +15,13 @@ steps: - name: install commands: - make install + when: + branch: + - master - name: restart commands: - systemctl restart craft-bot + when: + branch: + - master diff --git a/fragMessages.go b/fragMessages.go index 7ab0706..922feb4 100644 --- a/fragMessages.go +++ b/fragMessages.go @@ -47,7 +47,12 @@ func (fms *fragMessages) addFrag(ctx context.Context, playerName string, entityN 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)) + mess := tgbotapi.NewEditMessageText( + fm.chatID, + fm.messageID, + fmt.Sprintf("%s убил %s ✗ *%d*", fm.playerName, fm.entityName, fm.fragCount), + ) + mess.ParseMode = tgbotapi.ModeMarkdown _, err := botApi.Send(mess) if err != nil { return err