fuel_attack.go 11 KB

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