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