Repository navigation
Rename any player in a demo from the console, any length, everywhere their name shows (part of #1021) - #1030
Conversation
…ring playback (part of #1021) A detour of client.dll's copy of pfnGetPlayerInfo hands out the new name; SayText and TextMsg join/team lines are rewritten too, and a long name lifts the kill feed's 31-character copy cap to 63 (verify_killfeed_name_cap_offsets.py). Named parameters in any order: add id <slot|SteamID|self> [in <demo>,...] to <name>, list, remove <n>, clear. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…und a : or , GoldSrc's console splits an unquoted name at : and , and drops the spaces beside them, so to dicE[: :]Alex arrived as dicE[::]Alex with no word of it. The glued name is kept, with a warning that shows it as it now reads and says to quote it (part of #1021). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReviewI read the whole diff: What I checked, and found fine:
Fixed:
|
…e-1021 # Conflicts: # docs/dodstudio_commands.md # goldsrc-hooks/src/deathmsg.rs # studio/src/console_commands_data.js
|
Merged dev (after #1026 and #1034) in; head
|
…e-1021 # Conflicts: # studio/src/console_commands_data.js
Release note: New: ds_player_change_name renames a player everywhere their name shows during playback (kill feed, scoreboard, chat), by SteamID, slot or self, for one demo or all.
Part of #1021: the
ds_player_change_namehalf.ds_hud_deathmsg replaceis #1026.What it does
client.dll's copy ofpfnGetPlayerInfo(engine table slot 21, 19 call sites) now hands out the new name for a renamed slot: kill feed, scoreboard, capture lines, aim name, voice icon. The names are leaked on purpose and never freed, sinceclient.dllkeeps the pointer. The hook's own lookups (deathmsgSteamIDs, sprays, this module) still go through the engine's table, so they see the real player.poll(fromHUD_Frame) works out each slot (SteamID from the userinfo,self, the loaded demo's name) and publishes the result in per-slot atomics: the new name, plus a hash of the real name it was resolved for. The detour and the message filters only read those. The rule list sits behind anRwLockthat the frame onlytry_reads.*<name> joined Axis). This runs in the filterclan_textalready installs.push 0x20beforestrncpybecome0x40, and the two terminators move from[31]to[63]inside the existing 64-byteszKiller/szVictim. The terminators areARRAY_REFSentries, somaxkeeps them lifted (name_cap::field_for).tools/verify_killfeed_name_cap_offsets.pychecks every patched byte on both installs'client.dll. hw.dll is untouched.Decisions
docs/dodstudio_commands.mdgets the rule: more than three values, or optional ones, means named parameters.:and,tokens are glued back, because GoldSrc's tokenizer splits them. SoSTEAM_0:1:123andin a,bwork unquoted. A name with spaces or: , ( ) { } 'goes in quotes. An unknown word aftertogets a hint saying so.addwithoutidandto, any unknown word (named), a value given twice, a bad id, a name over 63 bytes,%(the game can read it as a format code), and control characters.selfor a slot withoutin.inbeats one without, then the one added last.addwith the sameidandinreplaces the name instead of adding a line, so a batch that re-runs its commands doesn't grow the list.inmatching: against the loaded demo's file name, without folder or.dem, case-insensitive. Only*is a wildcard.inrules apply only while a demo plays.cfg_scan.rsand one incommand_suggest.test.jspin that.deathmsg.rschanges are kept to the cap lift:mod name_cap, one line inapply_max,lift_name_cap/name_cap_lifted, andpub(crate)onparse_steam_id/classic_steam_id.usage()is untouched.console_commands_data.jswas regenerated. It also picks up two hints that were stale on dev (ds_debug_log_view_bob,ds_hud_hide_element).Test done
All runs used the Brain account, through the game lock, with
local\test-1021\. Grabs are inlocal\review-images\1021\hook\. The final DLL was rebuilt after a clippy-only change (a variant rename andptr::eq, no behaviour change). It is the one inlocal\test-1021\.POST,
ktps8w3-dyelife_ih_anzio_h1: PASS.add id self to "SELF[: :]Renamed", plus seanality bySTEAM_0:1:748805to a 44-character name.SELF[: :]RenamedkillsSomebody With A Much Longer Name Than Before, all 44 characters, in Axis red.SELF[: :]Renamed: glhfat 813 s.*Somebody With A Much Longer Name Than Before joined Spectators/Axis.list,remove 1,clear: every real name is back on the scoreboard.PRE, same demo and steps: PASS.
in ktps8w3-dyelife_*,other_demoshowsStealth By Slot: GLHFin the Allies colour, like the rest of the team.in no_such_demo_*: "nobody here", no change.vicitm,addwithoutid) and theds_debug_statusline are as expected.movie.cfgturns chat off, so chat was turned on live (hud_saytext 1; hud_saytext_internal 1; hud_saytext_time 6). No.cfgwas written.PRE,
solifotw-greetz1(laggy demo), done before the switch to dyelife:dicE[: :]Gorilla[bcshows on the scoreboard, in the kill feed, in capture lines and in console kill lines.list,remove,clear, a non-matchinginand the refusals all worked.Offline:
verify_killfeed_name_cap_offsets.pyALL OK on PRE and POSTclient.dll;verify_deathmsg_offsets.pyTABLES VERIFIED.cargo test -p goldsrc-hooks(795 pass); thenativecfg_scan test.npm run test:unit(854 pass) andapp-boot.spec.js.cargo fmt.Not seen in-game:
self/slot withoutin; only the console does.Test steps for you (PRE then POST)
1021in the Hooks DLL dropdown (orlocal\test-1021\dodstudio_goldsrc_hooks.dll). Playktps8w3-dyelife_ih_anzio_h1withviewdemoand wait for "Demo file completely loaded".ds_player_change_name add id self to "dicE[: :]Test". You should get the warning aboutself. Press TAB: your row readsdicE[: :]Test.ds_player_change_name add id STEAM_0:1:748805 to "Somebody With A Much Longer Name Than Before", thends_demo_seek_to 849. At about 856 s the kill feed shows your kill on that full 44-character name.hud_saytext 1; hud_saytext_internal 1; hud_saytext_time 6. Seek to787: the join lines at 793 s carry the long name, and yourglhfat 813 s shows the new name in the team colour.ds_player_change_name list, thenremove 1, thenclear. TAB shows the real names again.Other open PRs on the same files
deathmsg.rs: Kill feed: change who got a kill, who died or the weapon, or hide one kill, from the console (part of #1021) #1026 (replace, the other half of [R&D] Rename any player in a demo: any length, any characters, by console command #1021), Kill feed: an even layout where every weapon icon has the same height and nothing is cut off (#1022) #1023, Kill feed: outline the names and put boxes behind lines or names (part of #562) #1000.commands.rs,Commands.txt,dodstudio_commands.md: Kill feed: change who got a kill, who died or the weapon, or hide one kill, from the console (part of #1021) #1026, R&D: show the overview map in POV demos (part of #897) #906, R&D: a restyled health readout drawn by the hook (part of #849) #882, Review highlights: console commands can't move the demo or the camera while a review runs (#855) #880, While a demo loads, the demo player bar shows how far along it is (#465) #758, Hide server HUD text and engine centre text (part of #677) #717.msglog.rs: Hide server HUD text and engine centre text (part of #677) #717.console_commands_data.js: R&D: show the overview map in POV demos (part of #897) #906, R&D: a restyled health readout drawn by the hook (part of #849) #882, While a demo loads, the demo player bar shows how far along it is (#465) #758, Hide server HUD text and engine centre text (part of #677) #717. Whichever merges second regenerates it.🤖 Generated with Claude Code