sourcemod 1.13 upgrade. moved all plugins from steamworks to ripext. added smjanson and asyncsocket.inc an extra time so its easier to find. updated plugins that would not compile with 1.13

This commit is contained in:
jenz
2026-09-22 01:55:09 +02:00
parent 789b8ebef9
commit 2947bef434
17 changed files with 2131 additions and 462 deletions
@@ -4,7 +4,7 @@
#include <sourcemod> #include <sourcemod>
#include <sdktools> #include <sdktools>
#include <SteamWorks> #include <ripext>
#include <cstrike> #include <cstrike>
#include <AdvancedTargeting> #include <AdvancedTargeting>
@@ -437,17 +437,14 @@ public void OnClientAuthorized(int client, const char[] auth)
char sSteam64ID[32]; char sSteam64ID[32];
Steam32IDtoSteam64ID(auth, sSteam64ID, sizeof(sSteam64ID)); Steam32IDtoSteam64ID(auth, sSteam64ID, sizeof(sSteam64ID));
// format=json instead of format=vdf: ripext only exposes the response body
// as decoded JSON, so we ask Steam's own API for JSON directly rather than
// working around a missing raw-body accessor.
static char sRequest[256]; static char sRequest[256];
FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=%s&steamid=%s&relationship=friend&format=vdf", STEAM_API_KEY, sSteam64ID); FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=%s&steamid=%s&relationship=friend&format=json", STEAM_API_KEY, sSteam64ID);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); HTTPRequest hRequest = new HTTPRequest(sRequest);
if (!hRequest || hRequest.Get(OnTransferComplete, client);
!SteamWorks_SetHTTPRequestContextValue(hRequest, client) ||
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
CloseHandle(hRequest);
}
} }
public void OnClientDisconnect(int client) public void OnClientDisconnect(int client)
@@ -458,52 +455,38 @@ public void OnClientDisconnect(int client)
g_FriendsArray[client] = INVALID_HANDLE; g_FriendsArray[client] = INVALID_HANDLE;
} }
public int OnTransferComplete(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, int client) public void OnTransferComplete(HTTPResponse response, any client)
{ {
if(bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK) if(response.Status != HTTPStatus_OK || response.Data == null)
{ {
// Private profile or maybe steam down? // Private profile or maybe steam down?
//LogError("SteamAPI HTTP Response failed: %d", eStatusCode); //LogError("SteamAPI HTTP Response failed: %d", response.Status);
CloseHandle(hRequest);
return; return;
} }
int Length; APIWebResponse(view_as<JSONObject>(response.Data), client);
SteamWorks_GetHTTPResponseBodySize(hRequest, Length);
char[] sData = new char[Length];
SteamWorks_GetHTTPResponseBodyData(hRequest, sData, Length);
//SteamWorks_GetHTTPResponseBodyCallback(hRequest, APIWebResponse, client);
CloseHandle(hRequest);
APIWebResponse(sData, client);
} }
public void APIWebResponse(const char[] sData, int client) public void APIWebResponse(JSONObject Response, int client)
{ {
KeyValues Response = new KeyValues("SteamAPIResponse"); if(!Response.HasKey("friendslist"))
if(!Response.ImportFromString(sData, "SteamAPIResponse"))
{ {
LogError("ImportFromString(sData, \"SteamAPIResponse\") failed."); LogError("GetFriendList response missing \"friendslist\" key.");
delete Response; delete Response;
return; return;
} }
if(!Response.JumpToKey("friends")) JSONObject friendslist = view_as<JSONObject>(Response.Get("friendslist"));
// No friends, or private profile - Steam returns {"friendslist":{}} in that case.
if(!friendslist.HasKey("friends"))
{ {
LogError("JumpToKey(\"friends\") failed."); delete friendslist;
delete Response; delete Response;
return; return;
} }
// No friends? JSONArray friends = view_as<JSONArray>(friendslist.Get("friends"));
if(!Response.GotoFirstSubKey())
{
//LogError("GotoFirstSubKey() failed.");
delete Response;
return;
}
if(g_FriendsArray[client] != INVALID_HANDLE) if(g_FriendsArray[client] != INVALID_HANDLE)
CloseHandle(g_FriendsArray[client]); CloseHandle(g_FriendsArray[client]);
@@ -511,18 +494,20 @@ public void APIWebResponse(const char[] sData, int client)
g_FriendsArray[client] = CreateArray(); g_FriendsArray[client] = CreateArray();
char sCommunityID[32]; char sCommunityID[32];
do int len = friends.Length;
for(int i = 0; i < len; i++)
{ {
Response.GetString("steamid", sCommunityID, sizeof(sCommunityID)); JSONObject friendEntry = view_as<JSONObject>(friends.Get(i));
if(friendEntry.GetString("steamid", sCommunityID, sizeof(sCommunityID)))
PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID)); PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID));
delete friendEntry;
} }
while(Response.GotoNextKey());
delete friends;
delete friendslist;
delete Response; delete Response;
} }
stock bool Steam32IDtoSteam64ID(const char[] sSteam32ID, char[] sSteam64ID, int Size) stock bool Steam32IDtoSteam64ID(const char[] sSteam32ID, char[] sSteam64ID, int Size)
{ {
if(strlen(sSteam32ID) < 11 || strncmp(sSteam32ID[0], "STEAM_0:", 8)) if(strlen(sSteam32ID) < 11 || strncmp(sSteam32ID[0], "STEAM_0:", 8))
@@ -634,3 +619,4 @@ public int Native_ReadClientFriends(Handle plugin, int numParams)
return 0; return 0;
} }
+12 -7
View File
@@ -426,9 +426,12 @@ NotifyAdmins(int client, const char[] sReason)
if(IsClientInGame(i) && !IsFakeClient(i) && CheckCommandAccess(i, "sm_stats", ADMFLAG_GENERIC)) if(IsClientInGame(i) && !IsFakeClient(i) && CheckCommandAccess(i, "sm_stats", ADMFLAG_GENERIC))
{ {
CPrintToChat(i, "{green}[SM]{default} %L has been detected for {red}%s{default}, please check your console!", client, sReason); CPrintToChat(i, "{green}[SM]{default} %L has been detected for {red}%s{default}, please check your console!", client, sReason);
FormatStats(i, client); char sBuffer[2000];
FormatStats(i, client, sBuffer, 0);
PrintToConsole(client, "%s", "\n"); PrintToConsole(client, "%s", "\n");
FormatStreak(i, client, 0); int len = FormatStats(-1, client, sBuffer, sizeof(sBuffer));
sBuffer[len++] = '\n';
FormatStreak(i, client, 0, sBuffer[len], sizeof(sBuffer) - len);
} }
} }
@@ -464,12 +467,13 @@ public Action Command_Stats(int client, int argc)
for(int i = 0; i < iTargetCount; i++) for(int i = 0; i < iTargetCount; i++)
{ {
FormatStats(client, iTargets[i]); char sBuffer[2000];
FormatStats(i, client, sBuffer, 0);
PrintToConsole(client, "%s", "\n"); PrintToConsole(client, "%s", "\n");
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
{ {
FormatStreak(client, iTargets[i], j); FormatStreak(client, iTargets[i], j, sBuffer[0], sizeof(sBuffer) - 0);
PrintToConsole(client, "%s", "\n"); PrintToConsole(client, "%s", "\n");
} }
} }
@@ -509,13 +513,14 @@ public Action Command_Streak(int client, int argc)
for(int i = 0; i < iTargetCount; i++) for(int i = 0; i < iTargetCount; i++)
{ {
FormatStreak(client, iTargets[i], iStreak); char sBuffer[2000];
FormatStreak(client, iTargets[i], iStreak, sBuffer[0], 0);
} }
return Plugin_Handled; return Plugin_Handled;
} }
int FormatStats(int client, int iTarget, char[] sBuf=0, int len=0) int FormatStats(int client, int iTarget, char[] sBuf, int len=0)
{ {
int iUserID = GetClientUserId(iTarget); int iUserID = GetClientUserId(iTarget);
char sAuth[32]; char sAuth[32];
@@ -545,7 +550,7 @@ int FormatStats(int client, int iTarget, char[] sBuf=0, int len=0)
return iBuf; return iBuf;
} }
int FormatStreak(int client, int iTarget, int iStreak, char[] sBuf=0, int len=0) int FormatStreak(int client, int iTarget, int iStreak, char[] sBuf, int len=0)
{ {
int iUserID = GetClientUserId(iTarget); int iUserID = GetClientUserId(iTarget);
char sAuth[32]; char sAuth[32];
+10 -5
View File
@@ -248,7 +248,8 @@ public void OnMapStart()
if(StrEqual(sMethod, "breakable")) if(StrEqual(sMethod, "breakable"))
{ {
char sBreakable[64]; char sBreakable[64];
if(!KvConfig.GetString("breakable", sBreakable, sizeof(sBreakable))) KvConfig.GetString("breakable", sBreakable, sizeof(sBreakable), "not found");
if(StrEqual(sBreakable, "not found"))
{ {
LogError("Could not find \"breakable\" in \"%s\"", sSection); LogError("Could not find \"breakable\" in \"%s\"", sSection);
continue; continue;
@@ -263,7 +264,8 @@ public void OnMapStart()
else if(StrEqual(sMethod, "counter")) else if(StrEqual(sMethod, "counter"))
{ {
char sCounter[64]; char sCounter[64];
if(!KvConfig.GetString("counter", sCounter, sizeof(sCounter))) KvConfig.GetString("counter", sCounter, sizeof(sCounter), "not found");
if (StrEqual(sCounter, "not found"))
{ {
LogError("Could not find \"counter\" in \"%s\"", sSection); LogError("Could not find \"counter\" in \"%s\"", sSection);
continue; continue;
@@ -278,21 +280,24 @@ public void OnMapStart()
else if(StrEqual(sMethod, "hpbar")) else if(StrEqual(sMethod, "hpbar"))
{ {
char sIterator[64]; char sIterator[64];
if(!KvConfig.GetString("iterator", sIterator, sizeof(sIterator))) KvConfig.GetString("iterator", sIterator, sizeof(sIterator), "not found");
if (StrEqual(sIterator, "not found"))
{ {
LogError("Could not find \"iterator\" in \"%s\"", sSection); LogError("Could not find \"iterator\" in \"%s\"", sSection);
continue; continue;
} }
char sCounter[64]; char sCounter[64];
if(!KvConfig.GetString("counter", sCounter, sizeof(sCounter))) KvConfig.GetString("counter", sCounter, sizeof(sCounter), "not found");
if (StrEqual(sCounter, "not found"))
{ {
LogError("Could not find \"counter\" in \"%s\"", sSection); LogError("Could not find \"counter\" in \"%s\"", sSection);
continue; continue;
} }
char sBackup[64]; char sBackup[64];
if(!KvConfig.GetString("backup", sBackup, sizeof(sBackup))) KvConfig.GetString("backup", sBackup, sizeof(sBackup), "not found");
if (StrEqual(sBackup, "not found"))
{ {
LogError("Could not find \"backup\" in \"%s\"", sSection); LogError("Could not find \"backup\" in \"%s\"", sSection);
continue; continue;
+40 -49
View File
@@ -4,7 +4,7 @@
#include <basecomm> #include <basecomm>
#include <ccc> #include <ccc>
#include <clientprefs> #include <clientprefs>
#include <SteamWorks> #include <ripext>
#tryinclude <zombiereloaded> #tryinclude <zombiereloaded>
#include <selfmute> #include <selfmute>
#include <connect> #include <connect>
@@ -22,6 +22,8 @@ bool g_bSkipInfection = false;
char g_sLastWebclientIp[64]; char g_sLastWebclientIp[64];
int g_iHttpFileCounter;
public Plugin myinfo = public Plugin myinfo =
{ {
name = "NoSteam CELT Voice override", name = "NoSteam CELT Voice override",
@@ -145,28 +147,17 @@ public void SendWebclientNameToSignaling(const char[] webclientName)
// Adjust port/path to match your signaling servers actual endpoint // Adjust port/path to match your signaling servers actual endpoint
FormatEx(url, sizeof(url), "http://127.0.0.1:3000/webclient-name"); FormatEx(url, sizeof(url), "http://127.0.0.1:3000/webclient-name");
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, url); HTTPRequest hRequest = new HTTPRequest(url);
if (hRequest == null)
{
return;
}
// Send the name as a POST body parameter // Send the name as a POST body parameter
SteamWorks_SetHTTPRequestGetOrPostParameter(hRequest, "name", webclientName); hRequest.AppendFormParam("name", "%s", webclientName);
hRequest.PostForm(OnWebclientNamePosted);
if (!SteamWorks_SetHTTPCallbacks(hRequest, OnWebclientNamePosted) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
delete hRequest;
}
} }
public int OnWebclientNamePosted(Handle hRequest, bool bFailure, bool bRequestSuccessful, public void OnWebclientNamePosted(HTTPResponse response, any value)
EHTTPStatusCode eStatusCode, any data)
{ {
// Fire-and-forget: we dont care about the response, just clean up. // Fire-and-forget: we dont care about the response. ripext closes the
delete hRequest; // request handle for us once this callback returns.
return 0;
} }
public void OnMapStart() public void OnMapStart()
@@ -276,53 +267,53 @@ public Action Timer_SendVoiceInit(Handle timer, int Serial)
* If the IP has changed since the last * If the IP has changed since the last
* check and a webclient player is currently connected, forces them to * check and a webclient player is currently connected, forces them to
* reconnect with the new password via ClientCommand. * reconnect with the new password via ClientCommand.
*
* ripext's HTTPResponse only exposes the body as decoded JSON, unlike
* SteamWorks' GetHTTPResponseBodyCallback which handed back a plain char[].
* Rather than change the signaling server's response format, we use
* HTTPRequest.DownloadFile() to write the raw body to a temp file and read
* it back as plain text, keeping the endpoint untouched.
**/ **/
public void PollWebclientCurrentIp() public void PollWebclientCurrentIp()
{ {
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, "http://127.0.0.1:3000/webclient-current-ip"); g_iHttpFileCounter++;
if (hRequest == null)
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "data/nosteamcelt_ip_%d.tmp", g_iHttpFileCounter);
HTTPRequest hRequest = new HTTPRequest("http://127.0.0.1:3000/webclient-current-ip");
hRequest.DownloadFile(sPath, OnWebclientCurrentIpDownloaded, g_iHttpFileCounter);
}
public void OnWebclientCurrentIpDownloaded(HTTPStatus status, any value)
{ {
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "data/nosteamcelt_ip_%d.tmp", value);
if (status != HTTPStatus_OK)
{
DeleteFile(sPath);
return; return;
} }
if (!SteamWorks_SetHTTPCallbacks(hRequest, OnWebclientCurrentIpReceived) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
delete hRequest;
}
}
public int OnWebclientCurrentIpReceived(Handle hRequest, bool bFailure, bool bRequestSuccessful,
EHTTPStatusCode eStatusCode, any data)
{
if (bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
{
delete hRequest;
return 0;
}
int bodySize;
bool gotSize = SteamWorks_GetHTTPResponseBodySize(hRequest, bodySize);
char newIp[64]; char newIp[64];
newIp[0] = '\0'; newIp[0] = '\0';
if (gotSize && bodySize > 0 && bodySize < sizeof(newIp)) File hFile = OpenFile(sPath, "r");
if (hFile != null)
{ {
SteamWorks_GetHTTPResponseBodyData(hRequest, newIp, bodySize); hFile.ReadLine(newIp, sizeof(newIp));
delete hFile;
} }
DeleteFile(sPath);
delete hRequest; TrimString(newIp);
if (newIp[0] == '\0') if (newIp[0] == '\0')
{ return;
return 0;
}
if (StrEqual(newIp, g_sLastWebclientIp)) if (StrEqual(newIp, g_sLastWebclientIp))
{ return;
return 0;
}
for (int i = 1; i <= MaxClients; i++) for (int i = 1; i <= MaxClients; i++)
{ {
@@ -334,7 +325,6 @@ public int OnWebclientCurrentIpReceived(Handle hRequest, bool bFailure, bool bRe
break; break;
} }
} }
return 0;
} }
public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255]) public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255])
@@ -364,3 +354,4 @@ stock bool IsValidClient(int client)
return true; return true;
return false; return false;
} }
+70 -216
View File
@@ -2,9 +2,8 @@
#include <basecomm> #include <basecomm>
#include <sourcemod> #include <sourcemod>
#include <SteamWorks> #include <ripext>
#include <regex> #include <regex>
#include <smjansson>
#include <multicolors> #include <multicolors>
#include <sdktools> #include <sdktools>
#include <AFKManager> #include <AFKManager>
@@ -139,6 +138,9 @@ public void OnAdminAFKTimeChanged(ConVar convar, const char[] oldValue, const ch
g_iAdminAFKTime = g_cvAdminAFKTime.IntValue; g_iAdminAFKTime = g_cvAdminAFKTime.IntValue;
} }
//----------------------------------------------------------------------------------------------------
// Purpose: Steam player summary lookup (avatar) - now via ripext, JSON instead of VDF
//----------------------------------------------------------------------------------------------------
public void OnClientAuthorized(int client, const char[] sAuthID32) public void OnClientAuthorized(int client, const char[] sAuthID32)
{ {
if (IsFakeClient(client)) if (IsFakeClient(client))
@@ -149,19 +151,44 @@ public void OnClientAuthorized(int client, const char[] sAuthID32)
if (!Steam32IDtoSteam64ID(sAuthID32, sAuthID64, sizeof(sAuthID64))) if (!Steam32IDtoSteam64ID(sAuthID32, sAuthID64, sizeof(sAuthID64)))
return; return;
static char sRequest[256]; char sRequest[256];
FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s&format=vdf", STEAM_API_KEY, sAuthID64); FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s&format=json", STEAM_API_KEY, sAuthID64);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); HTTPRequest req = new HTTPRequest(sRequest);
req.Get(OnTransferComplete, GetClientSerial(client));
if (!hRequest ||
!SteamWorks_SetHTTPRequestContextValue(hRequest, client) ||
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
delete hRequest;
} }
public void OnTransferComplete(HTTPResponse response, any serial)
{
int client = GetClientFromSerial(serial);
if (!client) //Player disconnected.
return;
if (response.Status != HTTPStatus_OK || response.Data == null)
return;
APIWebResponse(view_as<JSONObject>(response.Data), client);
}
public void APIWebResponse(JSONObject root, int client)
{
if (!root.HasKey("players"))
return;
JSONArray players = view_as<JSONArray>(root.Get("players"));
if (players == null || !players.Length)
{
delete players;
return;
}
JSONObject player = view_as<JSONObject>(players.Get(0));
player.GetString("avatarfull", g_sAvatarURL[client], sizeof(g_sAvatarURL[]));
delete player;
delete players;
} }
public Action Command_PrintToAdminChat(int args) public Action Command_PrintToAdminChat(int args)
@@ -197,6 +224,9 @@ public Action Command_PrintToAllChat(int args)
return Plugin_Handled; return Plugin_Handled;
} }
//----------------------------------------------------------------------------------------------------
// Purpose: Drains the rate-limit queue - now via ripext
//----------------------------------------------------------------------------------------------------
public Action Timer_DataProcessor(Handle hThis) public Action Timer_DataProcessor(Handle hThis)
{ {
if (!g_bProcessingData) if (!g_bProcessingData)
@@ -205,8 +235,6 @@ public Action Timer_DataProcessor(Handle hThis)
if (g_iRatelimitRemaining == 0 && GetTime() < g_iRatelimitReset) if (g_iRatelimitRemaining == 0 && GetTime() < g_iRatelimitReset)
return Plugin_Handled; return Plugin_Handled;
//PrintToServer("[Timer_DataProcessor] Array Length #1: %d", g_arrQueuedMessages.Length);
char sContent[1024]; char sContent[1024];
g_arrQueuedMessages.GetString(0, sContent, sizeof(sContent)); g_arrQueuedMessages.GetString(0, sContent, sizeof(sContent));
g_arrQueuedMessages.Erase(0); g_arrQueuedMessages.Erase(0);
@@ -218,28 +246,13 @@ public Action Timer_DataProcessor(Handle hThis)
if (g_arrQueuedMessages.Length == 0) if (g_arrQueuedMessages.Length == 0)
g_bProcessingData = false; g_bProcessingData = false;
//PrintToServer("[Timer_DataProcessor] Array Length #2: %d", g_arrQueuedMessages.Length); JSONObject data = JSONObject.FromString(sContent);
//PrintToServer("%s | %s", sURL, sContent); HTTPRequest req = new HTTPRequest(sURL);
req.Post(data, OnHTTPRequestCompleted);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sURL); delete data;
JSONObject RequestJSON = view_as<JSONObject>(json_load(sContent));
if (!hRequest ||
!SteamWorks_SetHTTPRequestContextValue(hRequest, RequestJSON) ||
!SteamWorks_SetHTTPCallbacks(hRequest, OnHTTPRequestCompleted) ||
!SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sContent, strlen(sContent)) ||
!SteamWorks_SetHTTPRequestNetworkActivityTimeout(hRequest, 10) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
LogError("Discord SteamWorks_CreateHTTPRequest failed.");
delete RequestJSON;
delete hRequest;
return Plugin_Handled;
}
return Plugin_Handled; return Plugin_Handled;
} }
@@ -300,27 +313,11 @@ stock void Discord_MakeStringSafe(const char[] sOrigin, char[] sOut, int iOutSiz
{ {
if (sOrigin[i] < 0x20 && sOrigin[i] != 0x0) if (sOrigin[i] < 0x20 && sOrigin[i] != 0x0)
{ {
//sOut[iCurIndex] = 0x20;
//iCurIndex++;
continue; continue;
} }
switch (sOrigin[i]) switch (sOrigin[i])
{ {
// case '"':
// {
// strcopy(sOut[iCurIndex], iOutSize, "\\u0022");
// iCurIndex += 6;
// continue;
// }
// case '\\':
// {
// strcopy(sOut[iCurIndex], iOutSize, "\\u005C");
// iCurIndex += 6;
// continue;
// }
case '@': case '@':
{ {
strcopy(sOut[iCurIndex], iOutSize, "@"); //@ + zero-width space strcopy(sOut[iCurIndex], iOutSize, "@"); //@ + zero-width space
@@ -358,102 +355,12 @@ stock void Discord_MakeStringSafe(const char[] sOrigin, char[] sOut, int iOutSiz
} }
} }
stock int OnTransferComplete(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, int client) //----------------------------------------------------------------------------------------------------
{ // Purpose: Webhook POST helper - now via ripext
if (bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK) //----------------------------------------------------------------------------------------------------
{
if (eStatusCode != k_EHTTPStatusCode429TooManyRequests)
{
LogError("SteamAPI HTTP Response failed: %d", eStatusCode);
}
delete hRequest;
return 0;
}
int iBodyLength;
SteamWorks_GetHTTPResponseBodySize(hRequest, iBodyLength);
char[] sData = new char[iBodyLength];
SteamWorks_GetHTTPResponseBodyData(hRequest, sData, iBodyLength);
delete hRequest;
APIWebResponse(sData, client);
return 0;
}
stock void APIWebResponse(const char[] sData, int client)
{
KeyValues kvResponse = new KeyValues("SteamAPIResponse");
if (!kvResponse.ImportFromString(sData, "SteamAPIResponse"))
{
//LogError("kvResponse.ImportFromString(\"SteamAPIResponse\") in APIWebResponse failed.");
delete kvResponse;
return;
}
if (!kvResponse.JumpToKey("players"))
{
//LogError("kvResponse.JumpToKey(\"players\") in APIWebResponse failed.");
delete kvResponse;
return;
}
if (!kvResponse.GotoFirstSubKey())
{
//LogError("kvResponse.GotoFirstSubKey() in APIWebResponse failed.");
delete kvResponse;
return;
}
kvResponse.GetString("avatarfull", g_sAvatarURL[client], sizeof(g_sAvatarURL[]));
delete kvResponse;
}
stock void HTTPPostJSON(const char[] sURL, const char[] sText)
{
// if (g_iRatelimitRemaining > 0 && !g_bProcessingData && GetTime() < g_iRatelimitReset)
// {
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sURL);
JSONObject RequestJSON = view_as<JSONObject>(json_load(sText));
if (!hRequest ||
!SteamWorks_SetHTTPRequestContextValue(hRequest, RequestJSON) ||
!SteamWorks_SetHTTPCallbacks(hRequest, OnHTTPRequestCompleted) ||
!SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sText, strlen(sText)) ||
!SteamWorks_SetHTTPRequestNetworkActivityTimeout(hRequest, 15) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
LogError("Discord SteamWorks_CreateHTTPRequest failed.");
delete RequestJSON;
delete hRequest;
return;
}
// }
// else
// {
// g_arrQueuedMessages.PushString(sText);
// g_arrQueuedMessages.PushString(sURL);
// g_bProcessingData = true;
// }
//delete hRequest;
}
stock void Discord_POST(const char[] sURL, char[] sText, bool bUsingUsername=false, char[] sUsername=NULL_STRING, bool bUsingAvatar=false, char[] sAvatarURL=NULL_STRING, bool bSafe=true, bool bTimestamp=true) stock void Discord_POST(const char[] sURL, char[] sText, bool bUsingUsername=false, char[] sUsername=NULL_STRING, bool bUsingAvatar=false, char[] sAvatarURL=NULL_STRING, bool bSafe=true, bool bTimestamp=true)
{ {
//PrintToServer("[Discord_POST] Called with text: %s", sText); JSONObject hJSONRoot = new JSONObject();
JSONRootNode hJSONRoot = new JSONObject();
char sSafeText[4096]; char sSafeText[4096];
char sFinal[4096]; char sFinal[4096];
@@ -463,13 +370,13 @@ stock void Discord_POST(const char[] sURL, char[] sText, bool bUsingUsername=fal
TrimString(sUsername); TrimString(sUsername);
if (g_Regex_Clyde.Match(sUsername) > 0 || strlen(sUsername) < 2) if (g_Regex_Clyde.Match(sUsername) > 0 || strlen(sUsername) < 2)
(view_as<JSONObject>(hJSONRoot)).SetString("username", "Invalid Name"); hJSONRoot.SetString("username", "Invalid Name");
else else
(view_as<JSONObject>(hJSONRoot)).SetString("username", sUsername); hJSONRoot.SetString("username", sUsername);
} }
if (bUsingAvatar) if (bUsingAvatar)
(view_as<JSONObject>(hJSONRoot)).SetString("avatar_url", sAvatarURL); hJSONRoot.SetString("avatar_url", sAvatarURL);
if (bSafe) if (bSafe)
{ {
@@ -488,85 +395,61 @@ stock void Discord_POST(const char[] sURL, char[] sText, bool bUsingUsername=fal
Format(sSafeText, sizeof(sSafeText), "[ *%s* ] %s", sTime, sText); Format(sSafeText, sizeof(sSafeText), "[ *%s* ] %s", sTime, sText);
} }
(view_as<JSONObject>(hJSONRoot)).SetString("content", sSafeText); hJSONRoot.SetString("content", sSafeText);
(view_as<JSONObject>(hJSONRoot)).ToString(sFinal, sizeof(sFinal), 0);
//hJSONRoot.DumpToServer();
delete hJSONRoot;
if ((g_iRatelimitRemaining > 0 || GetTime() >= g_iRatelimitReset) && !g_bProcessingData) if ((g_iRatelimitRemaining > 0 || GetTime() >= g_iRatelimitReset) && !g_bProcessingData)
{ {
//PrintToServer("[Discord_POST] Have allowances and not processing data"); HTTPRequest req = new HTTPRequest(sURL);
req.Post(hJSONRoot, OnHTTPRequestCompleted);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sURL); delete hJSONRoot;
JSONObject RequestJSON = view_as<JSONObject>(json_load(sFinal));
if (!hRequest ||
!SteamWorks_SetHTTPRequestContextValue(hRequest, RequestJSON) ||
!SteamWorks_SetHTTPCallbacks(hRequest, OnHTTPRequestCompleted) ||
!SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sFinal, strlen(sFinal)) ||
!SteamWorks_SetHTTPRequestNetworkActivityTimeout(hRequest, 10) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
LogError("Discord SteamWorks_CreateHTTPRequest failed.");
delete RequestJSON;
delete hRequest;
return;
}
} }
else else
{ {
//PrintToServer("[Discord_POST] Have allowances? [%s] | Is processing data? [%s]", g_iRatelimitRemaining > 0 ? "YES":"NO", g_bProcessingData?"YES":"NO"); hJSONRoot.ToString(sFinal, sizeof(sFinal), 0);
delete hJSONRoot;
g_arrQueuedMessages.PushString(sFinal); g_arrQueuedMessages.PushString(sFinal);
g_arrQueuedMessages.PushString(sURL); g_arrQueuedMessages.PushString(sURL);
g_bProcessingData = true; g_bProcessingData = true;
} }
//delete hRequest; //nonono
} }
public int OnHTTPRequestCompleted(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, JSONObject RequestJSON) public void OnHTTPRequestCompleted(HTTPResponse response, any value)
{ {
if (bFailure || !bRequestSuccessful || (eStatusCode != k_EHTTPStatusCode200OK && eStatusCode != k_EHTTPStatusCode204NoContent)) if (response.Status != HTTPStatus_OK && response.Status != HTTPStatus_NoContent)
{ {
if (eStatusCode != k_EHTTPStatusCode429TooManyRequests) if (response.Status != HTTPStatus_TooManyRequests)
LogError("Discord HTTP request failed: %d", eStatusCode); LogError("Discord HTTP request failed: %d", response.Status);
if (eStatusCode == k_EHTTPStatusCode400BadRequest) if (response.Status == HTTPStatus_BadRequest && response.Data != null)
{ {
char sData[2048]; char sData[2048];
(view_as<JSONRootNode>(RequestJSON)).ToString(sData, sizeof(sData), 0); response.Data.ToString(sData, sizeof(sData), 0);
LogError("Malformed request? Dumping request data:\n%s", sData); LogError("Malformed request? Dumping request data:\n%s", sData);
} }
else if (eStatusCode == k_EHTTPStatusCode429TooManyRequests) else if (response.Status == HTTPStatus_TooManyRequests)
{ {
g_iRatelimitRemaining = 0; g_iRatelimitRemaining = 0;
g_iRatelimitReset = GetTime() + 5; g_iRatelimitReset = GetTime() + 5;
} }
delete RequestJSON; return;
delete hRequest;
return 0;
} }
static int iLastRatelimitRemaining = 0; static int iLastRatelimitRemaining = 0;
static int iLastRatelimitReset = 0; static int iLastRatelimitReset = 0;
char sTmp[32]; char sTmp[32];
bool bHeaderExists = SteamWorks_GetHTTPResponseHeaderValue(hRequest, "x-ratelimit-remaining", sTmp, sizeof(sTmp)); bool bHeaderExists = response.GetHeader("x-ratelimit-remaining", sTmp, sizeof(sTmp));
if (!bHeaderExists) if (!bHeaderExists)
LogError("x-ratelimit-remaining header value could not be retrieved"); LogError("x-ratelimit-remaining header value could not be retrieved");
int iRatelimitRemaining = StringToInt(sTmp); int iRatelimitRemaining = StringToInt(sTmp);
bHeaderExists = SteamWorks_GetHTTPResponseHeaderValue(hRequest, "x-ratelimit-reset", sTmp, sizeof(sTmp)); bHeaderExists = response.GetHeader("x-ratelimit-reset", sTmp, sizeof(sTmp));
if (!bHeaderExists) if (!bHeaderExists)
LogError("x-ratelimit-reset header value could not be retrieved"); LogError("x-ratelimit-reset header value could not be retrieved");
@@ -578,12 +461,6 @@ public int OnHTTPRequestCompleted(Handle hRequest, bool bFailure, bool bRequestS
g_iRatelimitRemaining = iRatelimitRemaining; g_iRatelimitRemaining = iRatelimitRemaining;
g_iRatelimitReset = iRatelimitReset; g_iRatelimitReset = iRatelimitReset;
} }
//PrintToServer("limit: %d | remaining: %d || reset %d - now %d", g_iRatelimitLimit, g_iRatelimitRemaining, g_iRatelimitReset, GetTime());
delete RequestJSON;
delete hRequest;
return 0;
} }
stock bool IsValidClient(int client) stock bool IsValidClient(int client)
@@ -815,29 +692,7 @@ public void CallAdmin_OnReportHandled(int client, int id)
Call_PushCell(5); Call_PushCell(5);
Call_Finish(); Call_Finish();
} }
//
/*
public Action Oryx_OnTrigger(int client, int &level, char[] cheat)
{
char sUsername[MAX_NAME_LENGTH];
GetClientName(client, sUsername, sizeof(sUsername));
char currentMap[64];
GetCurrentMap(currentMap, sizeof(currentMap));
char sAuthID[32];
GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false);
char sMessage[1900];
Format(sMessage, sizeof(sMessage), "```%s - Tick: %d``````NAME: %N\nSTEAMID: %s\nTRIGGER LEVEL: %i\n%s```", currentMap, GetGameTickCount(), client, sAuthID, level, cheat);
if (g_sAvatarURL[client][0] != '\0')
Discord_POST(DISCORD_ANTIBHOPCHEAT_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[client], false);
else
Discord_POST(DISCORD_ANTIBHOPCHEAT_WEBHOOKURL, sMessage, true, sUsername, false, "", false);
return Plugin_Continue;
}
*/
public void AntiBhopCheat_OnClientDetected(int client, char[] sReason, char[] sStats) public void AntiBhopCheat_OnClientDetected(int client, char[] sReason, char[] sStats)
{ {
char sCurrentMap[64]; char sCurrentMap[64];
@@ -907,7 +762,6 @@ public void EW_OnClientRestricted(int client, int target, int hours, int minutes
Call_Finish(); Call_Finish();
} }
public void EW_OnClientUnrestricted(int client, int target) public void EW_OnClientUnrestricted(int client, int target)
{ {
char sCurrentMap[64]; char sCurrentMap[64];
+6 -2
View File
@@ -1,5 +1,7 @@
#pragma semicolon 1 #pragma semicolon 1
#pragma newdecls required
#define PLUGIN_AUTHOR "Cloud Strife" #define PLUGIN_AUTHOR "Cloud Strife"
#define PLUGIN_VERSION "1.0" #define PLUGIN_VERSION "1.0"
@@ -21,15 +23,17 @@ public Plugin myinfo =
Handle g_CFuncRotating_StartForward = null; Handle g_CFuncRotating_StartForward = null;
Handle g_CFuncRotating_UpdateSpeed = null; Handle g_CFuncRotating_UpdateSpeed = null;
stock float FloatMod(float num, float denom) /*
float FloatMod(float num, float denom)
{ {
return num - denom * RoundToFloor(num / denom); return num - denom * RoundToFloor(num / denom);
} }
stock float operator%(float oper1, float oper2) float operator%(float oper1, float oper2)
{ {
return FloatMod(oper1, oper2); return FloatMod(oper1, oper2);
} }
*/
// Set m_bStopAtStartPos to false // Set m_bStopAtStartPos to false
public MRESReturn CFuncRotating_InputStartForward(int entity) public MRESReturn CFuncRotating_InputStartForward(int entity)
@@ -18,13 +18,13 @@ native bool PM_IsPlayerSteam(int client);
* Retrieve clients usertype. * Retrieve clients usertype.
* *
* @param client The client index. * @param client The client index.
* @param type The buffer to write to. * @param type The integer to write to (1 = Steam, 0 = NoSteam).
* @param maxlength The maximum buffer length.
* *
* @return True on success, false otherwise. * @return True on success, false otherwise.
* @error Invalid client index, not connected or fake client. * @error Invalid client index, not connected or fake client.
*/ */
native bool PM_GetPlayerType(int client, char[] type, int maxlength); //native bool PM_GetPlayerType(int client, int type);
native bool PM_GetPlayerType(int client, char[] buffer, int maxlength);
/** /**
* Retrieve clients globally unique identifier (GUID). * Retrieve clients globally unique identifier (GUID).
@@ -40,7 +40,7 @@ native int PM_GetPlayerGUID(int client);
public SharedPlugin __pl_PlayerManager = public SharedPlugin __pl_PlayerManager =
{ {
name = "PlayerManager", name = "PlayerManager",
file = "PlayerManager_Connect.smx", file = "PlayerManager.smx",
#if defined REQUIRE_PLUGIN #if defined REQUIRE_PLUGIN
required = 1 required = 1
+63
View File
@@ -0,0 +1,63 @@
#if defined _AsyncSocket_included
#endinput
#endif
#define _AsyncSocket_included
typedef AsyncSocketConnectCallback = function void(AsyncSocket socket);
typedef AsyncSocketErrorCallback = function void(AsyncSocket socket, int error, const char[] errorName);
typedef AsyncSocketDataCallback = function void(AsyncSocket socket, const char[] data, const int size);
methodmap AsyncSocket < Handle {
public native AsyncSocket();
public native bool Connect(const char[] host, const int port);
public native bool Listen(const char[] host, const int port);
public native bool Write(const char[] data, int length = -1);
public bool WriteNull(const char[] data)
{
return this.Write(data, strlen(data) + 1);
}
public native bool SetConnectCallback(AsyncSocketConnectCallback callback);
public native bool SetErrorCallback(AsyncSocketErrorCallback callback);
public native bool SetDataCallback(AsyncSocketDataCallback callback);
}
/**
* Do not edit below this line!
*/
public Extension __ext_AsyncSocket =
{
name = "AsyncSocket",
file = "AsyncSocket.ext",
#if defined AUTOLOAD_EXTENSIONS
autoload = 1,
#else
autoload = 0,
#endif
#if defined REQUIRE_EXTENSIONS
required = 1,
#else
required = 0,
#endif
};
#if !defined REQUIRE_EXTENSIONS
public __ext_AsyncSocket_SetNTVOptional()
{
MarkNativeAsOptional("AsyncSocket.AsyncSocket");
MarkNativeAsOptional("AsyncSocket.Connect");
MarkNativeAsOptional("AsyncSocket.Listen");
MarkNativeAsOptional("AsyncSocket.Write");
MarkNativeAsOptional("AsyncSocket.SetConnectCallback");
MarkNativeAsOptional("AsyncSocket.SetErrorCallback");
MarkNativeAsOptional("AsyncSocket.SetDataCallback");
}
#endif
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -25,7 +25,8 @@ public void SourceTV_OnSpectatorPutInServer(int client)
SourceTV_GetClientName(client, sName, sizeof(sName)); SourceTV_GetClientName(client, sName, sizeof(sName));
if(SourceTV_GetClientIP(client, sIP, sizeof(sIP)) && GeoipCountry(sIP, sCountry, sizeof(sCountry))) SourceTV_GetClientIP(client, sIP, sizeof(sIP));
if (strlen(sIP) != 0 && GeoipCountry(sIP, sCountry, sizeof(sCountry)))
PrintToChatAll("\x04[\x03SourceTV\x04] %s connected from %s", sName, sCountry); PrintToChatAll("\x04[\x03SourceTV\x04] %s connected from %s", sName, sCountry);
else else
PrintToChatAll("\x04[\x03SourceTV\x04] %s connected", sName); PrintToChatAll("\x04[\x03SourceTV\x04] %s connected", sName);
+4 -2
View File
@@ -115,7 +115,8 @@ public void CheckStage()
if(StrEqual(sMethod, "counter")) if(StrEqual(sMethod, "counter"))
{ {
char sCounter[64]; char sCounter[64];
if(!g_Config.GetString("counter", sCounter, sizeof(sCounter))) g_Config.GetString("counter", sCounter, sizeof(sCounter), "not found");
if (StrEqual(sCounter, "not found"))
{ {
LogError("Could not find \"counter\""); LogError("Could not find \"counter\"");
return; return;
@@ -172,7 +173,8 @@ public void CheckStage()
bHasDiffCounter = true; bHasDiffCounter = true;
char sDiffCounter[64]; char sDiffCounter[64];
if(!g_Config.GetString("counter", sDiffCounter, sizeof(sDiffCounter))) g_Config.GetString("counter", sDiffCounter, sizeof(sDiffCounter), "not found");
if (StrEqual(sDiffCounter, "not found"))
{ {
LogError("Could not find \"diffcounter\""); LogError("Could not find \"diffcounter\"");
return; return;
@@ -6,7 +6,7 @@
// //
//==================================================================================================== //====================================================================================================
#include <sourcemod> #include <sourcemod>
#include <SteamWorks> #include <ripext>
#include <unloze> #include <unloze>
#include <UNLOZE.secret> //#define UNLOZE_APIKEY here #include <UNLOZE.secret> //#define UNLOZE_APIKEY here
#include <cstrike> #include <cstrike>
@@ -131,68 +131,71 @@ public void OnClientAuthorized(int client, const char[] sSteamID32)
FormatEx(sRequest, sizeof(sRequest), "https://unloze.com/api/private_api.php?api_key=%s&steam_id=%s", UNLOZE_APIKEY, sSteamID64); FormatEx(sRequest, sizeof(sRequest), "https://unloze.com/api/private_api.php?api_key=%s&steam_id=%s", UNLOZE_APIKEY, sSteamID64);
int iSerial = GetClientSerial(client); int iSerial = GetClientSerial(client);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
if (!hRequest || char sPath[PLATFORM_MAX_PATH];
!SteamWorks_SetHTTPCallbacks(hRequest, OnClientAuthorized_OnTransferComplete) || BuildPath(Path_SM, sPath, sizeof(sPath), "data/unloze_forum_%d.tmp", iSerial);
!SteamWorks_SetHTTPRequestContextValue(hRequest, iSerial) ||
!SteamWorks_SendHTTPRequest(hRequest)) HTTPRequest hRequest = new HTTPRequest(sRequest);
{ hRequest.DownloadFile(sPath, OnClientAuthorized_OnDownloaded, iSerial);
delete hRequest;
}
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// Purpose: // Purpose: ripexts HTTPResponse only exposes the body as decoded JSON, unlike
// SteamWorks' GetHTTPResponseBodyCallback which handed back a plain char[].
// Rather than change private_api.php's response format, we use
// HTTPRequest.DownloadFile() to write the raw "GROUP\r\nNAME" body to a temp
// file and parse it back exactly like the original SteamWorks version did.
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
public int OnClientAuthorized_OnTransferComplete(Handle hRequest, bool bFailure, bool bSuccessful, EHTTPStatusCode eStatusCode, int iSerial) public void OnClientAuthorized_OnDownloaded(HTTPStatus status, any iSerial)
{ {
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "data/unloze_forum_%d.tmp", iSerial);
int client = GetClientFromSerial(iSerial); int client = GetClientFromSerial(iSerial);
if (!client) //Player disconnected. if (!client) //Player disconnected.
{ {
delete hRequest; DeleteFile(sPath);
return 0; return;
} }
if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK) if (status != HTTPStatus_OK)
{ {
DeleteFile(sPath);
G_bResponseFailed[client] = true; G_bResponseFailed[client] = true;
if (G_bPreAdminChecked[client]) if (G_bPreAdminChecked[client])
NotifyPostAdminCheck(client); NotifyPostAdminCheck(client);
delete hRequest; return;
return 0;
} }
SteamWorks_GetHTTPResponseBodyCallback(hRequest, OnClientAuthorized_OnTransferResponse, iSerial); char sGroup[64], sName[32];
return 0; sGroup[0] = '\0';
sName[0] = '\0';
File hFile = OpenFile(sPath, "r");
if (hFile != null)
{
hFile.ReadLine(sGroup, sizeof(sGroup));
hFile.ReadLine(sName, sizeof(sName));
delete hFile;
} }
DeleteFile(sPath);
//---------------------------------------------------------------------------------------------------- TrimString(sGroup);
// Purpose: StripQuotes(sGroup);
//---------------------------------------------------------------------------------------------------- TrimString(sName);
public int OnClientAuthorized_OnTransferResponse(char[] sData, int iSerial) StripQuotes(sName);
LogMessage("reached sData with status 200: %s", sGroup);
if (strlen(sName) > 0)
strcopy(G_sName[client], sizeof(G_sName[]), sName);
if (!StrEqual(sGroup, "NOGROUP"))
{ {
char splitData[2][32]; strcopy(G_sGroup[client], sizeof(G_sGroup[]), sGroup);
int client = GetClientFromSerial(iSerial);
if (!client) //Player disconnected.
return 0;
TrimString(sData);
StripQuotes(sData);
LogMessage("reached sData with status 200: %s", sData);
ExplodeString(sData, "\r\n", splitData, 2, sizeof(splitData[]));
if(strlen(splitData[1]) > 0)
strcopy(G_sName[client], sizeof(G_sName[]), splitData[1]);
if(!StrEqual(splitData[0], "NOGROUP"))
{
strcopy(G_sGroup[client], sizeof(G_sGroup[]), splitData[0]);
G_bResponsePassed[client] = true; G_bResponsePassed[client] = true;
@@ -201,7 +204,6 @@ public int OnClientAuthorized_OnTransferResponse(char[] sData, int iSerial)
} }
else else
G_bResponseFailed[client] = true; //users with just a forum name did not pass the VIP check! so the response "failed" (but we store their forum name for later!) G_bResponseFailed[client] = true; //users with just a forum name did not pass the VIP check! so the response "failed" (but we store their forum name for later!)
return 0;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@@ -295,40 +297,39 @@ public int Native_AsyncHasSteamIDReservedSlot(Handle plugin, int numParams)
hDataPack.WriteCell(plugin); hDataPack.WriteCell(plugin);
hDataPack.WriteCell(data); hDataPack.WriteCell(data);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); // The DataPack handle value is unique among currently-open handles, so it
if (!hRequest || // doubles as a collision-free key for the temp file this specific
!SteamWorks_SetHTTPCallbacks(hRequest, Native_AsyncHasSteamIDReservedSlot_OnTransferComplete) || // in-flight request will use.
!SteamWorks_SetHTTPRequestContextValue(hRequest, hDataPack) || char sPath[PLATFORM_MAX_PATH];
!SteamWorks_SendHTTPRequest(hRequest)) BuildPath(Path_SM, sPath, sizeof(sPath), "data/unloze_reslot_%d.tmp", view_as<int>(hDataPack));
{
delete hRequest; HTTPRequest hRequest = new HTTPRequest(sRequest);
} hRequest.DownloadFile(sPath, Native_AsyncHasSteamIDReservedSlot_OnDownloaded, hDataPack);
return 0; return 0;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// Purpose: // Purpose: same DownloadFile-to-tempfile approach as OnClientAuthorized_OnDownloaded
// above - keeps private_api.php's raw "GROUP\r\nNAME" text response untouched.
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
public int Native_AsyncHasSteamIDReservedSlot_OnTransferComplete(Handle hRequest, bool bFailure, bool bSuccessful, EHTTPStatusCode eStatusCode, DataPack hDataPack) public void Native_AsyncHasSteamIDReservedSlot_OnDownloaded(HTTPStatus status, DataPack hDataPack)
{
if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
{ {
char sPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sPath, sizeof(sPath), "data/unloze_reslot_%d.tmp", view_as<int>(hDataPack));
char sData[32] = "NOGROUP"; char sData[32] = "NOGROUP";
Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(sData, hDataPack);
delete hRequest; if (status == HTTPStatus_OK)
return 0;
}
SteamWorks_GetHTTPResponseBodyCallback(hRequest, Native_AsyncHasSteamIDReservedSlot_OnTransferResponse, hDataPack);
return 0;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(char[] sData, DataPack hDataPack)
{ {
File hFile = OpenFile(sPath, "r");
if (hFile != null)
{
hFile.ReadLine(sData, sizeof(sData));
delete hFile;
}
}
DeleteFile(sPath);
hDataPack.Reset(); hDataPack.Reset();
char sSteamID32[32]; char sSteamID32[32];
@@ -363,7 +364,6 @@ public int Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(char[] sData, D
Call_Finish(); Call_Finish();
delete hDataPack; delete hDataPack;
return 0;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
+32 -43
View File
@@ -1,7 +1,6 @@
#include <sourcemod> #include <sourcemod>
#include <SteamWorks> #include <ripext>
#include <multicolors> #include <multicolors>
#include <json>
#undef REQUIRE_PLUGIN #undef REQUIRE_PLUGIN
#tryinclude <PlayerManager> #tryinclude <PlayerManager>
@@ -154,69 +153,60 @@ public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[]
FormatEx(sRequest, sizeof(sRequest), "use a url here", sIP, APIKEY); FormatEx(sRequest, sizeof(sRequest), "use a url here", sIP, APIKEY);
//PrintToConsoleAll(sRequest); //PrintToConsoleAll(sRequest);
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); HTTPRequest hRequest = new HTTPRequest(sRequest);
if (!hRequest || hRequest.Get(OnTransferComplete, iSerial);
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
!SteamWorks_SetHTTPRequestContextValue(hRequest, iSerial) ||
!SteamWorks_SendHTTPRequest(hRequest))
{
delete hRequest;
}
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
// Purpose: // Purpose:
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
public int OnTransferComplete(Handle hRequest, bool bFailure, bool bSuccessful, EHTTPStatusCode eStatusCode, int iSerial) public void OnTransferComplete(HTTPResponse response, any iSerial)
{ {
int client = GetClientFromSerial(iSerial); int client = GetClientFromSerial(iSerial);
if (!client) //Player disconnected. if (!client) //Player disconnected.
{ return;
delete hRequest;
return 0;
}
if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK) if (response.Status != HTTPStatus_OK || response.Data == null)
{ {
delete hRequest;
g_bStatus[client] = STATUS_ERROR; g_bStatus[client] = STATUS_ERROR;
LogError("Request-Error: %d", eStatusCode); LogError("Request-Error: %d", response.Status);
return 0; return;
} }
SteamWorks_GetHTTPResponseBodyCallback(hRequest, OnTransferResponse, iSerial);
return 0;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int OnTransferResponse(char[] sData, int iSerial)
{
int client = GetClientFromSerial(iSerial);
if (!client) //Player disconnected.
return 0;
char sIP[32]; char sIP[32];
GetClientIP(client, sIP, sizeof(sIP)); GetClientIP(client, sIP, sizeof(sIP));
JSON_Object obj = json_decode(sData); // ripext already decodes the JSON body for us as a native JSONObject; no
JSONObject obj = view_as<JSONObject>(response.Data);
char sStatus[32]; char sStatus[32];
obj.GetString("status", sStatus, sizeof(sStatus)); if (!obj.GetString("status", sStatus, sizeof(sStatus)))
sStatus[0] = '\0';
if (!StrEqual(sStatus, "ok") && !StrEqual(sStatus, "warning")) if (!StrEqual(sStatus, "ok") && !StrEqual(sStatus, "warning"))
{ {
char sMessage[256]; char sMessage[256];
obj.GetString("message", sMessage, sizeof(sMessage)); if (!obj.GetString("message", sMessage, sizeof(sMessage)))
sMessage[0] = '\0';
LogError("API-Response: %s: %s", sStatus, sMessage); LogError("API-Response: %s: %s", sStatus, sMessage);
g_bStatus[client] = STATUS_ERROR; g_bStatus[client] = STATUS_ERROR;
json_cleanup_and_delete(obj); delete obj;
return 0; return;
} }
JSON_Object ipobj = obj.GetObject(sIP); if (!obj.HasKey(sIP))
{
LogError("API-Response: no entry for IP %s", sIP);
g_bStatus[client] = STATUS_ERROR;
delete obj;
return;
}
JSONObject ipobj = view_as<JSONObject>(obj.Get(sIP));
char sProxy[16]; char sProxy[16];
ipobj.GetString("proxy", sProxy, sizeof(sProxy)); if (!ipobj.GetString("proxy", sProxy, sizeof(sProxy)))
sProxy[0] = '\0';
if (StrEqual(sProxy, "no")) if (StrEqual(sProxy, "no"))
g_bStatus[client] = STATUS_SAFE; g_bStatus[client] = STATUS_SAFE;
else else
@@ -238,10 +228,8 @@ public int OnTransferResponse(char[] sData, int iSerial)
Format(sQuery, sizeof(sQuery), "INSERT INTO ip_table (ip, type, last_check) VALUES ('%s', '%d', '%d') ON DUPLICATE KEY UPDATE type='%d', last_check='%d';", sIP, g_bStatus[client], iCurrentTime, g_bStatus[client], iCurrentTime); Format(sQuery, sizeof(sQuery), "INSERT INTO ip_table (ip, type, last_check) VALUES ('%s', '%d', '%d') ON DUPLICATE KEY UPDATE type='%d', last_check='%d';", sIP, g_bStatus[client], iCurrentTime, g_bStatus[client], iCurrentTime);
g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_Low); g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_Low);
//https://github.com/clugg/sm-json/blob/master/addons/sourcemod/scripting/json_test.sp#L446 delete ipobj;
//as far as i can tell i just need to call json_cleanup_and_delete() on the most outer json object, all its children should get cleaned and deleted as well. delete obj;
json_cleanup_and_delete(obj);
return 0;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@@ -405,3 +393,4 @@ public void OnLibraryRemoved(const char[] sName)
if (strcmp(sName, "PlayerManager", false) == 0) if (strcmp(sName, "PlayerManager", false) == 0)
g_bPMLoaded = false; g_bPMLoaded = false;
} }
+8 -3
View File
@@ -87,17 +87,22 @@ public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] n
public void OnMapStart() public void OnMapStart()
{ {
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer)) if(g_hTimer != INVALID_HANDLE)
{
CloseHandle(g_hTimer);
g_hTimer = INVALID_HANDLE; g_hTimer = INVALID_HANDLE;
}
g_hTimer = CreateTimer(TIMER_INTERVAL, Timer_CleanupWeapons, INVALID_HANDLE, TIMER_REPEAT); g_hTimer = CreateTimer(TIMER_INTERVAL, Timer_CleanupWeapons, INVALID_HANDLE, TIMER_REPEAT);
} }
public void OnMapEnd() public void OnMapEnd()
{ {
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer)) if(g_hTimer != INVALID_HANDLE)
{
CloseHandle(g_hTimer);
g_hTimer = INVALID_HANDLE; g_hTimer = INVALID_HANDLE;
} }
}
public void OnClientPutInServer(int client) public void OnClientPutInServer(int client)
{ {
@@ -2701,11 +2701,11 @@ public Action Event_PlayerSay(Handle event, const char[] name, bool dontBroadcas
{ {
if (g_msgAuthor == -1 || GetClientOfUserId(GetEventInt(event, "userid")) != g_msgAuthor) if (g_msgAuthor == -1 || GetClientOfUserId(GetEventInt(event, "userid")) != g_msgAuthor)
{ {
return; return Plugin_Handled;
} }
if (strlen(g_msgText) == 0) if (strlen(g_msgText) == 0)
return; return Plugin_Handled;
int[] players = new int[MaxClients + 1]; int[] players = new int[MaxClients + 1];
int playersNum = 0; int playersNum = 0;
@@ -2738,7 +2738,7 @@ public Action Event_PlayerSay(Handle event, const char[] name, bool dontBroadcas
if (!playersNum) if (!playersNum)
{ {
g_msgAuthor = -1; g_msgAuthor = -1;
return; return Plugin_Handled;
} }
Handle SayText2 = StartMessage("SayText2", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS); Handle SayText2 = StartMessage("SayText2", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS);
@@ -2759,6 +2759,7 @@ public Action Event_PlayerSay(Handle event, const char[] name, bool dontBroadcas
} }
g_msgAuthor = -1; g_msgAuthor = -1;
return Plugin_Handled;
} }
// 888b 888 d8888 88888888888 8888888 888 888 8888888888 .d8888b. // 888b 888 d8888 88888888888 8888888 888 888 8888888888 .d8888b.
+1 -1
View File
@@ -20,7 +20,7 @@ methodmap AsyncSocket < Handle {
public bool WriteNull(const char[] data) public bool WriteNull(const char[] data)
{ {
this.Write(data, strlen(data) + 1); return this.Write(data, strlen(data) + 1);
} }
public native bool SetConnectCallback(AsyncSocketConnectCallback callback); public native bool SetConnectCallback(AsyncSocketConnectCallback callback);
+1 -1
View File
@@ -1053,7 +1053,7 @@ methodmap JSONRootNode < JSONValue {
} }
public static JSONRootNode Pack(const char[] packString, ArrayList params) { public static JSONRootNode Pack(const char[] packString, ArrayList params) {
return JSONValue_ByPack(packString, params); return view_as<JSONRootNode>(JSONValue_ByPack(packString, params));
} }
public void DumpToServer() { public void DumpToServer() {