mine.go 38 KB

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