// package bot -- бот для игры в wartank package bot import ( "fmt" "log" "strings" "time" . "gitp78su.ipnodns.ru/svi/kern" . "gitp78su.ipnodns.ru/svi/kern/kc/helpers" . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes" . "wartank/app/lev0/alias" "wartank/app/lev0/bfunc/bf_ammo_make" "wartank/app/lev0/bfunc/bf_ammo_stat" "wartank/app/lev0/bfunc/bf_fuel_attack" "wartank/app/lev0/bfunc/bf_fuel_find" "wartank/app/lev0/bfunc/bf_glory_make" "wartank/app/lev0/bfunc/bf_gold_find" "wartank/app/lev0/bfunc/bf_mission_simple" "wartank/app/lev0/bfunc/bf_polygon_activate" "wartank/app/lev0/bfunc/bf_silver_find" "wartank/app/lev0/bfunc/bf_silver_get" "wartank/app/lev0/bfunc/bf_silver_prod" "wartank/app/lev0/bfunc/bf_tank_stat" . "wartank/app/lev0/types" "wartank/app/lev2" "wartank/app/lev3/bot/bot_config" "wartank/app/lev3/bot/bot_net" "wartank/app/lev3/bot/bot_stat/tank_stat" ) // ВарБот -- бот для игры в вартанк type Бот struct { прилож ИПриложение хран IKernelStoreKv стата ИТанкСтат errFinal error // Финальная ошибка работы, если была сеть ИБотСеть ангар ИАренаАнгар еслиРаботает ISafeBool еслиАвтозапуск ISafeBoolReact лог ILogBuf конт ILocalCtx конфиг *bot_config.БотКонфиг } // ЗагрузитьВарБот -- загружает бота из базы func ЗагрузитьВарБот(номер АБотНомер) *Бот { лог := NewLogBuf() лог.Info("ЗагрузитьВарБот()\n") Hassert(номер != 0, "ЗагрузитьВарБот(): номер пустой") стрНомер := fmt.Sprint(номер) лог.Info("ЗагрузитьВарБот(): номер=%q\n", стрНомер) конт := GetKernelCtx() хран := конт.Get("kernStoreKV").Val().(IKernelStoreKv) binData, err := хран.Get("/bots/" + стрНомер) if err != nil { if !strings.Contains(err.Error(), "not found") { Hassert(false, "ЗагрузитьВарБот(): in load bot '%v' from store, err=\n\t%v\n", номер, err) } Hassert(err == nil, "ЗагрузитьВарБот(): in load bot '%v' from store, err=\n\t%v\n", номер, err) } конфиг := &bot_config.БотКонфиг{} конфиг.Unmarshal(binData) сам := создатьЯдроВарБот(конфиг) go сам.рестарт() _ = ИБот(сам) return сам } // Каждые два часа перезапускает себя func (сам *Бот) рестарт() { time.Sleep(time.Hour * 2) сам.конт.Cancel() сам.лог.Info("рестарт(): бот %q перезагружен\n", сам.конфиг.Логин_) } // НовВарБот -- возвращает новый WarBot func НовВарБот(конт IKernelCtx, номер АБотНомер, логин, пароль string, еслиАвто bool) *Бот { лог := NewLogBuf() лог.Info("НовВарБот()\n") Hassert(логин != "", "НовВарБот(): логин пустой") Hassert(пароль != "", "НовВарБот(): пароль пустой") лог.Info("НовВарБот(): name=%q\n", логин) config := &bot_config.БотКонфиг{ ЕслиАвтозапуск_: еслиАвто, Логин_: логин, Пароль_: пароль, Номер_: номер, } сам := создатьЯдроВарБот(config) сам.сохрКонфиг() _ = ИБот(сам) return сам } // Создаёт ядро бота func создатьЯдроВарБот(конфиг *bot_config.БотКонфиг) *Бот { Hassert(конфиг != nil, "создатьЯдроВарБот(): ВарБотКонфиг==nil") лог := NewLogBuf() лог.Info("создатьЯдроВарБот()\n") конт := GetKernelCtx() приложение := конт.Get("мод_сервер").Val().(ИПриложение) контБот := NewLocalCtx(конт.Ctx()) сам := &Бот{ конт: контБот, прилож: приложение, хран: конт.Get("kernStoreKV").Val().(IKernelStoreKv), стата: tank_stat.НовТанкСтат(контБот), еслиРаботает: NewSafeBool(), конфиг: конфиг, лог: лог, } сам.еслиАвтозапуск = NewSafeBoolReact() сам.еслиАвтозапуск.Add(сам.Имя(), сам.автозапускИзм) сам.конт.Set("бот", сам, "создание ядра") сам.конт.Set("приложение", приложение, "Приложение WarBot") сам.сеть = bot_net.НовБотСеть(сам.конт) if сам.конфиг.ЕслиАвтозапуск_ { сам.еслиАвтозапуск.Set() сам.Пуск() } сам.ангар = lev2.НовАнгар(сам.конт) _ = lev2.НовКонвой(сам.конт) _ = lev2.НовБанк(сам.конт) _ = lev2.НовМиссииПростые(сам.конт) _ = lev2.НовПолигон(сам.конт) _ = lev2.НовБаза(сам.конт) _ = lev2.НовШахта(сам.конт) _ = lev2.НовАрсенал(сам.конт) _ = lev2.НовАренаТопливо(сам.конт) return сам } // ЕслиРабота -- возвращает признак, что бот подключен func (сам *Бот) ЕслиРабота() bool { return сам.еслиРаботает.Get() } // Номер -- возвращает номер бота func (сам *Бот) Номер() АБотНомер { return сам.конфиг.Номер() } // Имя -- возвращает имя бота func (сам *Бот) Имя() string { return сам.конфиг.Логин() } // Пароль -- возвращает пароль бота func (сам *Бот) Пароль() string { return сам.конфиг.Пароль_ } // Пуск -- запускает бот в работу func (сам *Бот) Пуск() { if сам.еслиРаботает.Get() { return } go сам.пуск() сам.еслиРаботает.Set() } // Работает в отдельном потоке ,пока сервер не даст команду остановки func (сам *Бот) пуск() { for { select { case <-сам.конт.Ctx().Done(): return default: time.Sleep(time.Second * 5) сам.ангар.Обновить() bf_gold_find.ЗолотоНайти(сам.конт) bf_silver_find.СереброНайти(сам.конт) bf_fuel_find.ТопливоНайти(сам.конт) bf_fuel_attack.ТопливоАтаковать(сам.конт) bf_mission_simple.МиссииПростыеЗабрать(сам.конт) bf_silver_get.СереброЗабрать(сам.конт) bf_silver_prod.СереброПроизводить(сам.конт) bf_polygon_activate.ПолигонАктивировать(сам.конт) bf_tank_stat.ТанкСтатПолучить(сам.конт) bf_ammo_stat.СнарядыСтат(сам.конт) bf_ammo_make.СнарядыСделать(сам.конт) bf_glory_make.СлаваБой(сам.конт) } } } // Error -- возвращает финальную ошибку работы, если была func (сам *Бот) Error() error { return сам.errFinal } // Стата -- возвращает статистику танка func (сам *Бот) Стата() ИТанкСтат { return сам.стата } // Сеть -- возвращает ссылку на свой сетевой клиент func (сам *Бот) Сеть() ИБотСеть { return сам.сеть } // Автозапуск -- возвращает признак автоматического запуска бота func (сам *Бот) Автозапуск() ISafeBoolReact { return сам.еслиАвтозапуск } // Обратный вызов автоматического запуска бота func (сам *Бот) автозапускИзм(знач bool) { сам.лог.Debug("Бот.автозапускИзм()") // сам.еслиАвтозапуск.Уст() сам.конфиг.ЕслиАвтозапуск_ = знач сам.сохрКонфиг() } // Сохраняет конфиг бота func (сам *Бот) сохрКонфиг() { log.Printf("ВарБот.сохрКонфиг()") strConf := сам.конфиг.Marshall() стрНомер := fmt.Sprint(сам.Номер()) err := сам.хран.Set("/bots/"+стрНомер, strConf) Hassert(err == nil, "ВарБот.сохрКонфиг(): err=\n\t%v\n", err) } // КонтБот -- возвращает контекст бота func (сам *Бот) КонтБот() ILocalCtx { return сам.конт }