// package serv_bots -- словарь ботов сервера package serv_bots import ( "encoding/json" "fmt" "log" "strings" "sync" "wartank/pkg/types" "wartank/server/serv_bots/warbot" ) // ServBots -- словарь ботов на сервере type ServBots struct { server types.IServer store types.IStore dict map[string]types.IServBot block sync.RWMutex } // NewServBots -- возвращает новый словарь серверных ботов func NewServBots(server types.IServer) (*ServBots, error) { if server == nil { return nil, fmt.Errorf("NewServBots(): IServer == nil") } sf := &ServBots{ server: server, store: server.Store(), dict: make(map[string]types.IServBot), } if err := sf.Load(); err != nil { return nil, fmt.Errorf("NewServBots(): in load bots, err=\n\t%w", err) } return sf, nil } // Get -- возвращает боевого бота по имени func (sf *ServBots) Get(name string) types.IServBot { sf.block.RLock() defer sf.block.RUnlock() bot, isOk := sf.dict[name] if !isOk { return nil } return bot } // Загружает ботов из хранилища func (sf *ServBots) Load() error { sf.block.Lock() defer sf.block.Unlock() log.Println("ServBots.load()") strList, err := sf.store.Get("/bots/list") if err != nil { if !strings.Contains(err.Error(), "not found") { return fmt.Errorf("ServBots.Load(): in get list bot, err=\n\t%w", err) } } lstBot := make([]string, 0) if strList != "" { // Такое может быть при первом запуске err = json.Unmarshal([]byte(strList), &lstBot) if err != nil { return fmt.Errorf("ServBots.load(): in unmarshal list bot, err=\n\t%w", err) } } for _, name := range lstBot { bot, err := warbot.NewWarBot(sf.server, name) if err != nil { return fmt.Errorf("ServBots.load(): in create bot %q, err=\n\t%w", name, err) } go bot.Run() sf.dict[name] = bot } return nil } // BotStart -- запускает бота в работу по его имени func (sf *ServBots) BotStart(name string) error { bot := sf.dict[name] if bot == nil { return fmt.Errorf("ServBots.BotStart(): bot(%v) not found", name) } err := bot.Run() if err != nil { return fmt.Errorf("ServBots.BotStart(): in run bot(%v), err=\n\t%w", name, err) } return nil } // ListBot -- возвращает список существующих ботов func (sf *ServBots) ListBot() []types.IServBot { lst := make([]types.IServBot, 0) for _, bot := range sf.dict { lst = append(lst, bot) } return lst } // AddBot -- добавляет бота на ферму func (sf *ServBots) AddBot(login, pass string) error { { // Существует ли такой бот _, isOk := sf.dict[login] if isOk { return nil } } { // Сохранить бота в базу strList, err := sf.store.Get("/bots/list") if err != nil { if !strings.Contains(err.Error(), "not found") { return fmt.Errorf("ServBots.AddBot(): in get list bot, err=\n\t%w", err) } } lstBot := make([]string, 0) if strList != "" { // Такое может быть при первом запуске err = json.Unmarshal([]byte(strList), &lstBot) if err != nil { return fmt.Errorf("ServBots.AddBot(): in unmarshal list bot, err=\n\t%w", err) } } lstBot = append(lstBot, login) binData, _ := json.Marshal(lstBot) err = sf.store.Put("/bots/list", string(binData)) if err != nil { return fmt.Errorf("ServBots.AddBot(): in save to store list bot, err=\n\t%w", err) } err = sf.store.Put("/bots/"+login, pass) if err != nil { return fmt.Errorf("ServBots.AddBot(): in save to store bot(%q), err=\n\t%w", login, err) } } { // Нет такого бота, надо его создать bot, err := warbot.NewWarBot(sf.server, login) if err != nil { return fmt.Errorf("ServBots.AddBot(): in create bot %q, err=\n\t%w", login, err) } sf.dict[login] = bot } return nil }