// package warbot -- бот для игры в wartank package warbot import ( "context" "fmt" "log" "wartank/pkg/components/safebool" "wartank/pkg/types" "wartank/server/serv_bots/warbot/angar" "wartank/server/serv_bots/warbot/tank" "wartank/server/serv_bots/warbot/warbot_config" "wartank/server/serv_bots/warbot/warbot_net" ) // WarBot -- бот для игры в вартанк type WarBot struct { server types.IServer store types.IStore tank *tank.Tank errFinal error // Финальная ошибка работы, если была angar types.IAngar botNet types.IBotNet name string // Имя бота pass string // Пароль бота isRun *safebool.SafeBool isAutoRun *safebool.SafeBool config *warbot_config.WarBotConfig // Конфиг бота для хранения в базе ctx context.Context // Контекст бота fnCancel func() // Функция отменя контекста бота } // NewWarBot -- возвращает новый WarBot func NewWarBot(server types.IServer, name string) (*WarBot, error) { { // Предусловия if server == nil { return nil, fmt.Errorf("NewWarBot(): IApp is nil") } if name == "" { return nil, fmt.Errorf("NewWarBot(): name is empty") } } ctx, fnCancel := context.WithCancel(server.CtxApp()) sf := &WarBot{ server: server, store: server.Store(), tank: tank.NewTank(), name: name, isRun: safebool.NewSafeBool(), isAutoRun: safebool.NewSafeBool(), config: &warbot_config.WarBotConfig{}, ctx: ctx, fnCancel: fnCancel, } strData, err := sf.store.Get("/bots/" + sf.name) if err != nil { return nil, fmt.Errorf("NewWarBot(): in get binData for WarBotConfig from store, err=\n\t%w", err) } if err = sf.config.Unmarshall(strData); err != nil { return nil, fmt.Errorf("NewWarBot(): in unmarshall WarBotConfig from store, err=\n\t%w", err) } sf.pass = sf.config.Password_ { // WarBotNet sf.botNet, err = warbot_net.NewWarBotNet(sf) if err != nil { return nil, fmt.Errorf("NewWarBot(): in make IBotNet, err=\n\t%w", err) } } sf.angar, err = angar.NewAngar(sf) if err != nil { return nil, fmt.Errorf("NewWarBot(): bot(%q) in make IAngar, err=\n\t%w", sf.name, err) } if sf.config.IsAutoRun_ { sf.isAutoRun.Set() sf.Run() } return sf, nil } // Server -- возвращает ссылку на объект сервера func (sf *WarBot) Server() types.IServer { return sf.server } // IsRun -- возвращает признак, что бот подключен func (sf *WarBot) IsRun() bool { return sf.isRun.Get() } // Name -- возвращает имя бота func (sf *WarBot) Name() string { return sf.name } // Pass -- возвращает пароль бота func (sf *WarBot) Pass() string { return sf.pass } // Run -- запускает бот в работу func (sf *WarBot) Run() (err error) { if sf.isRun.Get() { return nil } if err := sf.angar.Run(); err != nil { return fmt.Errorf("WarBot.Run(): bot(%q) in run angar, err=\n\t%w", sf.name, err) } sf.isRun.Set() return nil } // Error -- возвращает финальную ошибку работы, если была func (sf *WarBot) Error() error { return sf.errFinal } // Angar -- возвращает ангар игры func (sf *WarBot) Angar() types.IAngar { return sf.angar } // Tank -- возвращает объект танка func (sf *WarBot) Tank() types.ITank { return sf.tank } // BotNet -- возвращает ссылку на свой сетевой клиент func (sf *WarBot) BotNet() types.IBotNet { return sf.botNet } // IsAutoGame -- возвращает признак автоматичского запуска бота func (sf *WarBot) IsAutoGame() bool { return sf.isAutoRun.Get() } // SetAutoGame -- устанавливает признак автоматического запуска бота func (sf *WarBot) SetAutoGame() { log.Printf("WarBot.SetAutoGame()") sf.isAutoRun.Set() sf.config.IsAutoRun_ = true sf.saveConfig() } // ResetAutoGame -- сбрасывает признак автоматического запуска бота func (sf *WarBot) ResetAutoGame() { log.Printf("WarBot.ResetAutoGame()") sf.isAutoRun.Set() sf.config.IsAutoRun_ = false sf.saveConfig() } // Сохраняет конфиг бота func (sf *WarBot) saveConfig() { log.Printf("WarBot.saveConfig()") strConf := sf.config.Marshall() err := sf.store.Put("/bots/"+sf.name, strConf) if err != nil { log.Printf("WarBot.saveConfig(): err=\n\t%v\n", err) } } // Ctx -- возвращает контекст бота func (sf *WarBot) Ctx() context.Context { return sf.ctx } // CancelBot -- отменяет контекст бота func (sf *WarBot) CancelBot() { sf.fnCancel() }