mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-28 21:47:31 +00:00
Updated patch map to an array and added null safety checks for the conversion
This commit is contained in:
@@ -51,9 +51,11 @@ struct ClientComponents
|
|||||||
case Version::SoF:
|
case Version::SoF:
|
||||||
messageComponent = std::make_unique<Message::SoF>();
|
messageComponent = std::make_unique<Message::SoF>();
|
||||||
break;
|
break;
|
||||||
default:
|
case Version::Titanium:
|
||||||
messageComponent = std::make_unique<Message::Titanium>();
|
messageComponent = std::make_unique<Message::Titanium>();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,19 +63,22 @@ struct ClientComponents
|
|||||||
std::unique_ptr<Message::IMessage> messageComponent;
|
std::unique_ptr<Message::IMessage> messageComponent;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::unordered_map<Version, ClientComponents> s_patches = [] {
|
// this array must be in the same order as the Version enum because it converts Version to index directly
|
||||||
std::unordered_map<Version, ClientComponents> p;
|
static const std::array<ClientComponents, EQ::versions::ClientVersionCount> s_patches = {
|
||||||
p.emplace(Version::Titanium, Version::Titanium);
|
{
|
||||||
p.emplace(Version::SoF, Version::SoF);
|
ClientComponents(Version::Unknown), // empty
|
||||||
p.emplace(Version::SoD, Version::SoD);
|
ClientComponents(Version::Client62), // empty
|
||||||
p.emplace(Version::UF, Version::UF);
|
ClientComponents(Version::Titanium),
|
||||||
p.emplace(Version::RoF, Version::RoF);
|
ClientComponents(Version::SoF),
|
||||||
p.emplace(Version::RoF2, Version::RoF2);
|
ClientComponents(Version::SoD),
|
||||||
p.emplace(Version::TOB, Version::TOB);
|
ClientComponents(Version::UF),
|
||||||
return p;
|
ClientComponents(Version::RoF),
|
||||||
}();
|
ClientComponents(Version::RoF2),
|
||||||
|
ClientComponents(Version::TOB),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const std::unique_ptr<Message::IMessage>& GetMessageComponent(Version version)
|
const std::unique_ptr<Message::IMessage>& GetMessageComponent(Version version)
|
||||||
{
|
{
|
||||||
return s_patches.at(version).messageComponent;
|
return s_patches.at(static_cast<uint32_t>(version)).messageComponent;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
|
|
||||||
namespace Message { class IMessage; }
|
namespace Message { class IMessage; }
|
||||||
|
|
||||||
// store all static functions for the different patches here
|
// store all static functions for the different patches here, this can return nullptr for unsupported patches
|
||||||
const std::unique_ptr<Message::IMessage>& GetMessageComponent(EQ::versions::ClientVersion version);
|
const std::unique_ptr<Message::IMessage>& GetMessageComponent(EQ::versions::ClientVersion version);
|
||||||
|
|||||||
+10
-4
@@ -22,15 +22,17 @@ template <typename Fun, typename Obj, typename... Args>
|
|||||||
requires std::is_member_function_pointer_v<Fun>
|
requires std::is_member_function_pointer_v<Fun>
|
||||||
static void QueuePacket(Client* c, Fun fun, Obj* obj, Args&&... args)
|
static void QueuePacket(Client* c, Fun fun, Obj* obj, Args&&... args)
|
||||||
{
|
{
|
||||||
|
if (obj != nullptr) {
|
||||||
std::unique_ptr<EQApplicationPacket> app = std::invoke(fun, obj, std::forward<Args>(args)...);
|
std::unique_ptr<EQApplicationPacket> app = std::invoke(fun, obj, std::forward<Args>(args)...);
|
||||||
if (app)
|
if (app)
|
||||||
c->QueuePacket(app.get());
|
c->QueuePacket(app.get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// packet generator queue functions
|
// packet generator queue functions
|
||||||
static auto QueueClients(Mob* sender, bool ignore_sender = false, bool ackreq = true)
|
static auto QueueClients(Mob* sender, bool ignore_sender = false, bool ackreq = true)
|
||||||
{
|
{
|
||||||
return [=]<typename Fun, typename Obj, typename... Args>(Fun fun, ComponentGetter<Obj> component, Args&&... args)
|
return [=]<typename Fun, typename Obj, typename... Args>(Fun fun, const ComponentGetter<Obj>& component, Args&&... args)
|
||||||
requires std::is_member_function_pointer_v<Fun>
|
requires std::is_member_function_pointer_v<Fun>
|
||||||
{
|
{
|
||||||
std::vector<std::pair<EQ::versions::ClientVersion, std::unique_ptr<EQApplicationPacket>>> build_packets;
|
std::vector<std::pair<EQ::versions::ClientVersion, std::unique_ptr<EQApplicationPacket>>> build_packets;
|
||||||
@@ -44,8 +46,9 @@ static auto QueueClients(Mob* sender, bool ignore_sender = false, bool ackreq =
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (packet_it == build_packets.end())
|
if (packet_it == build_packets.end())
|
||||||
|
if (Obj* comp = component(ent); comp != nullptr)
|
||||||
packet_it = build_packets.emplace(build_packets.end(), ent->ClientVersion(),
|
packet_it = build_packets.emplace(build_packets.end(), ent->ClientVersion(),
|
||||||
std::invoke(fun, component(ent), std::forward<Args>(args)...));
|
std::invoke(fun, comp, std::forward<Args>(args)...));
|
||||||
|
|
||||||
if (packet_it->second != nullptr)
|
if (packet_it->second != nullptr)
|
||||||
ent->QueuePacket(packet_it->second.get(), ackreq, Client::CLIENT_CONNECTED);
|
ent->QueuePacket(packet_it->second.get(), ackreq, Client::CLIENT_CONNECTED);
|
||||||
@@ -61,7 +64,7 @@ static auto QueueCloseClients(
|
|||||||
{
|
{
|
||||||
if (distance <= 0) distance = static_cast<float>(zone->GetClientUpdateRange());
|
if (distance <= 0) distance = static_cast<float>(zone->GetClientUpdateRange());
|
||||||
|
|
||||||
return [=]<typename Fun, typename Obj, typename... Args>(Fun fun, ComponentGetter<Obj> component, Args&&... args)
|
return [=]<typename Fun, typename Obj, typename... Args>(Fun fun, const ComponentGetter<Obj>& component, Args&&... args)
|
||||||
requires std::is_member_function_pointer_v<Fun>
|
requires std::is_member_function_pointer_v<Fun>
|
||||||
{
|
{
|
||||||
if (sender == nullptr) {
|
if (sender == nullptr) {
|
||||||
@@ -85,8 +88,9 @@ static auto QueueCloseClients(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (packet_it == build_packets.end())
|
if (packet_it == build_packets.end())
|
||||||
|
if (auto comp = component(client); comp != nullptr)
|
||||||
packet_it = build_packets.emplace(build_packets.end(), client->ClientVersion(),
|
packet_it = build_packets.emplace(build_packets.end(), client->ClientVersion(),
|
||||||
std::invoke(fun, component(client), std::forward<Args>(args)...));
|
std::invoke(fun, comp, std::forward<Args>(args)...));
|
||||||
|
|
||||||
if (packet_it->second != nullptr)
|
if (packet_it->second != nullptr)
|
||||||
client->QueuePacket(packet_it->second.get(), is_ack_required, Client::CLIENT_CONNECTED);
|
client->QueuePacket(packet_it->second.get(), is_ack_required, Client::CLIENT_CONNECTED);
|
||||||
@@ -101,6 +105,8 @@ static auto QueueCloseClients(
|
|||||||
|
|
||||||
// Helpers for the Message interface to send message packets
|
// Helpers for the Message interface to send message packets
|
||||||
namespace Message {
|
namespace Message {
|
||||||
|
|
||||||
|
// this can return nullptr when the component doesn't exist for the version
|
||||||
static std::function GetComponent = [](const Client* c) -> IMessage* {
|
static std::function GetComponent = [](const Client* c) -> IMessage* {
|
||||||
return GetMessageComponent(c->GetClientVersion()).get();
|
return GetMessageComponent(c->GetClientVersion()).get();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user