· 7 years ago · Jan 25, 2019, 09:32 PM
1#pragma semicolon 1
2
3#include <sourcemod>
4#include <SteamWorks>
5
6#pragma newdecls required
7
8#define PDAYS 30
9
10public Plugin myinfo =
11{
12 name = "[CSGO] VPN Block",
13 author = "PwnK, edited by VaLaKi.=D",
14 description = "VPN Block",
15 version = "2.0",
16 url = "http://sourcemod.net"
17};
18
19Database g_db;
20
21ConVar gcv_KickClients;
22ConVar gcv_url;
23ConVar gcv_response;
24
25public void OnPluginStart()
26{
27 LoadTranslations ("vpnblock.phrases");
28 if (SQL_CheckConfig("VPNBlock"))
29 Database.Connect(OnSqlConnect, "VPNBlock");
30 else
31 Database.Connect(OnSqlConnect, "default");
32 RegAdminCmd("sm_vbwhitelist", CommandWhiteList, ADMFLAG_ROOT, "sm_vbwhitelist \"<SteamID>\"");
33 RegAdminCmd("sm_vbunwhitelist", CommandUnWhiteList, ADMFLAG_ROOT, "sm_vbunwhitelist \"<SteamID>\"");
34
35 gcv_KickClients = CreateConVar("vpnblock_kickclients", "1", "1 = Kick and log client when he tries to join with a VPN 0 = only log", _, true, 0.0, true, 1.0);
36 gcv_url = CreateConVar("vpnblock_url", "http://antifrag.eu/checkVPN/?ip={IP}&mode=csgo", "The url used to check proxies.");
37 gcv_response = CreateConVar("vpnblock_response", "Y", "If the response contains this it means the player is using a VPN.");
38 AutoExecConfig(true, "VPNBlock");
39}
40
41public void OnSqlConnect(Database db, const char[] error, any data)
42{
43 if (db == null)
44 {
45 SetFailState("Databases don't work");
46 }
47 else
48 {
49 g_db = db;
50 g_db.Query(queryC, "CREATE TABLE IF NOT EXISTS `VPNBlock` (`playername` char(128) NOT NULL, `steamid` char(32) NOT NULL, `lastupdated` int(64) NOT NULL, `ip` char(32) NOT NULL, `proxy` boolean NOT NULL, PRIMARY KEY (`ip`))");
51 g_db.Query(queryI, "CREATE TABLE IF NOT EXISTS `VPNBlock_wl` (`steamid` char(32) NOT NULL, PRIMARY KEY (`steamid`))");
52 }
53}
54
55public void queryC(Database db, DBResultSet results, const char[] error, any data)
56{
57 if (results == null)
58 {
59 VPNBlock_Log(2, _, _, error);
60 return;
61 }
62 PruneDatabase();
63}
64
65public void OnClientAuthorized(int client, const char[] auth)
66{
67 if (!IsFakeClient(client))
68 {
69 char buffer[255], steamid[28];
70 GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid));
71 strcopy(steamid, sizeof(steamid), steamid[8]);
72 Format(buffer, sizeof(buffer), "SELECT * FROM `VPNBlock_wl` WHERE `steamid` = '%s'", steamid);
73 DBResultSet whitelist = SQL_Query(g_db, buffer);
74 if (whitelist == null)
75 {
76 char error[255];
77 SQL_GetError(g_db, error, sizeof(error));
78 VPNBlock_Log(2, _, _, error);
79 OnPluginStart();
80 }
81 else if (!SQL_FetchRow(whitelist))
82 {
83 char ip[30];
84 GetClientIP(client, ip, sizeof(ip));
85 Format(buffer, sizeof(buffer), "SELECT `proxy` FROM `VPNBlock` WHERE `ip` = '%s'", ip);
86 DBResultSet query = SQL_Query(g_db, buffer);
87 if (query == null)
88 {
89 char error[255];
90 SQL_GetError(g_db, error, sizeof(error));
91 VPNBlock_Log(2, _, _, error);
92 OnPluginStart();
93 }
94 else if (!SQL_FetchRow(query))
95 {
96 CheckIpHttp(ip, client);
97 }
98 else if (SQL_FetchInt(query, 0) == 1)
99 {
100 VPNBlock_Log(0, client, ip);
101 if (gcv_KickClients.BoolValue)
102 KickClient(client, "%t", "VPN Kick");
103 }
104 delete query;
105 }
106 delete whitelist;
107 }
108}
109
110void CheckIpHttp(char[] ip, int client)
111{
112 DataPack pack = new DataPack();
113 pack.WriteString(ip);
114 pack.WriteCell(client);
115 char url[85];
116 gcv_url.GetString(url, sizeof(url));
117 ReplaceString(url, sizeof(url), "{IP}", ip, true);
118 Handle CheckIp = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, url);
119 SteamWorks_SetHTTPCallbacks(CheckIp, HttpResponseCompleted, _, HttpResponseDataReceived);
120 SteamWorks_SetHTTPRequestContextValue(CheckIp, pack);
121 SteamWorks_SetHTTPRequestNetworkActivityTimeout(CheckIp, 5);
122 SteamWorks_SendHTTPRequest(CheckIp);
123}
124
125public int HttpRequestData(const char[] content, DataPack pack)
126{
127 char steamid[28], name[100], ip[30];
128 pack.Reset();
129 pack.ReadString(ip, sizeof(ip));
130 int client = pack.ReadCell();
131 delete pack;
132 if (!IsClientConnected(client))
133 return;
134 GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid));
135 GetClientName(client, name, sizeof(name));
136 int buffer_len = strlen(name) * 2 + 1;
137 char[] newname = new char[buffer_len];
138 SQL_EscapeString(g_db, name, newname, buffer_len);
139 int proxy;
140 char responsevpn[30];
141 gcv_response.GetString(responsevpn, sizeof(responsevpn));
142
143 if (StrContains(content, responsevpn) != -1)
144 {
145 VPNBlock_Log(0, client, ip);
146 if (gcv_KickClients.BoolValue)
147 KickClient(client, "%t", "VPN Kick");
148 proxy = 1;
149 }
150 else
151 {
152 proxy = 0;
153 }
154 char query[300];
155 Format(query, sizeof(query), "INSERT INTO `VPNBlock`(`playername`, `steamid`, `lastupdated`, `ip`, `proxy`) VALUES('%s', '%s', '%d', '%s', '%d');", newname, steamid, GetTime(), ip, proxy);
156 g_db.Query(queryI, query);
157}
158
159public int HttpResponseDataReceived(Handle request, bool failure, int offset, int bytesReceived, DataPack pack)
160{
161 SteamWorks_GetHTTPResponseBodyCallback(request, HttpRequestData, pack);
162 delete request;
163}
164
165public int HttpResponseCompleted(Handle request, bool failure, bool requestSuccessful, EHTTPStatusCode statusCode, DataPack pack)
166{
167 if(failure || !requestSuccessful)
168 {
169 VPNBlock_Log(1);
170 delete pack;
171 delete request;
172 }
173}
174
175public void queryI(Database db, DBResultSet results, const char[] error, any data)
176{
177 if (results == null)
178 {
179 VPNBlock_Log(2, _, _, error);
180 OnPluginStart();
181 }
182}
183
184void PruneDatabase()
185{
186 int maxlastupdated = GetTime() - (PDAYS * 86400);
187 char buffer[255];
188 Format(buffer, sizeof(buffer), "DELETE FROM `VPNBlock` WHERE `lastupdated`<'%d';", maxlastupdated);
189 g_db.Query(queryP, buffer);
190}
191
192public void queryP(Database db, DBResultSet results, const char[] error, any data)
193{
194 if (results == null)
195 {
196 VPNBlock_Log(2, _, _, error);
197 }
198}
199
200public Action CommandWhiteList(int client, int args)
201{
202 if (args != 1)
203 {
204 ReplyToCommand(client, "[SM] Usage: sm_vbwhitelist \"<SteamID>\"");
205 return Plugin_Handled;
206 }
207
208 WhiteList(true);
209 return Plugin_Handled;
210}
211
212public Action CommandUnWhiteList(int client, int args)
213{
214 if (args != 1)
215 {
216 ReplyToCommand(client, "[SM] Usage: sm_vbunwhitelist \"<SteamID>\"");
217 return Plugin_Handled;
218 }
219
220 WhiteList(false);
221 return Plugin_Handled;
222}
223
224void WhiteList(bool whitelist)
225{
226 char steamid[28];
227 GetCmdArgString(steamid, sizeof(steamid));
228 StripQuotes(steamid);
229 if (StrContains(steamid, "STEAM_") == 0)
230 strcopy(steamid, sizeof(steamid), steamid[8]);
231
232 int buffer_len = strlen(steamid) * 2 + 1;
233 char[] escsteamid = new char[buffer_len];
234 SQL_EscapeString(g_db, steamid, escsteamid, buffer_len);
235
236 char query[100];
237 if (whitelist)
238 Format(query, sizeof(query), "INSERT INTO `VPNBlock_wl`(`steamid`) VALUES('%s');", escsteamid);
239 else
240 Format(query, sizeof(query), "DELETE FROM `VPNBlock_wl` WHERE `steamid`='%s';", escsteamid);
241 g_db.Query(queryI, query);
242}
243
244void VPNBlock_Log(int logtype, int client = 0, char[] ip = "", const char[] error = "")
245{
246 char date[32];
247 FormatTime(date, sizeof(date), "%d/%m/%Y %H:%M:%S", GetTime());
248 char LogPath[PLATFORM_MAX_PATH];
249 BuildPath(Path_SM, LogPath, sizeof(LogPath), "logs/VPNBlock_Log.txt");
250 Handle logFile = OpenFile(LogPath, "a");
251 if (logtype == 0)
252 {
253 char steamid[28];
254 char name[100];
255 GetClientAuthId(client, AuthId_Steam2, steamid, sizeof(steamid));
256 GetClientName(client, name, sizeof(name));
257 WriteFileLine(logFile, "[VPNBlock] %T", "Log VPN Kick", LANG_SERVER, date, name, steamid, ip);
258 }
259 else if (logtype == 1)
260 {
261 WriteFileLine(logFile, "[VPNBlock] %T", "Http Error", LANG_SERVER, date);
262 }
263 else
264 {
265 WriteFileLine(logFile, "[VPNBlock] %T", "Query Failure", LANG_SERVER, date, error);
266 }
267 delete logFile;
268}