mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 14:27:27 +00:00
Merge pull request #36 from profullstack/fix/arcade-ncurses-term
fix(arcade): give ncurses games a TERM so they launch
This commit is contained in:
commit
d65c2bcecb
3 changed files with 29 additions and 0 deletions
|
|
@ -406,6 +406,9 @@ func (a *app) teaHandler(s ssh.Session) (tea.Model, []tea.ProgramOption) {
|
||||||
go func() { <-s.Context().Done(); _ = a.st.EndSession(sessID) }()
|
go func() { <-s.Context().Done(); _ = a.st.EndSession(sessID) }()
|
||||||
|
|
||||||
ctx := plugin.Context{Store: a.st, Sandbox: a.sandbox, AssetsDir: a.assets, Host: a.host}
|
ctx := plugin.Context{Store: a.st, Sandbox: a.sandbox, AssetsDir: a.assets, Host: a.host}
|
||||||
|
if pty, _, ok := s.Pty(); ok {
|
||||||
|
ctx.Term = pty.Term // ncurses arcade games need the client's TERM
|
||||||
|
}
|
||||||
if u.Kind != auth.Guest {
|
if u.Kind != auth.Guest {
|
||||||
ctx.DataDir = filepath.Join(a.dataDir, "users", u.Name)
|
ctx.DataDir = filepath.Join(a.dataDir, "users", u.Name)
|
||||||
_ = os.MkdirAll(filepath.Join(ctx.DataDir, "wads"), 0o755)
|
_ = os.MkdirAll(filepath.Join(ctx.DataDir, "wads"), 0o755)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@ type Context struct {
|
||||||
// Host is the BBS hostname (e.g. bbs.profullstack.com), for building
|
// Host is the BBS hostname (e.g. bbs.profullstack.com), for building
|
||||||
// member homepage URLs (https://Host/~name) and similar links.
|
// member homepage URLs (https://Host/~name) and similar links.
|
||||||
Host string
|
Host string
|
||||||
|
// Term is the client PTY's terminal type (e.g. xterm-256color). Needed by
|
||||||
|
// sandboxed ncurses games (Space Invaders, Pac-Man, Tetris, Moon Patrol),
|
||||||
|
// which call initscr() and fail with "Error opening terminal" if TERM is
|
||||||
|
// unset — the systemd daemon environment has no TERM to inherit.
|
||||||
|
Term string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin is the only integration point between a feature and the hub.
|
// Plugin is the only integration point between a feature and the hub.
|
||||||
|
|
|
||||||
|
|
@ -207,12 +207,32 @@ func (m *menu) workDir(sub string) string {
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gameEnv is the minimal environment handed to a sandboxed game. It does NOT
|
||||||
|
// inherit the daemon's environment (which carries operator secrets like
|
||||||
|
// COINPAY_API_KEY) — a third-party game binary has no business seeing those.
|
||||||
|
// TERM comes from the client PTY so ncurses games (Space Invaders, Pac-Man,
|
||||||
|
// Tetris, Moon Patrol) can open the terminal; without it initscr() fails with
|
||||||
|
// "Error opening terminal" and the game exits before drawing a frame.
|
||||||
|
func (m *menu) gameEnv(work string) []string {
|
||||||
|
term := m.ctx.Term
|
||||||
|
if term == "" {
|
||||||
|
term = "xterm-256color" // sane default if the client didn't request a PTY type
|
||||||
|
}
|
||||||
|
return []string{
|
||||||
|
"TERM=" + term,
|
||||||
|
"PATH=/usr/games:/usr/local/games:/usr/local/bin:/usr/bin:/bin",
|
||||||
|
"HOME=" + work,
|
||||||
|
"LANG=C.UTF-8", // unicode box-drawing for the ncurses games
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// launchDoom suspends the TUI and bridges the session to a sandboxed
|
// launchDoom suspends the TUI and bridges the session to a sandboxed
|
||||||
// doom-ascii on a real PTY. Savegames land in the per-user work dir.
|
// doom-ascii on a real PTY. Savegames land in the per-user work dir.
|
||||||
func (m *menu) launchDoom(wad string) tea.Cmd {
|
func (m *menu) launchDoom(wad string) tea.Cmd {
|
||||||
bin := doomBin(m.ctx)
|
bin := doomBin(m.ctx)
|
||||||
work := m.workDir(filepath.Join("doom", strings.TrimSuffix(filepath.Base(wad), filepath.Ext(wad))))
|
work := m.workDir(filepath.Join("doom", strings.TrimSuffix(filepath.Base(wad), filepath.Ext(wad))))
|
||||||
cmd := m.ctx.Sandbox.Command(work, bin, "-iwad", wad)
|
cmd := m.ctx.Sandbox.Command(work, bin, "-iwad", wad)
|
||||||
|
cmd.Env = m.gameEnv(work)
|
||||||
return tea.Exec(newPtyExec(cmd, m.width, m.height), func(err error) tea.Msg {
|
return tea.Exec(newPtyExec(cmd, m.width, m.height), func(err error) tea.Msg {
|
||||||
return gameDoneMsg{name: "DOOM", err: err}
|
return gameDoneMsg{name: "DOOM", err: err}
|
||||||
})
|
})
|
||||||
|
|
@ -228,6 +248,7 @@ func (m *menu) launchExt(g extGame) tea.Cmd {
|
||||||
}
|
}
|
||||||
work := m.workDir(g.id)
|
work := m.workDir(g.id)
|
||||||
cmd := m.ctx.Sandbox.Command(work, bin, g.args...)
|
cmd := m.ctx.Sandbox.Command(work, bin, g.args...)
|
||||||
|
cmd.Env = m.gameEnv(work)
|
||||||
return tea.Exec(newPtyExec(cmd, m.width, m.height), func(err error) tea.Msg {
|
return tea.Exec(newPtyExec(cmd, m.width, m.height), func(err error) tea.Msg {
|
||||||
return gameDoneMsg{name: g.label, err: err}
|
return gameDoneMsg{name: g.label, err: err}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue