polygon.go 10 KB

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