docs(reference): import Dune: Awakening server-manager references
Phase 2 references for the host-agent Dune adapter, moved out of volatile /tmp
into docs/reference-repos/ (per Commander). Three upstream projects, .git +
node_modules + compiled binaries stripped (16MB source). Nested AI-instruction
files (.claude/, CLAUDE.md) removed so they don't pollute Corrosion sessions.
- icehunter/ dune-admin (Go+React) — 4 control planes; SETUP_DOCKER.md is the
closest analog to our agent's Dune docker control plane (compose
lifecycle, docker logs, RabbitMQ-via-exec, dune Postgres schema)
- adainrivers/ Rust/Tauri desktop — SSH+k8s BattleGroup control, maintenance
daemon, in-game admin console (Rust idiom reference)
- the4rchangel/ Node web UI replacing battlegroup.bat — matches the Commander's
Hyper-V self-host path + game-config schema
See docs/reference-repos/README.md for the full index + how we use each.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
70
docs/reference-repos/icehunter/cmd/dune-admin/motd.go
Normal file
70
docs/reference-repos/icehunter/cmd/dune-admin/motd.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ── Message of the Day (#163/#167/#135) ─────────────────────────────────────
|
||||
// A configurable in-game message whispered to a player every time they join the
|
||||
// server (a per-session trigger, distinct from the welcome package's once-per-
|
||||
// version grant message). Join detection is the presenceTracker diffing the
|
||||
// online set across scanner ticks; the send reuses the proven GM-whisper path.
|
||||
|
||||
// motdDefaultPlayerName is substituted for {player} when a joining account has
|
||||
// no resolvable character name, so the message is never malformed.
|
||||
const motdDefaultPlayerName = "traveler"
|
||||
|
||||
// renderMOTD substitutes message placeholders with the joining player's details.
|
||||
// v1 supports {player} (the character name). Kept pure so it is trivially
|
||||
// testable and free of side effects.
|
||||
func renderMOTD(template string, acc welcomeAccount) string {
|
||||
name := strings.TrimSpace(acc.CharacterName)
|
||||
if name == "" {
|
||||
name = motdDefaultPlayerName
|
||||
}
|
||||
return strings.ReplaceAll(template, "{player}", name)
|
||||
}
|
||||
|
||||
// motdWhisper is one resolved message to send: recipient account, sender
|
||||
// identity (blank → seeded GM persona), and the rendered text.
|
||||
type motdWhisper struct {
|
||||
accountID int64
|
||||
sourcePlayer string
|
||||
message string
|
||||
}
|
||||
|
||||
// motdWhispersForJoins builds the whispers to send for a set of join events
|
||||
// under the given MOTD config. Returns nil when MOTD is disabled or the message
|
||||
// is blank, so the caller never sends an empty message. Pure (no side effects).
|
||||
func motdWhispersForJoins(joins []welcomeAccount, enabled bool, message, sourcePlayer string) []motdWhisper {
|
||||
if !enabled || strings.TrimSpace(message) == "" {
|
||||
return nil
|
||||
}
|
||||
out := make([]motdWhisper, 0, len(joins))
|
||||
for _, acc := range joins {
|
||||
out = append(out, motdWhisper{
|
||||
accountID: acc.AccountID,
|
||||
sourcePlayer: sourcePlayer,
|
||||
message: renderMOTD(message, acc),
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// welcomePresence is the join-detection state for the MOTD feature. Touched only
|
||||
// by the single welcome-scanner goroutine, so it needs no synchronisation.
|
||||
var welcomePresence = newPresenceTracker()
|
||||
|
||||
// runMOTDOnJoin observes the current online set, then whispers the configured
|
||||
// MOTD to each newly-joined player. Called from the scanner tick with the
|
||||
// online snapshot already fetched (shared with the package scan).
|
||||
func runMOTDOnJoin(ctx context.Context, rt welcomePackageRuntime, online []welcomeAccount) {
|
||||
joins := welcomePresence.observe(online)
|
||||
for _, m := range motdWhispersForJoins(joins, rt.motdEnabled, rt.motdMessage, rt.motdSourcePlayer) {
|
||||
if err := sendWelcomeWhisper(ctx, m.accountID, m.sourcePlayer, m.message); err != nil {
|
||||
log.Printf("motd: whisper to account %d failed: %v", m.accountID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user