diff --git a/common/features.h b/common/features.h index 8115efd82..9ceddb31b 100644 --- a/common/features.h +++ b/common/features.h @@ -273,6 +273,9 @@ enum { #define NPC_DEFAULT_LOGGING_ENABLED false +// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars +#define SAYLINK_ITEM_ID 0xFFFFF + /* diff --git a/zone/bot.cpp b/zone/bot.cpp index 5ce63714c..01aafa4aa 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -13774,11 +13774,10 @@ std::string Bot::CreateSayLink(Client* c, const char* message, const char* name) } safe_delete_array(escaped_string); - sayid += 500000; - Client::TextLink linker; linker.SetLinkType(linker.linkItemData); - linker.SetProxyItemID(sayid); + linker.SetProxyItemID(SAYLINK_ITEM_ID); + linker.SetProxyAugment1ID(sayid); linker.SetProxyText(name); auto say_link = linker.GenerateLink(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 58381db62..1475b6c74 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -8090,97 +8090,80 @@ void Client::Handle_OP_InstillDoubt(const EQApplicationPacket *app) void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) { - if (app->size != sizeof(ItemViewRequest_Struct)){ - Log.Out(Logs::General, Logs::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, sizeof(ItemViewRequest_Struct)); + if (app->size != sizeof(ItemViewRequest_Struct)) { + Log.Out(Logs::General, Logs::Error, "Wrong size on OP_ItemLinkClick. Got: %i, Expected: %i", app->size, + sizeof(ItemViewRequest_Struct)); DumpPacket(app); return; } DumpPacket(app); - ItemViewRequest_Struct* ivrs = (ItemViewRequest_Struct*)app->pBuffer; + ItemViewRequest_Struct *ivrs = (ItemViewRequest_Struct *)app->pBuffer; - //todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data from the item DB + // todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data + // from the item DB - const Item_Struct* item = database.GetItem(ivrs->item_id); + const Item_Struct *item = database.GetItem(ivrs->item_id); if (!item) { - if (ivrs->item_id > 500000) - { - std::string response = ""; - int sayid = ivrs->item_id - 500000; - bool silentsaylink = false; - - if (sayid > 250000) //Silent Saylink - { - sayid = sayid - 250000; - silentsaylink = true; - } - - if (sayid > 0) - { - - std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid); - auto results = database.QueryDatabase(query); - if (!results.Success()) { - Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); - return; - } - - if (results.RowCount() != 1) { - Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); - return; - } - - auto row = results.begin(); - response = row[0]; - - } - - if ((response).size() > 0) - { - if (!mod_saylink(response, silentsaylink)) { return; } - - if (GetTarget() && GetTarget()->IsNPC()) - { - if (silentsaylink) - { - parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0); - parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); - } - else - { - Message(7, "You say, '%s'", response.c_str()); - ChannelMessageReceived(8, 0, 100, response.c_str()); - } - return; - } - else - { - if (silentsaylink) - { - parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); - } - else - { - Message(7, "You say, '%s'", response.c_str()); - ChannelMessageReceived(8, 0, 100, response.c_str()); - } - return; - } - } - else - { - Message(13, "Error: Say Link not found or is too long."); - return; - } - } - else { + if (ivrs->item_id != SAYLINK_ITEM_ID) { Message(13, "Error: The item for the link you have clicked on does not exist!"); return; } + // This new scheme will shuttle the ID in the first augment for non-silent links + // and the second augment for silent. + std::string response = ""; + bool silentsaylink = ivrs->augments[1] > 0 ? true : false; + int sayid = silentsaylink ? ivrs->augments[1] : ivrs->augments[0]; + if (sayid > 0) { + std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid); + auto results = database.QueryDatabase(query); + if (!results.Success()) { + Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + return; + } + + if (results.RowCount() != 1) { + Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + return; + } + + auto row = results.begin(); + response = row[0]; + } + + if ((response).size() > 0) { + if (!mod_saylink(response, silentsaylink)) { + return; + } + + if (GetTarget() && GetTarget()->IsNPC()) { + if (silentsaylink) { + parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0); + parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); + } else { + Message(7, "You say, '%s'", response.c_str()); + ChannelMessageReceived(8, 0, 100, response.c_str()); + } + return; + } else { + if (silentsaylink) { + parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); + } else { + Message(7, "You say, '%s'", response.c_str()); + ChannelMessageReceived(8, 0, 100, response.c_str()); + } + return; + } + } else { + Message(13, "Error: Say Link not found or is too long."); + return; + } } - ItemInst* inst = database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]); + ItemInst *inst = + database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2], + ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]); if (inst) { SendItemPacket(0, inst, ItemPacketViewLink); safe_delete(inst); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 86b8cb7d9..fa8788bbf 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2766,14 +2766,13 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam } safe_delete_array(escaped_string); - if (silent) - sayid = sayid + 750000; - else - sayid = sayid + 500000; - //Create the say link as an item link hash Client::TextLink linker; - linker.SetProxyItemID(sayid); + linker.SetProxyItemID(SAYLINK_ITEM_ID); + if (silent) + linker.SetProxyAugment2ID(sayid); + else + linker.SetProxyAugment1ID(sayid); linker.SetProxyText(LinkName); auto say_link = linker.GenerateLink(); @@ -3164,4 +3163,4 @@ void QuestManager::UpdateZoneHeader(std::string type, std::string value) { memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(0, outapp); safe_delete(outapp); -} \ No newline at end of file +} diff --git a/zone/zone.cpp b/zone/zone.cpp index b3a6fc1ca..08a98fb10 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -292,7 +292,7 @@ bool Zone::LoadGroundSpawns() { char* name=0; uint32 gsnumber=0; for(gsindex=0;gsindex<50;gsindex++){ - if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item<500000){ + if(groundspawn.spawn[gsindex].item>0 && groundspawn.spawn[gsindex].item