Apply gamestochat restrictions to voice

This commit is contained in:
Antonio Martinez 2025-08-27 20:38:45 -04:00
parent 5de0539316
commit 8a87f0ed7d
8 changed files with 92 additions and 10 deletions

View file

@ -73,6 +73,7 @@
#include "r_fps.h"
#include "filesrch.h" // refreshdirmenu
#include "k_objects.h"
#include "k_serverstats.h" // updatemutes
// cl loading screen
#include "v_video.h"
@ -3435,6 +3436,7 @@ static void Got_RemovePlayer(const UINT8 **p, INT32 playernum);
static void Got_AddBot(const UINT8 **p, INT32 playernum);
static void Got_ServerMutePlayer(const UINT8 **p, INT32 playernum);
static void Got_ServerDeafenPlayer(const UINT8 **p, INT32 playernum);
static void Got_ServerTempMutePlayer(const UINT8 **p, INT32 playernum);
void Joinable_OnChange(void);
void Joinable_OnChange(void)
@ -3490,6 +3492,7 @@ void D_ClientServerInit(void)
COM_AddCommand("serverdeafen", Command_ServerDeafen);
COM_AddCommand("serverundeafen", Command_ServerUndeafen);
RegisterNetXCmd(XD_SERVERMUTEPLAYER, Got_ServerMutePlayer);
RegisterNetXCmd(XD_SERVERTEMPMUTEPLAYER, Got_ServerTempMutePlayer);
RegisterNetXCmd(XD_SERVERDEAFENPLAYER, Got_ServerDeafenPlayer);
gametic = 0;
@ -3822,6 +3825,7 @@ static void Got_AddPlayer(const UINT8 **p, INT32 playernum)
}
HU_AddChatText(joinmsg, false);
SV_UpdateTempMutes();
}
if (server && multiplayer && motd[0] != '\0')
@ -3913,6 +3917,34 @@ static void Got_ServerMutePlayer(const UINT8 **p, INT32 playernum)
}
}
// Xcmd XD_SERVERTEMPMUTEPLAYER
static void Got_ServerTempMutePlayer(const UINT8 **p, INT32 playernum)
{
UINT8 forplayer = READUINT8(*p);
UINT8 muted = READUINT8(*p);
if (playernum != serverplayer)
{
CONS_Alert(CONS_WARNING, M_GetText("Illegal server mute player cmd from %s\n"), player_names[playernum]);
if (server)
{
SendKick(playernum, KICK_MSG_CON_FAIL);
}
}
if (muted && !(players[forplayer].pflags2 & PF2_SERVERTEMPMUTE))
{
players[forplayer].pflags2 |= PF2_SERVERTEMPMUTE;
if (P_IsMachineLocalPlayer(&players[forplayer]))
HU_AddChatText(va("\x82* You are temporarily muted until you finish more rounds."), false);
}
else if (!muted && players[forplayer].pflags2 & PF2_SERVERTEMPMUTE)
{
players[forplayer].pflags2 &= ~PF2_SERVERTEMPMUTE;
if (P_IsMachineLocalPlayer(&players[forplayer]))
HU_AddChatText(va("\x82* You've now finished enough rounds to use chat."), false);
}
}
// Xcmd XD_SERVERDEAFENPLAYER
static void Got_ServerDeafenPlayer(const UINT8 **p, INT32 playernum)
{
@ -5327,7 +5359,7 @@ static void PT_HandleVoiceServer(SINT8 node)
}
player = &players[playernum];
if (player->pflags2 & (PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_SERVERMUTE | PF2_SERVERDEAFEN))
if (player->pflags2 & (PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_SERVERMUTE | PF2_SERVERDEAFEN | PF2_SERVERTEMPMUTE))
{
// ignore, they should not be able to broadcast voice
return;
@ -7543,7 +7575,7 @@ void NetVoiceUpdate(void)
// 1. In a netgame,
// 2. Not self-muted by cvar
// 3. The consoleplayer is not server or self muted or deafened
if (netgame && !cv_voice_selfmute.value && !(players[consoleplayer].pflags2 & (PF2_SERVERMUTE | PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_SERVERDEAFEN)))
if (netgame && !cv_voice_selfmute.value && !(players[consoleplayer].pflags2 & (PF2_SERVERMUTE | PF2_SELFMUTE | PF2_SERVERTEMPMUTE | PF2_SELFDEAFEN | PF2_SERVERDEAFEN)))
{
DoVoicePacket(servernode, g_local_opus_frame, encoded, result);
S_SetPlayerVoiceActive(consoleplayer);

View file

@ -189,6 +189,7 @@ typedef enum
XD_TEAMCHANGE, // 41
XD_SERVERMUTEPLAYER, // 42
XD_SERVERDEAFENPLAYER, // 43
XD_SERVERTEMPMUTEPLAYER, // 44
MAXNETXCMD
} netxcmd_t;

View file

@ -148,6 +148,8 @@ typedef enum
PF2_BUBBLECONTACT = 1<<7, // ACHTUNG VERY BAD HACK - Don't allow Bubble Shield to contact certain objects unless this is a fresh blowup.
PF2_SUPERTRANSFERVFX = 1<<8, // Don't respawn the "super transfer available" VFX.
PF2_FASTTUMBLEBOUNCE = 1<<9, // Don't lose speed when tumblebouncing.
PF2_SERVERTEMPMUTE = 1<<10, // Haven't met gamestochat requirement
} pflags2_t;
typedef enum

View file

@ -2407,7 +2407,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
xtralife = players[player].xtralife;
pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_AUTOROULETTE|PF_ANALOGSTICK|PF_AUTORING));
pflags2 = (players[player].pflags2 & (PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_SERVERMUTE | PF2_SERVERDEAFEN | PF2_STRICTFASTFALL));
pflags2 = (players[player].pflags2 & (PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_SERVERTEMPMUTE | PF2_SERVERMUTE | PF2_SERVERDEAFEN | PF2_STRICTFASTFALL));
// SRB2kart
memcpy(&itemRoulette, &players[player].itemRoulette, sizeof (itemRoulette));

View file

@ -3003,7 +3003,7 @@ void PositionFacesInfo::draw_1p()
{
voxmic = kp_voice_remotedeafened;
}
else if (players[rankplayer[i]].pflags2 & (PF2_SELFMUTE | PF2_SERVERMUTE))
else if (players[rankplayer[i]].pflags2 & (PF2_SELFMUTE | PF2_SERVERMUTE | PF2_SERVERTEMPMUTE))
{
voxmic = kp_voice_remotemuted;
}
@ -8283,7 +8283,7 @@ void K_drawKartHUD(void)
if (netgame && cv_voice_allowservervoice.value == 1)
{
if (players[consoleplayer].pflags2 & (PF2_SELFMUTE | PF2_SERVERMUTE | PF2_SELFDEAFEN | PF2_SERVERDEAFEN))
if (players[consoleplayer].pflags2 & (PF2_SELFMUTE | PF2_SERVERMUTE | PF2_SERVERTEMPMUTE | PF2_SELFDEAFEN | PF2_SERVERDEAFEN))
{
patch_t* micmuted = kp_voice_localmuted;
V_DrawFixedPatch(-1 * FRACUNIT, (BASEVIDHEIGHT - 21) << FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTOLEFT, micmuted, NULL);

View file

@ -20,6 +20,7 @@
#include "k_serverstats.h"
#include "z_zone.h"
#include "time.h"
#include "d_netcmd.h" // isplayeradmin
static serverplayer_t *trackedList;
static size_t numtracked = 0;
@ -231,7 +232,7 @@ serverplayer_t *SV_GetStats(player_t *player)
// Write clientpowerlevels and timestamps back to matching trackedList entries, then save trackedList to disk
// (NB: Stats changes can be made directly to trackedList through other paths, but will only write to disk here)
void SV_UpdateStats(void)
{
{
UINT32 i, j, hash;
if (!server)
@ -250,7 +251,7 @@ void SV_UpdateStats(void)
hash = quickncasehash((char*)players[i].public_key, PUBKEYLENGTH);
for(j = 0; j < numtracked; j++)
{
{
if (hash != trackedList[j].hash) // Not crypto magic, just an early out with a faster comparison
continue;
if (memcmp(&trackedList[j].public_key, players[i].public_key, PUBKEYLENGTH) == 0)
@ -265,6 +266,7 @@ void SV_UpdateStats(void)
// so this shouldn't be reachable.
}
SV_UpdateTempMutes();
SV_SaveStats();
}
@ -272,6 +274,9 @@ void SV_BumpMatchStats(void)
{
int i;
if (!server)
return;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
@ -284,7 +289,7 @@ void SV_BumpMatchStats(void)
serverplayer_t *stat = SV_GetStatsByPlayerIndex(i);
// It should never be advantageous to idle, only count rounds where the player accomplishes something.
// If you NO CONTESTed, assume no participation...
// If you NO CONTESTed, assume no participation...
boolean participated = !(players[i].pflags & PF_NOCONTEST);
if (gametyperules & GTR_CIRCUIT)
@ -303,4 +308,44 @@ void SV_BumpMatchStats(void)
if (participated)
stat->finishedrounds++;
}
}
SV_UpdateTempMutes();
}
static void SV_UpdateTempMute(player_t *player, boolean mute)
{
UINT8 buf[2];
buf[0] = player - players;
buf[1] = (UINT8)(mute);
SendNetXCmd(XD_SERVERTEMPMUTEPLAYER, &buf, 2);
}
void SV_UpdateTempMutes(void)
{
int i;
if (!server)
return;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].spectator)
continue;
if (PR_IsKeyGuest(players[i].public_key))
continue;
player_t *player = &players[i];
serverplayer_t *stat = SV_GetStatsByPlayerIndex(i);
if (i == serverplayer || IsPlayerAdmin(i))
SV_UpdateTempMute(player, false);
else if (stat->finishedrounds >= (UINT32)cv_gamestochat.value && player->pflags2 & PF2_SERVERTEMPMUTE)
SV_UpdateTempMute(player, false);
else if (stat->finishedrounds < (UINT32)cv_gamestochat.value && !(player->pflags2 & PF2_SERVERTEMPMUTE))
SV_UpdateTempMute(player, true);
}
}

View file

@ -48,6 +48,8 @@ void SV_UpdateStats(void);
void SV_BumpMatchStats(void);
void SV_UpdateTempMutes(void);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -814,7 +814,7 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset)
voxxoffs = 1;
voxyoffs = -5;
}
else if (players[pnum].pflags2 & (PF2_SELFMUTE | PF2_SERVERMUTE))
else if (players[pnum].pflags2 & (PF2_SELFMUTE | PF2_SERVERMUTE | PF2_SERVERTEMPMUTE))
{
voxpat = (patch_t*) W_CachePatchName("VOXCRM", PU_HUDGFX);
voxxoffs = 1;