| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // package bot -- бот для игры в wartank
- package bot
- import (
- "context"
- "fmt"
- "log"
- "strings"
- "time"
- . "wartank/app/lev0/alias"
- . "wartank/app/lev0/types"
- "wartank/app/lev2/arena_angar"
- "wartank/app/lev3/bot/bot_config"
- "wartank/app/lev3/bot/bot_net"
- "wartank/app/lev3/bot/bot_stat/tank_stat"
- "wartank/kernel"
- . "wartank/kernel/kernel_types"
- )
- // ВарБот -- бот для игры в вартанк
- type Бот struct {
- прилож ИПриложение
- хран ИЯдроХранилище
- стата ИТанкСтат
- errFinal error // Финальная ошибка работы, если была
- ангар ИАнгар
- сеть ИБотСеть
- еслиРаботает ИБезопБул
- еслиАвтозапуск ИБезопБул
- конфиг *bot_config.БотКонфиг // Конфиг бота для хранения в базе
- кнт context.Context // Контекст бота
- фтОтмена func() // Функция отменя контекста бота
- лог ИЯдроЛог
- конт ИБотКонтекст
- }
- // ЗагрузитьВарБот -- загружает бота из базы
- func ЗагрузитьВарБот(конт ИЯдроКонтекст, номер АБотНомер) *Бот {
- лог := kernel.НовЛог("ВарБот")
- лог.Инфо("ЗагрузитьВарБот()\n")
- лог.Паника(номер == 0, "ЗагрузитьВарБот(): номер пустой")
- стрНомер := fmt.Sprint(номер)
- log.Printf("ЗагрузитьВарБот(): номер=%q\n", стрНомер)
- хран := конт.Получ("kernStore").(ИЯдроХранилище)
- binData, err := хран.Get("/bots/" + стрНомер)
- if err != nil {
- if !strings.Contains(err.Error(), "not found") {
- лог.Паника(true, "ЗагрузитьВарБот(): in load bot '%v' from store, err=\n\t%v\n", номер, err)
- }
- лог.Паника(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)
- сам.прилож.Отменить()
- log.Printf("ВарБот.рестарт(): бот %q перезагружен\n", сам.конфиг.Логин_)
- }
- // НовВарБот -- возвращает новый WarBot
- func НовВарБот(конт ИЯдроКонтекст, номер АБотНомер, логин, пароль string, еслиАвто bool) *Бот {
- лог := kernel.НовЛог("ВарБот")
- лог.Инфо("НовВарБот()\n")
- лог.Паника(логин == "", "НовВарБот(): логин пустой")
- лог.Паника(пароль == "", "НовВарБот(): пароль пустой")
- log.Printf("НовВарБот(): name=%q\n", логин)
- config := &bot_config.БотКонфиг{
- ЕслиАвтозапуск_: еслиАвто,
- Логин_: логин,
- Пароль_: пароль,
- Номер_: номер,
- }
- сам := создатьЯдроВарБот(конт, config)
- сам.сохр()
- _ = ИБот(сам)
- return сам
- }
- // Создаёт ядро бота
- func создатьЯдроВарБот(конт ИЯдроКонтекст, конфиг *bot_config.БотКонфиг) *Бот {
- лог := kernel.НовЛог("ВарБот")
- лог.Инфо("создатьЯдроВарБот()\n")
- лог.Паника(конфиг == nil, "создатьЯдроВарБот(): ВарБотКонфиг==nil")
- ctx, fnCancel := context.WithCancel(конт.Конт())
- приложение := конт.Получ("приложение").(ИПриложение)
- контБот := kernel.НовКонтекст()
- сам := &Бот{
- конт: контБот,
- прилож: приложение,
- хран: конт.Получ("kernStore").(ИЯдроХранилище),
- стата: tank_stat.НовТанкСтат(конт),
- еслиРаботает: kernel.НовБезопБул(),
- еслиАвтозапуск: kernel.НовБезопБул(),
- конфиг: конфиг,
- кнт: ctx,
- фтОтмена: fnCancel,
- лог: лог,
- }
- сам.конт.Уст("бот", сам)
- сам.конт.Уст("приложение", приложение)
- var err error
- // WarBotNet
- сам.сеть = bot_net.НовБотСеть(сам.конт)
- сам.ангар, err = arena_angar.НовАнгар(сам.конт)
- сам.лог.Паника(err != nil, "НовВарБот(): in make IAngar, err=\n\t%w", err)
- if сам.конфиг.ЕслиАвтозапуск_ {
- сам.еслиАвтозапуск.Уст()
- сам.Пуск()
- }
- return сам
- }
- // Сервер -- возвращает ссылку на объект сервера
- func (сам *Бот) Сервер() ИПриложение {
- return сам.прилож
- }
- // ЕслиПуск -- возвращает признак, что бот подключен
- func (сам *Бот) ЕслиПуск() bool {
- return сам.еслиРаботает.Получ()
- }
- // Номер -- возвращает номер бота
- func (сам *Бот) Номер() АБотНомер {
- return сам.конфиг.Номер()
- }
- // Имя -- возвращает имя бота
- func (сам *Бот) Имя() string {
- return сам.конфиг.Логин()
- }
- // Пароль -- возвращает пароль бота
- func (сам *Бот) Пароль() string {
- return сам.конфиг.Пароль_
- }
- // Пуск -- запускает бот в работу
- func (сам *Бот) Пуск() {
- if сам.еслиРаботает.Получ() {
- return
- }
- сам.ангар.Пуск()
- сам.еслиРаботает.Уст()
- }
- // Error -- возвращает финальную ошибку работы, если была
- func (сам *Бот) Error() error {
- return сам.errFinal
- }
- // Ангар -- возвращает ангар игры
- func (сам *Бот) Ангар() ИАнгар {
- return сам.ангар
- }
- // Стата -- возвращает статистику танка
- func (сам *Бот) Стата() ИТанкСтат {
- return сам.стата
- }
- // Сеть -- возвращает ссылку на свой сетевой клиент
- func (сам *Бот) Сеть() ИБотСеть {
- return сам.сеть
- }
- // АвтоИграЕсли -- возвращает признак автоматического запуска бота
- func (сам *Бот) АвтоИграЕсли() bool {
- return сам.еслиАвтозапуск.Получ()
- }
- // АвтоИграУст -- устанавливает признак автоматического запуска бота
- func (сам *Бот) АвтоИграУст() {
- log.Printf("WarBot.SetAutoGame()")
- сам.еслиАвтозапуск.Уст()
- сам.конфиг.ЕслиАвтозапуск_ = true
- сам.сохрКонфиг()
- }
- // АвтоИграСброс -- сбрасывает признак автоматического запуска бота
- func (сам *Бот) АвтоИграСброс() {
- log.Printf("WarBot.ResetAutoGame()")
- сам.еслиАвтозапуск.Уст()
- сам.конфиг.ЕслиАвтозапуск_ = false
- сам.сохрКонфиг()
- }
- // Сохраняет конфиг бота
- func (сам *Бот) сохрКонфиг() {
- log.Printf("ВарБот.сохрКонфиг()")
- strConf := сам.конфиг.Marshall()
- err := сам.хран.Set("/bots/"+сам.Имя(), strConf)
- if err != nil {
- log.Printf("ВарБот.сохрКонфиг(): err=\n\t%v\n", err)
- }
- }
- // Контекст -- возвращает контекст бота
- func (сам *Бот) Контекст() context.Context {
- return сам.кнт
- }
- // Закончить -- отменяет контекст бота
- func (сам *Бот) Закончить() {
- сам.фтОтмена()
- }
- // Сохраняет себя в базу
- func (сам *Бот) сохр() {
- стрНомер := fmt.Sprint(сам.Номер())
- err := сам.хран.Set("/bots/"+стрНомер, сам.конфиг.Marshall())
- сам.лог.Паника(err != nil, "ВарБот.сохр(): err=\n\t%v\n", err)
- }
- // КонтБот -- возвращает контекст бота
- func (сам *Бот) КонтБот() ИБотКонтекст {
- return сам.конт
- }
|