divwar.go 6.8 KB

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