Compare commits

..

9 Commits

Author SHA1 Message Date
4456ca69a2 test
All checks were successful
continuous-integration/drone/pr Build is passing
2021-06-25 18:32:36 +03:00
8a3614419a CI
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-25 18:29:11 +03:00
4c88f0268d CI fix
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-25 17:51:39 +03:00
4bf5914d89 small fix
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-24 22:13:14 +03:00
d2cf73b61d Merge branch 'hotfix' into master
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2021-06-24 21:29:58 +03:00
3d010de8e0 fix fragCount
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-24 21:28:55 +03:00
762642b2cf Merge pull request 'Фраги приходят в одно сообщение и добавляют цифру, если это тот же тип фрага. Сообщения не удаляются дольше, если недавно был сделан такой же фраг' (#1) from feature_frag_messages into master
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #1
2021-06-24 19:25:46 +03:00
36055c61a8 fix drone CI, fix markdown in kill message
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-06-24 18:56:43 +03:00
90a86fc18b Фраги приходят в одно сообщение и добавляют цифру, если это тот же тип фрага. Сообщения не удаляются дольше, если недавно был сделан такой же фраг
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-06-24 17:56:49 +03:00
6 changed files with 183 additions and 21 deletions

View File

@ -7,6 +7,14 @@ platform:
os: linux
arch: amd64
trigger:
branch:
- master
event:
include:
- push
- pull_request
steps:
- name: build
commands:
@ -15,7 +23,13 @@ steps:
- name: install
commands:
- make install
when:
event:
- push
- name: restart
commands:
- systemctl restart craft-bot
when:
event:
- push

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

90
fragMessages.go Normal file
View File

@ -0,0 +1,90 @@
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 ✗ *%d*", fm.playerName, fm.entityName, fm.fragCount),
)
mess.ParseMode = tgbotapi.ModeMarkdown
m, err := botApi.Send(mess)
if err != nil {
return err
}
if m.MessageID != fm.messageID {
m.MessageID = fm.messageID
getLogger(ctx).Info("message id was changed")
}
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: 1,
latestFragTime: time.Now(),
}
fms.messages = append(fms.messages, fm)
return nil
}

View File

@ -114,13 +114,11 @@ func (c *quitCommand) run(ctx context.Context) {
err = db.updatePlayerLastLogout(ctx, p.id, time.Now())
if err != nil {
log.Error(err)
return
}
err = db.increasePlayerOnlineDuration(ctx, p.id, time.Now().Sub(p.lastLogin))
err = db.increasePlayerOnlineDuration(ctx, p.id, time.Since(p.lastLogin))
if err != nil {
log.Error(err)
return
}
pb.getPlayerBoard(p.id).setOnline(false)
@ -150,7 +148,6 @@ func (c *deathCommand) run(ctx context.Context) {
err = db.increasePlayerDeath(ctx, p.id, 1)
if err != nil {
log.Error(err)
return
}
err = pb.update(ctx, achievementDeathless, achievementBestFeeder)
@ -165,19 +162,14 @@ 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)
}
p, err := db.getPlayerByName(ctx, c.name)
@ -189,7 +181,6 @@ func (c *killCommand) run(ctx context.Context) {
err = db.increasePlayerEntryKills(ctx, p.id, c.entity, 1)
if err != nil {
log.Error(err)
return
}
err = pb.update(ctx, achievementMaxFrags, achievementPeaceable)
@ -217,7 +208,6 @@ func (c *changeLevelCommand) run(ctx context.Context) {
err = db.updatePlayerLevel(ctx, p.id, c.newLevel)
if err != nil {
log.Error(err)
return
}
err = pb.update(ctx, achievementMaxLevel)

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...")
@ -76,6 +78,8 @@ func main() {
runHttpServer(ctx, cfg.Http, &wg)
runSignalHandler(ctx, cancelFunc)
getLogger(ctx).Infof("Running")
wg.Wait()
}

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