Find CCSPlayerController_Respawn
Locate CCSPlayerController_Respawn in CS2 server.dll or server.so using IDA Pro MCP tools.
Method
1. Get CCSPlayerController VTable Address
ALWAYS Use SKILL /get-vtable-from-yaml with class_name=CCSPlayerController.
If the skill returns an error, STOP and report to user.
Otherwise, extract these values for subsequent steps:
vtable_va: The vtable start address (use as<VTABLE_START>)vtable_numvfunc: The valid vtable entry count (last valid index = count - 1)vtable_entries: An array of virtual functions starting from vtable[0]
2. Decompile vtable[270 ~ last] and Search for Pattern
Using vtable_entries from step 1, Decompile virtual functions from index 270 to the last valid index:
mcp__ida-pro-mcp__decompile addr="<function_addr>"
3. Identify CCSPlayerController_Respawn by Code Pattern (Cross-Platform)
The function has platform-specific differences but shares a common ending pattern.
Common Pattern (Both Platforms) - MOST RELIABLE
The function ends with a double GetPlayerPawn + vfunc forwarding pattern:
result = GetPlayerPawn(a1); // Called once
if ( result )
{
v6 = GetPlayerPawn(a1); // Called again (same function)
return (*(__int64 (__fastcall **)(__int64))(*(_QWORD *)v6 + PAWN_VFUNC_OFFSET))(v6);
}
return result;
| Platform | Pawn VFunc Offset | VFunc Index |
|---|---|---|
| Windows | 3368 (0xD28) | ~421 |
| Linux | 3376 (0xD30) | ~422 |
Windows-Specific Pattern
v2 = GetCurrentTick(&v7, -1.0);
if ( CompareAndUpdate((float *)(a1 + OFFSET_A), v2) )
{
NotifyChange(a1 + OFFSET_A, -1, -1);
*(float *)(a1 + OFFSET_A) = *v2;
}
v3 = GetCurrentTick(&v7, -1.0);
SetThinkFunction(a1, ThinkFunc, *v3, MAGIC_NUMBER, 0LL); // Magic: 0x760791F4
*(_BYTE *)(a1 + OFFSET_B) = 0;
// ... state resets ...
Windows identifying features:
GetCurrentTickcalled twice with-1.0parameterSetThinkFunctionwith magic number0x760791F4(1980207604)- Clean, simple code flow
Linux-Specific Pattern
sub_XXXXXXXX(); // Initialization call at start
v2 = *(_BYTE *)(a1 + OFFSET_FLAG) == 0;
*(_BYTE *)(a1 + OFFSET_A) = 0;
if ( !v2 )
{
// Complex StateChanged handling with string:
// "CNetworkTransmitComponent::StateChanged(%s) @%s:%d"
// ... network state management ...
}
// State resets at end before GetPlayerPawn pattern
v3 = *(_QWORD *)(a1 + OFFSET_PAWN_PTR);
*(_BYTE *)(a1 + OFFSET_B) = 0;
*(_DWORD *)(a1 + OFFSET_C) = 0;
*(_BYTE *)(a1 + OFFSET_D) = 0;
*(_DWORD *)(a1 + OFFSET_E) = 0;
// ... then common ending pattern ...
Linux identifying features:
- References
"CNetworkTransmitComponent::StateChanged(%s) @%s:%d"string - More complex code with network state handling
- Multiple consecutive state resets before GetPlayerPawn
State Reset Pattern (Both Platforms)
Both versions have multiple consecutive state field resets:
*(_BYTE *)(a1 + offset1) = 0;
*(_DWORD *)(a1 + offset2) = 0;
*(_BYTE *)(a1 + offset3) = 0;
*(_DWORD *)(a1 + offset4) = 0;
Key identifying characteristics (priority order):
- [MOST RELIABLE] Ends with double
GetPlayerPawncall + pawn vfunc forwarding - [Windows]
SetThinkFunctionwith magic number0x760791F4 - [Linux] References
"CNetworkTransmitComponent::StateChanged"string - [Both] Multiple consecutive byte/dword field resets to 0
4. Rename the Function
mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<function_addr>", "name": "CCSPlayerController_Respawn"}]}
5. Find VTable Offset and Index
ALWAYS Use SKILL /get-vtable-index to get vtable offset and index for the function.
VTable class name: CCSPlayerController
6. Generate and Validate Unique Signature
ALWAYS Use SKILL /generate-signature-for-function to generate a robust and unique signature for the function.
7. Write IDA Analysis Output as YAML
ALWAYS Use SKILL /write-vfunc-as-yaml to write the analysis results.
Required parameters:
func_name:CCSPlayerController_Respawnfunc_addr: The function addressfunc_sig: The validated signature from step 6
VTable parameters:
vtable_name:CCSPlayerControllervfunc_offset: The offset from step 5vfunc_index: The index from step 5
Function Characteristics
- VTable Index: ~272 (Windows) / ~274 (Linux) - Index varies by platform and game version
- Parameters:
(this)wherethisis CCSPlayerController pointer - Purpose: Handles player respawn logic, resetting various state flags and forwarding to pawn
Platform Differences
| Aspect | Windows | Linux |
|---|---|---|
| Code complexity | Simple, clean flow | Complex with network state handling |
| SetThink magic | 0x760791F4 visible |
Not directly visible |
| String reference | None | "CNetworkTransmitComponent::StateChanged..." |
| Pawn vfunc offset | 3368 (0xD28) | 3376 (0xD30) |
Distinguishing Features
| Feature | Windows | Linux |
|---|---|---|
| Double GetPlayerPawn + vfunc | ✅ Present | ✅ Present |
| GetCurrentTick pattern | ✅ Twice with -1.0 | ❌ Not visible |
| SetThinkFunction magic | ✅ 0x760791F4 |
❌ Not visible |
| StateChanged string | ❌ None | ✅ Present |
| State reset pattern | ✅ Multiple resets | ✅ Multiple resets |
Output YAML Format
The output YAML filename depends on the platform:
server.dll→CCSPlayerController_Respawn.windows.yamlserver.so→CCSPlayerController_Respawn.linux.yaml