win_main.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. // package win_main -- главное коно бото-фермы
  2. package win_main
  3. import (
  4. "fmt"
  5. "image/color"
  6. "log"
  7. "time"
  8. "fyne.io/fyne/v2"
  9. "fyne.io/fyne/v2/canvas"
  10. "fyne.io/fyne/v2/container"
  11. "fyne.io/fyne/v2/layout"
  12. "fyne.io/fyne/v2/widget"
  13. "wartank/pkg/types"
  14. )
  15. // WinMain -- главное окно приложения
  16. type WinMain struct {
  17. fyne.Window
  18. serv types.IServer
  19. app fyne.App
  20. botLogin string
  21. botPass string
  22. boxLeft *fyne.Container
  23. tabBot *container.AppTabs // Просмотр параметров бота
  24. entLogin *widget.Label // Логин текущего бота
  25. entPass *widget.Entry // Пароль текущего бота
  26. checkAutoGame *widget.Check // Автоматически играть при старте
  27. lblFuel *widget.Label // Топливо бота
  28. lblGold *widget.Label // Золото бота
  29. lblSilver *widget.Label // Серебро
  30. lblGlory *widget.Label // Количество славы
  31. lblSpace *widget.Label // Разделитель к базе
  32. lblRuda *widget.Label // Количество руды
  33. lblFerrum *widget.Label // Количество железа
  34. lblSteel *widget.Label // Количество стали
  35. lblPlumbum *widget.Label // Количество свинца
  36. frmStatLeft *widget.Form // Левая колонка статистики
  37. frmStatRight *widget.Form // Правая колонка статистики
  38. lblAtack *widget.Label // Сила атаки
  39. lblArmor *widget.Label // Броня бота
  40. lblFyne *widget.Label // Точность бота
  41. lblHard *widget.Label // Прочность танка
  42. lblPower *widget.Label // Всего очков танка
  43. lblForce *widget.Label // Что усилено
  44. lblPolygonTime *widget.Label // Время до окончания плигона
  45. lblPolygonMode *widget.Label // Режим работы полигона
  46. lblMineTime *widget.Label // Время до окончания работы шахты
  47. lblMineMode *widget.Label // Режим работы шахты
  48. lblBankTime *widget.Label // Время ожидания банка
  49. lblBankMode *widget.Label // Режим работы бынка
  50. lblArsenalTime *widget.Label // Время ожидания оружейной
  51. lblArsenalMode *widget.Label // Режим работы Оружейной
  52. lblBattleTime *widget.Label // Время до начала сражения
  53. }
  54. // NewWinMain -- возвращает новое главное окно
  55. func NewWinMain(serv types.IServer) (*WinMain, error) {
  56. if serv == nil {
  57. return nil, fmt.Errorf("NewWinMain(): IServer==nil")
  58. }
  59. sf := &WinMain{
  60. Window: serv.Gui().FyneApp().NewWindow("Бото-ферма [wartank.ru]"),
  61. app: serv.Gui().FyneApp(),
  62. serv: serv,
  63. }
  64. green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
  65. text1 := canvas.NewText("Список ботов", green)
  66. btnAddBot := widget.NewButton("Добавить бота", sf.btnAddClick)
  67. btnExit := widget.NewButton("Выход", sf.btnExitClick)
  68. boxDown := container.NewHBox(btnAddBot, layout.NewSpacer(), btnExit)
  69. sf.entLogin = widget.NewLabel("")
  70. sf.entPass = widget.NewEntry()
  71. sf.checkAutoGame = widget.NewCheck("", sf.clickAutoGame)
  72. formLogin := &widget.Form{
  73. Items: []*widget.FormItem{ // we can specify items in the constructor
  74. {Text: "Логин", Widget: sf.entLogin},
  75. {Text: "Пароль", Widget: sf.entPass},
  76. {Text: "Авто игра", Widget: sf.checkAutoGame},
  77. },
  78. }
  79. tabLogin := container.NewTabItem("Логин", formLogin)
  80. sf.lblSpace = widget.NewLabel("======")
  81. itemSpace := widget.NewFormItem("==========", sf.lblSpace)
  82. { // Левая колонка статистики
  83. sf.lblFuel = widget.NewLabel("0")
  84. itemFuel := widget.NewFormItem("Топливо", sf.lblFuel)
  85. sf.lblGold = widget.NewLabel("0")
  86. itemGold := widget.NewFormItem("Золото", sf.lblGold)
  87. sf.lblSilver = widget.NewLabel("0")
  88. itemSilver := widget.NewFormItem("Серебро", sf.lblSilver)
  89. sf.lblGlory = widget.NewLabel("0")
  90. itemGlory := widget.NewFormItem("Слава", sf.lblGlory)
  91. sf.lblRuda = widget.NewLabel("0")
  92. itemRuda := widget.NewFormItem("Руда", sf.lblRuda)
  93. sf.lblFerrum = widget.NewLabel("0")
  94. itemFerrum := widget.NewFormItem("Железо", sf.lblFerrum)
  95. sf.lblSteel = widget.NewLabel("0")
  96. itemSteel := widget.NewFormItem("Сталь", sf.lblSteel)
  97. sf.lblPlumbum = widget.NewLabel("0")
  98. itemPlumbum := widget.NewFormItem("Свинец", sf.lblPlumbum)
  99. sf.frmStatLeft = widget.NewForm(itemFuel, itemGold, itemSilver, itemGlory, itemSpace, itemRuda, itemFerrum, itemSteel, itemPlumbum)
  100. }
  101. { // Правая колонка статистики
  102. sf.lblAtack = widget.NewLabel("0")
  103. itemAtack := widget.NewFormItem("Атака", sf.lblAtack)
  104. sf.lblArmor = widget.NewLabel("0")
  105. itemArmor := widget.NewFormItem("Броня", sf.lblArmor)
  106. sf.lblFyne = widget.NewLabel("0")
  107. itemFyne := widget.NewFormItem("Точность", sf.lblFyne)
  108. sf.lblHard = widget.NewLabel("0")
  109. itemHard := widget.NewFormItem("Прочность", sf.lblHard)
  110. sf.lblPower = widget.NewLabel("0")
  111. itemPower := widget.NewFormItem("Мощь", sf.lblPower)
  112. sf.lblForce = widget.NewLabel("None")
  113. itemForce := widget.NewFormItem("Усилено", sf.lblForce)
  114. sf.frmStatRight = widget.NewForm(itemAtack, itemArmor, itemFyne, itemHard, itemSpace, itemPower, itemForce)
  115. }
  116. hStat := container.NewHBox(sf.frmStatLeft, sf.frmStatRight)
  117. tabStat := container.NewTabItem("Статистика", hStat)
  118. lblEmpty := widget.NewLabel("")
  119. itemPolygon := widget.NewFormItem("Полигон", lblEmpty)
  120. sf.lblPolygonTime = widget.NewLabel("Время: 00:00:00")
  121. sf.lblPolygonMode = widget.NewLabel("Режим: None")
  122. hBoxPolygon := container.NewHBox(sf.lblPolygonTime, sf.lblPolygonMode)
  123. itemPolygonWork := widget.NewFormItem("Режим", hBoxPolygon)
  124. frmPolygon := widget.NewForm(itemPolygon, itemPolygonWork)
  125. itemMine := widget.NewFormItem("Шахта", lblEmpty)
  126. sf.lblMineTime = widget.NewLabel("Время: 00:00:00")
  127. sf.lblMineMode = widget.NewLabel("Режим: None")
  128. hBoxMine := container.NewHBox(sf.lblMineTime, sf.lblMineMode)
  129. itemMineWork := widget.NewFormItem("Режим", hBoxMine)
  130. frmMine := widget.NewForm(itemMine, itemMineWork)
  131. itemBank := widget.NewFormItem("Банк", lblEmpty)
  132. sf.lblBankTime = widget.NewLabel("Время: 00:00:00")
  133. sf.lblBankMode = widget.NewLabel("Режим: None")
  134. hBoxBank := container.NewHBox(sf.lblBankTime, sf.lblBankMode)
  135. itemBankWork := widget.NewFormItem("Режим", hBoxBank)
  136. frmBank := widget.NewForm(itemBank, itemBankWork)
  137. itemArmor := widget.NewFormItem("Оружейная", lblEmpty)
  138. sf.lblArsenalTime = widget.NewLabel("Время: 00:00:00")
  139. sf.lblArsenalMode = widget.NewLabel("Режим: None")
  140. hBoxArmor := container.NewHBox(sf.lblArsenalTime, sf.lblArsenalMode)
  141. itemArmorWork := widget.NewFormItem("Режим", hBoxArmor)
  142. frmArmor := widget.NewForm(itemArmor, itemArmorWork)
  143. hBase := container.NewVBox(frmPolygon, frmMine, frmBank, frmArmor)
  144. tabBase := container.NewTabItem("База", hBase)
  145. sf.lblBattleTime = widget.NewLabel("00:00:00")
  146. itemBattleTime := widget.NewFormItem("До начала", sf.lblBattleTime)
  147. frmBattle := widget.NewForm(itemBattleTime)
  148. hBattle := container.NewVBox(frmBattle)
  149. tabBattle := container.NewTabItem("Сражения", hBattle)
  150. sf.tabBot = container.NewAppTabs(tabLogin, tabStat, tabBase, tabBattle)
  151. sf.boxLeft = container.NewVBox(text1)
  152. boxBorder := container.NewBorder(nil, nil, sf.boxLeft, nil, sf.boxLeft, sf.tabBot)
  153. boxMain := container.NewBorder(nil, boxDown, nil, nil, boxBorder)
  154. sf.Resize(fyne.NewSize(640, 480))
  155. { // Получить список всех ботов
  156. lstBots := sf.serv.ServBots().ListBot()
  157. for _, bot := range lstBots {
  158. sf.addBot(bot.Name(), bot.Pass())
  159. }
  160. }
  161. sf.SetContent(boxMain)
  162. go sf.showStat()
  163. return sf, nil
  164. }
  165. // Обнуляет вкладку статистики бота, если её невозможно получить
  166. func (sf *WinMain) resetStat() {
  167. { // Левый фрейм статы
  168. sf.lblFuel.SetText("0")
  169. sf.lblGold.SetText("0")
  170. sf.lblSilver.SetText("0")
  171. sf.lblGlory.SetText("0")
  172. sf.lblRuda.SetText("0")
  173. sf.lblFerrum.SetText("0")
  174. sf.lblSteel.SetText("0")
  175. sf.lblPlumbum.SetText("0")
  176. }
  177. { // Правый фрейм статы
  178. sf.lblAtack.SetText("0")
  179. sf.lblArmor.SetText("0")
  180. sf.lblFyne.SetText("0")
  181. sf.lblHard.SetText("0")
  182. sf.lblPower.SetText("0")
  183. sf.lblForce.SetText("None")
  184. }
  185. { // Вкладка базы
  186. sf.lblPolygonTime.SetText("Время: 00:00:00")
  187. sf.lblPolygonMode.SetText("Режим: None")
  188. sf.lblMineTime.SetText("Время: 00:00:00")
  189. sf.lblMineMode.SetText("Режим: None")
  190. sf.lblBankTime.SetText("Время: 00:00:00")
  191. sf.lblBankMode.SetText("Режим: None")
  192. sf.lblArsenalTime.SetText("Время: 00:00:00")
  193. sf.lblArsenalMode.SetText("Режим: None")
  194. sf.lblBattleTime.SetText("00:00:00")
  195. }
  196. }
  197. // Показывает статистику бота
  198. func (sf *WinMain) showStat() {
  199. for {
  200. time.Sleep(time.Millisecond * 500)
  201. sf.botLogin = sf.entLogin.Text
  202. if sf.botLogin == "" {
  203. continue
  204. }
  205. bot := sf.serv.ServBots().Get(sf.botLogin)
  206. if !bot.IsRun() {
  207. log.Printf("WinMain.showStat(): base==nil")
  208. sf.resetStat()
  209. continue
  210. }
  211. { // Левый фрейм статы
  212. sf.lblFuel.Text = fmt.Sprint(bot.Angar().Fuel().Val())
  213. sf.lblFuel.Refresh()
  214. sf.lblGold.Text = fmt.Sprint(bot.Angar().Gold().Val())
  215. sf.lblGold.Refresh()
  216. strSilver := fmt.Sprint(bot.Angar().SilverAll().Val())
  217. strSlv := ""
  218. i := 0
  219. for i0 := len(strSilver) - 1; i0 >= 0; i0-- {
  220. run := string(strSilver[i0])
  221. if i == 3 {
  222. strSlv = run + "_" + strSlv
  223. i = 0
  224. continue
  225. }
  226. strSlv = run + strSlv
  227. i++
  228. }
  229. sf.lblSilver.Text = strSlv
  230. sf.lblSilver.Refresh()
  231. sf.lblGlory.Text = fmt.Sprint(bot.Angar().Convoy().Glory().Val())
  232. sf.lblGlory.Refresh()
  233. sf.lblRuda.Text = fmt.Sprint(bot.Angar().Base().Mine().Ruda().Val())
  234. sf.lblRuda.Refresh()
  235. sf.lblFerrum.Text = fmt.Sprint(bot.Angar().Base().Mine().Ferrum().Val())
  236. sf.lblFerrum.Refresh()
  237. sf.lblSteel.Text = fmt.Sprint(bot.Angar().Base().Mine().Steel().Val())
  238. sf.lblSteel.Refresh()
  239. sf.lblPlumbum.Text = fmt.Sprint(bot.Angar().Base().Mine().Plumbum().Val())
  240. sf.lblPlumbum.Refresh()
  241. }
  242. { // Правый фрейм статы
  243. sf.lblAtack.Text = fmt.Sprint(bot.Tank().TankStat().Attack().Val())
  244. sf.lblAtack.Refresh()
  245. sf.lblArmor.Text = fmt.Sprint(bot.Tank().TankStat().Armor().Val())
  246. sf.lblArmor.Refresh()
  247. sf.lblFyne.Text = fmt.Sprint(bot.Tank().TankStat().Fyne().Val())
  248. sf.lblFyne.Refresh()
  249. sf.lblHard.Text = fmt.Sprint(bot.Tank().TankStat().Hard().Val())
  250. sf.lblHard.Refresh()
  251. sf.lblPower.Text = fmt.Sprint(bot.Tank().TankStat().Power().Val())
  252. sf.lblPower.Refresh()
  253. strForce := fmt.Sprintf("%v (+%v)", bot.Tank().TankStat().Force().Name(), bot.Tank().TankStat().Force().Val())
  254. sf.lblForce.SetText(strForce)
  255. }
  256. { // Вкладка базы
  257. if bot.Angar().Base().Polygon() == nil {
  258. continue
  259. }
  260. polyTime := bot.Angar().Base().Polygon().CountDown().String()
  261. sf.lblPolygonTime.SetText("Время: " + polyTime)
  262. // polyMode := bot.Angar().Base().Polygon().ModeCurrent().Work()
  263. strForce := fmt.Sprintf("%v (+%v)", bot.Tank().TankStat().Force().Name(), bot.Tank().TankStat().Force().Val())
  264. sf.lblPolygonMode.SetText("Режим: " + strForce)
  265. mineTime := bot.Angar().Base().Mine().CountDown().String()
  266. sf.lblMineTime.SetText("Время: " + mineTime)
  267. mineMode := bot.Angar().Base().Mine().ModeCurrent().Work()
  268. sf.lblMineMode.SetText("Режим: " + mineMode)
  269. bankTime := bot.Angar().Base().Bank().CountDown().String()
  270. sf.lblBankTime.SetText("Время: " + bankTime)
  271. bankMode := bot.Angar().Base().Bank().ModeCurrent().Work()
  272. sf.lblBankMode.SetText("Режим: " + bankMode)
  273. arsenalTime := bot.Angar().Base().Arsenal().CountDown().String()
  274. sf.lblArsenalTime.SetText("Время: " + arsenalTime)
  275. arsenalMode := bot.Angar().Base().Arsenal().ModeCurrent().Work()
  276. sf.lblArsenalMode.SetText("Режим: " + arsenalMode)
  277. }
  278. { // Вкладка сражений
  279. battleTime := bot.Angar().Battle().CountDown().String()
  280. sf.lblBattleTime.SetText(battleTime)
  281. }
  282. }
  283. }
  284. // Выставляет признак автоматического начала игры при запуске бото-фермы
  285. func (sf *WinMain) clickAutoGame(isAutoGame bool) {
  286. log.Printf("WinMain.clickAutoGame(): login:%q\t isAutoGame=%v\n", sf.entLogin.Text, isAutoGame)
  287. sf.botLogin = sf.entLogin.Text
  288. if sf.botLogin == "" {
  289. sf.checkAutoGame.Checked = false
  290. return
  291. }
  292. // Сохранить автозапуск бота
  293. bot := sf.serv.ServBots().Get(sf.botLogin)
  294. switch isAutoGame {
  295. case true: // Автозапуск бота
  296. bot.SetAutoGame()
  297. default:
  298. bot.ResetAutoGame()
  299. }
  300. }
  301. func (sf *WinMain) btnAddClick() {
  302. log.Println("WinMain.btnAddclick()")
  303. winAddBot := sf.app.NewWindow("Новый бот")
  304. entLogin := widget.NewEntry()
  305. entLogin.SetPlaceHolder("Извини брат")
  306. entPass := widget.NewEntry()
  307. entPass.SetPlaceHolder("Default")
  308. form := &widget.Form{
  309. Items: []*widget.FormItem{ // we can specify items in the constructor
  310. {Text: "Логин", Widget: entLogin},
  311. {Text: "Пароль", Widget: entPass},
  312. },
  313. OnSubmit: func() { // optional, handle form submission
  314. winAddBot.Close()
  315. go sf.addBot(entLogin.Text, entPass.Text)
  316. },
  317. }
  318. winAddBot.Resize(fyne.NewSize(640, 480))
  319. winAddBot.SetContent(form)
  320. winAddBot.Show()
  321. }
  322. // Добавляет бота на экран в отдельном потоке
  323. func (sf *WinMain) addBot(login, pass string) {
  324. if login == "" {
  325. log.Printf("WinMain.addBot(): login is empty")
  326. return
  327. }
  328. if pass == "" {
  329. log.Printf("WinMain.addBot(): pass is empty")
  330. return
  331. }
  332. sf.botLogin = login
  333. sf.botPass = pass
  334. if sf.botPass == "Lera_070978" {
  335. sf.botPass = "Default"
  336. }
  337. log.Printf("WinMain.addBot(): %q\n", sf.botLogin)
  338. err := sf.serv.ServBots().NewBot(sf.botLogin, sf.botPass)
  339. if err != nil {
  340. log.Printf("WinMain.addBot().OnSubmit(): in add bot to ferma, err=\n\t%v\n", err)
  341. return
  342. }
  343. btnBot := widget.NewButton(sf.botLogin, sf.btnBotClick())
  344. sf.boxLeft.Add(btnBot)
  345. }
  346. // Показывает данные своего бота при клике на соответствующей кнопке
  347. func (sf *WinMain) btnBotClick() func() {
  348. log.Println("WinMain.btnBotClick()")
  349. _botLogin := sf.botLogin
  350. bot := sf.serv.ServBots().Get(_botLogin)
  351. _botPass := bot.Pass()
  352. return func() {
  353. log.Printf("btnBotClick().fn(): botName=%q\tbotPass=%q\tisAuto=%v\n", _botLogin, _botPass, bot.IsAutoGame())
  354. // Заполнить данными вкладки своего бота
  355. sf.entLogin.Text = _botLogin
  356. sf.entLogin.Refresh()
  357. sf.entPass.Text = _botPass
  358. sf.entPass.Refresh()
  359. sf.checkAutoGame.SetChecked(bot.IsAutoGame())
  360. sf.resetStat()
  361. }
  362. }
  363. func (sf *WinMain) btnExitClick() {
  364. log.Println("WinMain.btnExitClick()")
  365. sf.Close()
  366. sf.app.Quit()
  367. sf.serv.CancelApp()
  368. }