fuel_attack.go 11 KB

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