mine.go 38 KB

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