manevr.go 6.2 KB

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