// package dict_warbot -- потокобезопасный словарь ботов package dict_warbot import ( "fmt" "log" "strings" "sync" "wartank/pkg/types" "wartank/server/serv_bots/warbot" ) const ( strBotList = "/bots/list" // Константа путь к списку ботов в базе ) // DictWarBot -- потокобезопасный словарь ботов type DictWarBot struct { server types.ИСервер store types.IStore dict map[string]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") sf := &DictWarBot{ server: server, store: server.Store(), dict: map[string]types.ИБот{}, } if err := sf.load(); err != nil { return nil, fmt.Errorf("NewDictBot(): in load list bots from store, err=%w", err) } return sf, nil } // ListBot -- возвращает список существующих ботов func (sf *DictWarBot) ListBot() []types.ИБот { lst := make([]types.ИБот, 0) for _, bot := range sf.dict { lst = append(lst, bot) } return lst } // Get -- возвращает бота по имени func (sf *DictWarBot) Get(botName string) types.ИБот { sf.block.RLock() defer sf.block.RUnlock() bot := sf.dict[botName] return bot } // Add -- добавляет нового бота в словарь func (sf *DictWarBot) Add(bot types.ИБот) { sf.block.Lock() defer sf.block.Unlock() if bot == nil { return } sf.dict[bot.Имя()] = bot sf.save() } // Сохраняет словарь ботов в базе func (sf *DictWarBot) save() { strName := "" for name := range sf.dict { strName += name + ";" } strName = strName[:len(strName)-1] err := sf.store.Put(strBotList, strName) if err != nil { sf.server.CancelApp() } } // Загружает всех ботов с базы func (sf *DictWarBot) load() error { strName, err := sf.store.Get(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) } } if strName == "" { return nil } lstName := strings.Split(strName, ";") for _, name := range lstName { if name == "" { continue } _, isOk := sf.dict[name] if isOk { continue } bot, err := warbot.ЗагрузитьВарБот(sf.server, name) if err != nil { return fmt.Errorf("ServBots.load(): in create bot %q, err=\n\t%w", name, err) } if bot.АвтоИграЕсли() { go bot.Пуск() } sf.dict[name] = bot } return nil }