Skip to content

Commit

Permalink
Merge pull request #962 from openmultiplayer/amir/improve-scoreboard
Browse files Browse the repository at this point in the history
cache generated BS for a short period of time for scoreboard rpc
  • Loading branch information
AmyrAhmady committed Aug 14, 2024
2 parents cffcc4b + bf9d4d8 commit 85650d5
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
10 changes: 8 additions & 2 deletions Server/Source/player_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public
bool* allowInteriorWeapons_;
int* maxBots;
StaticArray<bool, 256> allowNickCharacter;
TimePoint lastScoresAndPingsCached;

struct PlayerRequestSpawnRPCHandler : public SingleNetworkInEventHandler
{
Expand Down Expand Up @@ -95,9 +96,13 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public
const TimePoint now = Time::now();

// SA:MP client is nice and makes this request every 3 seconds.
if (now - player.lastScoresAndPings_ >= Seconds(2))
// But not every client is the official one... so I guess we need a hard limit for player here as well
if (now - player.lastScoresAndPings_ >= Seconds(3))
{
NetCode::RPC::SendPlayerScoresAndPings sendPlayerScoresAndPingsRPC(self.storage.entries());
// There is also a cache tick diff we are sending to SendPlayerScoresAndPings constructor to use in SendPlayerScoresAndPings::write
// This is added to make sure we have a global cache and we don't recalculate and regenerate for every player and every request of theirs
// So instead it keeps a cache of our bitstream to use, which won't loop through player pool and gathering data
NetCode::RPC::SendPlayerScoresAndPings sendPlayerScoresAndPingsRPC(self.storage.entries(), now - self.lastScoresAndPingsCached);
PacketHelper::send(sendPlayerScoresAndPingsRPC, peer);
player.lastScoresAndPings_ = now;
}
Expand Down Expand Up @@ -1820,6 +1825,7 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public
PlayerPool(ICore& core)
: core(core)
, networks(core.getNetworks())
, lastScoresAndPingsCached(Time::now())
, playerRequestSpawnRPCHandler(*this)
, playerRequestScoresAndPingsRPCHandler(*this)
, onPlayerClickMapRPCHandler(*this)
Expand Down
21 changes: 16 additions & 5 deletions Shared/NetCode/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1123,9 +1123,11 @@ namespace RPC
struct SendPlayerScoresAndPings : NetworkPacketBase<155, NetworkPacketType::RPC, OrderingChannel_SyncRPC>
{
const FlatPtrHashSet<IPlayer>& Players;
const Nanoseconds LastCachedTickDiff;

SendPlayerScoresAndPings(const FlatPtrHashSet<IPlayer>& players)
SendPlayerScoresAndPings(const FlatPtrHashSet<IPlayer>& players, Nanoseconds lastCachedTickDiff)
: Players(players)
, LastCachedTickDiff(lastCachedTickDiff)
{
}

Expand All @@ -1136,12 +1138,21 @@ namespace RPC

void write(NetworkBitStream& bs) const
{
for (IPlayer* player : Players)
// This is added to make sure we have a global cache and we don't recalculate and regenerate for every player and every request of theirs
// So instead it keeps a cache of our bitstream to use, which won't loop through player pool and gathering data
static NetworkBitStream cache;
if (LastCachedTickDiff >= Seconds(2))
{
bs.writeUINT16(player->getID());
bs.writeINT32(player->getScore());
bs.writeUINT32(player->getPing());
cache.reset();
for (IPlayer* player : Players)
{
cache.writeUINT16(player->getID());
cache.writeINT32(player->getScore());
cache.writeUINT32(player->getPing());
}
}

bs.WriteBits(cache.GetData(), cache.GetNumberOfBitsUsed());
}
};

Expand Down

0 comments on commit 85650d5

Please sign in to comment.