diff --git a/common/item.cpp b/common/item.cpp index 3e8be66ca..7c871e630 100644 --- a/common/item.cpp +++ b/common/item.cpp @@ -1440,7 +1440,11 @@ int16 Inventory::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup) // ItemInst::ItemInst(const Item_Struct* item, int16 charges) { m_use_type = ItemInstNormal; - m_item = item; + if(item) { + m_item = new Item_Struct(*item); + } else { + m_item = nullptr; + } m_charges = charges; m_price = 0; m_attuned = false; @@ -1467,6 +1471,13 @@ ItemInst::ItemInst(const Item_Struct* item, int16 charges) { ItemInst::ItemInst(SharedDatabase *db, uint32 item_id, int16 charges) { m_use_type = ItemInstNormal; m_item = db->GetItem(item_id); + if(m_item) { + m_item = new Item_Struct(*m_item); + } + else { + m_item = nullptr; + } + m_charges = charges; m_price = 0; m_merchantslot = 0; @@ -1515,7 +1526,11 @@ ItemInst::ItemInst(ItemInstTypes use_type) { ItemInst::ItemInst(const ItemInst& copy) { m_use_type=copy.m_use_type; - m_item=copy.m_item; + if(copy.m_item) + m_item = new Item_Struct(*copy.m_item); + else + m_item = nullptr; + m_charges=copy.m_charges; m_price=copy.m_price; m_color=copy.m_color; @@ -1568,6 +1583,7 @@ ItemInst::ItemInst(const ItemInst& copy) ItemInst::~ItemInst() { Clear(); + safe_delete(m_item); safe_delete(m_scaledItem); safe_delete(m_evolveInfo); } diff --git a/common/servertalk.h b/common/servertalk.h index 6693e86bc..0945d500d 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -84,6 +84,7 @@ #define ServerOP_QGlobalDelete 0x0064 #define ServerOP_DepopPlayerCorpse 0x0065 #define ServerOP_RequestTellQueue 0x0066 // client asks for it's tell queues +#define ServerOP_ChangeSharedMem 0x0067 #define ServerOP_RaidAdd 0x0100 //in use #define ServerOP_RaidRemove 0x0101 //in use @@ -545,6 +546,7 @@ struct ServerLSPeerConnect { struct ServerConnectInfo { char address[250]; + char local_address[250]; uint16 port; }; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index c9106ea04..7301346c9 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -16,29 +16,16 @@ #include "string_util.h" SharedDatabase::SharedDatabase() -: Database(), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), faction_mmf(nullptr), faction_hash(nullptr), - loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), loot_drop_hash(nullptr), base_data_mmf(nullptr) +: Database() { } SharedDatabase::SharedDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port) -: Database(host, user, passwd, database, port), skill_caps_mmf(nullptr), items_mmf(nullptr), items_hash(nullptr), - faction_mmf(nullptr), faction_hash(nullptr), loot_table_mmf(nullptr), loot_table_hash(nullptr), loot_drop_mmf(nullptr), - loot_drop_hash(nullptr), base_data_mmf(nullptr) +: Database(host, user, passwd, database, port) { } SharedDatabase::~SharedDatabase() { - safe_delete(skill_caps_mmf); - safe_delete(items_mmf); - safe_delete(items_hash); - safe_delete(faction_mmf); - safe_delete(faction_hash); - safe_delete(loot_table_mmf); - safe_delete(loot_drop_mmf); - safe_delete(loot_table_hash); - safe_delete(loot_drop_hash); - safe_delete(base_data_mmf); } bool SharedDatabase::SetHideMe(uint32 account_id, uint8 hideme) @@ -797,28 +784,15 @@ void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id) item_count = atoi(row[1]); } -bool SharedDatabase::LoadItems() { - if(items_mmf) { - return true; - } +bool SharedDatabase::LoadItems(const std::string &prefix) { + items_mmf.reset(nullptr); try { EQEmu::IPCMutex mutex("items"); mutex.Lock(); - items_mmf = new EQEmu::MemoryMappedFile("shared/items"); - - int32 items = -1; - uint32 max_item = 0; - GetItemsCount(items, max_item); - if(items == -1) { - EQ_EXCEPT("SharedDatabase", "Database returned no result"); - } - uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); - if(items_mmf->Size() != size) { - EQ_EXCEPT("SharedDatabase", "Couldn't load items because items_mmf->Size() != size"); - } - - items_hash = new EQEmu::FixedMemoryHashSet(reinterpret_cast(items_mmf->Get()), size); + std::string file_name = std::string("shared/") + prefix + std::string("items"); + items_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name)); + items_hash = std::unique_ptr>(new EQEmu::FixedMemoryHashSet(reinterpret_cast(items_mmf->Get()), items_mmf->Size())); mutex.Unlock(); } catch(std::exception& ex) { Log.Out(Logs::General, Logs::Error, "Error Loading Items: %s", ex.what()); @@ -1229,27 +1203,16 @@ void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_co } -bool SharedDatabase::LoadNPCFactionLists() { - if(faction_hash) { - return true; - } +bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) { + faction_mmf.reset(nullptr); + faction_hash.reset(nullptr); try { EQEmu::IPCMutex mutex("faction"); mutex.Lock(); - faction_mmf = new EQEmu::MemoryMappedFile("shared/faction"); - - uint32 list_count = 0; - uint32 max_lists = 0; - GetFactionListInfo(list_count, max_lists); - uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size( - list_count, max_lists)); - - if(faction_mmf->Size() != size) { - EQ_EXCEPT("SharedDatabase", "Couldn't load npc factions because faction_mmf->Size() != size"); - } - - faction_hash = new EQEmu::FixedMemoryHashSet(reinterpret_cast(faction_mmf->Get()), size); + std::string file_name = std::string("shared/") + prefix + std::string("faction"); + faction_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name)); + faction_hash = std::unique_ptr>(new EQEmu::FixedMemoryHashSet(reinterpret_cast(faction_mmf->Get()), faction_mmf->Size())); mutex.Unlock(); } catch(std::exception& ex) { Log.Out(Logs::General, Logs::Error, "Error Loading npc factions: %s", ex.what()); @@ -1378,9 +1341,8 @@ bool SharedDatabase::GetCommandSettings(std::map &commands) { return true; } -bool SharedDatabase::LoadSkillCaps() { - if(skill_caps_mmf) - return true; +bool SharedDatabase::LoadSkillCaps(const std::string &prefix) { + skill_caps_mmf.reset(nullptr); uint32 class_count = PLAYER_CLASS_COUNT; uint32 skill_count = HIGHEST_SKILL + 1; @@ -1390,11 +1352,8 @@ bool SharedDatabase::LoadSkillCaps() { try { EQEmu::IPCMutex mutex("skill_caps"); mutex.Lock(); - skill_caps_mmf = new EQEmu::MemoryMappedFile("shared/skill_caps"); - if(skill_caps_mmf->Size() != size) { - EQ_EXCEPT("SharedDatabase", "Unable to load skill caps: skill_caps_mmf->Size() != size"); - } - + std::string file_name = std::string("shared/") + prefix + std::string("skill_caps"); + skill_caps_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name)); mutex.Unlock(); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "Error loading skill caps: %s", ex.what()); @@ -1542,8 +1501,29 @@ int SharedDatabase::GetMaxSpellID() { return atoi(row[0]); } +bool SharedDatabase::LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp) { + spells_mmf.reset(nullptr); + + try { + EQEmu::IPCMutex mutex("spells"); + mutex.Lock(); + + std::string file_name = std::string("shared/") + prefix + std::string("spells"); + spells_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name)); + *records = *reinterpret_cast(spells_mmf->Get()); + *sp = reinterpret_cast((char*)spells_mmf->Get() + 4); + mutex.Unlock(); + } + catch(std::exception& ex) { + Log.Out(Logs::General, Logs::Error, "Error Loading Spells: %s", ex.what()); + return false; + } + return true; +} + void SharedDatabase::LoadSpells(void *data, int max_spells) { - SPDat_Spell_Struct *sp = reinterpret_cast(data); + *(uint32*)data = max_spells; + SPDat_Spell_Struct *sp = reinterpret_cast((char*)data + sizeof(uint32)); const std::string query = "SELECT * FROM spells_new ORDER BY id ASC"; auto results = QueryDatabase(query); @@ -1720,25 +1700,15 @@ int SharedDatabase::GetMaxBaseDataLevel() { return atoi(row[0]); } -bool SharedDatabase::LoadBaseData() { - if(base_data_mmf) { - return true; - } +bool SharedDatabase::LoadBaseData(const std::string &prefix) { + base_data_mmf.reset(nullptr); try { EQEmu::IPCMutex mutex("base_data"); mutex.Lock(); - base_data_mmf = new EQEmu::MemoryMappedFile("shared/base_data"); - - int size = 16 * (GetMaxBaseDataLevel() + 1) * sizeof(BaseDataStruct); - if(size == 0) { - EQ_EXCEPT("SharedDatabase", "Base Data size is zero"); - } - - if(base_data_mmf->Size() != size) { - EQ_EXCEPT("SharedDatabase", "Couldn't load base data because base_data_mmf->Size() != size"); - } + std::string file_name = std::string("shared/") + prefix + std::string("base_data"); + base_data_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name)); mutex.Unlock(); } catch(std::exception& ex) { Log.Out(Logs::General, Logs::Error, "Error Loading Base Data: %s", ex.what()); @@ -1794,7 +1764,6 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) { bd->mana_factor = atof(row[8]); bd->endurance_factor = atof(row[9]); } - } const BaseDataStruct* SharedDatabase::GetBaseData(int lvl, int cl) { @@ -1968,21 +1937,23 @@ void SharedDatabase::LoadLootDrops(void *data, uint32 size) { } -bool SharedDatabase::LoadLoot() { - if(loot_table_mmf || loot_drop_mmf) - return true; +bool SharedDatabase::LoadLoot(const std::string &prefix) { + loot_table_mmf.reset(nullptr); + loot_drop_mmf.reset(nullptr); try { EQEmu::IPCMutex mutex("loot"); mutex.Lock(); - loot_table_mmf = new EQEmu::MemoryMappedFile("shared/loot_table"); - loot_table_hash = new EQEmu::FixedMemoryVariableHashSet( + std::string file_name_lt = std::string("shared/") + prefix + std::string("loot_table"); + loot_table_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name_lt)); + loot_table_hash = std::unique_ptr>(new EQEmu::FixedMemoryVariableHashSet( reinterpret_cast(loot_table_mmf->Get()), - loot_table_mmf->Size()); - loot_drop_mmf = new EQEmu::MemoryMappedFile("shared/loot_drop"); - loot_drop_hash = new EQEmu::FixedMemoryVariableHashSet( + loot_table_mmf->Size())); + std::string file_name_ld = std::string("shared/") + prefix + std::string("loot_drop"); + loot_drop_mmf = std::unique_ptr(new EQEmu::MemoryMappedFile(file_name_ld)); + loot_drop_hash = std::unique_ptr>(new EQEmu::FixedMemoryVariableHashSet( reinterpret_cast(loot_drop_mmf->Get()), - loot_drop_mmf->Size()); + loot_drop_mmf->Size())); mutex.Unlock(); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "Error loading loot: %s", ex.what()); diff --git a/common/shareddb.h b/common/shareddb.h index aef325380..923e5b775 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -12,6 +12,7 @@ #include #include +#include class EvolveInfo; class Inventory; @@ -92,7 +93,7 @@ class SharedDatabase : public Database //items void GetItemsCount(int32 &item_count, uint32 &max_id); void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id); - bool LoadItems(); + bool LoadItems(const std::string &prefix); const Item_Struct* IterateItems(uint32* id); const Item_Struct* GetItem(uint32 id); const EvolveInfo* GetEvolveInfo(uint32 loregroup); @@ -101,43 +102,45 @@ class SharedDatabase : public Database void GetFactionListInfo(uint32 &list_count, uint32 &max_lists); const NPCFactionList* GetNPCFactionEntry(uint32 id); void LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists); - bool LoadNPCFactionLists(); + bool LoadNPCFactionLists(const std::string &prefix); //loot void GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries); void GetLootDropInfo(uint32 &loot_drop_count, uint32 &max_loot_drop, uint32 &loot_drop_entries); void LoadLootTables(void *data, uint32 size); void LoadLootDrops(void *data, uint32 size); - bool LoadLoot(); + bool LoadLoot(const std::string &prefix); const LootTable_Struct* GetLootTable(uint32 loottable_id); const LootDrop_Struct* GetLootDrop(uint32 lootdrop_id); void LoadSkillCaps(void *data); - bool LoadSkillCaps(); + bool LoadSkillCaps(const std::string &prefix); uint16 GetSkillCap(uint8 Class_, SkillUseTypes Skill, uint8 Level); uint8 GetTrainLevel(uint8 Class_, SkillUseTypes Skill, uint8 Level); int GetMaxSpellID(); + bool LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp); void LoadSpells(void *data, int max_spells); void LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID); int GetMaxBaseDataLevel(); - bool LoadBaseData(); + bool LoadBaseData(const std::string &prefix); void LoadBaseData(void *data, int max_level); const BaseDataStruct* GetBaseData(int lvl, int cl); protected: - EQEmu::MemoryMappedFile *skill_caps_mmf; - EQEmu::MemoryMappedFile *items_mmf; - EQEmu::FixedMemoryHashSet *items_hash; - EQEmu::MemoryMappedFile *faction_mmf; - EQEmu::FixedMemoryHashSet *faction_hash; - EQEmu::MemoryMappedFile *loot_table_mmf; - EQEmu::FixedMemoryVariableHashSet *loot_table_hash; - EQEmu::MemoryMappedFile *loot_drop_mmf; - EQEmu::FixedMemoryVariableHashSet *loot_drop_hash; - EQEmu::MemoryMappedFile *base_data_mmf; + std::unique_ptr skill_caps_mmf; + std::unique_ptr items_mmf; + std::unique_ptr> items_hash; + std::unique_ptr faction_mmf; + std::unique_ptr> faction_hash; + std::unique_ptr loot_table_mmf; + std::unique_ptr> loot_table_hash; + std::unique_ptr loot_drop_mmf; + std::unique_ptr> loot_drop_hash; + std::unique_ptr base_data_mmf; + std::unique_ptr spells_mmf; }; #endif /*SHAREDDB_H_*/ diff --git a/shared_memory/base_data.cpp b/shared_memory/base_data.cpp index 086256cda..e82c5a2c1 100644 --- a/shared_memory/base_data.cpp +++ b/shared_memory/base_data.cpp @@ -23,7 +23,7 @@ #include "../common/memory_mapped_file.h" #include "../common/eqemu_exception.h" -void LoadBaseData(SharedDatabase *database) { +void LoadBaseData(SharedDatabase *database, const std::string &prefix) { EQEmu::IPCMutex mutex("base_data"); mutex.Lock(); int records = (database->GetMaxBaseDataLevel() + 1); @@ -32,11 +32,12 @@ void LoadBaseData(SharedDatabase *database) { } uint32 size = records * 16 * sizeof(BaseDataStruct); - EQEmu::MemoryMappedFile mmf("shared/base_data", size); + + std::string file_name = std::string("shared/") + prefix + std::string("base_data"); + EQEmu::MemoryMappedFile mmf(file_name, size); mmf.ZeroFile(); void *ptr = mmf.Get(); database->LoadBaseData(ptr, records); mutex.Unlock(); } - diff --git a/shared_memory/base_data.h b/shared_memory/base_data.h index c1f6c87ea..afa799eea 100644 --- a/shared_memory/base_data.h +++ b/shared_memory/base_data.h @@ -19,7 +19,8 @@ #ifndef __EQEMU_SHARED_MEMORY_BASE_DATA_H #define __EQEMU_SHARED_MEMORY_BASE_DATA_H +#include class SharedDatabase; -void LoadBaseData(SharedDatabase *database); +void LoadBaseData(SharedDatabase *database, const std::string &prefix); #endif diff --git a/shared_memory/items.cpp b/shared_memory/items.cpp index 48b81b6fc..02a102a8f 100644 --- a/shared_memory/items.cpp +++ b/shared_memory/items.cpp @@ -24,7 +24,7 @@ #include "../common/eqemu_exception.h" #include "../common/item_struct.h" -void LoadItems(SharedDatabase *database) { +void LoadItems(SharedDatabase *database, const std::string &prefix) { EQEmu::IPCMutex mutex("items"); mutex.Lock(); @@ -36,7 +36,9 @@ void LoadItems(SharedDatabase *database) { } uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(items, max_item)); - EQEmu::MemoryMappedFile mmf("shared/items", size); + + std::string file_name = std::string("shared/") + prefix + std::string("items"); + EQEmu::MemoryMappedFile mmf(file_name, size); mmf.ZeroFile(); void *ptr = mmf.Get(); diff --git a/shared_memory/items.h b/shared_memory/items.h index 21702eb50..cff9794fd 100644 --- a/shared_memory/items.h +++ b/shared_memory/items.h @@ -19,7 +19,9 @@ #ifndef __EQEMU_SHARED_MEMORY_ITEMS_H #define __EQEMU_SHARED_MEMORY_ITEMS_H +#include + class SharedDatabase; -void LoadItems(SharedDatabase *database); +void LoadItems(SharedDatabase *database, const std::string &prefix); #endif diff --git a/shared_memory/loot.cpp b/shared_memory/loot.cpp index 66982c05a..956383cd3 100644 --- a/shared_memory/loot.cpp +++ b/shared_memory/loot.cpp @@ -25,7 +25,7 @@ #include "../common/fixed_memory_variable_hash_set.h" #include "../common/loottable.h" -void LoadLoot(SharedDatabase *database) { +void LoadLoot(SharedDatabase *database, const std::string &prefix) { EQEmu::IPCMutex mutex("loot"); mutex.Lock(); @@ -44,8 +44,11 @@ void LoadLoot(SharedDatabase *database) { (loot_drop_count * sizeof(LootDrop_Struct)) + //loot table headers (loot_drop_entries_count * sizeof(LootDropEntries_Struct)); //number of loot table entries - EQEmu::MemoryMappedFile mmf_loot_table("shared/loot_table", loot_table_size); - EQEmu::MemoryMappedFile mmf_loot_drop("shared/loot_drop", loot_drop_size); + std::string file_name_lt = std::string("shared/") + prefix + std::string("loot_table"); + std::string file_name_ld = std::string("shared/") + prefix + std::string("loot_drop"); + + EQEmu::MemoryMappedFile mmf_loot_table(file_name_lt, loot_table_size); + EQEmu::MemoryMappedFile mmf_loot_drop(file_name_ld, loot_drop_size); mmf_loot_table.ZeroFile(); mmf_loot_drop.ZeroFile(); diff --git a/shared_memory/loot.h b/shared_memory/loot.h index df97ad321..27e812185 100644 --- a/shared_memory/loot.h +++ b/shared_memory/loot.h @@ -19,7 +19,9 @@ #ifndef __EQEMU_SHARED_MEMORY_LOOT_H #define __EQEMU_SHARED_MEMORY_LOOT_H +#include + class SharedDatabase; -void LoadLoot(SharedDatabase *database); +void LoadLoot(SharedDatabase *database, const std::string &prefix); #endif diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index 2623ccd26..3d47f217f 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -26,6 +26,7 @@ #include "../common/crash.h" #include "../common/rulesys.h" #include "../common/eqemu_exception.h" +#include "../common/string_util.h" #include "items.h" #include "npc_faction.h" #include "loot.h" @@ -61,6 +62,7 @@ int main(int argc, char **argv) { database.LoadLogSettings(Log.log_settings); Log.StartFileLogs(); + std::string hotfix_name = ""; bool load_all = true; bool load_items = false; bool load_factions = false; @@ -69,112 +71,125 @@ int main(int argc, char **argv) { bool load_spells = false; bool load_bd = false; if(argc > 1) { - load_all = false; - for(int i = 1; i < argc; ++i) { - switch(argv[i][0]) { - case 'a': - if(strcasecmp("all", argv[i]) == 0) { - load_all = true; - } - break; - + switch(argv[i][0]) { case 'b': if(strcasecmp("base_data", argv[i]) == 0) { load_bd = true; + load_all = false; } break; - + case 'i': if(strcasecmp("items", argv[i]) == 0) { load_items = true; + load_all = false; } break; - + case 'f': if(strcasecmp("factions", argv[i]) == 0) { load_factions = true; + load_all = false; } break; - + case 'l': if(strcasecmp("loot", argv[i]) == 0) { load_loot = true; + load_all = false; } break; - + case 's': if(strcasecmp("skill_caps", argv[i]) == 0) { load_skill_caps = true; + load_all = false; } else if(strcasecmp("spells", argv[i]) == 0) { load_spells = true; + load_all = false; } break; + case '-': { + auto split = SplitString(argv[i], '='); + if(split.size() >= 2) { + auto command = split[0]; + auto argument = split[1]; + if(strcasecmp("-hotfix", command.c_str()) == 0) { + hotfix_name = argument; + load_all = true; + } + } + break; + } } } } + if(hotfix_name.length() > 0) { + Log.Out(Logs::General, Logs::Status, "Writing data for hotfix '%s'", hotfix_name.c_str()); + } + if(load_all || load_items) { Log.Out(Logs::General, Logs::Status, "Loading items..."); try { - LoadItems(&database); + LoadItems(&database, hotfix_name); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "%s", ex.what()); return 1; } } - + if(load_all || load_factions) { Log.Out(Logs::General, Logs::Status, "Loading factions..."); try { - LoadFactions(&database); + LoadFactions(&database, hotfix_name); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "%s", ex.what()); return 1; } } - + if(load_all || load_loot) { Log.Out(Logs::General, Logs::Status, "Loading loot..."); try { - LoadLoot(&database); + LoadLoot(&database, hotfix_name); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "%s", ex.what()); return 1; } } - + if(load_all || load_skill_caps) { Log.Out(Logs::General, Logs::Status, "Loading skill caps..."); try { - LoadSkillCaps(&database); + LoadSkillCaps(&database, hotfix_name); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "%s", ex.what()); return 1; } } - + if(load_all || load_spells) { Log.Out(Logs::General, Logs::Status, "Loading spells..."); try { - LoadSpells(&database); + LoadSpells(&database, hotfix_name); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "%s", ex.what()); return 1; } } - + if(load_all || load_bd) { Log.Out(Logs::General, Logs::Status, "Loading base data..."); try { - LoadBaseData(&database); + LoadBaseData(&database, hotfix_name); } catch(std::exception &ex) { Log.Out(Logs::General, Logs::Error, "%s", ex.what()); return 1; } } - + Log.CloseFileLogs(); - return 0; } diff --git a/shared_memory/npc_faction.cpp b/shared_memory/npc_faction.cpp index ebaeb3457..9ac8510bd 100644 --- a/shared_memory/npc_faction.cpp +++ b/shared_memory/npc_faction.cpp @@ -24,7 +24,7 @@ #include "../common/eqemu_exception.h" #include "../common/faction.h" -void LoadFactions(SharedDatabase *database) { +void LoadFactions(SharedDatabase *database, const std::string &prefix) { EQEmu::IPCMutex mutex("faction"); mutex.Lock(); @@ -33,7 +33,9 @@ void LoadFactions(SharedDatabase *database) { database->GetFactionListInfo(lists, max_list); uint32 size = static_cast(EQEmu::FixedMemoryHashSet::estimated_size(lists, max_list)); - EQEmu::MemoryMappedFile mmf("shared/faction", size); + + std::string file_name = std::string("shared/") + prefix + std::string("faction"); + EQEmu::MemoryMappedFile mmf(file_name, size); mmf.ZeroFile(); void *ptr = mmf.Get(); diff --git a/shared_memory/npc_faction.h b/shared_memory/npc_faction.h index 52038dd9b..8fe5dbadb 100644 --- a/shared_memory/npc_faction.h +++ b/shared_memory/npc_faction.h @@ -19,7 +19,9 @@ #ifndef __EQEMU_SHARED_MEMORY_NPC_FACTION_H #define __EQEMU_SHARED_MEMORY_NPC_FACTION_H +#include + class SharedDatabase; -void LoadFactions(SharedDatabase *database); +void LoadFactions(SharedDatabase *database, const std::string &prefix); #endif diff --git a/shared_memory/skill_caps.cpp b/shared_memory/skill_caps.cpp index 94205ce72..153d06e13 100644 --- a/shared_memory/skill_caps.cpp +++ b/shared_memory/skill_caps.cpp @@ -25,7 +25,7 @@ #include "../common/classes.h" #include "../common/features.h" -void LoadSkillCaps(SharedDatabase *database) { +void LoadSkillCaps(SharedDatabase *database, const std::string &prefix) { EQEmu::IPCMutex mutex("skill_caps"); mutex.Lock(); @@ -33,7 +33,9 @@ void LoadSkillCaps(SharedDatabase *database) { uint32 skill_count = HIGHEST_SKILL + 1; uint32 level_count = HARD_LEVEL_CAP + 1; uint32 size = (class_count * skill_count * level_count * sizeof(uint16)); - EQEmu::MemoryMappedFile mmf("shared/skill_caps", size); + + std::string file_name = std::string("shared/") + prefix + std::string("skill_caps"); + EQEmu::MemoryMappedFile mmf(file_name, size); mmf.ZeroFile(); void *ptr = mmf.Get(); diff --git a/shared_memory/skill_caps.h b/shared_memory/skill_caps.h index e01dab4f4..90ae5733c 100644 --- a/shared_memory/skill_caps.h +++ b/shared_memory/skill_caps.h @@ -19,8 +19,10 @@ #ifndef __EQEMU_SHARED_MEMORY_SKILL_CAPS_H #define __EQEMU_SHARED_MEMORY_SKILL_CAPS_H +#include + class SharedDatabase; -void LoadSkillCaps(SharedDatabase *database); +void LoadSkillCaps(SharedDatabase *database, const std::string &prefix); #endif diff --git a/shared_memory/spells.cpp b/shared_memory/spells.cpp index 444f3b466..34cce35bc 100644 --- a/shared_memory/spells.cpp +++ b/shared_memory/spells.cpp @@ -24,7 +24,7 @@ #include "../common/eqemu_exception.h" #include "../common/spdat.h" -void LoadSpells(SharedDatabase *database) { +void LoadSpells(SharedDatabase *database, const std::string &prefix) { EQEmu::IPCMutex mutex("spells"); mutex.Lock(); int records = database->GetMaxSpellID() + 1; @@ -32,8 +32,10 @@ void LoadSpells(SharedDatabase *database) { EQ_EXCEPT("Shared Memory", "Unable to get any spells from the database."); } - uint32 size = records * sizeof(SPDat_Spell_Struct); - EQEmu::MemoryMappedFile mmf("shared/spells", size); + uint32 size = records * sizeof(SPDat_Spell_Struct) + sizeof(uint32); + + std::string file_name = std::string("shared/") + prefix + std::string("spells"); + EQEmu::MemoryMappedFile mmf(file_name, size); mmf.ZeroFile(); void *ptr = mmf.Get(); diff --git a/shared_memory/spells.h b/shared_memory/spells.h index 590ee0536..bde0f8233 100644 --- a/shared_memory/spells.h +++ b/shared_memory/spells.h @@ -19,7 +19,9 @@ #ifndef __EQEMU_SHARED_MEMORY_SPELLS_H #define __EQEMU_SHARED_MEMORY_SPELLS_H +#include + class SharedDatabase; -void LoadSpells(SharedDatabase *database); +void LoadSpells(SharedDatabase *database, const std::string &prefix); #endif diff --git a/world/client.cpp b/world/client.cpp index 2c476902a..6d7233256 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1217,30 +1217,31 @@ void Client::Clearance(int8 response) return; } - // @bp This is the chat server - /* - char packetData[] = "64.37.148.34.9876,MyServer,Testchar,23cd2c95"; - outapp = new EQApplicationPacket(OP_0x0282, sizeof(packetData)); - strcpy((char*)outapp->pBuffer, packetData); - QueuePacket(outapp); - delete outapp; - */ - // Send zone server IP data outapp = new EQApplicationPacket(OP_ZoneServerInfo, sizeof(ZoneServerInfo_Struct)); ZoneServerInfo_Struct* zsi = (ZoneServerInfo_Struct*)outapp->pBuffer; - const char *zs_addr=zs->GetCAddress(); - if (!zs_addr[0]) { - if (cle->IsLocalClient()) { + + const char *zs_addr = nullptr; + if(cle && cle->IsLocalClient()) { + const char *local_addr = zs->GetCLocalAddress(); + if(local_addr[0]) { + zs_addr = local_addr; + } else { struct in_addr in; in.s_addr = zs->GetIP(); - zs_addr=inet_ntoa(in); - if (!strcmp(zs_addr,"127.0.0.1")) - zs_addr=WorldConfig::get()->LocalAddress.c_str(); + zs_addr = inet_ntoa(in); + } + } else { + const char *addr = zs->GetCAddress(); + if(addr[0]) { + zs_addr = addr; } else { - zs_addr=WorldConfig::get()->WorldAddress.c_str(); + struct in_addr in; + in.s_addr = zs->GetIP(); + zs_addr = inet_ntoa(in); } } + strcpy(zsi->ip, zs_addr); zsi->port =zs->GetCPort(); Log.Out(Logs::Detail, Logs::World_Server,"Sending client to zone %s (%d:%d) at %s:%d",zonename,zoneID,instanceID,zsi->ip,zsi->port); diff --git a/world/net.cpp b/world/net.cpp index 434491a0a..3032e4c97 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -294,6 +294,14 @@ int main(int argc, char** argv) { } Log.Out(Logs::General, Logs::World_Server, "Loading variables.."); database.LoadVariables(); + + char hotfix_name[256] = { 0 }; + if(database.GetVariable("hotfix_name", hotfix_name, 256)) { + if(strlen(hotfix_name) > 0) { + Log.Out(Logs::General, Logs::Zone_Server, "Current hotfix in use: '%s'", hotfix_name); + } + } + Log.Out(Logs::General, Logs::World_Server, "Loading zones.."); database.LoadZoneNames(); Log.Out(Logs::General, Logs::World_Server, "Clearing groups.."); @@ -303,10 +311,10 @@ int main(int argc, char** argv) { database.ClearRaidDetails(); database.ClearRaidLeader(); Log.Out(Logs::General, Logs::World_Server, "Loading items.."); - if (!database.LoadItems()) + if(!database.LoadItems(hotfix_name)) Log.Out(Logs::General, Logs::World_Server, "Error: Could not load item data. But ignoring"); Log.Out(Logs::General, Logs::World_Server, "Loading skill caps.."); - if (!database.LoadSkillCaps()) + if(!database.LoadSkillCaps(std::string(hotfix_name))) Log.Out(Logs::General, Logs::World_Server, "Error: Could not load skill cap data. But ignoring"); Log.Out(Logs::General, Logs::World_Server, "Loading guilds.."); guild_mgr.LoadGuilds(); diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 17cac7f62..d36507f04 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -57,6 +57,7 @@ ZoneServer::ZoneServer(EmuTCPConnection* itcpc) instanceID = 0; memset(clientaddress, 0, sizeof(clientaddress)); + memset(clientlocaladdress, 0, sizeof(clientlocaladdress)); clientport = 0; BootingUp = false; authenticated = false; @@ -581,7 +582,7 @@ bool ZoneServer::Process() { ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer; if (!sci->port) { - clientport=zoneserver_list.GetAvailableZonePort(); + clientport = zoneserver_list.GetAvailableZonePort(); ServerPacket p(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo)); memset(p.pBuffer,0,sizeof(ServerConnectInfo)); @@ -590,8 +591,18 @@ bool ZoneServer::Process() { SendPacket(&p); Log.Out(Logs::Detail, Logs::World_Server,"Auto zone port configuration. Telling zone to use port %d",clientport); } else { - clientport=sci->port; - Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d, must be a previously allocated zone reconnecting.",clientport); + clientport = sci->port; + Log.Out(Logs::Detail, Logs::World_Server,"Zone specified port %d.",clientport); + } + + if(sci->address[0]) { + strn0cpy(clientaddress, sci->address, 250); + Log.Out(Logs::Detail, Logs::World_Server, "Zone specified address %s.", sci->address); + } + + if(sci->local_address[0]) { + strn0cpy(clientlocaladdress, sci->local_address, 250); + Log.Out(Logs::Detail, Logs::World_Server, "Zone specified local address %s.", sci->address); } } @@ -1286,10 +1297,6 @@ bool ZoneServer::Process() { case ServerOP_CZSignalNPC: case ServerOP_CZSetEntityVariableByNPCTypeID: case ServerOP_CZSignalClient: - { - zoneserver_list.SendPacket(pack); - break; - } case ServerOP_DepopAllPlayersCorpses: case ServerOP_DepopPlayerCorpse: case ServerOP_ReloadTitles: @@ -1301,6 +1308,23 @@ bool ZoneServer::Process() { zoneserver_list.SendPacket(pack); break; } + case ServerOP_ChangeSharedMem: { + std::string hotfix_name = std::string((char*)pack->pBuffer); + + Log.Out(Logs::General, Logs::World_Server, "Loading items..."); + if(!database.LoadItems(hotfix_name)) { + Log.Out(Logs::General, Logs::World_Server, "Error: Could not load item data. But ignoring"); + } + + Log.Out(Logs::General, Logs::World_Server, "Loading skill caps..."); + if(!database.LoadSkillCaps(hotfix_name)) { + Log.Out(Logs::General, Logs::World_Server, "Error: Could not load skill cap data. But ignoring"); + } + + zoneserver_list.SendPacket(pack); + break; + } + case ServerOP_RequestTellQueue: { ServerRequestTellQueue_Struct* rtq = (ServerRequestTellQueue_Struct*) pack->pBuffer; diff --git a/world/zoneserver.h b/world/zoneserver.h index 1babecc98..0c2cd6bec 100644 --- a/world/zoneserver.h +++ b/world/zoneserver.h @@ -56,6 +56,7 @@ public: inline uint32 GetIP() const { return tcpc->GetrIP(); } inline uint16 GetPort() const { return tcpc->GetrPort(); } inline const char* GetCAddress() const { return clientaddress; } + inline const char* GetCLocalAddress() const { return clientaddress; } inline uint16 GetCPort() const { return clientport; } inline uint32 GetID() const { return ID; } inline bool IsBootingUp() const { return BootingUp; } @@ -73,6 +74,7 @@ private: uint32 ID; char clientaddress[250]; + char clientlocaladdress[250]; uint16 clientport; bool BootingUp; bool staticzone; diff --git a/zone/command.cpp b/zone/command.cpp index 3b8fba3f6..85437da47 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef _WINDOWS #define strcasecmp _stricmp @@ -168,6 +169,7 @@ int command_init(void) { command_add("aggrozone", "[aggro] - Aggro every mob in the zone with X aggro. Default is 0. Not recommend if you're not invulnerable.", 100, command_aggrozone) || command_add("ai", "[factionid/spellslist/con/guard/roambox/stop/start] - Modify AI on NPC target", 100, command_ai) || command_add("appearance", "[type] [value] - Send an appearance packet for you or your target", 150, command_appearance) || + command_add("apply_shared_memory", "[shared_memory_name] - Tells every zone and world to apply a specific shared memory segment by name.", 250, command_apply_shared_memory) || command_add("attack", "[targetname] - Make your NPC target attack targetname", 150, command_attack) || command_add("augmentitem", "Force augments an item. Must have the augment item window open.", 250, command_augmentitem) || command_add("aug", nullptr, 250, command_augmentitem) || @@ -252,6 +254,7 @@ int command_init(void) { command_add("heromodel", "[hero model] [slot] - Full set of Hero's Forge Armor appearance. If slot is set, sends exact model just to slot.", 200, command_heromodel) || command_add("hideme", "[on/off] - Hide yourself from spawn lists.", 80, command_hideme) || command_add("hm", "[hero model] [slot] - Full set of Hero's Forge Armor appearance. If slot is set, sends exact model just to slot.)", 200, command_heromodel) || + command_add("hotfix", "[hotfix_name] - Reloads shared memory into a hotfix, equiv to load_shared_memory followed by apply_shared_memory", 250, command_hotfix) || command_add("hp", "- Refresh your HP bar from the server.", 0, command_hp) || command_add("incstat", "- Increases or Decreases a client's stats permanently.", 200, command_incstat) || command_add("instance", "- Modify Instances", 200, command_instance) || @@ -269,6 +272,7 @@ int command_init(void) { command_add("level", "[level] - Set your or your target's level", 10, command_level) || command_add("listnpcs", "[name/range] - Search NPCs", 20, command_listnpcs) || command_add("listpetition", "- List petitions", 50, command_listpetition) || + command_add("load_shared_memory", "[shared_memory_name] - Reloads shared memory and uses the input as output", 250, command_load_shared_memory) || command_add("loc", "- Print out your or your target's current location and heading", 0, command_loc) || command_add("lock", "- Lock the worldserver", 150, command_lock) || command_add("logs", "Manage anything to do with logs", 250, command_logs) || @@ -10619,3 +10623,94 @@ void command_reloadaa(Client *c, const Seperator *sep) { c->Message(0, "Alternate Advancement Data Reloaded"); entity_list.SendAlternateAdvancementStats(); } + +void command_hotfix(Client *c, const Seperator *sep) { + char hotfix[256] = { 0 }; + database.GetVariable("hotfix_name", hotfix, 256); + std::string current_hotfix = hotfix; + + std::string hotfix_name; + if(!strcasecmp(current_hotfix.c_str(), "hotfix_")) { + hotfix_name = ""; + } else { + hotfix_name = "hotfix_"; + } + + c->Message(0, "Creating and applying hotfix"); + std::thread t1([c,hotfix_name]() { +#ifdef WIN32 + if(hotfix_name.length() > 0) { + system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + } else { + system(StringFormat("shared_memory").c_str()); + } +#else + if(hotfix_name.length() > 0) { + system(StringFormat("./shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + } + else { + system(StringFormat("./shared_memory").c_str()); + } +#endif + database.SetVariable("hotfix_name", hotfix_name.c_str()); + + ServerPacket pack(ServerOP_ChangeSharedMem, hotfix_name.length() + 1); + if(hotfix_name.length() > 0) { + strcpy((char*)pack.pBuffer, hotfix_name.c_str()); + } + worldserver.SendPacket(&pack); + + c->Message(0, "Hotfix applied"); + }); + + t1.detach(); +} + +void command_load_shared_memory(Client *c, const Seperator *sep) { + char hotfix[256] = { 0 }; + database.GetVariable("hotfix_name", hotfix, 256); + std::string current_hotfix = hotfix; + + std::string hotfix_name; + if(strcasecmp(current_hotfix.c_str(), sep->arg[1]) == 0) { + c->Message(0, "Cannot attempt to load this shared memory segment as it is already loaded."); + return; + } + + hotfix_name = sep->arg[1]; + c->Message(0, "Loading shared memory segment %s", hotfix_name.c_str()); + std::thread t1([c,hotfix_name]() { +#ifdef WIN32 + if(hotfix_name.length() > 0) { + system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + } else { + system(StringFormat("shared_memory").c_str()); + } +#else + if(hotfix_name.length() > 0) { + system(StringFormat("./shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + } + else { + system(StringFormat("./shared_memory").c_str()); + } +#endif + c->Message(0, "Shared memory segment finished loading."); + }); + + t1.detach(); +} + +void command_apply_shared_memory(Client *c, const Seperator *sep) { + char hotfix[256] = { 0 }; + database.GetVariable("hotfix_name", hotfix, 256); + std::string hotfix_name = sep->arg[1]; + + c->Message(0, "Applying shared memory segment %s", hotfix_name.c_str()); + database.SetVariable("hotfix_name", hotfix_name.c_str()); + + ServerPacket pack(ServerOP_ChangeSharedMem, hotfix_name.length() + 1); + if(hotfix_name.length() > 0) { + strcpy((char*)pack.pBuffer, hotfix_name.c_str()); + } + worldserver.SendPacket(&pack); +} \ No newline at end of file diff --git a/zone/command.h b/zone/command.h index bf20d46d2..6ab9666d2 100644 --- a/zone/command.h +++ b/zone/command.h @@ -325,6 +325,9 @@ void command_mysqltest(Client *c, const Seperator *sep); void command_logs(Client *c, const Seperator *sep); void command_resetaa_timer(Client *c, const Seperator *sep); void command_reloadaa(Client *c, const Seperator *sep); +void command_hotfix(Client *c, const Seperator *sep); +void command_load_shared_memory(Client *c, const Seperator *sep); +void command_apply_shared_memory(Client *c, const Seperator *sep); #ifdef EQPROFILE void command_profiledump(Client *c, const Seperator *sep); diff --git a/zone/net.cpp b/zone/net.cpp index ccd371858..acf217b84 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -102,7 +102,6 @@ QuestParserCollection *parse = 0; EQEmuLogSys Log; const SPDat_Spell_Struct* spells; -void LoadSpells(EQEmu::MemoryMappedFile **mmf); int32 SPDAT_RECORDS = -1; void Shutdown(); @@ -242,37 +241,46 @@ int main(int argc, char** argv) { Log.Out(Logs::General, Logs::Zone_Server, "Loading Variables"); database.LoadVariables(); + char hotfix_name[256] = { 0 }; + if(database.GetVariable("hotfix_name", hotfix_name, 256)) { + if(strlen(hotfix_name) > 0) { + Log.Out(Logs::General, Logs::Zone_Server, "Current hotfix in use: '%s'", hotfix_name); + } + } + Log.Out(Logs::General, Logs::Zone_Server, "Loading zone names"); database.LoadZoneNames(); Log.Out(Logs::General, Logs::Zone_Server, "Loading items"); - if (!database.LoadItems()) { + if(!database.LoadItems(hotfix_name)) { Log.Out(Logs::General, Logs::Error, "Loading items FAILED!"); Log.Out(Logs::General, Logs::Error, "Failed. But ignoring error and going on..."); } Log.Out(Logs::General, Logs::Zone_Server, "Loading npc faction lists"); - if (!database.LoadNPCFactionLists()) { + if(!database.LoadNPCFactionLists(hotfix_name)) { Log.Out(Logs::General, Logs::Error, "Loading npcs faction lists FAILED!"); return 1; } Log.Out(Logs::General, Logs::Zone_Server, "Loading loot tables"); - if (!database.LoadLoot()) { + if(!database.LoadLoot(hotfix_name)) { Log.Out(Logs::General, Logs::Error, "Loading loot FAILED!"); return 1; } Log.Out(Logs::General, Logs::Zone_Server, "Loading skill caps"); - if (!database.LoadSkillCaps()) { + if(!database.LoadSkillCaps(std::string(hotfix_name))) { Log.Out(Logs::General, Logs::Error, "Loading skill caps FAILED!"); return 1; } Log.Out(Logs::General, Logs::Zone_Server, "Loading spells"); - EQEmu::MemoryMappedFile *mmf = nullptr; - LoadSpells(&mmf); + if(!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) { + Log.Out(Logs::General, Logs::Error, "Loading spells FAILED!"); + return 1; + } Log.Out(Logs::General, Logs::Zone_Server, "Loading base data"); - if (!database.LoadBaseData()) { + if(!database.LoadBaseData(hotfix_name)) { Log.Out(Logs::General, Logs::Error, "Loading base data FAILED!"); return 1; } @@ -502,7 +510,6 @@ int main(int argc, char** argv) { safe_delete(lua_parser); #endif - safe_delete(mmf); safe_delete(Config); if (zone != 0) @@ -568,16 +575,6 @@ uint32 NetConnection::GetIP(char* name) } -void NetConnection::SaveInfo(char* address, uint32 port, char* waddress, char* filename) { - - ZoneAddress = new char[strlen(address)+1]; - strcpy(ZoneAddress, address); - ZonePort = port; - WorldAddress = new char[strlen(waddress)+1]; - strcpy(WorldAddress, waddress); - strn0cpy(ZoneFileName, filename, sizeof(ZoneFileName)); -} - NetConnection::NetConnection() : object_timer(5000), @@ -587,9 +584,6 @@ NetConnection::NetConnection() raid_timer(1000), trap_timer(1000) { - ZonePort = 0; - ZoneAddress = 0; - WorldAddress = 0; group_timer.Disable(); raid_timer.Disable(); corpse_timer.Disable(); @@ -599,32 +593,6 @@ NetConnection::NetConnection() } NetConnection::~NetConnection() { - if (ZoneAddress != 0) - safe_delete_array(ZoneAddress); - if (WorldAddress != 0) - safe_delete_array(WorldAddress); -} - -void LoadSpells(EQEmu::MemoryMappedFile **mmf) { - int records = database.GetMaxSpellID() + 1; - - try { - EQEmu::IPCMutex mutex("spells"); - mutex.Lock(); - *mmf = new EQEmu::MemoryMappedFile("shared/spells"); - uint32 size = (*mmf)->Size(); - if(size != (records * sizeof(SPDat_Spell_Struct))) { - EQ_EXCEPT("Zone", "Unable to load spells: (*mmf)->Size() != records * sizeof(SPDat_Spell_Struct)"); - } - - spells = reinterpret_cast((*mmf)->Get()); - mutex.Unlock(); - } catch(std::exception &ex) { - Log.Out(Logs::General, Logs::Error, "Error loading spells: %s", ex.what()); - return; - } - - SPDAT_RECORDS = records; } /* Update Window Title with relevant information */ diff --git a/zone/net.h b/zone/net.h index c49e1ec8e..8908a3740 100644 --- a/zone/net.h +++ b/zone/net.h @@ -39,20 +39,10 @@ public: uint32 GetIP(); uint32 GetIP(char* name); - void SaveInfo(char* address, uint32 port, char* waddress,char* filename); - char* GetWorldAddress() { return WorldAddress; } - char* GetZoneAddress() { return ZoneAddress; } - char* GetZoneFileName() { return ZoneFileName; } - uint32 GetZonePort() { return ZonePort; } Timer object_timer; Timer door_timer; Timer corpse_timer; Timer group_timer; Timer raid_timer; Timer trap_timer; -private: - uint16 ZonePort; - char* ZoneAddress; - char* WorldAddress; - char ZoneFileName[50]; }; diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index d3e3ee289..59eca67ac 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -112,7 +112,16 @@ void WorldServer::OnConnected() { pack = new ServerPacket(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo)); ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer; + auto config = ZoneConfig::get(); sci->port = ZoneConfig::get()->ZonePort; + if(config->WorldAddress.length() > 0) { + strn0cpy(sci->address, config->WorldAddress.c_str(), 250); + } + + if(config->LocalAddress.length() > 0) { + strn0cpy(sci->address, config->LocalAddress.c_str(), 250); + } + SendPacket(pack); safe_delete(pack); @@ -485,9 +494,7 @@ void WorldServer::Process() { if (zst->adminname[0] != 0) std::cout << "Zone bootup by " << zst->adminname << std::endl; - if (!(Zone::Bootup(zst->zoneid, zst->instanceid, zst->makestatic))) { - SendChannelMessage(0, 0, 10, 0, 0, "%s:%i Zone::Bootup failed: %s", net.GetZoneAddress(), net.GetZonePort(), database.GetZoneName(zst->zoneid)); - } + Zone::Bootup(zst->zoneid, zst->instanceid, zst->makestatic); break; } case ServerOP_ZoneIncClient: { @@ -508,8 +515,6 @@ void WorldServer::Process() { if ((Zone::Bootup(szic->zoneid, szic->instanceid))) { zone->AddAuth(szic); } - else - SendEmoteMessage(0, 0, 100, 0, "%s:%i Zone::Bootup failed: %s (%i)", net.GetZoneAddress(), net.GetZonePort(), database.GetZoneName(szic->zoneid, true), szic->zoneid); } break; } @@ -715,30 +720,6 @@ void WorldServer::Process() { case ServerOP_ZoneReboot: { std::cout << "Got Server Requested Zone reboot" << std::endl; ServerZoneReboot_Struct* zb = (ServerZoneReboot_Struct*) pack->pBuffer; - // printf("%i\n",zb->zoneid); - struct in_addr in; - in.s_addr = GetIP(); -#ifdef _WINDOWS - char buffer[200]; - snprintf(buffer,200,". %s %i %s",zb->ip2, zb->port, inet_ntoa(in)); - if(zb->zoneid != 0) { - snprintf(buffer,200,"%s %s %i %s",database.GetZoneName(zb->zoneid),zb->ip2, zb->port ,inet_ntoa(in)); - std::cout << "executing: " << buffer; - ShellExecute(0,"Open",net.GetZoneFileName(), buffer, 0, SW_SHOWDEFAULT); - } - else - { - std::cout << "executing: " << net.GetZoneFileName() << " " << buffer; - ShellExecute(0,"Open",net.GetZoneFileName(), buffer, 0, SW_SHOWDEFAULT); - } -#else - char buffer[5]; - snprintf(buffer,5,"%i",zb->port); //just to be sure that it will work on linux - if(zb->zoneid != 0) - execl(net.GetZoneFileName(),net.GetZoneFileName(),database.GetZoneName(zb->zoneid),zb->ip2, buffer,inet_ntoa(in), nullptr); - else - execl(net.GetZoneFileName(),net.GetZoneFileName(),".",zb->ip2, buffer,inet_ntoa(in), nullptr); -#endif break; } case ServerOP_SyncWorldTime: { @@ -1841,6 +1822,41 @@ void WorldServer::Process() { } break; } + + case ServerOP_ChangeSharedMem: + { + std::string hotfix_name = std::string((char*)pack->pBuffer); + Log.Out(Logs::General, Logs::Zone_Server, "Loading items"); + if(!database.LoadItems(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading items FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading npc faction lists"); + if(!database.LoadNPCFactionLists(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading npcs faction lists FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading loot tables"); + if(!database.LoadLoot(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading loot FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading skill caps"); + if(!database.LoadSkillCaps(std::string(hotfix_name))) { + Log.Out(Logs::General, Logs::Error, "Loading skill caps FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading spells"); + if(!database.LoadSpells(hotfix_name, &SPDAT_RECORDS, &spells)) { + Log.Out(Logs::General, Logs::Error, "Loading spells FAILED!"); + } + + Log.Out(Logs::General, Logs::Zone_Server, "Loading base data"); + if(!database.LoadBaseData(hotfix_name)) { + Log.Out(Logs::General, Logs::Error, "Loading base data FAILED!"); + } + break; + } default: { std::cout << " Unknown ZSopcode:" << (int)pack->opcode; std::cout << " size:" << pack->size << std::endl;