diff --git a/common/message.proto b/common/message.proto index 66a793fb8..6b904ad18 100644 --- a/common/message.proto +++ b/common/message.proto @@ -1,6 +1,9 @@ syntax = "proto3"; package eqproto; +option cc_enable_arenas = true; +option optimize_for = SPEED; + message ChannelMessage { int32 chan_num = 1; int32 language = 2; @@ -16,8 +19,7 @@ message ChannelMessage { bool is_emote = 12; //0 not queued, 1 queued, 2 queue full, 3 offline int32 queued = 13; - //You can specify a zone id if you want a message exclusively to one zone - int32 zone_id = 14; + string result = 15; } message CommandMessage { diff --git a/utils/nats/helloworld/helloworld.go b/utils/nats/helloworld/helloworld.go index 984f1dfba..977f330b2 100644 --- a/utils/nats/helloworld/helloworld.go +++ b/utils/nats/helloworld/helloworld.go @@ -47,7 +47,7 @@ func asyncChannelMessageSubscriber(nc *nats.Conn) { // and poll for messages syncronously func syncChannelMessageSubscriber(nc *nats.Conn) { - sub, err := nc.SubscribeSync("world.channel_message") + sub, err := nc.SubscribeSync("world.channel_message.out") if err != nil { log.Fatal(err) } @@ -72,7 +72,7 @@ func testBroadcastMessage(nc *nats.Conn, msg string) { if err != nil { log.Fatal(err) } - if err = nc.Publish("world.channel_message", d); err != nil { + if err = nc.Publish("world.channel_message.in", d); err != nil { log.Println("Failed to publish:", err.Error()) return } diff --git a/world/nats_manager.cpp b/world/nats_manager.cpp index 68b5d906a..27e1706cc 100644 --- a/world/nats_manager.cpp +++ b/world/nats_manager.cpp @@ -5,11 +5,12 @@ #include "clientlist.h" #include "worlddb.h" +#include #include "../common/seperator.h" #include "../common/eqemu_logsys.h" #ifndef PROTO_H #define PROTO_H -#include "../common/proto/message.pb.h" +#include "../common/message->pb.h" #endif #include "../common/servertalk.h" #include "../common/string_util.h" @@ -19,6 +20,8 @@ extern LoginServerList loginserverlist; extern ClientList client_list; const WorldConfig *worldConfig; +google::protobuf::Arena the_arena; + NatsManager::NatsManager() { //new timers, object initialization @@ -69,6 +72,15 @@ bool NatsManager::connect() { Log(Logs::General, Logs::NATS, "connected to %s", connection.c_str()); nats_timer.Disable(); + + s = natsConnection_SubscribeSync(&channelMessageSub, conn, "world.channel_message->in"); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "world.channel_message->in: failed to subscribe: %s", nats_GetLastError(&s)); + + s = natsConnection_SubscribeSync(&commandMessageSub, conn, "world.command_message->in"); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "world.command_message->in: failed to subscribe: %s", nats_GetLastError(&s)); + return true; } @@ -79,174 +91,229 @@ void NatsManager::Process() if (!connect()) return; s = NATS_OK; - for (int count = 0; (s == NATS_OK) && count < 5; count++) + for (int count = 0; (s == NATS_OK) && count < 5; count++) { s = natsSubscription_NextMsg(&msg, channelMessageSub, 1); - if (s != NATS_OK) break; - Log(Logs::General, Logs::NATS, "Got Broadcast Message '%s'", natsMsg_GetData(msg)); - eqproto::ChannelMessage message; - if (!message.ParseFromString(natsMsg_GetData(msg))) { - Log(Logs::General, Logs::NATS, "Failed to marshal"); + if (s != NATS_OK) + break; + + eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); + if (!message->ParseFromString(natsMsg_GetData(msg))) { + Log(Logs::General, Logs::NATS, "world.channel_message->in: failed to parse"); natsMsg_Destroy(msg); continue; } - ChannelMessageEvent(&message); + + GetChannelMessage(message, natsMsg_GetReply(msg)); } s = NATS_OK; for (int count = 0; (s == NATS_OK) && count < 5; count++) { s = natsSubscription_NextMsg(&msg, commandMessageSub, 1); - if (s != NATS_OK) break; - Log(Logs::General, Logs::NATS, "Got Command Message '%s'", natsMsg_GetData(msg)); - eqproto::CommandMessage message; - - - if (!message.ParseFromString(natsMsg_GetData(msg))) { - Log(Logs::General, Logs::NATS, "Failed to marshal"); + if (s != NATS_OK) + break; + + eqproto::CommandMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); + if (!message->ParseFromString(natsMsg_GetData(msg))) { + Log(Logs::General, Logs::NATS, "world.command_message->in: failed to parse"); natsMsg_Destroy(msg); continue; } - CommandMessageEvent(&message, natsMsg_GetReply(msg)); + GetCommandMessage(message, natsMsg_GetReply(msg)); } } void NatsManager::OnChannelMessage(ServerChannelMessage_Struct* msg) { - if (!connect()) return; + if (!connect()) + return; - eqproto::ChannelMessage message; + eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); - message.set_fromadmin(msg->fromadmin); - message.set_deliverto(msg->deliverto); - message.set_guilddbid(msg->guilddbid); - message.set_noreply(msg->noreply); - message.set_queued(msg->queued); - message.set_chan_num(msg->chan_num); - message.set_message(msg->message); - message.set_to(msg->to); - message.set_language(msg->language); - message.set_from(msg->from); - SendChannelMessage(&message); + message->set_fromadmin(msg->fromadmin); + message->set_deliverto(msg->deliverto); + message->set_guilddbid(msg->guilddbid); + message->set_noreply(msg->noreply); + message->set_queued(msg->queued); + message->set_chan_num(msg->chan_num); + message->set_message(msg->message); + message->set_to(msg->to); + message->set_language(msg->language); + message->set_from(msg->from); + SendChannelMessage(message); return; } void NatsManager::OnEmoteMessage(ServerEmoteMessage_Struct* msg) { - if (!connect()) return; - - eqproto::ChannelMessage message; - message.set_guilddbid(msg->guilddbid); - message.set_minstatus(msg->minstatus); - message.set_type(msg->type); - message.set_message(msg->message); - message.set_to(msg->to); - message.set_is_emote(true); - SendChannelMessage(&message); + if (!connect()) + return; + eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); + message->set_guilddbid(msg->guilddbid); + message->set_minstatus(msg->minstatus); + message->set_type(msg->type); + message->set_message(msg->message); + message->set_to(msg->to); + message->set_is_emote(true); + SendChannelMessage(message); return; } -void NatsManager::SendAdminMessage(std::string adminMessage) { - if (!connect()) return; +// SendAdminMessage will send an admin message to NATS +void NatsManager::SendAdminMessage(std::string adminMessage, const char* reply) { + if (!connect()) + return; + eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); - eqproto::ChannelMessage message; - message.set_message(adminMessage.c_str()); + message->set_message(adminMessage.c_str()); std::string pubMessage; - if (!message.SerializeToString(&pubMessage)) { - Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + if (!message->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "global.admin_message->out: failed to serialize message to string"); return; } - s = natsConnection_PublishString(conn, "world.admin_message", pubMessage.c_str()); + + if (reply && strlen(reply) > 0) + s = natsConnection_Publish(conn, reply, (const void*)pubMessage.c_str(), pubMessage.length()); + else + s = natsConnection_Publish(conn, "global.admin_message->out", (const void*)pubMessage.c_str(), pubMessage.length()); + if (s != NATS_OK) { - Log(Logs::General, Logs::NATS, "Failed to publish to world.admin_message"); + Log(Logs::General, Logs::NATS, "global.admin_message->out failed: %s", nats_GetLastError(&s)); + return; } - Log(Logs::General, Logs::NATS, "world.admin_message: %s", adminMessage.c_str()); + Log(Logs::General, Logs::NATS, "global.admin_message->out: %s", adminMessage.c_str()); } -//Send (publish) message to NATS -void NatsManager::SendChannelMessage(eqproto::ChannelMessage* message) { - if (!connect()) return; +// SendChannelMessage will send a channel message to NATS +void NatsManager::SendChannelMessage(eqproto::ChannelMessage* message, const char* reply) { + if (!connect()) + return; std::string pubMessage; if (!message->SerializeToString(&pubMessage)) { - Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + Log(Logs::General, Logs::NATS, "world.channel_message->out: failed to serialize message to string"); return; } - s = natsConnection_PublishString(conn, "world.channel_message", pubMessage.c_str()); + + if (reply && strlen(reply) > 0) + s = natsConnection_Publish(conn, reply, (const void*)pubMessage.c_str(), pubMessage.length()); + else + s = natsConnection_Publish(conn, "world.channel_message->out", (const void*)pubMessage.c_str(), pubMessage.length()); + if (s != NATS_OK) { - Log(Logs::General, Logs::NATS, "Failed to send world.command_message"); + Log(Logs::General, Logs::NATS, "world.channel_message->out failed: %s"); + return; } + Log(Logs::General, Logs::NATS, "world.channel_message->out: %s", message->message().c_str()); } -void NatsManager::CommandMessageEvent(eqproto::CommandMessage* message, const char* reply) { - if (!connect()) return; +// SendCommandMessage will send a channel message to NATS +void NatsManager::SendCommandMessage(eqproto::CommandMessage* message, const char* reply) { + if (!connect()) + return; + + if (message->result().length() <= 1) + message->set_result("Failed to parse command."); + + std::string pubMessage; - //Log(Logs::General, Logs::NATS, "Command: %s", message->command().c_str()); - // message->params() - - - if (message->command().compare("who") == 0) { + if (!message->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "world.command_message->out: failed to serialize message to string"); + return; + } + + if (reply && strlen(reply) > 0) + s = natsConnection_Publish(conn, reply, (const void*)pubMessage.c_str(), pubMessage.length()); + else + s = natsConnection_Publish(conn, "world.command_message->out", (const void*)pubMessage.c_str(), pubMessage.length()); + + if (s != NATS_OK) { + Log(Logs::General, Logs::NATS, "world.command_message->out failed: %s"); + return; + } + Log(Logs::General, Logs::NATS, "world.command_message->out: %s", message->command().c_str()); +} + +// GetCommandMessage is used to process a command message +void NatsManager::GetCommandMessage(eqproto::CommandMessage* message, const char* reply) { + if (!connect()) + return; + + std::string pubMessage; + + Log(Logs::General, Logs::NATS, "world.command_message->in: %s", message->command().c_str()); + + if (message->command().compare("who") == 0) { message->set_result(client_list.GetWhoAll()); + SendCommandMessage(message, reply); + return; } if (message->command().compare("unlock") == 0) { WorldConfig::UnlockWorld(); - if (loginserverlist.Connected()) loginserverlist.SendStatus(); + if (loginserverlist.Connected()) + loginserverlist.SendStatus(); message->set_result("Server is now unlocked."); + SendCommandMessage(message, reply); + return; } if (message->command().compare("lock") == 0) { WorldConfig::LockWorld(); - if (loginserverlist.Connected()) loginserverlist.SendStatus(); + if (loginserverlist.Connected()) + loginserverlist.SendStatus(); message->set_result("Server is now locked."); + SendCommandMessage(message, reply); + return; } if(message->command().compare("worldshutdown") == 0) { uint32 time=0; uint32 interval=0; - if(message->params_size() < 1) { - message->set_result("worldshutdown - Shuts down the server and all zones.\n \ - Usage: worldshutdown now - Shuts down the server and all zones immediately.\n \ - Usage: worldshutdown disable - Stops the server from a previously scheduled shut down.\n \ - Usage: worldshutdown [timer] [interval] - Shuts down the server and all zones after [timer] seconds and sends warning every [interval] seconds\n"); - } else if(message->params_size() == 2 && ((time=atoi(message->params(0).c_str()))>0) && ((interval=atoi(message->params(1).c_str()))>0)) { + if(message->params_size() == 2 && ((time=atoi(message->params(0).c_str()))>0) && ((interval=atoi(message->params(1).c_str()))>0)) { message->set_result(StringFormat("Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval)); zoneserver_list.WorldShutDown(time, interval); + SendCommandMessage(message, reply); + return; } else if(strcasecmp(message->params(0).c_str(), "now") == 0){ message->set_result("Sending shutdown packet now"); zoneserver_list.WorldShutDown(0, 0); + SendCommandMessage(message, reply); + return; } else if(strcasecmp(message->params(0).c_str(), "disable") == 0){ message->set_result("Shutdown prevented, next time I may not be so forgiving..."); zoneserver_list.SendEmoteMessage(0, 0, 0, 15, ":SYSTEM MSG:World shutdown aborted."); zoneserver_list.shutdowntimer->Disable(); zoneserver_list.reminder->Disable(); + SendCommandMessage(message, reply); + return; } - } - - if (message->result().length() <= 1) { - message->set_result("Failed to parse command."); - } - - if (!message->SerializeToString(&pubMessage)) { - Log(Logs::General, Logs::NATS, "Failed to serialize command message to string"); + message->set_result("worldshutdown - Shuts down the server and all zones.\n \ + Usage: worldshutdown now - Shuts down the server and all zones immediately.\n \ + Usage: worldshutdown disable - Stops the server from a previously scheduled shut down.\n \ + Usage: worldshutdown [timer] [interval] - Shuts down the server and all zones after [timer] seconds and sends warning every [interval] seconds\n"); + SendCommandMessage(message, reply); return; } - s = natsConnection_PublishString(conn, reply, pubMessage.c_str()); - if (s != NATS_OK) { - Log(Logs::General, Logs::NATS, "Failed to send CommandMessageEvent"); - return; - } + message->set_result("unknown command sent"); + SendCommandMessage(message, reply); + return; } -//Send a message to all zone servers. -void NatsManager::ChannelMessageEvent(eqproto::ChannelMessage* message) { - if (!connect()) return; - if (message->zone_id() > 0) return; //do'nt process non-zero messages - Log(Logs::General, Logs::NATS, "Broadcasting Message"); +// GetChannelMessage is when a 3rd party app sends a channel message via NATS. +void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char* reply) { + if (!connect()) + return; + + + Log(Logs::General, Logs::NATS, "world.channel_message->in: %s", message->message().c_str()); if (message->is_emote()) { //emote message zoneserver_list.SendEmoteMessage(message->to().c_str(), message->guilddbid(), message->minstatus(), message->type(), message->message().c_str()); + message->set_result("Sent message"); + SendChannelMessage(message, reply); return; } @@ -256,20 +323,18 @@ void NatsManager::ChannelMessageEvent(eqproto::ChannelMessage* message) { strcpy(&tmpname[1], message->from().c_str()); //TODO: add To support on tells int channel = message->chan_num(); - if (channel < 1) channel = 5; //default to ooc + if (channel < 1) + channel = 5; //default to ooc zoneserver_list.SendChannelMessage(tmpname, 0, channel, message->language(), message->message().c_str()); -} - -void NatsManager::Save() -{ + message->set_result("Sent message"); + SendChannelMessage(message, reply); return; } void NatsManager::Load() { - if (!connect()) return; + if (!connect()) + return; - s = natsConnection_SubscribeSync(&channelMessageSub, conn, "world.channel_message"); - s = natsConnection_SubscribeSync(&commandMessageSub, conn, "world.command_message"); return; } \ No newline at end of file diff --git a/world/nats_manager.h b/world/nats_manager.h index 867177c36..2c920fb1c 100644 --- a/world/nats_manager.h +++ b/world/nats_manager.h @@ -22,10 +22,11 @@ public: void Process(); void OnChannelMessage(ServerChannelMessage_Struct * msg); void OnEmoteMessage(ServerEmoteMessage_Struct * msg); - void SendAdminMessage(std::string adminMessage); - void ChannelMessageEvent(eqproto::ChannelMessage* message); - void CommandMessageEvent(eqproto::CommandMessage* message, const char* reply); - void SendChannelMessage(eqproto::ChannelMessage* message); + void SendAdminMessage(std::string adminMessage, const char* reply = nullptr); + void GetChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr); + void SendChannelMessage(eqproto::ChannelMessage* message, const char* reply = nullptr); + void GetCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr); + void SendCommandMessage(eqproto::CommandMessage* message, const char* reply = nullptr); void Save(); void Load(); protected: diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 1d4dc8cbe..7cd7c3777 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -411,12 +411,13 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { if (pack->size < sizeof(ServerChannelMessage_Struct)) break; ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*)pack->pBuffer; + + nats.OnChannelMessage(scm); if (scm->chan_num == 20) { UCSLink.SendMessage(scm->from, scm->message); break; } - nats.OnChannelMessage(scm); if (scm->chan_num == 7 || scm->chan_num == 14) { if (scm->deliverto[0] == '*') { diff --git a/zone/nats_manager.cpp b/zone/nats_manager.cpp index b3fb510cc..0dcbaf7be 100644 --- a/zone/nats_manager.cpp +++ b/zone/nats_manager.cpp @@ -15,6 +15,9 @@ #define PROTO_H #include "../common/message.pb.h" #endif +#include + +google::protobuf::Arena the_arena; const ZoneConfig *zoneConfig; @@ -38,7 +41,9 @@ NatsManager::~NatsManager() void NatsManager::Process() { - if (!connect()) return; + if (!connect()) + return; + natsMsg *msg = NULL; std::string pubMessage; @@ -46,31 +51,35 @@ void NatsManager::Process() for (int count = 0; (s == NATS_OK) && count < 5; count++) { s = natsSubscription_NextMsg(&msg, zoneCommandMessageSub, 1); - if (s != NATS_OK) break; - Log(Logs::General, Logs::World_Server, "NATS Got Command Message '%s'", natsMsg_GetData(msg)); - eqproto::CommandMessage message; + if (s != NATS_OK) + break; - if (!message.ParseFromString(natsMsg_GetData(msg))) { - Log(Logs::General, Logs::World_Server, "Failed to marshal"); + eqproto::CommandMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); + + if (!message->ParseFromString(natsMsg_GetData(msg))) { + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->in: failed to parse"); natsMsg_Destroy(msg); continue; } - if (message.command().compare("npctypespawn") == 0) { - if (message.params_size() < 2) { - message.set_result("Usage: !npctypespawn ."); + + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->in: %s", message->command().c_str()); + + if (message->command().compare("npctypespawn") == 0) { + if (message->params_size() < 2) { + message->set_result("Usage: !npctypespawn ."); } else { - uint32 npctypeid = atoi(message.params(0).c_str()); - uint32 factionid = atoi(message.params(1).c_str()); - float x = atof(message.params(2).c_str()); - float y = atof(message.params(3).c_str()); - float z = atof(message.params(4).c_str()); - float h = atof(message.params(5).c_str()); + uint32 npctypeid = atoi(message->params(0).c_str()); + uint32 factionid = atoi(message->params(1).c_str()); + float x = atof(message->params(2).c_str()); + float y = atof(message->params(3).c_str()); + float z = atof(message->params(4).c_str()); + float h = atof(message->params(5).c_str()); auto position = glm::vec4(x, y, z, h); const NPCType* tmp = 0; /*if (!(tmp = database.LoadNPCTypesData(npctypeid))) { - message.set_result(StringFormat("NPC Type %i not found", npctypeid)); + message->set_result(StringFormat("NPC Type %i not found", npctypeid)); } else { //tmp->fixedZ = 1; @@ -79,158 +88,169 @@ void NatsManager::Process() npc->SetNPCFactionID(factionid); npc->AddLootTable(); entity_list.AddNPC(npc); - message.set_result("Created NPC successfully."); + message->set_result("Created NPC successfully."); } */ } } - if (message.command().compare("spawn") == 0) { - if (message.params_size() < 5) { - message.set_result("Usage: npctypespawn name race level material hp gender class priweapon secweapon merchantid bodytype."); + if (message->command().compare("spawn") == 0) { + if (message->params_size() < 5) { + message->set_result("Usage: npctypespawn name race level material hp gender class priweapon secweapon merchantid bodytype."); } else { - float x = atof(message.params(0).c_str()); - float y = atof(message.params(1).c_str()); - float z = atof(message.params(2).c_str()); - float h = atof(message.params(3).c_str()); + float x = atof(message->params(0).c_str()); + float y = atof(message->params(1).c_str()); + float z = atof(message->params(2).c_str()); + float h = atof(message->params(3).c_str()); auto position = glm::vec4(x, y, z, h); std::string argumentString; - for (int i = 4; i < message.params_size(); i++) { - argumentString.append(StringFormat(" %s", message.params(i).c_str())); + for (int i = 4; i < message->params_size(); i++) { + argumentString.append(StringFormat(" %s", message->params(i).c_str())); } NPC* npc = NPC::SpawnNPC(argumentString.c_str(), position, NULL); if (!npc) { - message.set_result("Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters."); + message->set_result("Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters."); } else { - message.set_result(StringFormat("%u", npc->GetID())); + message->set_result(StringFormat("%u", npc->GetID())); } } } - if (message.command().compare("moveto") == 0) { - if (message.params_size() < 5) { - message.set_result("Usage: moveto ."); + if (message->command().compare("moveto") == 0) { + if (message->params_size() < 5) { + message->set_result("Usage: moveto ."); } else { - uint16 entityid = atoi(message.params(0).c_str()); - float x = atof(message.params(1).c_str()); - float y = atof(message.params(2).c_str()); - float z = atof(message.params(3).c_str()); - float h = atof(message.params(4).c_str()); + uint16 entityid = atoi(message->params(0).c_str()); + float x = atof(message->params(1).c_str()); + float y = atof(message->params(2).c_str()); + float z = atof(message->params(3).c_str()); + float h = atof(message->params(4).c_str()); auto position = glm::vec4(x, y, z, h); auto npc = entity_list.GetNPCByID(entityid); if (!npc) { - message.set_result("Invalid entity ID passed, or not an npc, etc"); + message->set_result("Invalid entity ID passed, or not an npc, etc"); } else { npc->MoveTo(position, true); - message.set_result("OK"); + message->set_result("OK"); } } } - if (message.command().compare("attack") == 0) { - if (message.params_size() < 3) { - message.set_result("Usage: attack ."); + if (message->command().compare("attack") == 0) { + if (message->params_size() < 3) { + message->set_result("Usage: attack ."); } else { - uint16 entityID = atoi(message.params(0).c_str()); - uint16 targetEntityID = atoi(message.params(1).c_str()); - uint32 hateAmount = atoi(message.params(2).c_str()); + uint16 entityID = atoi(message->params(0).c_str()); + uint16 targetEntityID = atoi(message->params(1).c_str()); + uint32 hateAmount = atoi(message->params(2).c_str()); auto npc = entity_list.GetNPCByID(entityID); if (!npc) { - message.set_result("Invalid entity ID passed, or not an npc, etc"); + message->set_result("Invalid entity ID passed, or not an npc, etc"); } else { auto mob = entity_list.GetMobID(targetEntityID); if (!mob) { - message.set_result("Invalid target entitiy ID passed, or not a mob, etc"); + message->set_result("Invalid target entitiy ID passed, or not a mob, etc"); } else { npc->AddToHateList(mob, hateAmount); - message.set_result("OK"); + message->set_result("OK"); } } } } - if (message.command().compare("entitylist") == 0) { + if (message->command().compare("entitylist") == 0) { std::string entityPayload; - if (message.params_size() < 1) { - message.set_result("Usage: entitylist ."); + if (message->params_size() < 1) { + message->set_result("Usage: entitylist ."); } else { - auto entities = eqproto::Entities(); - if (message.params(0).compare("npc") == 0) { + eqproto::Entities* entities = google::protobuf::Arena::CreateMessage(&the_arena); + if (message->params(0).compare("npc") == 0) { auto npcs = entity_list.ListNPCs(); auto it = npcs.begin(); for (const auto &entry : npcs) { - auto entity = entities.add_entities(); + auto entity = entities->add_entities(); entity->set_id(entry.second->GetID()); entity->set_type(1); entity->set_name(entry.second->GetName()); } - if (!entities.SerializeToString(&entityPayload)) { - message.set_result("Failed to serialized entitiy result"); + if (!entities->SerializeToString(&entityPayload)) { + message->set_result("Failed to serialized entitiy result"); } else { - message.set_payload(entityPayload.c_str()); + message->set_payload(entityPayload.c_str()); } } - /*else if (message.params(0).compare("client") == 0) { + /*else if (message->params(0).compare("client") == 0) { auto clients = entity_list.ListClients(); auto it = clients.begin(); for (const auto &entry : clients) { - auto entity = entities.add_entities(); + auto entity = entities->add_entities(); entity->set_id(entry.second->GetID()); entity->set_type(0); entity->set_name(entry.second->GetName()); } - if (!entities.SerializeToString(&entityMessage)) { - message.set_result("Failed to serialized entitiy result"); + if (!entities->SerializeToString(&entityMessage)) { + message->set_result("Failed to serialized entitiy result"); } else { - message.set_result(entityMessage.c_str()); + message->set_result(entityMessage.c_str()); } }*/ else { - message.set_result("Usage: entitylist ."); + message->set_result("Usage: entitylist ."); } } } - - if (message.result().length() < 1) { - message.set_result("Failed to parse command."); + if (message->result().length() < 1) { + message->set_result("Failed to parse command."); + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->out: failed to parse command", subscribedZoneName.c_str(), subscribedZoneInstance); + natsMsg_Destroy(msg); + continue; } - if (!message.SerializeToString(&pubMessage)) { - Log(Logs::General, Logs::World_Server, "NATS Failed to serialize command message to string"); - return; + if (!message->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->out: failed to serialize to string", subscribedZoneName.c_str(), subscribedZoneInstance); + natsMsg_Destroy(msg); + continue; } - s = natsConnection_PublishString(conn, natsMsg_GetReply(msg), pubMessage.c_str()); - if (s != NATS_OK) { - Log(Logs::General, Logs::World_Server, "NATS Failed to send CommandMessageEvent"); - return; + s = natsConnection_Publish(conn, natsMsg_GetReply(msg), (const void*)pubMessage.c_str(), pubMessage.length()); + if (s != NATS_OK) { + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->out: failed to publish: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); + natsMsg_Destroy(msg); + continue; } + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->out: success", subscribedZoneName.c_str(), subscribedZoneInstance); + } } //Unregister is called when a zone is being put to sleep or being swapped void NatsManager::Unregister() { - if (!connect()) return; + if (!connect()) + return; + + if (subscribedZoneName.length() == 0) + return; + if (zoneCommandMessageSub != NULL) { s = natsSubscription_Unsubscribe(zoneCommandMessageSub); zoneCommandMessageSub = NULL; @@ -260,64 +280,109 @@ void NatsManager::Unregister() if (s != NATS_OK) Log(Logs::General, Logs::NATS, "unsubscribe from zoneEntityEventSub failed: %s", nats_GetLastError(&s)); } - Log(Logs::General, Logs::NATS, "unsubscribed from %s", subscribedZonename.c_str()); - subscribedZonename.clear(); + Log(Logs::General, Logs::NATS, "unsubscribed from %s (%d)", subscribedZoneName.c_str(), subscribedZoneInstance); + subscribedZoneName.clear(); return; } -void NatsManager::ZoneSubscribe(const char* zonename) { - if (strcmp(subscribedZonename.c_str(), zonename) == 0) return; - if (!connect()) return; +void NatsManager::ZoneSubscribe(const char* zonename, uint32 instance) { + if (strcmp(subscribedZoneName.c_str(), zonename) == 0) + return; + + if (!connect()) + return; + Unregister(); - subscribedZonename = std::string(zonename); + subscribedZoneName = std::string(zonename); + subscribedZoneInstance = instance; + + if (subscribedZoneInstance == 0) { + s = natsConnection_SubscribeSync(&zoneChannelMessageSub, conn, StringFormat("zone.%s.channel_message->in", subscribedZoneName.c_str()).c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.channel_message->in: failed to subscribe: %s", subscribedZoneName.c_str(), nats_GetLastError(&s)); + + s = natsSubscription_SetPendingLimits(zoneChannelMessageSub, -1, -1); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.channel_message->in: failed to set pending limits: %s", subscribedZoneName.c_str(), nats_GetLastError(&s)); + + s = natsConnection_SubscribeSync(&zoneCommandMessageSub, conn, StringFormat("zone.%s.command_message->in", subscribedZoneName.c_str()).c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.command_message->in: failed to subscribe: %s", subscribedZoneName.c_str(), nats_GetLastError(&s)); + + s = natsSubscription_SetPendingLimits(zoneCommandMessageSub, -1, -1); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.channel_message->in: failed to set pending limits: %s", subscribedZoneName.c_str(), nats_GetLastError(&s)); + + s = natsConnection_SubscribeSync(&zoneEntityEventSubscribeAllSub, conn, StringFormat("zone.%s.entity.event_subscribe.all", subscribedZoneName.c_str(), subscribedZoneInstance).c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.command_message->in: failed to subscribe: %s", subscribedZoneName.c_str(), nats_GetLastError(&s)); + + s = natsSubscription_SetPendingLimits(zoneEntityEventSubscribeAllSub, -1, -1); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.channel_message->in: failed to set pending limits: %s", subscribedZoneName.c_str(), nats_GetLastError(&s)); + } + + s = natsConnection_SubscribeSync(&zoneChannelMessageSub, conn, StringFormat("zone.%s.%d.channel_message->in", subscribedZoneName.c_str(), subscribedZoneInstance).c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message->in: failed to subscribe: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); - s = natsConnection_SubscribeSync(&zoneChannelMessageSub, conn, StringFormat("zone.%s.channel_message", subscribedZonename.c_str()).c_str()); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneChannelMessageSub %s", nats_GetLastError(&s)); s = natsSubscription_SetPendingLimits(zoneChannelMessageSub, -1, -1); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneChannelMessageSub %s", nats_GetLastError(&s)); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message->in: failed to set pending limits: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); + - s = natsConnection_SubscribeSync(&zoneCommandMessageSub, conn, StringFormat("zone.%s.command_message", subscribedZonename.c_str()).c_str()); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneCommandMessageSub %s", nats_GetLastError(&s)); + s = natsConnection_SubscribeSync(&zoneCommandMessageSub, conn, StringFormat("zone.%s.%d.command_message->in", subscribedZoneName.c_str()).c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->in: failed to subscribe: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); + s = natsSubscription_SetPendingLimits(zoneCommandMessageSub, -1, -1); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneCommandMessageSub %s", nats_GetLastError(&s)); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message->in: failed to set pending limits: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); + + s = natsConnection_SubscribeSync(&zoneEntityEventSubscribeAllSub, conn, StringFormat("zone.%s.%d.entity.event_subscribe.all", subscribedZoneName.c_str(), subscribedZoneInstance).c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.%d.command_message->in: failed to subscribe: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); - s = natsConnection_SubscribeSync(&zoneEntityEventSubscribeAllSub, conn, StringFormat("zone.%s.entity.event_subscribe.all", subscribedZonename.c_str()).c_str()); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s)); s = natsSubscription_SetPendingLimits(zoneEntityEventSubscribeAllSub, -1, -1); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s)); - - s = natsConnection_SubscribeSync(&zoneEntityEventSubscribeAllSub, conn, StringFormat("zone.%s.entity.event_subscribe.all", subscribedZonename.c_str()).c_str()); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to subscribe to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s)); - s = natsSubscription_SetPendingLimits(zoneEntityEventSubscribeAllSub, -1, -1); - if (s != NATS_OK) Log(Logs::General, Logs::NATS, "failed to set pending limits to zoneEntityEventSubscribeAllSub %s", nats_GetLastError(&s)); - - Log(Logs::General, Logs::NATS, "subscribed to %s", subscribedZonename.c_str()); + if (s != NATS_OK) + Log(Logs::General, Logs::NATS, "zone.%s.%d.channel_message->in: failed to set pending limits: %s", subscribedZoneName.c_str(), subscribedZoneInstance, nats_GetLastError(&s)); + + Log(Logs::General, Logs::NATS, "subscribed as %s (%d)", subscribedZoneName.c_str(), subscribedZoneInstance); } void NatsManager::SendAdminMessage(std::string adminMessage) { - if (!connect()) return; + if (!connect()) + return; - eqproto::ChannelMessage message; - message.set_message(adminMessage.c_str()); + eqproto::ChannelMessage* message = google::protobuf::Arena::CreateMessage(&the_arena); + message->set_message(adminMessage.c_str()); std::string pubMessage; - if (!message.SerializeToString(&pubMessage)) { - Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + if (!message->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "global.admin_message->out: failed to serialize message to string"); return; } - s = natsConnection_PublishString(conn, "NATS AdminMessage", pubMessage.c_str()); + + s = natsConnection_Publish(conn, "global.admin_message->out", (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) { - Log(Logs::General, Logs::NATS, "Failed to SendAdminMessage"); + Log(Logs::General, Logs::NATS, "global.admin_message->out: failed: %s", nats_GetLastError(&s)); + return; } - Log(Logs::General, Logs::NATS, "AdminMessage: %s", adminMessage.c_str()); + + Log(Logs::General, Logs::NATS, "global.admin_message->out: %s", adminMessage.c_str()); } bool NatsManager::connect() { auto ncs = natsConnection_Status(conn); - if (ncs == CONNECTED) return true; - if (nats_timer.Enabled() && !nats_timer.Check()) return false; + + if (ncs == CONNECTED) + return true; + + if (nats_timer.Enabled() && !nats_timer.Check()) + return false; + natsOptions *opts = NULL; natsOptions_Create(&opts); natsOptions_SetMaxReconnect(opts, 0); @@ -328,7 +393,9 @@ bool NatsManager::connect() { //but since NATS is a second priority I wanted server impact minimum. natsOptions_SetTimeout(opts, 100); std::string connection = StringFormat("nats://%s:%d", zoneConfig->NATSHost.c_str(), zoneConfig->NATSPort); - if (zoneConfig->NATSHost.length() == 0) connection = "nats://localhost:4222"; + if (zoneConfig->NATSHost.length() == 0) + connection = "nats://localhost:4222"; + natsOptions_SetURL(opts, connection.c_str()); s = natsConnection_Connect(&conn, opts); natsOptions_Destroy(opts); @@ -339,6 +406,7 @@ bool NatsManager::connect() { nats_timer.SetTimer(20000); return false; } + Log(Logs::General, Logs::NATS, "connected to %s", connection.c_str()); nats_timer.Disable(); return true; @@ -346,7 +414,8 @@ bool NatsManager::connect() { void NatsManager::Load() { - if (!connect()) return; + if (!connect()) + return; return; } @@ -364,7 +433,7 @@ void NatsManager::OnEntityEvent(const EmuOpcode op, Entity *ent, Entity *target) } eqproto::EntityEvent event; - event.set_op(eqproto::OpCode(op)); + event->set_op(eqproto::OpCode(op)); eqproto::Entity entity; entity.set_id(ent->GetID()); entity.set_name(ent->GetName()); @@ -413,55 +482,66 @@ void NatsManager::OnEntityEvent(const EmuOpcode op, Entity *ent, Entity *target) entity.set_allocated_position(&position); targetEntity.set_allocated_position(&targetPosition); - event.set_allocated_entity(&entity); - event.set_allocated_target(&targetEntity); + event->set_allocated_entity(&entity); + event->set_allocated_target(&targetEntity); std::string pubMessage; - bool isSerialized = event.SerializeToString(&pubMessage); + bool isSerialized = event->SerializeToString(&pubMessage); if (!isSerialized) Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); Log(Logs::General, Logs::NATS, "Event: %d", op); - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), ent->GetID()).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZonename.c_str(), ent->GetID()).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); entity.release_name(); targetEntity.release_name(); entity.release_position(); targetEntity.release_position(); - event.release_entity(); - event.release_target(); + event->release_entity(); + event->release_target(); return; }*/ bool NatsManager::isEntitySubscribed(const uint16 ID) { - if (!connect()) return false; + if (!connect()) + return false; return false; } void NatsManager::OnDeathEvent(Death_Struct* d) { - if (!connect()) return; - if (d == NULL) return; - if (!isEntityEventAllEnabled && !isEntitySubscribed(d->spawn_id)) return; + if (!connect()) + return; + if (d == NULL) + return; + if (!isEntityEventAllEnabled && !isEntitySubscribed(d->spawn_id)) + return; std::string pubMessage; - auto event = eqproto::DeathEvent(); + eqproto::DeathEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); - event.set_spawn_id(d->spawn_id); - event.set_killer_id(d->killer_id); - event.set_bind_zone_id(d->bindzoneid); - event.set_spell_id(d->spell_id); - event.set_attack_skill_id(d->attack_skill); - event.set_damage(d->damage); + event->set_spawn_id(d->spawn_id); + event->set_killer_id(d->killer_id); + event->set_bind_zone_id(d->bindzoneid); + event->set_spell_id(d->spell_id); + event->set_attack_skill_id(d->attack_skill); + event->set_damage(d->damage); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + if (!event->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + return; + } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_Death); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), d->spawn_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_Death); + if (!finalEvent->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + return; + } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), d->spawn_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -472,22 +552,27 @@ void NatsManager::OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct* if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::ChannelMessageEvent(); + eqproto::ChannelMessageEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + + event->set_target_name(cm->targetname); + event->set_sender(cm->sender); + event->set_language(cm->language); + event->set_chan_num(cm->chan_num); + event->set_cm_unknown4(*cm->cm_unknown4); + event->set_skill_in_language(cm->skill_in_language); + event->set_message(cm->message); - event.set_target_name(cm->targetname); - event.set_sender(cm->sender); - event.set_language(cm->language); - event.set_chan_num(cm->chan_num); - event.set_cm_unknown4(*cm->cm_unknown4); - event.set_skill_in_language(cm->skill_in_language); - event.set_message(cm->message); + if (!event->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; + } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_ChannelMessage); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_ChannelMessage); + if (!finalEvent->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; + } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -498,82 +583,97 @@ void NatsManager::OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 tar if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::EntityEvent(); - event.set_entity_id(entity_id); - event.set_target_id(target_id); + eqproto::EntityEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_entity_id(entity_id); + event->set_target_id(target_id); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - if (op == OP_Camp) finalEvent.set_op(eqproto::OP_Camp); - else if (op == OP_Assist) finalEvent.set_op(eqproto::OP_Assist); - else { Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); return; } - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + if (op == OP_Camp) { + finalEvent->set_op(eqproto::OP_Camp); + } + else if (op == OP_Assist) { + finalEvent->set_op(eqproto::OP_Assist); + } + else { + Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); + return; + } + if (!finalEvent->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + return; + } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } void NatsManager::OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struct *spawn) { - if (!connect()) return; - if (entity_id == 0) return; - if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; + if (!connect()) + return; + if (entity_id == 0) + return; + if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) + return; std::string pubMessage; - auto event = eqproto::SpawnEvent(); - event.set_unknown0000(spawn->unknown0000); - event.set_gm(spawn->gm); - event.set_unknown0003(spawn->unknown0003); - event.set_aaitle(spawn->aaitle); - event.set_unknown0004(spawn->unknown0004); - event.set_anon(spawn->anon); - event.set_face(spawn->face); - event.set_name(spawn->name); - event.set_deity(spawn->deity); - event.set_unknown0073(spawn->unknown0073); - event.set_size(spawn->size); - event.set_unknown0079(spawn->unknown0079); - event.set_npc(spawn->NPC); - event.set_invis(spawn->invis); - event.set_haircolor(spawn->haircolor); - event.set_curhp(spawn->curHp); - event.set_max_hp(spawn->max_hp); - event.set_findable(spawn->findable); - event.set_unknown0089(*spawn->unknown0089); - event.set_deltaheading(spawn->deltaHeading); - event.set_x(spawn->x); - event.set_padding0054(spawn->padding0054); - event.set_y(spawn->y); - event.set_animation(spawn->animation); - event.set_padding0058(spawn->padding0058); - event.set_z(spawn->z); - event.set_deltay(spawn->deltaY); - event.set_deltax(spawn->deltaX); - event.set_heading(spawn->heading); - event.set_padding0066(spawn->padding0066); - event.set_deltaz(spawn->deltaZ); - event.set_padding0070(spawn->padding0070); - event.set_eyecolor1(spawn->eyecolor1); - event.set_unknown0115(*spawn->unknown0115); - event.set_standstate(spawn->StandState); - event.set_drakkin_heritage(spawn->drakkin_heritage); - event.set_drakkin_tattoo(spawn->drakkin_tattoo); - event.set_drakkin_details(spawn->drakkin_details); - event.set_showhelm(spawn->showhelm); - event.set_unknown0140(*spawn->unknown0140); - event.set_is_npc(spawn->is_npc); - event.set_hairstyle(spawn->hairstyle); - event.set_beard(spawn->beard); - event.set_unknown0147(*spawn->unknown0147); - event.set_level(spawn->level); - event.set_playerstate(spawn->PlayerState); - event.set_beardcolor(spawn->beardcolor); - event.set_suffix(spawn->suffix); - event.set_petownerid(spawn->petOwnerId); - event.set_guildrank(spawn->guildrank); - event.set_unknown0194(*spawn->unknown0194); + eqproto::SpawnEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + + event->set_unknown0000(spawn->unknown0000); + event->set_gm(spawn->gm); + event->set_unknown0003(spawn->unknown0003); + event->set_aaitle(spawn->aaitle); + event->set_unknown0004(spawn->unknown0004); + event->set_anon(spawn->anon); + event->set_face(spawn->face); + event->set_name(spawn->name); + event->set_deity(spawn->deity); + event->set_unknown0073(spawn->unknown0073); + event->set_size(spawn->size); + event->set_unknown0079(spawn->unknown0079); + event->set_npc(spawn->NPC); + event->set_invis(spawn->invis); + event->set_haircolor(spawn->haircolor); + event->set_curhp(spawn->curHp); + event->set_max_hp(spawn->max_hp); + event->set_findable(spawn->findable); + event->set_unknown0089(*spawn->unknown0089); + event->set_deltaheading(spawn->deltaHeading); + event->set_x(spawn->x); + event->set_padding0054(spawn->padding0054); + event->set_y(spawn->y); + event->set_animation(spawn->animation); + event->set_padding0058(spawn->padding0058); + event->set_z(spawn->z); + event->set_deltay(spawn->deltaY); + event->set_deltax(spawn->deltaX); + event->set_heading(spawn->heading); + event->set_padding0066(spawn->padding0066); + event->set_deltaz(spawn->deltaZ); + event->set_padding0070(spawn->padding0070); + event->set_eyecolor1(spawn->eyecolor1); + event->set_unknown0115(*spawn->unknown0115); + event->set_standstate(spawn->StandState); + event->set_drakkin_heritage(spawn->drakkin_heritage); + event->set_drakkin_tattoo(spawn->drakkin_tattoo); + event->set_drakkin_details(spawn->drakkin_details); + event->set_showhelm(spawn->showhelm); + event->set_unknown0140(*spawn->unknown0140); + event->set_is_npc(spawn->is_npc); + event->set_hairstyle(spawn->hairstyle); + event->set_beard(spawn->beard); + event->set_unknown0147(*spawn->unknown0147); + event->set_level(spawn->level); + event->set_playerstate(spawn->PlayerState); + event->set_beardcolor(spawn->beardcolor); + event->set_suffix(spawn->suffix); + event->set_petownerid(spawn->petOwnerId); + event->set_guildrank(spawn->guildrank); + event->set_unknown0194(*spawn->unknown0194); /*auto texture = eqproto::Texture(); texture.set_elitemodel(spawn->equipment.Arms.EliteModel); @@ -581,62 +681,63 @@ void NatsManager::OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struc texture.set_material(spawn->equipment.Arms.Material); texture.set_unknown1(spawn->equipment.Arms.Unknown1); texture.set_unknown2(spawn->equipment.Arms.Unknown2); - event.set_allocated_equipment(textureProfile);*/ - event.set_runspeed(spawn->runspeed); - event.set_afk(spawn->afk); - event.set_guildid(spawn->guildID); - event.set_title(spawn->title); - event.set_unknown0274(spawn->unknown0274); - event.set_set_to_0xff(*spawn->set_to_0xFF); - event.set_helm(spawn->helm); - event.set_race(spawn->race); - event.set_unknown0288(spawn->unknown0288); - event.set_lastname(spawn->lastName); - event.set_walkspeed(spawn->walkspeed); - event.set_unknown0328(spawn->unknown0328); - event.set_is_pet(spawn->is_pet); - event.set_light(spawn->light); - event.set_class_(spawn->class_); - event.set_eyecolor2(spawn->eyecolor2); - event.set_flymode(spawn->flymode); - event.set_gender(spawn->gender); - event.set_bodytype(spawn->bodytype); - event.set_unknown0336(*spawn->unknown0336); - event.set_equip_chest2(spawn->equip_chest2); - event.set_mount_color(spawn->mount_color); - event.set_spawnid(spawn->spawnId); - event.set_ismercenary(spawn->IsMercenary); - //event.set_equipment_tint(spawn->equipment_tint); - event.set_lfg(spawn->lfg); - event.set_destructibleobject(spawn->DestructibleObject); - event.set_destructiblemodel(spawn->DestructibleModel); - event.set_destructiblename2(spawn->DestructibleName2); - event.set_destructiblestring(spawn->DestructibleString); - event.set_destructibleappearance(spawn->DestructibleAppearance); - event.set_destructibleunk1(spawn->DestructibleUnk1); - event.set_destructibleid1(spawn->DestructibleID1); - event.set_destructibleid2(spawn->DestructibleID2); - event.set_destructibleid3(spawn->DestructibleID3); - event.set_destructibleid4(spawn->DestructibleID4); - event.set_destructibleunk2(spawn->DestructibleUnk2); - event.set_destructibleunk3(spawn->DestructibleUnk3); - event.set_destructibleunk4(spawn->DestructibleUnk4); - event.set_destructibleunk5(spawn->DestructibleUnk5); - event.set_destructibleunk6(spawn->DestructibleUnk6); - event.set_destructibleunk7(spawn->DestructibleUnk7); - event.set_destructibleunk8(spawn->DestructibleUnk8); - event.set_destructibleunk9(spawn->DestructibleUnk9); - event.set_targetable_with_hotkey(spawn->targetable_with_hotkey); - event.set_show_name(spawn->show_name); + event->set_allocated_equipment(textureProfile);*/ + event->set_runspeed(spawn->runspeed); + event->set_afk(spawn->afk); + event->set_guildid(spawn->guildID); + event->set_title(spawn->title); + event->set_unknown0274(spawn->unknown0274); + event->set_set_to_0xff(*spawn->set_to_0xFF); + event->set_helm(spawn->helm); + event->set_race(spawn->race); + event->set_unknown0288(spawn->unknown0288); + event->set_lastname(spawn->lastName); + event->set_walkspeed(spawn->walkspeed); + event->set_unknown0328(spawn->unknown0328); + event->set_is_pet(spawn->is_pet); + event->set_light(spawn->light); + event->set_class_(spawn->class_); + event->set_eyecolor2(spawn->eyecolor2); + event->set_flymode(spawn->flymode); + event->set_gender(spawn->gender); + event->set_bodytype(spawn->bodytype); + event->set_unknown0336(*spawn->unknown0336); + event->set_equip_chest2(spawn->equip_chest2); + event->set_mount_color(spawn->mount_color); + event->set_spawnid(spawn->spawnId); + event->set_ismercenary(spawn->IsMercenary); + //event->set_equipment_tint(spawn->equipment_tint); + event->set_lfg(spawn->lfg); + event->set_destructibleobject(spawn->DestructibleObject); + event->set_destructiblemodel(spawn->DestructibleModel); + event->set_destructiblename2(spawn->DestructibleName2); + event->set_destructiblestring(spawn->DestructibleString); + event->set_destructibleappearance(spawn->DestructibleAppearance); + event->set_destructibleunk1(spawn->DestructibleUnk1); + event->set_destructibleid1(spawn->DestructibleID1); + event->set_destructibleid2(spawn->DestructibleID2); + event->set_destructibleid3(spawn->DestructibleID3); + event->set_destructibleid4(spawn->DestructibleID4); + event->set_destructibleunk2(spawn->DestructibleUnk2); + event->set_destructibleunk3(spawn->DestructibleUnk3); + event->set_destructibleunk4(spawn->DestructibleUnk4); + event->set_destructibleunk5(spawn->DestructibleUnk5); + event->set_destructibleunk6(spawn->DestructibleUnk6); + event->set_destructibleunk7(spawn->DestructibleUnk7); + event->set_destructibleunk8(spawn->DestructibleUnk8); + event->set_destructibleunk9(spawn->DestructibleUnk9); + event->set_targetable_with_hotkey(spawn->targetable_with_hotkey); + event->set_show_name(spawn->show_name); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - if (op == OP_ZoneEntry) finalEvent.set_op(eqproto::OP_ZoneEntry); - else if (op == OP_NewSpawn) finalEvent.set_op(eqproto::OP_NewSpawn); + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + if (op == OP_ZoneEntry) finalEvent->set_op(eqproto::OP_ZoneEntry); + else if (op == OP_NewSpawn) finalEvent->set_op(eqproto::OP_NewSpawn); else { Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); return; } - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + if (!finalEvent->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -647,24 +748,22 @@ void NatsManager::OnWearChangeEvent(uint32 entity_id, WearChange_Struct *wc) { if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::WearChangeEvent(); + eqproto::WearChangeEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_spawn_id(wc->spawn_id); + event->set_material(wc->material); + event->set_unknown06(wc->unknown06); + event->set_elite_material(wc->elite_material); + event->set_hero_forge_model(wc->hero_forge_model); + event->set_unknown18(wc->unknown18); + //event->set_color(wc->color); //tint + event->set_wear_slot_id(wc->wear_slot_id); - - event.set_spawn_id(wc->spawn_id); - event.set_material(wc->material); - event.set_unknown06(wc->unknown06); - event.set_elite_material(wc->elite_material); - event.set_hero_forge_model(wc->hero_forge_model); - event.set_unknown18(wc->unknown18); - //event.set_color(wc->color); //tint - event.set_wear_slot_id(wc->wear_slot_id); - - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_WearChange); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_WearChange); + if (!finalEvent->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -674,18 +773,18 @@ void NatsManager::OnDeleteSpawnEvent(uint32 entity_id, DeleteSpawn_Struct *ds) { if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::DeleteSpawnEvent(); + eqproto::DeleteSpawnEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); - event.set_spawn_id(ds->spawn_id); - event.set_decay(ds->Decay); + event->set_spawn_id(ds->spawn_id); + event->set_decay(ds->Decay); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_DeleteSpawn); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_DeleteSpawn); + if (!finalEvent->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -695,20 +794,21 @@ void NatsManager::OnHPEvent(const EmuOpcode op, uint32 entity_id, uint32 cur_hp, if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; if (cur_hp == max_hp) return; std::string pubMessage; - auto event = eqproto::HPEvent(); - event.set_spawn_id(entity_id); - event.set_cur_hp(cur_hp); - event.set_max_hp(max_hp); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - if (op == OP_MobHealth) finalEvent.set_op(eqproto::OP_MobHealth); - else if (op == OP_HPUpdate) finalEvent.set_op(eqproto::OP_HPUpdate); + eqproto::HPEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_spawn_id(entity_id); + event->set_cur_hp(cur_hp); + event->set_max_hp(max_hp); + + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + if (op == OP_MobHealth) finalEvent->set_op(eqproto::OP_MobHealth); + else if (op == OP_HPUpdate) finalEvent->set_op(eqproto::OP_HPUpdate); else { Log(Logs::General, Logs::NATS, "unhandled op type passed: %i", op); return; } - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + if (!finalEvent->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -717,23 +817,24 @@ void NatsManager::OnDamageEvent(uint32 entity_id, CombatDamage_Struct *cd) { if (entity_id == 0) return; if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::DamageEvent(); - event.set_target(cd->target); - event.set_source(cd->source); - event.set_type(cd->type); - event.set_spellid(cd->spellid); - event.set_damage(cd->damage); - event.set_force(cd->force); - event.set_meleepush_xy(cd->hit_heading); - event.set_meleepush_z(cd->hit_pitch); + + eqproto::DamageEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_target(cd->target); + event->set_source(cd->source); + event->set_type(cd->type); + event->set_spellid(cd->spellid); + event->set_damage(cd->damage); + event->set_force(cd->force); + event->set_meleepush_xy(cd->hit_heading); + event->set_meleepush_z(cd->hit_pitch); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_Damage); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_Damage); + if (!finalEvent->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -743,29 +844,36 @@ void NatsManager::OnClientUpdateEvent(uint32 entity_id, PlayerPositionUpdateServ if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::PlayerPositionUpdateEvent(); - - event.set_spawn_id(spu->spawn_id); - event.set_delta_heading(spu->delta_heading); - event.set_x_pos(spu->x_pos); - event.set_padding0002(spu->padding0002); - event.set_y_pos(spu->y_pos); - event.set_animation(spu->animation); - event.set_padding0006(spu->padding0006); - event.set_z_pos(spu->z_pos); - event.set_delta_y(spu->delta_y); - event.set_delta_x(spu->delta_x); - event.set_heading(spu->heading); - event.set_padding0014(spu->padding0014); - event.set_delta_z(spu->delta_z); - event.set_padding0018(spu->padding0018); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_ClientUpdate); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + + eqproto::PlayerPositionUpdateEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_spawn_id(spu->spawn_id); + event->set_delta_heading(spu->delta_heading); + event->set_x_pos(spu->x_pos); + event->set_padding0002(spu->padding0002); + event->set_y_pos(spu->y_pos); + event->set_animation(spu->animation); + event->set_padding0006(spu->padding0006); + event->set_z_pos(spu->z_pos); + event->set_delta_y(spu->delta_y); + event->set_delta_x(spu->delta_x); + event->set_heading(spu->heading); + event->set_padding0014(spu->padding0014); + event->set_delta_z(spu->delta_z); + event->set_padding0018(spu->padding0018); + + if (!event->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + return; + } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_ClientUpdate); + if (!finalEvent->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); + return; + } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } @@ -776,17 +884,19 @@ void NatsManager::OnAnimationEvent(uint32 entity_id, Animation_Struct *anim) { if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) return; std::string pubMessage; - auto event = eqproto::AnimationEvent(); - event.set_spawnid(anim->spawnid); - event.set_speed(anim->speed); - event.set_action(anim->action); - if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - auto finalEvent = eqproto::Event(); - finalEvent.set_payload(pubMessage.c_str()); - finalEvent.set_op(eqproto::OP_Animation); - if (!finalEvent.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } - s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event.%d", subscribedZonename.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); + eqproto::AnimationEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_spawnid(anim->spawnid); + event->set_speed(anim->speed); + event->set_action(anim->action); + + if (!event->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + eqproto::Event* finalEvent = google::protobuf::Arena::CreateMessage(&the_arena); + + finalEvent->set_payload(pubMessage.c_str()); + finalEvent->set_op(eqproto::OP_Animation); + if (!finalEvent->SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; } + s = natsConnection_Publish(conn, StringFormat("zone.%s.entity.event->%d", subscribedZoneName.c_str(), entity_id).c_str(), (const void*)pubMessage.c_str(), pubMessage.length()); if (s != NATS_OK) Log(Logs::General, Logs::NATS, "Failed to send EntityEvent"); } \ No newline at end of file diff --git a/zone/nats_manager.h b/zone/nats_manager.h index e8e003183..7a714fb1a 100644 --- a/zone/nats_manager.h +++ b/zone/nats_manager.h @@ -16,7 +16,7 @@ public: ~NatsManager(); void Process(); void Unregister(); - void ZoneSubscribe(const char * zonename); + void ZoneSubscribe(const char * zonename, uint32 instance); void Load(); void OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct * cm); void OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 target_id); @@ -37,7 +37,8 @@ protected: natsConnection *conn = NULL; natsStatus s; natsOptions *opts = NULL; - std::string subscribedZonename; + std::string subscribedZoneName; + uint32 subscribedZoneInstance; natsSubscription *zoneChannelMessageSub = NULL; natsSubscription *zoneCommandMessageSub = NULL; natsSubscription *zoneEntityEventSubscribeAllSub = NULL; diff --git a/zone/net.cpp b/zone/net.cpp index 714cceddc..198525a2a 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -515,7 +515,7 @@ int main(int argc, char** argv) { entity_list.BeaconProcess(); entity_list.EncounterProcess(); if (zone->IsLoaded()) { - nats.ZoneSubscribe(zone->GetShortName()); + nats.ZoneSubscribe(zone->GetShortName(), zone->GetInstanceID()); nats.Process(); } if (zone) {