Find CBasePlayerController_Respawn
Locate CBasePlayerController_Respawn vfunc call in CS2 server.dll or libserver.so using IDA Pro MCP tools.
Method
Search for the
GMR_BeginRoundlog string:mcp__ida-pro-mcp__find_regex pattern="GMR_BeginRound"Find cross-references to the string:
mcp__ida-pro-mcp__xrefs_to addrs="<string_addr>"This leads to the
CCSGameRules_BeginRoundfunction.Rename the function:
mcp__ida-pro-mcp__rename batch={"func": {"addr": "<function_addr>", "name": "CCSGameRules_BeginRound"}}Decompile and locate the respawn loop pattern:
mcp__ida-pro-mcp__decompile addr="<function_addr>"Look for a loop pattern like this:
do { v30 = *v28; // player controller (*(void (__fastcall **)(__int64))(*(_QWORD *)*v28 + <PreRound_offset>))(*v28); v31 = sub_XXX(v30); // resolve m_hPawn -> pawn entity // ... resolve another entity handle from controller ... if ( v31 ) { if ( (*(unsigned __int8 (__fastcall **)(__int64))(*(_QWORD *)v31 + <IsAlive_offset>))(v31) ) { (*(void (__fastcall **)(__int64))(*(_QWORD *)v33 + <AliveAction_offset>))(v33); if ( v36 ) { sub_XXX(v36); sub_XXX(v36, 32LL); } } else if ( v36 && *(_BYTE *)(v30 + <team_offset>) == 3 || *(_BYTE *)(v30 + <team_offset>) == 2 ) { sub_XXX(v36); // reset pawn model/skeleton state (*(void (__fastcall **)(__int64))(*(_QWORD *)v30 + <Respawn_offset>))(v30); // CBasePlayerController::Respawn } } ++v28; } while ( v28 != v29 );The loop iterates over a shuffled player controller list. For each controller:
- Resolves the player pawn via
m_hPawnhandle - If pawn is alive: performs alive-state updates
- If pawn is NOT alive AND team is T(2) or CT(3): calls
controller->Respawn()via vtable
Extract
<Respawn_offset>from the virtual call on the controller (v30), in the else branch. This is the vfunc offset forCBasePlayerController_Respawn.Key identification points:
- The Respawn call is in the else branch (pawn not alive)
- It is guarded by a team number check (
== 2 || == 3) - The call target is on the controller object, not the pawn
- A model/skeleton reset function is called just before Respawn
- Resolves the player pawn via
Calculate vtable index:
vfunc_index = <Respawn_offset> / 8Generate vfunc offset signature:
Identify the instruction address (
inst_addr) of the virtual callcall qword ptr [rax+<Respawn_offset>].ALWAYS Use SKILL
/generate-signature-for-vfuncoffsetto generate a robust and unique signature forCBasePlayerController_Respawn, withinst_addrandvfunc_offsetfrom this step.Write IDA analysis output as YAML beside the binary:
ALWAYS Use SKILL
/write-vfunc-as-yamlto write the analysis results.Required parameters:
func_name:CBasePlayerController_Respawnfunc_addr:None(virtual call, actual address resolved at runtime)func_sig:Nonevfunc_sig: The validated signature from step 6
VTable parameters:
vtable_name:CBasePlayerControllervfunc_offset:<Respawn_offset>from step 4vfunc_index: The vtable index from step 5
Function Characteristics
- Purpose: Respawns a player controller's pawn at round start
- Called from:
CCSGameRules_BeginRound— the round-start handler logged as"GMR_BeginRound" - Call context: Only called for dead players on T(2) or CT(3) teams
- Call site object:
CBasePlayerController(not the pawn)
VTable Information
- VTable Name:
CBasePlayerController - VTable Mangled Name:
??_7CBasePlayerController@@6B@(Windows) /_ZTV21CBasePlayerController(Linux) - VTable Offset: Changes with game updates. Extract from the
CCSGameRules_BeginRoundrespawn loop. - VTable Index: Changes with game updates. Resolve via
<Respawn_offset> / 8.
String-Based Discovery
The primary discovery method uses the GMR_BeginRound log message:
- Search string:
"GMR_BeginRound" - Xref chain: String →
CCSGameRules_BeginRound - Respawn loop: The function iterates shuffled players, calling
controller->Respawn()via vtable for dead T/CT players
This is robust because:
- The
GMR_BeginRoundstring is unique and stable across updates - The respawn loop structure with team checks (2/3) is distinctive
- The vfunc offset is extracted directly from the call site
Output YAML Format
The output YAML filename depends on the platform:
server.dll→CBasePlayerController_Respawn.windows.yamllibserver.so/libserver.so→CBasePlayerController_Respawn.linux.yaml