Home » Renegade Discussions » Mod Release Forum » [CODE] Blockable Team Change hook
[CODE] Blockable Team Change hook [message #470568] |
Mon, 02 July 2012 14:57 |
iRANian
Messages: 4311 Registered: April 2011
Karma: 0
|
General (4 Stars) |
|
|
For those who missed me posting it in the TT forums. Doesn't trigger on TEAM or TEAM2 so just replace those with a custom version.
Hook *TeamChangeHook = new Hook;
int TTHookAddress = 0; // Will be loaded with the calculated address of script 4.0's suicide hook code
bool __cdecl ChangeTeamHook(int ID)
{
Console_Output("derppppp = %d\n", ID);
return true;
}
void _declspec(naked) TeamChangeHook_Glue()
{
_asm
{
mov edi, ecx // save ecx
push [edi+6B4h] // First argument, the ID of the player attempting to suicide
call ChangeTeamHook
add esp, 4; // Manually re-align the stack (our hook is __cdecl)
mov ecx, edi // restore ecx
test al, al // Check the return value of our hook
jz BlockTeamChange // If the return value is zero (return false), jump to BlockTeamChange
mov edi, TTHookAddress // Otherwise move the address of scripts 4.0's hook
jmp edi // And jump to it
BlockTeamChange:
retn // Return immediately without doing the team change
}
}
int Calculate_Address_From_Displacement(int JMPStartAddress)
{
char OpCodes[5];
int Displacement, Address;
Hooking::ReadMemory(JMPStartAddress, OpCodes, 5); // 0x004B4910 is where the JMP opcode (E9) starts, next 4 are the displacement/relative address
memcpy(&Displacement, OpCodes+1, sizeof(char)*4); // OpCodeBuffer+1 or we'll also read the JMP opcode
Address = JMPStartAddress + 5 + Displacement;
return Address;
}
char OpCodeBuffer[5];
Hooking::ReadMemory(0x004B4910, OpCodeBuffer, 5); // 0x004B4910 is where the JMP opcode (E9) starts, next 4 are the displacement/relative address
int Displacement;
memcpy(&Displacement, OpCodeBuffer+1, sizeof(char)*4); // OpCodeBuffer+1 or we'll also read the JMP opcode
TTHookAddress = 0x004B4910 + 5 + Displacement;
Console_Output("displacement = %x, function address = 0x%X\n", Displacement, TTHookAddress);
TeamChangeHook->Install('\xE9', 0x004B4910, (int)&TeamChangeHook_Glue, "");
Long time and well respected Renegade community member, programmer, modder and tester.
Scripts 4.0 private beta tester since May 2011.
My Renegade server plugins releases
[Updated on: Tue, 03 July 2012 00:33] Report message to a moderator
|
|
|
|
|
|
|
Re: [CODE] Blockable Team Change hook [message #470637 is a reply to message #470568] |
Tue, 03 July 2012 08:06 |
|
Gen_Blacky
Messages: 3250 Registered: September 2006
Karma: 1
|
General (3 Stars) |
|
|
Hook *TeamChangeHook = new Hook;
int TeamChangeHookAddress = 0;
void Console(const char *Format, ...)
{
char buffer[256];
va_list va;
_crt_va_start(va, Format);
vsnprintf(buffer, 256, Format, va);
va_end(va);
Console_Input(buffer);
}
bool __cdecl ChangeTeamHook(int ID)
{
int GDIPlayers = (Tally_Team_Size(1));
int NodPlayers = (Tally_Team_Size(0));
int difference = GDIPlayers - NodPlayers;
int Team = Find_Player(ID)->Get_Player_Type();
StringClass side;
if ( Team == 0 )
{
side = "GDI";
Team = 1;
}
else
{
side = "Nod";
Team = 0;
}
if ( GDIPlayers == NodPlayers )
{
Console("ppage %d Teams are Even!", ID);
return false;
}
else if ( difference == 1 && NodPlayers != 0)
{
Console("ppage %d GDI only has one more player then Nod!", ID);
return false;
}
else if ( difference == -1 && GDIPlayers != 0)
{
Console("ppage %d Nod only has one more player then GDI!", ID);
return false;
}
else if ( GDIPlayers > NodPlayers && Team == 1 )
{
Console("ppage %d GDI has more player's then Nod!", ID);
return false;
}
else if ( GDIPlayers < NodPlayers && Team == 0 )
{
Console("ppage %d Nod has more player's then GDI!", ID);
return false;
}
Change_Team(Get_GameObj(ID), Team);
Console_Output("%S Changed to Team %s\n", Find_Player(ID)->PlayerName, side);
Console("msg %S Changed to Team %s\n", Find_Player(ID)->PlayerName, side);
Find_Player(ID)->Set_Deaths(Find_Player(ID)->Get_Deaths() - 1 );
return false;
}
void _declspec(naked) TeamChangeHook_Glue()
{
_asm
{
mov edi, ecx // save ecx
push [edi+6B4h] // First argument, the ID of the player attempting to suicide
call ChangeTeamHook
add esp, 4; // Manually re-align the stack (our hook is __cdecl)
mov ecx, edi // restore ecx
test al, al // Check the return value of our hook
jz BlockTeamChange // If the return value is zero (return false), jump to BlockTeamChange
mov edi, TeamChangeHookAddress // Otherwise move the address of scripts 4.0's hook
jmp edi // And jump to it
BlockTeamChange:
retn // Return immediately without doing the team change
}
}
int Calculate_Address_From_Displacement(int JMPStartAddress)
{
char OpCodes[5];
int Displacement, Address;
Hooking::ReadMemory(JMPStartAddress, OpCodes, 5); // 0x004B4910 is where the JMP opcode (E9) starts, next 4 are the displacement/relative address
memcpy(&Displacement, OpCodes+1, sizeof(char)*4); // OpCodeBuffer+1 or we'll also read the JMP opcode
Address = JMPStartAddress + 5 + Displacement;
return Address;
}
TeamChangeHookAddress = Calculate_Address_From_Displacement(0x004B4910);
Console_Output("[HOOK] TT TeamChangeHook address = 0x%X\n", TeamChangeHookAddress);
TeamChangeHook->Install('\xE9', 0x004B4910, (int)&TeamChangeHook_Glue, "");
|
|
|
Goto Forum:
Current Time: Sat Jan 11 03:49:12 MST 2025
Total time taken to generate the page: 0.01068 seconds
|