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