desktop.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // package desktop -- консольный клиент для вар-танка
  2. package desktop
  3. import (
  4. "fmt"
  5. "time"
  6. "github.com/charmbracelet/bubbles/textinput"
  7. tea "github.com/charmbracelet/bubbletea"
  8. "wartank/desktop/client_serv"
  9. "wartank/desktop/win_bots_menu"
  10. "wartank/desktop/win_config"
  11. "wartank/desktop/win_config_server"
  12. "wartank/desktop/win_config_server_host_input"
  13. "wartank/desktop/win_config_server_login_input"
  14. "wartank/desktop/win_config_server_pass_input"
  15. "wartank/desktop/win_default"
  16. "wartank/desktop/win_server_connect"
  17. "wartank/pkg/alias"
  18. "wartank/pkg/cons"
  19. "wartank/pkg/types"
  20. )
  21. // Desktop -- консольный клиент для вар-танка
  22. type Desktop struct {
  23. TeaModel
  24. winName alias.AWinName // Режим показа на экране
  25. p *tea.Program // Объект приложения
  26. client *client_serv.ClientServ // Клиент подключния к бото-серверу
  27. isConnect bool // Признак подключения к бот-серверу
  28. isLogin bool // Признак логина на сервер
  29. isMakeAdmin bool // Признак создания админа
  30. dictWin map[alias.AWinName]types.ITermWin // Список окон показа
  31. }
  32. var desk *Desktop
  33. func NewDesktop() (*Desktop, error) {
  34. sf := &Desktop{
  35. client: client_serv.NewClientServ(),
  36. dictWin: make(map[alias.AWinName]types.ITermWin),
  37. }
  38. sf.TeaModel = NewModel()
  39. sf.p = tea.NewProgram(sf, tea.WithAltScreen(), tea.WithANSICompressor())
  40. desk = sf
  41. { // Создание окон
  42. { // WinDefault
  43. winDefault, err := win_default.NewWinDefault(sf)
  44. if err != nil {
  45. return nil, fmt.Errorf("NewDesktop(): in create WinDefault, err=\n\t%w", err)
  46. }
  47. sf.dictWin[winDefault.Name()] = winDefault
  48. }
  49. { // WinConfig
  50. winConfig, err := win_config.NewWinConfig(sf)
  51. if err != nil {
  52. return nil, fmt.Errorf("NewDesktop(): in create WinConfig, err=\n\t%w", err)
  53. }
  54. sf.dictWin[winConfig.Name()] = winConfig
  55. }
  56. { // WinConfigServer
  57. winConfigServer, err := win_config_server.NewWinConfigServer(sf)
  58. if err != nil {
  59. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServer, err=\n\t%w", err)
  60. }
  61. sf.dictWin[winConfigServer.Name()] = winConfigServer
  62. }
  63. { // WinConfigServerHostInput
  64. winConfigServerHostInput, err := win_config_server_host_input.NewWinConfigServerHostInput(sf)
  65. if err != nil {
  66. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerHostInput, err=\n\t%w", err)
  67. }
  68. sf.dictWin[winConfigServerHostInput.Name()] = winConfigServerHostInput
  69. }
  70. { // WinConfigServerLoginInput
  71. winConfigServerLoginInput, err := win_config_server_login_input.NewWinConfigServerLoginInput(sf)
  72. if err != nil {
  73. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerLoginInput, err=\n\t%w", err)
  74. }
  75. sf.dictWin[winConfigServerLoginInput.Name()] = winConfigServerLoginInput
  76. }
  77. { // WinConfigServerPassInput
  78. winConfigServerPassInput, err := win_config_server_pass_input.NewWinConfigServerPasswordInput(sf)
  79. if err != nil {
  80. return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerPasswordInput, err=\n\t%w", err)
  81. }
  82. sf.dictWin[winConfigServerPassInput.Name()] = winConfigServerPassInput
  83. }
  84. { // WinServerConnect
  85. winServerConnect, err := win_server_connect.NewWinServerConnect(sf)
  86. if err != nil {
  87. return nil, fmt.Errorf("NewDesktop(): in create WinServerConnect, err=\n\t%w", err)
  88. }
  89. sf.dictWin[winServerConnect.Name()] = winServerConnect
  90. }
  91. { // WinBotsMenu
  92. winBotsMenu, err := win_bots_menu.NewWinBotsMenu(sf)
  93. if err != nil {
  94. return nil, fmt.Errorf("NewDesktop(): in create WinBotsMenu, err=\n\t%w", err)
  95. }
  96. sf.dictWin[winBotsMenu.Name()] = winBotsMenu
  97. }
  98. }
  99. sf.winName = cons.WinDefault
  100. go sf.tick()
  101. return sf, nil
  102. }
  103. // SetWin -- устанавливает главное окно
  104. func (sf *Desktop) SetWin(winName alias.AWinName) {
  105. sf.winName = winName
  106. }
  107. type TeaModel struct {
  108. textInput textinput.Model
  109. host string // Имя хоста сервера (с портом)
  110. login string // Логин для сервера
  111. pass string // Пароль для сервера
  112. }
  113. func NewModel() TeaModel {
  114. ti := textinput.New()
  115. ti.Placeholder = "localhost"
  116. ti.Focus()
  117. ti.CharLimit = 156
  118. ti.Width = 20
  119. m := TeaModel{
  120. textInput: ti,
  121. }
  122. return m
  123. }
  124. func (sf *Desktop) tick() {
  125. for {
  126. time.Sleep(time.Second * 1)
  127. msg := tea.MouseEvent{}
  128. // m.Update(msg)
  129. sf.p.Send(msg)
  130. }
  131. }
  132. // Run -- запускает в работу консольный клиент
  133. func (sf *Desktop) Run() error {
  134. if _, err := sf.p.Run(); err != nil {
  135. return fmt.Errorf("Deskto.Run(): err=\n\t%w", err)
  136. }
  137. return nil
  138. }
  139. // Init -- инициализация перед запуском главного цикла
  140. func (sf *Desktop) Init() tea.Cmd {
  141. // Просто вернуть `nil`, т.е. никаких команд
  142. return textinput.Blink
  143. }
  144. // Update -- обновление консоли по требованию
  145. func (sf *Desktop) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  146. var cmd tea.Cmd
  147. switch msg := msg.(type) {
  148. // Может клавиша нажата
  149. case tea.KeyMsg:
  150. switch msg.String() { // Да, нажато, а что именно?
  151. case "ctrl+q": // Надо выйти из программы
  152. return sf, tea.Quit
  153. }
  154. }
  155. mod_, cmd_ := sf.dictWin[sf.winName].Update(msg)
  156. if mod_ != nil {
  157. return mod_, cmd_
  158. }
  159. /*
  160. case ModeShowMenuBot:
  161. // Может клавиша нажата
  162. switch msg := msg.(type) {
  163. case tea.KeyMsg:
  164. switch msg.String() { // Да, нажато, а что именно?
  165. case "esc": // Нажатие "esc" прекращает показ меню
  166. desk.winName = ModeConfig
  167. }
  168. }
  169. // Возвращает обновлённую модель дляe Bubble Tea runtime для обработки.
  170. //Здесь команду возвращать надо.
  171. */
  172. return desk, cmd
  173. }
  174. func (sf *Desktop) View() string {
  175. s := time.Now().Local().Format("[ WarTank ] = 2006-01-02 15:04:05.000")
  176. s += fmt.Sprintf("\tХост=%q\tЛогин=%q\tПароль=%q\tПодключено=%v\tЛогин=%v\tЕстьАдмин=%v\n\n", desk.host, desk.login, desk.pass, desk.isConnect, desk.isLogin, desk.isMakeAdmin)
  177. s += desk.dictWin[desk.winName].View()
  178. /*
  179. case ModeShowMenuBot: // Меню бото-фермы
  180. s += desk.winMenuBotoFerma()
  181. }
  182. */
  183. return s
  184. }
  185. // IsLogin -- возвращает признак логина на сервер ботов
  186. func (sf *Desktop) IsLogin() bool {
  187. return sf.isLogin
  188. }
  189. // IsConnect -- возвращает признак подключения на сервер ботов
  190. func (sf *Desktop) IsConnect() bool {
  191. return sf.isConnect
  192. }
  193. // SetHost -- устанавливает имя хоста бото-фермы
  194. func (sf *Desktop) SetHost(hostName string) {
  195. sf.host = hostName
  196. }
  197. // SetLogin -- устанавливает логин бото-фермы
  198. func (sf *Desktop) SetLogin(login string) {
  199. sf.login = login
  200. }
  201. // SetPass -- устанавливает пароль бото-фермы
  202. func (sf *Desktop) SetPass(password string) {
  203. sf.pass = password
  204. }
  205. // Connect -- подключает клиент к бото-ферме
  206. func (sf *Desktop) Connect() error {
  207. err := sf.client.Connect(sf.host)
  208. sf.isConnect = false
  209. if err != nil {
  210. return fmt.Errorf("Desktop.Connect(): err=\n\t%v", err)
  211. }
  212. sf.isConnect = true
  213. return nil
  214. }
  215. // MakeLogin -- выполняет вход на бото-ферму
  216. func (sf *Desktop) MakeLogin() error {
  217. err := sf.client.Login(sf.login, sf.pass)
  218. sf.isLogin = false
  219. if err != nil {
  220. return fmt.Errorf("Desktop.MakeLogin(): in login to server, err=\n\t%v", err)
  221. }
  222. sf.isLogin = true
  223. return nil
  224. }