From 98f4e570e79ee83664c031f75c9b29b732e9a64c Mon Sep 17 00:00:00 2001 From: Xackery Date: Tue, 13 Mar 2018 17:39:44 -0700 Subject: [PATCH] Added MessageType and SpecialMessage support --- common/message.proto | 124 +++++++++++++++++++++++++++++- utils/nats/npcwalk/npcwalk.go | 2 + utils/nats/playersay/playersay.go | 11 +-- world/nats_manager.cpp | 6 +- zone/client.cpp | 8 +- zone/nats_manager.cpp | 35 ++++++++- zone/nats_manager.h | 1 + 7 files changed, 169 insertions(+), 18 deletions(-) diff --git a/common/message.proto b/common/message.proto index 9f9b1dd86..b0e6518c2 100644 --- a/common/message.proto +++ b/common/message.proto @@ -5,7 +5,7 @@ option cc_enable_arenas = true; option optimize_for = SPEED; message ChannelMessage { - int32 chan_num = 1; + MessageType number = 1; int32 language = 2; string from = 3; string to = 4; @@ -138,12 +138,23 @@ message ChannelMessageEvent { string target_name = 1; // Tell recipient string sender = 2; // The senders name (len might be wrong) uint32 language = 3; // Language - uint32 chan_num = 4; // Channel + MessageType number = 4; // Channel number uint32 cm_unknown4 = 5; // ***Placeholder uint32 skill_in_language = 6; // The players skill in this language? might be wrong string message = 7; // Variable length message } + +//OP_SpecialMesg +message SpecialMessageEvent { + string header = 1; // 04 04 00 <-- for #emote style msg + MessageType number = 2; // Color of text (see MT_*** below) + uint32 target_spawn_id = 3; // Who is it being said to? + string sayer = 4; // Who is the source of the info + uint32 unknown12 = 5; + string message = 6; // What is being said? +} + //OP_WearChange message WearChangeEvent { uint32 spawn_id = 1; @@ -311,6 +322,113 @@ enum EntityType { Object = 6; //Inherits entity } + +enum MessageType { + //option allow_alias = true; + WhiteSmoke = 0; // FF|F0F0F0 + DimGray = 1; // FF|606060 + Green = 2; // FF|008000 + BrightBlue = 3; // FF|0040FF + Magenta = 5; // FF|F000F0 + Gray = 6; // FF|808080 + LightGray = 7; // FF|E0E0E0 + WhiteSmoke2 = 10; // FF|F0F0F0 + DarkGray = 12; // FF|A0A0A0 + Red= 13; // FF|F00000 + Lime = 14; // FF|00F000 + Yellow = 15; // FF|F0F000 + Blue = 16; // FF|0000F0 + LightNavy = 17; // FF|0000AF + Cyan = 18; // FF|00F0F0 + Black = 20; // FF|000000 + + Say = 256; + Tell = 257; + Group = 258; + Guild = 259; + OOC = 260; + Auction = 261; + Shout = 262; + Emote = 263; + Spells = 264; + YouHitOther = 265; + OtherHitsYou = 266; + YouMissOther = 267; + OtherMissesYou = 268; + Broadcasts = 269; + Skills = 270; + Disciplines = 271; + Unused1 = 272; + DefaultText = 273; + Unused2 = 274; + MerchantOffer = 275; + MerchantBuySell = 276; + YourDeath = 277; + OtherDeath = 278; + OtherHits = 279; + OtherMisses = 280; + Who = 281; + YellForHelp = 282; + NonMelee = 283; + WornOff = 284; + MoneySplit = 285; + LootMessages = 286; + DiceRoll = 287; + OtherSpells = 288; + SpellFailure = 289; + Chat = 290; + Channel1 = 291; + Channel2 = 292; + Channel3 = 293; + Channel4 = 294; + Channel5 = 295; + Channel6 = 296; + Channel7 = 297; + Channel8 = 298; + Channel9 = 299; + Channel10 = 300; + CritMelee = 301; + SpellCrits = 302; + TooFarAway = 303; + NPCRampage = 304; + NPCFlurry = 305; + NPCEnrage = 306; + SayEcho = 307; + TellEcho = 308; + GroupEcho = 309; + GuildEcho = 310; + OOCEcho = 311; + AuctionEcho = 312; + ShoutECho = 313; + EmoteEcho = 314; + Chat1Echo = 315; + Chat2Echo = 316; + Chat3Echo = 317; + Chat4Echo = 318; + Chat5Echo = 319; + Chat6Echo = 320; + Chat7Echo = 321; + Chat8Echo = 322; + Chat9Echo = 323; + Chat10Echo = 324; + DoTDamage = 325; + ItemLink = 326; + RaidSay = 327; + MyPet = 328; + DS = 329; + Leadership = 330; + PetFlurry = 331; + PetCrit = 332; + FocusEffect = 333; + Experience = 334; + System = 335; + PetSpell = 336; + PetResponse = 337; + ItemSpeech = 338; + StrikeThrough = 339; + Stun = 340; +} + enum OpCode { //option allow_alias = true; OP_Unknown = 0; @@ -791,7 +909,7 @@ enum OpCode { OP_SpawnAppearance = 475; OP_SpawnDoor = 476; OP_SpawnPositionUpdate = 477; - OP_SpecialMesg = 478; + OP_SpecialMesg = 478; //supported OP_SpellEffect = 479; OP_Split = 480; OP_Stamina = 481; diff --git a/utils/nats/npcwalk/npcwalk.go b/utils/nats/npcwalk/npcwalk.go index b04750e54..a9804c6b2 100644 --- a/utils/nats/npcwalk/npcwalk.go +++ b/utils/nats/npcwalk/npcwalk.go @@ -234,6 +234,8 @@ func entityEventSubscriber(zone string, instance int, entityID int64) { eventPayload = &eqproto.DeleteSpawnEvent{} case eqproto.OpCode_OP_Damage: eventPayload = &eqproto.DamageEvent{} + case eqproto.OpCode_OP_SpecialMesg: + eventPayload = &eqproto.SpecialMessageEvent{} default: return } diff --git a/utils/nats/playersay/playersay.go b/utils/nats/playersay/playersay.go index a9d670e01..4040fea14 100644 --- a/utils/nats/playersay/playersay.go +++ b/utils/nats/playersay/playersay.go @@ -44,15 +44,15 @@ func main() { } go entityEventSubscriber(zone, instance, entityID) - zoneChannel(zone, instance, entityID, eqproto.EntityType_Client, 256, "Hello, World!") + zoneChannel(zone, instance, entityID, eqproto.EntityType_Client, eqproto.MessageType_Say, "Hello, World!") time.Sleep(1000 * time.Second) } -func zoneChannel(zone string, instance int64, fromEntityID int32, fromEntityType eqproto.EntityType, chanNumber int32, message string) { +func zoneChannel(zone string, instance int64, fromEntityID int32, fromEntityType eqproto.EntityType, chanNumber eqproto.MessageType, message string) { msg := &eqproto.ChannelMessage{ Message: message, - ChanNum: chanNumber, + Number: chanNumber, FromEntityId: fromEntityID, FromEntityType: fromEntityType, Distance: 500, @@ -197,7 +197,6 @@ func entityEventSubscriber(zone string, instance int64, entityID int32) { return }*/ - var opCode int64 var index int channel := fmt.Sprintf("zone.%s.%d.entity.%d.event.out", zone, instance, entityID) nc.Subscribe(channel, func(m *nats.Msg) { @@ -225,12 +224,14 @@ func entityEventSubscriber(zone string, instance int64, entityID int32) { eventPayload = &eqproto.DeleteSpawnEvent{} case eqproto.OpCode_OP_Damage: eventPayload = &eqproto.DamageEvent{} + case eqproto.OpCode_OP_SpecialMesg: + eventPayload = &eqproto.SpecialMessageEvent{} default: return } err = proto.Unmarshal(event.Payload, eventPayload) if err != nil { - fmt.Println("Invalid data passed for opcode", eqproto.OpCode(opCode), err.Error(), string(m.Data[index+1:])) + fmt.Println("Invalid data passed for opcode", event.Op, err.Error(), string(m.Data[index+1:])) return } fmt.Println(m.Subject, event.Op, eventPayload) diff --git a/world/nats_manager.cpp b/world/nats_manager.cpp index a8076cd1d..5114c61d2 100644 --- a/world/nats_manager.cpp +++ b/world/nats_manager.cpp @@ -135,7 +135,7 @@ void NatsManager::OnChannelMessage(ServerChannelMessage_Struct* msg) { message->set_guilddbid(msg->guilddbid); message->set_noreply(msg->noreply); message->set_queued(msg->queued); - message->set_chan_num(msg->chan_num); + message->set_number(static_cast(msg->chan_num)); message->set_message(msg->message); message->set_to(msg->to); message->set_language(msg->language); @@ -297,9 +297,9 @@ void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char tmpname[0] = '*'; strcpy(&tmpname[1], message->from().c_str()); //TODO: add To support on tells - int channel = message->chan_num(); + int channel = message->number(); if (channel < 1) - channel = 5; //default to ooc + channel = MT_OOC; //default to ooc zoneserver_list.SendChannelMessage(tmpname, 0, channel, message->language(), message->message().c_str()); message->set_result("1"); SendChannelMessage(message, reply); diff --git a/zone/client.cpp b/zone/client.cpp index 16157c807..b7971fa15 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -54,7 +54,9 @@ extern volatile bool RunLoops; #include "guild_mgr.h" #include "quest_parser_collection.h" #include "queryserv.h" +#include "nats_manager.h" +extern NatsManager nats; extern QueryServ* QServ; extern EntityList entity_list; extern Zone* zone; @@ -1270,7 +1272,7 @@ void Client::Message(uint32 type, const char* message, ...) { sm->header[2] = 0x00; sm->msg_type = type; memcpy(sm->message, buffer, len+1); - + nats.OnSpecialMessageEvent(GetID(), sm); FastQueuePacket(&app); safe_delete_array(buffer); @@ -1301,7 +1303,7 @@ void Client::FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, cons sm->header[2] = 0x00; sm->msg_type = type; memcpy(sm->message, buffer, len + 1); - + nats.OnSpecialMessageEvent(GetID(), sm); FastQueuePacket(&app); safe_delete_array(buffer); @@ -1341,7 +1343,7 @@ void Client::QuestJournalledMessage(const char *npcname, const char* message) { dest = dest + strlen(OutNPCName) + 13; memcpy(dest, OutMessage, strlen(OutMessage) + 1); - + nats.OnSpecialMessageEvent(GetID(), sm); QueuePacket(app); safe_delete(app); diff --git a/zone/nats_manager.cpp b/zone/nats_manager.cpp index c0f7487b0..47536bee2 100644 --- a/zone/nats_manager.cpp +++ b/zone/nats_manager.cpp @@ -137,9 +137,9 @@ void NatsManager::GetChannelMessage(eqproto::ChannelMessage* message, const char } if (message->distance() > 0) - entity_list.MessageClose(mob, message->skip_sender(), message->distance(), message->chan_num(), message->message().c_str()); + entity_list.MessageClose(mob, message->skip_sender(), message->distance(), message->number(), message->message().c_str()); else - mob->Message(message->chan_num(), message->message().c_str()); + mob->Message(message->number(), message->message().c_str()); message->set_result("1"); SendChannelMessage(message, reply); @@ -668,8 +668,8 @@ void NatsManager::OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct* 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_language(cm->language); + event->set_number((eqproto::MessageType)cm->chan_num); event->set_cm_unknown4(*cm->cm_unknown4); event->set_skill_in_language(cm->skill_in_language); event->set_message(cm->message); @@ -681,6 +681,33 @@ void NatsManager::OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct* } +void NatsManager::OnSpecialMessageEvent(uint32 entity_id, SpecialMesg_Struct* sm) { + if (!connect()) + return; + if (entity_id == 0) + return; + if (!isEntityEventAllEnabled && !isEntitySubscribed(entity_id)) + return; + + auto op = eqproto::OP_SpecialMesg; + + std::string pubMessage; + eqproto::SpecialMessageEvent* event = google::protobuf::Arena::CreateMessage(&the_arena); + event->set_header(sm->header); + event->set_number(static_cast(sm->msg_type)); + event->set_target_spawn_id(sm->target_spawn_id); + event->set_sayer(sm->sayer); + event->set_unknown12(*sm->unknown12); + event->set_message(sm->message); + + if (!event->SerializeToString(&pubMessage)) { + Log(Logs::General, Logs::NATS, "zone.%s.%d.entity.%d.event.out: (OP: %d) failed to serialize message to string", subscribedZoneName.c_str(), subscribedZoneInstance, entity_id, op); + return; + } + + SendEvent(op, entity_id, pubMessage); +} + void NatsManager::OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 target_id) { if (!connect()) return; diff --git a/zone/nats_manager.h b/zone/nats_manager.h index e683faeba..3233a5442 100644 --- a/zone/nats_manager.h +++ b/zone/nats_manager.h @@ -32,6 +32,7 @@ public: void SendEvent(eqproto::OpCode op, uint32 entity_id, std::string pubMessage); void OnChannelMessageEvent(uint32 entity_id, ChannelMessage_Struct * cm); + void OnSpecialMessageEvent(uint32 entity_id, SpecialMesg_Struct *sm); void OnEntityEvent(const EmuOpcode op, uint32 entity_id, uint32 target_id); void OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struct * spawn); void OnWearChangeEvent(uint32 entity_id, WearChange_Struct * wc);