diff options
Diffstat (limited to 'internal/world/room.go')
| -rw-r--r-- | internal/world/room.go | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/internal/world/room.go b/internal/world/room.go index f4390da..3783a73 100644 --- a/internal/world/room.go +++ b/internal/world/room.go @@ -1,6 +1,7 @@ package world import ( + "fmt" "strings" "gopkg.in/yaml.v3" @@ -122,6 +123,28 @@ type RoomObject struct { } func (ro *RoomObject) UnmarshalYAML(value *yaml.Node) error { + // yaml.v3's Node.Decode builds a fresh decoder that does NOT inherit + // KnownFields(true), so a misspelled key inside a room's objects: entry + // (inroom_description, onlook, ...) would be silently discarded even + // though the top-level room file is decoded strictly. Reject unknown + // keys here so the startup validator's "unknown field is an ERROR" + // guarantee extends to the region authors edit most. + if value.Kind != yaml.MappingNode { + return fmt.Errorf("room object must be a mapping") + } + allowed := map[string]bool{ + "id": true, "wander_rooms": true, "wander_interval": true, "hidden": true, + "name": true, "aliases": true, "color": true, "inroom_description": true, + "removal_item": true, "description": true, "on_use": true, "steal": true, + "gather": true, "talk": true, "safespot": true, "on_look": true, + } + for i := 0; i+1 < len(value.Content); i += 2 { + key := value.Content[i].Value + if !allowed[key] { + return fmt.Errorf("unknown room object field %q", key) + } + } + type rawRef struct { ID string `yaml:"id"` WanderRooms []int `yaml:"wander_rooms"` |
