mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-08-20 09:57:09 +00:00
perf: skip split-screen system-mate checks on dedicated server
The EntityTracker and TrackedEntity classes have O(players^2 * entities) loops that check IsSameSystem() for split-screen couch co-op visibility expansion. On the dedicated server, all players are remote so IsSameSystem() always returns false, making these loops pure overhead. Skip them entirely when g_Win64DedicatedServer is true. The original split-screen logic is preserved for game client LAN hosting.
This commit is contained in:
parent
aecef7f10d
commit
ea15409bb9
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -420,3 +420,4 @@ server-data/
|
||||||
tools/*.class
|
tools/*.class
|
||||||
tools/*.swf
|
tools/*.swf
|
||||||
tools/staging/
|
tools/staging/
|
||||||
|
tools/server-monitor/
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@
|
||||||
#include "..\Minecraft.World\net.minecraft.world.level.chunk.h"
|
#include "..\Minecraft.World\net.minecraft.world.level.chunk.h"
|
||||||
#include "PlayerConnection.h"
|
#include "PlayerConnection.h"
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
extern bool g_Win64DedicatedServer;
|
||||||
|
#endif
|
||||||
|
|
||||||
EntityTracker::EntityTracker(ServerLevel *level)
|
EntityTracker::EntityTracker(ServerLevel *level)
|
||||||
{
|
{
|
||||||
this->level = level;
|
this->level = level;
|
||||||
|
|
@ -139,32 +143,40 @@ void EntityTracker::tick()
|
||||||
// 4J Stu - If one player on a system is updated, then make sure they all are as they all have their
|
// 4J Stu - If one player on a system is updated, then make sure they all are as they all have their
|
||||||
// range extended to include entities visible by any other player on the system
|
// range extended to include entities visible by any other player on the system
|
||||||
// Fix for #11194 - Gameplay: Host player and their split-screen avatars can become invisible and invulnerable to client.
|
// Fix for #11194 - Gameplay: Host player and their split-screen avatars can become invisible and invulnerable to client.
|
||||||
MinecraftServer *server = MinecraftServer::getInstance();
|
// NOTE: On dedicated servers, IsSameSystem() always returns false for remote
|
||||||
for( unsigned int i = 0; i < server->getPlayers()->players.size(); i++ )
|
// players (no split-screen), so this loop does nothing. Skip it entirely to
|
||||||
|
// avoid the O(players * movedPlayers) overhead.
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (!g_Win64DedicatedServer)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
shared_ptr<ServerPlayer> ep = server->getPlayers()->players[i];
|
MinecraftServer *server = MinecraftServer::getInstance();
|
||||||
if( ep->dimension != level->dimension->id ) continue;
|
for( unsigned int i = 0; i < server->getPlayers()->players.size(); i++ )
|
||||||
|
|
||||||
if( ep->connection == nullptr ) continue;
|
|
||||||
INetworkPlayer *thisPlayer = ep->connection->getNetworkPlayer();
|
|
||||||
if( thisPlayer == nullptr ) continue;
|
|
||||||
|
|
||||||
bool addPlayer = false;
|
|
||||||
for (unsigned int j = 0; j < movedPlayers.size(); j++)
|
|
||||||
{
|
{
|
||||||
shared_ptr<ServerPlayer> sp = movedPlayers[j];
|
shared_ptr<ServerPlayer> ep = server->getPlayers()->players[i];
|
||||||
|
if( ep->dimension != level->dimension->id ) continue;
|
||||||
|
|
||||||
if( sp == ep ) break;
|
if( ep->connection == nullptr ) continue;
|
||||||
|
INetworkPlayer *thisPlayer = ep->connection->getNetworkPlayer();
|
||||||
|
if( thisPlayer == nullptr ) continue;
|
||||||
|
|
||||||
if(sp->connection == nullptr) continue;
|
bool addPlayer = false;
|
||||||
INetworkPlayer *otherPlayer = sp->connection->getNetworkPlayer();
|
for (unsigned int j = 0; j < movedPlayers.size(); j++)
|
||||||
if( otherPlayer != nullptr && thisPlayer->IsSameSystem(otherPlayer) )
|
|
||||||
{
|
{
|
||||||
addPlayer = true;
|
shared_ptr<ServerPlayer> sp = movedPlayers[j];
|
||||||
break;
|
|
||||||
|
if( sp == ep ) break;
|
||||||
|
|
||||||
|
if(sp->connection == nullptr) continue;
|
||||||
|
INetworkPlayer *otherPlayer = sp->connection->getNetworkPlayer();
|
||||||
|
if( otherPlayer != nullptr && thisPlayer->IsSameSystem(otherPlayer) )
|
||||||
|
{
|
||||||
|
addPlayer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if( addPlayer ) movedPlayers.push_back( ep );
|
||||||
if( addPlayer ) movedPlayers.push_back( ep );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < movedPlayers.size(); i++)
|
for (unsigned int i = 0; i < movedPlayers.size(); i++)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
extern bool g_Win64DedicatedServer;
|
||||||
|
#endif
|
||||||
|
|
||||||
TrackedEntity::TrackedEntity(shared_ptr<Entity> e, int range, int updateInterval, bool trackDelta)
|
TrackedEntity::TrackedEntity(shared_ptr<Entity> e, int range, int updateInterval, bool trackDelta)
|
||||||
{
|
{
|
||||||
// 4J added initialisers
|
// 4J added initialisers
|
||||||
|
|
@ -351,6 +355,19 @@ void TrackedEntity::sendDirtyEntityData()
|
||||||
|
|
||||||
void TrackedEntity::broadcast(shared_ptr<Packet> packet)
|
void TrackedEntity::broadcast(shared_ptr<Packet> packet)
|
||||||
{
|
{
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
// On dedicated servers, IsSameSystem() always returns false for remote players
|
||||||
|
// (no split-screen), so the dedup loop never filters anything. Skip straight
|
||||||
|
// to sending to all players in seenBy to avoid O(seenBy^2) overhead.
|
||||||
|
if (g_Win64DedicatedServer)
|
||||||
|
{
|
||||||
|
for (auto& player : seenBy)
|
||||||
|
{
|
||||||
|
player->connection->send(packet);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if( Packet::canSendToAnyClient( packet ) )
|
if( Packet::canSendToAnyClient( packet ) )
|
||||||
{
|
{
|
||||||
// 4J-PB - due to the knockback on a player being hit, we need to send to all players, but limit the network traffic here to players that have not already had it sent to their system
|
// 4J-PB - due to the knockback on a player being hit, we need to send to all players, but limit the network traffic here to players that have not already had it sent to their system
|
||||||
|
|
@ -462,7 +479,13 @@ TrackedEntity::eVisibility TrackedEntity::isVisible(EntityTracker *tracker, shar
|
||||||
// 4J - added. Try and find other players who are in the same dimension as this one and on the same machine, and extend our visibility
|
// 4J - added. Try and find other players who are in the same dimension as this one and on the same machine, and extend our visibility
|
||||||
// so things are consider visible to this player if they are near the other one. This is because we only send entity tracking info to
|
// so things are consider visible to this player if they are near the other one. This is because we only send entity tracking info to
|
||||||
// players who canReceiveAllPackets().
|
// players who canReceiveAllPackets().
|
||||||
if(!bVisible)
|
// NOTE: On dedicated servers, all real players are remote so IsSameSystem()
|
||||||
|
// always returns false. Skip this O(players) loop entirely.
|
||||||
|
#ifdef _WINDOWS64
|
||||||
|
if (!bVisible && !g_Win64DedicatedServer)
|
||||||
|
#else
|
||||||
|
if (!bVisible)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
MinecraftServer *server = MinecraftServer::getInstance();
|
MinecraftServer *server = MinecraftServer::getInstance();
|
||||||
INetworkPlayer *thisPlayer = sp->connection->getNetworkPlayer();
|
INetworkPlayer *thisPlayer = sp->connection->getNetworkPlayer();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue