angar_attack.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. // package angar_attack -- объект боя на топливе
  2. package angar_attack
  3. import (
  4. "fmt"
  5. "log"
  6. "os"
  7. "strings"
  8. "time"
  9. "wartank/pkg/components/sectionnet"
  10. "wartank/pkg/cons"
  11. "wartank/pkg/types"
  12. )
  13. // ТопливоБой -- объект боя на топливе
  14. type ТопливоБой struct {
  15. *sectionnet.SectionNet
  16. ангар types.ИАнгар
  17. }
  18. // НовТопливоБой -- возвращает новый *ТопливоБойNet
  19. func НовТопливоБой(angar types.ИАнгар) (*ТопливоБой, error) {
  20. sectionNet, err := sectionnet.NewSectionNet(angar, "https://wartank.ru/battle")
  21. if err != nil {
  22. return nil, fmt.Errorf("NewТопливоБой(): in create SectionNet, err=\n\t%w", err)
  23. }
  24. sf := &ТопливоБой{
  25. SectionNet: sectionNet,
  26. ангар: angar,
  27. }
  28. return sf, nil
  29. }
  30. func (sf *ТопливоБой) Пуск() error {
  31. go sf.пуск()
  32. return nil
  33. }
  34. func (sf *ТопливоБой) пуск() {
  35. for {
  36. time.Sleep(time.Second * 30) // Минимальный интервал ожттдания прибавки топлива
  37. топливо := sf.ангар.Топливо().Получ()
  38. if топливо < cons.ТопливоМин { // Минимальная ёмкость бака -- 315
  39. continue
  40. }
  41. log.Printf("Fuel.Run: val=%v\n", топливо)
  42. списСтрБой, err := sf.начатьБой()
  43. if err != nil {
  44. // log._rintf("ERRO ТопливоБой.findFuel(): in get page battle, err=\n\t%v\n", err)
  45. continue
  46. }
  47. списВыстрел1, err := sf.выбратьБойСлабый(списСтрБой)
  48. if err != nil {
  49. // log._rintf("ERRO ТопливоБой.findFuel(): in get page shooting, err=\n\t%v\n", err)
  50. continue
  51. }
  52. if err := sf.сделатьВыстрелы(списВыстрел1); err != nil {
  53. log.Printf("ERRO ТопливоБой.findFuel(): in make shooting, err=\n\t%v\n", err)
  54. }
  55. }
  56. }
  57. // Идёт в атаку, если топлива больше cons.ТопливоМин
  58. func (sf *ТопливоБой) начатьБой() (спискСтрБой []string, err error) {
  59. // Получить ссылку на атаку
  60. // _mt.Println("\t ТопливоБой.начатьБой()")
  61. lstAngar := sf.ангар.СписПолучить()
  62. var стрАнализ string
  63. for _, стрАтак := range lstAngar {
  64. if strings.Contains(стрАтак, `<span>В бой!</span>`) {
  65. стрАнализ = стрАтак
  66. break
  67. }
  68. }
  69. // Вырезать ссылку на атаку
  70. lstAngar = strings.Split(стрАнализ, `<a class="simple-but border mb1" href="`)
  71. if len(lstAngar) == 0 { // Не та страница
  72. return nil, fmt.Errorf("ТопливоБой.начатьБой(): список строк для атаки пустой")
  73. }
  74. бойСсылка := lstAngar[1]
  75. lstAngar = strings.Split(бойСсылка, `"><span><span>В бой!</span></span></a>`)
  76. бойСсылка = "https://wartank.ru/" + lstAngar[0]
  77. спискСтрБой, err = sf.Get(бойСсылка)
  78. if err != nil {
  79. return nil, fmt.Errorf("ТопливоБой.начатьБой(): in make GET-request to battle, err=\n\t%w", err)
  80. }
  81. return спискСтрБой, nil
  82. }
  83. // Выбирает первого более слабого противника и делает первый выстрел
  84. func (sf *ТопливоБой) выбратьБойСлабый(списСтрБой []string) (списСтрВыстрел1 []string, err error) {
  85. // _mt.Println("\tAngarNet.makeSelectBattle()")
  86. var стрАнализ string
  87. defer func() {
  88. if паника := recover(); паника != nil {
  89. msg := time.Now().Local().Format("2006-01-02 15:04:05.000 ") + "fnShoot1\n"
  90. msg += "\tNetClient.makeSelectBattle().fnShoot1()\n"
  91. msg0 := fmt.Sprintf("%v\n", паника)
  92. msg1 := ""
  93. for _, _msg := range strings.Split(msg0, "\n") {
  94. if _msg == "" {
  95. continue
  96. }
  97. msg1 += "\t" + _msg + "\n"
  98. }
  99. msg += msg1
  100. // _mt.Println(msg)
  101. err = fmt.Errorf("%v", msg)
  102. msg1 = "" // Сброс накопленной ошибки
  103. for _, _msg := range списСтрБой {
  104. if _msg == "" {
  105. continue
  106. }
  107. msg1 += "\t" + _msg + "\n"
  108. }
  109. msg += msg1
  110. // Выкинуть ошибку в файл
  111. _ = os.MkdirAll("./errors", 0700)
  112. err = os.WriteFile("./errors/attack_shoot1.html", []byte(msg), 0600)
  113. }
  114. }()
  115. // Выдернуть строку с первой ссылкой на противника
  116. for _, стрБой_ := range списСтрБой {
  117. if strings.Contains(стрБой_, `opponents-opponents-0`) {
  118. стрАнализ = стрБой_
  119. break
  120. }
  121. }
  122. var ссылкаБой string
  123. switch стрАнализ == "" {
  124. case true: // Такая ситуация возможна, если уже были какие-то выстрелы
  125. return списСтрБой, nil
  126. default: // Успешный выстрел
  127. // Вырезать ссылку из строки
  128. списСтрБой = strings.Split(стрАнализ, `<td class="cntr"><a href="`)
  129. ссылкаБой = списСтрБой[1]
  130. списСтрБой = strings.Split(ссылкаБой, `"><img class="tank-img" alt="tank" src="/tankimg?`)
  131. ссылкаБой = "https://wartank.ru/" + списСтрБой[0]
  132. }
  133. списСтрВыстрел1, err = sf.Get(ссылкаБой)
  134. if err != nil {
  135. return nil, fmt.Errorf("ТопливоБой.makeSelectBattle(): in GET-response select battle tank, err=\n\t%w", err)
  136. }
  137. return списСтрВыстрел1, nil
  138. }
  139. // Ведёт бой в 2 выстрела (здесь только 2 и 3 выстрел -- первый сделан при слабом противнике)
  140. func (сам *ТопливоБой) сделатьВыстрелы(lstShoot2 []string) error {
  141. // _mt.Println("\tAngarNet.makeShooting()")
  142. var списВыстрел3 []string // Тело страницы для третьего выстрела
  143. фнВыстрел2 := func() (err error) { // Второй выстрел
  144. // _mt.Println("\tAngarNet.makeShooting().fnShoot2()")
  145. defer func() {
  146. if _panic := recover(); _panic != nil {
  147. msg := time.Now().Local().Format("2006-01-02 15:04:05.000 ") + "fnShoot2\n"
  148. msg += "\tNetClient.makeShooting().fnShoot2()\n"
  149. msg0 := fmt.Sprintf("%v\n", _panic)
  150. msg1 := ""
  151. for _, _msg := range strings.Split(msg0, "\n") {
  152. if _msg == "" {
  153. continue
  154. }
  155. msg1 += "\t" + _msg + "\n"
  156. }
  157. msg += msg1
  158. // _mt.Println(msg)
  159. err = fmt.Errorf("%v", msg)
  160. msg1 = "" // Сброс накопленной ошибки
  161. for _, _msg := range lstShoot2 {
  162. if _msg == "" {
  163. continue
  164. }
  165. msg1 += "\t" + _msg + "\n"
  166. }
  167. msg += msg1
  168. // Выкинуть ошибку в файл
  169. _ = os.MkdirAll("./errors", 0700)
  170. err = os.WriteFile("./errors/attack_shoot2.html", []byte(msg), 0600)
  171. }
  172. }()
  173. // Получить ссылку на второй выстрел
  174. var strOut string
  175. for _, strShoot := range lstShoot2 {
  176. if strings.Contains(strShoot, `<span>Добить</span>`) {
  177. strOut = strShoot
  178. break
  179. }
  180. }
  181. var linkShoot2 string
  182. switch strOut == "" {
  183. case true: // Первый выстрел был неудачным
  184. for _, strShoot := range lstShoot2 {
  185. if strings.Contains(strShoot, `<span>Взять реванш</span>`) {
  186. strOut = strShoot
  187. break
  188. }
  189. }
  190. if strOut == "" { // Это ситуация для третьего выстрела
  191. списВыстрел3 = lstShoot2
  192. return nil
  193. }
  194. // Вырезать ссылку из строки
  195. lstShoot2 = strings.Split(strOut, `<a class="simple-but border" href="`)
  196. linkShoot2 = lstShoot2[1]
  197. lstShoot2 = strings.Split(linkShoot2, `"><span><span>Взять реванш</span></span></a>`)
  198. linkShoot2 = "https://wartank.ru/" + lstShoot2[0]
  199. default: // Первый выстрел был удачным
  200. // Вырезать ссылку из строки
  201. lstShoot2 = strings.Split(strOut, `<a class="simple-but border" href="`)
  202. linkShoot2 = lstShoot2[1]
  203. lstShoot2 = strings.Split(linkShoot2, `"><span><span>Добить</span></span></a>`)
  204. linkShoot2 = "https://wartank.ru/" + lstShoot2[0]
  205. }
  206. списВыстрел3, err = сам.Get(linkShoot2)
  207. if err != nil {
  208. return fmt.Errorf("ТопливоБой.makeShooting(): in Get-response shoot2, err=\n\t%w", err)
  209. }
  210. fuel := сам.ангар.Топливо().Получ()
  211. fuel -= 30
  212. сам.ангар.Топливо().Уст(fuel)
  213. return nil
  214. }
  215. if err := фнВыстрел2(); err != nil {
  216. return err
  217. }
  218. фнВыстрел3 := func() (err error) { // Третий выстрел
  219. // _mt.Println("\tAngarNet.makeShooting().fnShoot3()")
  220. defer func() {
  221. if _panic := recover(); _panic != nil {
  222. msg := time.Now().Local().Format("2006-01-02 15:04:05.000 fnShoot3\n")
  223. msg += "\tNetClient.makeShooting().fnShoot3()\n"
  224. msg0 := fmt.Sprintf("%v\n", _panic)
  225. msg1 := ""
  226. for _, _msg := range strings.Split(msg0, "\n") {
  227. if _msg == "" {
  228. continue
  229. }
  230. msg1 += "\t" + _msg + "\n"
  231. }
  232. msg += msg1
  233. // _mt.Println(msg)
  234. err = fmt.Errorf("%v", msg)
  235. msg1 = "" // Сброс накопленной ошибки
  236. for _, _msg := range списВыстрел3 {
  237. if _msg == "" {
  238. continue
  239. }
  240. msg1 += "\t" + _msg + "\n"
  241. }
  242. msg += msg1
  243. // Выкинуть ошибку в файл
  244. _ = os.MkdirAll("./errors", 0700)
  245. err = os.WriteFile("./errors/attack_shoot3.html", []byte(msg), 0600)
  246. }
  247. }()
  248. // Получить ссылку на третий выстрел
  249. var strOut string
  250. for _, strShoot3 := range списВыстрел3 {
  251. if strings.Contains(strShoot3, `<span>Уничтожить</span>`) {
  252. strOut = strShoot3
  253. break
  254. }
  255. }
  256. linkShoot3 := ""
  257. switch strOut == "" {
  258. case true: // Если не найдена ссылка -- значит было поражение в выстреле
  259. if strOut == "" {
  260. for _, strShoot3 := range списВыстрел3 {
  261. if strings.Contains(strShoot3, `<span>Взять реванш</span>`) {
  262. strOut = strShoot3
  263. break
  264. }
  265. }
  266. }
  267. // Вырезать ссылку из строки
  268. списВыстрел3 = strings.Split(strOut, `<a class="simple-but border" href="`)
  269. linkShoot3 = списВыстрел3[1]
  270. списВыстрел3 = strings.Split(linkShoot3, `"><span><span>Взять реванш</span></span></a>`)
  271. linkShoot3 = "https://wartank.ru/" + списВыстрел3[0]
  272. default: // Успешный выстрел
  273. // Вырезать ссылку из строки
  274. списВыстрел3 = strings.Split(strOut, `<a class="simple-but border" href="`)
  275. linkShoot3 = списВыстрел3[1]
  276. списВыстрел3 = strings.Split(linkShoot3, `"><span><span>Уничтожить</span></span></a>`)
  277. linkShoot3 = "https://wartank.ru/" + списВыстрел3[0]
  278. }
  279. if _, err = сам.Get(linkShoot3); err != nil {
  280. return fmt.Errorf("ТопливоБой.makeShooting(): in Get-response shoot3, err=\n\t%w", err)
  281. }
  282. fuel := сам.ангар.Топливо().Получ()
  283. fuel -= 30
  284. сам.ангар.Топливо().Уст(fuel)
  285. return nil
  286. }
  287. if err := фнВыстрел3(); err != nil {
  288. return err
  289. }
  290. сам.ангар.РесурсыОбновить()
  291. return nil
  292. }