#include #include #include "Main.h" #include #include #include #include #include #include using namespace std; extern void OnClientCommand_PreHook(edict_t *pPlayerEntity); extern void OnClientUserInfoChanged_PreHook(edict_t *pPlayerEntity, char *infoBuffer); extern void OnServerActivate_PostHook(edict_t *pEdictList, int edictCount, int maxClients); static const uint32_t g_isPrintTable[2048] = { 0x00000200, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF9FFFFFF, 0x00030003, 0x0000401F, 0x00000000, 0x00000000, 0x00000000, 0x7CCF0000, 0xFFFFD7C0, 0xFFFFFFFB, 0xFFFFFFFF, 0xFFBFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFC03, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFE000F, 0xFE7FFFFF, 0xFFFFFFFE, 0x000006FF, 0x40000000, 0xFFFF0049, 0x001F07FF, 0xC8003600, 0xFFFFFFFE, 0x000007FF, 0xFFFEFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x003FFFFF, 0x9FFFC060, 0xFFFD3FFF, 0x0000FFFF, 0xFFFFE000, 0xFFFFFFFF, 0xFFFFFFFF, 0x0002003F, 0xFFFFFFFF, 0x07B007FF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFF0, 0x23FFFFFF, 0xFF010000, 0xF807FFF3, 0xFFF99FE0, 0x23C5FDFF, 0xB0004000, 0x0003FFC3, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001CFFC0, 0xFFFBBFE0, 0x23EDFDFF, 0x00010000, 0x0000FFC3, 0xFFF99FE0, 0x23EDFDFF, 0xB0000000, 0x0002FFC3, 0xD63DC7E8, 0x03FFC718, 0x00010000, 0x0000FFC0, 0xFFFDDFE0, 0x23EFFDFF, 0x03000000, 0x0000FFC3, 0xFFFDDFE0, 0x23EFFDFF, 0x40000000, 0x0000FFC3, 0xFFFDDFE0, 0x23FFFDFF, 0x00000000, 0xFC00FFC3, 0xFC7FFFE0, 0x2FFBFFFF, 0x0000007F, 0x00100000, 0xFFFFFFFE, 0x07FFFFFF, 0x0FFFFFFF, 0x00000000, 0xFEF02596, 0x200DECAE, 0x33FF005F, 0x00000000, 0x0007FFF1, 0x3C0003FF, 0xFFFFFEFF, 0x00001FFF, 0x00000F20, 0x00000000, 0x001F0000, 0x00000000, 0xFFFFFFFF, 0x800007FF, 0x3C3FFFFF, 0xFFE1C062, 0x03FF4003, 0xFFFFFFFF, 0xFFFF003F, 0x1FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFF07, 0xFFFFFFFF, 0x03FFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x3D7F3DFF, 0xFFFFFFFF, 0xFFFF3DFF, 0x7F3DFFFF, 0xFF7FFF3D, 0xFFFFFFFF, 0xFF3DFFFF, 0xFFFFFFFF, 0x07FFFFFF, 0x000001FE, 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x007FFFFF, 0x1FFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x0001FFFF, 0x0003DFFF, 0x0063FFFF, 0x0003FFFF, 0x0001DFFF, 0xFFFFFFFF, 0x000FFFFF, 0x17F00000, 0x000003FF, 0x03FF07FF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00FFFFFF, 0xFFFFFFFF, 0x000005FF, 0x00000000, 0x00000000, 0x1FFFFFFF, 0x00000000, 0xFFFFFFF0, 0x001F3FFF, 0xFFFFFFFF, 0x000003FF, 0xC3FF00FE, 0x00000000, 0xC07FFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFE0, 0x000FFFFF, 0xFFFF0FE0, 0x00000001, 0xFFFFFFF8, 0x03FFC001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xF800000F, 0xFFFFE3FF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0xFFFF0000, 0xFFFF00FF, 0x7FFBFFEF, 0xE0020000, 0x001F6000, 0x00000000, 0x00000000, 0x00000000, 0x3E2FFC84, 0xF3FFBD50, 0x000043E0, 0xFFFFFFFF, 0x000001FF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000600, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x003FFF00, 0x00000000, 0x00000000, 0x00000060, 0x0000FFC0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x01FFFFF8, 0x00000000, 0x0F000000, 0x30000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFF7FFF, 0x7FFFFFFF, 0x3FFEFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xDE00001F, 0xFFFFFFFF, 0xFFFF003F, 0xFFFFFFFF, 0x0000803F, 0x007FFFFF, 0x7F7F7F7F, 0x7F7F7F7F, 0x00000000, 0xFFFFFFFF, 0x00017FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFF3FFEF, 0x3F3F03FE, 0xFFFFFFFE, 0xFFFFFFFF, 0xE07FFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFE0, 0xFFFE3FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00007FFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x003FFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00001FFF, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000FFF, 0xFFFFFFFF, 0x40087FFC, 0x00FFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x000018FF, 0x00000000, 0x00000000, 0xF8000000, 0xFFFFF7BB, 0x00000007, 0xFFFFFFFF, 0x00FFFFFF, 0xFFFFFFFC, 0x000FFFFF, 0x03FFC000, 0x00000000, 0xFFFFFFFF, 0xFFFFC03F, 0x8000007F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0x000001FF, 0xF3FF0FF7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF3FFF, 0xFFFFFFFF, 0xFFFF07FF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, 0x00000000, 0xA0F8007F, 0x5F7FFDFF, 0xFFFFFFDB, 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF, 0xFFF80000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0000, 0xFFFFFFFF, 0xFFFCFFFF, 0xFFFFFFFF, 0x000000FF, 0x0FFF0000, 0x03FF0000, 0xFFFF0000, 0xFFF7FFFF, 0xFFDF0D0B, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x9FFFFFFF, 0x8FFFF7EE, 0xBFFFFFFF, 0xAFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0x1CFCFCFC, 0x00000000 }; enginefuncs_t g_engfuncs; globalvars_t *gpGlobals; extern void PF_MessageEnd_I(); char g_originalBytes[5]; char g_patchedBytes[5]; bool PatternMemoryEqual(const void* memory, const int* pattern, int size) { for (int i = 0; i < size; i++) { if (pattern[i] == -1) continue; if (((byte *)memory)[i] == pattern[i]) continue; return false; } return true; } uintptr_t FindMemoryByPattern(void* startPtr, string pattern) { pattern.erase(std::remove_if(pattern.begin(), pattern.end(), std::isspace), pattern.end()); auto HexDigitToNum = [](char hexDigit) -> int { return ('0' <= hexDigit && hexDigit <= '9') ? (hexDigit - '0') : ((hexDigit - 'A') + 10); }; auto searchSize = pattern.length() / 2; auto search = std::make_unique(searchSize); for (size_t i = 0; i < searchSize; i++) { if (pattern[2 * i] == '?') search[i] = -1; else search[i] = ((byte)HexDigitToNum(pattern[2 * i]) << 4) | ((byte)HexDigitToNum(pattern[2 * i + 1])); } auto codeBase = (uintptr_t)startPtr; for (auto codePtr = codeBase; ; codePtr++) { if (PatternMemoryEqual((const void *)codePtr, search.get(), searchSize)) { return codePtr; } } } struct { const char *buffername; uint16 flags; byte *data; int maxsize; int cursize; } *g_msgBuffer; int *g_msgType; #ifndef PAGESIZE constexpr auto PAGESIZE = 0x1000; #endif void Init() { string gameName = GET_GAME_INFO(PLID, GINFO_NAME); if (gameName != "cstrike" && gameName != "czero") { return; } #ifdef _WIN32 bool isReHLDS = false; { auto swds = GetModuleHandleA("swds.dll"); if (swds != nullptr) { auto createInterface = GetProcAddress(swds, "CreateInterface"); if (((void* (*)(const char*, void*))createInterface)("VREHLDS_HLDS_API_VERSION001", nullptr) != nullptr) { isReHLDS = true; } } } if (isReHLDS) { uintptr_t addr = FindMemoryByPattern(g_engfuncs.pfnMessageEnd, "F6 05 ?? ?? ?? ?? 02 0F 85 ?? ?? ?? ?? 8B ?? ?? ?? ?? ?? 83 ?? 3A"); g_msgBuffer = decltype(g_msgBuffer)(*(uintptr_t *)(addr + 2) - offsetof(remove_pointer_t, flags)); g_msgType = *(int **)(addr + 15); } else { uintptr_t addr = FindMemoryByPattern(g_engfuncs.pfnMessageEnd, "F6 05 ?? ?? ?? ?? 02 74 11 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 ?? 5F 5E 5B C3 8B"); g_msgBuffer = decltype(g_msgBuffer)(*(uintptr_t *)(addr + 2) - offsetof(remove_pointer_t, flags)); g_msgType = *(int **)(addr + 28); } DWORD oldProtect; VirtualProtect(g_engfuncs.pfnMessageEnd, 5, PAGE_EXECUTE_READWRITE, &oldProtect); memcpy(g_originalBytes, g_engfuncs.pfnMessageEnd, 5); g_patchedBytes[0] = char(0xE9); *(uint32_t*)&g_patchedBytes[1] = (uint32_t)&PF_MessageEnd_I - ((uint32_t)g_engfuncs.pfnMessageEnd + 5); memcpy(g_engfuncs.pfnMessageEnd, g_patchedBytes, 5); VirtualProtect(g_engfuncs.pfnMessageEnd, 5, oldProtect, &oldProtect); #else Dl_info dlinfo; dladdr(g_engfuncs.pfnMessageEnd, &dlinfo); auto handle = dlopen(dlinfo.dli_fname, RTLD_NOW); g_msgBuffer = dlsym(handle, "gMsgBuffer"); g_msgType = dlsym(handle, "gMsgType"); dlclose(handle); uintptr_t addr = (uintptr_t)g_engfuncs.pfnMessageEnd; mprotect(addr/PAGESIZE*PAGESIZE, 5 + addr%PAGESIZE, PROT_EXEC | PROT_READ | PROT_WRITE); memcpy(g_originalBytes, g_engfuncs.pfnMessageEnd, 5); g_patchedBytes[0] = char(0xE9); *(uint32_t*)&g_patchedBytes[1] = (uint32_t)&PF_MessageEnd_I - ((uint32_t)g_engfuncs.pfnMessageEnd + 5); memcpy(g_engfuncs.pfnMessageEnd, g_patchedBytes, 5); mprotect(addr/PAGESIZE*PAGESIZE, 5 + addr%PAGESIZE, PROT_EXEC | PROT_READ); #endif } C_DLLEXPORT #ifdef _WIN32 __declspec(naked) #endif void GiveFnptrsToDll(enginefuncs_t *pEngFuncs, globalvars_t *pGlobalVars) { #ifdef _WIN32 __asm { push ebp mov ebp, esp sub esp, __LOCAL_SIZE push ebx push esi push edi } #endif memcpy(&g_engfuncs, pEngFuncs, sizeof(g_engfuncs)); gpGlobals = pGlobalVars; Init(); #ifdef _WIN32 __asm { pop edi pop esi pop ebx mov esp, ebp pop ebp ret 8 } #endif } C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) { pFunctionTable->pfnClientCommand = &OnClientCommand_PreHook; pFunctionTable->pfnClientUserInfoChanged = &OnClientUserInfoChanged_PreHook; return TRUE; } C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) { pFunctionTable->pfnServerActivate = &OnServerActivate_PostHook; return TRUE; } template T Min(T a, T b) { return (a < b) ? a : b; } size_t GetPluginRelPath(char *path, size_t maxPathLength) { const char *pluginAbsPath = GET_PLUGIN_PATH(PLID); const char *gamedirAbsPath = GET_GAME_INFO(PLID, GINFO_GAMEDIR); const char *pluginRelPath = &pluginAbsPath[strlen(gamedirAbsPath) + 1]; // + slash // Find last slash const char *searchChar = pluginRelPath + strlen(pluginRelPath) - 1; // go to string end while (true) { if (*searchChar == '/' || *searchChar == '\\') { break; // ok we found it } searchChar--; } size_t charsToCopy = Min((size_t)searchChar - (size_t)pluginRelPath + 1, maxPathLength); // with slash strncpy(path, pluginRelPath, charsToCopy); path[charsToCopy] = '\0'; return charsToCopy; } void ExecPluginConfig() { static char execConfigCmd[300]; if (execConfigCmd[0] == '\0') { char relPath[260]; GetPluginRelPath(relPath, sizeof(relPath)); snprintf(execConfigCmd, sizeof(execConfigCmd), "exec \"%s%s.cfg\"\n", relPath, Plugin_info.name); } SERVER_COMMAND(execConfigCmd); SERVER_EXECUTE(); } void OnServerActivate_PostHook(edict_t *pEdictList, int edictCount, int maxClients) { ExecPluginConfig(); RETURN_META(MRES_IGNORED); } void FromUtf8ToUtf16(char16_t *out, const char *in) { while (*in != '\0') { if (0x0 < *in && *in < 0x80) { *out++ = (char16_t)*in++; } else if ((*in & 0xE0) == 0xC0) { *out = (char16_t)(*in++ & 0x1F) << 6; if (*in != '\0') { *out++ |= (char16_t)(*in++ & 0x3F); } } else if ((*in & 0xF0) == 0xE0) { *out = (char16_t)(*in++ & 0x0F) << 12; if (*in != '\0') { *out |= (char16_t)(*in++ & 0x3F) << 6; if (*in != '\0') { *out++ |= (char16_t)(*in++ & 0x3F); } } } else { in++; } } *out = u'\0'; } void FromUtf16ToUtf8(char *out, const char16_t *in) { while (*in != u'\0') { if (*in < 0x80) { *out++ = (char)*in++; } else if (*in < 0x800) { *out++ = 0xC0 | (char)(*in >> 6); *out++ = 0x80 | (char)(*in++ & 0x3F); } else { *out++ = 0xE0 | (char)(*in >> 12); *out++ = 0x80 | (char)((*in >> 6) & 0x3F); *out++ = 0x80 | (char)(*in++ & 0x3F); } } *out = '\0'; } bool IsUtf16CharPrintable(char16_t ch) { return (g_isPrintTable[ch / 32] & (1 << (ch % 32))) != 0; } bool IsUtf16CharMeanSpace(char16_t ch) { switch (ch) { case 0x0020: case 0x0082: // BREAK PERMITTED HERE case 0x0083: // NO BREAK PERMITTED HERE case 0x00A0: // NO-BREAK SPACE case 0x034F: // COMBINING GRAPHEME JOINER case 0x1680: case 0x180E: case 0x2000: // EN QUAD case 0x2001: // EM QUAD case 0x2002: // EN SPACE case 0x2003: // EM SPACE case 0x2004: // THICK SPACE case 0x2005: // MID SPACE case 0x2006: // SIX SPACE case 0x2007: // figure space case 0x2008: // PUNCTUATION SPACE case 0x2009: // THIN SPACE case 0x200A: // HAIR SPACE case 0x200B: // ZERO-WIDTH SPACE case 0x200C: // ZERO-WIDTH NON-JOINER case 0x200D: // ZERO WIDTH JOINER case 0x2028: // LINE SEPARATOR case 0x2029: // PARAGRAPH SEPARATOR case 0x202F: // NARROW NO-BREAK SPACE case 0x205F: case 0x2060: // word joiner case 0x3000: case 0xFEFF: // ZERO-WIDTH NO BREAK SPACE case 0xFFFC: // OBJECT REPLACEMENT CHARACTER return true; } return false; } cvar_t g_cvarVersion = {"SNAC_Version" , Plugin_info.version, FCVAR_EXTDLL | FCVAR_SERVER, 0, nullptr}; cvar_t g_cvarChatReplaceNumberSign = {"SNAC_Chat_ReplaceNumberSign" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarChatReplacePercentSign = {"SNAC_Chat_ReplacePercentSign" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarChatRemoveUnprintable = {"SNAC_Chat_RemoveUnprintable" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarChatTrimSpaces = {"SNAC_Chat_TrimSpaces" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarChatTruncateToEngineLimitAfterReplace = {"SNAC_Chat_TruncateToEngineLimitAfterReplace", "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarNameReplaceNumberSign = {"SNAC_Name_ReplaceNumberSign" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarNameReplacePercentSign = {"SNAC_Name_ReplacePercentSign" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarNameReplaceAmpersand = {"SNAC_Name_ReplaceAmpersand" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarNameReplacePlusSign = {"SNAC_Name_ReplacePlusSign" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarNameRemoveUnprintable = {"SNAC_Name_RemoveUnprintable" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t g_cvarNameTrimSpaces = {"SNAC_Name_TrimSpaces" , "1" , FCVAR_EXTDLL , 0, nullptr}; cvar_t *g_pcvarChatReplaceNumberSign; cvar_t *g_pcvarChatReplacePercentSign; cvar_t *g_pcvarChatRemoveUnprintable; cvar_t *g_pcvarChatTrimSpaces; cvar_t *g_pcvarChatTruncateToEngineLimitAfterReplace; cvar_t *g_pcvarNameReplaceNumberSign; cvar_t *g_pcvarNameReplacePercentSign; cvar_t *g_pcvarNameReplaceAmpersand; cvar_t *g_pcvarNameReplacePlusSign; cvar_t *g_pcvarNameRemoveUnprintable; cvar_t *g_pcvarNameTrimSpaces; void OnClientCommand_PreHook(edict_t *pPlayerEntity) { if (!g_pcvarChatReplaceNumberSign->value && !g_pcvarChatReplacePercentSign->value && !g_pcvarChatRemoveUnprintable->value && !g_pcvarChatTrimSpaces->value) { RETURN_META(MRES_IGNORED); } const char *commandName = CMD_ARGV(0); if ((FStrEq(commandName, "say") || FStrEq(commandName, "say_team")) && CMD_ARGC() > 1) { const char *origArgs = CMD_ARGS(); // Remove quotes bool restoreQuotes = false; if (*origArgs == '"') { origArgs++; *(char *)&origArgs[strlen(origArgs) - 1] = '\0'; restoreQuotes = true; } char16_t utf16OrigArgs[128]; FromUtf8ToUtf16(utf16OrigArgs, origArgs); char16_t utf16Args[128]; size_t n = 0; bool isStrBegin = true; size_t lastNonSpacePos = 0; for (size_t i = 0; utf16OrigArgs[i] != '\0'; i++) { if (!IsUtf16CharPrintable(utf16OrigArgs[i]) && g_pcvarChatRemoveUnprintable->value) { continue; } if (IsUtf16CharMeanSpace(utf16OrigArgs[i]) && g_pcvarChatTrimSpaces->value) { if (!isStrBegin) { utf16Args[n++] = utf16OrigArgs[i]; } continue; } if (utf16OrigArgs[i] == '#' && g_pcvarChatReplaceNumberSign->value) { utf16Args[n++] = u'#'; } else if (utf16OrigArgs[i] == '%' && g_pcvarChatReplacePercentSign->value) { utf16Args[n++] = u'%'; } else { utf16Args[n++] = utf16OrigArgs[i]; } lastNonSpacePos = n; isStrBegin = false; } utf16Args[lastNonSpacePos] = u'\0'; if (g_pcvarChatTruncateToEngineLimitAfterReplace->value != 0.0f) { size_t utf8Length = 0; size_t maxLength = restoreQuotes ? 125 : 127; for (size_t i = 0; i != lastNonSpacePos; i++) { if (utf16Args[i] < 0x80) { utf8Length++; } else if (utf16Args[i] < 0x800) { utf8Length += 2; } else { utf8Length += 3; } if (utf8Length > maxLength) { utf16Args[i] = u'\0'; break; } } } if (restoreQuotes) { origArgs = CMD_ARGS(); *(char *)&origArgs[0] = '"'; FromUtf16ToUtf8((char *)&origArgs[1], utf16Args); size_t len = strlen(origArgs); *(char *)&origArgs[len++] = '"'; *(char *)&origArgs[len] = '\0'; } else { FromUtf16ToUtf8((char *)CMD_ARGS(), utf16Args); } } RETURN_META(MRES_IGNORED); } const char *GetClientName(edict_t *pClientEntity) { return GET_INFOKEYBUFFER(pClientEntity) + 256 + 4 + 4 + 64; } void OnClientUserInfoChanged_PreHook(edict_t *pPlayerEntity, char *infoBuffer) { if (!g_pcvarNameReplaceNumberSign->value && !g_pcvarNameReplacePercentSign->value && !g_pcvarNameReplaceAmpersand->value && !g_pcvarNameReplacePlusSign->value && !g_pcvarNameRemoveUnprintable->value && !g_pcvarNameTrimSpaces->value) { RETURN_META(MRES_IGNORED); } const char *oldName = GetClientName(pPlayerEntity); const char *newName = INFOKEY_VALUE(infoBuffer, "name"); if (oldName[0] == '\0' || !FStrEq(newName, oldName)) { char16_t utf16NewName[32]; FromUtf8ToUtf16(utf16NewName, newName); char16_t utf16CorrectedName[32]; size_t n = 0; bool isStrBegin = true; size_t lastNonSpacePos = 0; for (size_t i = 0; utf16NewName[i] != '\0'; i++) { if (!IsUtf16CharPrintable(utf16NewName[i]) && g_pcvarNameRemoveUnprintable->value) { continue; } if (IsUtf16CharMeanSpace(utf16NewName[i]) && g_pcvarNameTrimSpaces->value) { if (!isStrBegin) { utf16CorrectedName[n++] = utf16NewName[i]; } continue; } if ((utf16NewName[i] == '#' && g_pcvarNameReplaceNumberSign->value) || (utf16NewName[i] == '%' && g_pcvarNameReplacePercentSign->value) || (utf16NewName[i] == '&' && g_pcvarNameReplaceAmpersand->value) || (n && g_pcvarNameReplacePlusSign->value && utf16CorrectedName[n-1] == '+' && utf16NewName[i] <= 127 && (isdigit(utf16NewName[i]) || isalpha(utf16NewName[i])))) { utf16CorrectedName[n++] = 0xFF00 + utf16NewName[i] - 0x20; } else { utf16CorrectedName[n++] = utf16NewName[i]; } lastNonSpacePos = n; isStrBegin = false; } utf16CorrectedName[lastNonSpacePos] = u'\0'; size_t utf8Length = 0; for (size_t i = 0; i != lastNonSpacePos; i++) { if (utf16CorrectedName[i] < 0x80) { utf8Length++; } else if (utf16CorrectedName[i] < 0x800) { utf8Length += 2; } else { utf8Length += 3; } if (utf8Length > 31) { utf16CorrectedName[i] = u'\0'; break; } } char correctedName[32]; FromUtf16ToUtf8(correctedName, utf16CorrectedName); SET_CLIENT_KEYVALUE(ENTINDEX(pPlayerEntity), infoBuffer, "name", correctedName); } RETURN_META(MRES_IGNORED); } plugin_info_t Plugin_info = { META_INTERFACE_VERSION, // ifvers "SafeNameAndChat", // name PLUGIN_VERSION, // version "2017.02.01", // date "WPMG.PRoSToC0der", // author "http://snac.wpmg.ru/", // url "SNAC", // logtag, all caps please PT_ANYTIME, // (when) loadable PT_ANYTIME, // (when) unloadable }; meta_globals_t *gpMetaGlobals; gamedll_funcs_t *gpGamedllFuncs; mutil_funcs_t *gpMetaUtilFuncs; C_DLLEXPORT int Meta_Query(char *pchInterfaceVersion, plugin_info_t **pPluginInfo, mutil_funcs_t *pMetaUtilFuncs) { *pPluginInfo = &Plugin_info; gpMetaUtilFuncs = pMetaUtilFuncs; return TRUE; } C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs) { pFunctionTable->pfnGetEntityAPI2 = &GetEntityAPI2; pFunctionTable->pfnGetEntityAPI2_Post = &GetEntityAPI2_Post; gpMetaGlobals = pMGlobals; gpGamedllFuncs = pGamedllFuncs; CVAR_REGISTER(&g_cvarVersion); CVAR_SET_STRING(g_cvarVersion.name, g_cvarVersion.string); CVAR_REGISTER(&g_cvarChatReplaceNumberSign); CVAR_REGISTER(&g_cvarChatReplacePercentSign); CVAR_REGISTER(&g_cvarChatRemoveUnprintable); CVAR_REGISTER(&g_cvarChatTrimSpaces); CVAR_REGISTER(&g_cvarChatTruncateToEngineLimitAfterReplace); CVAR_REGISTER(&g_cvarNameReplaceNumberSign); CVAR_REGISTER(&g_cvarNameReplacePercentSign); CVAR_REGISTER(&g_cvarNameReplaceAmpersand); CVAR_REGISTER(&g_cvarNameReplacePlusSign); CVAR_REGISTER(&g_cvarNameRemoveUnprintable); CVAR_REGISTER(&g_cvarNameTrimSpaces); g_pcvarChatReplaceNumberSign = CVAR_GET_POINTER(g_cvarChatReplaceNumberSign .name); g_pcvarChatReplacePercentSign = CVAR_GET_POINTER(g_cvarChatReplacePercentSign .name); g_pcvarChatRemoveUnprintable = CVAR_GET_POINTER(g_cvarChatRemoveUnprintable .name); g_pcvarChatTrimSpaces = CVAR_GET_POINTER(g_cvarChatTrimSpaces .name); g_pcvarChatTruncateToEngineLimitAfterReplace = CVAR_GET_POINTER(g_cvarChatTruncateToEngineLimitAfterReplace.name); g_pcvarNameReplaceNumberSign = CVAR_GET_POINTER(g_cvarNameReplaceNumberSign .name); g_pcvarNameReplacePercentSign = CVAR_GET_POINTER(g_cvarNameReplacePercentSign .name); g_pcvarNameReplaceAmpersand = CVAR_GET_POINTER(g_cvarNameReplaceAmpersand .name); g_pcvarNameReplacePlusSign = CVAR_GET_POINTER(g_cvarNameReplacePlusSign .name); g_pcvarNameRemoveUnprintable = CVAR_GET_POINTER(g_cvarNameRemoveUnprintable .name); g_pcvarNameTrimSpaces = CVAR_GET_POINTER(g_cvarNameTrimSpaces .name); ExecPluginConfig(); return TRUE; } C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) { return TRUE; } string SafePositionalPrintf(string format, vector args, bool positional = true) { string result{}; enum class State { None, FoundPercent, FoundString, } state = State::None; size_t curArg = 0; for (auto ch : format) { switch (state) { case State::None: { if (ch == '%') { state = State::FoundPercent; } else { result.push_back(ch); state = State::None; } } break; case State::FoundPercent: { if (ch == 's') { state = State::FoundString; } else { result.push_back('%'); if (ch != '%') { result.push_back(ch); } state = State::None; } } break; case State::FoundString: { if ('1' <= ch && ch <= '9' && ch - '1' < args.size() && positional) { result += args[ch - '1']; state = State::None; } else if (curArg < args.size()) { result += args[curArg++]; result.push_back(ch); state = State::None; } else { result.push_back('%'); result.push_back('s'); result.push_back(ch); state = State::None; } } break; } } if (state == State::FoundPercent) { result.push_back('%'); } else if (state == State::FoundString) { if (curArg < args.size()) { result += args[curArg++]; } else { result.push_back('%'); result.push_back('s'); } } return result; } void PF_MessageEnd_I() { LOG_CONSOLE(PLID, "Message end! %d %d", *g_msgType, g_msgBuffer->cursize); const char *temp = GET_USER_MSG_NAME(PLID, *g_msgType, nullptr); string msgName = temp != nullptr ? temp : ""; if (msgName == "SayText" || msgName == "TextMsg") { int curPos = 0; int arg = 0; if (curPos != g_msgBuffer->cursize) { arg = g_msgBuffer->data[curPos]; curPos++; } string format{}; if (curPos != g_msgBuffer->cursize) { format = (const char*)&g_msgBuffer->data[curPos]; curPos += format.length() + 1; } vector args{}; while (curPos != g_msgBuffer->cursize) { args.emplace_back((const char*)&g_msgBuffer->data[curPos]); curPos += args[args.size() - 1].length() + 1; } if (msgName == "SayText" && format[0] != '#') { if (args.size() == 0) { g_msgBuffer->cursize = 0; g_msgBuffer->data[g_msgBuffer->cursize++] = arg; strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], "#Spec_PlayerItem"); g_msgBuffer->cursize += sizeof("#Spec_PlayerItem"); strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], format.c_str()); g_msgBuffer->cursize += format.length() + 1; } else { g_msgBuffer->cursize = 0; g_msgBuffer->data[g_msgBuffer->cursize++] = arg; strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], "#Spec_PlayerItem"); g_msgBuffer->cursize += sizeof("#Spec_PlayerItem"); if (arg != 0 && args[0] == "") { args[0] = STRING(INDEXENT(arg)->v.netname); } string formatted = SafePositionalPrintf(format, args); strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], formatted.c_str()); g_msgBuffer->cursize += formatted.length() + 1; } } else if (msgName == "TextMsg" && format[0] != '#' && arg == HUD_PRINTTALK) { if (args.size() == 0) { g_msgBuffer->cursize = 0; g_msgBuffer->data[g_msgBuffer->cursize++] = arg; strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], "#Spec_PlayerItem"); g_msgBuffer->cursize += sizeof("#Spec_PlayerItem"); strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], format.c_str()); g_msgBuffer->cursize += format.length() + 1; } else { g_msgBuffer->cursize = 0; g_msgBuffer->data[g_msgBuffer->cursize++] = arg; strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], "#Spec_PlayerItem"); g_msgBuffer->cursize += sizeof("#Spec_PlayerItem"); string formatted = SafePositionalPrintf(format, args); strcpy((char*)&g_msgBuffer->data[g_msgBuffer->cursize], formatted.c_str()); g_msgBuffer->cursize += formatted.length() + 1; } } //LOG_MESSAGE(PLID, "%s: %s %s %s %s", GET_USER_MSG_NAME(PLID, *g_msgType, nullptr), format.c_str(), arg1.c_str(), arg2.c_str(), arg3.c_str()); } #ifdef _WIN32 DWORD oldProtect; VirtualProtect(g_engfuncs.pfnMessageEnd, 5, PAGE_EXECUTE_READWRITE, &oldProtect); memcpy(g_engfuncs.pfnMessageEnd, g_originalBytes, 5); g_engfuncs.pfnMessageEnd(); memcpy(g_engfuncs.pfnMessageEnd, g_patchedBytes, 5); VirtualProtect(g_engfuncs.pfnMessageEnd, 5, oldProtect, &oldProtect); #else uintptr_t addr = (uintptr_t)g_engfuncs.pfnMessageEnd; mprotect(addr/PAGESIZE*PAGESIZE, 5 + addr%PAGESIZE, PROT_EXEC | PROT_READ | PROT_WRITE); memcpy(g_engfuncs.pfnMessageEnd, g_originalBytes, 5); g_engfuncs.pfnMessageEnd(); memcpy(g_engfuncs.pfnMessageEnd, g_patchedBytes, 5); mprotect(addr/PAGESIZE*PAGESIZE, 5 + addr%PAGESIZE, PROT_EXEC | PROT_READ); #endif }