diff --git a/internal/nethack/nethack.go b/internal/nethack/nethack.go index 1dbc56c..4bcd79c 100644 --- a/internal/nethack/nethack.go +++ b/internal/nethack/nethack.go @@ -1,63 +1,14 @@ package nethack import ( - "fmt" - "io" - "os/exec" - - "github.com/creack/pty" "github.com/gliderlabs/ssh" - "github.com/rs/zerolog/log" - "go.xsfx.dev/samurai/internal/tools" + "go.xsfx.dev/samurai/internal/terminal" ) func Nethack(s ssh.Session) { - cmd := exec.Command("nethack") - ptyReq, winCh, isPty := s.Pty() - - // nolint: nestif - if isPty { - cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyReq.Term)) - - f, err := pty.Start(cmd) - if err != nil { - panic(err) - } - - go func() { - for win := range winCh { - tools.SetWinsize(f, win.Width, win.Height) - } - }() - - go func() { - // STDIN. - _, err := io.Copy(f, s) - if err != nil { - log.Error().Msgf("could not copy STDIN: %s", err.Error()) - } - }() - - // STDOUT. - _, err = io.Copy(s, f) - if err != nil { - log.Error().Msgf("could not copy STDOUT: %s", err.Error()) - } - - if err := cmd.Wait(); err != nil { - log.Error().Msgf("could not wait: %s", err.Error()) - } - - // This is needed that it doesnt need double input after quitting nethack. - f.Close() - } else { - _, err := io.WriteString(s, "No PTY requested.\n") - if err != nil { - log.Error().Msgf("could not write: %s", err.Error()) - } - - if err := s.Exit(1); err != nil { - log.Error().Msgf("could not exit: %s", err.Error()) - } - } + terminal.Run(s, "nethack") +} + +func Highscore(s ssh.Session) { + terminal.Run(s, "nethack", "-s") } diff --git a/internal/router/router.go b/internal/router/router.go index 9776bdb..27bcd5b 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -1,36 +1,47 @@ +// nolint: exhaustivestruct package router import ( + "io" + "github.com/gliderlabs/ssh" + "github.com/manifoldco/promptui" "github.com/rs/zerolog/log" "go.xsfx.dev/samurai/internal/nethack" - "golang.org/x/term" ) func Router(s ssh.Session) { - term := term.NewTerminal(s, "> ") + prompt := promptui.Select{ + Label: "What do you wanna do?", + Items: []string{"play", "edit", "highscore", "quit"}, + Stdout: s, + Stdin: s, + } - for { - line, err := term.ReadLine() + done := false + for !done { + _, result, err := prompt.Run() if err != nil { - log.Error().Msgf("could not read line: %s", err.Error()) - - break + log.Error().Msg(err.Error()) } - log.Debug().Msgf("got input: %s", line) + log.Debug().Msgf("got %s", result) - if line == "q" { - term.Write([]byte("goodbye...\n")) + switch result { + case "quit": + _, err := io.WriteString(s, "goodbye!\n") + if err != nil { + log.Error().Msg(err.Error()) + } - break - } - - if line == "nethack" { + done = true + case "play": nethack.Nethack(s) + case "highscore": + nethack.Highscore(s) + default: + continue } - - term.Write([]byte("hello world\n")) } log.Info().Msg("terminal closed") diff --git a/internal/terminal/terminal.go b/internal/terminal/terminal.go new file mode 100644 index 0000000..c73bdff --- /dev/null +++ b/internal/terminal/terminal.go @@ -0,0 +1,63 @@ +package terminal + +import ( + "fmt" + "io" + "os/exec" + + "github.com/creack/pty" + "github.com/gliderlabs/ssh" + "github.com/rs/zerolog/log" + "go.xsfx.dev/samurai/internal/tools" +) + +func Run(s ssh.Session, command string, arg ...string) { + cmd := exec.Command(command, arg...) + ptyReq, winCh, isPty := s.Pty() + + // nolint: nestif + if isPty { + cmd.Env = append(cmd.Env, fmt.Sprintf("TERM=%s", ptyReq.Term)) + + f, err := pty.Start(cmd) + if err != nil { + panic(err) + } + + go func() { + for win := range winCh { + tools.SetWinsize(f, win.Width, win.Height) + } + }() + + go func() { + // STDIN. + _, err := io.Copy(f, s) + if err != nil { + log.Error().Msgf("could not copy STDIN: %s", err.Error()) + } + }() + + // STDOUT. + _, err = io.Copy(s, f) + if err != nil { + log.Error().Msgf("could not copy STDOUT: %s", err.Error()) + } + + if err := cmd.Wait(); err != nil { + log.Error().Msgf("could not wait: %s", err.Error()) + } + + // This is needed that it doesnt need double input after quitting nethack. + f.Close() + } else { + _, err := io.WriteString(s, "No PTY requested.\n") + if err != nil { + log.Error().Msgf("could not write: %s", err.Error()) + } + + if err := s.Exit(1); err != nil { + log.Error().Msgf("could not exit: %s", err.Error()) + } + } +}