195 lines
3.6 KiB
Go
195 lines
3.6 KiB
Go
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"sync"
|
||
|
||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
||
"github.com/hako/durafmt"
|
||
"github.com/pkg/errors"
|
||
)
|
||
|
||
type playerInfo struct {
|
||
playerID string
|
||
playerMessageID int
|
||
isOnline bool
|
||
}
|
||
|
||
func (p *playerInfo) setOnline(v bool) *playerInfo {
|
||
p.isOnline = v
|
||
return p
|
||
}
|
||
|
||
const (
|
||
emojiUp = "\xE2\xAC\x86"
|
||
emojiDeaths = "\xF0\x9F\x92\x80"
|
||
emojiTime = "\xF0\x9F\x95\x90"
|
||
emojiGun = "\xF0\x9F\x94\xAB"
|
||
)
|
||
|
||
func (p *playerInfo) updatePlayerInfo(ctx context.Context) error {
|
||
botApi := getBotApi(ctx)
|
||
conf := getConfig(ctx)
|
||
db := getDB(ctx)
|
||
|
||
player, err := db.getPlayerByID(ctx, p.playerID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
kills, err := db.getKillsByOPlayerID(ctx, player.id)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
test := `*%s* | %s
|
||
%s Уровень: *%s*
|
||
%s Смертей: *%d*
|
||
%s Время в игре: %s
|
||
%s Фрагов: %d
|
||
`
|
||
|
||
access := "\xE2\x9D\x8C offLine"
|
||
if p.isOnline {
|
||
access = "\xE2\x9C\x85 onLine"
|
||
}
|
||
|
||
level := "-"
|
||
if player.level >= 0 {
|
||
level = fmt.Sprintf("%d", player.level)
|
||
}
|
||
|
||
d := durafmt.Parse(player.onlineDuration).LimitFirstN(3)
|
||
|
||
units, err := durafmt.DefaultUnitsCoder.Decode("мес.:мес.,нед.:нед.,дн.:дн.,чс.:чс.,мин.:мин.,cек.:cек.,-:-,-:-")
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
test = fmt.Sprintf(test, player.name, access,
|
||
emojiUp, level,
|
||
emojiDeaths, player.deaths,
|
||
emojiTime, d.Format(units),
|
||
emojiGun, kills,
|
||
)
|
||
|
||
if p.playerMessageID != 0 {
|
||
mess := tgbotapi.NewEditMessageText(conf.ChatID, p.playerMessageID, test)
|
||
mess.ParseMode = tgbotapi.ModeMarkdown
|
||
|
||
ikm := tgbotapi.NewInlineKeyboardMarkup(
|
||
tgbotapi.NewInlineKeyboardRow(
|
||
tgbotapi.NewInlineKeyboardButtonData("Подробнее", "additional"),
|
||
),
|
||
)
|
||
|
||
mess.ReplyMarkup = &ikm
|
||
|
||
_, err := botApi.Send(mess)
|
||
if err != nil {
|
||
return errors.Wrap(err, "Failed to update message")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
mess := tgbotapi.NewMessage(conf.ChatID, test)
|
||
mess.ParseMode = tgbotapi.ModeMarkdown
|
||
|
||
m, err := botApi.Send(mess)
|
||
if err != nil {
|
||
return errors.Wrap(err, "Failed to send message")
|
||
}
|
||
|
||
p.playerMessageID = m.MessageID
|
||
|
||
return nil
|
||
}
|
||
|
||
func (p *playerInfo) deletePlayerInfo(ctx context.Context) error {
|
||
botApi := getBotApi(ctx)
|
||
conf := getConfig(ctx)
|
||
|
||
mess := tgbotapi.NewDeleteMessage(conf.ChatID, p.playerMessageID)
|
||
_, err := botApi.Send(mess)
|
||
if err != nil {
|
||
return errors.Wrap(err, "Failed to send message")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
type playersBoard struct {
|
||
mx sync.Mutex
|
||
players []playerInfo
|
||
}
|
||
|
||
func newPlayersBoard() *playersBoard {
|
||
return &playersBoard{
|
||
players: make([]playerInfo, 0),
|
||
}
|
||
}
|
||
|
||
func (pb *playersBoard) load(ctx context.Context) error {
|
||
pb.mx.Lock()
|
||
defer pb.mx.Unlock()
|
||
|
||
db := getDB(ctx)
|
||
|
||
players, err := db.getPlayers(ctx)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
pb.players = make([]playerInfo, 0, len(players))
|
||
|
||
for _, p := range players {
|
||
pi := playerInfo{
|
||
playerID: p.id,
|
||
}
|
||
|
||
err := pi.updatePlayerInfo(ctx)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
pb.players = append(pb.players, pi)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func (pb *playersBoard) getPlayerBoard(playerID string) *playerInfo {
|
||
for i := range pb.players {
|
||
if pb.players[i].playerID == playerID {
|
||
return &pb.players[i]
|
||
}
|
||
}
|
||
|
||
pb.mx.Lock()
|
||
defer pb.mx.Unlock()
|
||
|
||
pb.players = append(pb.players, playerInfo{
|
||
playerID: playerID,
|
||
})
|
||
|
||
return &pb.players[len(pb.players)-1]
|
||
}
|
||
|
||
func (pb *playersBoard) run(ctx context.Context) {
|
||
log := getLogger(ctx)
|
||
|
||
<-ctx.Done()
|
||
|
||
pb.mx.Lock()
|
||
defer pb.mx.Unlock()
|
||
|
||
for _, p := range pb.players {
|
||
err := p.deletePlayerInfo(ctx)
|
||
if err != nil {
|
||
log.Error(err)
|
||
}
|
||
}
|
||
}
|