polygon.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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.ИБот
  17. tankStat types.ИТанкСтат
  18. net *polygonnet.PolygonNet
  19. }
  20. // NewPolygon -- возвращает новый *Polygon
  21. func NewPolygon(base types.ИБаза) (*Polygon, error) {
  22. section, err := section.NewSection(base.Бот(), "Полигон", `<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.Бот(),
  29. tankStat: base.Бот().Танк().ТанкСтат(),
  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.Кнт().Done():
  48. sf.ВремяОпрос().Стоп()
  49. return
  50. case <-sf.ВремяОпрос().КаналСиг():
  51. mode := sf.РежимТекущ().Получ()
  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.СписПолучить()
  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.СписПолучить()
  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. форсажИмя := ""
  116. switch { // Вычисляем контрольную строку
  117. case strings.Contains(strOut, `>улучшение точности<`):
  118. форсажИмя = "fyne"
  119. case strings.Contains(strOut, `>увеличение прочности<`):
  120. форсажИмя = "hard"
  121. case strings.Contains(strOut, `>усиление брони<`):
  122. форсажИмя = "armor"
  123. case strings.Contains(strOut, `>усиление атаки<`):
  124. форсажИмя = "attack"
  125. }
  126. // Вычислим на сколько
  127. strOut = lstPolygon[ind+1]
  128. lstOut := strings.Split(strOut, `<span class="green2">+`)
  129. strOut = lstOut[1]
  130. lstOut = strings.Split(strOut, ` на `)
  131. strOut = lstOut[0]
  132. iForce, err := strconv.Atoi(strOut)
  133. if err != nil {
  134. // log._rintf("NetPolygon.checkTime(): force(%v) not number, err=\n\t%v\n", strOut, err)
  135. return
  136. }
  137. sf.tankStat.ФорсажОбнов(форсажИмя, iForce)
  138. }
  139. // Выбирает самый слабый параметр и усиливает его
  140. func (sf *Polygon) addForce() {
  141. if err := sf.net.UpdateLst(); err != nil {
  142. // log._rintf("Polygon.checkPolygon(): при принудительном обновлении lstPlygon, mode=%s\terr=\n\t%v\n", sf.ModeCurrent().Get(), err)
  143. sf.SetCountDown(5)
  144. return
  145. }
  146. lstPoligon := sf.СписПолучить()
  147. if len(lstPoligon) == 0 {
  148. return
  149. }
  150. stat := sf.tankStat
  151. iAttack := stat.Атака().Получ()
  152. iArmor := stat.Броня().Получ()
  153. iFyne := stat.Точность().Получ()
  154. iHard := stat.Прочность().Получ()
  155. strParam := "attack"
  156. iParam := iHard
  157. {
  158. /*
  159. Вычислить самый слабый параметр.
  160. Политика вычислений:
  161. 1) hard -- прочность, самый низкоприоритетный параметр
  162. 2) armor -- броня, чуть лучше power
  163. 3) fyne -- точность, чуть лучше armor
  164. 4) attack -- атака, самый важный
  165. */
  166. if iArmor <= iParam {
  167. iParam = iArmor
  168. strParam = "armor"
  169. }
  170. if iFyne <= iParam {
  171. iParam = iFyne
  172. strParam = "fyne"
  173. }
  174. if iAttack < iParam {
  175. strParam = "attack"
  176. }
  177. }
  178. // Найти нужную строку активации
  179. var (
  180. ind int
  181. strOut string
  182. isFind bool
  183. )
  184. switch strParam {
  185. case "attack": // Усиливаем атаку
  186. for ind, strOut = range lstPoligon {
  187. if strings.Contains(strOut, `>усиление атаки<`) {
  188. isFind = true
  189. break
  190. }
  191. }
  192. if !isFind {
  193. return
  194. }
  195. ind += 8
  196. strOut = lstPoligon[ind]
  197. if strOut == "" {
  198. return
  199. }
  200. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  201. strOut = lstLink[1]
  202. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  203. strLink := "https://wartank.ru/" + lstLink[0]
  204. if _, err := sf.net.Get(strLink); err != nil {
  205. // log._rintf("ERRO NetPolygon.addForce(): in make request force attack, err=\n\t%v\n", err)
  206. return
  207. }
  208. { // Узнать на сколько форсирована атака
  209. strForce := lstPoligon[ind-7]
  210. lstForce := strings.Split(strForce, `<span class="green2">+`)
  211. strForce = lstForce[1]
  212. lstForce = strings.Split(strForce, ` на `)
  213. strForce = lstForce[0]
  214. iForce, err := strconv.Atoi(strForce)
  215. if err != nil {
  216. // log._rintf("ERRO NetPolygon.addForce(): strForceAttack(%v) not int, err=\n\t%v\n", strForce, err)
  217. return
  218. }
  219. sf.tankStat.ФорсажОбнов("attack", iForce)
  220. sf.РежимТекущ().Уст("атака")
  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 := "https://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.ФорсажОбнов("armor", iForce)
  258. sf.РежимТекущ().Уст("броня")
  259. }
  260. case "fyne": // Усиливаем точность
  261. isFind = false
  262. for ind, strOut = range lstPoligon {
  263. if strings.Contains(strOut, `>улучшение точности<`) {
  264. isFind = true
  265. break
  266. }
  267. }
  268. if !isFind {
  269. return
  270. }
  271. ind += 8
  272. strOut = lstPoligon[ind]
  273. if strOut == "" {
  274. return
  275. }
  276. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  277. strOut = lstLink[1]
  278. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  279. strLink := "https://wartank.ru/" + lstLink[0]
  280. if _, err := sf.net.Get(strLink); err != nil {
  281. // log._rintf("ERRO NetPolygon.addForce(): in make request force fyne, err=\n\t%v\n", err)
  282. return
  283. }
  284. { // Узнать на сколько форсирована точность
  285. strForce := lstPoligon[ind-7]
  286. lstForce := strings.Split(strForce, `<span class="green2">+`)
  287. strForce = lstForce[1]
  288. lstForce = strings.Split(strForce, ` на `)
  289. strForce = lstForce[0]
  290. iForce, err := strconv.Atoi(strForce)
  291. if err != nil {
  292. // log._rintf("ERRO NetPolygon.addForce(): strForceFyne(%v) not int, err=\n\t%v\n", strForce, err)
  293. return
  294. }
  295. sf.tankStat.ФорсажОбнов("fyne", iForce)
  296. sf.РежимТекущ().Уст("точность")
  297. }
  298. case "hard": // Усиливаем мощность
  299. isFind = false
  300. for ind, strOut = range lstPoligon {
  301. if strings.Contains(strOut, `>увеличение прочности<`) {
  302. isFind = true
  303. break
  304. }
  305. }
  306. if !isFind {
  307. return
  308. }
  309. ind += 8
  310. strOut = lstPoligon[ind]
  311. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  312. strOut = lstLink[1]
  313. lstLink = strings.Split(strOut, `"><span><span>Получить бесплатно</span></span></a>`)
  314. strLink := "https://wartank.ru/" + lstLink[0]
  315. if _, err := sf.net.Get(strLink); err != nil {
  316. // log._rintf("NetPolygon.addForce(): in make request force hard, err=\n\t%v\n", err)
  317. return
  318. }
  319. { // Узнать на сколько форсирована прочность
  320. strForce := lstPoligon[ind-7]
  321. lstForce := strings.Split(strForce, `<span class="green2">+`)
  322. strForce = lstForce[1]
  323. lstForce = strings.Split(strForce, ` на `)
  324. strForce = lstForce[0]
  325. iForce, err := strconv.Atoi(strForce)
  326. if err != nil {
  327. // log._rintf("ERRO NetPolygon.addForce(): strForceHard(%v) not int, err=\n\t%v\n", strForce, err)
  328. return
  329. }
  330. sf.tankStat.ФорсажОбнов("hard", iForce)
  331. sf.РежимТекущ().Уст("прочность")
  332. }
  333. default: // Неизвестно что
  334. sf.РежимТекущ().Уст("неизвестно")
  335. // log._rintf("ERRO NetPolygon.addForce(): неизвестно что это, strParam=%q", strParam)
  336. return
  337. }
  338. }