desktop.go 9.3 KB

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