// package desktop -- консольный клиент для вар-танка package desktop import ( "fmt" "log" "os" "time" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "wartank/desktop/client_serv" "wartank/desktop/config" "wartank/desktop/win_bots_add_login" "wartank/desktop/win_bots_add_pass" "wartank/desktop/win_bots_list" "wartank/desktop/win_bots_menu" "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/desktop/win_server_login" "wartank/pkg/alias" "wartank/pkg/bot" "wartank/pkg/cons" "wartank/pkg/types" ) // Desktop -- консольный клиент для вар-танка type Desktop struct { conf *config.Config winName alias.AWinName // Режим показа на экране p *tea.Program // Объект приложения client *client_serv.ClientServ // Клиент подключния к бото-серверу isConnect bool // Признак подключения к бот-серверу isLogin bool // Признак логина на сервер dictWin map[alias.AWinName]types.ITermWin // Список окон показа botCurrent *bot.Bot } // var desk *Desktop func NewDesktop() (*Desktop, error) { sf := &Desktop{ client: client_serv.NewClientServ(), dictWin: make(map[alias.AWinName]types.ITermWin), conf: config.NewConfig(), botCurrent: &bot.Bot{}, } sf.p = tea.NewProgram(sf, tea.WithAltScreen(), tea.WithANSICompressor()) { // Создание окон { // 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 } { // WinServerLogin winServerLogin, err := win_server_login.NewWinServerLogin(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinServerLogin, err=\n\t%w", err) } sf.dictWin[winServerLogin.Name()] = winServerLogin } { // WinBotsMenu winBotsMenu, err := win_bots_menu.NewWinBotsMenu(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinBotsMenu, err=\n\t%w", err) } sf.dictWin[winBotsMenu.Name()] = winBotsMenu } { // WinBotsAddLogin winBotsAddLogin, err := win_bots_add_login.NewWinBotsAddLogin(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinBotsAddLogin, err=\n\t%w", err) } sf.dictWin[winBotsAddLogin.Name()] = winBotsAddLogin } { // WinBotsAddPass winBotsAddPass, err := win_bots_add_pass.NewWinBotsAddPass(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinBotsAddPass, err=\n\t%w", err) } sf.dictWin[winBotsAddPass.Name()] = winBotsAddPass } { // WinBotsLst winBotsLst, err := win_bots_list.NewWinBotsList(sf) if err != nil { return nil, fmt.Errorf("NewDesktop(): in create WinBotsLst, err=\n\t%w", err) } sf.dictWin[winBotsLst.Name()] = winBotsLst } } sf.winName = cons.WinDefault go sf.tick() return sf, nil } // SetWin -- устанавливает главное окно func (sf *Desktop) SetWin(winName alias.AWinName) { sf.winName = winName } 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_, _ := sf.dictWin[sf.winName].Update(msg) if mod_ != nil { return sf, nil } return sf, cmd } func (sf *Desktop) View() string { _ = tea.ClearScreen() _s := fmt.Sprintf("Desktop.View(): winName=%q\n", sf.winName) os.WriteFile("./out.log", []byte(_s), 0600) 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\n\n", sf.conf.Host_, sf.conf.Login_, sf.conf.Pass_, sf.isConnect, sf.isLogin) s += _s + sf.dictWin[sf.winName].View() + "\n\n\n\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.conf.Host_ = hostName sf.conf.Save() } // SetLogin -- устанавливает логин бото-фермы func (sf *Desktop) SetLogin(login string) { sf.conf.Login_ = login sf.conf.Save() } // SetPass -- устанавливает пароль бото-фермы func (sf *Desktop) SetPass(password string) { sf.conf.Pass_ = password sf.conf.Save() } // Connect -- подключает клиент к бото-ферме func (sf *Desktop) Connect() error { err := sf.client.Connect(sf.conf.Host_) sf.isConnect = false if err != nil { return fmt.Errorf("Desktop.Connect(): err=\n\t%v", err) } sf.isConnect = true return nil } // MakeLogin -- выполняет вход на бото-ферму func (sf *Desktop) MakeLogin() error { err := sf.client.Login(sf.conf.Login_, sf.conf.Pass_) sf.isLogin = false if err != nil { return fmt.Errorf("Desktop.MakeLogin(): in login to server, err=\n\t%v", err) } sf.isLogin = true return nil } // SetBotLogin -- устанавливает логин текущего бота func (sf *Desktop) SetBotLogin(login string) { sf.botCurrent.Login_ = login } // SetBotPass -- устанавливает пароль текущего бота func (sf *Desktop) SetBotPass(password string) { sf.botCurrent.Pass_ = password for _, bot_ := range sf.conf.ListBot_ { if bot_.Login_ == sf.botCurrent.Login_ { return } } err := sf.client.AddBot(sf.botCurrent.Login_, password) if err != nil { log.Printf("Desktop.SetBotPass(): in make request, err=\n\t%v\n", err) return } botNew := &bot.Bot{ Login_: sf.botCurrent.Login_, Pass_: password, } sf.conf.ListBot_ = append(sf.conf.ListBot_, botNew) sf.conf.Save() } // LstBot -- список ботов из десктоп-клиента func (sf *Desktop) LstBot() []*bot.Bot { return sf.conf.ListBot_ } // CurrentBotStart -- стартует текущего бота func (sf *Desktop) CurrentBotStart() { sf.client.BotStart(sf.botCurrent.Login_) }