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:
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <sourcemod>
|
||||
#include <sdktools>
|
||||
#include <SteamWorks>
|
||||
#include <ripext>
|
||||
#include <cstrike>
|
||||
#include <AdvancedTargeting>
|
||||
|
||||
@@ -437,17 +437,14 @@ public void OnClientAuthorized(int client, const char[] auth)
|
||||
char sSteam64ID[32];
|
||||
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];
|
||||
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);
|
||||
if (!hRequest ||
|
||||
!SteamWorks_SetHTTPRequestContextValue(hRequest, client) ||
|
||||
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
CloseHandle(hRequest);
|
||||
}
|
||||
HTTPRequest hRequest = new HTTPRequest(sRequest);
|
||||
hRequest.Get(OnTransferComplete, client);
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
@@ -458,52 +455,38 @@ public void OnClientDisconnect(int client)
|
||||
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?
|
||||
//LogError("SteamAPI HTTP Response failed: %d", eStatusCode);
|
||||
CloseHandle(hRequest);
|
||||
//LogError("SteamAPI HTTP Response failed: %d", response.Status);
|
||||
return;
|
||||
}
|
||||
|
||||
int Length;
|
||||
SteamWorks_GetHTTPResponseBodySize(hRequest, Length);
|
||||
|
||||
char[] sData = new char[Length];
|
||||
SteamWorks_GetHTTPResponseBodyData(hRequest, sData, Length);
|
||||
//SteamWorks_GetHTTPResponseBodyCallback(hRequest, APIWebResponse, client);
|
||||
|
||||
CloseHandle(hRequest);
|
||||
|
||||
APIWebResponse(sData, client);
|
||||
APIWebResponse(view_as<JSONObject>(response.Data), client);
|
||||
}
|
||||
|
||||
public void APIWebResponse(const char[] sData, int client)
|
||||
public void APIWebResponse(JSONObject Response, int client)
|
||||
{
|
||||
KeyValues Response = new KeyValues("SteamAPIResponse");
|
||||
if(!Response.ImportFromString(sData, "SteamAPIResponse"))
|
||||
if(!Response.HasKey("friendslist"))
|
||||
{
|
||||
LogError("ImportFromString(sData, \"SteamAPIResponse\") failed.");
|
||||
LogError("GetFriendList response missing \"friendslist\" key.");
|
||||
delete Response;
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
// No friends?
|
||||
if(!Response.GotoFirstSubKey())
|
||||
{
|
||||
//LogError("GotoFirstSubKey() failed.");
|
||||
delete Response;
|
||||
return;
|
||||
}
|
||||
JSONArray friends = view_as<JSONArray>(friendslist.Get("friends"));
|
||||
|
||||
if(g_FriendsArray[client] != INVALID_HANDLE)
|
||||
CloseHandle(g_FriendsArray[client]);
|
||||
@@ -511,18 +494,20 @@ public void APIWebResponse(const char[] sData, int client)
|
||||
g_FriendsArray[client] = CreateArray();
|
||||
|
||||
char sCommunityID[32];
|
||||
do
|
||||
int len = friends.Length;
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
Response.GetString("steamid", sCommunityID, sizeof(sCommunityID));
|
||||
|
||||
PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID));
|
||||
JSONObject friendEntry = view_as<JSONObject>(friends.Get(i));
|
||||
if(friendEntry.GetString("steamid", sCommunityID, sizeof(sCommunityID)))
|
||||
PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID));
|
||||
delete friendEntry;
|
||||
}
|
||||
while(Response.GotoNextKey());
|
||||
|
||||
delete friends;
|
||||
delete friendslist;
|
||||
delete Response;
|
||||
}
|
||||
|
||||
|
||||
stock bool Steam32IDtoSteam64ID(const char[] sSteam32ID, char[] sSteam64ID, int Size)
|
||||
{
|
||||
if(strlen(sSteam32ID) < 11 || strncmp(sSteam32ID[0], "STEAM_0:", 8))
|
||||
@@ -634,3 +619,4 @@ public int Native_ReadClientFriends(Handle plugin, int numParams)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -426,9 +426,12 @@ NotifyAdmins(int client, const char[] sReason)
|
||||
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);
|
||||
FormatStats(i, client);
|
||||
char sBuffer[2000];
|
||||
FormatStats(i, client, sBuffer, 0);
|
||||
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++)
|
||||
{
|
||||
FormatStats(client, iTargets[i]);
|
||||
char sBuffer[2000];
|
||||
FormatStats(i, client, sBuffer, 0);
|
||||
PrintToConsole(client, "%s", "\n");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
@@ -509,13 +513,14 @@ public Action Command_Streak(int client, int argc)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
char sAuth[32];
|
||||
@@ -545,7 +550,7 @@ int FormatStats(int client, int iTarget, char[] sBuf=0, int len=0)
|
||||
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);
|
||||
char sAuth[32];
|
||||
|
||||
@@ -248,7 +248,8 @@ public void OnMapStart()
|
||||
if(StrEqual(sMethod, "breakable"))
|
||||
{
|
||||
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);
|
||||
continue;
|
||||
@@ -263,7 +264,8 @@ public void OnMapStart()
|
||||
else if(StrEqual(sMethod, "counter"))
|
||||
{
|
||||
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);
|
||||
continue;
|
||||
@@ -278,21 +280,24 @@ public void OnMapStart()
|
||||
else if(StrEqual(sMethod, "hpbar"))
|
||||
{
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
continue;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <basecomm>
|
||||
#include <ccc>
|
||||
#include <clientprefs>
|
||||
#include <SteamWorks>
|
||||
#include <ripext>
|
||||
#tryinclude <zombiereloaded>
|
||||
#include <selfmute>
|
||||
#include <connect>
|
||||
@@ -22,6 +22,8 @@ bool g_bSkipInfection = false;
|
||||
|
||||
char g_sLastWebclientIp[64];
|
||||
|
||||
int g_iHttpFileCounter;
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "NoSteam CELT Voice override",
|
||||
@@ -73,7 +75,7 @@ public Action check_mutes(Handle timer, any data)
|
||||
}
|
||||
else
|
||||
{
|
||||
//maybe this is a fix? maybe not.
|
||||
//maybe this is a fix? maybe not.
|
||||
clear_steam_listen_override(i);
|
||||
}
|
||||
for (int j = 1; j <= MaxClients; j++)
|
||||
@@ -145,28 +147,17 @@ public void SendWebclientNameToSignaling(const char[] webclientName)
|
||||
// Adjust port/path to match your signaling servers actual endpoint
|
||||
FormatEx(url, sizeof(url), "http://127.0.0.1:3000/webclient-name");
|
||||
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, url);
|
||||
if (hRequest == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HTTPRequest hRequest = new HTTPRequest(url);
|
||||
|
||||
// Send the name as a POST body parameter
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(hRequest, "name", webclientName);
|
||||
|
||||
if (!SteamWorks_SetHTTPCallbacks(hRequest, OnWebclientNamePosted) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
delete hRequest;
|
||||
}
|
||||
hRequest.AppendFormParam("name", "%s", webclientName);
|
||||
hRequest.PostForm(OnWebclientNamePosted);
|
||||
}
|
||||
|
||||
public int OnWebclientNamePosted(Handle hRequest, bool bFailure, bool bRequestSuccessful,
|
||||
EHTTPStatusCode eStatusCode, any data)
|
||||
public void OnWebclientNamePosted(HTTPResponse response, any value)
|
||||
{
|
||||
// Fire-and-forget: we dont care about the response, just clean up.
|
||||
delete hRequest;
|
||||
return 0;
|
||||
// Fire-and-forget: we dont care about the response. ripext closes the
|
||||
// request handle for us once this callback returns.
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
@@ -259,7 +250,7 @@ public Action ZR_OnClientMotherZombieEligible(int client)
|
||||
|
||||
public Action Timer_SendVoiceInit(Handle timer, int Serial)
|
||||
{
|
||||
int client;
|
||||
int client;
|
||||
if ((client = GetClientFromSerial(Serial)) == 0)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
@@ -276,53 +267,53 @@ public Action Timer_SendVoiceInit(Handle timer, int Serial)
|
||||
* If the IP has changed since the last
|
||||
* check and a webclient player is currently connected, forces them to
|
||||
* 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()
|
||||
{
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, "http://127.0.0.1:3000/webclient-current-ip");
|
||||
if (hRequest == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_iHttpFileCounter++;
|
||||
|
||||
if (!SteamWorks_SetHTTPCallbacks(hRequest, OnWebclientCurrentIpReceived) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
delete hRequest;
|
||||
}
|
||||
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 int OnWebclientCurrentIpReceived(Handle hRequest, bool bFailure, bool bRequestSuccessful,
|
||||
EHTTPStatusCode eStatusCode, any data)
|
||||
public void OnWebclientCurrentIpDownloaded(HTTPStatus status, any value)
|
||||
{
|
||||
if (bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
|
||||
{
|
||||
delete hRequest;
|
||||
return 0;
|
||||
}
|
||||
char sPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, sPath, sizeof(sPath), "data/nosteamcelt_ip_%d.tmp", value);
|
||||
|
||||
int bodySize;
|
||||
bool gotSize = SteamWorks_GetHTTPResponseBodySize(hRequest, bodySize);
|
||||
if (status != HTTPStatus_OK)
|
||||
{
|
||||
DeleteFile(sPath);
|
||||
return;
|
||||
}
|
||||
|
||||
char newIp[64];
|
||||
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')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
|
||||
if (StrEqual(newIp, g_sLastWebclientIp))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
@@ -334,7 +325,6 @@ public int OnWebclientCurrentIpReceived(Handle hRequest, bool bFailure, bool bRe
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255])
|
||||
@@ -344,7 +334,7 @@ public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], co
|
||||
if (sv_set_steam_id_ips != null)
|
||||
{
|
||||
sv_set_steam_id_ips.GetString(allowedIp, sizeof(allowedIp));
|
||||
//this is to handle that the connect extension receives the password parameter for the webclient as its real connecting IP.
|
||||
//this is to handle that the connect extension receives the password parameter for the webclient as its real connecting IP.
|
||||
//works both for the client command retry and for the case that somebody presses the connect button in the clients Menu as the same password
|
||||
//is applied again.
|
||||
if (StrEqual(sIP, allowedIp) && strlen(g_sLastWebclientIp) > 0)
|
||||
@@ -353,7 +343,7 @@ public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], co
|
||||
LogMessage("Backfilled empty password for webclient with cached IP: %s", g_sLastWebclientIp);
|
||||
}
|
||||
}
|
||||
// ET_LowEvent takes the LOWEST value returned across all plugins hooking this forward.
|
||||
// ET_LowEvent takes the LOWEST value returned across all plugins hooking this forward.
|
||||
//this plugin returns 1 (Accept), meanwhile the reserved slot plugin still might return 0 (reject) or -1 (async) to overrule the decision from this return value.
|
||||
return k_OnClientPreConnectEx_Accept;
|
||||
}
|
||||
@@ -364,3 +354,4 @@ stock bool IsValidClient(int client)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
#include <basecomm>
|
||||
#include <sourcemod>
|
||||
#include <SteamWorks>
|
||||
#include <ripext>
|
||||
#include <regex>
|
||||
#include <smjansson>
|
||||
#include <multicolors>
|
||||
#include <sdktools>
|
||||
#include <AFKManager>
|
||||
@@ -139,6 +138,9 @@ public void OnAdminAFKTimeChanged(ConVar convar, const char[] oldValue, const ch
|
||||
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)
|
||||
{
|
||||
if (IsFakeClient(client))
|
||||
@@ -149,19 +151,44 @@ public void OnClientAuthorized(int client, const char[] sAuthID32)
|
||||
if (!Steam32IDtoSteam64ID(sAuthID32, sAuthID64, sizeof(sAuthID64)))
|
||||
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))
|
||||
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 hRequest;
|
||||
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)
|
||||
@@ -197,6 +224,9 @@ public Action Command_PrintToAllChat(int args)
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose: Drains the rate-limit queue - now via ripext
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public Action Timer_DataProcessor(Handle hThis)
|
||||
{
|
||||
if (!g_bProcessingData)
|
||||
@@ -205,8 +235,6 @@ public Action Timer_DataProcessor(Handle hThis)
|
||||
if (g_iRatelimitRemaining == 0 && GetTime() < g_iRatelimitReset)
|
||||
return Plugin_Handled;
|
||||
|
||||
//PrintToServer("[Timer_DataProcessor] Array Length #1: %d", g_arrQueuedMessages.Length);
|
||||
|
||||
char sContent[1024];
|
||||
g_arrQueuedMessages.GetString(0, sContent, sizeof(sContent));
|
||||
g_arrQueuedMessages.Erase(0);
|
||||
@@ -218,28 +246,13 @@ public Action Timer_DataProcessor(Handle hThis)
|
||||
if (g_arrQueuedMessages.Length == 0)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -300,27 +313,11 @@ stock void Discord_MakeStringSafe(const char[] sOrigin, char[] sOut, int iOutSiz
|
||||
{
|
||||
if (sOrigin[i] < 0x20 && sOrigin[i] != 0x0)
|
||||
{
|
||||
//sOut[iCurIndex] = 0x20;
|
||||
//iCurIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (sOrigin[i])
|
||||
{
|
||||
// case '"':
|
||||
// {
|
||||
// strcopy(sOut[iCurIndex], iOutSize, "\\u0022");
|
||||
// iCurIndex += 6;
|
||||
|
||||
// continue;
|
||||
// }
|
||||
// case '\\':
|
||||
// {
|
||||
// strcopy(sOut[iCurIndex], iOutSize, "\\u005C");
|
||||
// iCurIndex += 6;
|
||||
|
||||
// continue;
|
||||
// }
|
||||
case '@':
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose: Webhook POST helper - now via ripext
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
|
||||
JSONRootNode hJSONRoot = new JSONObject();
|
||||
JSONObject hJSONRoot = new JSONObject();
|
||||
|
||||
char sSafeText[4096];
|
||||
char sFinal[4096];
|
||||
@@ -463,13 +370,13 @@ stock void Discord_POST(const char[] sURL, char[] sText, bool bUsingUsername=fal
|
||||
TrimString(sUsername);
|
||||
|
||||
if (g_Regex_Clyde.Match(sUsername) > 0 || strlen(sUsername) < 2)
|
||||
(view_as<JSONObject>(hJSONRoot)).SetString("username", "Invalid Name");
|
||||
hJSONRoot.SetString("username", "Invalid Name");
|
||||
else
|
||||
(view_as<JSONObject>(hJSONRoot)).SetString("username", sUsername);
|
||||
hJSONRoot.SetString("username", sUsername);
|
||||
}
|
||||
|
||||
if (bUsingAvatar)
|
||||
(view_as<JSONObject>(hJSONRoot)).SetString("avatar_url", sAvatarURL);
|
||||
hJSONRoot.SetString("avatar_url", sAvatarURL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
(view_as<JSONObject>(hJSONRoot)).SetString("content", sSafeText);
|
||||
(view_as<JSONObject>(hJSONRoot)).ToString(sFinal, sizeof(sFinal), 0);
|
||||
|
||||
//hJSONRoot.DumpToServer();
|
||||
|
||||
delete hJSONRoot;
|
||||
hJSONRoot.SetString("content", sSafeText);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
delete hJSONRoot;
|
||||
}
|
||||
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(sURL);
|
||||
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)
|
||||
LogError("Discord HTTP request failed: %d", eStatusCode);
|
||||
if (response.Status != HTTPStatus_TooManyRequests)
|
||||
LogError("Discord HTTP request failed: %d", response.Status);
|
||||
|
||||
if (eStatusCode == k_EHTTPStatusCode400BadRequest)
|
||||
if (response.Status == HTTPStatus_BadRequest && response.Data != null)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (eStatusCode == k_EHTTPStatusCode429TooManyRequests)
|
||||
else if (response.Status == HTTPStatus_TooManyRequests)
|
||||
{
|
||||
g_iRatelimitRemaining = 0;
|
||||
g_iRatelimitReset = GetTime() + 5;
|
||||
}
|
||||
|
||||
delete RequestJSON;
|
||||
delete hRequest;
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int iLastRatelimitRemaining = 0;
|
||||
static int iLastRatelimitReset = 0;
|
||||
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)
|
||||
LogError("x-ratelimit-remaining header value could not be retrieved");
|
||||
|
||||
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)
|
||||
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_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)
|
||||
@@ -815,29 +692,7 @@ public void CallAdmin_OnReportHandled(int client, int id)
|
||||
Call_PushCell(5);
|
||||
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)
|
||||
{
|
||||
char sCurrentMap[64];
|
||||
@@ -907,7 +762,6 @@ public void EW_OnClientRestricted(int client, int target, int hours, int minutes
|
||||
Call_Finish();
|
||||
}
|
||||
|
||||
|
||||
public void EW_OnClientUnrestricted(int client, int target)
|
||||
{
|
||||
char sCurrentMap[64];
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma semicolon 1
|
||||
|
||||
#pragma newdecls required
|
||||
|
||||
#define PLUGIN_AUTHOR "Cloud Strife"
|
||||
#define PLUGIN_VERSION "1.0"
|
||||
|
||||
@@ -21,15 +23,17 @@ public Plugin myinfo =
|
||||
Handle g_CFuncRotating_StartForward = 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);
|
||||
}
|
||||
|
||||
stock float operator%(float oper1, float oper2)
|
||||
float operator%(float oper1, float oper2)
|
||||
{
|
||||
return FloatMod(oper1, oper2);
|
||||
}
|
||||
*/
|
||||
|
||||
// Set m_bStopAtStartPos to false
|
||||
public MRESReturn CFuncRotating_InputStartForward(int entity)
|
||||
@@ -106,4 +110,4 @@ public void OnPluginStart()
|
||||
{
|
||||
LogError("Could not enable detour for CFuncRotating::UpdateSpeed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ native bool PM_IsPlayerSteam(int client);
|
||||
* Retrieve clients usertype.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param type The buffer to write to.
|
||||
* @param maxlength The maximum buffer length.
|
||||
* @param type The integer to write to (1 = Steam, 0 = NoSteam).
|
||||
*
|
||||
* @return True on success, false otherwise.
|
||||
* @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).
|
||||
@@ -40,7 +40,7 @@ native int PM_GetPlayerGUID(int client);
|
||||
public SharedPlugin __pl_PlayerManager =
|
||||
{
|
||||
name = "PlayerManager",
|
||||
file = "PlayerManager_Connect.smx",
|
||||
file = "PlayerManager.smx",
|
||||
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1
|
||||
@@ -50,10 +50,10 @@ public SharedPlugin __pl_PlayerManager =
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public void __pl_PlayerManager_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("PM_IsPlayerSteam");
|
||||
MarkNativeAsOptional("PM_GetPlayerType");
|
||||
MarkNativeAsOptional("PM_GetPlayerGUID");
|
||||
}
|
||||
public void __pl_PlayerManager_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("PM_IsPlayerSteam");
|
||||
MarkNativeAsOptional("PM_GetPlayerType");
|
||||
MarkNativeAsOptional("PM_GetPlayerGUID");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
@@ -25,7 +25,8 @@ public void SourceTV_OnSpectatorPutInServer(int client)
|
||||
|
||||
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);
|
||||
else
|
||||
PrintToChatAll("\x04[\x03SourceTV\x04] %s connected", sName);
|
||||
|
||||
@@ -115,7 +115,8 @@ public void CheckStage()
|
||||
if(StrEqual(sMethod, "counter"))
|
||||
{
|
||||
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\"");
|
||||
return;
|
||||
@@ -172,7 +173,8 @@ public void CheckStage()
|
||||
bHasDiffCounter = true;
|
||||
|
||||
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\"");
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//====================================================================================================
|
||||
#include <sourcemod>
|
||||
#include <SteamWorks>
|
||||
#include <ripext>
|
||||
#include <unloze>
|
||||
#include <UNLOZE.secret> //#define UNLOZE_APIKEY here
|
||||
#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);
|
||||
|
||||
int iSerial = GetClientSerial(client);
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
|
||||
if (!hRequest ||
|
||||
!SteamWorks_SetHTTPCallbacks(hRequest, OnClientAuthorized_OnTransferComplete) ||
|
||||
!SteamWorks_SetHTTPRequestContextValue(hRequest, iSerial) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
delete hRequest;
|
||||
}
|
||||
|
||||
char sPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, sPath, sizeof(sPath), "data/unloze_forum_%d.tmp", iSerial);
|
||||
|
||||
HTTPRequest hRequest = new HTTPRequest(sRequest);
|
||||
hRequest.DownloadFile(sPath, OnClientAuthorized_OnDownloaded, iSerial);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// 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);
|
||||
|
||||
if (!client) //Player disconnected.
|
||||
{
|
||||
delete hRequest;
|
||||
return 0;
|
||||
DeleteFile(sPath);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
|
||||
|
||||
if (status != HTTPStatus_OK)
|
||||
{
|
||||
DeleteFile(sPath);
|
||||
G_bResponseFailed[client] = true;
|
||||
|
||||
if (G_bPreAdminChecked[client])
|
||||
NotifyPostAdminCheck(client);
|
||||
|
||||
delete hRequest;
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SteamWorks_GetHTTPResponseBodyCallback(hRequest, OnClientAuthorized_OnTransferResponse, iSerial);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public int OnClientAuthorized_OnTransferResponse(char[] sData, int iSerial)
|
||||
{
|
||||
char splitData[2][32];
|
||||
char sGroup[64], sName[32];
|
||||
sGroup[0] = '\0';
|
||||
sName[0] = '\0';
|
||||
|
||||
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"))
|
||||
File hFile = OpenFile(sPath, "r");
|
||||
if (hFile != null)
|
||||
{
|
||||
strcopy(G_sGroup[client], sizeof(G_sGroup[]), splitData[0]);
|
||||
hFile.ReadLine(sGroup, sizeof(sGroup));
|
||||
hFile.ReadLine(sName, sizeof(sName));
|
||||
delete hFile;
|
||||
}
|
||||
DeleteFile(sPath);
|
||||
|
||||
TrimString(sGroup);
|
||||
StripQuotes(sGroup);
|
||||
TrimString(sName);
|
||||
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"))
|
||||
{
|
||||
strcopy(G_sGroup[client], sizeof(G_sGroup[]), sGroup);
|
||||
|
||||
G_bResponsePassed[client] = true;
|
||||
|
||||
@@ -201,7 +204,6 @@ public int OnClientAuthorized_OnTransferResponse(char[] sData, int iSerial)
|
||||
}
|
||||
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!)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -263,7 +265,7 @@ public int Native_GetClientForumName(Handle plugin, int numParams)
|
||||
{
|
||||
int len = GetNativeCell(2);
|
||||
int client = GetNativeCell(1);
|
||||
|
||||
|
||||
SetNativeString(2, G_sName[client], len+1);
|
||||
return 0;
|
||||
}
|
||||
@@ -295,40 +297,39 @@ public int Native_AsyncHasSteamIDReservedSlot(Handle plugin, int numParams)
|
||||
hDataPack.WriteCell(plugin);
|
||||
hDataPack.WriteCell(data);
|
||||
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
|
||||
if (!hRequest ||
|
||||
!SteamWorks_SetHTTPCallbacks(hRequest, Native_AsyncHasSteamIDReservedSlot_OnTransferComplete) ||
|
||||
!SteamWorks_SetHTTPRequestContextValue(hRequest, hDataPack) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
delete hRequest;
|
||||
}
|
||||
// The DataPack handle value is unique among currently-open handles, so it
|
||||
// doubles as a collision-free key for the temp file this specific
|
||||
// in-flight request will use.
|
||||
char sPath[PLATFORM_MAX_PATH];
|
||||
BuildPath(Path_SM, sPath, sizeof(sPath), "data/unloze_reslot_%d.tmp", view_as<int>(hDataPack));
|
||||
|
||||
HTTPRequest hRequest = new HTTPRequest(sRequest);
|
||||
hRequest.DownloadFile(sPath, Native_AsyncHasSteamIDReservedSlot_OnDownloaded, hDataPack);
|
||||
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";
|
||||
|
||||
if (status == HTTPStatus_OK)
|
||||
{
|
||||
char sData[32] = "NOGROUP";
|
||||
Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(sData, hDataPack);
|
||||
|
||||
delete hRequest;
|
||||
return 0;
|
||||
File hFile = OpenFile(sPath, "r");
|
||||
if (hFile != null)
|
||||
{
|
||||
hFile.ReadLine(sData, sizeof(sData));
|
||||
delete hFile;
|
||||
}
|
||||
}
|
||||
DeleteFile(sPath);
|
||||
|
||||
SteamWorks_GetHTTPResponseBodyCallback(hRequest, Native_AsyncHasSteamIDReservedSlot_OnTransferResponse, hDataPack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public int Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(char[] sData, DataPack hDataPack)
|
||||
{
|
||||
hDataPack.Reset();
|
||||
|
||||
char sSteamID32[32];
|
||||
@@ -347,7 +348,7 @@ public int Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(char[] sData, D
|
||||
|
||||
TrimString(sData);
|
||||
StripQuotes(sData);
|
||||
|
||||
|
||||
SplitString(sData, "\r\n", splitData, sizeof(splitData));
|
||||
|
||||
int result;
|
||||
@@ -363,7 +364,6 @@ public int Native_AsyncHasSteamIDReservedSlot_OnTransferResponse(char[] sData, D
|
||||
Call_Finish();
|
||||
|
||||
delete hDataPack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <sourcemod>
|
||||
#include <SteamWorks>
|
||||
#include <ripext>
|
||||
#include <multicolors>
|
||||
#include <json>
|
||||
|
||||
#undef REQUIRE_PLUGIN
|
||||
#tryinclude <PlayerManager>
|
||||
@@ -151,72 +150,63 @@ public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[]
|
||||
GetClientIP(client, sIP, sizeof(sIP));
|
||||
|
||||
char sRequest[256];
|
||||
FormatEx(sRequest, sizeof(sRequest), "use a url here", sIP, APIKEY);
|
||||
FormatEx(sRequest, sizeof(sRequest), "use a url here", sIP, APIKEY);
|
||||
//PrintToConsoleAll(sRequest);
|
||||
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
|
||||
if (!hRequest ||
|
||||
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
|
||||
!SteamWorks_SetHTTPRequestContextValue(hRequest, iSerial) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
delete hRequest;
|
||||
}
|
||||
HTTPRequest hRequest = new HTTPRequest(sRequest);
|
||||
hRequest.Get(OnTransferComplete, iSerial);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// 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);
|
||||
if (!client) //Player disconnected.
|
||||
{
|
||||
delete hRequest;
|
||||
return 0;
|
||||
}
|
||||
return;
|
||||
|
||||
if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
|
||||
if (response.Status != HTTPStatus_OK || response.Data == null)
|
||||
{
|
||||
delete hRequest;
|
||||
g_bStatus[client] = STATUS_ERROR;
|
||||
LogError("Request-Error: %d", eStatusCode);
|
||||
return 0;
|
||||
LogError("Request-Error: %d", response.Status);
|
||||
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];
|
||||
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];
|
||||
obj.GetString("status", sStatus, sizeof(sStatus));
|
||||
if (!obj.GetString("status", sStatus, sizeof(sStatus)))
|
||||
sStatus[0] = '\0';
|
||||
|
||||
if (!StrEqual(sStatus, "ok") && !StrEqual(sStatus, "warning"))
|
||||
{
|
||||
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);
|
||||
g_bStatus[client] = STATUS_ERROR;
|
||||
json_cleanup_and_delete(obj);
|
||||
return 0;
|
||||
delete obj;
|
||||
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];
|
||||
ipobj.GetString("proxy", sProxy, sizeof(sProxy));
|
||||
if (!ipobj.GetString("proxy", sProxy, sizeof(sProxy)))
|
||||
sProxy[0] = '\0';
|
||||
|
||||
if (StrEqual(sProxy, "no"))
|
||||
g_bStatus[client] = STATUS_SAFE;
|
||||
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);
|
||||
g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_Low);
|
||||
|
||||
//https://github.com/clugg/sm-json/blob/master/addons/sourcemod/scripting/json_test.sp#L446
|
||||
//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.
|
||||
json_cleanup_and_delete(obj);
|
||||
return 0;
|
||||
delete ipobj;
|
||||
delete obj;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -405,3 +393,4 @@ public void OnLibraryRemoved(const char[] sName)
|
||||
if (strcmp(sName, "PlayerManager", false) == 0)
|
||||
g_bPMLoaded = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,16 +87,21 @@ public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] n
|
||||
|
||||
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 = CreateTimer(TIMER_INTERVAL, Timer_CleanupWeapons, INVALID_HANDLE, TIMER_REPEAT);
|
||||
}
|
||||
|
||||
public void OnMapEnd()
|
||||
{
|
||||
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer))
|
||||
if(g_hTimer != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(g_hTimer);
|
||||
g_hTimer = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
if (strlen(g_msgText) == 0)
|
||||
return;
|
||||
return Plugin_Handled;
|
||||
|
||||
int[] players = new int[MaxClients + 1];
|
||||
int playersNum = 0;
|
||||
@@ -2738,7 +2738,7 @@ public Action Event_PlayerSay(Handle event, const char[] name, bool dontBroadcas
|
||||
if (!playersNum)
|
||||
{
|
||||
g_msgAuthor = -1;
|
||||
return;
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
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;
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
// 888b 888 d8888 88888888888 8888888 888 888 8888888888 .d8888b.
|
||||
|
||||
@@ -20,7 +20,7 @@ methodmap AsyncSocket < Handle {
|
||||
|
||||
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);
|
||||
|
||||
@@ -1052,9 +1052,9 @@ methodmap JSONRootNode < JSONValue {
|
||||
return view_as<JSONRootNode>(json_load_file(path));
|
||||
}
|
||||
|
||||
public static JSONRootNode Pack(const char[] packString, ArrayList params) {
|
||||
return JSONValue_ByPack(packString, params);
|
||||
}
|
||||
public static JSONRootNode Pack(const char[] packString, ArrayList params) {
|
||||
return view_as<JSONRootNode>(JSONValue_ByPack(packString, params));
|
||||
}
|
||||
|
||||
public void DumpToServer() {
|
||||
char sMsg[4096];
|
||||
|
||||
Reference in New Issue
Block a user