win_main.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. }
  46. // NewWinMain -- возвращает новое главное окно
  47. func NewWinMain(serv types.IServer) (*WinMain, error) {
  48. if serv == nil {
  49. return nil, fmt.Errorf("NewWinMain(): IServer==nil")
  50. }
  51. sf := &WinMain{
  52. Window: serv.Gui().FyneApp().NewWindow("Бото-ферма [wartank.ru]"),
  53. app: serv.Gui().FyneApp(),
  54. serv: serv,
  55. }
  56. green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
  57. text1 := canvas.NewText("Список ботов", green)
  58. btnAddBot := widget.NewButton("Добавить бота", sf.btnAddClick)
  59. btnExit := widget.NewButton("Выход", sf.btnExitClick)
  60. boxDown := container.NewHBox(btnAddBot, layout.NewSpacer(), btnExit)
  61. sf.entLogin = widget.NewLabel("")
  62. sf.entPass = widget.NewEntry()
  63. sf.checkAutoGame = widget.NewCheck("", sf.clickAutoGame)
  64. formLogin := &widget.Form{
  65. Items: []*widget.FormItem{ // we can specify items in the constructor
  66. {Text: "Логин", Widget: sf.entLogin},
  67. {Text: "Пароль", Widget: sf.entPass},
  68. {Text: "Авто игра", Widget: sf.checkAutoGame},
  69. },
  70. }
  71. tabLogin := container.NewTabItem("Логин", formLogin)
  72. sf.lblSpace = widget.NewLabel("======")
  73. itemSpace := widget.NewFormItem("==========", sf.lblSpace)
  74. { // Левая колонка статистики
  75. sf.lblFuel = widget.NewLabel("0")
  76. itemFuel := widget.NewFormItem("Топливо", sf.lblFuel)
  77. sf.lblGold = widget.NewLabel("0")
  78. itemGold := widget.NewFormItem("Золото", sf.lblGold)
  79. sf.lblSilver = widget.NewLabel("0")
  80. itemSilver := widget.NewFormItem("Серебро", sf.lblSilver)
  81. sf.lblGlory = widget.NewLabel("0")
  82. itemGlory := widget.NewFormItem("Слава", sf.lblGlory)
  83. sf.lblRuda = widget.NewLabel("0")
  84. itemRuda := widget.NewFormItem("Руда", sf.lblRuda)
  85. sf.lblFerrum = widget.NewLabel("0")
  86. itemFerrum := widget.NewFormItem("Железо", sf.lblFerrum)
  87. sf.lblSteel = widget.NewLabel("0")
  88. itemSteel := widget.NewFormItem("Сталь", sf.lblSteel)
  89. sf.lblPlumbum = widget.NewLabel("0")
  90. itemPlumbum := widget.NewFormItem("Свинец", sf.lblPlumbum)
  91. sf.frmStatLeft = widget.NewForm(itemFuel, itemGold, itemSilver, itemGlory, itemSpace, itemRuda, itemFerrum, itemSteel, itemPlumbum)
  92. }
  93. { // Правая колонка статистики
  94. sf.lblAtack = widget.NewLabel("0")
  95. itemAtack := widget.NewFormItem("Атака", sf.lblAtack)
  96. sf.lblArmor = widget.NewLabel("0")
  97. itemArmor := widget.NewFormItem("Броня", sf.lblArmor)
  98. sf.lblFyne = widget.NewLabel("0")
  99. itemFyne := widget.NewFormItem("Точность", sf.lblFyne)
  100. sf.lblHard = widget.NewLabel("0")
  101. itemHard := widget.NewFormItem("Прочность", sf.lblHard)
  102. sf.lblPower = widget.NewLabel("0")
  103. itemPower := widget.NewFormItem("Мощь", sf.lblPower)
  104. sf.lblForce = widget.NewLabel("None")
  105. itemForce := widget.NewFormItem("Усилено", sf.lblForce)
  106. sf.frmStatRight = widget.NewForm(itemAtack, itemArmor, itemFyne, itemHard, itemSpace, itemPower, itemForce)
  107. }
  108. hStat := container.NewHBox(sf.frmStatLeft, sf.frmStatRight)
  109. tabStat := container.NewTabItem("Статистика", hStat)
  110. // Вкладка базы
  111. itemPolygon := widget.NewFormItem("Полигон", nil)
  112. sf.lblPolygonTime = widget.NewLabel("00:00:00")
  113. itemPolygonTime := widget.NewFormItem("Время", sf.lblPolygonTime)
  114. frmPolygon := widget.NewForm(itemPolygon, itemPolygonTime)
  115. vBase`
  116. ` := container.NewVBox(frmPolygon)
  117. tabBase := container.NewTabItem("База", vBase)
  118. sf.tabBot = container.NewAppTabs(tabLogin, tabStat, tabBase)
  119. sf.boxLeft = container.NewVBox(text1)
  120. boxBorder := container.NewBorder(nil, nil, sf.boxLeft, nil, sf.boxLeft, sf.tabBot)
  121. boxMain := container.NewBorder(nil, boxDown, nil, nil, boxBorder)
  122. sf.Resize(fyne.NewSize(640, 480))
  123. { // Получить список всех ботов
  124. lstBots := sf.serv.ServBots().ListBot()
  125. for _, bot := range lstBots {
  126. sf.botLogin = bot.Name()
  127. sf.addBot()
  128. }
  129. }
  130. sf.SetContent(boxMain)
  131. go sf.showStat()
  132. return sf, nil
  133. }
  134. // Обнуляет вкладку статистики бота, если её невозможно получить
  135. func (sf *WinMain) resetStat() {
  136. { // Левый фрейм статы
  137. sf.lblFuel.SetText("0")
  138. sf.lblGold.SetText("0")
  139. sf.lblSilver.SetText("0")
  140. sf.lblGlory.SetText("0")
  141. sf.lblRuda.SetText("0")
  142. sf.lblFerrum.SetText("0")
  143. sf.lblSteel.SetText("0")
  144. sf.lblPlumbum.SetText("0")
  145. }
  146. { // Правый фрейм статы
  147. sf.lblAtack.SetText("0")
  148. sf.lblArmor.SetText("0")
  149. sf.lblFyne.SetText("0")
  150. sf.lblHard.SetText("0")
  151. sf.lblPower.SetText("0")
  152. sf.lblForce.SetText("None")
  153. }
  154. { // Вкладка базы
  155. sf.lblPolygonTime.SetText("00:00:00")
  156. }
  157. }
  158. // Показывает статистику бота
  159. func (sf *WinMain) showStat() {
  160. for {
  161. time.Sleep(time.Millisecond * 500)
  162. sf.botLogin = sf.entLogin.Text
  163. if sf.botLogin == "" {
  164. continue
  165. }
  166. bot := sf.serv.ServBots().Get(sf.botLogin)
  167. if !bot.IsRun() {
  168. log.Printf("WinMain.showStat(): base==nil")
  169. sf.resetStat()
  170. continue
  171. }
  172. { // Левый фрейм статы
  173. sf.lblFuel.Text = fmt.Sprint(bot.Angar().Fuel().Get())
  174. sf.lblFuel.Refresh()
  175. sf.lblGold.Text = fmt.Sprint(bot.Angar().Gold().Get())
  176. sf.lblGold.Refresh()
  177. strSilver := fmt.Sprint(bot.Angar().SilverAll().Get())
  178. strSlv := ""
  179. i := 0
  180. for i0 := len(strSilver) - 1; i0 >= 0; i0-- {
  181. run := string(strSilver[i0])
  182. if i == 3 {
  183. strSlv = run + "_" + strSlv
  184. i = 0
  185. continue
  186. }
  187. strSlv = run + strSlv
  188. i++
  189. }
  190. sf.lblSilver.Text = strSlv
  191. sf.lblSilver.Refresh()
  192. sf.lblGlory.Text = fmt.Sprint(bot.Angar().Convoy().Glory().Get())
  193. sf.lblGlory.Refresh()
  194. sf.lblRuda.Text = fmt.Sprint(bot.Angar().Base().Mine().Ruda().Get())
  195. sf.lblRuda.Refresh()
  196. sf.lblFerrum.Text = fmt.Sprint(bot.Angar().Base().Mine().Ferrum().Get())
  197. sf.lblFerrum.Refresh()
  198. sf.lblSteel.Text = fmt.Sprint(bot.Angar().Base().Mine().Steel().Get())
  199. sf.lblSteel.Refresh()
  200. sf.lblPlumbum.Text = fmt.Sprint(bot.Angar().Base().Mine().Plumbum().Get())
  201. sf.lblPlumbum.Refresh()
  202. }
  203. { // Правый фрейм статы
  204. sf.lblAtack.Text = fmt.Sprint(bot.Tank().TankStat().Attack().Get())
  205. sf.lblAtack.Refresh()
  206. sf.lblArmor.Text = fmt.Sprint(bot.Tank().TankStat().Armor().Get())
  207. sf.lblArmor.Refresh()
  208. sf.lblFyne.Text = fmt.Sprint(bot.Tank().TankStat().Fyne().Get())
  209. sf.lblFyne.Refresh()
  210. sf.lblHard.Text = fmt.Sprint(bot.Tank().TankStat().Hard().Get())
  211. sf.lblHard.Refresh()
  212. sf.lblPower.Text = fmt.Sprint(bot.Tank().TankStat().Power().Get())
  213. sf.lblPower.Refresh()
  214. strForce := fmt.Sprintf("%v (+%v)", bot.Tank().TankStat().Force().Name(), bot.Tank().TankStat().Force().Get())
  215. sf.lblForce.SetText(strForce)
  216. }
  217. { // Вкладка базы
  218. if bot.Angar().Base().Polygon() == nil {
  219. continue
  220. }
  221. polyTime := bot.Angar().Base().Polygon().CountDown().String()
  222. sf.lblPolygonTime.SetText(polyTime)
  223. }
  224. }
  225. }
  226. // Выставляет признак автоматического начала игры при запуске бото-фермы
  227. func (sf *WinMain) clickAutoGame(isAutoGame bool) {
  228. log.Printf("WinMain.clickAutoGame(): login:%q\t isAutoGame=%v\n", sf.entLogin.Text, isAutoGame)
  229. sf.botLogin = sf.entLogin.Text
  230. if sf.botLogin == "" {
  231. sf.checkAutoGame.Checked = false
  232. return
  233. }
  234. // Сохранить автозапуск бота
  235. bot := sf.serv.ServBots().Get(sf.botLogin)
  236. switch isAutoGame {
  237. case true: // Автозапуск бота
  238. bot.SetAutoGame()
  239. default:
  240. bot.ResetAutoGame()
  241. }
  242. }
  243. func (sf *WinMain) btnAddClick() {
  244. log.Println("WinMain.btnAddclick()")
  245. winAddBot := sf.app.NewWindow("Новый бот")
  246. entLogin := widget.NewEntry()
  247. entPass := widget.NewEntry()
  248. form := &widget.Form{
  249. Items: []*widget.FormItem{ // we can specify items in the constructor
  250. {Text: "Логин", Widget: entLogin},
  251. {Text: "Пароль", Widget: entPass},
  252. },
  253. OnSubmit: func() { // optional, handle form submission
  254. sf.botLogin = entLogin.Text
  255. sf.botPass = entPass.Text
  256. winAddBot.Close()
  257. go sf.addBot()
  258. },
  259. }
  260. winAddBot.Resize(fyne.NewSize(640, 480))
  261. winAddBot.SetContent(form)
  262. winAddBot.Show()
  263. }
  264. // Добавляет бота на экран
  265. func (sf *WinMain) addBot() {
  266. log.Printf("WinMain.addBot(): %q\n", sf.botLogin)
  267. err := sf.serv.ServBots().AddBot(sf.botLogin, sf.botPass)
  268. if err != nil {
  269. log.Printf("WinMain.addBot().OnSubmit(): in add bot to ferma, err=\n\t%v\n", err)
  270. return
  271. }
  272. btnBot := widget.NewButton(sf.botLogin, sf.btnBotClick())
  273. sf.boxLeft.Add(btnBot)
  274. }
  275. // Показывает данные своего бота при клике на соответствующей кнопке
  276. func (sf *WinMain) btnBotClick() func() {
  277. log.Println("WinMain.btnBotClick()")
  278. _botLogin := sf.botLogin
  279. bot := sf.serv.ServBots().Get(_botLogin)
  280. _botPass := bot.Pass()
  281. return func() {
  282. log.Printf("btnBotClick().fn(): botName=%q\tbotPass=%q\tisAuto=%v\n", _botLogin, _botPass, bot.IsAutoGame())
  283. // Заполнить данными вкладки своего бота
  284. sf.entLogin.Text = _botLogin
  285. sf.entLogin.Refresh()
  286. sf.entPass.Text = _botPass
  287. sf.entPass.Refresh()
  288. sf.checkAutoGame.SetChecked(bot.IsAutoGame())
  289. sf.resetStat()
  290. }
  291. }
  292. func (sf *WinMain) btnExitClick() {
  293. log.Println("WinMain.btnExitClick()")
  294. sf.Close()
  295. sf.app.Quit()
  296. sf.serv.CancelApp()
  297. }