diff options
| author | historia <[not public]> | 2026-09-18 17:48:26 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-18 17:48:26 -0400 |
| commit | 8fe9e3c3fef0049df82281a62afe35dda516dfe2 (patch) | |
| tree | dd269f2c0710f334e19f00a191260ebc46284a90 /internal/net/conn.go | |
| parent | 194164a77eb4f2479b94c19e6f0e1278ab608781 (diff) | |
| download | thehouseoficarus-8fe9e3c3fef0049df82281a62afe35dda516dfe2.tar.gz | |
fix: close combat ghost, admin traversal, login throttle, journal double-pay, and quality/economy gaps
Diffstat (limited to 'internal/net/conn.go')
| -rw-r--r-- | internal/net/conn.go | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/internal/net/conn.go b/internal/net/conn.go index 42b7c41..4aa4db4 100644 --- a/internal/net/conn.go +++ b/internal/net/conn.go @@ -11,6 +11,7 @@ import ( "strings" "sync/atomic" "time" + "unicode/utf8" ) type Conn interface { @@ -72,6 +73,7 @@ func (t *tcpConn) ReadMessage() (string, error) { } text := strings.TrimRight(string(line), "\r\n") text = stripIAC(text) + text = truncateLine(text, maxLineLength) if t.echoOff.Load() { t.conn.Write([]byte("\r\n")) } @@ -82,6 +84,32 @@ func (t *tcpConn) Write(b []byte) (int, error) { return t.conn.Write(b) } +// RemoteAddr reports the peer address for the login throttle. +func (t *tcpConn) RemoteAddr() string { + if t.conn == nil { + return "" + } + return t.conn.RemoteAddr().String() +} + +// truncateLine cuts s to at most max bytes without splitting a UTF-8 rune. +// Both the telnet and websocket paths bound line length, and a byte-boundary +// cut would otherwise emit an invalid trailing rune to the game. +func truncateLine(s string, max int) string { + if max <= 0 || len(s) <= max { + return s + } + s = s[:max] + for len(s) > 0 { + r, size := utf8.DecodeLastRuneInString(s) + if r != utf8.RuneError || size > 1 { + break + } + s = s[:len(s)-1] + } + return s +} + func (t *tcpConn) SetWriteDeadline(ts time.Time) error { return t.conn.SetWriteDeadline(ts) } |
