Compare commits

..
4 Commits
Author SHA1 Message Date
cjdenio 644ce0d273 fix bug 2026-09-11 22:00:00 -05:00
cjdenio c1d024a97e fix text encoding for utf-8 puz files 2026-09-11 17:38:37 -05:00
cjdenio 0f1da4c461 some SSH logging 2026-09-11 14:35:53 -05:00
cjdenio e6798b1a67 jump backwards 2026-09-11 14:25:51 -05:00
5 changed files with 64 additions and 36 deletions

No files matched your search

+1 -3
View File
@@ -1,10 +1,8 @@
todo todo
- fix bug with that one 6x6 puzzle
- correctly calculate uiHeight with multi-line clues - correctly calculate uiHeight with multi-line clues
- timer - timer
- reveal grid/word - reveal grid/word
- .puz checksums - .puz checksums
- fix shift+enter / short+tab in other terminals - fix shift+enter / shift+tab in other terminals
- after entering letter, jump to next unfilled cell (even if it's backwards)
- clear grid - clear grid
+31 -15
View File
@@ -348,6 +348,23 @@ func (state *State) LoadSaveFile(f []byte) error {
return nil return nil
} }
func (state *State) SwitchDirections() bool {
switch state.SelectedClue.Direction {
case puz.DirectionAcross:
if state.Puzzle.Cells[state.SelectedCell][1] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
}
return true
case puz.DirectionDown:
if state.Puzzle.Cells[state.SelectedCell][0] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
}
return true
}
return false
}
func (state *State) HandleInput(buffer []byte) (exited bool) { func (state *State) HandleInput(buffer []byte) (exited bool) {
if len(buffer) == 0 { if len(buffer) == 0 {
return false return false
@@ -360,16 +377,7 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
} }
if buffer[0] == ' ' { if buffer[0] == ' ' {
switch state.SelectedClue.Direction { state.SwitchDirections()
case puz.DirectionAcross:
if state.Puzzle.Cells[state.SelectedCell][1] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
}
case puz.DirectionDown:
if state.Puzzle.Cells[state.SelectedCell][0] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
}
}
} }
if buffer[0] >= 0x61 && buffer[0] <= 0x7a { if buffer[0] >= 0x61 && buffer[0] <= 0x7a {
@@ -380,7 +388,7 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
if !cellWasFilled { if !cellWasFilled {
// jump to next unfilled cell in clue // jump to next unfilled cell in clue
for x := i + 1; x < len(state.SelectedClue.Cells); x++ { for x := (i + 1) % len(state.SelectedClue.Cells); x != i; x = ((x + 1) % len(state.SelectedClue.Cells)) {
if state.PuzzleState[state.SelectedClue.Cells[x]] == '-' { if state.PuzzleState[state.SelectedClue.Cells[x]] == '-' {
state.SelectedCell = state.SelectedClue.Cells[x] state.SelectedCell = state.SelectedClue.Cells[x]
break break
@@ -427,9 +435,9 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
if string(buffer[0:2]) == "\x1b[" { if string(buffer[0:2]) == "\x1b[" {
if (buffer[2] == 68 || buffer[2] == 67) && state.SelectedClue != nil && state.SelectedClue.Direction == puz.DirectionDown { if (buffer[2] == 68 || buffer[2] == 67) && state.SelectedClue != nil && state.SelectedClue.Direction == puz.DirectionDown {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0] state.SwitchDirections()
} else if (buffer[2] == 65 || buffer[2] == 66) && state.SelectedClue != nil && state.SelectedClue.Direction == puz.DirectionAcross { } else if (buffer[2] == 65 || buffer[2] == 66) && state.SelectedClue != nil && state.SelectedClue.Direction == puz.DirectionAcross {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1] state.SwitchDirections()
} else { } else {
switch buffer[2] { switch buffer[2] {
case 68: // left case 68: // left
@@ -444,9 +452,17 @@ func (state *State) HandleInput(buffer []byte) (exited bool) {
switch state.SelectedClue.Direction { switch state.SelectedClue.Direction {
case puz.DirectionAcross: case puz.DirectionAcross:
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0] if state.Puzzle.Cells[state.SelectedCell][0] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
} else {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
}
case puz.DirectionDown: case puz.DirectionDown:
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1] if state.Puzzle.Cells[state.SelectedCell][1] != nil {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][1]
} else {
state.SelectedClue = state.Puzzle.Cells[state.SelectedCell][0]
}
} }
} }
} }
-1
View File
@@ -103,7 +103,6 @@ func main() {
} }
state.SelectedClue = nil state.SelectedClue = nil
state.SelectedCell = -1 state.SelectedCell = -1
state.Goodbye = true
fmt.Printf("\r\x1b[%dA", uiHeight) fmt.Printf("\r\x1b[%dA", uiHeight)
fmt.Print("\x1b[J") fmt.Print("\x1b[J")
state.RenderUI(os.Stdout) state.RenderUI(os.Stdout)
+15 -10
View File
@@ -75,18 +75,22 @@ func startOfAcrossClue(puzzle string, width, index int) bool {
return false return false
} }
func readText(b *bufio.Reader) (string, error) { func readText(b *bufio.Reader, version string) (string, error) {
text, err := b.ReadString(0x00) text, err := b.ReadString(0x00)
if err != nil { if err != nil {
return "", err return "", err
} }
decoded, err := charmap.ISO8859_1.NewDecoder().String(text[:len(text)-1]) if version == "1" {
if err != nil { decoded, err := charmap.ISO8859_1.NewDecoder().String(text[:len(text)-1])
return "", err if err != nil {
} return "", err
}
return decoded, nil return decoded, nil
} else {
return string(text[:len(text)-1]), nil
}
} }
func ParsePuz(file []byte) (*Puzzle, error) { func ParsePuz(file []byte) (*Puzzle, error) {
@@ -99,6 +103,7 @@ func ParsePuz(file []byte) (*Puzzle, error) {
puzzle := new(Puzzle) puzzle := new(Puzzle)
// read header // read header
version := string(file[0x18:0x1B])
puzzle.Width = int(file[0x2C]) puzzle.Width = int(file[0x2C])
puzzle.Height = int(file[0x2D]) puzzle.Height = int(file[0x2D])
puzzle.ClueCount = int(binary.LittleEndian.Uint16(file[0x2E:0x30])) puzzle.ClueCount = int(binary.LittleEndian.Uint16(file[0x2E:0x30]))
@@ -116,19 +121,19 @@ func ParsePuz(file []byte) (*Puzzle, error) {
// read text // read text
buf := bufio.NewReader(bytes.NewReader(file[stateEnd:])) buf := bufio.NewReader(bytes.NewReader(file[stateEnd:]))
title, err := readText(buf) title, err := readText(buf, string(version[0]))
if err != nil { if err != nil {
return nil, err return nil, err
} }
puzzle.Title = title puzzle.Title = title
author, err := readText(buf) author, err := readText(buf, string(version[0]))
if err != nil { if err != nil {
return nil, err return nil, err
} }
puzzle.Author = author puzzle.Author = author
copyright, err := readText(buf) copyright, err := readText(buf, string(version[0]))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -137,7 +142,7 @@ func ParsePuz(file []byte) (*Puzzle, error) {
// read clues // read clues
clues := make([]string, 0, puzzle.ClueCount) clues := make([]string, 0, puzzle.ClueCount)
for range puzzle.ClueCount { for range puzzle.ClueCount {
clue, err := readText(buf) clue, err := readText(buf, string(version[0]))
if err != nil { if err != nil {
return nil, err return nil, err
} }
+17 -7
View File
@@ -13,11 +13,19 @@ import (
) )
func main() { 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) { ssh.Handle(func(s ssh.Session) {
file, err := os.ReadFile(os.Args[1]) log.Printf("new connection from %s (username %s)\n", s.RemoteAddr().String(), s.User())
if err != nil {
log.Fatal(err)
}
puzzle, err := puz.ParsePuz(file) puzzle, err := puz.ParsePuz(file)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@@ -66,11 +74,10 @@ func main() {
if exited { if exited {
state.SelectedClue = nil state.SelectedClue = nil
state.SelectedCell = -1 state.SelectedCell = -1
state.Goodbye = true
fmt.Fprintf(s, "\r\x1b[%dA", uiHeight) fmt.Fprintf(s, "\r\x1b[%dA", uiHeight)
fmt.Fprint(s, "\x1b[J") fmt.Fprint(s, "\x1b[J")
state.RenderUI(s) state.RenderUI(s)
return break
} }
fmt.Fprintf(s, "\r\x1b[%dA", uiHeight) fmt.Fprintf(s, "\r\x1b[%dA", uiHeight)
@@ -78,6 +85,9 @@ func main() {
uiHeight = state.RenderUI(s) uiHeight = state.RenderUI(s)
} }
log.Printf("%s disconnected\n", s.RemoteAddr().String())
}) })
log.Fatal(ssh.ListenAndServe(":1234", nil)) log.Printf("starting on port %s...\n", port)
log.Fatal(ssh.ListenAndServe(port, nil))
} }