mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-14 07:47:13 +00:00
fix(entity): message handlers run in the order they registered, as the client
Handlers sat in an unordered_multimap, whose order for one message is up to the standard library: GCC ran them newest first, so the components loaded last answered a RequestUse first, and Windows builds could differ. They are now kept per message in registration order: the object's own handlers, then its components' in load order (LWOGameObject::PassMessageToComponents). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1731,18 +1731,23 @@ int32_t Entity::GetCollisionGroup() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// LWOGameObject::PassMessageToComponents (0x00f62500): every handler registered for the message, in registration
|
||||
// order; only the ones there when the call starts (the client copies the list first; GetPosition is too hot for a copy)
|
||||
bool Entity::HandleMsg(GameMessages::GameMsg& msg) const {
|
||||
const auto it = m_MsgHandlers.find(msg.msgId);
|
||||
if (it == m_MsgHandlers.end()) return false;
|
||||
|
||||
bool handled = false;
|
||||
auto [beg, end] = m_MsgHandlers.equal_range(msg.msgId);
|
||||
for (auto& it = beg; it != end; ++it) {
|
||||
if (it->second) handled |= it->second(msg);
|
||||
const auto& handlers = it->second;
|
||||
for (size_t i = 0, count = handlers.size(); i < count; i++) {
|
||||
if (handlers[i]) handled |= handlers[i](msg);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void Entity::RegisterMsg(const MessageType::Game msgId, std::function<bool(GameMessages::GameMsg&)> handler) {
|
||||
m_MsgHandlers.emplace(msgId, handler);
|
||||
m_MsgHandlers[msgId].push_back(std::move(handler));
|
||||
}
|
||||
|
||||
bool Entity::MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfoEvent& event) {
|
||||
|
||||
@@ -480,7 +480,9 @@ private:
|
||||
// objectID of receiver and map of notification name to script
|
||||
std::map<LWOOBJID, std::map<std::string, CppScripts::Script*>> m_Subscriptions;
|
||||
|
||||
std::unordered_multimap<MessageType::Game, std::function<bool(GameMessages::GameMsg&)>> m_MsgHandlers;
|
||||
// Each message's handlers in the order they registered: the object's own, then its components' in load order
|
||||
// (LWOGameObject::registeredGameMessages)
|
||||
std::unordered_map<MessageType::Game, std::vector<std::function<bool(GameMessages::GameMsg&)>>> m_MsgHandlers;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user