Browse Source

Split API request into its own file w/ callback

API request is now callback-based so we can check DRY the CBL status
checks (instead of duplicating the functionality for
`OnClientAuithorized` and the command).
nosoop 6 years ago
parent
commit
80a883132f
2 changed files with 132 additions and 81 deletions
  1. 24 81
      scripting/source_cbl.sp
  2. 108 0
      scripting/source_cbl/webapi.sp

+ 24 - 81
scripting/source_cbl.sp

@@ -6,12 +6,10 @@
 #pragma semicolon 1
 #include <sourcemod>
 
-#include <steamtools>
-
 #pragma newdecls required
-#include <newdecl-handles/smjansson>
+#include "source_cbl/webapi.sp"
 
-#define PLUGIN_VERSION "0.1.0"
+#define PLUGIN_VERSION "0.2.0"
 public Plugin myinfo = {
 	name = "[CSRD] SourceCBL Integration",
 	author = "nosoop",
@@ -20,14 +18,8 @@ public Plugin myinfo = {
 	url = "https://git.csrd.science/"
 }
 
+#define REQUESTER_CONSOLE -1
 #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];
 
@@ -62,7 +54,7 @@ void RequestClientBanStatus(int client) {
 	char steamid64[64];
 	
 	if (GetClientAuthId(client, AuthId_SteamID64, steamid64, sizeof(steamid64))) {
-		QueryBanList(steamid64, GetClientUserId(client));
+		QueryBanList(steamid64, OnSteamAuthBanStatusReceived, GetClientUserId(client));
 	}
 }
 
@@ -72,79 +64,30 @@ public Action CheckCBLStatus(int client, int argc) {
 	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);
+	QueryBanList(steamid64, OnCommandBanStatusReceived,
+			client? GetClientUserId(client) : REQUESTER_CONSOLE);
 	
-	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);
+	return Plugin_Handled;
 }
 
-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];
+public void OnSteamAuthBanStatusReceived(const char[] steamid64, bool bBanned, int userid) {
+	// player in banlist, request ban
+	if (bBanned && 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.");
 			
-			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
+			LogToFile(g_CommunityKickLog, "Kicked \"%L\" from server.", client);
 		}
-		delete accountStatus;
+	}
+}
+
+public void OnCommandBanStatusReceived(const char[] steamid64, bool bBanned, int requester) {
+	int client = requester == REQUESTER_CONSOLE? 0 : GetClientOfUserId(requester);
+	
+	if (requester == REQUESTER_CONSOLE || client) {
+		ReplyToCommand(client, "Steam account %s CBL status: %b", steamid64, bBanned);
 	}
 }

+ 108 - 0
scripting/source_cbl/webapi.sp

@@ -0,0 +1,108 @@
+#pragma newdecls optional
+#include <steamtools>
+
+#pragma newdecls required
+#include <newdecl-handles/smjansson>
+
+#define SOURCECBL_REQUEST_BAN_ENDPOINT "https://sourcecbl.com/api/steam/"
+#define SOURCECBL_API_TIMEOUT 5
+
+typedef BanStatusCallback = function void(const char[] steamid64, bool bBanned, any data);
+
+/**
+ * Status codes.
+ */
+enum APIResponse {
+	Response_Success = 0,
+	Response_NotAuthorized
+};
+
+/**
+ * Queries the SourceCBL API for a ban on the specified SteamID64.
+ * User-facing function.
+ */
+void QueryBanList(const char[] steamid64, BanStatusCallback callback, any data = 0) {
+	// 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(data);
+	pack.WriteString(steamid64);
+	pack.WriteFunction(callback);
+	
+	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);
+}
+
+/** 
+ * Called when the response to the API request is received.
+ */
+public int OnAccountStatusReceived(HTTPRequestHandle request, bool bSuccess,
+		HTTPStatusCode status, DataPack pack) {
+	if (!bSuccess || status != HTTPStatusCode_OK) {
+		return;
+	}
+	
+	int maxlen = Steam_GetHTTPResponseBodySize(request) + 1;
+	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();
+	any data = pack.ReadCell();
+	char steamid64[64];
+	pack.ReadString(steamid64, sizeof(steamid64));
+	Function callback = pack.ReadFunction();
+	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) {
+		JSONInteger response = view_as<JSONInteger>(accountStatus.Get("response"));
+		APIResponse apiStatus = response?
+				view_as<APIResponse>(response.Value) : Response_Success;
+		delete response;
+		
+		JSONObjectIterator iterator;
+		if (apiStatus == Response_Success &&
+				(iterator = JSONObjectIterator.From(accountStatus))) {
+			char steamid64Key[64];
+			
+			bool bBanned;
+			do {
+				iterator.GetKey(steamid64Key, sizeof(steamid64Key));
+				if (StrEqual(steamid64Key, steamid64)) {
+					bBanned = true;
+				}
+			} while ((iterator.Next(accountStatus)));
+			
+			CallBanStatusCallback(callback, steamid64, bBanned, data);
+			// iterator auto-closes
+		} else if (apiStatus == Response_NotAuthorized) {
+			// TODO shut down everything
+		}
+		delete accountStatus;
+	}
+}
+
+/**
+ * Wrapper to isolate the callback function.
+ */
+static void CallBanStatusCallback(Function callback, const char[] steamid64, bool bBanned,
+		any data) {
+	Call_StartFunction(INVALID_HANDLE, callback);
+	Call_PushString(steamid64);
+	Call_PushCell(bBanned);
+	Call_PushCell(data);
+	Call_Finish();
+}