Compare commits
9 Commits
70594a62d2
...
feature_te
Author | SHA1 | Date | |
---|---|---|---|
4456ca69a2 | |||
8a3614419a | |||
4c88f0268d | |||
4bf5914d89 | |||
d2cf73b61d | |||
3d010de8e0 | |||
762642b2cf | |||
36055c61a8 | |||
90a86fc18b |
14
.drone.yml
14
.drone.yml
@ -7,6 +7,14 @@ platform:
|
|||||||
os: linux
|
os: linux
|
||||||
arch: amd64
|
arch: amd64
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- master
|
||||||
|
event:
|
||||||
|
include:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build
|
- name: build
|
||||||
commands:
|
commands:
|
||||||
@ -15,7 +23,13 @@ steps:
|
|||||||
- name: install
|
- name: install
|
||||||
commands:
|
commands:
|
||||||
- make install
|
- make install
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
|
||||||
- name: restart
|
- name: restart
|
||||||
commands:
|
commands:
|
||||||
- systemctl restart craft-bot
|
- systemctl restart craft-bot
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
16
context.go
16
context.go
@ -2,9 +2,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ const (
|
|||||||
ctxKeyMessageCleaner
|
ctxKeyMessageCleaner
|
||||||
ctxKeyDataBase
|
ctxKeyDataBase
|
||||||
ctxKeyPlayersBoard
|
ctxKeyPlayersBoard
|
||||||
|
ctxKeyFragMessages
|
||||||
)
|
)
|
||||||
|
|
||||||
func createLogger(debug bool) *logrus.Logger {
|
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, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
|
||||||
ctx = context.WithValue(ctx, ctxKeyLogger, createLogger(true))
|
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, ctxKeyCommandHandler, ch)
|
||||||
ctx = context.WithValue(ctx, ctxKeyDataBase, db)
|
ctx = context.WithValue(ctx, ctxKeyDataBase, db)
|
||||||
ctx = context.WithValue(ctx, ctxKeyPlayersBoard, pb)
|
ctx = context.WithValue(ctx, ctxKeyPlayersBoard, pb)
|
||||||
|
ctx = context.WithValue(ctx, ctxKeyFragMessages, fms)
|
||||||
|
|
||||||
return ctx, cancelFunc
|
return ctx, cancelFunc
|
||||||
}
|
}
|
||||||
@ -118,3 +121,12 @@ func getDPlayersBoard(ctx context.Context) *playersBoard {
|
|||||||
|
|
||||||
panic("Failed to get players board from ctx")
|
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
90
fragMessages.go
Normal 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
|
||||||
|
}
|
16
handlers.go
16
handlers.go
@ -114,13 +114,11 @@ func (c *quitCommand) run(ctx context.Context) {
|
|||||||
err = db.updatePlayerLastLogout(ctx, p.id, time.Now())
|
err = db.updatePlayerLastLogout(ctx, p.id, time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
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 {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pb.getPlayerBoard(p.id).setOnline(false)
|
pb.getPlayerBoard(p.id).setOnline(false)
|
||||||
@ -150,7 +148,6 @@ func (c *deathCommand) run(ctx context.Context) {
|
|||||||
err = db.increasePlayerDeath(ctx, p.id, 1)
|
err = db.increasePlayerDeath(ctx, p.id, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pb.update(ctx, achievementDeathless, achievementBestFeeder)
|
err = pb.update(ctx, achievementDeathless, achievementBestFeeder)
|
||||||
@ -165,19 +162,14 @@ type killCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *killCommand) run(ctx context.Context) {
|
func (c *killCommand) run(ctx context.Context) {
|
||||||
botApi := getBotApi(ctx)
|
|
||||||
cfg := getConfig(ctx)
|
|
||||||
mc := getMessageCleaner(ctx)
|
|
||||||
db := getDB(ctx)
|
db := getDB(ctx)
|
||||||
log := getLogger(ctx)
|
log := getLogger(ctx)
|
||||||
pb := getDPlayersBoard(ctx)
|
pb := getDPlayersBoard(ctx)
|
||||||
|
fms := getFragMessages(ctx)
|
||||||
|
|
||||||
mess := tgbotapi.NewMessage(cfg.ChatID, fmt.Sprintf("%s убил %s", c.name, c.entity))
|
err := fms.addFrag(ctx, c.name, c.entity)
|
||||||
m, err := botApi.Send(mess)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
} else {
|
|
||||||
mc.add(ctx, m.MessageID, cfg.ChatID, time.Second*30)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := db.getPlayerByName(ctx, c.name)
|
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)
|
err = db.increasePlayerEntryKills(ctx, p.id, c.entity, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pb.update(ctx, achievementMaxFrags, achievementPeaceable)
|
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)
|
err = db.updatePlayerLevel(ctx, p.id, c.newLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pb.update(ctx, achievementMaxLevel)
|
err = pb.update(ctx, achievementMaxLevel)
|
||||||
|
6
main.go
6
main.go
@ -61,7 +61,9 @@ func main() {
|
|||||||
|
|
||||||
pb := newPlayersBoard()
|
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...")
|
getLogger(ctx).Infof("Run...")
|
||||||
|
|
||||||
@ -76,6 +78,8 @@ func main() {
|
|||||||
runHttpServer(ctx, cfg.Http, &wg)
|
runHttpServer(ctx, cfg.Http, &wg)
|
||||||
runSignalHandler(ctx, cancelFunc)
|
runSignalHandler(ctx, cancelFunc)
|
||||||
|
|
||||||
|
getLogger(ctx).Infof("Running")
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,32 +8,84 @@ import (
|
|||||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type messageToClean struct {
|
||||||
|
messID int
|
||||||
|
chatID int64
|
||||||
|
timer *time.Timer
|
||||||
|
}
|
||||||
|
|
||||||
type messageCleaner struct {
|
type messageCleaner struct {
|
||||||
botApi *tgbotapi.BotAPI
|
botApi *tgbotapi.BotAPI
|
||||||
wg *sync.WaitGroup
|
wg *sync.WaitGroup
|
||||||
|
messages []*messageToClean
|
||||||
|
mx sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMessageCleaner(bot *tgbotapi.BotAPI, wg *sync.WaitGroup) *messageCleaner {
|
func newMessageCleaner(bot *tgbotapi.BotAPI, wg *sync.WaitGroup) *messageCleaner {
|
||||||
return &messageCleaner{
|
return &messageCleaner{
|
||||||
botApi: bot,
|
botApi: bot,
|
||||||
wg: wg,
|
wg: wg,
|
||||||
|
messages: make([]*messageToClean, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *messageCleaner) add(ctx context.Context, messID int, chatID int64, d time.Duration) {
|
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)
|
m.wg.Add(1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer m.wg.Done()
|
defer m.wg.Done()
|
||||||
|
|
||||||
|
ms := &messageToClean{
|
||||||
|
messID: messID,
|
||||||
|
chatID: chatID,
|
||||||
|
timer: time.NewTimer(d),
|
||||||
|
}
|
||||||
|
|
||||||
|
m.messages = append(m.messages, ms)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-time.NewTimer(d).C:
|
case <-ms.timer.C:
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m.remove(messID, chatID)
|
||||||
|
|
||||||
_, _ = m.botApi.DeleteMessage(tgbotapi.DeleteMessageConfig{
|
_, _ = m.botApi.DeleteMessage(tgbotapi.DeleteMessageConfig{
|
||||||
MessageID: messID,
|
MessageID: messID,
|
||||||
ChatID: chatID,
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user