arena_arsenal.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. // package arena_arsenal -- объект оружейной на базе
  2. package arena_arsenal
  3. import (
  4. "log"
  5. "strconv"
  6. "strings"
  7. "time"
  8. . "wartank/app/lev0/types"
  9. "wartank/app/lev1"
  10. "wartank/app/lev1/web_log"
  11. "wartank/app/lev2/arena"
  12. . "gitp78su.ipnodns.ru/svi/kern"
  13. . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
  14. )
  15. const (
  16. стрКумулятивы = "кумулятивы"
  17. стрБронебойки = "бронебойки"
  18. стрФугасы = "фугасы"
  19. стрРемки = "ремки"
  20. )
  21. // Арсенал -- объект оружейной на базе
  22. type АренаАрсенал struct {
  23. ИАрена
  24. вЛог ИВебЛог
  25. лог ILogBuf
  26. бот ИБот
  27. база ИАренаБаза
  28. фугас ИСтатПарам
  29. бронебойка ИСтатПарам
  30. кумулятив ИСтатПарам
  31. ремка ИСтатПарам
  32. продуктИмя string // Что сейчас делается
  33. продуктКол ИСтатПарам // Сколько делается прямо сейчас
  34. продуктВремя string // Сколько осталось времени прямо сейчас
  35. конт ILocalCtx
  36. }
  37. // НовАрсенал -- возвращает новый *Arsenal
  38. func НовАрсенал(конт ILocalCtx) ИАренаАрсенал {
  39. лог := NewLogBuf()
  40. лог.Info("НовАрсенал()\n")
  41. сам := &АренаАрсенал{
  42. бот: конт.Get("бот").Val().(ИБот),
  43. база: конт.Get("база").Val().(ИАренаБаза),
  44. фугас: lev1.НовСтатПарам(стрФугасы),
  45. бронебойка: lev1.НовСтатПарам(стрБронебойки),
  46. кумулятив: lev1.НовСтатПарам(стрКумулятивы),
  47. ремка: lev1.НовСтатПарам(стрРемки),
  48. продуктКол: lev1.НовСтатПарам("свинец"),
  49. конт: конт,
  50. лог: лог,
  51. }
  52. аренаКонфиг := arena.АренаКонфиг{
  53. Бот_: сам.бот,
  54. АренаИмя_: "Арсенал",
  55. СтрКонтроль_: `<span class="green2">Ремкомплект</span><br/>`,
  56. ФнПуск_: сам.пуск,
  57. СтрУрл_: "https://wartank.ru/production/Armory",
  58. }
  59. сам.ИАрена = arena.НовАрена(конт, аренаКонфиг)
  60. сам.вЛог = web_log.НовВебЛог(true)
  61. // go сам.пуск()
  62. сам.вЛог.Добавить("НовАрсенал(): Арсенал создан")
  63. конт.Set("арсенал", сам, "Арсенал бота")
  64. return сам
  65. }
  66. // ПродуктКолСейчас -- возвращает количество производимого продукта
  67. func (сам *АренаАрсенал) ПродуктКолСейчас() int {
  68. return сам.продуктКол.Получ()
  69. }
  70. // ПродуктИмяСейчас -- возвращает имя производимого продукта
  71. func (сам *АренаАрсенал) ПродуктИмяСейчас() string {
  72. return сам.продуктИмя
  73. }
  74. // ПродуктВремяСейчас -- сколько осталось времени до производства продукта
  75. func (сам *АренаАрсенал) ПродуктВремяСейчас() string {
  76. return сам.продуктВремя
  77. // return сам.Секция.ВремяОпрос().Стр()
  78. }
  79. // запускает обработку арсенала
  80. func (сам *АренаАрсенал) пуск() {
  81. еслиПостроить := true
  82. фнРабота := func() {
  83. defer func() {
  84. for сам.ВремяОстат().ПолучМилСек() > 0 {
  85. select {
  86. case <-сам.конт.Ctx().Done():
  87. return
  88. default:
  89. time.Sleep(time.Second * 5)
  90. }
  91. }
  92. }()
  93. сам.вЛог.Добавить("Арсенал.пуск().фнРабота()\n")
  94. еслиПостроить = сам.проверитьПостроить()
  95. if еслиПостроить {
  96. еслиПостроено, ош := сам.построить()
  97. if ош != nil {
  98. return
  99. }
  100. if еслиПостроено {
  101. сам.вЛог.Добавить("построено")
  102. return
  103. }
  104. }
  105. { // апгрейд
  106. счёт := 5
  107. for счёт > 0 {
  108. if сам.проапгрейдить() {
  109. break
  110. }
  111. счёт--
  112. }
  113. }
  114. _ = сам.уровеньОбновить()
  115. сам.забрать()
  116. сам.сделать()
  117. сам.лог.Info("пуск(): бот=%q, цикл завершён\n", сам.бот.Имя())
  118. }
  119. for {
  120. фнРабота()
  121. }
  122. }
  123. // Проверяет необходимость постройки
  124. func (сам *АренаАрсенал) проверитьПостроить() bool {
  125. сам.вЛог.Добавить("Арсенал.проверитьПостроить()\n")
  126. _ = сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Armory")
  127. return true
  128. }
  129. // Обновляет текущий уровень арсенала (может быть не построена)
  130. func (сам *АренаАрсенал) уровеньОбновить() bool {
  131. сам.вЛог.Добавить("Арсенал.уровеньОбновить()\n")
  132. списСтр := сам.Сеть().ВебВоркер().Получ("http://wartank.ru/buildings")
  133. // <span class="green2">Оружейная - 0</span><br/>
  134. var (
  135. еслиНайти = false
  136. стр = ""
  137. )
  138. for _, стр = range списСтр {
  139. if strings.Contains(стр, `<span class="green2">Оружейная -`) {
  140. еслиНайти = true
  141. break
  142. }
  143. }
  144. if !еслиНайти {
  145. сам.вЛог.Добавить("Арсенал.уровеньОбновить(): не надо\n")
  146. return false
  147. }
  148. _стр := strings.TrimPrefix(стр, `<span class="green2">Оружейная - `)
  149. _стр = strings.TrimSuffix(_стр, `</span><br/>`)
  150. иУровень, ош := strconv.Atoi(_стр)
  151. if ош != nil {
  152. сам.лог.Err("уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
  153. сам.вЛог.Добавить("ОШИБКА Арсенал.уровеньОбновить(): строка уровня сбойная, стр=%q, ош=\n\t%v\n", стр, ош)
  154. return false
  155. }
  156. сам.Уровень().Уст(иУровень)
  157. сам.лог.Info("уровеньОбновить(): уровень=%d\n", иУровень)
  158. сам.вЛог.Добавить("Арсенал.уровеньОбновить(): уровень=%d\n", иУровень)
  159. return true
  160. }
  161. // Строит арсенал при нулевом уровне
  162. func (сам *АренаАрсенал) построить() (bool, error) {
  163. сам.вЛог.Добавить("Арсенал.построить()\n")
  164. списСтр := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Armory")
  165. // <span class="green2">Арсенал - 0</span><br/>
  166. var (
  167. еслиНайти = false
  168. стр = ""
  169. )
  170. for _, стр = range списСтр {
  171. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  172. еслиНайти = true
  173. break
  174. }
  175. }
  176. if !еслиНайти {
  177. сам.вЛог.Добавить("Арсенал.построить(): не надо\n")
  178. return true, nil
  179. }
  180. // <a class="simple-but border mb5" href="Armory?30-1.ILinkListener-upgradeLink-link">
  181. // Пробуем построить арсенал
  182. _стр := strings.TrimPrefix(стр, `<a class="simple-but border mb5" href="`)
  183. _стр = strings.TrimSuffix(_стр, `">`)
  184. ссылка := "https://wartank.ru/building-upgrade/" + _стр
  185. // https://wartank.ru/building-upgrade/Armory?35-1.ILinkListener-upgradeLink-link
  186. списСтр = сам.Сеть().ВебВоркер().Получ(ссылка)
  187. еслиНайти = false
  188. // "<a class=\"simple-but border mb5\" href=\"Armory?14-1.ILinkListener-upgradeLink-link\">"
  189. for _, стр = range списСтр {
  190. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  191. еслиНайти = true
  192. break
  193. }
  194. }
  195. if !еслиНайти {
  196. сам.вЛог.Добавить("Арсенал.построить(): не надо\n")
  197. return true, nil
  198. }
  199. сам.лог.Info("построить(): ок\n")
  200. сам.вЛог.Добавить("Арсенал.построить(): ок\n")
  201. return true, nil
  202. }
  203. // Пытается проапгрейдить арсенал
  204. func (сам *АренаАрсенал) проапгрейдить() bool {
  205. сам.вЛог.Добавить("Арсенал.проапгрейдить()\n")
  206. var (
  207. еслиНайти = false
  208. списСтр []string
  209. стр = ""
  210. )
  211. фнКупить := func() bool {
  212. defer time.Sleep(time.Millisecond * 1000)
  213. списСтр = сам.Сеть().ВебВоркер().Получ("https://wartank.ru/building-upgrade/Armory")
  214. for _, стр = range списСтр {
  215. // <a class="simple-but border mb5" href="Armory?5-1.ILinkListener-upgradeLink-link">
  216. if strings.Contains(стр, `ILinkListener-upgradeLink-link`) {
  217. еслиНайти = true
  218. break
  219. }
  220. }
  221. if !еслиНайти {
  222. сам.вЛог.Добавить("Арсенал.проапгрейдить(): не надо\n")
  223. return true
  224. }
  225. // Пробуем улучшить шахту
  226. _стр := strings.TrimPrefix(стр, "<a class=\"simple-but border mb5\" href=\"")
  227. _стр = strings.TrimSuffix(_стр, "\">")
  228. // https://wartank.ru/building-upgrade/Armory?4-1.ILinkListener-upgradeLink-link
  229. // <a class="simple-but border mb5" href="Armory?50-1.ILinkListener-upgradeLink-link">
  230. ссылка := "https://wartank.ru/building-upgrade/" + _стр
  231. списСтр = сам.Сеть().ВебВоркер().Получ(ссылка)
  232. // Проверить, что постройка состоялась
  233. for _, стр := range списСтр {
  234. if strings.Contains(стр, "ILinkListener-upgradeLink-link") {
  235. log.Printf("Арсенал.проапгрейдить().фнКупить(): покупка арсенала не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  236. return false // Покупка не оплачена
  237. }
  238. }
  239. сам.вЛог.Добавить("Арсенал.проапгрейдить().фнКупить(): ок\n")
  240. return true
  241. }
  242. фнПодтверждение := func() bool {
  243. for _, стр = range списСтр {
  244. // <a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="../wicket/page?7-1.ILinkListener-confirmLink"><span><span>да, подтверждаю</span></span></a>
  245. if strings.Contains(стр, `ILinkListener-confirmLink`) {
  246. еслиНайти = true
  247. break
  248. }
  249. }
  250. if !еслиНайти {
  251. сам.вЛог.Добавить("Арсенал.проапгрейдить().фнПодтверждение(): не надо\n")
  252. return true
  253. }
  254. // Пробуем построить шахту
  255. _стр := strings.TrimPrefix(стр, `<a class="simple-but border w50 mXa mb10" w:id="confirmLink" href="..`)
  256. _стр = strings.TrimSuffix(_стр, `"><span><span>да, подтверждаю</span></span></a>`)
  257. // https://wartank.ru/wicket/page?6-1.ILinkListener-confirmLink
  258. ссылка := "https://wartank.ru" + _стр
  259. списСтр = сам.Сеть().ВебВоркер().Получ(ссылка)
  260. // Проверить, что постройка состоялась
  261. for _, стр := range списСтр {
  262. if strings.Contains(стр, "<title>Вы сделали слишком большую паузу</title>") {
  263. сам.вЛог.Добавить("ОШИБКА Арсенал.проапгрейдить().фнПодтверждение(): подтверждение покупка склада топлива не прошла\n\tlink=%v\n\tстр=\n\t%v\n", ссылка, стр)
  264. return false // Покупка не оплачена
  265. }
  266. }
  267. сам.вЛог.Добавить("Арсенал.проапгрейдить().фнПодтверждение(): ок\n")
  268. return true
  269. }
  270. фнКомплекс := func() {
  271. count := 5
  272. for count > 0 {
  273. if фнКупить() {
  274. if фнПодтверждение() {
  275. break
  276. }
  277. }
  278. count--
  279. }
  280. }
  281. фнКомплекс()
  282. return true
  283. }
  284. // Проверяет на забрать оружейную
  285. func (сам *АренаАрсенал) забрать() bool {
  286. var (
  287. strOut string
  288. ind int
  289. еслиНайдено bool
  290. lstBase = сам.СписПолучить()
  291. )
  292. for ind, strOut = range lstBase {
  293. if strings.Contains(strOut, `Моя амуниция`) {
  294. еслиНайдено = true
  295. ind += 17
  296. strOut = lstBase[ind]
  297. break
  298. }
  299. }
  300. if !еслиНайдено {
  301. return false
  302. }
  303. if !strings.Contains(strOut, `"><span><span>Забрать</span></span></a>`) {
  304. return false
  305. }
  306. lstLink := strings.Split(strOut, `<a class="simple-but border" href="`)
  307. strLink := lstLink[1]
  308. lstLink = strings.Split(strLink, `"><span><span>Забрать</span></span></a>`)
  309. // https://wartank.ru/buildings?80-1.ILinkListener-buildings-0-building-rootBlock-actionPanel-takeProductionLink
  310. strLink = "https://wartank.ru/" + lstLink[0]
  311. var (
  312. лстАрсенал []string
  313. ош error
  314. )
  315. time.Sleep(time.Millisecond * 100)
  316. лстАрсенал, ош = сам.Сеть().Get(strLink)
  317. if ош != nil {
  318. log.Printf("Арсенал.забрать(): при выполнении Get-запроса? err=\n\t%v\n", ош)
  319. return false
  320. }
  321. if len(лстАрсенал) == 0 {
  322. log.Printf("Арсенал.забрать(): len lstBase(%v)==0", len(lstBase))
  323. return false
  324. }
  325. for _, strOut = range лстАрсенал {
  326. if strings.Contains(strOut, `<title>Производство</title>`) {
  327. return false
  328. }
  329. }
  330. if ош = сам.СтрОбновить(лстАрсенал); ош != nil {
  331. log.Printf("Арсенал.checkArsenalGet(): при обновлении lstBase, err=\n\t%v\n", ош)
  332. }
  333. if ош = сам.СтрОбновить(лстАрсенал); ош != nil {
  334. log.Printf("Арсенал.checkArsenalGet(): при обновлении lstArsenal, err=\n\t%v\n", ош)
  335. }
  336. return true
  337. }
  338. // Фугасы -- возвращает объект числа фугасов
  339. func (сам *АренаАрсенал) Фугасы() ИСтатПарам {
  340. return сам.фугас
  341. }
  342. // Бронебойки -- возвращает объект бронебойных снарядов
  343. func (сам *АренаАрсенал) Бронебойки() ИСтатПарам {
  344. return сам.бронебойка
  345. }
  346. // Кумулятивы -- возвращает объект бронебойных снарядов
  347. func (сам *АренаАрсенал) Кумулятивы() ИСтатПарам {
  348. return сам.кумулятив
  349. }
  350. // Ремки -- возвращает объект ремкомплектов
  351. func (сам *АренаАрсенал) Ремки() ИСтатПарам {
  352. return сам.ремка
  353. }
  354. // Выбирает что надо делать, запускает процесс изготовления
  355. func (сам *АренаАрсенал) сделать() bool {
  356. сам.Обновить()
  357. // _mt.Println("\tArsenalNet.сделать()")
  358. var (
  359. ремкаКол = сам.Ремки().Получ()
  360. фугасКол = сам.Фугасы().Получ()
  361. кумульКол = сам.Кумулятивы().Получ()
  362. ббКол = сам.Бронебойки().Получ()
  363. снарядТип string
  364. )
  365. if ремкаКол < 70 { // Контроль ремки по времени суток и минимальному количеству ремок
  366. for !сам.сделатьРемку() {
  367. }
  368. сам.продуктИмя = стрРемки
  369. return true
  370. }
  371. { // Контроль по числу снарядов. В равных долях без приоритетов
  372. // снарядТип = стрФугасы
  373. снарядТип = стрБронебойки
  374. if ббКол > фугасКол {
  375. снарядТип = стрФугасы
  376. }
  377. if фугасКол > кумульКол {
  378. снарядТип = стрКумулятивы
  379. }
  380. switch снарядТип {
  381. case стрФугасы: // Мало фугасов
  382. for !сам.сделатьФугасы() {
  383. }
  384. case стрКумулятивы: // Мало кумулятивов
  385. for !сам.сделатьКумули() {
  386. }
  387. case стрБронебойки: // Мало бронебойных
  388. for !сам.сделатьБронебойки() {
  389. }
  390. default:
  391. // log._rintf("ERRO Арсенал.сделать(): неизвестный тип арсенала(%v)", typeArmor)
  392. }
  393. сам.продуктИмя = снарядТип
  394. }
  395. return true
  396. }
  397. // Создать бронебойные
  398. func (сам *АренаАрсенал) сделатьБронебойки() bool {
  399. var (
  400. стрВых string
  401. lstArsenal = сам.СписПолучить()
  402. еслиНайдено bool
  403. инд int
  404. )
  405. for инд, стрВых = range lstArsenal {
  406. if strings.Contains(стрВых, `<span class="green2">Бронебойный снаряд</span><br/>`) {
  407. еслиНайдено = true
  408. break
  409. }
  410. }
  411. if !еслиНайдено {
  412. return false
  413. }
  414. стрВых = lstArsenal[инд+10]
  415. // Получить ссылку на бронебойные
  416. lstArmor := strings.Split(стрВых, `<a class="simple-but border" href="`)
  417. if len(lstArmor) <= 1 { // Тут возможно есть пустая строка
  418. return true // Считаем, что производство уже запущено
  419. }
  420. strLink := lstArmor[1]
  421. lstArmor = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  422. strLink = "https://wartank.ru/production/" + lstArmor[0]
  423. time.Sleep(time.Millisecond * 50)
  424. if _, err := сам.Сеть().Get(strLink); err != nil {
  425. // log._rintf("ERRO ArsenalNet.makeArmor(): in update lstArsenal, err=\n\t%v\n", err)
  426. return false
  427. }
  428. сам.АренаСостояние().СостояниеУст(стрБронебойки)
  429. return true
  430. }
  431. // Создать кумулятивные
  432. func (сам *АренаАрсенал) сделатьКумули() bool {
  433. var (
  434. стрВых string
  435. lstArsenal = сам.СписПолучить()
  436. еслиНайдено bool
  437. инд int
  438. )
  439. for инд, стрВых = range lstArsenal {
  440. if strings.Contains(стрВых, `<span class="green2">Кумулятивный снаряд</span><br/>`) {
  441. еслиНайдено = true
  442. break
  443. }
  444. }
  445. if !еслиНайдено {
  446. return false
  447. }
  448. стрВых = lstArsenal[инд+10]
  449. if !strings.Contains(стрВых, `>Начать производство<`) {
  450. return false
  451. }
  452. // Получить ссылку на кумулятив
  453. списКумул := strings.Split(стрВых, `<a class="simple-but border" href="`)
  454. strLink := списКумул[1]
  455. списКумул = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  456. strLink = "https://wartank.ru/production/" + списКумул[0]
  457. time.Sleep(time.Millisecond * 50)
  458. if _, err := сам.Сеть().Get(strLink); err != nil {
  459. // log._rintf("ERRO ArsenalNet.makeКумуль(): in make product arsenal кумуль , err=\n\t%v\n", err)
  460. return false
  461. }
  462. сам.АренаСостояние().СостояниеУст(стрКумулятивы)
  463. return true
  464. }
  465. // Создать фугасы
  466. func (сам *АренаАрсенал) сделатьФугасы() bool {
  467. var (
  468. lstArsenal = сам.СписПолучить()
  469. стрВых string
  470. еслиНайдено bool
  471. инд int
  472. )
  473. for инд, стрВых = range lstArsenal {
  474. if strings.Contains(стрВых, `<span class="green2">Фугасный снаряд</span><br/>`) {
  475. еслиНайдено = true
  476. break
  477. }
  478. }
  479. if !еслиНайдено {
  480. return false
  481. }
  482. стрВых = lstArsenal[инд+10]
  483. if !strings.Contains(стрВых, `"><span><span>Начать производство</span></span></a>`) {
  484. return false
  485. }
  486. // Получить ссылку на ремку
  487. списКумул := strings.Split(стрВых, `<a class="simple-but border" href="`)
  488. strLink := списКумул[1]
  489. списКумул = strings.Split(strLink, `"><span><span>Начать производство</span></span></a>`)
  490. strLink = "https://wartank.ru/production/" + списКумул[0]
  491. time.Sleep(time.Millisecond * 50)
  492. if _, err := сам.Сеть().Get(strLink); err != nil {
  493. // log._rintf("ERRO ArsenalNet.makeФугас(): in make request arsenal product, err=\n\t%v\n", err)
  494. return false
  495. }
  496. сам.АренаСостояние().СостояниеУст(стрФугасы)
  497. // log._rintf("INFO Арсенал.makeФугас()\n")
  498. return true
  499. }
  500. // Создать ремку. Выполняется если подходят условия
  501. func (сам *АренаАрсенал) сделатьРемку() bool {
  502. // _mt.Println("\tArsenalNet.makeРемка()")
  503. var (
  504. стрВых string
  505. еслиНайдено bool
  506. инд int
  507. )
  508. lstArsenal := сам.Сеть().ВебВоркер().Получ("https://wartank.ru/production/Armory")
  509. // <span class="green2">Ремкомплект</span><br/>
  510. for инд, стрВых = range lstArsenal {
  511. if strings.Contains(стрВых, `<span class="green2">Ремкомплект</span><br/>`) {
  512. еслиНайдено = true
  513. break
  514. }
  515. }
  516. if !еслиНайдено {
  517. return false
  518. }
  519. стрВых = lstArsenal[инд+10]
  520. // Если кривая строка, то надо вернуться
  521. if strings.Contains(стрВых, `</div></div></div></div></div></div></div></div>`) {
  522. return true
  523. }
  524. // Получить ссылку на ремку
  525. _ссылка := strings.TrimPrefix(стрВых, `<a class="simple-but border" href="`)
  526. _ссылка = strings.TrimSuffix(_ссылка, `"><span><span>Начать производство</span></span></a>`)
  527. // https://wartank.ru/production/Armory?37-1.ILinkListener-productions-3-production-startProduceLink
  528. ссылка := "https://wartank.ru/production/" + _ссылка
  529. time.Sleep(time.Millisecond * 50)
  530. _ = сам.Сеть().ВебВоркер().Получ(ссылка)
  531. сам.АренаСостояние().СостояниеУст(стрРемки)
  532. return true
  533. }