mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-04-21 15:40:33 +00:00
rework GetClient to use new ForEachClient, return shared_ptr
this simplifies a lot of functions, and removes a lot of potential errors when using the function. You now only check whether the return value is null, and if it's not, you have a valid, reference-counted, client pointer.
This commit is contained in:
@@ -129,4 +129,5 @@ private:
|
|||||||
std::chrono::time_point<TimeType> mLastPingTime;
|
std::chrono::time_point<TimeType> mLastPingTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::optional<std::weak_ptr<TClient>> GetClient(class TServer& Server, int ID);
|
// Returns a valid client, or nullptr if no such client exists
|
||||||
|
std::shared_ptr<TClient> GetClient(class TServer& Server, int ID);
|
||||||
|
|||||||
@@ -136,20 +136,14 @@ int TClient::SecondsSinceLastPing() {
|
|||||||
return int(seconds);
|
return int(seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::weak_ptr<TClient>> GetClient(TServer& Server, int ID) {
|
std::shared_ptr<TClient> GetClient(TServer& Server, int ID) {
|
||||||
std::optional<std::weak_ptr<TClient>> MaybeClient { std::nullopt };
|
std::shared_ptr<TClient> Result {};
|
||||||
Server.ForEachClientWeak([&](std::weak_ptr<TClient> CPtr) -> bool {
|
Server.ForEachClient([&](const auto& Client) {
|
||||||
ReadLock Lock(Server.GetClientMutex());
|
if (Client->GetID() == ID) {
|
||||||
try {
|
Result = Client;
|
||||||
auto C = CPtr.lock();
|
return Break;
|
||||||
if (C->GetID() == ID) {
|
|
||||||
MaybeClient = CPtr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (const std::exception&) {
|
|
||||||
// ignore
|
|
||||||
}
|
}
|
||||||
return true;
|
return Continue;
|
||||||
});
|
});
|
||||||
return MaybeClient;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,15 +119,14 @@ static inline std::pair<bool, std::string> InternalTriggerClientEvent(int Player
|
|||||||
LuaAPI::MP::Engine->Network().SendToAll(nullptr, StringToVector(Packet), true, true);
|
LuaAPI::MP::Engine->Network().SendToAll(nullptr, StringToVector(Packet), true, true);
|
||||||
return { true, "" };
|
return { true, "" };
|
||||||
} else {
|
} else {
|
||||||
auto MaybeClient = GetClient(LuaAPI::MP::Engine->Server(), PlayerID);
|
auto Client = GetClient(LuaAPI::MP::Engine->Server(), PlayerID);
|
||||||
if (!MaybeClient || MaybeClient.value().expired()) {
|
if (!Client) {
|
||||||
beammp_lua_errorf("TriggerClientEvent invalid Player ID '{}'", PlayerID);
|
beammp_lua_errorf("TriggerClientEvent invalid Player ID '{}'", PlayerID);
|
||||||
return { false, "Invalid Player ID" };
|
return { false, "Invalid Player ID" };
|
||||||
}
|
}
|
||||||
auto c = MaybeClient.value().lock();
|
if (!LuaAPI::MP::Engine->Network().Respond(*Client, StringToVector(Packet), true)) {
|
||||||
if (!LuaAPI::MP::Engine->Network().Respond(*c, StringToVector(Packet), true)) {
|
|
||||||
beammp_lua_errorf("Respond failed, dropping client {}", PlayerID);
|
beammp_lua_errorf("Respond failed, dropping client {}", PlayerID);
|
||||||
LuaAPI::MP::Engine->Network().ClientKick(*c, "Disconnected after failing to receive packets");
|
LuaAPI::MP::Engine->Network().ClientKick(*Client, "Disconnected after failing to receive packets");
|
||||||
return { false, "Respond failed, dropping client" };
|
return { false, "Respond failed, dropping client" };
|
||||||
}
|
}
|
||||||
return { true, "" };
|
return { true, "" };
|
||||||
@@ -140,13 +139,12 @@ std::pair<bool, std::string> LuaAPI::MP::TriggerClientEvent(int PlayerID, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, std::string> LuaAPI::MP::DropPlayer(int ID, std::optional<std::string> MaybeReason) {
|
std::pair<bool, std::string> LuaAPI::MP::DropPlayer(int ID, std::optional<std::string> MaybeReason) {
|
||||||
auto MaybeClient = GetClient(Engine->Server(), ID);
|
auto Client = GetClient(Engine->Server(), ID);
|
||||||
if (!MaybeClient || MaybeClient.value().expired()) {
|
if (!Client) {
|
||||||
beammp_lua_errorf("Tried to drop client with id {}, who doesn't exist", ID);
|
beammp_lua_errorf("Tried to drop client with id {}, who doesn't exist", ID);
|
||||||
return { false, "Player does not exist" };
|
return { false, "Player does not exist" };
|
||||||
}
|
}
|
||||||
auto c = MaybeClient.value().lock();
|
LuaAPI::MP::Engine->Network().ClientKick(*Client, MaybeReason.value_or("No reason"));
|
||||||
LuaAPI::MP::Engine->Network().ClientKick(*c, MaybeReason.value_or("No reason"));
|
|
||||||
return { true, "" };
|
return { true, "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,16 +156,15 @@ std::pair<bool, std::string> LuaAPI::MP::SendChatMessage(int ID, const std::stri
|
|||||||
Engine->Network().SendToAll(nullptr, StringToVector(Packet), true, true);
|
Engine->Network().SendToAll(nullptr, StringToVector(Packet), true, true);
|
||||||
Result.first = true;
|
Result.first = true;
|
||||||
} else {
|
} else {
|
||||||
auto MaybeClient = GetClient(Engine->Server(), ID);
|
auto Client = GetClient(Engine->Server(), ID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
auto c = MaybeClient.value().lock();
|
if (!Client->IsSynced()) {
|
||||||
if (!c->IsSynced()) {
|
|
||||||
Result.first = false;
|
Result.first = false;
|
||||||
Result.second = "Player still syncing data";
|
Result.second = "Player still syncing data";
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
LogChatMessage("<Server> (to \"" + c->GetName() + "\")", -1, Message);
|
LogChatMessage("<Server> (to \"" + Client->GetName() + "\")", -1, Message);
|
||||||
if (!Engine->Network().Respond(*c, StringToVector(Packet), true)) {
|
if (!Engine->Network().Respond(*Client, StringToVector(Packet), true)) {
|
||||||
beammp_errorf("Failed to send chat message back to sender (id {}) - did the sender disconnect?", ID);
|
beammp_errorf("Failed to send chat message back to sender (id {}) - did the sender disconnect?", ID);
|
||||||
// TODO: should we return an error here?
|
// TODO: should we return an error here?
|
||||||
}
|
}
|
||||||
@@ -184,18 +181,17 @@ std::pair<bool, std::string> LuaAPI::MP::SendChatMessage(int ID, const std::stri
|
|||||||
|
|
||||||
std::pair<bool, std::string> LuaAPI::MP::RemoveVehicle(int PID, int VID) {
|
std::pair<bool, std::string> LuaAPI::MP::RemoveVehicle(int PID, int VID) {
|
||||||
std::pair<bool, std::string> Result;
|
std::pair<bool, std::string> Result;
|
||||||
auto MaybeClient = GetClient(Engine->Server(), PID);
|
auto Client = GetClient(Engine->Server(), PID);
|
||||||
if (!MaybeClient || MaybeClient.value().expired()) {
|
if (!Client) {
|
||||||
beammp_lua_error("RemoveVehicle invalid Player ID");
|
beammp_lua_error("RemoveVehicle invalid Player ID");
|
||||||
Result.first = false;
|
Result.first = false;
|
||||||
Result.second = "Invalid Player ID";
|
Result.second = "Invalid Player ID";
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
auto c = MaybeClient.value().lock();
|
if (!Client->GetCarData(VID).empty()) {
|
||||||
if (!c->GetCarData(VID).empty()) {
|
|
||||||
std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
|
std::string Destroy = "Od:" + std::to_string(PID) + "-" + std::to_string(VID);
|
||||||
Engine->Network().SendToAll(nullptr, StringToVector(Destroy), true, true);
|
Engine->Network().SendToAll(nullptr, StringToVector(Destroy), true, true);
|
||||||
c->DeleteCar(VID);
|
Client->DeleteCar(VID);
|
||||||
Result.first = true;
|
Result.first = true;
|
||||||
} else {
|
} else {
|
||||||
Result.first = false;
|
Result.first = false;
|
||||||
@@ -273,18 +269,18 @@ void LuaAPI::MP::Sleep(size_t Ms) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LuaAPI::MP::IsPlayerConnected(int ID) {
|
bool LuaAPI::MP::IsPlayerConnected(int ID) {
|
||||||
auto MaybeClient = GetClient(Engine->Server(), ID);
|
auto Client = GetClient(Engine->Server(), ID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
return MaybeClient.value().lock()->IsConnected();
|
return Client->IsConnected();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LuaAPI::MP::IsPlayerGuest(int ID) {
|
bool LuaAPI::MP::IsPlayerGuest(int ID) {
|
||||||
auto MaybeClient = GetClient(Engine->Server(), ID);
|
auto Client = GetClient(Engine->Server(), ID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
return MaybeClient.value().lock()->IsGuest();
|
return Client->IsGuest();
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -528,9 +528,9 @@ sol::table TLuaEngine::StateThreadData::Lua_TriggerLocalEvent(const std::string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
sol::table TLuaEngine::StateThreadData::Lua_GetPlayerIdentifiers(int ID) {
|
sol::table TLuaEngine::StateThreadData::Lua_GetPlayerIdentifiers(int ID) {
|
||||||
auto MaybeClient = GetClient(mEngine->Server(), ID);
|
auto Client = GetClient(mEngine->Server(), ID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
auto IDs = MaybeClient.value().lock()->GetIdentifiers();
|
auto IDs = Client->GetIdentifiers();
|
||||||
if (IDs.empty()) {
|
if (IDs.empty()) {
|
||||||
return sol::lua_nil;
|
return sol::lua_nil;
|
||||||
}
|
}
|
||||||
@@ -591,18 +591,17 @@ sol::table TLuaEngine::StateThreadData::Lua_FS_ListDirectories(const std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string TLuaEngine::StateThreadData::Lua_GetPlayerName(int ID) {
|
std::string TLuaEngine::StateThreadData::Lua_GetPlayerName(int ID) {
|
||||||
auto MaybeClient = GetClient(mEngine->Server(), ID);
|
auto Client = GetClient(mEngine->Server(), ID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
return MaybeClient.value().lock()->GetName();
|
return Client->GetName();
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table TLuaEngine::StateThreadData::Lua_GetPlayerVehicles(int ID) {
|
sol::table TLuaEngine::StateThreadData::Lua_GetPlayerVehicles(int ID) {
|
||||||
auto MaybeClient = GetClient(mEngine->Server(), ID);
|
auto Client = GetClient(mEngine->Server(), ID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
auto Client = MaybeClient.value().lock();
|
|
||||||
TClient::TSetOfVehicleData VehicleData;
|
TClient::TSetOfVehicleData VehicleData;
|
||||||
{ // Vehicle Data Lock Scope
|
{ // Vehicle Data Lock Scope
|
||||||
auto LockedData = Client->GetAllCars();
|
auto LockedData = Client->GetAllCars();
|
||||||
@@ -623,9 +622,8 @@ sol::table TLuaEngine::StateThreadData::Lua_GetPlayerVehicles(int ID) {
|
|||||||
|
|
||||||
std::pair<sol::table, std::string> TLuaEngine::StateThreadData::Lua_GetPositionRaw(int PID, int VID) {
|
std::pair<sol::table, std::string> TLuaEngine::StateThreadData::Lua_GetPositionRaw(int PID, int VID) {
|
||||||
std::pair<sol::table, std::string> Result;
|
std::pair<sol::table, std::string> Result;
|
||||||
auto MaybeClient = GetClient(mEngine->Server(), PID);
|
auto Client = GetClient(mEngine->Server(), PID);
|
||||||
if (MaybeClient && !MaybeClient.value().expired()) {
|
if (Client) {
|
||||||
auto Client = MaybeClient.value().lock();
|
|
||||||
std::string VehiclePos = Client->GetCarPositionRaw(VID);
|
std::string VehiclePos = Client->GetCarPositionRaw(VID);
|
||||||
|
|
||||||
if (VehiclePos.empty()) {
|
if (VehiclePos.empty()) {
|
||||||
|
|||||||
@@ -97,22 +97,21 @@ void TNetwork::UDPServerMain() {
|
|||||||
// to represent packets. This would mean that player 0 would
|
// to represent packets. This would mean that player 0 would
|
||||||
// cause empty packets.
|
// cause empty packets.
|
||||||
uint8_t ID = uint8_t(Data.at(0)) - 1;
|
uint8_t ID = uint8_t(Data.at(0)) - 1;
|
||||||
auto MaybeClient = GetClient(mServer, ID);
|
auto Client = GetClient(mServer, ID);
|
||||||
if (MaybeClient) {
|
if (Client) {
|
||||||
try {
|
try {
|
||||||
auto Locked = MaybeClient.value().lock();
|
if (Client->IsConnected() && Client->GetUDPAddr() != client) {
|
||||||
if (Locked->IsConnected() && Locked->GetUDPAddr() != client) {
|
beammp_debugf("Client at {}:{} tried to send UDP for client {}", client.address().to_string(), client.port(), Client->GetID());
|
||||||
beammp_debugf("Client at {}:{} tried to send UDP for client {}", client.address().to_string(), client.port(), Locked->GetID());
|
|
||||||
++Application::InvalidUdpPackets;
|
++Application::InvalidUdpPackets;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
Locked->SetUDPAddr(client);
|
Client->SetUDPAddr(client);
|
||||||
Locked->SetIsConnected(true);
|
Client->SetIsConnected(true);
|
||||||
}
|
}
|
||||||
Locked->UdpReceived += Data.size();
|
Client->UdpReceived += Data.size();
|
||||||
++Locked->UdpPacketsReceived;
|
++Client->UdpPacketsReceived;
|
||||||
Data.erase(Data.begin() + 0, Data.begin() + 2);
|
Data.erase(Data.begin() + 0, Data.begin() + 2);
|
||||||
TServer::GlobalParser(Locked, std::move(Data), *this);
|
TServer::GlobalParser(Client, std::move(Data), *this);
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
++Application::InvalidUdpPackets;
|
++Application::InvalidUdpPackets;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user