polygon.go 10 KB

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