diff --git a/code/components/citizen-server-impl/include/state/ServerGameState.h b/code/components/citizen-server-impl/include/state/ServerGameState.h index fb89b982d5..7bf0be0dbd 100644 --- a/code/components/citizen-server-impl/include/state/ServerGameState.h +++ b/code/components/citizen-server-impl/include/state/ServerGameState.h @@ -1314,12 +1314,24 @@ struct GameStateClientData uint32_t routingBucket = 0; float playerCullingRadius = 0.0f; + + std::bitset<1000000> playerCullingRelevantPlayers; inline float GetPlayerCullingRadius() { return playerCullingRadius; } + inline std::vector GetPlayerCullingRelevantPlayers() + { + return playerCullingRelevantPlayers; + } + + inline bool GetPlayerCullingIsRelevantPlayer(uint32_t playerId) + { + return playerCullingRelevantPlayers.test(playerId); + } + GameStateClientData() : syncing(false) { diff --git a/code/components/citizen-server-impl/src/state/ServerGameState.cpp b/code/components/citizen-server-impl/src/state/ServerGameState.cpp index 818444154e..ce48338d7f 100644 --- a/code/components/citizen-server-impl/src/state/ServerGameState.cpp +++ b/code/components/citizen-server-impl/src/state/ServerGameState.cpp @@ -1220,6 +1220,11 @@ void ServerGameState::Tick(fx::ServerInstanceBase* instance) } } + if (isRelevant && entity->type == sync::NetObjEntityType::Player && !clientDataUnlocked->GetPlayerCullingRelevantPlayers().none()) + { + isRelevant = clientDataUnlocked->GetPlayerCullingIsRelevantPlayer(entityClient->GetNetId()); + } + // if we own this entity, we need to assign as relevant. // -> even if not client-script, as if it isn't, we'll end up stuck without migrating it if (ownsEntity/* && entity->IsOwnedByClientScript()*/) diff --git a/code/components/citizen-server-impl/src/state/ServerGameState_Scripting.cpp b/code/components/citizen-server-impl/src/state/ServerGameState_Scripting.cpp index 7b4d448a14..e5d03ccd23 100644 --- a/code/components/citizen-server-impl/src/state/ServerGameState_Scripting.cpp +++ b/code/components/citizen-server-impl/src/state/ServerGameState_Scripting.cpp @@ -1505,6 +1505,36 @@ static void Init() return true; })); + fx::ScriptEngine::RegisterNativeHandler("SET_PLAYER_CULLING_RELEVANT_PLAYERS", MakeClientFunction([](fx::ScriptContext& context, const fx::ClientSharedPtr& client) + { + if (context.GetArgumentCount() > 1) + { + std::bitset<1000000> players; + if (context.GetArgument(1) != 0) + { + for (int i = 1; i < context.GetArgumentCount(); i ) + { + int value = context.GetArgument(i); + players.set(value); + } + } + + // get the current resource manager + auto resourceManager = fx::ResourceManager::GetCurrent(); + + // get the owning server instance + auto instance = resourceManager->GetComponent()->Get(); + + // get the server's game state + auto gameState = instance->GetComponent(); + + auto [lock, clientData] = gameState->ExternalGetClientData(client); + clientData->playerCullingRelevantPlayers = players; + } + + return true; + })); + fx::ScriptEngine::RegisterNativeHandler("SET_ENTITY_IGNORE_REQUEST_CONTROL_FILTER", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity) { if (context.GetArgumentCount() > 1) diff --git a/ext/native-decls/SetPlayerCullingReleventPlayers.md b/ext/native-decls/SetPlayerCullingReleventPlayers.md new file mode 100644 index 0000000000..b8cf0e9d91 --- /dev/null +++ b/ext/native-decls/SetPlayerCullingReleventPlayers.md @@ -0,0 +1,29 @@ +--- +ns: CFX +apiset: server +--- +## SET_PLAYER_CULLING_RELEVANT_PLAYERS + +```c +void SET_PLAYER_CULLING_RELEVANT_PLAYERS(char* playerSrc, int playerTarget); +``` + +Sets the culling relevent players list for the specified player. +Set to `0` to reset. + +## Parameters +* **playerSrc**: The player to set the culling players for. +* **playerTarget**: The players you want cull. (You can pass many net ids) + +## Examples + +```lua +RegisterServerEvent("cullingPlayers") +AddEventHandler("cullingPlayers", function(list) + local Source = source + for i, v in ipairs(list) do + list[i] = tonumber(v) + end + SetPlayerCullingRelevantPlayers(Source, table.unpack(list)) +end) +```