manevr.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package manevr
  2. import (
  3. "context"
  4. // "log"
  5. "strings"
  6. "time"
  7. "wartank/app/lev1/repair_time"
  8. // "wartank/internal/components/sound"
  9. . "wartank/app/lev0/types"
  10. . "gitp78su.ipnodns.ru/svi/kern"
  11. . "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
  12. . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
  13. )
  14. /*
  15. Пытается маневрировать после выстрела
  16. */
  17. // манёвр -- маневрирует после выстрела
  18. type манёвр struct {
  19. ИСражениеПроцесс // FIXME:
  20. лог ILogBuf
  21. isEnd ISafeBool
  22. ctxEnd context.Context
  23. еслиНадо ISafeBool
  24. еслиГотов ISafeBool // Возможность выполнить манёвр
  25. manevrTime *repair_time.RepairTime // Время до восстановления манёвра
  26. chTick chan int // Тики для поиска маневра
  27. }
  28. // НовМанёвр -- возвращает новый манёвр
  29. func НовМанёвр(проц ИСражениеПроцесс) ИМанёвр {
  30. Hassert(проц != nil, "НовМанёвр(): ИСражениеПроцесс==nil")
  31. сам := &манёвр{
  32. ИСражениеПроцесс: проц,
  33. лог: проц.Бот().КонтБот().Log(),
  34. ctxEnd: проц.Контекст(),
  35. еслиНадо: NewSafeBool(),
  36. isEnd: проц.ЕслиКонец(),
  37. еслиГотов: NewSafeBool(),
  38. manevrTime: repair_time.NewRepairTime(),
  39. chTick: make(chan int, 1),
  40. }
  41. _ = сам.manevrTime.Уст("0") // При запуске боя есть возможность маневрировать
  42. go сам.makeTick()
  43. go сам.run()
  44. return сам
  45. }
  46. // ЕслиГотов -- возвращает признак готовности к манёвру
  47. func (сам *манёвр) ЕслиГотов() bool {
  48. return сам.еслиГотов.Get()
  49. }
  50. // УстНадо -- устанавливает требование манёвра
  51. func (сам *манёвр) УстНадо() {
  52. сам.еслиНадо.Set()
  53. }
  54. // Генерирует тик для уменьшения времени ожидания восстановления возможности манёвра
  55. func (сам *манёвр) makeTick() {
  56. defer func() {
  57. close(сам.chTick)
  58. // log._rintf("манёвр.makeTick(): сражение завершено\n")
  59. }()
  60. for {
  61. select {
  62. case <-сам.ctxEnd.Done():
  63. return
  64. default:
  65. if сам.manevrTime.Получ() == 0 {
  66. сам.chTick <- 1
  67. }
  68. сам.manevrTime.Dec()
  69. time.Sleep(time.Second * 1)
  70. }
  71. }
  72. }
  73. // Рабочий цикл поиска маневра (~)
  74. func (сам *манёвр) run() {
  75. for range сам.chTick {
  76. if !сам.еслиГотов.Get() {
  77. continue
  78. }
  79. сам.findManevrTime()
  80. }
  81. }
  82. // Ищет время для манёвра
  83. func (сам *манёвр) findManevrTime() {
  84. var (
  85. еслиНайдено bool
  86. ind int
  87. lstBattleOn = сам.СписПолучить()
  88. стрВых string
  89. )
  90. for ind, стрВых = range lstBattleOn {
  91. // <a href="pve?4-88.ILinkListener-currentControl-maneuverLink" class="simple-but blue"><span><span>5 секунд</span></span></a>
  92. if strings.Contains(стрВых, `-currentControl-maneuverLink`) {
  93. еслиНайдено = true
  94. break
  95. }
  96. }
  97. if !еслиНайдено { // Или манёвр успел восстановиться, или конец сражения
  98. if strings.Contains(стрВых, `<span>Маневр</span>`) {
  99. _ = сам.manevrTime.Уст("0")
  100. time.Sleep(time.Second * 1)
  101. return
  102. }
  103. if сам.isEnd.Get() {
  104. time.Sleep(time.Second * 1)
  105. return
  106. }
  107. сам.лог.Warn("findManevrTime(): ошибка в поиске времени манёвра, стрВых=%v", стрВых)
  108. time.Sleep(time.Second * 1)
  109. return
  110. }
  111. { // Найти время манёвра
  112. lstTime := strings.Split(стрВых, `ILinkListener-currentControl-maneuverLink" class="simple-but blue"><span><span>`)
  113. if len(lstTime) != 2 {
  114. сам.лог.Err("манёвр.findManevrTime(): нет двух полей во времени ожидания инд=%v\n\n%v\n%v\n%v",
  115. ind,
  116. lstBattleOn[ind-1],
  117. стрВых,
  118. lstBattleOn[ind+1],
  119. )
  120. сам.еслиГотов.Reset()
  121. time.Sleep(time.Second * 1)
  122. return
  123. }
  124. strTime := lstTime[1]
  125. lstTime = strings.Split(strTime, ` секунд</span></span></a>`)
  126. strTime = lstTime[0]
  127. if err := сам.manevrTime.Уст(strTime); err != nil {
  128. сам.лог.Err("манёвр.findManevrTime(): при обновлении времени ожидания манёвра, ош=\n\t%v", err)
  129. сам.еслиГотов.Reset()
  130. time.Sleep(time.Second * 1)
  131. return
  132. }
  133. }
  134. сам.еслиГотов.Set()
  135. сам.лог.Info("манёвр.findManevrTime(): до манёвра, время=%v", сам.manevrTime.Получ())
  136. }
  137. // Выполнить -- принудительный манёвр по требованию
  138. func (сам *манёвр) Выполнить() {
  139. var (
  140. еслиНайдено = false
  141. lstBattleOn = сам.СписПолучить()
  142. strOut = ""
  143. )
  144. if !сам.еслиГотов.Get() {
  145. time.Sleep(time.Second * 1)
  146. return
  147. }
  148. for _, strOut = range lstBattleOn {
  149. // <a href="pve?4-21.ILinkListener-currentControl-maneuverLink" class="simple-but blue"><span><span>Маневр</span></span></a>
  150. if strings.Contains(strOut, `<span>Маневр</span>`) {
  151. еслиНайдено = true
  152. break
  153. }
  154. }
  155. if !еслиНайдено { // Либо ждём восстановления манёвра, либо сражение закончилось
  156. сам.еслиГотов.Reset()
  157. time.Sleep(time.Second * 1)
  158. return
  159. }
  160. { // Попытка манёвра
  161. lstLink := strings.Split(strOut, `<a href="`)
  162. strLink := lstLink[1]
  163. lstLink = strings.Split(strLink, `" class="simple-but blue"><span><span>Маневр</span></span></a>`)
  164. strLink = "https://wartank.ru/" + lstLink[0]
  165. lstBattleOn, err := сам.Сеть().Get(strLink)
  166. if err != nil {
  167. сам.лог.Err("манёвр.Выполнить(): при выполнении GET-команды маневра, ош=\n\t%v", err)
  168. сам.еслиГотов.Reset()
  169. time.Sleep(time.Second * 1)
  170. return
  171. }
  172. сам.СтрОбновить(lstBattleOn)
  173. // sound.манёвр()
  174. }
  175. }
  176. // IsReady -- возвращает готовность манёвра
  177. func (сам *манёвр) IsReady() bool {
  178. return сам.manevrTime.IsReady()
  179. }