bot.go 9.4 KB

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