div_war.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package div_war
  2. import (
  3. "fmt"
  4. "strings"
  5. "sync"
  6. "time"
  7. "wartank/app/lev0/alias"
  8. . "wartank/app/lev0/types"
  9. "wartank/app/lev1"
  10. "wartank/app/lev2/arena"
  11. "wartank/app/lev2/arena/arena_division/div_war/div_war_net"
  12. "wartank/app/lev2/arena/arena_division/div_war/process_divwar"
  13. "wartank/app/lev2/arena/arena_division/div_war/process_divwar/div_war_sound"
  14. . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
  15. )
  16. /*
  17. Объект ожидания битвы дивизий
  18. */
  19. // DivWar -- объект ожидания битвы дивизий
  20. type DivWar struct {
  21. ИАрена
  22. конт ILocalCtx
  23. bot ИБот
  24. alarm ИСтатПарам
  25. net *div_war_net.DivWarNet
  26. conn ИХттпВоркер
  27. // Непосредственная битва
  28. процВойна ИСражениеПроцесс
  29. логин string // Для непосредственной битвы дивизий
  30. block sync.Mutex
  31. chDivWar chan int // Сигнал начала битвы дивизий
  32. sound *div_war_sound.DivWarSound // Однопоточное проигрывание звука
  33. }
  34. // NewDivWar -- возвращает новый *DivWar
  35. func NewDivWar(конт IKernelCtx, bot ИБот) (*DivWar, error) {
  36. if bot == nil {
  37. return nil, fmt.Errorf("NewDivWar(): IBot == nil")
  38. }
  39. сам := &DivWar{
  40. bot: bot,
  41. alarm: lev1.НовСтатПарам("тревога"),
  42. chDivWar: make(chan int, 1),
  43. sound: div_war_sound.NewDivWarSound(),
  44. conn: bot.Сеть().ВебВоркер(),
  45. логин: "prospero tank",
  46. }
  47. аренаКонфиг := arena.АренаКонфиг{
  48. Бот_: bot,
  49. АренаИмя_: "Битва дивизий",
  50. СтрКонтроль_: `<span>до начала `,
  51. ФнПуск_: сам.пуск,
  52. }
  53. сам.ИАрена = arena.НовАрена(конт, аренаКонфиг)
  54. // сам.shotTimeFull.Set(8000) // 8000 msec
  55. var err error
  56. { // Net
  57. сам.net, err = div_war_net.NewDivWarNet(bot)
  58. if err != nil {
  59. return nil, fmt.Errorf("NewDivWar(): при создании DivWarNet, err=\n\t%w", err)
  60. }
  61. }
  62. go сам.run()
  63. go сам.резервТик()
  64. return сам, nil
  65. }
  66. // запускает в работу битву дивизий
  67. func (сам *DivWar) пуск() {
  68. }
  69. func (сам *DivWar) резервТик() {
  70. for {
  71. select {
  72. case <-сам.bot.КонтБот().Ctx().Done():
  73. return
  74. default:
  75. ct0 := сам.ВремяОстат().ПолучМилСек()
  76. time.Sleep(time.Second * 7)
  77. ct1 := сам.ВремяОстат().ПолучМилСек()
  78. if ct1.Сек() != ct0.Сек() {
  79. continue
  80. }
  81. if сам.процВойна != nil {
  82. continue
  83. }
  84. сам.chDivWar <- 1
  85. }
  86. }
  87. }
  88. // запускает в работу битву дивизий
  89. func (сам *DivWar) run() {
  90. сам.chDivWar <- 1
  91. for {
  92. select {
  93. case <-сам.bot.КонтБот().Ctx().Done():
  94. return
  95. case <-сам.ВремяОстат().КаналСиг(): // Время обновить данные по сражению
  96. сам.findTimeCount()
  97. сам.upDivWar()
  98. case <-сам.chDivWar: // Сигнал к началу сражения
  99. сам.block.Lock()
  100. if сам.процВойна != nil {
  101. continue
  102. }
  103. сам.alarm.Уст(1)
  104. сам.sound.Play()
  105. go сам.DivWar() // Запустить цикл непосредственного сражения
  106. time.Sleep(time.Second * 10) // Задержка для звука на странице
  107. сам.alarm.Уст(0)
  108. }
  109. }
  110. }
  111. // Ищет время до начала битвы дивизий
  112. func (сам *DivWar) findTimeCount() {
  113. сам.net.Обновить()
  114. var (
  115. strOut string
  116. lstDivWar = сам.СписПолучить()
  117. еслиНайдено bool
  118. ind int
  119. )
  120. for ind, strOut = range lstDivWar {
  121. if strings.Contains(strOut, `до начала: `) {
  122. ind++
  123. strOut = lstDivWar[ind]
  124. еслиНайдено = true
  125. break
  126. }
  127. if strings.Contains(strOut, `>ОБЫЧНЫЕ<`) { // Это уже битва
  128. сам.chDivWar <- 1
  129. return
  130. }
  131. }
  132. if !еслиНайдено { // Битва дивизий уже идёт
  133. сам.chDivWar <- 1
  134. return
  135. }
  136. lstTime := strings.Split(strOut, `<span>`)
  137. strTime := lstTime[1]
  138. lstTime = strings.Split(strTime, `</span>`)
  139. strTime = lstTime[0]
  140. сам.ОбратВремяУст(alias.АВремя(strTime))
  141. }
  142. // При необходимости поднимает взвод в атаку, вызывается только если обнаружено приглашение (+)
  143. func (сам *DivWar) upDivWar() {
  144. var (
  145. strOut string
  146. lstDivWar = сам.СписПолучить()
  147. еслиНайдено bool
  148. )
  149. for _, strOut = range lstDivWar {
  150. if strings.Contains(strOut, `>Взвод, подъем! В атаку!<`) {
  151. еслиНайдено = true
  152. break
  153. }
  154. if strings.Contains(strOut, `<div class="white medium cntr bold mb5">Вы в рядах участников</div>`) {
  155. // log._rintf("INFO DivWar.upDivWar(): уже зарегистрирован\n")
  156. return
  157. }
  158. }
  159. if !еслиНайдено {
  160. return
  161. }
  162. // Найдено приглашение на участие
  163. lstUp := strings.Split(strOut, `<a class="simple-but border" href="`)
  164. linkUp := lstUp[1]
  165. lstUp = strings.Split(linkUp, `"><span><span>Взвод, подъем! В атаку!</span></span></a>`)
  166. linkUp = "https://wartank.ru/" + lstUp[0]
  167. lstDivWar, err := сам.net.Get(linkUp)
  168. if err != nil {
  169. // log._rintf("ERRO DivWar.upDivWar(): при выполнении GET-команды на подъём в атаку, err=\n\t%v\n", err)
  170. return
  171. }
  172. сам.СтрОбновить(lstDivWar)
  173. }
  174. // Ведёт сражение
  175. func (сам *DivWar) DivWar() {
  176. defer func() {
  177. сам.процВойна = nil
  178. сам.block.Unlock()
  179. сам.ОбратВремяУст("01")
  180. }()
  181. сам.процВойна = process_divwar.НовПроцессДивизияВойна(сам.конт) // IDivWarOn (онлайн)
  182. // Цикл ожидания окончания сражения
  183. for !сам.процВойна.ЕслиКонец().Get() {
  184. time.Sleep(time.Second * 1)
  185. }
  186. }
  187. // Alarm -- возвращает признак начала сражения (для браузера)
  188. func (сам *DivWar) Alarm() ИСтатПарам {
  189. return сам.alarm
  190. }