Files
crossword/ssh/main.go
T
2026-09-11 14:35:53 -05:00

94 lines
1.7 KiB
Go

package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"github.com/cjdenio/crossword/game"
"github.com/cjdenio/crossword/puz"
"github.com/gliderlabs/ssh"
)
func main() {
file, err := os.ReadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
port := ":2222"
if portEnv, ok := os.LookupEnv("PORT"); ok && portEnv != "" {
port = ":" + portEnv
}
ssh.Handle(func(s ssh.Session) {
log.Printf("new connection from %s (username %s)\n", s.RemoteAddr().String(), s.User())
puzzle, err := puz.ParsePuz(file)
if err != nil {
log.Fatal(err)
}
state := game.State{
Puzzle: puzzle,
PuzzleState: []rune(puzzle.State),
SelectedClue: puzzle.Clues[0],
SelectedCell: puzzle.Clues[0].Cells[0],
}
io.WriteString(s, "\x1b[?25l")
defer func() {
io.WriteString(s, "\x1b[?25h")
}()
uiHeight := state.RenderUI(s)
scanner := bufio.NewScanner(s)
scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if len(data) == 0 {
return 0, nil, bufio.ErrFinalToken
}
if data[0] == 0x1b {
if len(data) < 3 {
return 0, nil, nil
}
return 3, data[0:3], nil
}
return 1, data[0:1], nil
})
for {
ok := scanner.Scan()
if !ok {
break
}
buffer := scanner.Bytes()
exited := state.HandleInput(buffer)
if exited {
state.SelectedClue = nil
state.SelectedCell = -1
fmt.Fprintf(s, "\r\x1b[%dA", uiHeight)
fmt.Fprint(s, "\x1b[J")
state.RenderUI(s)
break
}
fmt.Fprintf(s, "\r\x1b[%dA", uiHeight)
fmt.Fprint(s, "\x1b[J")
uiHeight = state.RenderUI(s)
}
log.Printf("%s disconnected\n", s.RemoteAddr().String())
})
log.Printf("starting on port %s...\n", port)
log.Fatal(ssh.ListenAndServe(port, nil))
}