Browse Source

Actually commit the plugin

nosoop 6 years ago
parent
commit
1659547746
1 changed files with 150 additions and 0 deletions
  1. 150 0
      scripting/source_cbl.sp

+ 150 - 0
scripting/source_cbl.sp

@@ -0,0 +1,150 @@
+/**
+ * [CSRD] SourceCBL Integration
+ * 
+ * An optimized version of the SourceCBL plugin.
+ */
+#pragma semicolon 1
+#include <sourcemod>
+
+#include <steamtools>
+
+#pragma newdecls required
+#include <newdecl-handles/smjansson>
+
+#define PLUGIN_VERSION "0.1.0"
+public Plugin myinfo = {
+	name = "[CSRD] SourceCBL Integration",
+	author = "nosoop",
+	description = "Personal integartion of the SourceCBL API.",
+	version = PLUGIN_VERSION,
+	url = "https://git.csrd.science/"
+}
+
+#define INVALID_USERID -1
+#define SOURCECBL_REQUEST_BAN_ENDPOINT "https://sourcecbl.com/api/steam/"
+#define SOURCECBL_API_TIMEOUT 5
+
+enum APIResponse {
+	Response_Success = 0,
+	Response_NotAuthorized
+};
+
+char g_CommunityKickLog[PLATFORM_MAX_PATH];
+
+public void OnPluginStart() {
+	CreateConVar("sm_scbl_enabled", "1",
+			"Teamwork.TF convar for A2S_RULES's sake.  Does absolutely nothing else.",
+			FCVAR_NOTIFY);
+	
+	// really though, does this actually matter?  we're just going to skip the thing anyways
+	int port = FindConVar("hostport").IntValue;
+	char portString[6];
+	IntToString(port, portString, sizeof(portString));
+	
+	
+	RegAdminCmd("cbl_check_steamid", CheckCBLStatus, ADMFLAG_ROOT);
+	
+	BuildPath(Path_SM, g_CommunityKickLog, sizeof(g_CommunityKickLog), "logs/sourcecbl.log");
+}
+
+public void OnClientAuthorized(int client) {
+	if (!IsFakeClient(client) && !SkipCommunityBanListCheck(client)) {
+		RequestClientBanStatus(client);
+	}
+}
+
+bool SkipCommunityBanListCheck(int client) {
+	// TODO check if account is whitelisted (command group / keyvalues / clientprefs cache, etc.)
+	return CheckCommandAccess(client, "cbl_whitelist", 0);
+}
+
+void RequestClientBanStatus(int client) {
+	char steamid64[64];
+	
+	if (GetClientAuthId(client, AuthId_SteamID64, steamid64, sizeof(steamid64))) {
+		QueryBanList(steamid64, GetClientUserId(client));
+	}
+}
+
+public Action CheckCBLStatus(int client, int argc) {
+	char steamid64[64];
+	GetCmdArgString(steamid64, sizeof(steamid64));
+	StripQuotes(steamid64);
+	
+	// TODO make sure this is a valid steamid
+	QueryBanList(steamid64);
+}
+
+void QueryBanList(const char[] steamid64, int userid = INVALID_USERID) {
+	// we need to use the steamid64 later on down the line to verify the request even if the
+	// player disconnects
+	DataPack pack = new DataPack();
+	pack.WriteCell(userid);
+	pack.WriteString(steamid64);
+	
+	HTTPRequestHandle request = Steam_CreateHTTPRequest(HTTPMethod_GET,
+			SOURCECBL_REQUEST_BAN_ENDPOINT);
+	Steam_SetHTTPRequestNetworkActivityTimeout(request, SOURCECBL_API_TIMEOUT);
+	Steam_SetHTTPRequestGetOrPostParameter(request, "steamid", steamid64);
+	
+	Steam_SendHTTPRequest(request, OnAccountStatusReceived, pack);
+}
+
+public int OnAccountStatusReceived(HTTPRequestHandle request, bool bSuccess,
+		HTTPStatusCode status, DataPack pack) {
+	if (!bSuccess || status != HTTPStatusCode_OK) {
+		return;
+	}
+	
+	int maxlen = Steam_GetHTTPResponseBodySize(request);
+	char[] buffer = new char[maxlen];
+	
+	Steam_GetHTTPResponseBodyData(request, buffer, maxlen);
+	Steam_ReleaseHTTPRequest(request);
+	
+	// they should've just gone with outputting VDF so I could just slap that shit into a buffer and call it a day
+	// also would've preferred SteamID3 so I wouldn't have to use strings
+	
+	pack.Reset();
+	int userid = pack.ReadCell();
+	char steamid64[64];
+	pack.ReadString(steamid64, sizeof(steamid64));
+	delete pack;
+	
+	/**
+	 * The API response (currently) has SteamID64 strings as keys for players that are banned.
+	 * It's going to be a painus in the anus if they change the API again.
+	 */
+	JSONObject accountStatus = view_as<JSONObject>(json_load(buffer));
+	if (accountStatus) {
+		APIResponse apiStatus = view_as<APIResponse>(
+				accountStatus.GetInt("response", view_as<int>(Response_Success)) );
+		
+		JSONObjectIterator iterator;
+		if (apiStatus == Response_Success &&
+				(iterator = JSONObjectIterator.From(accountStatus))) {
+			char steamid64Key[64];
+			
+			do {
+				iterator.GetKey(steamid64Key, sizeof(steamid64Key));
+				if (StrEqual(steamid64Key, steamid64)) {
+					// player in banlist, request ban
+					if (userid != INVALID_USERID) {
+						int client = GetClientOfUserId(userid);
+						if (client) {
+							KickClient(client,
+									"You have been banned by SourceCBL for hacking / cheating."
+									... "\nVisit www.SourceCBL.com for more information.");
+							
+							LogToFile(g_CommunityKickLog, "Kicked \"%L\" from server.", client);
+						}
+					}
+				}
+			} while ((iterator.Next(accountStatus)));
+			// iterator auto-closes
+		} else if (apiStatus == Response_NotAuthorized) {
+			// TODO shut down everything
+		}
+		delete accountStatus;
+	}
+}