Skip to content

Add per player glitch functions #4336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 100 additions & 6 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,26 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo())
m_Glitches[GLITCH_QUICKSTAND] = false;
m_Glitches[GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE] = false;
m_Glitches[GLITCH_VEHICLE_RAPID_STOP] = false;


for (int i = 0; i < NUM_GLITCHES; i++)
{
m_PlayerGlitches[i] = false;
m_bHasPlayerGlitchOverride[i] = false;
}


m_GlitchNames["quickreload"] = GLITCH_QUICKRELOAD;
m_GlitchNames["fastfire"] = GLITCH_FASTFIRE;
m_GlitchNames["fastmove"] = GLITCH_FASTMOVE;
m_GlitchNames["crouchbug"] = GLITCH_CROUCHBUG;
m_GlitchNames["highcloserangedamage"] = GLITCH_CLOSEDAMAGE;
m_GlitchNames["hitanim"] = GLITCH_HITANIM;
m_GlitchNames["fastsprint"] = GLITCH_FASTSPRINT;
m_GlitchNames["baddrivebyhitbox"] = GLITCH_BADDRIVEBYHITBOX;
m_GlitchNames["quickstand"] = GLITCH_QUICKSTAND;
m_GlitchNames["kickoutofvehicle_onmodelreplace"] = GLITCH_KICKOUTOFVEHICLE_ONMODELREPLACE;
m_GlitchNames["vehicle_rapid_stop"] = GLITCH_VEHICLE_RAPID_STOP;
g_pMultiplayer->SetRapidVehicleStopFixEnabled(true);

g_pMultiplayer->DisableBadDrivebyHitboxes(true);
Expand Down Expand Up @@ -5992,12 +6012,9 @@ bool CClientGame::SetGlitchEnabled(unsigned char ucGlitch, bool bEnabled)
if (ucGlitch < NUM_GLITCHES && bEnabled != m_Glitches[ucGlitch])
{
m_Glitches[ucGlitch] = bEnabled;
if (ucGlitch == GLITCH_QUICKRELOAD)
g_pMultiplayer->DisableQuickReload(!bEnabled);
if (ucGlitch == GLITCH_CLOSEDAMAGE)
g_pMultiplayer->DisableCloseRangeDamage(!bEnabled);
if (ucGlitch == GLITCH_VEHICLE_RAPID_STOP)
g_pMultiplayer->SetRapidVehicleStopFixEnabled(!bEnabled);

// Calculate and apply effective state
ApplyEffectiveGlitchState(ucGlitch);
return true;
}
return false;
Expand All @@ -6008,6 +6025,83 @@ bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch)
return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch];
}

bool CClientGame::RequestPlayerGlitchEnabled(const std::string& strGlitchName, bool bEnabled)
{
// Find the glitch index for validation
auto it = m_GlitchNames.find(strGlitchName);
if (it == m_GlitchNames.end())
return false;

unsigned char ucGlitch = it->second;
if (ucGlitch >= NUM_GLITCHES)
return false;

// Send request to server (don't apply locally yet)
if (auto stream = g_pNet->AllocateNetBitStream())
{
stream->Write(strGlitchName);
stream->WriteBit(bEnabled);
g_pNet->SendPacket(PACKET_ID_PLAYER_GLITCH_REQUEST, stream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED);
g_pNet->DeallocateNetBitStream(stream);
}

return true;
}

bool CClientGame::SetPlayerGlitchEnabled(const std::string& strGlitchName, bool bEnabled)
{
auto it = m_GlitchNames.find(strGlitchName);
if (it == m_GlitchNames.end())
return false;

unsigned char ucGlitch = it->second;
if (ucGlitch >= NUM_GLITCHES)
return false;

// Check if state is actually changing
if (m_bHasPlayerGlitchOverride[ucGlitch] && m_PlayerGlitches[ucGlitch] == bEnabled)
return true;

// Set per-player override
m_PlayerGlitches[ucGlitch] = bEnabled;
m_bHasPlayerGlitchOverride[ucGlitch] = true;

// Apply effective state to game engine
ApplyEffectiveGlitchState(ucGlitch);
return true;
}

bool CClientGame::IsPlayerGlitchEnabled(const std::string& strGlitchName)
{
auto it = m_GlitchNames.find(strGlitchName);
if (it == m_GlitchNames.end())
return false;

unsigned char ucGlitch = it->second;
if (ucGlitch >= NUM_GLITCHES)
return false;

if (m_bHasPlayerGlitchOverride[ucGlitch])
return m_PlayerGlitches[ucGlitch];

return m_Glitches[ucGlitch];
}

void CClientGame::ApplyEffectiveGlitchState(unsigned char ucGlitch)
{
if (ucGlitch >= NUM_GLITCHES)
return;

bool bEffectiveState = m_bHasPlayerGlitchOverride[ucGlitch] ? m_PlayerGlitches[ucGlitch] : m_Glitches[ucGlitch];

if (ucGlitch == GLITCH_QUICKRELOAD)
g_pMultiplayer->DisableQuickReload(!bEffectiveState);
else if (ucGlitch == GLITCH_CLOSEDAMAGE)
g_pMultiplayer->DisableCloseRangeDamage(!bEffectiveState);
else if (ucGlitch == GLITCH_VEHICLE_RAPID_STOP)
g_pMultiplayer->SetRapidVehicleStopFixEnabled(!bEffectiveState);
}

bool CClientGame::SetWorldSpecialProperty(const WorldSpecialProperty property, const bool enabled) noexcept
{
switch (property)
Expand Down
12 changes: 12 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,15 @@ class CClientGame
bool SetGlitchEnabled(unsigned char cGlitch, bool bEnabled);
bool IsGlitchEnabled(unsigned char cGlitch);

bool RequestPlayerGlitchEnabled(const std::string& strGlitchName, bool bEnabled);
bool SetPlayerGlitchEnabled(const std::string& strGlitchName, bool bEnabled);
bool IsPlayerGlitchEnabled(const std::string& strGlitchName);

private:
void ApplyEffectiveGlitchState(unsigned char ucGlitch);

public:

bool SetWorldSpecialProperty(const WorldSpecialProperty property, const bool enabled) noexcept;
bool IsWorldSpecialProperty(const WorldSpecialProperty property);

Expand Down Expand Up @@ -783,6 +792,9 @@ class CClientGame
DWORD m_dwWanted;

SFixedArray<bool, NUM_GLITCHES> m_Glitches;
SFixedArray<bool, NUM_GLITCHES> m_PlayerGlitches;
SFixedArray<bool, NUM_GLITCHES> m_bHasPlayerGlitchOverride;
std::map<std::string, unsigned char> m_GlitchNames;

// Clouds Enabled
bool m_bCloudsEnabled;
Expand Down
53 changes: 52 additions & 1 deletion Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ void CLuaWorldDefs::LoadFunctions()
{"isTimeFrozen", ArgumentParser<IsTimeFrozen>},
{"isVolumetricShadowsEnabled", ArgumentParser<IsVolumetricShadowsEnabled>},
{"isDynamicPedShadowsEnabled", ArgumentParser<IsDynamicPedShadowsEnabled>},
{"testSphereAgainstWorld", ArgumentParser<TestSphereAgainstWorld>}};
{"testSphereAgainstWorld", ArgumentParser<TestSphereAgainstWorld>},

// Per-player glitch functions
{"setPlayerGlitchEnabled", SetPlayerGlitchEnabled},
{"isPlayerGlitchEnabled", IsPlayerGlitchEnabled}};

// Add functions
for (const auto& [name, func] : functions)
Expand Down Expand Up @@ -2352,3 +2356,50 @@ CLuaMultiReturn<bool, CClientEntity*, int, float, float, float, float, float, fl

return {result.collisionDetected, collidedEntity, result.modelID, result.entityPosition.fX, result.entityPosition.fY, result.entityPosition.fZ, ConvertRadiansToDegrees(result.entityRotation.fX), ConvertRadiansToDegrees(result.entityRotation.fY), ConvertRadiansToDegrees(result.entityRotation.fZ), result.lodID, result.type};
}

int CLuaWorldDefs::SetPlayerGlitchEnabled(lua_State* luaVM)
{
// bool setPlayerGlitchEnabled ( string glitchName, bool enable )
SString strGlitch;
bool bEnabled;

CScriptArgReader argStream(luaVM);
argStream.ReadString(strGlitch);
argStream.ReadBool(bEnabled);

if (!argStream.HasErrors())
{
// Send request to server
if (g_pClientGame->RequestPlayerGlitchEnabled(strGlitch, bEnabled))
{
lua_pushboolean(luaVM, true);
return 1;
}
}
else
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());

lua_pushboolean(luaVM, false);
return 1;
}

int CLuaWorldDefs::IsPlayerGlitchEnabled(lua_State* luaVM)
{
// bool isPlayerGlitchEnabled ( string glitchName )
SString strGlitch;

CScriptArgReader argStream(luaVM);
argStream.ReadString(strGlitch);

if (!argStream.HasErrors())
{
bool bEnabled = g_pClientGame->IsPlayerGlitchEnabled(strGlitch);
lua_pushboolean(luaVM, bEnabled);
return 1;
}
else
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());

lua_pushboolean(luaVM, false);
return 1;
}
4 changes: 4 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,8 @@ class CLuaWorldDefs : public CLuaDefs

static void RemoveGameWorld();
static void RestoreGameWorld();


LUA_DECLARE(SetPlayerGlitchEnabled);
LUA_DECLARE(IsPlayerGlitchEnabled);
};
12 changes: 12 additions & 0 deletions Client/mods/deathmatch/logic/rpc/CWorldRPCs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void CWorldRPCs::LoadFunctions()
AddHandler(SET_FPS_LIMIT, SetFPSLimit, "SetFPSLimit");
AddHandler(SET_GARAGE_OPEN, SetGarageOpen, "SetGarageOpen");
AddHandler(SET_GLITCH_ENABLED, SetGlitchEnabled, "SetGlitchEnabled");
AddHandler(SET_PLAYER_GLITCH_ENABLED, SetPlayerGlitchEnabled, "SetPlayerGlitchEnabled");
AddHandler(SET_JETPACK_WEAPON_ENABLED, SetJetpackWeaponEnabled, "SetJetpackWeaponEnabled");
AddHandler(SET_CLOUDS_ENABLED, SetCloudsEnabled, "SetCloudsEnabled");
AddHandler(SET_TRAFFIC_LIGHT_STATE, SetTrafficLightState, "SetTrafficLightState");
Expand Down Expand Up @@ -241,6 +242,17 @@ void CWorldRPCs::SetGlitchEnabled(NetBitStreamInterface& bitStream)
g_pClientGame->SetGlitchEnabled(eGlitch, (ucIsEnabled == 1));
}

void CWorldRPCs::SetPlayerGlitchEnabled(NetBitStreamInterface& bitStream)
{
SString strGlitchName;
bool bEnabled;

if (bitStream.Read(strGlitchName) && bitStream.ReadBit(bEnabled))
{
g_pClientGame->SetPlayerGlitchEnabled(strGlitchName, bEnabled);
}
}

void CWorldRPCs::SetJetpackWeaponEnabled(NetBitStreamInterface& bitStream)
{
unsigned char ucWeaponID = 0;
Expand Down
1 change: 1 addition & 0 deletions Client/mods/deathmatch/logic/rpc/CWorldRPCs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class CWorldRPCs : public CRPCFunctions
DECLARE_RPC(SetFPSLimit);
DECLARE_RPC(SetGarageOpen);
DECLARE_RPC(SetGlitchEnabled);
DECLARE_RPC(SetPlayerGlitchEnabled);
DECLARE_RPC(SetJetpackWeaponEnabled);
DECLARE_RPC(SetCloudsEnabled);
DECLARE_RPC(SetTrafficLightState);
Expand Down
40 changes: 40 additions & 0 deletions Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "packets/CPlayerListPacket.h"
#include "packets/CPlayerClothesPacket.h"
#include "packets/CPlayerWorldSpecialPropertyPacket.h"
#include "packets/CPlayerGlitchRequestPacket.h"
#include "packets/CServerInfoSyncPacket.h"
#include "packets/CLuaPacket.h"
#include "../utils/COpenPortsTester.h"
Expand Down Expand Up @@ -1328,6 +1329,12 @@ bool CGame::ProcessPacket(CPacket& Packet)
return true;
}

case PACKET_ID_PLAYER_GLITCH_REQUEST:
{
Packet_PlayerGlitchRequest(static_cast<CPlayerGlitchRequestPacket&>(Packet));
return true;
}

default:
break;
}
Expand Down Expand Up @@ -1480,6 +1487,12 @@ void CGame::InitialDataStream(CPlayer& Player)
CLuaArguments Arguments;
Player.CallEvent("onPlayerJoin", Arguments);

// Send the joining player's own glitch states (if any were set before joining)
if (Player.IsJoined())
{
Player.SendAllPlayerGlitchStates();
}

marker.Set("onPlayerJoin");

// Register them on the lightweight sync manager.
Expand Down Expand Up @@ -4186,6 +4199,33 @@ void CGame::Packet_PlayerWorldSpecialProperty(CPlayerWorldSpecialPropertyPacket&
player->CallEvent("onPlayerChangesWorldSpecialProperty", arguments, nullptr);
}

void CGame::Packet_PlayerGlitchRequest(CPlayerGlitchRequestPacket& packet) noexcept
{
CPlayer* pPlayer = packet.GetSourcePlayer();
if (!pPlayer)
return;

const std::string& strGlitchName = packet.GetGlitchName();
const bool bEnabled = packet.IsEnabled();


if (!IsGlitch(strGlitchName))
return;


if (pPlayer->SetPlayerGlitchEnabled(strGlitchName, bEnabled))
{

pPlayer->SendPlayerGlitchState(strGlitchName);


CLuaArguments arguments;
arguments.PushString(strGlitchName);
arguments.PushBoolean(bEnabled);
pPlayer->CallEvent("onPlayerGlitchStateChange", arguments, nullptr);
}
}

void CGame::Packet_PlayerModInfo(CPlayerModInfoPacket& Packet)
{
CPlayer* pPlayer = Packet.GetSourcePlayer();
Expand Down
2 changes: 2 additions & 0 deletions Server/mods/deathmatch/logic/CGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ class CGame
bool IsGlitchEnabled(eGlitchType cGlitch);
eGlitchType GetGlitchIndex(const std::string& strGlitch) { return m_GlitchNames[strGlitch]; }
bool IsGlitch(const std::string& strGlitch) { return m_GlitchNames.count(strGlitch) > 0; }
const std::map<std::string, eGlitchType>& GetGlitchNames() const { return m_GlitchNames; }

bool IsWorldSpecialPropertyEnabled(WorldSpecialProperty property) { return m_WorldSpecialProps[property]; }
void SetWorldSpecialPropertyEnabled(WorldSpecialProperty property, bool isEnabled) { m_WorldSpecialProps[property] = isEnabled; }
Expand Down Expand Up @@ -523,6 +524,7 @@ class CGame
void Packet_PlayerNetworkStatus(class CPlayerNetworkStatusPacket& Packet);
void Packet_PlayerResourceStart(class CPlayerResourceStartPacket& Packet);
void Packet_PlayerWorldSpecialProperty(class CPlayerWorldSpecialPropertyPacket& packet) noexcept;
void Packet_PlayerGlitchRequest(class CPlayerGlitchRequestPacket& packet) noexcept;

static void PlayerCompleteConnect(CPlayer* pPlayer);

Expand Down
5 changes: 5 additions & 0 deletions Server/mods/deathmatch/logic/CPacketTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "packets/CPlayerNetworkStatusPacket.h"
#include "packets/CPlayerResourceStartPacket.h"
#include "packets/CPlayerWorldSpecialPropertyPacket.h"
#include "packets/CPlayerGlitchRequestPacket.h"

CPacketTranslator::CPacketTranslator(CPlayerManager* pPlayerManager)
{
Expand Down Expand Up @@ -217,6 +218,10 @@ CPacket* CPacketTranslator::Translate(const NetServerPlayerID& Socket, ePacketID
pTemp = new CPlayerWorldSpecialPropertyPacket;
break;

case PACKET_ID_PLAYER_GLITCH_REQUEST:
pTemp = new CPlayerGlitchRequestPacket;
break;

default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions Server/mods/deathmatch/logic/CPerfStat.RPCPacketUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ ADD_ENUM1(SET_FPS_LIMIT)
ADD_ENUM1(SET_GARAGE_OPEN)
ADD_ENUM1(RESET_MAP_INFO)
ADD_ENUM1(SET_GLITCH_ENABLED)
ADD_ENUM1(SET_PLAYER_GLITCH_ENABLED)
ADD_ENUM1(SET_CLOUDS_ENABLED)
ADD_ENUM1(REMOVE_ELEMENT_DATA)
ADD_ENUM1(SET_VEHICLE_HANDLING)
Expand Down
Loading
Loading