ReGameDLL_CS/regamedll/game_shared/voice_gamemgr.cpp

218 lines
6.1 KiB
C++
Raw Normal View History

2015-06-30 12:46:07 +03:00
#include "precompiled.h"
2017-10-12 17:50:56 +03:00
cvar_t voice_serverdebug = { "voice_serverdebug", "0", 0, 0.0f, nullptr };
// Set game rules to allow all clients to talk to each other.
// Muted players still can't talk to each other.
cvar_t sv_alltalk = { "sv_alltalk", "0", FCVAR_SERVER, 0.0f, nullptr };
2015-06-30 12:46:07 +03:00
// These are stored off as CVoiceGameMgr is created and deleted.
2017-10-12 17:50:56 +03:00
CPlayerBitVec g_PlayerModEnable; // Set to 1 for each player if the player wants to use voice in this mod.
// (If it's zero, then the server reports that the game rules are saying the player can't hear anyone).
2017-10-12 17:50:56 +03:00
CBitVec<VOICE_MAX_PLAYERS> g_BanMasks[VOICE_MAX_PLAYERS]; // Tells which players don't want to hear each other.
// These are indexed as clients and each bit represents a client (so player entity is bit + 1).
2017-10-12 17:50:56 +03:00
CBitVec<VOICE_MAX_PLAYERS> g_SentGameRulesMasks[VOICE_MAX_PLAYERS]; // These store the masks we last sent to each client so we can determine if
CBitVec<VOICE_MAX_PLAYERS> g_SentBanMasks[VOICE_MAX_PLAYERS]; // we need to resend them.
CPlayerBitVec g_bWantModEnable;
2015-06-30 12:46:07 +03:00
void VoiceServerDebug(const char *pFmt, ...)
2015-06-30 12:46:07 +03:00
{
char msg[4096];
va_list marker;
if (!voice_serverdebug.value)
return;
va_start(marker, pFmt);
2015-08-20 13:35:01 +03:00
Q_vsnprintf(msg, ARRAYSIZE(msg), pFmt, marker);
va_end(marker);
ALERT(at_console, "%s", msg);
2015-06-30 12:46:07 +03:00
}
CVoiceGameMgr::CVoiceGameMgr()
2015-06-30 12:46:07 +03:00
{
m_UpdateInterval = 0;
m_nMaxPlayers = 0;
2015-06-30 12:46:07 +03:00
}
CVoiceGameMgr::~CVoiceGameMgr()
2015-06-30 12:46:07 +03:00
{
;
2015-06-30 12:46:07 +03:00
}
bool CVoiceGameMgr::Init(IVoiceGameMgrHelper *pHelper, int maxClients)
2015-06-30 12:46:07 +03:00
{
m_pHelper = pHelper;
m_nMaxPlayers = (maxClients > VOICE_MAX_PLAYERS) ? VOICE_MAX_PLAYERS : maxClients;
PRECACHE_MODEL("sprites/voiceicon.spr");
m_msgPlayerVoiceMask = REG_USER_MSG("VoiceMask", VOICE_MAX_PLAYERS_DW * 4 * 2);
m_msgRequestState = REG_USER_MSG("ReqState", 0);
2015-09-16 23:19:21 +03:00
// register voice_serverdebug if it hasn't been registered already
if (!CVAR_GET_POINTER("voice_serverdebug"))
CVAR_REGISTER(&voice_serverdebug);
if (!CVAR_GET_POINTER("sv_alltalk"))
CVAR_REGISTER(&sv_alltalk);
return true;
2015-06-30 12:46:07 +03:00
}
void CVoiceGameMgr::SetHelper(IVoiceGameMgrHelper *pHelper)
2015-06-30 12:46:07 +03:00
{
m_pHelper = pHelper;
2015-06-30 12:46:07 +03:00
}
void CVoiceGameMgr::Update(double frametime)
2015-06-30 12:46:07 +03:00
{
// Only update periodically.
m_UpdateInterval += frametime;
2017-11-01 19:07:52 +03:00
const float UPDATE_INTERVAL = 0.3f;
if (m_UpdateInterval >= UPDATE_INTERVAL)
UpdateMasks();
2015-06-30 12:46:07 +03:00
}
void CVoiceGameMgr::ClientConnected(edict_t *pEdict)
2015-06-30 12:46:07 +03:00
{
int index = ENTINDEX(pEdict) - 1;
// Clear out everything we use for deltas on this guy.
g_bWantModEnable[index] = true;
g_SentGameRulesMasks[index].Init(0);
g_SentBanMasks[index].Init(0);
2015-06-30 12:46:07 +03:00
}
// Called to determine if the Receiver has muted (blocked) the Sender
// Returns true if the receiver has blocked the sender
bool CVoiceGameMgr::PlayerHasBlockedPlayer(CBasePlayer *pReceiver, CBasePlayer *pSender)
2015-06-30 12:46:07 +03:00
{
int iReceiverIndex, iSenderIndex;
if (!pReceiver || !pSender)
return false;
iReceiverIndex = pReceiver->entindex() - 1;
iSenderIndex = pSender->entindex() - 1;
if (iReceiverIndex < 0 || iReceiverIndex >= m_nMaxPlayers || iSenderIndex < 0 || iSenderIndex >= m_nMaxPlayers)
return false;
return (g_BanMasks[iReceiverIndex][iSenderIndex] != 0);
2015-06-30 12:46:07 +03:00
}
2015-09-16 23:19:21 +03:00
bool CVoiceGameMgr::ClientCommand(CBasePlayer *pPlayer, const char *cmd)
2015-06-30 12:46:07 +03:00
{
int playerClientIndex = pPlayer->entindex() - 1;
if (playerClientIndex < 0 || playerClientIndex >= m_nMaxPlayers)
{
VoiceServerDebug("CVoiceGameMgr::ClientCommand: cmd %s from invalid client (%d)\n", cmd, playerClientIndex);
return true;
}
bool bBan = Q_stricmp(cmd, "vban") == 0;
if (bBan && CMD_ARGC() >= 2)
{
2017-10-12 17:50:56 +03:00
for (int i = 1; i < CMD_ARGC(); i++)
{
uint32 mask = 0;
2017-10-12 17:50:56 +03:00
sscanf(CMD_ARGV(i), "%x", &mask);
if (i <= VOICE_MAX_PLAYERS_DW)
{
VoiceServerDebug("CVoiceGameMgr::ClientCommand: vban (0x%x) from %d\n", mask, playerClientIndex);
g_BanMasks[playerClientIndex].SetDWord(i - 1, mask);
}
else
VoiceServerDebug("CVoiceGameMgr::ClientCommand: invalid index (%d)\n", i);
}
// Force it to update the masks now.
//UpdateMasks();
return true;
}
else if (Q_stricmp(cmd, "VModEnable") == 0 && CMD_ARGC() >= 2)
{
2015-08-20 13:35:01 +03:00
VoiceServerDebug("CVoiceGameMgr::ClientCommand: VModEnable (%d)\n", !!Q_atoi(CMD_ARGV(1)));
g_PlayerModEnable[playerClientIndex] = !!Q_atoi(CMD_ARGV(1));
g_bWantModEnable[playerClientIndex] = false;
//UpdateMasks();
return true;
}
return false;
2015-06-30 12:46:07 +03:00
}
void CVoiceGameMgr::UpdateMasks()
2015-06-30 12:46:07 +03:00
{
m_UpdateInterval = 0;
bool bAllTalk = sv_alltalk.value == 1.0f;
2017-10-12 17:50:56 +03:00
for (int iClient = 0; iClient < m_nMaxPlayers; iClient++)
{
CBaseEntity *pEnt = UTIL_PlayerByIndex(iClient + 1);
if (!pEnt
#ifndef REGAMEDLL_FIXES
|| !pEnt->IsPlayer()
#endif
)
continue;
2015-09-16 23:19:21 +03:00
CBasePlayer *pPlayer = static_cast<CBasePlayer *>(pEnt);
CPlayerBitVec gameRulesMask;
// Request the state of their "VModEnable" cvar.
if (g_bWantModEnable[iClient])
{
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN(MSG_ONE, m_msgRequestState, nullptr, pEnt->pev);
MESSAGE_END();
}
if (g_PlayerModEnable[iClient])
{
// Build a mask of who they can hear based on the game rules.
2017-10-12 17:50:56 +03:00
for (int iOtherClient = 0; iOtherClient < m_nMaxPlayers; iOtherClient++)
{
CBaseEntity *pEnt = UTIL_PlayerByIndex(iOtherClient + 1);
if (pEnt && (bAllTalk || m_pHelper->CanPlayerHearPlayer(pPlayer, (CBasePlayer *)pEnt)))
{
gameRulesMask[iOtherClient] = true;
}
}
}
// If this is different from what the client has, send an update.
if (gameRulesMask != g_SentGameRulesMasks[iClient] || g_BanMasks[iClient] != g_SentBanMasks[iClient])
{
g_SentGameRulesMasks[iClient] = gameRulesMask;
g_SentBanMasks[iClient] = g_BanMasks[iClient];
2017-10-12 17:50:56 +03:00
MESSAGE_BEGIN(MSG_ONE, m_msgPlayerVoiceMask, nullptr, pPlayer->pev);
for (int dw = 0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
WRITE_LONG(gameRulesMask.GetDWord(dw));
WRITE_LONG(g_BanMasks[iClient].GetDWord(dw));
}
// ServerModEnable +1 to buffer size
// WRITE_BYTE(1);
MESSAGE_END();
}
// Tell the engine.
2017-10-12 17:50:56 +03:00
for (int iOtherClient = 0; iOtherClient < m_nMaxPlayers; iOtherClient++)
{
bool bCanHear = gameRulesMask[iOtherClient] && !g_BanMasks[iClient][iOtherClient];
SET_CLIENT_LISTENING(iClient + 1, iOtherClient + 1, bCanHear);
}
}
2015-06-30 12:46:07 +03:00
}