polygon.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. package polygon
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "wartank/pkg/components/section"
  7. "wartank/pkg/types"
  8. "wartank/server/serv_bots/warbot/angar/base/polygon/polygonnet"
  9. )
  10. /*
  11. Объект полигона на базе
  12. */
  13. // Polygon -- объект полигона на базе
  14. type Polygon struct {
  15. *section.Section
  16. bot types.IBot
  17. tankStat types.ITankStat
  18. net *polygonnet.PolygonNet
  19. }
  20. // NewPolygon -- возвращает новый *Polygon
  21. func NewPolygon(base types.IBase) (*Polygon, error) {
  22. section, err := section.NewSection(base.Bot(), "Полигон", `<title>Полигон</title>`)
  23. if err != nil {
  24. return nil, fmt.Errorf("NewPolygon(): in create *Section, err=\n\t%w", err)
  25. }
  26. sf := &Polygon{
  27. Section: section,
  28. bot: base.Bot(),
  29. tankStat: base.Bot().Tank().TankStat(),
  30. }
  31. sf.net, err = polygonnet.NewPolygonNet(sf)
  32. if err != nil {
  33. return nil, fmt.Errorf("NewPolygon(): in create NetPolygon, err=\n\t%w", err)
  34. }
  35. return sf, nil
  36. }
  37. // Run -- запускает работу полигона в отдельном потоке
  38. func (sf *Polygon) Run() error {
  39. go sf.run()
  40. return nil
  41. }
  42. // выполняет опрос полигона базы.
  43. func (sf *Polygon) run() {
  44. sf.SetCountDown(2)
  45. for {
  46. select {
  47. case <-sf.bot.Ctx().Done():
  48. sf.CountDown().Stop()
  49. return
  50. case <-sf.CountDown().ChanSig():
  51. mode := sf.ModeCurrent().Get()
  52. if mode == "upgrade" {
  53. continue
  54. }
  55. sf.addForce()
  56. sf.checkForce()
  57. sf.updateTime()
  58. }
  59. }
  60. }
  61. // Обновляет оставшееся время полигона
  62. //
  63. // Этот объект сам описывает своё время
  64. func (sf *Polygon) updateTime() {
  65. var (
  66. strLastTime string
  67. isFind bool
  68. isSet bool
  69. lstPolygon = sf.GetLst()
  70. )
  71. defer func() {
  72. if !isSet {
  73. sf.SetCountDown(5)
  74. }
  75. }()
  76. for _, lastTime := range lstPolygon {
  77. if strings.Contains(lastTime, `>Осталось: `) {
  78. strLastTime = lastTime
  79. isFind = true
  80. break
  81. }
  82. }
  83. if !isFind { // Время полигона вышло
  84. return
  85. }
  86. lstTime := strings.Split(strLastTime, `>Осталось: `)
  87. strLastTime = lstTime[1]
  88. lstTime = strings.Split(strLastTime, `</span>`)
  89. strLastTime = lstTime[0]
  90. if err := sf.ParseCountDown(strLastTime); err != nil {
  91. // log._rintf("ERRO Polygon.updateTime(): при установке времени ожидания полигона(%v)\n\terr=%v\n", strLastTime, err)
  92. return
  93. }
  94. isSet = true
  95. }
  96. // Проверяет что именно активировано
  97. func (sf *Polygon) checkForce() {
  98. var (
  99. isFind bool
  100. lstPolygon = sf.GetLst()
  101. ind = 0
  102. strOut string
  103. )
  104. for ind, strOut = range lstPolygon {
  105. if strings.Contains(strOut, `<span>Активно</span>`) {
  106. ind -= 9
  107. isFind = true
  108. break
  109. }
  110. }
  111. if !isFind {
  112. return
  113. }
  114. strOut = lstPolygon[ind]
  115. switch { // Вычисляем контрольную строку
  116. case strings.Contains(strOut, `>улучшение точности<`):
  117. sf.tankStat.Force().SetName("fyne")
  118. case strings.Contains(strOut, `>увеличение прочности<`):
  119. sf.tankStat.Force().SetName("hard")
  120. case strings.Contains(strOut, `>усиление брони<`):
  121. sf.tankStat.Force().SetName("armor")
  122. case strings.Contains(strOut, `>усиление атаки<`):
  123. sf.tankStat.Force().SetName("attack")
  124. }
  125. // Вычислим на сколько
  126. strOut = lstPolygon[ind+1]
  127. lstOut := strings.Split(strOut, `<span class="green2">+`)
  128. strOut = lstOut[1]
  129. lstOut = strings.Split(strOut, ` на `)
  130. strOut = lstOut[0]
  131. iForce, err := strconv.Atoi(strOut)
  132. if err != nil {
  133. // log._rintf("NetPolygon.checkTime(): force(%v) not number, err=\n\t%v\n", strOut, err)
  134. return
  135. }
  136. sf.tankStat.Force().SetVal(iForce)
  137. }
  138. // Выбирает самый слабый параметр и усиливает его
  139. func (sf *Polygon) addForce() {
  140. if err := sf.net.UpdateLst(); err != nil {
  141. // log._rintf("Polygon.checkPolygon(): при принудительном обновлении lstPlygon, mode=%s\terr=\n\t%v\n", sf.ModeCurrent().Get(), err)
  142. sf.SetCountDown(5)
  143. return
  144. }
  145. lstPoligon := sf.GetLst()
  146. if len(lstPoligon) == 0 {
  147. return
  148. }
  149. stat := sf.tankStat
  150. iAttack := stat.Attack().Val()
  151. iArmor := stat.Armor().Val()
  152. iFyne := stat.Fyne().Val()
  153. iHard := stat.Hard().Val()
  154. strParam := "attack"
  155. iParam := iHard
  156. {
  157. /*
  158. Вычислить самый слабый параметр.
  159. Политика вычислений:
  160. 1) hard -- прочность, самый низкоприоритетный параметр
  161. 2) armor -- броня, чуть лучше power
  162. 3) fyne -- точность, чуть лучше armor
  163. 4) attack -- атака, самый важный
  164. */
  165. if iArmor <= iParam {
  166. iParam = iArmor
  167. strParam = "armor"
  168. }
  169. if iFyne <= iParam {
  170. iParam = iFyne
  171. strParam = "fyne"
  172. }
  173. if iAttack < iParam {
  174. strParam = "attack"
  175. }
  176. }
  177. // Найти нужную строку активации
  178. var (
  179. ind int
  180. strOut string
  181. isFind bool
  182. )
  183. switch strParam {
  184. case "attack": // Усиливаем атаку
  185. for ind, strOut = range lstPoligon {
  186. if strings.Contains(strOut, `>усиление атаки<`) {
  187. isFind = true
  188. break
  189. }
  190. }
  191. if !isFind {
  192. return
  193. }
  194. ind += 8
  195. strOut = lstPoligon[ind]
  196. if strOut == "" {
  197. return
  198. }
  199. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  200. strOut = lstLink[1]
  201. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  202. strLink := "http://wartank.ru/" + lstLink[0]
  203. if _, err := sf.net.Get(strLink); err != nil {
  204. // log._rintf("ERRO NetPolygon.addForce(): in make request force attack, err=\n\t%v\n", err)
  205. return
  206. }
  207. { // Узнать на сколько форсирована атака
  208. strForce := lstPoligon[ind-7]
  209. lstForce := strings.Split(strForce, `<span class="green2">+`)
  210. strForce = lstForce[1]
  211. lstForce = strings.Split(strForce, ` на `)
  212. strForce = lstForce[0]
  213. iForce, err := strconv.Atoi(strForce)
  214. if err != nil {
  215. // log._rintf("ERRO NetPolygon.addForce(): strForceAttack(%v) not int, err=\n\t%v\n", strForce, err)
  216. return
  217. }
  218. sf.tankStat.Force().SetVal(iForce)
  219. sf.tankStat.Force().SetName("attack")
  220. sf.ModeCurrent().Set("атака")
  221. }
  222. case "armor": // Усиливаем броню
  223. isFind = false
  224. for ind, strOut = range lstPoligon {
  225. if strings.Contains(strOut, `>усиление брони<`) {
  226. isFind = true
  227. break
  228. }
  229. }
  230. if !isFind {
  231. return
  232. }
  233. ind += 8
  234. strOut = lstPoligon[ind]
  235. if strOut == "" {
  236. return
  237. }
  238. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  239. strOut = lstLink[1]
  240. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  241. strLink := "http://wartank.ru/" + lstLink[0]
  242. if _, err := sf.net.Get(strLink); err != nil {
  243. // log._rintf("NetPolygon.addForce(): in make request force armor, err=\n\t%v\n", err)
  244. return
  245. }
  246. { // Узнать на сколько форсирована броня
  247. strForce := lstPoligon[ind-7]
  248. lstForce := strings.Split(strForce, `<span class="green2">+`)
  249. strForce = lstForce[1]
  250. lstForce = strings.Split(strForce, ` на `)
  251. strForce = lstForce[0]
  252. iForce, err := strconv.Atoi(strForce)
  253. if err != nil {
  254. // log._rintf("ERRO NetPolygon.addForce(): strForceArmor(%v) not int, err=\n\t%v\n", strForce, err)
  255. return
  256. }
  257. sf.tankStat.Force().SetVal(iForce)
  258. sf.tankStat.Force().SetName("armor")
  259. sf.ModeCurrent().Set("броня")
  260. }
  261. case "fyne": // Усиливаем точность
  262. isFind = false
  263. for ind, strOut = range lstPoligon {
  264. if strings.Contains(strOut, `>улучшение точности<`) {
  265. isFind = true
  266. break
  267. }
  268. }
  269. if !isFind {
  270. return
  271. }
  272. ind += 8
  273. strOut = lstPoligon[ind]
  274. if strOut == "" {
  275. return
  276. }
  277. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  278. strOut = lstLink[1]
  279. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  280. strLink := "http://wartank.ru/" + lstLink[0]
  281. if _, err := sf.net.Get(strLink); err != nil {
  282. // log._rintf("ERRO NetPolygon.addForce(): in make request force fyne, err=\n\t%v\n", err)
  283. return
  284. }
  285. { // Узнать на сколько форсирована точность
  286. strForce := lstPoligon[ind-7]
  287. lstForce := strings.Split(strForce, `<span class="green2">+`)
  288. strForce = lstForce[1]
  289. lstForce = strings.Split(strForce, ` на `)
  290. strForce = lstForce[0]
  291. iForce, err := strconv.Atoi(strForce)
  292. if err != nil {
  293. // log._rintf("ERRO NetPolygon.addForce(): strForceFyne(%v) not int, err=\n\t%v\n", strForce, err)
  294. return
  295. }
  296. sf.tankStat.Force().SetVal(iForce)
  297. sf.tankStat.Force().SetName("fyne")
  298. sf.ModeCurrent().Set("точность")
  299. }
  300. case "hard": // Усиливаем мощность
  301. isFind = false
  302. for ind, strOut = range lstPoligon {
  303. if strings.Contains(strOut, `>увеличение прочности<`) {
  304. isFind = true
  305. break
  306. }
  307. }
  308. if !isFind {
  309. return
  310. }
  311. ind += 8
  312. strOut = lstPoligon[ind]
  313. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  314. strOut = lstLink[1]
  315. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  316. strLink := "http://wartank.ru/" + lstLink[0]
  317. if _, err := sf.net.Get(strLink); err != nil {
  318. // log._rintf("NetPolygon.addForce(): in make request force hard, err=\n\t%v\n", err)
  319. return
  320. }
  321. { // Узнать на сколько форсирована прочность
  322. strForce := lstPoligon[ind-7]
  323. lstForce := strings.Split(strForce, `<span class="green2">+`)
  324. strForce = lstForce[1]
  325. lstForce = strings.Split(strForce, ` на `)
  326. strForce = lstForce[0]
  327. iForce, err := strconv.Atoi(strForce)
  328. if err != nil {
  329. // log._rintf("ERRO NetPolygon.addForce(): strForceHard(%v) not int, err=\n\t%v\n", strForce, err)
  330. return
  331. }
  332. sf.tankStat.Force().SetVal(iForce)
  333. sf.tankStat.Force().SetName("hard")
  334. sf.ModeCurrent().Set("прочность")
  335. }
  336. default: // Неизвестно что
  337. sf.ModeCurrent().Set("неизвестно")
  338. // log._rintf("ERRO NetPolygon.addForce(): неизвестно что это, strParam=%q", strParam)
  339. return
  340. }
  341. }