forwards finally detect the webclient, handling password and retry through the plugin for the webclient
This commit is contained in:
parent
622bc8da4e
commit
2d91202469
@ -4,8 +4,10 @@
|
||||
#include <basecomm>
|
||||
#include <ccc>
|
||||
#include <clientprefs>
|
||||
#include <SteamWorks>
|
||||
#tryinclude <zombiereloaded>
|
||||
#include <selfmute>
|
||||
#include <connect>
|
||||
#include <voice>
|
||||
|
||||
#pragma semicolon 1
|
||||
@ -14,20 +16,22 @@
|
||||
Handle g_hCheckMutes = null;
|
||||
Handle g_hCookieTorchMuted = null;
|
||||
|
||||
bool g_bWasChecked[MAXPLAYERS + 1];
|
||||
bool g_bWebclient[MAXPLAYERS + 1];
|
||||
|
||||
bool g_bReRunWebClientName;
|
||||
bool g_bSkipInfection = false;
|
||||
|
||||
char g_sLastWebclientIp[64];
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "NoSteam CELT Voice override",
|
||||
author = "jenz",
|
||||
version = "1.0"
|
||||
version = "1.5"
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
Format(g_sLastWebclientIp, sizeof(g_sLastWebclientIp), "");
|
||||
g_hCheckMutes = CreateTimer(2.0, check_mutes, _, TIMER_REPEAT);
|
||||
g_hCookieTorchMuted = RegClientCookie("torch_muted", "is torch muted", CookieAccess_Protected);
|
||||
}
|
||||
@ -63,14 +67,6 @@ public Action check_mutes(Handle timer, any data)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!g_bWasChecked[i])
|
||||
{
|
||||
//this exists for the webclient. the webclient is skipping all connection related forwards. hence a manual check like this is needed for the webclient.
|
||||
char dummy[64];
|
||||
OnClientAuthorized(i, dummy);
|
||||
g_bWebclient[i] = true;
|
||||
g_bSkipInfection = GetConVarInt(FindConVar("zr_infect_mzombie_ratio")) > 10 ? true : false;
|
||||
}
|
||||
if (!PM_IsPlayerSteam(i))
|
||||
{
|
||||
set_nosteam_listen_override(i);
|
||||
@ -89,8 +85,15 @@ public Action check_mutes(Handle timer, any data)
|
||||
//PrintToChatAll("i: %N. j: %N. isMuted: %i", i, j, isMuted);
|
||||
ClientMutedOtherClient(i, j, isMuted);
|
||||
}
|
||||
if (g_bReRunWebClientName && g_bWebclient[i])
|
||||
{
|
||||
char dummy[64];
|
||||
OnClientAuthorized(i, dummy);
|
||||
g_bReRunWebClientName = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//sourceTV special case, index 0.
|
||||
for (int j = 1; j <= MaxClients; j++)
|
||||
{
|
||||
@ -111,23 +114,90 @@ public Action check_mutes(Handle timer, any data)
|
||||
ClientMutedOtherClient(j, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
//check if webclient has new IP every 2 seconds through endpoint.
|
||||
PollWebclientCurrentIp();
|
||||
return Plugin_Continue;
|
||||
}
|
||||
|
||||
//AI slop
|
||||
public void SendWebclientNameToSignaling(const char[] webclientName)
|
||||
{
|
||||
char url[256];
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Send the name as a POST body parameter
|
||||
SteamWorks_SetHTTPRequestGetOrPostParameter(hRequest, "name", webclientName);
|
||||
|
||||
if (!SteamWorks_SetHTTPCallbacks(hRequest, OnWebclientNamePosted) ||
|
||||
!SteamWorks_SendHTTPRequest(hRequest))
|
||||
{
|
||||
delete hRequest;
|
||||
}
|
||||
}
|
||||
|
||||
public int OnWebclientNamePosted(Handle hRequest, bool bFailure, bool bRequestSuccessful,
|
||||
EHTTPStatusCode eStatusCode, any data)
|
||||
{
|
||||
// Fire-and-forget: we dont care about the response, just clean up.
|
||||
delete hRequest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
g_bReRunWebClientName = true;
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
g_bWasChecked[client] = false;
|
||||
g_bWebclient[client] = false;
|
||||
}
|
||||
|
||||
public void OnClientAuthorized(int client, const char[] auth)
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
g_bWasChecked[client] = true;
|
||||
g_bWebclient[client] = false;
|
||||
if (IsFakeClient(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char sIP[32];
|
||||
GetClientIP(client, sIP, sizeof(sIP));
|
||||
|
||||
char allowed_ips[128];
|
||||
ConVar sv_set_steam_id_ips = FindConVar("sv_set_steam_id_ips");
|
||||
if (sv_set_steam_id_ips != null)
|
||||
{
|
||||
sv_set_steam_id_ips.GetString(allowed_ips, sizeof(allowed_ips));
|
||||
if (StrEqual(sIP, allowed_ips))
|
||||
{
|
||||
g_bWebclient[client] = true;
|
||||
g_bSkipInfection = GetConVarInt(FindConVar("zr_infect_mzombie_ratio")) > 10 ? true : false;
|
||||
|
||||
//this works fine with one webclient only existing.
|
||||
char webclientName[64];
|
||||
GetConVarString(FindConVar("sv_webclient_name"), webclientName, sizeof(webclientName));
|
||||
SetClientName(client, webclientName);
|
||||
SendWebclientNameToSignaling(webclientName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientAuthorized(int client, const char[] auth)
|
||||
{
|
||||
if (IsFakeClient(client))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetClientNoSteam(client, false);
|
||||
if (!PM_IsPlayerSteam(client))
|
||||
{
|
||||
@ -183,6 +253,93 @@ public Action Timer_SendVoiceInit(Handle timer, int Serial)
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls the signaling server for the current webclient controller's real IP.
|
||||
* 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.
|
||||
**/
|
||||
public void PollWebclientCurrentIp()
|
||||
{
|
||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, "http://127.0.0.1:3000/webclient-current-ip");
|
||||
if (hRequest == null)
|
||||
{
|
||||
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];
|
||||
newIp[0] = '\0';
|
||||
|
||||
if (gotSize && bodySize > 0 && bodySize < sizeof(newIp))
|
||||
{
|
||||
SteamWorks_GetHTTPResponseBodyData(hRequest, newIp, bodySize);
|
||||
}
|
||||
|
||||
delete hRequest;
|
||||
|
||||
if (newIp[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (StrEqual(newIp, g_sLastWebclientIp))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
if (IsValidClient(i) && g_bWebclient[i])
|
||||
{
|
||||
strcopy(g_sLastWebclientIp, sizeof(g_sLastWebclientIp), newIp);
|
||||
LogMessage("Forcing webclient reconnect for client %N with new IP: %s", i, newIp);
|
||||
ClientCommand(i, "retry");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255])
|
||||
{
|
||||
char allowedIp[64];
|
||||
ConVar sv_set_steam_id_ips = FindConVar("sv_set_steam_id_ips");
|
||||
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.
|
||||
//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)
|
||||
{
|
||||
strcopy(sPassword, 255, g_sLastWebclientIp);
|
||||
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.
|
||||
//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;
|
||||
}
|
||||
|
||||
stock bool IsValidClient(int client)
|
||||
{
|
||||
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user