Bump version v3.9.0

This commit is contained in:
Tixx
2025-10-20 22:41:29 +02:00
parent 039a44bba5
commit c4c894c1f7
5 changed files with 66 additions and 16 deletions

View File

@@ -24,6 +24,7 @@
#include <queue> #include <queue>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
#include <utility>
#include "BoostAliases.h" #include "BoostAliases.h"
#include "Common.h" #include "Common.h"
@@ -101,6 +102,8 @@ public:
[[nodiscard]] TServer& Server() const; [[nodiscard]] TServer& Server() const;
void UpdatePingTime(); void UpdatePingTime();
int SecondsSinceLastPing(); int SecondsSinceLastPing();
void SetMagic(std::vector<uint8_t> magic) { mMagic = std::move(magic); }
[[nodiscard]] const std::vector<uint8_t>& GetMagic() const { return mMagic; }
private: private:
void InsertVehicle(int ID, const std::string& Data); void InsertVehicle(int ID, const std::string& Data);
@@ -125,6 +128,7 @@ private:
std::string mDID; std::string mDID;
int mID = -1; int mID = -1;
std::chrono::time_point<std::chrono::high_resolution_clock> mLastPingTime = std::chrono::high_resolution_clock::now(); std::chrono::time_point<std::chrono::high_resolution_clock> mLastPingTime = std::chrono::high_resolution_clock::now();
std::vector<uint8_t> mMagic;
}; };
std::optional<std::weak_ptr<TClient>> GetClient(class TServer& Server, int ID); std::optional<std::weak_ptr<TClient>> GetClient(class TServer& Server, int ID);

View File

@@ -74,7 +74,7 @@ public:
static TConsole& Console() { return mConsole; } static TConsole& Console() { return mConsole; }
static std::string ServerVersionString(); static std::string ServerVersionString();
static const Version& ServerVersion() { return mVersion; } static const Version& ServerVersion() { return mVersion; }
static Version ClientMinimumVersion() { return Version { 2, 2, 0 }; } static Version ClientMinimumVersion() { return Version { 2, 7, 0 }; }
static std::string PPS() { return mPPS; } static std::string PPS() { return mPPS; }
static void SetPPS(const std::string& NewPPS) { mPPS = NewPPS; } static void SetPPS(const std::string& NewPPS) { mPPS = NewPPS; }
@@ -129,7 +129,7 @@ private:
static inline std::mutex mShutdownHandlersMutex {}; static inline std::mutex mShutdownHandlersMutex {};
static inline std::deque<TShutdownHandler> mShutdownHandlers {}; static inline std::deque<TShutdownHandler> mShutdownHandlers {};
static inline Version mVersion { 3, 8, 5 }; static inline Version mVersion { 3, 9, 0 };
}; };
void SplitString(std::string const& str, const char delim, std::vector<std::string>& out); void SplitString(std::string const& str, const char delim, std::vector<std::string>& out);

View File

@@ -44,7 +44,7 @@ public:
void ForEachClient(const std::function<bool(std::weak_ptr<TClient>)>& Fn); void ForEachClient(const std::function<bool(std::weak_ptr<TClient>)>& Fn);
size_t ClientCount() const; size_t ClientCount() const;
void GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uint8_t>&& Packet, TPPSMonitor& PPSMonitor, TNetwork& Network); void GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uint8_t>&& Packet, TPPSMonitor& PPSMonitor, TNetwork& Network, bool udp);
static void HandleEvent(TClient& c, const std::string& Data); static void HandleEvent(TClient& c, const std::string& Data);
RWMutex& GetClientMutex() const { return mClientsMutex; } RWMutex& GetClientMutex() const { return mClientsMutex; }

View File

@@ -32,6 +32,8 @@
#include <boost/asio/ip/address_v6.hpp> #include <boost/asio/ip/address_v6.hpp>
#include <boost/asio/ip/v6_only.hpp> #include <boost/asio/ip/v6_only.hpp>
#include <cstring> #include <cstring>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <zlib.h> #include <zlib.h>
typedef boost::asio::detail::socket_option::integer<SOL_SOCKET, SO_RCVTIMEO> rcv_timeout_option; typedef boost::asio::detail::socket_option::integer<SOL_SOCKET, SO_RCVTIMEO> rcv_timeout_option;
@@ -146,23 +148,30 @@ void TNetwork::UDPServerMain() {
} }
if (Client->GetID() == ID) { if (Client->GetID() == ID) {
// not initialized yet if (Client->GetUDPAddr() == ip::udp::endpoint {} && !Client->IsUDPConnected() && !Client->GetMagic().empty()) {
if (Client->GetUDPAddr() == ip::udp::endpoint {} || !Client->IsUDPConnected()) { if (Data.size() != 66) {
// same IP (just a sanity check) beammp_debugf("Invalid size for UDP value. IP: {} ID: {}", remote_client_ep.address().to_string(), ID);
if (remote_client_ep.address() == Client->GetTCPSock().remote_endpoint().address()) {
Client->SetUDPAddr(remote_client_ep);
Client->SetIsUDPConnected(true);
beammp_debugf("UDP connected for client {}", ID);
} else {
beammp_debugf("Denied initial UDP packet due to IP mismatch");
return false; return false;
} }
const std::vector Magic(Data.begin() + 2, Data.end());
if (Magic != Client->GetMagic()) {
beammp_debugf("Invalid value for UDP IP: {} ID: {}", remote_client_ep.address().to_string(), ID);
return false;
}
Client->SetMagic({});
Client->SetUDPAddr(remote_client_ep);
Client->SetIsUDPConnected(true);
return false;
} }
if (Client->GetUDPAddr() == remote_client_ep) { if (Client->GetUDPAddr() == remote_client_ep) {
Data.erase(Data.begin(), Data.begin() + 2); Data.erase(Data.begin(), Data.begin() + 2);
mServer.GlobalParser(ClientPtr, std::move(Data), mPPSMonitor, *this); mServer.GlobalParser(ClientPtr, std::move(Data), mPPSMonitor, *this, true);
} else { } else {
beammp_debugf("Ignored UDP packet due to remote address mismatch"); beammp_debugf("Ignored UDP packet for Client {} due to remote address mismatch. Source: {}, Client: {}", ID, remote_client_ep.address().to_string(), Client->GetUDPAddr().address().to_string());
return false; return false;
} }
} }
@@ -660,7 +669,7 @@ void TNetwork::TCPClient(const std::weak_ptr<TClient>& c) {
Client->Disconnect("TCPRcv failed"); Client->Disconnect("TCPRcv failed");
break; break;
} }
mServer.GlobalParser(c, std::move(res), mPPSMonitor, *this); mServer.GlobalParser(c, std::move(res), mPPSMonitor, *this, false);
} }
if (QueueSync.joinable()) if (QueueSync.joinable())
@@ -751,6 +760,18 @@ void TNetwork::OnConnect(const std::weak_ptr<TClient>& c) {
SyncResources(*LockedClient); SyncResources(*LockedClient);
if (LockedClient->IsDisconnected()) if (LockedClient->IsDisconnected())
return; return;
std::vector<unsigned char> buf(64);
int ret = RAND_bytes(buf.data(), buf.size());
if (ret != 1) {
unsigned long error = ERR_get_error();
beammp_errorf("RAND_bytes failed with error code {}", error);
beammp_assert(ret != 1);
return;
}
LockedClient->SetMagic(buf);
buf.insert(buf.begin(), 'U');
(void)Respond(*LockedClient, buf, true);
(void)Respond(*LockedClient, StringToVector("M" + Application::Settings.getAsString(Settings::Key::General_Map)), true); // Send the Map on connect (void)Respond(*LockedClient, StringToVector("M" + Application::Settings.getAsString(Settings::Key::General_Map)), true); // Send the Map on connect
beammp_info(LockedClient->GetName() + " : Connected"); beammp_info(LockedClient->GetName() + " : Connected");
LuaAPI::MP::Engine->ReportErrors(LuaAPI::MP::Engine->TriggerEvent("onPlayerJoining", "", LockedClient->GetID())); LuaAPI::MP::Engine->ReportErrors(LuaAPI::MP::Engine->TriggerEvent("onPlayerJoining", "", LockedClient->GetID()));

View File

@@ -161,7 +161,7 @@ size_t TServer::ClientCount() const {
return mClients.size(); return mClients.size();
} }
void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uint8_t>&& Packet, TPPSMonitor& PPSMonitor, TNetwork& Network) { void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uint8_t>&& Packet, TPPSMonitor& PPSMonitor, TNetwork& Network, bool udp) {
constexpr std::string_view ABG = "ABG:"; constexpr std::string_view ABG = "ABG:";
if (Packet.size() >= ABG.size() && std::equal(Packet.begin(), Packet.begin() + ABG.size(), ABG.begin(), ABG.end())) { if (Packet.size() >= ABG.size() && std::equal(Packet.begin(), Packet.begin() + ABG.size(), ABG.begin(), ABG.end())) {
Packet.erase(Packet.begin(), Packet.begin() + ABG.size()); Packet.erase(Packet.begin(), Packet.begin() + ABG.size());
@@ -213,6 +213,10 @@ void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uin
} }
switch (Code) { switch (Code) {
case 'H': // initial connection case 'H': // initial connection
if (udp) {
beammp_debugf("Received 'H' packet over UDP from client '{}' ({}), ignoring it", LockedClient->GetName(), LockedClient->GetID());
return;
}
if (!Network.SyncClient(Client)) { if (!Network.SyncClient(Client)) {
// TODO handle // TODO handle
} }
@@ -226,12 +230,20 @@ void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uin
} }
return; return;
case 'O': case 'O':
if (udp) {
beammp_debugf("Received 'O' packet over UDP from client '{}' ({}), ignoring it", LockedClient->GetName(), LockedClient->GetID());
return;
}
if (Packet.size() > 1000) { if (Packet.size() > 1000) {
beammp_debug(("Received data from: ") + LockedClient->GetName() + (" Size: ") + std::to_string(Packet.size())); beammp_debug(("Received data from: ") + LockedClient->GetName() + (" Size: ") + std::to_string(Packet.size()));
} }
ParseVehicle(*LockedClient, StringPacket, Network); ParseVehicle(*LockedClient, StringPacket, Network);
return; return;
case 'C': { case 'C': {
if (udp) {
beammp_debugf("Received 'C' packet over UDP from client '{}' ({}), ignoring it", LockedClient->GetName(), LockedClient->GetID());
return;
}
if (Packet.size() < 4 || std::find(Packet.begin() + 3, Packet.end(), ':') == Packet.end()) if (Packet.size() < 4 || std::find(Packet.begin() + 3, Packet.end(), ':') == Packet.end())
break; break;
const auto PacketAsString = std::string(reinterpret_cast<const char*>(Packet.data()), Packet.size()); const auto PacketAsString = std::string(reinterpret_cast<const char*>(Packet.data()), Packet.size());
@@ -262,6 +274,10 @@ void TServer::GlobalParser(const std::weak_ptr<TClient>& Client, std::vector<uin
return; return;
} }
case 'E': case 'E':
if (udp) {
beammp_debugf("Received 'E' packet over UDP from client '{}' ({}), ignoring it", LockedClient->GetName(), LockedClient->GetID());
return;
}
HandleEvent(*LockedClient, StringPacket); HandleEvent(*LockedClient, StringPacket);
return; return;
case 'N': case 'N':
@@ -304,6 +320,15 @@ void TServer::HandleEvent(TClient& c, const std::string& RawData) {
} }
std::string Name = RawData.substr(2, NameDataSep - 2); std::string Name = RawData.substr(2, NameDataSep - 2);
std::string Data = RawData.substr(NameDataSep + 1); std::string Data = RawData.substr(NameDataSep + 1);
std::vector<std::string> exclude = {"onInit", "onFileChanged","onVehicleDeleted","onConsoleInput","onPlayerAuth","postPlayerAuth", "onPlayerDisconnect",
"onPlayerConnecting","onPlayerJoining","onPlayerJoin","onChatMessage","postChatMessage","onVehicleSpawn","postVehicleSpawn","onVehicleEdited", "postVehicleEdited",
"onVehicleReset","onVehiclePaintChanged","onShutdown"};
if (std::ranges::find(exclude, Name) != exclude.end()) {
beammp_debugf("Excluded event triggered by client '{}' ({}): '{}', ignoring.", c.GetName(), c.GetID(), Name);
return;
}
LuaAPI::MP::Engine->ReportErrors(LuaAPI::MP::Engine->TriggerEvent(Name, "", c.GetID(), Data)); LuaAPI::MP::Engine->ReportErrors(LuaAPI::MP::Engine->TriggerEvent(Name, "", c.GetID(), Data));
} }