bot.go 9.3 KB

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