bot.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // package bot -- бот для игры в wartank
  2. package bot
  3. import (
  4. "fmt"
  5. "log"
  6. "strings"
  7. "time"
  8. . "gitp78su.ipnodns.ru/svi/kern"
  9. . "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
  10. . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
  11. . "wartank/app/lev0/alias"
  12. "wartank/app/lev0/bfunc/bf_fuel_attack"
  13. "wartank/app/lev0/bfunc/bf_fuel_find"
  14. "wartank/app/lev0/bfunc/bf_gold_find"
  15. "wartank/app/lev0/bfunc/bf_mission_simple"
  16. "wartank/app/lev0/bfunc/bf_silver_find"
  17. . "wartank/app/lev0/types"
  18. "wartank/app/lev2"
  19. "wartank/app/lev3/bot/bot_config"
  20. "wartank/app/lev3/bot/bot_net"
  21. "wartank/app/lev3/bot/bot_stat/tank_stat"
  22. )
  23. // ВарБот -- бот для игры в вартанк
  24. type Бот struct {
  25. прилож ИПриложение
  26. хран IKernelStoreKv
  27. стата ИТанкСтат
  28. errFinal error // Финальная ошибка работы, если была
  29. сеть ИБотСеть
  30. ангар ИАренаАнгар
  31. еслиРаботает ISafeBool
  32. еслиАвтозапуск ISafeBoolReact
  33. лог ILogBuf
  34. конт ILocalCtx
  35. конфиг *bot_config.БотКонфиг
  36. }
  37. // ЗагрузитьВарБот -- загружает бота из базы
  38. func ЗагрузитьВарБот(номер АБотНомер) *Бот {
  39. лог := NewLogBuf()
  40. лог.Info("ЗагрузитьВарБот()\n")
  41. Hassert(номер != 0, "ЗагрузитьВарБот(): номер пустой")
  42. стрНомер := fmt.Sprint(номер)
  43. лог.Info("ЗагрузитьВарБот(): номер=%q\n", стрНомер)
  44. конт := GetKernelCtx()
  45. хран := конт.Get("kernStoreKV").Val().(IKernelStoreKv)
  46. binData, err := хран.Get("/bots/" + стрНомер)
  47. if err != nil {
  48. if !strings.Contains(err.Error(), "not found") {
  49. Hassert(false, "ЗагрузитьВарБот(): in load bot '%v' from store, err=\n\t%v\n", номер, err)
  50. }
  51. Hassert(err == nil, "ЗагрузитьВарБот(): in load bot '%v' from store, err=\n\t%v\n", номер, err)
  52. }
  53. конфиг := &bot_config.БотКонфиг{}
  54. конфиг.Unmarshal(binData)
  55. сам := создатьЯдроВарБот(конфиг)
  56. go сам.рестарт()
  57. _ = ИБот(сам)
  58. return сам
  59. }
  60. // Каждые два часа перезапускает себя
  61. func (сам *Бот) рестарт() {
  62. time.Sleep(time.Hour * 2)
  63. сам.конт.Cancel()
  64. сам.лог.Info("рестарт(): бот %q перезагружен\n", сам.конфиг.Логин_)
  65. }
  66. // НовВарБот -- возвращает новый WarBot
  67. func НовВарБот(конт IKernelCtx, номер АБотНомер, логин, пароль string, еслиАвто bool) *Бот {
  68. лог := NewLogBuf()
  69. лог.Info("НовВарБот()\n")
  70. Hassert(логин != "", "НовВарБот(): логин пустой")
  71. Hassert(пароль != "", "НовВарБот(): пароль пустой")
  72. лог.Info("НовВарБот(): name=%q\n", логин)
  73. config := &bot_config.БотКонфиг{
  74. ЕслиАвтозапуск_: еслиАвто,
  75. Логин_: логин,
  76. Пароль_: пароль,
  77. Номер_: номер,
  78. }
  79. сам := создатьЯдроВарБот(config)
  80. сам.сохрКонфиг()
  81. _ = ИБот(сам)
  82. return сам
  83. }
  84. // Создаёт ядро бота
  85. func создатьЯдроВарБот(конфиг *bot_config.БотКонфиг) *Бот {
  86. Hassert(конфиг != nil, "создатьЯдроВарБот(): ВарБотКонфиг==nil")
  87. лог := NewLogBuf()
  88. лог.Info("создатьЯдроВарБот()\n")
  89. конт := GetKernelCtx()
  90. приложение := конт.Get("мод_сервер").Val().(ИПриложение)
  91. контБот := NewLocalCtx(конт.Ctx())
  92. сам := &Бот{
  93. конт: контБот,
  94. прилож: приложение,
  95. хран: конт.Get("kernStoreKV").Val().(IKernelStoreKv),
  96. стата: tank_stat.НовТанкСтат(контБот),
  97. еслиРаботает: NewSafeBool(),
  98. конфиг: конфиг,
  99. лог: лог,
  100. }
  101. сам.еслиАвтозапуск = NewSafeBoolReact()
  102. сам.еслиАвтозапуск.Add(сам.Имя(), сам.автозапускИзм)
  103. сам.конт.Set("бот", сам, "создание ядра")
  104. сам.конт.Set("приложение", приложение, "Приложение WarBot")
  105. сам.сеть = bot_net.НовБотСеть(сам.конт)
  106. if сам.конфиг.ЕслиАвтозапуск_ {
  107. сам.еслиАвтозапуск.Set()
  108. сам.Пуск()
  109. }
  110. сам.ангар = lev2.НовАнгар(сам.конт)
  111. _ = lev2.НовМиссииПростые(сам.конт)
  112. _ = lev2.НовПолигон(сам.конт)
  113. _ = lev2.НовБаза(сам.конт)
  114. _ = lev2.НовШахта(сам.конт)
  115. _ = lev2.НовАрсенал(сам.конт)
  116. _ = lev2.НовАренаТопливо(сам.конт)
  117. return сам
  118. }
  119. // ЕслиРабота -- возвращает признак, что бот подключен
  120. func (сам *Бот) ЕслиРабота() bool {
  121. return сам.еслиРаботает.Get()
  122. }
  123. // Номер -- возвращает номер бота
  124. func (сам *Бот) Номер() АБотНомер {
  125. return сам.конфиг.Номер()
  126. }
  127. // Имя -- возвращает имя бота
  128. func (сам *Бот) Имя() string {
  129. return сам.конфиг.Логин()
  130. }
  131. // Пароль -- возвращает пароль бота
  132. func (сам *Бот) Пароль() string {
  133. return сам.конфиг.Пароль_
  134. }
  135. // Пуск -- запускает бот в работу
  136. func (сам *Бот) Пуск() {
  137. if сам.еслиРаботает.Get() {
  138. return
  139. }
  140. go сам.пуск()
  141. сам.еслиРаботает.Set()
  142. }
  143. // Работает в отдельном потоке ,пока сервер не даст команду остановки
  144. func (сам *Бот) пуск() {
  145. for {
  146. select {
  147. case <-сам.конт.Ctx().Done():
  148. return
  149. default:
  150. time.Sleep(time.Second * 5)
  151. сам.ангар.Обновить()
  152. bf_gold_find.ЗолотоНайти(сам.конт)
  153. bf_silver_find.СереброНайти(сам.конт)
  154. bf_fuel_find.ТопливоНайти(сам.конт)
  155. bf_fuel_attack.ТопливоАтаковать(сам.конт)
  156. bf_mission_simple.МиссииПростыеЗабрать(сам.конт)
  157. }
  158. }
  159. }
  160. // Error -- возвращает финальную ошибку работы, если была
  161. func (сам *Бот) Error() error {
  162. return сам.errFinal
  163. }
  164. // Стата -- возвращает статистику танка
  165. func (сам *Бот) Стата() ИТанкСтат {
  166. return сам.стата
  167. }
  168. // Сеть -- возвращает ссылку на свой сетевой клиент
  169. func (сам *Бот) Сеть() ИБотСеть {
  170. return сам.сеть
  171. }
  172. // Автозапуск -- возвращает признак автоматического запуска бота
  173. func (сам *Бот) Автозапуск() ISafeBoolReact {
  174. return сам.еслиАвтозапуск
  175. }
  176. // Обратный вызов автоматического запуска бота
  177. func (сам *Бот) автозапускИзм(знач bool) {
  178. сам.лог.Debug("Бот.автозапускИзм()")
  179. // сам.еслиАвтозапуск.Уст()
  180. сам.конфиг.ЕслиАвтозапуск_ = знач
  181. сам.сохрКонфиг()
  182. }
  183. // Сохраняет конфиг бота
  184. func (сам *Бот) сохрКонфиг() {
  185. log.Printf("ВарБот.сохрКонфиг()")
  186. strConf := сам.конфиг.Marshall()
  187. стрНомер := fmt.Sprint(сам.Номер())
  188. err := сам.хран.Set("/bots/"+стрНомер, strConf)
  189. Hassert(err == nil, "ВарБот.сохрКонфиг(): err=\n\t%v\n", err)
  190. }
  191. // КонтБот -- возвращает контекст бота
  192. func (сам *Бот) КонтБот() ILocalCtx {
  193. return сам.конт
  194. }