From 3a20bbd834acba48d361119dad98b1b057c1db51 Mon Sep 17 00:00:00 2001 From: Luke Wahlmeier Date: Tue, 5 Jan 2016 14:16:29 -0700 Subject: [PATCH 1/5] fixed else error case for eqtime table --- common/database.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 932aa4229..b8889fa06 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -2185,8 +2185,7 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime) std::string query = StringFormat("SELECT minute,hour,day,month,year,realtime FROM eqtime limit 1"); auto results = QueryDatabase(query); - if (!results.Success() || results.RowCount() == 0) - { + if (!results.Success() || results.RowCount() == 0){ Log.Out(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults."); eqTime.minute = 0; eqTime.hour = 9; @@ -2195,15 +2194,16 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime) eqTime.year = 3100; realtime = time(0); } + else{ + auto row = results.begin(); - auto row = results.begin(); - - eqTime.minute = atoi(row[0]); - eqTime.hour = atoi(row[1]); - eqTime.day = atoi(row[2]); - eqTime.month = atoi(row[3]); - eqTime.year = atoi(row[4]); - realtime = atoi(row[5]); + eqTime.minute = atoi(row[0]); + eqTime.hour = atoi(row[1]); + eqTime.day = atoi(row[2]); + eqTime.month = atoi(row[3]); + eqTime.year = atoi(row[4]); + realtime = atoi(row[5]); + } return eqTime; } @@ -2215,4 +2215,4 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year return results.Success(); -} \ No newline at end of file +} From 04b7ba7a1d0ff983e0de2d2e6800e3ec7e334015 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 20 Jan 2016 21:54:18 -0500 Subject: [PATCH 2/5] Added proxy accessors for all TextLink fields --- zone/client.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++------- zone/client.h | 30 +++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index ceedf19d7..3fab7671e 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -8423,7 +8423,19 @@ void Client::TextLink::Reset() m_ItemData = nullptr; m_LootData = nullptr; m_ItemInst = nullptr; + m_Proxy_unknown_1 = NOT_USED; m_ProxyItemID = NOT_USED; + m_ProxyAugment1ID = NOT_USED; + m_ProxyAugment2ID = NOT_USED; + m_ProxyAugment3ID = NOT_USED; + m_ProxyAugment4ID = NOT_USED; + m_ProxyAugment5ID = NOT_USED; + m_ProxyAugment6ID = NOT_USED; + m_ProxyIsEvolving = NOT_USED; + m_ProxyEvolveGroup = NOT_USED; + m_ProxyEvolveLevel = NOT_USED; + m_ProxyOrnamentIcon = NOT_USED; + m_ProxyHash = NOT_USED; m_ProxyText = nullptr; m_TaskUse = false; m_Link.clear(); @@ -8439,8 +8451,8 @@ void Client::TextLink::generate_body() RoF2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X" (56) RoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (55) - SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50) - 6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45) + SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50) + 6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45) */ memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct)); @@ -8492,13 +8504,36 @@ void Client::TextLink::generate_body() break; } - if (m_ProxyItemID != NOT_USED) { + if (m_Proxy_unknown_1) + m_LinkBodyStruct.unknown_1 = m_Proxy_unknown_1; + if (m_ProxyItemID) m_LinkBodyStruct.item_id = m_ProxyItemID; - } + if (m_ProxyAugment1ID) + m_LinkBodyStruct.augment_1 = m_ProxyAugment1ID; + if (m_ProxyAugment2ID) + m_LinkBodyStruct.augment_2 = m_ProxyAugment2ID; + if (m_ProxyAugment3ID) + m_LinkBodyStruct.augment_3 = m_ProxyAugment3ID; + if (m_ProxyAugment4ID) + m_LinkBodyStruct.augment_4 = m_ProxyAugment4ID; + if (m_ProxyAugment5ID) + m_LinkBodyStruct.augment_5 = m_ProxyAugment5ID; + if (m_ProxyAugment6ID) + m_LinkBodyStruct.augment_6 = m_ProxyAugment6ID; + if (m_ProxyIsEvolving) + m_LinkBodyStruct.is_evolving = m_ProxyIsEvolving; + if (m_ProxyEvolveGroup) + m_LinkBodyStruct.evolve_group = m_ProxyEvolveGroup; + if (m_ProxyEvolveLevel) + m_LinkBodyStruct.evolve_level = m_ProxyEvolveLevel; + if (m_ProxyOrnamentIcon) + m_LinkBodyStruct.ornament_icon = m_ProxyOrnamentIcon; + if (m_ProxyHash) + m_LinkBodyStruct.hash = m_ProxyHash; - if (m_TaskUse) { + + if (m_TaskUse) m_LinkBodyStruct.hash = 0x14505DC2; - } m_LinkBody = StringFormat( "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X", @@ -8515,7 +8550,7 @@ void Client::TextLink::generate_body() (0xFF & m_LinkBodyStruct.evolve_level), (0x000FFFFF & m_LinkBodyStruct.ornament_icon), (0xFFFFFFFF & m_LinkBodyStruct.hash) - ); + ); } void Client::TextLink::generate_text() diff --git a/zone/client.h b/zone/client.h index 24522f63d..d9f2f0dfc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -831,7 +831,22 @@ public: void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; } void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; } void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; } - void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to + + // mainly for saylinks..but, not limited to + void SetProxyUnknown1(uint8 proxyUnknown1) { m_Proxy_unknown_1 = proxyUnknown1; } + void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } + void SetProxyAugment1ID(uint32 proxyAugmentID) { m_ProxyAugment1ID = proxyAugmentID; } + void SetProxyAugment2ID(uint32 proxyAugmentID) { m_ProxyAugment2ID = proxyAugmentID; } + void SetProxyAugment3ID(uint32 proxyAugmentID) { m_ProxyAugment3ID = proxyAugmentID; } + void SetProxyAugment4ID(uint32 proxyAugmentID) { m_ProxyAugment4ID = proxyAugmentID; } + void SetProxyAugment5ID(uint32 proxyAugmentID) { m_ProxyAugment5ID = proxyAugmentID; } + void SetProxyAugment6ID(uint32 proxyAugmentID) { m_ProxyAugment6ID = proxyAugmentID; } + void SetProxyIsEvolving(uint8 proxyIsEvolving) { m_ProxyIsEvolving = proxyIsEvolving; } + void SetProxyEvolveGroup(uint32 proxyEvolveGroup) { m_ProxyEvolveGroup = proxyEvolveGroup; } + void SetProxyEvolveLevel(uint8 proxyEvolveLevel) { m_ProxyEvolveLevel = proxyEvolveLevel; } + void SetProxyOrnamentIcon(uint32 proxyOrnamentIcon) { m_ProxyOrnamentIcon = proxyOrnamentIcon; } + void SetProxyHash(int proxyHash) { m_ProxyHash = proxyHash; } + void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use void SetTaskUse() { m_TaskUse = true; } @@ -855,7 +870,20 @@ public: const Item_Struct* m_ItemData; const ServerLootItem_Struct* m_LootData; const ItemInst* m_ItemInst; + + uint8 m_Proxy_unknown_1; uint32 m_ProxyItemID; + uint32 m_ProxyAugment1ID; + uint32 m_ProxyAugment2ID; + uint32 m_ProxyAugment3ID; + uint32 m_ProxyAugment4ID; + uint32 m_ProxyAugment5ID; + uint32 m_ProxyAugment6ID; + uint8 m_ProxyIsEvolving; + uint32 m_ProxyEvolveGroup; + uint8 m_ProxyEvolveLevel; + uint32 m_ProxyOrnamentIcon; + int m_ProxyHash; const char* m_ProxyText; bool m_TaskUse; TextLinkBody_Struct m_LinkBodyStruct; From d86307c7203eb55e2d341c960c823f91109f804f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 20 Jan 2016 22:31:35 -0500 Subject: [PATCH 3/5] Rework say links We now consume 1 item ID for say links, this means you will be able to create more items! We used ID 0xFFFFF for this, which is the max ID an item can be in the item links. You have the rest to play with! Normal say links pass the ID in the first aug slot and silent say links in the second aug slot. This means we can have MANY more say links as well! --- common/features.h | 3 + zone/bot.cpp | 5 +- zone/client_packet.cpp | 137 ++++++++++++++++++----------------------- zone/questmgr.cpp | 13 ++-- zone/zone.cpp | 2 +- 5 files changed, 72 insertions(+), 88 deletions(-) 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 Date: Thu, 21 Jan 2016 11:53:14 -0500 Subject: [PATCH 4/5] If an error occurs (!results.Success()) in loadlootdrops the method continues processing instead of exiting. --- common/shareddb.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index f82d54fad..97f2f69ee 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1920,6 +1920,7 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) { "ON lootdrop.id = lootdrop_entries.lootdrop_id ORDER BY lootdrop_id"; auto results = QueryDatabase(query); if (!results.Success()) { + return; } uint32 current_id = 0; From c4cdf811e3cbbf009d4d3b2ad6af7505e52f9def Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 22 Jan 2016 13:42:14 -0600 Subject: [PATCH 5/5] Fix for zone controller spawn events where npc isn't inserted into entity list yet --- zone/entity.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/zone/entity.cpp b/zone/entity.cpp index 92fefb2ec..a79d01609 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -644,15 +644,6 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0); - /* Zone controller process EVENT_SPAWN_ZONE */ - if (RuleB(Zone, UseZoneController)) { - if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){ - char data_pass[100] = { 0 }; - snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID()); - parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0); - } - } - uint16 emoteid = npc->GetEmoteID(); if (emoteid != 0) npc->DoNPCEmote(ONSPAWN, emoteid); @@ -678,6 +669,16 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue) npc_list.insert(std::pair(npc->GetID(), npc)); mob_list.insert(std::pair(npc->GetID(), npc)); + + /* Zone controller process EVENT_SPAWN_ZONE */ + if (RuleB(Zone, UseZoneController)) { + if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){ + char data_pass[100] = { 0 }; + snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID()); + parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0); + } + } + } void EntityList::AddMerc(Merc *merc, bool SendSpawnPacket, bool dontqueue)