// package desktop -- консольный клиент для вар-танка package desktop import ( "fmt" "time" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "wartank/desktop/client_serv" "wartank/desktop/win_config" "wartank/desktop/win_config_server" "wartank/desktop/win_config_server_host_input" "wartank/desktop/win_config_server_login_input" "wartank/desktop/win_config_server_pass_input" "wartank/desktop/win_default" "wartank/desktop/win_server_connect" "wartank/pkg/alias" "wartank/pkg/cons" "wartank/pkg/types" ) // Desktop -- консольный клиент для вар-танка type Desktop struct { TeaModel winName alias.AWinName // Режим показа на экране p *tea.Program // Объект приложения client *client_serv.ClientServ // Клиент подключния к бото-серверу isConnect bool // Признак подключения к бот-серверу isLogin bool // Признак логина на сервер isMakeAdmin bool // Признак создания админа dictWin map[alias.AWinName]types.ITermWin // Список окон показа } var desk *Desktop func NewDesktop() (*Desktop, error) { sf := &Desktop{ client: client_serv.NewClientServ(), dictWin: make(map[alias.AWinName]types.ITermWin), } sf.TeaModel = NewModel() sf.p = tea.NewProgram(sf, tea.WithAltScreen(), tea.WithANSICompressor()) desk = sf { // Создание окон { // WinDefault winDefault, err := win_default.NewWinDefault(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinDefault, err=\n\t%w", err) } sf.dictWin[winDefault.Name()] = winDefault } { // WinConfig winConfig, err := win_config.NewWinConfig(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinConfig, err=\n\t%w", err) } sf.dictWin[winConfig.Name()] = winConfig } { // WinConfigServer winConfigServer, err := win_config_server.NewWinConfigServer(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinConfigServer, err=\n\t%w", err) } sf.dictWin[winConfigServer.Name()] = winConfigServer } { // WinConfigServerHostInput winConfigServerHostInput, err := win_config_server_host_input.NewWinConfigServerHostInput(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerHostInput, err=\n\t%w", err) } sf.dictWin[winConfigServerHostInput.Name()] = winConfigServerHostInput } { // WinConfigServerLoginInput winConfigServerLoginInput, err := win_config_server_login_input.NewWinConfigServerLoginInput(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerLoginInput, err=\n\t%w", err) } sf.dictWin[winConfigServerLoginInput.Name()] = winConfigServerLoginInput } { // WinConfigServerPassInput winConfigServerPassInput, err := win_config_server_pass_input.NewWinConfigServerPasswordInput(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinConfigServerPasswordInput, err=\n\t%w", err) } sf.dictWin[winConfigServerPassInput.Name()] = winConfigServerPassInput } { // WinServerConnect winServerConnect, err := win_server_connect.NewWinServerConnect(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinServerConnect, err=\n\t%w", err) } sf.dictWin[winServerConnect.Name()] = winServerConnect } } sf.winName = cons.WinDefault go sf.tick() return sf, nil } // SetWin -- устанавливает главное окно func (sf *Desktop) SetWin(winName alias.AWinName) { sf.winName = winName } type TeaModel struct { textInput textinput.Model host string // Имя хоста сервера (с портом) login string // Логин для сервера pass string // Пароль для сервера } func NewModel() TeaModel { ti := textinput.New() ti.Placeholder = "localhost" ti.Focus() ti.CharLimit = 156 ti.Width = 20 m := TeaModel{ textInput: ti, } return m } func (sf *Desktop) tick() { for { time.Sleep(time.Second * 1) msg := tea.MouseEvent{} // m.Update(msg) sf.p.Send(msg) } } // Run -- запускает в работу консольный клиент func (sf *Desktop) Run() error { if _, err := sf.p.Run(); err != nil { return fmt.Errorf("Deskto.Run(): err=\n\t%w", err) } return nil } // Init -- инициализация перед запуском главного цикла func (sf *Desktop) Init() tea.Cmd { // Просто вернуть `nil`, т.е. никаких команд return textinput.Blink } // Update -- обновление консоли по требованию func (sf *Desktop) Update(msg tea.Msg) (tea.Model, tea.Cmd) { var cmd tea.Cmd switch msg := msg.(type) { // Может клавиша нажата case tea.KeyMsg: switch msg.String() { // Да, нажато, а что именно? case "ctrl+q": // Надо выйти из программы return sf, tea.Quit } } mod_, cmd_ := sf.dictWin[sf.winName].Update(msg) if mod_ != nil { return mod_, cmd_ } /* case ModeLoginServer: switch msg := msg.(type) { // Может клавиша нажата case tea.KeyMsg: switch msg.String() { // Да, нажато, а что именно? case "esc": // Нажатие "esc" прекращает логин на сервер desk.winName = ModeConfig } } case ModeServerMakeAdmin: switch msg := msg.(type) { // Может клавиша нажата case tea.KeyMsg: switch msg.String() { // Да, нажато, а что именно? case "esc": // Нажатие "esc" прекращает создание админа desk.winName = ModeConfig } } case ModeShowMenuBot: // Может клавиша нажата switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { // Да, нажато, а что именно? case "esc": // Нажатие "esc" прекращает показ меню desk.winName = ModeConfig } } // Возвращает обновлённую модель дляe Bubble Tea runtime для обработки. //Здесь команду возвращать надо. */ return desk, cmd } func (sf *Desktop) View() string { s := time.Now().Local().Format("[ WarTank ] = 2006-01-02 15:04:05.000") 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) s += desk.dictWin[desk.winName].View() /* switch desk.winName { case ModeLoginServer: // Режим логина на сервер s += desk.winServerLogin() case ModeServerMakeAdmin: // Режим содания админа на бот-сервере s += desk.winServerMakeAdmin() case ModeShowMenuBot: // Меню бото-фермы s += desk.winMenuBotoFerma() } */ return s } /* func (sf *Desktop) winMenuBotoFerma() string { s := "=Меню бото-фермы вар-танк=\n\n" s += "[1]-Список ботов\n" s += "[2]-Добавить бота\n" s += "[3]-Удалить бота\n" s += "\n\n[ctrl+q]-выход [esc]-отмена\n" return s } func (sf *Desktop) winServerMakeAdmin() string { s := "=Создание админа на бот-сервере вар-танк=\n\n" if !desk.isMakeAdmin { err := desk.client.MakeAdmin(desk.pass) if err != nil { s += fmt.Sprintf("Desktop.winServerMakeAdmin(): err=\n\t%v", err) s += "\n\n[ctrl+q]-выход [esc]-отмена\n" return s } } s += "Desktop.winServerMakeAdmin(): ok\n" desk.isMakeAdmin = true s += "\n\n[ctrl+q]-выход [esc]-отмена\n" return s } func (sf *Desktop) winServerLogin() string { s := "=Логин на бот-сервер вар-танк=\n\n" err := desk.client.Login(desk.login, desk.pass) if err != nil { s += fmt.Sprintf("Desktop.winServerLogin(): err=\n\t%v", err) s += "\n\n[ctrl+q]-выход [esc]-отмена\n" return s } s += "Desktop.winServerLogin(): ok\n" desk.isLogin = true s += "\n\n[ctrl+q]-выход [esc]-отмена\n" return s } */ // IsLogin -- возвращает признак логина на сервер ботов func (sf *Desktop) IsLogin() bool { return sf.isLogin } // IsConnect -- возвращает признак подключения на сервер ботов func (sf *Desktop) IsConnect() bool { return sf.isConnect } // SetHost -- устанавливает имя хоста бото-фермы func (sf *Desktop) SetHost(hostName string) { sf.host = hostName } // SetLogin -- устанавливает логин бото-фермы func (sf *Desktop) SetLogin(login string) { sf.login = login } // SetPass -- устанавливает пароль бото-фермы func (sf *Desktop) SetPass(password string) { sf.pass = password } // Connect -- подключает клиент к бото-ферме func (sf *Desktop) Connect() error { err := sf.client.Connect(sf.host) sf.isConnect = false if err != nil { return fmt.Errorf("Desktop.Connect(): err=\n\t%v", err) } sf.isConnect = true return nil }