mirror of
https://github.com/cjdenio/crossword.git
synced 2026-10-03 11:06:19 +00:00
89 lines
1.6 KiB
Go
89 lines
1.6 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.NewState(puzzle)
|
|
|
|
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))
|
|
}
|