| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- // package dict_warbot -- потокобезопасный словарь ботов
- package dict_warbot
- import (
- "fmt"
- "log"
- "strconv"
- "strings"
- "sync"
- "wartank/pkg/alias"
- "wartank/pkg/types"
- "wartank/server/serv_bots/warbot"
- )
- const (
- strBotList = "/bots/list" // Константа путь к списку ботов в базе
- )
- // DictWarBot -- потокобезопасный словарь ботов
- type DictWarBot struct {
- server types.ИСервер
- store types.ИХранилище
- dict map[alias.БотНомер]types.ИБот
- block sync.RWMutex
- }
- // NewDictWarBot -- возвращает новый потокобезопасный словарь ботов
- func NewDictWarBot(server types.ИСервер) (*DictWarBot, error) {
- if server == nil {
- return nil, fmt.Errorf("NewDictWarBot(): IServer==nil")
- }
- log.Printf("NewDictWarBot()\n")
- сам := &DictWarBot{
- server: server,
- store: server.Хранилище(),
- dict: map[alias.БотНомер]types.ИБот{},
- }
- if err := сам.load(); err != nil {
- return nil, fmt.Errorf("NewDictBot(): in load list bots from store, err=%w", err)
- }
- return сам, nil
- }
- // ListBot -- возвращает список существующих ботов
- func (сам *DictWarBot) ListBot() []types.ИБот {
- сам.block.RLock()
- defer сам.block.RUnlock()
- lst := make([]types.ИБот, 0)
- for _, bot := range сам.dict {
- lst = append(lst, bot)
- }
- return lst
- }
- // Get -- возвращает бота по имени
- func (сам *DictWarBot) Get(botNumber alias.БотНомер) types.ИБот {
- сам.block.RLock()
- defer сам.block.RUnlock()
- bot := сам.dict[botNumber]
- return bot
- }
- // Add -- добавляет нового бота в словарь
- func (сам *DictWarBot) Add(bot types.ИБот) {
- сам.block.Lock()
- defer сам.block.Unlock()
- if bot == nil {
- return
- }
- сам.dict[bot.Номер()] = bot
- сам.save()
- }
- // Сохраняет словарь ботов в базе
- func (сам *DictWarBot) save() {
- strNumber := ""
- for botNumber := range сам.dict {
- strNumber += fmt.Sprint(botNumber) + ";"
- }
- strNumber = strNumber[:len(strNumber)-1]
- err := сам.store.Уст(strBotList, []byte(strNumber))
- if err != nil {
- сам.server.Отменить()
- }
- }
- // Загружает всех ботов с базы
- func (сам *DictWarBot) load() error {
- binNumber, err := сам.store.Получ(strBotList)
- if err != nil {
- if !strings.Contains(err.Error(), "not found") {
- return fmt.Errorf("DictWarBot.load(): in get list bot, err=\n\t%w", err)
- }
- }
- strNumbers := string(binNumber)
- if strNumbers == "" {
- return nil
- }
- lstNumbers := strings.Split(strNumbers, ";")
- for _, strNumber := range lstNumbers {
- if strNumber == "" {
- continue
- }
- iNumber, err := strconv.Atoi(strNumber)
- if err != nil {
- return fmt.Errorf("DictWarBot.load(): in conver number bot(%v), err=\n\t%w", strNumber, err)
- }
- number := alias.БотНомер(iNumber)
- _, isOk := сам.dict[number]
- if isOk {
- continue
- }
- bot, err := warbot.ЗагрузитьВарБот(сам.server, number)
- if err != nil {
- return fmt.Errorf("ServBots.load(): in create bot %q, err=\n\t%w", strNumber, err)
- }
- if bot.АвтоИграЕсли() {
- go bot.Пуск()
- }
- сам.dict[number] = bot
- }
- return nil
- }
|