Skip to content
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

Add a way to reserve players on the first received RakNet packet #827

Open
wants to merge 2 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
4 changes: 3 additions & 1 deletion SDK/include/network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ enum class ClientVersion : uint8_t
{
ClientVersion_SAMP_037,
ClientVersion_SAMP_03DL,
ClientVersion_openmp
ClientVersion_openmp,

ClientVersion_none = 255
};

struct PeerRequestParams
Expand Down
10 changes: 10 additions & 0 deletions SDK/include/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1080,3 +1080,13 @@ struct IPlayerPool : public IExtensible, public IReadOnlyPool<IPlayer>
/// Get the colour assigned to a player ID when it first connects.
virtual Colour getDefaultColour(int pid) const = 0;
};

static const UID IPlayerReserveExtension_UID = UID(0x7DEF26D24A04F2FD);
struct IPlayerReserveExtension : public IExtension
{
PROVIDE_EXT_UID(IPlayerReserveExtension_UID)

/// Request a new player with the given network parameters
virtual Pair<NewConnectionResult, IPlayer*> reservePlayer(const PeerNetworkData& netData) = 0;
virtual NewConnectionResult finalizePlayer(IPlayer* peer, const PeerRequestParams& params) = 0;
};
72 changes: 58 additions & 14 deletions Server/Components/LegacyNetwork/legacy_network_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,18 +317,6 @@ IPlayer* RakNetLegacyNetwork::OnPeerConnect(RakNet::RPCParameters* rpcParams, bo
{
const RakNet::PlayerID rid = rpcParams->sender;

if (playerFromRakIndex[rpcParams->senderIndex])
{
// Connection already exists
return nullptr;
}

PeerNetworkData netData {};
netData.networkID.address.ipv6 = false;
netData.networkID.address.v4 = rid.binaryAddress;
netData.networkID.port = rid.port;
netData.network = this;

Pair<NewConnectionResult, IPlayer*> newConnectionResult { NewConnectionResult_Ignore, nullptr };

const bool isDL = version == LegacyClientVersion_03DL && (SAMPRakNet::GetToken() == (challenge ^ LegacyClientVersion_03DL));
Expand All @@ -344,7 +332,35 @@ IPlayer* RakNetLegacyNetwork::OnPeerConnect(RakNet::RPCParameters* rpcParams, bo
params.bot = isNPC;
params.serial = serial;
params.isUsingOfficialClient = isUsingOfficialClient;
newConnectionResult = core->getPlayers().requestPlayer(netData, params);

if (reservePlayers)
{
if (!playerFromRakIndex[rpcParams->senderIndex])
{
// Player not reserved
rakNetServer.Kick(rid);
return nullptr;
}

newConnectionResult.second = playerFromRakIndex[rpcParams->senderIndex];
newConnectionResult.first = reservePlayers->finalizePlayer(newConnectionResult.second, params);
}
else
{
if (playerFromRakIndex[rpcParams->senderIndex])
{
// Connection already exists
return nullptr;
}

PeerNetworkData netData {};
netData.networkID.address.ipv6 = false;
netData.networkID.address.v4 = rid.binaryAddress;
netData.networkID.port = rid.port;
netData.network = this;

newConnectionResult = core->getPlayers().requestPlayer(netData, params);
}
}
else
{
Expand All @@ -362,7 +378,15 @@ IPlayer* RakNetLegacyNetwork::OnPeerConnect(RakNet::RPCParameters* rpcParams, bo

if (newConnectionResult.first != NewConnectionResult_VersionMismatch)
{
rakNetServer.Kick(rid);
if (reservePlayers)
{
// Player is reserved, kick them
newConnectionResult.second->kick();
}
else
{
rakNetServer.Kick(rid);
}
}
}
return nullptr;
Expand Down Expand Up @@ -774,6 +798,7 @@ void RakNetLegacyNetwork::update()
void RakNetLegacyNetwork::init(ICore* c)
{
core = c;
reservePlayers = queryExtension<IPlayerReserveExtension>(core->getPlayers());

core->getEventDispatcher().addEventHandler(this);
core->getPlayers().getPlayerChangeDispatcher().addEventHandler(this);
Expand Down Expand Up @@ -872,6 +897,25 @@ void RakNetLegacyNetwork::onTick(Microseconds elapsed, TimePoint now)
}

IPlayer* player = playerFromRakIndex[pkt->playerIndex];
if (!player && reservePlayers)
{
PeerNetworkData netData {};
netData.networkID.address.ipv6 = false;
netData.networkID.address.v4 = pkt->playerId.binaryAddress;
netData.networkID.port = pkt->playerId.port;
netData.network = this;

Pair<NewConnectionResult, IPlayer*> newConnectionResult = reservePlayers->reservePlayer(netData);
if (newConnectionResult.first == NewConnectionResult_Success)
{
playerFromRakIndex[pkt->playerIndex] = newConnectionResult.second;
}
else
{
rakNetServer.Kick(pkt->playerId);
}
}

if (player)
{
NetworkBitStream bs(pkt->data, pkt->length, false);
Expand Down
1 change: 1 addition & 0 deletions Server/Components/LegacyNetwork/legacy_network_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class RakNetLegacyNetwork final : public Network, public CoreEventHandler, publi
{
private:
ICore* core = nullptr;
IPlayerReserveExtension* reservePlayers = nullptr;
Query query;
RakNet::RakServerInterface& rakNetServer;
std::array<IPlayer*, PLAYER_POOL_SIZE> playerFromRakIndex;
Expand Down
8 changes: 4 additions & 4 deletions Server/Source/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ EPlayerNameStatus Player::setName(StringView name)
return EPlayerNameStatus::Taken;
}

const auto oldName = name_;
name_ = name;
const auto oldName = clientParams_.name;
clientParams_.name = name;
pool_.playerChangeDispatcher.dispatch(&PlayerChangeEventHandler::onPlayerNameChange, *this, oldName);

NetCode::RPC::SetPlayerName setPlayerNameRPC;
setPlayerNameRPC.PlayerID = poolID;
setPlayerNameRPC.Name = StringView(name_);
setPlayerNameRPC.Name = StringView(clientParams_.name);
setPlayerNameRPC.Success = true;
PacketHelper::broadcast(setPlayerNameRPC, pool_);
return EPlayerNameStatus::Updated;
Expand Down Expand Up @@ -365,7 +365,7 @@ void Player::ban(StringView reason)
{
PeerAddress::AddressString address;
PeerAddress::ToString(netData_.networkID.address, address);
const BanEntry entry(address, name_, reason);
const BanEntry entry(address, clientParams_.name, reason);
for (INetwork* network : pool_.core.getNetworks())
{
network->ban(entry);
Expand Down
54 changes: 34 additions & 20 deletions Server/Source/player_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,40 @@ enum SecondarySyncUpdateType
SecondarySyncUpdateType_Trailer = (1 << 2),
};

struct ClientParams
{
HybridString<16> versionName;
HybridString<MAX_PLAYER_NAME + 1> name;
HybridString<16> serial;
ClientVersion version;
bool isBot;
bool isUsingOfficialClient;

ClientParams()
: version(ClientVersion::ClientVersion_none)
{
}

ClientParams(const PeerRequestParams& params)
: versionName(params.versionName)
, name(params.name)
, serial(params.serial)
, version(params.version)
, isBot(params.bot)
, isUsingOfficialClient(params.isUsingOfficialClient)
{
}
};

struct Player final : public IPlayer, public PoolIDProvider, public NoCopy
{
PlayerPool& pool_;
PeerNetworkData netData_;
ClientVersion version_;
HybridString<16> versionName_;
ClientParams clientParams_;
Vector3 pos_;
Vector3 cameraPos_;
Vector3 cameraLookAt_;
GTAQuat rot_;
HybridString<MAX_PLAYER_NAME + 1> name_;
HybridString<16> serial_;
WeaponSlots weapons_;
Colour colour_;
FlatHashMap<int, Colour> othersColours_;
Expand Down Expand Up @@ -107,7 +129,6 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy
int targetPlayer_, targetActor_;
TimePoint chatBubbleExpiration_;
PlayerChatBubble chatBubble_;
const bool isBot_;
bool toSpawn_;
TimePoint lastGameTimeUpdate_;
PlayerSpectateData spectateData_;
Expand All @@ -116,7 +137,6 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy
int defaultObjectsRemoved_;
bool allowWeapons_;
bool allowTeleport_;
bool isUsingOfficialClient_;

PrimarySyncUpdateType primarySyncUpdateType_;
int secondarySyncUpdateType_;
Expand Down Expand Up @@ -203,16 +223,12 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy
IExtensible::resetExtensions();
}

Player(PlayerPool& pool, const PeerNetworkData& netData, const PeerRequestParams& params, bool* allAnimationLibraries, bool* validateAnimations, bool* allowInteriorWeapons, IFixesComponent* fixesComponent)
Player(PlayerPool& pool, const PeerNetworkData& netData, bool* allAnimationLibraries, bool* validateAnimations, bool* allowInteriorWeapons, IFixesComponent* fixesComponent)
: pool_(pool)
, netData_(netData)
, version_(params.version)
, versionName_(params.versionName)
, pos_(0.0f, 0.0f, 0.0f)
, cameraPos_(0.f, 0.f, 0.f)
, cameraLookAt_(0.f, 0.f, 0.f)
, name_(params.name)
, serial_(params.serial)
, virtualWorld_(0)
, score_(0)
, fightingStyle_(PlayerFightingStyle_Normal)
Expand Down Expand Up @@ -245,7 +261,6 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy
, targetPlayer_(INVALID_PLAYER_ID)
, targetActor_(INVALID_ACTOR_ID)
, chatBubbleExpiration_(Time::now())
, isBot_(params.bot)
, toSpawn_(false)
, lastGameTimeUpdate_()
, spectateData_({ false, INVALID_PLAYER_ID, PlayerSpectateData::ESpectateType::None })
Expand All @@ -254,7 +269,6 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy
, defaultObjectsRemoved_(0)
, allowWeapons_(true)
, allowTeleport_(false)
, isUsingOfficialClient_(params.isUsingOfficialClient)
, primarySyncUpdateType_(PrimarySyncUpdateType::None)
, secondarySyncUpdateType_(0)
, lastScoresAndPings_(Time::now())
Expand Down Expand Up @@ -299,22 +313,22 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy

ClientVersion getClientVersion() const override
{
return version_;
return clientParams_.version;
}

StringView getClientVersionName() const override
{
return versionName_;
return clientParams_.versionName;
}

bool isBot() const override
{
return isBot_;
return clientParams_.isBot;
}

bool isUsingOfficialClient() const override
{
return isUsingOfficialClient_;
return clientParams_.isUsingOfficialClient;
}

void setState(PlayerState state, bool dispatchEvents = true);
Expand Down Expand Up @@ -1091,12 +1105,12 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy

StringView getName() const override
{
return name_;
return clientParams_.name;
}

StringView getSerial() const override
{
return serial_;
return clientParams_.serial;
}

int getID() const override
Expand Down Expand Up @@ -1548,7 +1562,7 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy

virtualWorld_ = vw;

if (version_ == ClientVersion::ClientVersion_SAMP_037)
if (clientParams_.version == ClientVersion::ClientVersion_SAMP_037)
return;

NetCode::RPC::SetPlayerVirtualWorld setWorld;
Expand Down
Loading
Loading