rendered paste body#include "amxxmodule.h"
#include <windows.h>
#define OFFSET_TEAM 456
#define TEAM_SPECTATOR 3
#define FREELOOK_ENABLE 0
#define FREELOOK_DISABLE 1
const BYTE signature[]=
{0x8B,0x83,0xC8,0x01,0x00,0x00,0xC6,0x44,0x24,0x1C,0x01,0x83,0xF8,0x03};
BYTE patch[]=
{0xC6,0x44,0x24,0x1C,0x01,0xB8,0x90,0x90,0x90,0x90,0xFF,0xD0,0x85,0xC0};
cvar_t amx_adminfreelook = {"amx_adminfreelook", "1", 1, 1.0};
cvar_t amx_adminfreelookflag = {"amx_adminfreelookflag", "d"};
cvar_t *amx_afl;
cvar_t *amx_aflf;
static DWORD get_patch_loc()
{
MEMORY_BASIC_INFORMATION mem;
if(!VirtualQuery(MDLL_AddToFullPack, &mem, sizeof(mem)))
return NULL;
if(mem.AllocationBase == NULL)
return NULL;
DWORD address = (DWORD)mem.AllocationBase;
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)address;
if(IsBadReadPtr(dos, sizeof(IMAGE_DOS_HEADER)) || dos->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
address += dos->e_lfanew;
IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS *)address;
if(IsBadReadPtr(pe, sizeof(IMAGE_NT_HEADERS)) || pe->Signature != IMAGE_NT_SIGNATURE)
return NULL;
DWORD begin = address + pe->OptionalHeader.BaseOfCode;
DWORD end = begin + pe->OptionalHeader.SizeOfCode - sizeof(signature);
for(DWORD addr = begin; addr < end; ++addr)
{
if(!memcmp((PVOID)addr, signature, sizeof(signature)))
return addr;
}
return NULL;
}
inline int PrivateToIndex(const PVOID pdata)
{
if(pdata)
{
char *ptr = (char *)pdata;
ptr += 4;
entvars_t *pev = *(entvars_t **)ptr;
if(pev && pev->pContainingEntity)
return ENTINDEX(pev->pContainingEntity);
}
return -1;
}
int UTIL_ReadFlags(const char* c)
{
int flags = 0;
while(*c)
flags |= (1<<(*c++ - 'a'));
return flags;
}
int admin_freelook()
{
int team;
__asm mov eax, [ebx + OFFSET_TEAM];
__asm mov team, eax;
if(amx_afl->value == 0)
return team != TEAM_SPECTATOR;
PVOID pWatcher = NULL;
__asm mov pWatcher, ebx;
int id = PrivateToIndex(pWatcher);
if(MF_GetPlayerFlags(id) & UTIL_ReadFlags(amx_aflf->string))
return FREELOOK_ENABLE;
return team != TEAM_SPECTATOR;
}
void OnMetaAttach()
{
PVOID addr = (PVOID)get_patch_loc();
if(!addr)
{
SERVER_PRINT("[ADMIN FREE LOOK] patch failed.\n");
return;
}
union
{
PVOID func;
BYTE fbyte[4];
}ptob;
ptob.func = &admin_freelook;
patch[6] = ptob.fbyte[0];
patch[7] = ptob.fbyte[1];
patch[8] = ptob.fbyte[2];
patch[9] = ptob.fbyte[3];
DWORD oldflags;
if(VirtualProtect(addr, sizeof(signature), PAGE_EXECUTE_READWRITE, &oldflags))
{
memcpy(addr, patch, sizeof(patch));
DWORD flags;
if(VirtualProtect(addr, sizeof(signature), oldflags, &flags))
{
SERVER_PRINT("[ADMIN FREE LOOK] patch succeed.\n");
CVAR_REGISTER(&amx_adminfreelook);
CVAR_REGISTER(&amx_adminfreelookflag);
amx_afl = CVAR_GET_POINTER(amx_adminfreelook.name);
amx_aflf = CVAR_GET_POINTER(amx_adminfreelookflag.name);
return;
}
}
SERVER_PRINT("[ADMIN FREE LOOK] patch failed.\n");
return;
}