mine.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. // package mine -- объект шахты на базе
  2. package mine
  3. import (
  4. "context"
  5. "fmt"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "wartank/pkg/alias"
  10. "wartank/pkg/arena"
  11. "wartank/pkg/components/arena_net"
  12. "wartank/pkg/types"
  13. "wartank/server/serv_bots/warbot/tank_stat/static_param"
  14. )
  15. // Шахта -- объект шахты на базе
  16. type Шахта struct {
  17. types.ИАрена
  18. сеть types.ИАренаСеть
  19. лог types.ИВебЛог
  20. бот types.ИБот
  21. база types.ИБаза
  22. руда types.ИСтатПарам
  23. железо types.ИСтатПарам
  24. сталь types.ИСтатПарам
  25. свинец types.ИСтатПарам
  26. уровень types.ИСтатПарам
  27. продуктИмя string // Что сейчас делается
  28. продуктКол types.ИСтатПарам // Сколько делается прямо сейчас
  29. продуктВремя string // Сколько осталось времени прямо сейчас
  30. кнт context.Context // контекст шахты
  31. фнОтмена func() // Функция отмены шахты
  32. }
  33. // НовШахта -- возвращает новый *Mine
  34. func НовШахта(база types.ИБаза) (types.ИБазаШахта, error) {
  35. кнт, фнОтмена := context.WithCancel(база.Контекст())
  36. сам := &Шахта{
  37. бот: база.Бот(),
  38. база: база,
  39. руда: static_param.НовСтатПарам("руда"),
  40. железо: static_param.НовСтатПарам("железо"),
  41. сталь: static_param.НовСтатПарам("сталь"),
  42. свинец: static_param.НовСтатПарам("свинец"),
  43. продуктКол: static_param.НовСтатПарам("свинец"),
  44. уровень: static_param.НовСтатПарам("уровень"),
  45. кнт: кнт,
  46. фнОтмена: фнОтмена,
  47. }
  48. аренаКонфиг := arena.АренаКонфиг{
  49. Бот_: сам.бот,
  50. АренаИмя_: "Шахта",
  51. СтрКонтроль_: `<span class="green2">Руда</span><br/>`,
  52. ФнПуск_: сам.пуск,
  53. }
  54. сам.ИАрена = arena.НовАрена(аренаКонфиг)
  55. сам.лог = сам.ВебЛог()
  56. сам.сеть = arena_net.НовАренаСеть(сам, "https://wartank.ru/production/Mine")
  57. go сам.пуск()
  58. сам.лог.ОтклВывод()
  59. сам.лог.Добавить("Шахта.НовШахта(): бот=%q\n", сам.бот.Имя())
  60. return сам, nil
  61. }
  62. // пуск -- запускает обработку шахты
  63. func (сам *Шахта) пуск() {
  64. фнРабота := func() {
  65. defer func() {
  66. for сам.ВремяОстат().ПолучМилСек() > 0 {
  67. time.Sleep(time.Second * 5)
  68. }
  69. }()
  70. сам.лог.Добавить("Шахта.пуск().фнРабота(): бот=%q\n", сам.бот.Имя())
  71. { // Построить
  72. счёт := 5
  73. for счёт > 0 {
  74. еcлиНет := сам.построить()
  75. if еcлиНет {
  76. break
  77. }
  78. счёт--
  79. }
  80. }
  81. { // Забрать из шахты
  82. счёт := 5
  83. for счёт > 0 { // Забрать из шахты
  84. if сам.шахтаЗабрать() {
  85. break
  86. }
  87. счёт--
  88. }
  89. }
  90. сам.уровеньОбновить()
  91. сам.ускорениеПровер()
  92. { // Проапгрейдить
  93. счёт := 5
  94. for счёт > 0 {
  95. if сам.проапгрейдить() {
  96. break
  97. }
  98. счёт--
  99. }
  100. }
  101. { // Получить продукцию
  102. счёт := 5
  103. for счёт > 0 {
  104. счёт--
  105. еслиПолуч, ош := сам.количествоПолучить()
  106. if ош != nil {
  107. continue
  108. }
  109. if еслиПолуч {
  110. break
  111. }
  112. }
  113. }
  114. сам.Сделать()
  115. }
  116. for {
  117. select {
  118. case <-сам.кнт.Done():
  119. return
  120. case <-сам.ВремяОстат().КаналСиг():
  121. фнРабота()
  122. default:
  123. фнРабота()
  124. }
  125. }
  126. }
  127. // Проверяет количество продукта в шахте
  128. func (сам *Шахта) количествоПолучить() (bool, error) {
  129. сам.лог.Добавить("Шахта.количествоПолучить()\n")
  130. var (
  131. ind int
  132. strOut string
  133. еслиНайдено bool
  134. режим string
  135. )
  136. lstMine, err := сам.сеть.ВебВоркер().Получ("https://wartank.ru/buildings")
  137. if err != nil {
  138. сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): при обновлении строк шахты, ош=\n\t%v\n", err)
  139. return false, fmt.Errorf("")
  140. }
  141. /*
  142. Режим (руда-1):
  143. <td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/ore.png?2" alt="ore"/>&nbsp;1</div></td>
  144. Время (+8 строк):
  145. <td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/ore.png?2" alt="ore"/>&nbsp;1</div></td>
  146. */
  147. for ind, strOut = range lstMine {
  148. // Руда текущее
  149. if strings.Contains(strOut, `src="/images/icons/ore.png?2" alt="ore"`) {
  150. // <td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/ore.png?2" alt="ore"/>&nbsp;1</div></td>
  151. еслиНайдено = true
  152. режим = "руда"
  153. break
  154. }
  155. // Железо текущее
  156. if strings.Contains(strOut, `src="/images/icons/iron.png?2" alt="iron"`) {
  157. // <td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/iron.png?2" alt="iron"/>&nbsp;2</div></td>
  158. еслиНайдено = true
  159. режим = "железо"
  160. break
  161. }
  162. // Сталь текущее
  163. if strings.Contains(strOut, `src="/images/icons/steel.png?2" alt="steel"`) {
  164. // <td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/steel.png?2" alt="iron"/>&nbsp;2</div></td>
  165. еслиНайдено = true
  166. режим = "сталь"
  167. break
  168. }
  169. // Свинец текущее
  170. if strings.Contains(strOut, `src="/images/icons/plumbum.png?2" alt="plumbum"`) {
  171. // <td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/plumbum.png?2" alt="iron"/>&nbsp;2</div></td>
  172. еслиНайдено = true
  173. режим = "свинец"
  174. break
  175. }
  176. }
  177. if !еслиНайдено {
  178. сам.лог.Добавить("Шахта.количествоПолучить(): не надо\n")
  179. return true, nil
  180. }
  181. switch режим {
  182. case "руда":
  183. _число := strings.TrimPrefix(strOut, `<td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/ore.png?2" alt="ore"/>&nbsp;`)
  184. _число = strings.TrimSuffix(_число, `</div></td>`)
  185. iNum, err := strconv.Atoi(_число)
  186. if err != nil {
  187. сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во руды (%v) не число, err=\n\t%v\n", _число, err)
  188. return false, fmt.Errorf("")
  189. }
  190. сам.продуктКол.Уст(iNum)
  191. сам.продуктИмя = "руда"
  192. сам.лог.Добавить("Шахта.количествоПолучить(): кол-во руды = %v\n", iNum)
  193. case "железо":
  194. _число := strings.TrimPrefix(strOut, `<td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/iron.png?2" alt="iron"/>&nbsp;`)
  195. _число = strings.TrimSuffix(_число, `</div></td>`)
  196. iNum, err := strconv.Atoi(_число)
  197. if err != nil {
  198. сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во железа (%v) не число, err=\n\t%v\n", _число, err)
  199. return false, fmt.Errorf("")
  200. }
  201. сам.продуктКол.Уст(iNum)
  202. сам.продуктИмя = "железо"
  203. сам.лог.Добавить("Шахта.количествоПолучить(): кол-во железа = %v\n", iNum)
  204. case "сталь":
  205. _число := strings.TrimPrefix(strOut, `<td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/steel.png?2" alt="steel"/>&nbsp;`)
  206. _число = strings.TrimSuffix(_число, `</div></td>`)
  207. iNum, err := strconv.Atoi(_число)
  208. if err != nil {
  209. сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во стали (%v) не число, err=\n\t%v\n", _число, err)
  210. return false, fmt.Errorf("")
  211. }
  212. сам.продуктКол.Уст(iNum)
  213. сам.продуктИмя = "сталь"
  214. сам.лог.Добавить("Шахта.количествоПолучить(): кол-во стали = %v\n", iNum)
  215. case "свинец":
  216. _число := strings.TrimPrefix(strOut, `<td class="vam"><div class="nwr pr5 gray1"><img class="rico vm" src="/images/icons/plumbum.png?2" alt="plumbum"/>&nbsp;`)
  217. _число = strings.TrimSuffix(_число, `</div></td>`)
  218. iNum, err := strconv.Atoi(_число)
  219. if err != nil {
  220. сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): кол-во свинца (%v) не число, err=\n\t%v\n", _число, err)
  221. return false, fmt.Errorf("")
  222. }
  223. сам.продуктКол.Уст(iNum)
  224. сам.продуктИмя = "свинец"
  225. сам.лог.Добавить("Шахта.количествоПолучить(): кол-во свинца = %v\n", iNum)
  226. default:
  227. сам.лог.Добавить("Шахта.количествоПолучить(): неизвестный режим (%v)\n", режим)
  228. return false, fmt.Errorf("")
  229. }
  230. // <td><div class="value-block lh1"><span><span>00:00:34</span></span></div></td>
  231. strTime := lstMine[ind+3]
  232. // <td><div class="value-block lh1"><span><span>00:19:53</span></span></div></td>
  233. strTime = strings.TrimPrefix(strTime, `<td><div class="value-block lh1"><span><span>`)
  234. strTime = strings.TrimSuffix(strTime, `</span></span></div></td>`)
  235. сам.продуктВремя = strTime
  236. if err := сам.ОбратВремяУст(alias.Время(strTime)); err != nil {
  237. сам.лог.Добавить("ОШИБКА Шахта.количествоПолучить(): при установке времени производства(%v), err=\n\t%v\n", strTime, err)
  238. }
  239. сам.лог.Добавить("Шахта.количествоПолучить(): время=%q\n", strTime)
  240. return true, nil
  241. }
  242. // Проверяет на забор из шахты
  243. func (сам *Шахта) шахтаЗабрать() bool {
  244. сам.лог.Добавить("Шахта.шахтаЗабрать()\n")
  245. var (
  246. strOut string
  247. еслиНайдено bool
  248. )
  249. списШахта, ош := сам.сеть.ВебВоркер().Получ("https://wartank.ru/buildings")
  250. if ош != nil {
  251. сам.лог.Добавить("ОШИБКА Шахта.шахтаЗабрать(): при GET-запросе, ош=\n\t%v\n", ош)
  252. return false
  253. }
  254. // <a class="simple-but border" href="buildings?35-1.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink"><span><span>Забрать</span></span></a>
  255. for _, strOut = range списШахта {
  256. if strings.Contains(strOut, `.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink`) {
  257. еслиНайдено = true
  258. break
  259. }
  260. }
  261. if !еслиНайдено {
  262. сам.лог.Добавить("Шахта.шахтаЗабрать(): не надо\n")
  263. return true
  264. }
  265. _ссылка := strings.TrimPrefix(strOut, `<a class="simple-but border" href="`)
  266. _ссылка = strings.TrimSuffix(_ссылка, `"><span><span>Забрать</span></span></a>`)
  267. ссылка := "https://wartank.ru/" + _ссылка
  268. // http://wartank.ru/buildings?5-1.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink
  269. lstBase1, err := сам.сеть.ВебВоркер().Получ(ссылка)
  270. if err != nil {
  271. сам.лог.Добавить("ОШИБКА Шахта.шахтаЗабрать(): при выполнении GET-запроса 'забрать', err=\n\t%v\n", err)
  272. return false
  273. }
  274. if err = сам.СтрОбновить(lstBase1); err != nil {
  275. сам.лог.Добавить("Шахта.шахтаЗабрать(): при обновлении lstMine, err=\n\t%v\n", err)
  276. return false
  277. }
  278. сам.лог.Добавить("Шахта.шахтаЗабрать(): ОК\n")
  279. return true
  280. }
  281. // Проверяет ускорение строительства FIXME: не работает
  282. func (сам *Шахта) ускорениеПровер() {
  283. сам.лог.Добавить("")
  284. списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
  285. if ош != nil {
  286. сам.лог.Добавить("ОШИБКА Шахта.ускорениеПровер(): при получении списка строк, err=\n\t%v\n", ош)
  287. return
  288. }
  289. // <span class="green2">Шахта - 0</span><br/>
  290. var (
  291. еслиНайти bool
  292. стр string
  293. )
  294. for _, стр = range списСтр {
  295. if strings.Contains(стр, `<span class="green2">Шахта - `) {
  296. еслиНайти = true
  297. break
  298. }
  299. }
  300. if !еслиНайти {
  301. сам.лог.Добавить("Шахта.ускорениеПровер(): не надо\n")
  302. return
  303. }
  304. сам.лог.Добавить("Шахта.ускорениеПровер(): надо\n")
  305. }
  306. // Уровень -- возвращает уровень шахты
  307. func (сам *Шахта) Уровень() types.ИСтатПарам {
  308. return сам.уровень
  309. }
  310. // Обновляет текущий уровень шахты (может быть не построена)
  311. func (сам *Шахта) уровеньОбновить() bool {
  312. сам.лог.Добавить("Шахта.уровеньОбновить()\n")
  313. списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
  314. if ош != nil {
  315. сам.лог.Добавить("ОШИБКА Шахта.уровеньОбновить(): in make request, err=\n\t%v\n", ош)
  316. return false
  317. }
  318. // <span class="green2">Шахта - 0</span><br/>
  319. var (
  320. еслиНайти = false
  321. стр = ""
  322. )
  323. for _, стр = range списСтр {
  324. if strings.Contains(стр, `<span class="green2">Шахта - `) {
  325. еслиНайти = true
  326. break
  327. }
  328. }
  329. if !еслиНайти {
  330. сам.лог.Добавить("Шахта.уровеньОбновить(): нет уровня\n")
  331. return false
  332. }
  333. _стр := strings.TrimPrefix(стр, `<span class="green2">Шахта - `)
  334. _стр = strings.TrimSuffix(_стр, `</span><br/>`)
  335. иУровень, ош := strconv.Atoi(_стр)
  336. if ош != nil {
  337. сам.лог.Добавить("ОШИБКА Шахта.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
  338. return false
  339. }
  340. сам.уровень.Уст(иУровень)
  341. сам.лог.Добавить("Шахта.уровеньОбновить(): уровень=%v\n", иУровень)
  342. return true
  343. }
  344. // Строит шахту при нулевом уровне
  345. func (сам *Шахта) построить() bool {
  346. сам.лог.Добавить("Шахта.построить()\n")
  347. // <td style="width:50%;padding-left:1px;"><a class="simple-but border mb5" href="building-upgrade/Mine"><span><span>Построить</span></span></a></td>
  348. var (
  349. еслиНайти = false
  350. стр = ""
  351. )
  352. списСтр, ош := сам.сеть.ВебВоркер().Получ("http://wartank.ru/buildings")
  353. if ош != nil {
  354. сам.лог.Добавить("Шахта.уровеньОбновить(): при выполнении запроса, ош=\n\t%v\n", ош)
  355. return false
  356. }
  357. for _, стр = range списСтр {
  358. if strings.Contains(стр, `href="building-upgrade/Mine"><span><span>Построить</span></span>`) {
  359. еслиНайти = true
  360. break
  361. }
  362. }
  363. if !еслиНайти {
  364. сам.лог.Добавить("Шахта.построить(): не надо\n")
  365. return true
  366. }
  367. // Пробуем построить шахту
  368. _стр := strings.TrimPrefix(стр, `<td style="width:50%;padding-left:1px;"><a class="simple-but border mb5" href="`)
  369. _стр = strings.TrimSuffix(_стр, `"><span><span>Построить</span></span></a></td>`)
  370. ссылка := "https://wartank.ru/" + _стр
  371. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  372. if ош != nil {
  373. сам.лог.Добавить("ОШИБКА Шахта.построить(): при выполнении GET-команды 'построить шахту', err=\n\t%v\n", ош)
  374. return false
  375. }
  376. еслиНайти = false
  377. // "<a class=\"simple-but border mb5\" href=\"Mine?14-1.ILinkListener-upgradeLink-link\">"
  378. for _, стр = range списСтр {
  379. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  380. еслиНайти = true
  381. break
  382. }
  383. }
  384. if !еслиНайти {
  385. сам.лог.Добавить("Шахта.построить(): не найдена команда постройки\n")
  386. return true
  387. }
  388. _стр = strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
  389. _стр = strings.TrimSuffix(_стр, "\">")
  390. // http://wartank.ru/building-upgrade/Mine?16-1.ILinkListener-upgradeLink-link
  391. ссылка = "https://wartank.ru/building-upgrade/" + _стр
  392. _, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  393. if ош != nil {
  394. сам.лог.Добавить("ОШИБКА Шахта.построить(): при GET-команде 'купить постройку шахты', err=\n\t%v\n", ош)
  395. return false
  396. }
  397. return true
  398. }
  399. // Пытается проапгрейдить топливный склад
  400. func (сам *Шахта) проапгрейдить() bool {
  401. сам.лог.Добавить("Шахта.проапгрейдить()\n")
  402. var (
  403. еслиНайти = false
  404. списСтр []string
  405. стр = ""
  406. ош error
  407. )
  408. фнКупить := func() (bool, error) {
  409. defer time.Sleep(time.Millisecond * 1000)
  410. списСтр, ош = сам.сеть.ВебВоркер().Получ("https://wartank.ru/building-upgrade/Mine")
  411. if ош != nil {
  412. сам.лог.Добавить("ОШИБКА Шахта.проапгрейдить().фнКупить(): при GET-команде 'купить постройку шахты', err=\n\t%v\n", ош)
  413. return false, fmt.Errorf("не получены строки")
  414. }
  415. for _, стр = range списСтр {
  416. // <a class="simple-but border mb5" href="Mine?5-1.ILinkListener-upgradeLink-link">
  417. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  418. еслиНайти = true
  419. break
  420. }
  421. }
  422. if !еслиНайти {
  423. сам.лог.Добавить("Шахта.проапгрейдить().фнКупить(): не надо\n")
  424. return false, nil
  425. }
  426. // Пробуем улучшить шахту
  427. _стр := strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
  428. _стр = strings.TrimSuffix(_стр, "\">")
  429. // https://wartank.ru/building-upgrade/Mine?4-1.ILinkListener-upgradeLink-link
  430. // <a class="simple-but border mb5" href="FuelStorage?50-1.ILinkListener-upgradeLink-link">
  431. ссылка := "https://wartank.ru/building-upgrade/" + _стр
  432. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  433. if ош != nil {
  434. сам.лог.Добавить("ОШИБКА Шахта.проапгрейдить().фнКупить(): при GET-команде 'купить постройку шахты', err=\n\t%v\n", ош)
  435. return false, fmt.Errorf("не получены строки")
  436. }
  437. // Проверить, что постройка состоялась
  438. for _, стр := range списСтр {
  439. if strings.Contains(стр, "ILinkListener-upgradeLink-link") {
  440. сам.лог.Добавить("ОШИБКА Шахта.проапгрейдить().фнКупить(): покупка шахты не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  441. return false, fmt.Errorf("покупка шахты не прошла") // Покупка не оплачена
  442. }
  443. }
  444. сам.лог.Добавить("Шахта.проапгрейдить().фнКупить(): покупка шахты прошла\n")
  445. return true, nil
  446. }
  447. фнПодтверждение := func() bool {
  448. for _, стр = range списСтр {
  449. // <a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="../wicket/page?7-1.ILinkListener-confirmLink"><span><span>да, подтверждаю</span></span></a>
  450. if strings.Contains(стр, `ILinkListener-confirmLink`) {
  451. еслиНайти = true
  452. break
  453. }
  454. }
  455. if !еслиНайти {
  456. сам.лог.Добавить("Шахта.проапгрейдить().фнПодтверждение(): нет подтверждения\n")
  457. return true
  458. }
  459. // Пробуем построить шахту
  460. _стр := strings.TrimPrefix(стр, `<a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="..`)
  461. _стр = strings.TrimSuffix(_стр, `"><span><span>да, подтверждаю</span></span></a>`)
  462. // https://wartank.ru/wicket/page?6-1.ILinkListener-confirmLink
  463. ссылка := "https://wartank.ru" + _стр
  464. списСтр, ош = сам.сеть.ВебВоркер().Получ(ссылка)
  465. if ош != nil {
  466. сам.лог.Добавить("Шахта.проапгрейдить().фнПодтверждение(): при GET-команде 'подтвердить постройку шахты', err=\n\t%v\n", ош)
  467. return false
  468. }
  469. // Проверить, что постройка состоялась
  470. for _, стр := range списСтр {
  471. if strings.Contains(стр, "<title>Вы сделали слишком большую паузу</title>") {
  472. сам.лог.Добавить("Шахта.проапгрейдить().фнПодтверждение(): подтверждение покупка шахты не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  473. return false // Покупка не оплачена
  474. }
  475. }
  476. сам.лог.Добавить("Шахта.проапгрейдить().фнПодтверждение(): подтверждение покупка шахты прошла\n")
  477. return true
  478. }
  479. фнКомплекс := func() {
  480. сам.лог.Добавить("Шахта.проапгрейдить().фнКомплекс()\n")
  481. count := 5
  482. for count > 0 {
  483. еслиОк, ош := фнКупить()
  484. switch {
  485. case ош == nil && еслиОк: // покупка шахты прошла
  486. if фнПодтверждение() {
  487. return
  488. }
  489. case ош == nil && !еслиОк: // покупка шахты не нужна
  490. return
  491. case ош != nil: // ошибка при работе с сетью
  492. count--
  493. }
  494. }
  495. }
  496. фнКомплекс()
  497. return true
  498. }
  499. // Сделать -- вызывается с базы, если она обнаружила, что пора сделать продукцию
  500. func (сам *Шахта) Сделать() {
  501. сам.сеть.Обновить()
  502. if err := сам.выбратьМеталл(); err != nil {
  503. сам.лог.Добавить("ERRO Шахта.Сделать(): при выборе продукции, err=\n\t%v\n", err)
  504. return
  505. }
  506. работа := сам.АренаСостояние().РаботаИмя()
  507. switch работа {
  508. case "руда":
  509. for !сам.рудаСделать() {
  510. }
  511. case "железо":
  512. for !сам.железоСделать() {
  513. }
  514. case "сталь":
  515. for !сам.стальСделать() {
  516. }
  517. case "свинец":
  518. for !сам.свинецСделать() {
  519. }
  520. default:
  521. сам.лог.Добавить("ERRO Шахта.Сделать(): неизвестный режим производства, режим=%q\n", работа)
  522. }
  523. }
  524. // Свинец -- возвращает объект свинца
  525. func (сам *Шахта) Свинец() types.ИСтатПарам {
  526. return сам.свинец
  527. }
  528. // Сталь -- возвращает объект стали
  529. func (сам *Шахта) Сталь() types.ИСтатПарам {
  530. return сам.сталь
  531. }
  532. // Железо -- возвращает объект железа
  533. func (сам *Шахта) Железо() types.ИСтатПарам {
  534. return сам.железо
  535. }
  536. // Руда -- возвращает объект руды
  537. func (сам *Шахта) Руда() types.ИСтатПарам {
  538. return сам.руда
  539. }
  540. // ПродуктКолСейчас -- возвращает количество производимого продукта
  541. func (сам *Шахта) ПродуктКолСейчас() int {
  542. return сам.продуктКол.Получ()
  543. }
  544. // ПродуктИмяСейчас -- возвращает имя производимого продукта
  545. func (сам *Шахта) ПродуктИмяСейчас() string {
  546. return сам.продуктИмя
  547. }
  548. // ПродуктВремяСейчас -- сколько осталось времени до производства продукта
  549. func (сам *Шахта) ПродуктВремяСейчас() string {
  550. // сам.количествоПолучить()
  551. return сам.продуктВремя
  552. // return сам.Секция.ВремяОпрос().Стр()
  553. }
  554. // Выбирает продукцию по возможности произвести и её количеству
  555. func (сам *Шахта) выбратьМеталл() error {
  556. var (
  557. диктПродукция = make(map[string]bool) // Словарь известной продукции
  558. lstMine = сам.СписПолучить()
  559. )
  560. фнВыбратьПродукт := func() { // вычисляет список допустимой продукции
  561. диктПродукция["руда"] = true // Руда есть всегда
  562. диктПродукция["железо"] = false
  563. диктПродукция["сталь"] = false
  564. диктПродукция["свинец"] = false
  565. for _, strProd := range lstMine { // Проверить руду
  566. if strings.Contains(strProd, `<span class="green2">Руда</span><br/>`) {
  567. диктПродукция["руда"] = true
  568. break
  569. }
  570. }
  571. for _, strProd := range lstMine { // Проверить руду
  572. if strings.Contains(strProd, `<span class="green2">Железо</span><br/>`) {
  573. диктПродукция["железо"] = true
  574. break
  575. }
  576. }
  577. for _, strProd := range lstMine { // Проверить сталь
  578. if strings.Contains(strProd, `<span class="green2">Сталь</span><br/>`) {
  579. диктПродукция["сталь"] = true
  580. break
  581. }
  582. }
  583. for _, strProd := range lstMine { // Проверить свинец
  584. if strings.Contains(strProd, `<span class="green2">Свинец</span><br/>`) {
  585. диктПродукция["свинец"] = true
  586. break
  587. }
  588. }
  589. }
  590. фнВыбратьПродукт()
  591. сам.АренаСостояние().РаботаИмяУст("руда")
  592. руда := сам.Руда().Получ()
  593. железо := сам.Железо().Получ()
  594. if диктПродукция["железо"] {
  595. if руда > железо*2 {
  596. сам.АренаСостояние().РаботаИмяУст("железо")
  597. }
  598. }
  599. сталь := сам.Сталь().Получ()
  600. if диктПродукция["сталь"] {
  601. if железо > сталь*2 {
  602. сам.АренаСостояние().РаботаИмяУст("сталь")
  603. }
  604. }
  605. свинец := сам.Свинец().Получ()
  606. if диктПродукция["свинец"] {
  607. if сталь > свинец*2 {
  608. сам.АренаСостояние().РаботаИмяУст("свинец")
  609. }
  610. }
  611. return nil
  612. }
  613. // Создаёт руду
  614. func (сам *Шахта) рудаСделать() bool {
  615. time.Sleep(time.Millisecond * 55)
  616. lstMine, err := сам.сеть.Get("https://wartank.ru/production/Mine")
  617. if err != nil {
  618. // log._rintf("ERRO Шахта.сделатьРуду(): при GET-команде 'начать производство руды', err=\n\t%v\n", err)
  619. return false
  620. }
  621. var (
  622. инд int
  623. стрВых string
  624. strTime string
  625. strLink string
  626. strNum string
  627. еслиНайдено bool
  628. )
  629. for инд, стрВых = range lstMine {
  630. if strings.Contains(стрВых, `<span class="green2">Руда</span><br/>`) { // <span class="green2">Руда</span><br/>
  631. strNum = lstMine[инд+1]
  632. strTime = lstMine[инд+3]
  633. strLink = lstMine[инд+10]
  634. еслиНайдено = true
  635. break
  636. }
  637. }
  638. if !еслиНайдено {
  639. return false
  640. }
  641. if !strings.Contains(strLink, `>Начать производство<`) {
  642. return true
  643. }
  644. // "Mine?16-1.ILinkListener-productions-0-production-startProduceLink\"><span><span>Начать производство</span></span></a>"
  645. // "<a class=\"simple-but border\" href=\"Mine?16-1.ILinkListener-productions-0-production-startProduceLink\"><span><span>Начать производство</span></span></a>"
  646. _link := strings.TrimPrefix(strLink, `<a class="simple-but border" href="`)
  647. _link = strings.TrimSuffix(_link, "\"><span><span>Начать производство</span></span></a>")
  648. strLink = "https://wartank.ru/production/" + _link
  649. // https://wartank.ru/production/Mine?19-1.ILinkListener-productions-0-production-startProduceLink
  650. time.Sleep(time.Millisecond * 55)
  651. lstMine, err = сам.сеть.Get(strLink)
  652. if err != nil {
  653. // log._rintf("ERRO Шахта.сделатьРуду(): при GET-команде 'начать производство руды', err=\n\t%v\n", err)
  654. return false
  655. }
  656. for _, стрВых = range lstMine {
  657. if strings.Contains(стрВых, `><span><span>Начать производство</span></span></a>`) {
  658. return false
  659. }
  660. }
  661. if err = сам.СтрОбновить(lstMine); err != nil {
  662. // log._rintf("ERRO Шахта.сделатьРуду(): при обновлении lstMine, err=\n\t%v\n", err)
  663. return false
  664. }
  665. if err := сам.ОбратВремяУст(alias.Время(strTime)); err != nil {
  666. сам.лог.Добавить("ERRO Шахта.сделатьРуду(): при установке времени ожидания добычи руды(%v)\n\terr=%v\n", strTime, err)
  667. }
  668. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  669. strNum = lstNum[1]
  670. lstNum = strings.Split(strNum, `</span><br/>`)
  671. strNum = lstNum[0]
  672. iNum, err := strconv.Atoi(strNum)
  673. if err != nil {
  674. // log._rintf("ERRO Шахта.сделатьРуду(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  675. return false
  676. }
  677. сам.продуктКол.Уст(iNum)
  678. return true
  679. }
  680. // Создаёт железо
  681. func (сам *Шахта) железоСделать() bool {
  682. var (
  683. lstMine = сам.СписПолучить()
  684. ind int
  685. strOut string
  686. strTime string
  687. strLink string
  688. strNum string
  689. еслиНайдено bool
  690. )
  691. for ind, strOut = range lstMine {
  692. if strings.Contains(strOut, `<span class="green2">Железо</span><br/>`) {
  693. // <span class="green2">Железо</span><br/>
  694. strNum = lstMine[ind+1]
  695. // Кол-во: <span class="green2">1</span><br/>
  696. strTime = lstMine[ind+3]
  697. // <a class="simple-but border" href="Mine?4-1.ILinkListener-productions-1-production-startProduceLink"><span><span>Начать производство</span></span></a>
  698. strLink = lstMine[ind+10]
  699. еслиНайдено = true
  700. break
  701. }
  702. }
  703. if !еслиНайдено {
  704. return true
  705. }
  706. lstLink := strings.Split(strLink, `<a class="simple-but border" href="`)
  707. strLink = lstLink[1]
  708. lstLink = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  709. strLink = "https://wartank.ru/production/" + lstLink[0]
  710. // https://wartank.ru/production/Mine?4-1.ILinkListener-productions-1-production-startProduceLink
  711. lstMine, err := сам.сеть.Get(strLink)
  712. if err != nil {
  713. // log._rintf("ERRO MineNet.makeFerrum(): при GET-команде 'начать производство железа', err=\n\t%v\n", err)
  714. return false
  715. }
  716. for _, strOut := range lstMine { // Проверка на базу
  717. if strings.Contains(strOut, `<title>База</title>`) {
  718. // log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine найден lstBase")
  719. return false
  720. }
  721. }
  722. if err = сам.СтрОбновить(lstMine); err != nil {
  723. // log._rintf("ERRO MineNet.makeFerrum(): при обновлении lstMine, err=\n\t%v\n", err)
  724. return false
  725. }
  726. if err := сам.ОбратВремяУст(alias.Время(strTime)); err != nil {
  727. сам.лог.Добавить("ERRO Mine.makeFerrum(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
  728. }
  729. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  730. strNum = lstNum[1]
  731. lstNum = strings.Split(strNum, `</span><br/>`)
  732. strNum = lstNum[0]
  733. iNum, err := strconv.Atoi(strNum)
  734. if err != nil {
  735. // log._rintf("ERRO MineNet.makeFerrum(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  736. return false
  737. }
  738. сам.продуктКол.Уст(iNum)
  739. return true
  740. }
  741. // Создаёт сталь
  742. func (сам *Шахта) стальСделать() bool {
  743. var (
  744. lstMine = сам.СписПолучить()
  745. ind int
  746. strOut string
  747. strTime string
  748. strLink string
  749. strNum string
  750. еслиНайдено bool
  751. )
  752. for ind, strOut = range lstMine {
  753. if strings.Contains(strOut, `<span class="green2">Сталь</span><br/>`) {
  754. strNum = lstMine[ind+1]
  755. strTime = lstMine[ind+3]
  756. strLink = lstMine[ind+10]
  757. еслиНайдено = true
  758. break
  759. }
  760. }
  761. if !еслиНайдено {
  762. return true
  763. }
  764. lstLink := strings.Split(strLink, `<a class="simple-but border" href="`)
  765. strLink = lstLink[1]
  766. lstLink = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  767. strLink = "https://wartank.ru/production/" + lstLink[0]
  768. time.Sleep(time.Millisecond * 55)
  769. lstMine, err := сам.сеть.Get(strLink)
  770. if err != nil {
  771. // log._rintf("ERRO MineNet.makeSteel(): при GET-команде 'начать производство стали', err=\n\t%v\n", err)
  772. return false
  773. }
  774. for _, strOut := range lstMine { // Проверка на базу
  775. if strings.Contains(strOut, `<title>База</title>`) {
  776. // log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine найден lstBase")
  777. return false
  778. }
  779. }
  780. if err = сам.СтрОбновить(lstMine); err != nil {
  781. // log._rintf("ERRO MineNet.makeSteel(): при обновлении lstMine, err=\n\t%v\n", err)
  782. return false
  783. }
  784. if err := сам.ОбратВремяУст(alias.Время(strTime)); err != nil {
  785. сам.лог.Добавить("ERRO Mine.makeSteel(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
  786. }
  787. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  788. strNum = lstNum[1]
  789. lstNum = strings.Split(strNum, `</span><br/>`)
  790. strNum = lstNum[0]
  791. iNum, err := strconv.Atoi(strNum)
  792. if err != nil {
  793. // log._rintf("ERRO MineNet.makeSteel(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  794. return false
  795. }
  796. сам.продуктКол.Уст(iNum)
  797. return true
  798. }
  799. // Создаёт свинец
  800. func (сам *Шахта) свинецСделать() bool {
  801. var (
  802. lstMine = сам.СписПолучить()
  803. ind int
  804. strOut string
  805. strTime string
  806. strLink string
  807. strNum string
  808. еслиНайдено bool
  809. )
  810. for ind, strOut = range lstMine {
  811. if strings.Contains(strOut, `<span class="green2">Свинец</span><br/>`) {
  812. strNum = lstMine[ind+1]
  813. strTime = lstMine[ind+3]
  814. strLink = lstMine[ind+10]
  815. еслиНайдено = true
  816. break
  817. }
  818. }
  819. if !еслиНайдено {
  820. return true
  821. }
  822. lstLink := strings.Split(strLink, `<a class="simple-but border" href="`)
  823. strLink = lstLink[1]
  824. lstLink = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  825. strLink = "https://wartank.ru/production/" + lstLink[0]
  826. time.Sleep(time.Millisecond * 55)
  827. lstMine, err := сам.сеть.Get(strLink)
  828. if err != nil {
  829. // log._rintf("ERRO Шахта.сделатьСвинец(): при GET-команде 'начать производство стали', err=\n\t%v\n", err)
  830. return false
  831. }
  832. for _, strOut := range lstMine { // Проверка на базу
  833. if strings.Contains(strOut, `<title>База</title>`) {
  834. // log._rintf("ERRO Шахта.сделатьСвинец(): при обновлении lstMine найден lstBase")
  835. return false
  836. }
  837. }
  838. if err = сам.СтрОбновить(lstMine); err != nil {
  839. // log._rintf("ERRO Шахта.сделатьСвинец(): при обновлении lstMine, err=\n\t%v\n", err)
  840. return false
  841. }
  842. if err := сам.ОбратВремяУст(alias.Время(strTime)); err != nil {
  843. сам.лог.Добавить("ERRO Шахта.сделатьСвинец(): при установке времени производства железа(%v)\n\terr=%v\n", strTime, err)
  844. }
  845. lstNum := strings.Split(strNum, `Кол-во: <span class="green2">`)
  846. strNum = lstNum[1]
  847. lstNum = strings.Split(strNum, `</span><br/>`)
  848. strNum = lstNum[0]
  849. iNum, err := strconv.Atoi(strNum)
  850. if err != nil {
  851. // log._rintf("ERRO Шахта.сделатьСвинец(): кол-во(%v) не число, err=\n\t%v\n", strNum, err)
  852. return false
  853. }
  854. сам.продуктКол.Уст(iNum)
  855. return true
  856. }