adds login menu and command abstraction

This commit is contained in:
Marvin Steadfast 2021-02-11 14:01:52 +01:00
parent c41f97ed40
commit 4d0713055b
3 changed files with 96 additions and 71 deletions

View File

@ -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")
}

View File

@ -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"))
break
switch result {
case "quit":
_, err := io.WriteString(s, "goodbye!\n")
if err != nil {
log.Error().Msg(err.Error())
}
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")

View File

@ -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())
}
}
}