polygon.go 10 KB

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