angar_attack.go 9.9 KB

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