From ec8c46abfe3775bf5e08cff432b4bf28886b8779 Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 24 Sep 2014 19:46:53 -0700 Subject: [PATCH 1/4] I keep seeing a crash due to an invalidated iter during mob delete every few days, seeing if this fixes it. --- zone/entity.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/zone/entity.cpp b/zone/entity.cpp index 8d21262c6..243bf99f5 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -497,7 +497,6 @@ void EntityList::MobProcess() if (!it->second->Process()) { Mob *mob = it->second; uint16 tempid = it->first; - ++it; // we don't erase here because the destructor will if (mob->IsNPC()) { entity_list.RemoveNPC(mob->CastToNPC()->GetID()); } else if (mob->IsMerc()) { @@ -525,7 +524,12 @@ void EntityList::MobProcess() } entity_list.RemoveClient(mob->GetID()); } - entity_list.RemoveMob(tempid); + + if(entity_list.RemoveMob(tempid)) { + it = mob_list.begin(); + } else { + ++it; + } } else { ++it; } From a73ac9cfe85beef94c94e0f578e2bbe1718ea936 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 24 Sep 2014 23:35:10 -0400 Subject: [PATCH 2/4] Added helper function bool EQEmu::IsTradeskill(uint32 skill) Returns true if you pass a tradeskill to it, otherwise false --- changelog.txt | 1 + common/CMakeLists.txt | 3 ++- common/skills.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ common/skills.h | 5 +++++ world/client.cpp | 23 +++++------------------ 5 files changed, 53 insertions(+), 19 deletions(-) create mode 100644 common/skills.cpp diff --git a/changelog.txt b/changelog.txt index f5ada28d5..fdc882932 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 09/24/2014 == Uleat: Re-ordered server opcodes and handlers to give them some predictability of location (I need this for the inventory re-enumeration.) +demonstar55: Added helper function bool EQEmu::IsTradeskill(uint32 skill) == 09/22/2014 == Akkadius: #resetaa now covers the function of #resetaa and #refundaa diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 6047e2712..65d5e9caf 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -55,8 +55,9 @@ SET(common_sources rulesys.cpp serverinfo.cpp shareddb.cpp + skills.cpp spdat.cpp - string_util.cpp + string_util.cpp struct_strategy.cpp tcp_connection.cpp tcp_server.cpp diff --git a/common/skills.cpp b/common/skills.cpp new file mode 100644 index 000000000..96b87c4a9 --- /dev/null +++ b/common/skills.cpp @@ -0,0 +1,40 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "types.h" +#include "skills.h" + +bool EQEmu::IsTradeskill(uint32 skill) +{ + switch (skill) { + case SkillFishing: + case SkillMakePoison: + case SkillTinkering: + case SkillResearch: + case SkillAlchemy: + case SkillBaking: + case SkillTailoring: + case SkillBlacksmithing: + case SkillFletching: + case SkillBrewing: + case SkillPottery: + case SkillJewelryMaking: + return true; + default: + return false; + } +} diff --git a/common/skills.h b/common/skills.h index 88b05967f..15876cedc 100644 --- a/common/skills.h +++ b/common/skills.h @@ -260,4 +260,9 @@ typedef enum { #define HIGHEST_SKILL FRENZY */ +// for skill related helper functions +namespace EQEmu { + bool IsTradeskill(uint32 skill); +} + #endif diff --git a/world/client.cpp b/world/client.cpp index ca90b1f46..9120ce70b 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1790,28 +1790,15 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc) return Charerrors == 0; } -void Client::SetClassStartingSkills( PlayerProfile_Struct *pp ) +void Client::SetClassStartingSkills(PlayerProfile_Struct *pp) { - for(uint32 i = 0; i <= HIGHEST_SKILL; ++i) { - if(pp->skills[i] == 0) { - if(i >= SkillSpecializeAbjure && i <= SkillSpecializeEvocation) { + for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) { + if (pp->skills[i] == 0) { + if (i >= SkillSpecializeAbjure && i <= SkillSpecializeEvocation) continue; - } - if(i == SkillMakePoison || - i == SkillTinkering || - i == SkillResearch || - i == SkillAlchemy || - i == SkillBaking || - i == SkillTailoring || - i == SkillBlacksmithing || - i == SkillFletching || - i == SkillBrewing || - i == SkillPottery || - i == SkillJewelryMaking || - i == SkillBegging) { + if (EQEmu::IsTradeskill(i) || i == SkillBegging) continue; - } pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1); } From c0cbbf3a656f7d1f5b2ca259bad1993b218673f6 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Thu, 25 Sep 2014 03:14:43 -0400 Subject: [PATCH 3/4] World needs to load skill cap data for char creation --- world/net.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/world/net.cpp b/world/net.cpp index 3c4ab53c3..c7340333e 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -284,9 +284,11 @@ int main(int argc, char** argv) { database.ClearRaid(); database.ClearRaidDetails(); _log(WORLD__INIT, "Loading items.."); - if (!database.LoadItems()) { + if (!database.LoadItems()) _log(WORLD__INIT_ERR, "Error: Could not load item data. But ignoring"); - } + _log(WORLD__INIT, "Loading skill caps.."); + if (!database.LoadSkillCaps()) + _log(WORLD__INIT_ERR, "Error: Could not load skill cap data. But ignoring"); _log(WORLD__INIT, "Loading guilds.."); guild_mgr.LoadGuilds(); //rules: From aa021addc1928d8746ab4d96033fa724303c5433 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 25 Sep 2014 03:59:59 -0700 Subject: [PATCH 4/4] Fix for potion belt name loading. --- common/CMakeLists.txt | 1 + common/data_verification.h | 5 +++++ common/database.h | 6 ------ tests/data_verification_test.h | 14 ++++++++++++++ zone/client_packet.cpp | 7 +++++++ zone/lua_packet.cpp | 1 + zone/zonedb.cpp | 10 ++++++++-- 7 files changed, 36 insertions(+), 8 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 65d5e9caf..ac42f5e4e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -103,6 +103,7 @@ SET(common_headers crash.h crc16.h crc32.h + data_verification.h database.h dbcore.h debug.h diff --git a/common/data_verification.h b/common/data_verification.h index d42f72aac..9da85a579 100644 --- a/common/data_verification.h +++ b/common/data_verification.h @@ -38,6 +38,11 @@ T ClampUpper(const T& value, const T& upper) { return std::min(value, upper); } +template +bool ValueWithin(const T& value, const T& lower, const T& upper) { + return value >= lower && value <= upper; +} + } #endif diff --git a/common/database.h b/common/database.h index c4d3af336..a24198ca4 100644 --- a/common/database.h +++ b/common/database.h @@ -26,12 +26,6 @@ #include "dbcore.h" #include "linked_list.h" #include "eq_packet_structs.h" -/*#include "eq_stream.h" -#include "guilds.h" -#include "misc_functions.h" -#include "mutex.h" -#include "item.h" -#include "extprofile.h"*/ #include #include #include diff --git a/tests/data_verification_test.h b/tests/data_verification_test.h index 1a151c7fa..b9eb210fa 100644 --- a/tests/data_verification_test.h +++ b/tests/data_verification_test.h @@ -29,6 +29,7 @@ public: TEST_ADD(DataVerificationTest::Clamp); TEST_ADD(DataVerificationTest::ClampUpper); TEST_ADD(DataVerificationTest::ClampLower); + TEST_ADD(DataVerificationTest::ValueWithin); } ~DataVerificationTest() { @@ -89,6 +90,19 @@ public: TEST_ASSERT_EQUALS(vi1, 500); TEST_ASSERT_EQUALS(vi2, 750); } + + void ValueWithin() { + float value_f = 500.0f; + int value_i = 500; + + TEST_ASSERT(EQEmu::ValueWithin(value_f, 0.0f, 1000.0f)); + TEST_ASSERT(!EQEmu::ValueWithin(value_f, 0.0f, 400.0f)); + TEST_ASSERT(!EQEmu::ValueWithin(value_f, 600.0f, 900.0f)); + + TEST_ASSERT(EQEmu::ValueWithin(value_i, 0, 1000)); + TEST_ASSERT(!EQEmu::ValueWithin(value_i, 0, 400)); + TEST_ASSERT(!EQEmu::ValueWithin(value_i, 600, 900)); + } }; #endif diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 62e31c075..0061efff4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -48,6 +48,7 @@ #include "../common/guilds.h" #include "../common/rulesys.h" #include "../common/spdat.h" +#include "../common/data_verification.h" #include "petitions.h" #include "npc_ai.h" #include "../common/skills.h" @@ -10490,7 +10491,13 @@ void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app) DumpPacket(app); return; } + MovePotionToBelt_Struct *mptbs = (MovePotionToBelt_Struct*)app->pBuffer; + if(!EQEmu::ValueWithin(mptbs->SlotNumber, 0U, 3U)) { + LogFile->write(EQEMuLog::Debug, "Client::Handle_OP_PotionBelt mptbs->SlotNumber out of range."); + return; + } + if (mptbs->Action == 0) { const Item_Struct *BaseItem = database.GetItem(mptbs->ItemID); if (BaseItem) { diff --git a/zone/lua_packet.cpp b/zone/lua_packet.cpp index deff0f0f2..e16a85c6d 100644 --- a/zone/lua_packet.cpp +++ b/zone/lua_packet.cpp @@ -301,6 +301,7 @@ luabind::scope lua_register_packet() { .def("ReadFixedLengthString", &Lua_Packet::ReadFixedLengthString); } +//TODO: Reorder these to match emu_oplist.h again luabind::scope lua_register_packet_opcodes() { return luabind::class_("Opcode") .enum_("constants") diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 3728e3144..b49837704 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1178,8 +1178,14 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc } for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); /* Potion belt slot number */ - pp->potionbelt.items[i].item_id = atoi(row[1]); - pp->potionbelt.items[i].icon = atoi(row[2]); + uint32 item_id = atoi(row[1]); + const Item_Struct *item = database.GetItem(item_id); + + if(item) { + pp->potionbelt.items[i].item_id = item_id; + pp->potionbelt.items[i].icon = atoi(row[2]); + strncpy(pp->potionbelt.items[i].item_name, item->Name, 64); + } } return true; }