no zr edition for mg/zr

This commit is contained in:
jenz 2026-07-24 11:08:49 +02:00
parent 2d91202469
commit ef15dfc71c

View File

@ -0,0 +1,333 @@
#include <sourcemod>
#include <PlayerManager>
#include <sdktools>
#include <basecomm>
#include <ccc>
#include <clientprefs>
#include <SteamWorks>
#include <selfmute>
#include <connect>
#include <voice>
#pragma semicolon 1
#pragma newdecls required
Handle g_hCheckMutes = null;
Handle g_hCookieTorchMuted = null;
bool g_bWebclient[MAXPLAYERS + 1];
bool g_bReRunWebClientName;
char g_sLastWebclientIp[64];
public Plugin myinfo =
{
name = "NoSteam CELT Voice override",
author = "jenz",
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);
}
public void OnPluginEnd()
{
if (g_hCheckMutes != null)
{
delete g_hCheckMutes;
}
}
public void set_nosteam_listen_override(int client)
{
for (int j = 1; j <= MaxClients; j++)
{
if (!IsValidClient(j) || client == j || IsFakeClient(j))
continue;
if (PM_IsPlayerSteam(j))
{
//the nosteam client is not allowed to hear the steam client because broadcastvoicedata would ear rape them.
//LogMessage("%N has muted %N", client, j);
SetListenOverride(client, j, Listen_No);
}
}
}
public Action check_mutes(Handle timer, any data)
{
for (int i = 1; i <= MaxClients; i++)
{
if (!IsValidClient(i) || IsFakeClient(i))
{
continue;
}
if (!PM_IsPlayerSteam(i))
{
set_nosteam_listen_override(i);
}
for (int j = 1; j <= MaxClients; j++)
{
if (!IsValidClient(j) || i == j || IsFakeClient(j))
{
continue;
}
bool isMuted = BaseComm_IsClientMuted(j);
if (!isMuted)
{
isMuted = SelfMute_IsIgnoring(i, j);
}
//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++)
{
if (!IsValidClient(j) || IsFakeClient(j))
{
continue;
}
//yeah its monkey work but server can probably handle it fine.
char sBuffer[2];
GetClientCookie(j, g_hCookieTorchMuted, sBuffer, sizeof(sBuffer));
//PrintToChatAll("sBuffer: %s. j: %N", sBuffer, j);
if(sBuffer[0] != '\0')
{
ClientMutedOtherClient(j, 0, true);
}
else
{
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_bWebclient[client] = false;
}
public void OnClientPostAdminCheck(int client)
{
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;
//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))
{
SetClientNoSteam(client, true);
//LogMessage("here in onauthorized client: %N", client);
//setting it too early does not work, so some delay needed.
CreateTimer(10.0, Timer_SendVoiceInit, GetClientSerial(client));
CreateTimer(20.0, Timer_SendVoiceInit, GetClientSerial(client));
CreateTimer(30.0, Timer_SendVoiceInit, GetClientSerial(client));
CreateTimer(40.0, Timer_SendVoiceInit, GetClientSerial(client));
CreateTimer(50.0, Timer_SendVoiceInit, GetClientSerial(client));
CreateTimer(60.0, Timer_SendVoiceInit, GetClientSerial(client));
}
}
public Action CCC_OnChatMessage(int client, int author, const char[] message)
{
if (!g_bWebclient[client])
{
return Plugin_Continue;
}
int index = FindCharInString(message, '"', false);
int index1 = FindCharInString(message, ';', false);
if (index != -1 || index1 != -1)
{
return Plugin_Handled;
}
return Plugin_Continue;
}
public Action Timer_SendVoiceInit(Handle timer, int Serial)
{
int client;
if ((client = GetClientFromSerial(Serial)) == 0)
{
return Plugin_Handled;
}
if (IsValidClient(client))
{
SendCeltVoiceInit(client);
}
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))
return true;
return false;
}