This repository has been archived by the owner on Nov 2, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extension.cpp
186 lines (162 loc) · 4.52 KB
/
extension.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "extension.h"
IGameConfig *g_pGameConf = NULL;
IMemoryUtils *memutils = NULL;
Cleaner g_Cleaner;
SMEXT_LINK(&g_Cleaner);
CDetour *g_pDetour = 0;
char ** g_szStrings;
int g_iStrings = 0;
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
DETOUR_DECL_MEMBER4(Detour_LogDirect, LoggingResponse_t, LoggingChannelID_t, channelID, LoggingSeverity_t, severity, Color, color, const tchar *, pMessage)
{
for(int i=0;i<g_iStrings;++i)
if(strstr(pMessage, g_szStrings[i])!=0)
return LR_CONTINUE;
return DETOUR_MEMBER_CALL(Detour_LogDirect)(channelID, severity, color, pMessage);
}
#else
DETOUR_DECL_STATIC2(Detour_DefSpew, SpewRetval_t, SpewType_t, channel, char *, text)
{
for(int i=0;i<g_iStrings;++i)
if(strstr(text, g_szStrings[i])!=0)
return SPEW_CONTINUE;
return DETOUR_STATIC_CALL(Detour_DefSpew)(channel, text);
}
#endif
#ifdef WIN32
//https://github.com/alliedmodders/sourcemod/blob/237db0504c7a59e394828446af3e8ca3d53ef647/extensions/sdktools/vglobals.cpp#L149
size_t UTIL_StringToSignature(const char *str, char buffer[], size_t maxlength)
{
size_t real_bytes = 0;
size_t length = strlen(str);
for (size_t i=0; i<length; i++)
{
if (real_bytes >= maxlength)
{
break;
}
buffer[real_bytes++] = (unsigned char)str[i];
if (str[i] == '\\'
&& str[i+1] == 'x')
{
if (i + 3 >= length)
{
continue;
}
/* Get the hex part */
char s_byte[3];
int r_byte;
s_byte[0] = str[i+2];
s_byte[1] = str[i+3];
s_byte[2] = '\n';
/* Read it as an integer */
sscanf(s_byte, "%x", &r_byte);
/* Save the value */
buffer[real_bytes-1] = (unsigned char)r_byte;
/* Adjust index */
i += 3;
}
}
return real_bytes;
}
#endif
bool Cleaner::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
SM_GET_IFACE(MEMORYUTILS, memutils);
CDetourManager::Init(g_pSM->GetScriptingEngine(), 0);
char szPath[256];
g_pSM->BuildPath(Path_SM, szPath, sizeof(szPath), "configs/cleaner.cfg");
FILE * file = fopen(szPath, "r");
if(file==NULL)
{
snprintf(error, maxlength, "Could not read configs/cleaner.cfg.");
return false;
}
int c, lines = 0;
do
{
c = fgetc(file);
++lines;
} while (c != EOF);
rewind(file);
int len;
g_szStrings = (char**)malloc(lines*sizeof(char**));
while(!feof(file))
{
g_szStrings[g_iStrings] = (char*)malloc(256*sizeof(char*));
if (fgets(g_szStrings[g_iStrings], 255, file) != NULL)
{
len = strlen(g_szStrings[g_iStrings]);
if(g_szStrings[g_iStrings][len-1]=='\r' || g_szStrings[g_iStrings][len-1]=='\n')
g_szStrings[g_iStrings][len-1]=0;
if(g_szStrings[g_iStrings][len-2]=='\r')
g_szStrings[g_iStrings][len-2]=0;
++g_iStrings;
}
}
fclose(file);
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
char ConfigError[128];
if(!gameconfs->LoadGameConfigFile("cleaner", &g_pGameConf, ConfigError, sizeof(ConfigError)))
{
if (error)
{
snprintf(error, maxlength, "cleaner.txt error : %s", ConfigError);
}
return false;
}
#ifdef PLATFORM_WINDOWS
HMODULE tier0 = GetModuleHandle("tier0.dll");
char sig[256];
size_t size = UTIL_StringToSignature(g_pGameConf->GetKeyValue("ServerConsolePrintSig_windows"), sig, sizeof(sig));
void * fn = memutils->FindPattern(tier0, sig, size);
#elif defined PLATFORM_LINUX
#if SOURCE_ENGINE == SE_LEFT4DEAD2
void * tier0 = dlopen("libtier0_srv.so", RTLD_NOW);
#else
void * tier0 = dlopen("libtier0.so", RTLD_NOW);
#endif
void * fn = memutils->ResolveSymbol(tier0, g_pGameConf->GetKeyValue("ServerConsolePrintSig_linux"));
#elif defined PLATFORM_APPLE
void * tier0 = dlopen("libtier0.dylib", RTLD_NOW);
void * fn = memutils->ResolveSymbol(tier0, g_pGameConf->GetKeyValue("ServerConsolePrintSig_mac"));
#endif
if(!fn)
{
snprintf(error, maxlength, "Failed to find signature. Please contact the author.");
return false;
}
#endif
#if SOURCE_ENGINE == SE_CSGO
#ifdef PLATFORM_LINUX
int offset = 0;
if (!g_pGameConf->GetOffset("ServerConsolePrint", &offset))
{
snprintf(error, maxlength, "Failed to get ServerConsolePrint offset.");
return false;
}
fn = (void *)((intptr_t)fn + offset);
#endif
#endif
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
g_pDetour = DETOUR_CREATE_MEMBER(Detour_LogDirect, fn);
#else
g_pDetour = DETOUR_CREATE_STATIC(Detour_DefSpew, (gpointer)GetSpewOutputFunc());
#endif
if (g_pDetour == NULL)
{
snprintf(error, maxlength, "Failed to initialize the detours. Please contact the author.");
return false;
}
g_pDetour->EnableDetour();
return true;
}
void Cleaner::SDK_OnUnload()
{
if(g_pDetour)
g_pDetour->Destroy();
delete [] g_szStrings;
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
gameconfs->CloseGameConfigFile(g_pGameConf);
#endif
}