feat(map): surface AppMap.Monument.is_custom_name - #139
Conversation
Applies the wire change reported for server build 25653776 (#138). - Proto: AppMap.Monument.is_custom_name = 4, verbatim from the drift report. - ServerMapMonument.IsCustomName is bool?, mapped through ShouldSerializeIsCustomName() rather than read directly: a server older than this build omits the field, and false would be a fabricated answer instead of "it did not say" (same shape as ServerInfo.CamerasEnabled). - The mapper comment no longer claims `token` is always a localization key. The absent-field test was confirmed to fail against the naive `IsCustomName = appMapMonument.IsCustomName` mapping. Closes #138 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The one-field addition faithfully replicates the reviewed CamerasEnabled pattern, matches the drift report exactly, and has full branch coverage with no objective defects.
Review effort: Balanced
Findings: None
What changed in this PR
This PR surfaces a single new wire field that Facepunch added to the Rust+ companion protocol in server build 25653776 (reported in #138): optional bool is_custom_name = 4 on AppMap.Monument. The flag tells consumers whether a monument's token/Name is a server-defined custom name rather than a built-in monument localization key. The implementation mirrors the previously reviewed ServerInfo.CamerasEnabled pattern (#124): the field is modeled as a nullable bool? and mapped through protobuf-net's ShouldSerialize* presence check so that an older server omitting the field maps to null rather than a fabricated false.
Changes:
- Added
is_custom_name = 4to theAppMap.Monumentmessage in the authoritative proto. - Added
ServerMapMonument.IsCustomName(bool?) and mapped it viaShouldSerializeIsCustomName(); refreshed the mapper comment abouttoken. - Added unit tests covering the present (
true/false) and absent (null) cases.
| File | Description |
|---|---|
src/RustPlusApi/Protobuf/RustPlusContracts.proto |
Adds the new optional bool is_custom_name = 4 field, copied verbatim from the drift report. |
src/RustPlusApi/Data/ServerMapMonument.cs |
Adds the nullable IsCustomName property with XML docs matching the CamerasEnabled style. |
src/RustPlusApi/Extensions/AppMapToModel.cs |
Maps the field via ShouldSerializeIsCustomName() presence check; updates the token comment. |
tests/RustPlusApi.UnitTests/RemainingMapperTests.cs |
Adds tests pinning true/false pass-through and null-on-absent, covering both mapper branches. |
The change is small, correctly scoped, and faithfully mirrors the established CamerasEnabled precedent. The proto edit matches the drift diff exactly, the mapper uses the same ShouldSerialize* presence pattern as AppInfoToModel.cs:28-30, the model docs match ServerInfo.cs:51-55, and both mapper branches are exercised by the new tests. The semantic ambiguity around what null means is the same accepted tradeoff as CamerasEnabled and is explicitly documented by the author. I found no objective defects.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Summary
Applies the one wire change reported in #138 for server build
25653776: Facepunch addedoptional bool is_custom_name = 4toAppMap.Monument.AppMap.Monument.is_custom_name = 4, copied exactly from the drift report.ServerMapMonument.IsCustomName(bool?): mapped throughShouldSerializeIsCustomName()rather than read directly. A server older than this build leaves the field out, and that maps tonullinstead offalse. Same shape asServerInfo.CamerasEnabled(feat(team): add KickFromTeamAsync + surface AppInfo.cameras_enabled #124).tokenis always a localization key.The change only adds a field, so current library builds still parse
AppMapfrom new servers; they just can't see the flag.Unverified assumptions
These weren't checked against the decompiled server; only the drift diff was available:
tokenis a literal custom name rather than a monument translation key". The XML doc forIsCustomNamesays this.nullappears: assumes current servers always send the field, sonullmeans "server too old". If the server only sends it whentrue,nullwould also cover "not custom".Test plan
RemainingMapperTests:true/ explicitfalsepass through; field missing givesnullIsCustomName = appMapMonument.IsCustomNamemappingdtk dotnet build RustPlusApi.sln(strict analyzers) cleandtk dotnet test RustPlusApi.sln: 1245 passed on both net8.0 and net10.0 hostsReformatAndReorderapplied to the changed filesCloses #138
🤖 Generated with Claude Code