hdkv
/
i2_bot
Archived
1
Fork 0
This repository has been archived on 2022-11-04. You can view files and clone it, but cannot push or open issues/pull-requests.
i2_bot/lib/datacache/players.go

189 lines
5.4 KiB
Go
Raw Normal View History

// i2_bot Instinct PokememBro Bot
// Copyright (c) 2018 Vladimir "fat0troll" Hodakov
package datacache
import (
"errors"
"strconv"
"time"
2018-05-02 07:25:39 +04:00
2018-05-19 12:14:25 +04:00
"github.com/fat0troll/i2_bot/lib/dbmapping"
)
func (dc *DataCache) initPlayers() {
c.Log.Info("Initializing Players storage...")
dc.players = make(map[int]*dbmapping.Player)
}
func (dc *DataCache) loadPlayers() {
c.Log.Info("Load current Players data from database to DataCache...")
players := []dbmapping.Player{}
err := c.Db.Select(&players, "SELECT * FROM players")
if err != nil {
// This is critical error and we need to stop immediately!
c.Log.Fatal(err.Error())
}
dc.playersMutex.Lock()
for i := range players {
dc.players[players[i].ID] = &players[i]
}
c.Log.Info("Loaded players in DataCache: " + strconv.Itoa(len(dc.players)))
dc.playersMutex.Unlock()
}
// External functions
// AddPlayer creates new player in database
func (dc *DataCache) AddPlayer(player *dbmapping.Player) (int, error) {
c.Log.Info("DataCache: Creating new user...")
_, err := c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :karma, :created_at, :updated_at)", &player)
if err != nil {
c.Log.Error(err.Error())
return 0, err
}
insertedPlayer := dbmapping.Player{}
err = c.Db.Get(&insertedPlayer, "SELECT * FROM players WHERE telegram_id=? AND created_at=?", player.TelegramID, player.CreatedAt)
if err != nil {
c.Log.Error(err.Error())
return 0, err
}
dc.playersMutex.Lock()
dc.players[insertedPlayer.ID] = &insertedPlayer
dc.playersMutex.Unlock()
return insertedPlayer.ID, nil
}
// ChangePlayerKarma changes karma value for user
func (dc *DataCache) ChangePlayerKarma(addition int, playerID int) (*dbmapping.Player, error) {
if dc.players[playerID] == nil {
return nil, errors.New("There is no player with ID = " + strconv.Itoa(playerID))
}
dc.playersMutex.Lock()
dc.players[playerID].Karma += addition
dc.players[playerID].UpdatedAt = time.Now().UTC()
dc.playersMutex.Unlock()
_, err := c.Db.NamedExec("UPDATE `players` SET karma=:karma, updated_at=:updated_at WHERE id=:id", dc.players[playerID])
if err != nil {
c.Log.Error(err.Error())
}
return dc.players[playerID], nil
}
// GetOrCreatePlayerByTelegramID finds user by Telegram ID and creates one if not exist
func (dc *DataCache) GetOrCreatePlayerByTelegramID(telegramID int) (*dbmapping.Player, error) {
c.Log.Info("DataCache: Getting player with Telegram ID=", telegramID)
var player *dbmapping.Player
dc.playersMutex.Lock()
for i := range dc.players {
if dc.players[i].TelegramID == telegramID {
player = dc.players[i]
}
}
dc.playersMutex.Unlock()
if player == nil {
c.Log.Info("There is no such user, creating one...")
newPlayer := dbmapping.Player{}
newPlayer.TelegramID = telegramID
newPlayer.LeagueID = 0
newPlayer.Karma = 250
newPlayer.Status = "nobody"
newPlayer.CreatedAt = time.Now().UTC()
newPlayer.UpdatedAt = time.Now().UTC()
newPlayerID, err := dc.AddPlayer(&newPlayer)
if err != nil {
return nil, err
}
player = dc.players[newPlayerID]
}
return player, nil
}
// GetPlayerByID returns player from datacache by ID
func (dc *DataCache) GetPlayerByID(playerID int) (*dbmapping.Player, error) {
c.Log.Info("DataCache: Getting player with ID = ", playerID)
if dc.players[playerID] != nil {
c.Log.Debug("DataCache: found player with ID = " + strconv.Itoa(playerID))
return dc.players[playerID], nil
}
return nil, errors.New("There is no user with ID = " + strconv.Itoa(playerID))
}
// GetPlayerByTelegramID returns player with such Telegram ID
func (dc *DataCache) GetPlayerByTelegramID(telegramID int) (*dbmapping.Player, error) {
c.Log.Info("DataCache: Getting player with Telegram ID=", telegramID)
var player *dbmapping.Player
dc.playersMutex.Lock()
for i := range dc.players {
if dc.players[i].TelegramID == telegramID {
player = dc.players[i]
}
}
dc.playersMutex.Unlock()
if player != nil {
return player, nil
}
return nil, errors.New("There is no user with Telegram ID = " + strconv.Itoa(telegramID))
}
// UpdatePlayerFields writes new fields to player
func (dc *DataCache) UpdatePlayerFields(player *dbmapping.Player) (*dbmapping.Player, error) {
if dc.players[player.ID] != nil {
_, err := c.Db.NamedExec("UPDATE `players` SET league_id=:league_id, status=:status, karma=:karma WHERE id=:id", player)
if err != nil {
c.Log.Error(err.Error())
return dc.players[player.ID], err
}
dc.playersMutex.Lock()
dc.players[player.ID].LeagueID = player.LeagueID
dc.players[player.ID].Status = player.Status
dc.playersMutex.Unlock()
return dc.players[player.ID], nil
}
return nil, errors.New("There is no user with ID = " + strconv.Itoa(player.ID))
}
// UpdatePlayerTimestamp writes current update time to player
func (dc *DataCache) UpdatePlayerTimestamp(playerID int) error {
if dc.players[playerID] != nil {
dc.playersMutex.Lock()
dc.players[playerID].UpdatedAt = time.Now().UTC()
_, err := c.Db.NamedExec("UPDATE `players` SET updated_at=:updated_at WHERE id=:id", dc.players[playerID])
if err != nil {
c.Log.Error(err.Error())
dc.playersMutex.Unlock()
return err
}
2018-02-17 19:47:22 +04:00
dc.squadsMutex.Lock()
for i := range dc.squadPlayers {
for j := range dc.squadPlayers[i] {
if dc.squadPlayers[i][j].Player.ID == playerID {
dc.squadPlayers[i][j].Player = *dc.players[playerID]
}
}
}
dc.squadsMutex.Unlock()
dc.playersMutex.Unlock()
return nil
}
return errors.New("There is no user with ID = " + strconv.Itoa(playerID))
}