mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-02-16 02:30:54 +00:00
Bump version v3.9.0
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|
||||||
|
|||||||
@@ -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()));
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user