fuel_attack.go 11 KB

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