bot.go 9.3 KB

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