fuel_attack.go 12 KB

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