Files
Vantz Stockwell 651a35d4be
All checks were successful
CI / backend-types (push) Successful in 10s
CI / frontend-build (push) Successful in 15s
CI / agent-tests (push) Successful in 39s
CI / integration (push) Successful in 22s
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>
2026-06-11 21:08:05 -04:00

381 lines
11 KiB
Go

package main
import (
"sort"
"strings"
)
// dbItemTemplates is the merged, sorted list of item templates.
var dbItemTemplates []string
// ── domain types ─────────────────────────────────────────────────────────────
type playerInfo struct {
ID int64 `json:"id"`
AccountID int64 `json:"account_id"`
ControllerID int64 `json:"controller_id"`
FLSID string `json:"fls_id"`
Name string `json:"name"`
Class string `json:"class"`
Map string `json:"map"`
FactionID int16 `json:"faction_id"`
OnlineStatus string `json:"online_status"`
}
// gmIdentity is the seeded "GM/Server" persona used as the sender for admin chat
// (whisper, map announcement). HexID is the AMQP user_id (accounts."user") the
// game resolves the visible sender name from; FuncomID is the chat id shown
// in-game (m_FuncomIdFrom).
type gmIdentity struct {
AccountID int64 `json:"account_id"`
HexID string `json:"hex_id"`
FuncomID string `json:"funcom_id"`
}
type journeyNode struct {
NodeID string `json:"node_id"`
IsComplete bool `json:"is_complete"`
IsRevealed bool `json:"is_revealed"`
HasPendingReward bool `json:"has_pending_reward"`
}
type itemInfo struct {
ID int64 `json:"id"`
TemplateID string `json:"template_id"`
Name string `json:"name"`
StackSize int64 `json:"stack_size"`
Quality int64 `json:"quality"`
Durability string `json:"durability"`
MaxDurability string `json:"max_durability"`
}
type currencyRow struct {
PlayerID int64 `json:"player_id"`
CurrencyID int16 `json:"currency_id"`
Balance int64 `json:"balance"`
}
type factionRep struct {
ActorID int64 `json:"actor_id"`
FactionID int16 `json:"faction_id"`
FactionName string `json:"faction_name"`
Reputation int32 `json:"reputation"`
Scrips int64 `json:"scrips"`
}
type specTrack struct {
PlayerID int64 `json:"player_id"`
TrackType string `json:"track_type"`
XP int32 `json:"xp"`
Level float32 `json:"level"`
}
type itemRule struct {
Name string `json:"name"`
StackMax int64 `json:"stack_max"`
Volume float64 `json:"volume"`
Tier int `json:"tier"`
Rarity string `json:"rarity"`
Category string `json:"category"`
IsSchematic bool `json:"is_schematic"`
MaxDurability *float64 `json:"max_durability,omitempty"`
Icon *string `json:"icon"`
}
type itemDataFile struct {
DefaultStackMax int64 `json:"default_stack_max"`
DefaultVolume float64 `json:"default_volume"`
Names map[string]string `json:"names"`
Items map[string]itemRule `json:"items"`
}
// tagsDataFile is the output of dune-item-data/build-tags-data.sh — maps from
// journey story node IDs / contract names to the gameplay tags those in-game
// completions would emit. The admin tool uses these to apply tags when an
// admin clicks Mark Complete (since the DB-only completion bypasses the
// in-game effects).
type tagsDataFile struct {
JourneyNodeTags map[string][]string `json:"journey_node_tags"`
ContractTags map[string][]string `json:"contract_tags"`
ContractAliases map[string]string `json:"contract_aliases"`
// ContractSkillGrants[contract_id] = skill-block tags this contract's
// SkillsKeyRewards would unlock in-game (e.g. "Skills.Key.Trooper3").
// Without applying these the trainer contract's tags land but the skill
// tree branch stays locked.
ContractSkillGrants map[string][]string `json:"contract_skill_grants"`
// JobSkillBlocks["Trooper"] = every bExternal Skills.Key.* module in the
// Trooper skill tree (tier 1/2/3 + capstones). Used by Unlock Trainer to
// grant the *entire* job's block set, since only ~10 of 30 are
// contract-granted (the rest are normally unlocked by dialogue or auto).
JobSkillBlocks map[string][]string `json:"job_skill_blocks"`
// JobAllModules["Trooper"] = every module (Key, Ability, Attribute,
// Perk) whose SkillArea is ESkillTree::Trooper. Used by Reset Job Skills
// to fully nuke a class tree — the trainer Key blocks alone aren't
// enough because the game auto-grants the corresponding tier-1 ability
// (e.g. Skills.Ability.SuspensorGrenade_Reduction) which then sticks
// around as a refundable 1-SP phantom unless we remove it here.
JobAllModules map[string][]string `json:"job_all_modules"`
}
type blueprintRow struct {
ID int64 `json:"id"`
OwnerName string `json:"owner_name"`
ItemID int64 `json:"item_id"`
Pieces int64 `json:"pieces"`
Placeables int64 `json:"placeables"`
Name string `json:"name"`
}
type baseRow struct {
ID int64 `json:"id"`
Name string `json:"name"`
Pieces int64 `json:"pieces"`
Placeables int64 `json:"placeables"`
}
// mapMarker is one plottable entity on the Live Map: a player pawn, a vehicle,
// or (Phase 2b) a base. Position is the location vector of dune.actors.transform.
// Pixel placement and "last seen" age are computed client-side.
type mapMarker struct {
Type string `json:"type"` // "player" | "vehicle" | "base"
ID int64 `json:"id"`
Name string `json:"name"`
Class string `json:"class,omitempty"`
Map string `json:"map"`
PartitionID int64 `json:"partition_id"`
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
OnlineStatus string `json:"online_status,omitempty"`
FLSID string `json:"fls_id,omitempty"`
}
// ── message types (used by db.go cmd* functions) ──────────────────────────────
type msgConnect struct{ err error }
type msgPlayers struct {
rows []playerInfo
err error
}
type msgInventory struct {
rows []itemInfo
err error
}
type msgCurrency struct {
rows []currencyRow
err error
}
type msgFactions struct {
rows []factionRep
scripCurrencyID int16
err error
}
type msgSpecs struct {
rows []specTrack
err error
}
type msgSQL struct {
result string
headers []string
rows [][]string
truncated bool
err error
}
type msgMutate struct {
ok string
err error
}
type msgPlayerPosition struct {
pos playerPosition
err error
}
type msgRepairGear struct {
repaired int
scanned int
err error
}
type msgRepairVehicle struct {
repaired int
skipped int
total int
err error
}
type msgJourney struct {
rows []journeyNode
err error
}
type msgBlueprintList struct {
rows []blueprintRow
err error
}
type msgBaseList struct {
rows []baseRow
err error
}
type msgItemTemplates struct {
templates []string
}
type vehicleRow struct {
ID int64 `json:"id"`
Class string `json:"class"`
Map string `json:"map"`
ChassisDurability float64 `json:"chassis_durability"`
VehicleName string `json:"vehicle_name"`
IsRecovered bool `json:"is_recovered"`
IsBackup bool `json:"is_backup"`
}
type cheatEntry struct {
FLSID string `json:"fls_id"`
CheatType string `json:"cheat_type"`
EventTime string `json:"event_time"`
CharacterName string `json:"character_name"`
}
type gameEvent struct {
ActorID int64 `json:"actor_id"`
UniverseTime string `json:"universe_time"`
Map string `json:"map"`
EventType int32 `json:"event_type"`
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
CustomData string `json:"custom_data"`
}
type dungeonRecord struct {
DungeonID string `json:"dungeon_id"`
Difficulty string `json:"difficulty"`
DurationMs int64 `json:"duration_ms"`
PlayersNum int `json:"players_num"`
CompletionID int64 `json:"completion_id"`
}
// ── market board types ────────────────────────────────────────────────────────
type marketItem struct {
TemplateID string `json:"template_id"`
Quality int64 `json:"quality"`
DisplayName string `json:"display_name"`
Category string `json:"category"`
Tier int `json:"tier"`
Rarity string `json:"rarity"`
LowestPrice int64 `json:"lowest_price"`
TotalStock int64 `json:"total_stock"`
BotStock int64 `json:"bot_stock"`
ListingCount int64 `json:"listing_count"`
Icon *string `json:"icon"`
}
type marketListing struct {
OrderID int64 `json:"order_id"`
TemplateID string `json:"template_id"`
OwnerType string `json:"owner_type"` // "bot" or "player"
OwnerName string `json:"owner_name"`
Price int64 `json:"price"`
Stock int64 `json:"stock"`
Quality int64 `json:"quality"`
}
type marketSale struct {
OrderID int64 `json:"order_id"`
TemplateID string `json:"template_id"`
SellerType string `json:"seller_type"` // "bot" or "player"
SellerName string `json:"seller_name"`
Price int64 `json:"price"`
Quantity int64 `json:"quantity"`
}
type marketStats struct {
TotalListings int64 `json:"total_listings"`
BotListings int64 `json:"bot_listings"`
PlayerListings int64 `json:"player_listings"`
TotalStock int64 `json:"total_stock"`
BotStock int64 `json:"bot_stock"`
PlayerStock int64 `json:"player_stock"`
UniqueItems int64 `json:"unique_items"`
}
type msgMarketItems struct {
rows []marketItem
err error
}
type msgMarketListings struct {
rows []marketListing
err error
}
type msgMarketSales struct {
rows []marketSale
err error
}
type msgMarketStats struct {
stats marketStats
err error
}
type teleportLocation struct {
Name string `json:"name"`
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
}
type msgVehicles struct {
rows []vehicleRow
err error
}
type msgCheatLog struct {
rows []cheatEntry
err error
}
type msgEvents struct {
rows []gameEvent
err error
}
type msgDungeons struct {
rows []dungeonRecord
err error
}
type msgPartitions struct {
rows []teleportLocation
err error
}
type msgKeystones struct {
ids []int16
err error
}
type msgTags struct {
rows []string
err error
}
// ── item template merge (called after connect) ────────────────────────────────
func mergeItemTemplates(dbTemplates []string) {
seen := make(map[string]string)
for _, t := range dbTemplates {
seen[strings.ToLower(t)] = t
}
for k := range itemData.Names {
if _, ok := seen[k]; !ok {
seen[k] = k
}
}
if itemData.Items != nil {
for k := range itemData.Items {
if _, ok := seen[k]; !ok {
seen[k] = k
}
}
}
merged := make([]string, 0, len(seen))
for _, v := range seen {
merged = append(merged, v)
}
sort.Strings(merged)
dbItemTemplates = merged
}