From dae20afcbaa7f2e2d818155ffe9bfb93d76aa6a4 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 31 Mar 2020 01:49:42 -0500 Subject: [PATCH] Fix character creation tenancy operations --- common/database.cpp | 55 -------------- common/database.h | 1 - .../character_recipe_list_repository.h | 4 +- common/repositories/grid_entries_repository.h | 2 +- common/repositories/grid_repository.h | 4 +- common/repositories/spawngroup_repository.h | 4 +- .../tradeskill_recipe_repository.h | 4 +- world/client.cpp | 64 +++++++++++++++- world/client.h | 7 ++ world/main.cpp | 20 ++--- world/worlddb.cpp | 74 ++++++++++++------- world/worlddb.h | 9 ++- zone/client.cpp | 5 +- zone/command.cpp | 53 ++++++++++--- 14 files changed, 186 insertions(+), 120 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 69ac0b997..b3a4c0bf4 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -750,61 +750,6 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe return true; } -/* This only for new Character creation storing */ -bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv) { - uint32 charid = 0; - char zone[50]; - float x, y, z; - charid = GetCharacterID(pp->name); - - if(!charid) { - LogError("StoreCharacter: no character id"); - return false; - } - - const char *zname = GetZoneName(pp->zone_id); - if(zname == nullptr) { - /* Zone not in the DB, something to prevent crash... */ - strn0cpy(zone, "qeynos", 49); - pp->zone_id = 1; - } - else{ strn0cpy(zone, zname, 49); } - - x = pp->x; - y = pp->y; - z = pp->z; - - /* Saves Player Profile Data */ - SaveCharacterCreate(charid, account_id, pp); - - /* Insert starting inventory... */ - std::string invquery; - for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invbag::BANK_BAGS_END;) { - const EQEmu::ItemInstance* newinv = inv->GetItem(i); - if (newinv) { - invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)", - charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor()); - - auto results = QueryDatabase(invquery); - } - - if (i == EQEmu::invslot::slotCursor) { - i = EQEmu::invbag::GENERAL_BAGS_BEGIN; - continue; - } - else if (i == EQEmu::invbag::CURSOR_BAG_END) { - i = EQEmu::invslot::BANK_BEGIN; - continue; - } - else if (i == EQEmu::invslot::BANK_END) { - i = EQEmu::invbag::BANK_BAGS_BEGIN; - continue; - } - i++; - } - return true; -} - uint32 Database::GetCharacterID(const char *name) { std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); diff --git a/common/database.h b/common/database.h index 95458c1c1..2239282ba 100644 --- a/common/database.h +++ b/common/database.h @@ -115,7 +115,6 @@ public: bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp); bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked); bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone); - bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv); bool UpdateName(const char* oldname, const char* newname); /* General Information Queries */ diff --git a/common/repositories/character_recipe_list_repository.h b/common/repositories/character_recipe_list_repository.h index d3349cf6a..f0a53f099 100644 --- a/common/repositories/character_recipe_list_repository.h +++ b/common/repositories/character_recipe_list_repository.h @@ -62,7 +62,7 @@ public: ); } - static CharacterRecipeList GetDefaults() + static CharacterRecipeList NewEntity() { CharacterRecipeList character_recipe_list_entry; @@ -109,7 +109,7 @@ public: } } - return GetDefaults(); + return NewEntity(); } }; diff --git a/common/repositories/grid_entries_repository.h b/common/repositories/grid_entries_repository.h index 0c2e34d85..efb2126d7 100644 --- a/common/repositories/grid_entries_repository.h +++ b/common/repositories/grid_entries_repository.h @@ -74,7 +74,7 @@ public: ); } - static GridEntry Default() + static GridEntry NewEntity() { GridEntry entry{}; diff --git a/common/repositories/grid_repository.h b/common/repositories/grid_repository.h index 523c5212d..49305c33b 100644 --- a/common/repositories/grid_repository.h +++ b/common/repositories/grid_repository.h @@ -64,7 +64,7 @@ public: ); } - static Grid Default() + static Grid NewEntity() { Grid entry{}; @@ -113,7 +113,7 @@ public: } } - return Default(); + return NewEntity(); } }; diff --git a/common/repositories/spawngroup_repository.h b/common/repositories/spawngroup_repository.h index 4c800639f..7c55711b6 100644 --- a/common/repositories/spawngroup_repository.h +++ b/common/repositories/spawngroup_repository.h @@ -81,7 +81,7 @@ public: ); } - static SpawnGroup New() + static SpawnGroup NewEntity() { SpawnGroup entry; @@ -155,7 +155,7 @@ public: } } - return New(); + return NewEntity(); } }; diff --git a/common/repositories/tradeskill_recipe_repository.h b/common/repositories/tradeskill_recipe_repository.h index 9cdcb178a..15ee26ce3 100644 --- a/common/repositories/tradeskill_recipe_repository.h +++ b/common/repositories/tradeskill_recipe_repository.h @@ -78,7 +78,7 @@ public: ); } - static TradeskillRecipe New() + static TradeskillRecipe NewEntity() { TradeskillRecipe entry; @@ -107,7 +107,7 @@ public: ) ); - TradeskillRecipe tradeskill_recipe = New(); + TradeskillRecipe tradeskill_recipe = NewEntity(); auto row = results.begin(); if (results.RowCount() == 0) { diff --git a/world/client.cpp b/world/client.cpp index 82db1c4a7..ebc01e03e 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1568,7 +1568,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) /* Overrides if we have the tutorial flag set! */ if (cc->tutorial && RuleB(World, EnableTutorialButton)) { pp.zone_id = RuleI(World, TutorialZoneID); - database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z); + content_db.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z); } /* Will either be the same as home or tutorial if enabled. */ @@ -1592,7 +1592,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) // now we give the pp and the inv we made to StoreCharacter // to see if we can store it - if (!database.StoreCharacter(GetAccountID(), &pp, &inv)) { + if (!StoreCharacter(GetAccountID(), &pp, &inv)) { LogInfo("Character creation failed: [{}]", pp.name); return false; } @@ -2075,3 +2075,63 @@ void Client::SetClassLanguages(PlayerProfile_Struct *pp) } } +bool Client::StoreCharacter( + uint32 account_id, + PlayerProfile_Struct *p_player_profile_struct, + EQEmu::InventoryProfile *p_inventory_profile +) +{ + uint32 character_id = 0; + char zone[50]; + character_id = database.GetCharacterID(p_player_profile_struct->name); + + if (!character_id) { + LogError("StoreCharacter: no character id"); + return false; + } + + const char *zone_name = content_db.GetZoneName(p_player_profile_struct->zone_id); + if (zone_name == nullptr) { + /* Zone not in the DB, something to prevent crash... */ + strn0cpy(zone, "qeynos", 49); + p_player_profile_struct->zone_id = 1; + } + else { + strn0cpy(zone, zone_name, 49); + } + + database.SaveCharacterCreate(character_id, account_id, p_player_profile_struct); + + std::string invquery; + for (int16 i = EQEmu::invslot::EQUIPMENT_BEGIN; i <= EQEmu::invbag::BANK_BAGS_END;) { + const EQEmu::ItemInstance *new_inventory_item = p_inventory_profile->GetItem(i); + if (new_inventory_item) { + invquery = StringFormat( + "INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)", + character_id, + i, + new_inventory_item->GetItem()->ID, + new_inventory_item->GetCharges(), + new_inventory_item->GetColor() + ); + + auto results = database.QueryDatabase(invquery); + } + + if (i == EQEmu::invslot::slotCursor) { + i = EQEmu::invbag::GENERAL_BAGS_BEGIN; + continue; + } + else if (i == EQEmu::invbag::CURSOR_BAG_END) { + i = EQEmu::invslot::BANK_BEGIN; + continue; + } + else if (i == EQEmu::invslot::BANK_END) { + i = EQEmu::invbag::BANK_BAGS_BEGIN; + continue; + } + i++; + } + + return true; +} \ No newline at end of file diff --git a/world/client.h b/world/client.h index 4dbad85c5..2bea3adf6 100644 --- a/world/client.h +++ b/world/client.h @@ -22,6 +22,7 @@ #include "../common/linked_list.h" #include "../common/timer.h" +#include "../common/inventory_profile.h" //#include "zoneserver.h" #include "../common/eq_packet_structs.h" @@ -71,6 +72,12 @@ public: inline EQEmu::versions::ClientVersion GetClientVersion() { return m_ClientVersion; } inline ClientListEntry* GetCLE() { return cle; } inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; } + bool StoreCharacter( + uint32 account_id, + PlayerProfile_Struct *p_player_profile_struct, + EQEmu::InventoryProfile *p_inventory_profile + ); + private: uint32 ip; diff --git a/world/main.cpp b/world/main.cpp index 4d5511f7c..03a39ea79 100644 --- a/world/main.cpp +++ b/world/main.cpp @@ -247,17 +247,10 @@ int main(int argc, char** argv) { if (argc > 1) { LogSys.SilenceConsoleLogging(); - /** - * Get Config - */ WorldConfig::LoadConfig(); Config = WorldConfig::get(); - /** - * Load database - */ LoadDatabaseConnections(); - LogSys.EnableConsoleLogging(); WorldserverCommandHandler::CommandHandler(argc, argv); @@ -340,12 +333,15 @@ int main(int argc, char** argv) { LogInfo("Clearing inventory snapshots"); database.ClearInvSnapshots(); LogInfo("Loading items"); - if (!database.LoadItems(hotfix_name)) - LogError("Error: Could not load item data. But ignoring"); - LogInfo("Loading skill caps"); - if (!database.LoadSkillCaps(std::string(hotfix_name))) - LogError("Error: Could not load skill cap data. But ignoring"); + if (!content_db.LoadItems(hotfix_name)) { + LogError("Error: Could not load item data. But ignoring"); + } + + LogInfo("Loading skill caps"); + if (!content_db.LoadSkillCaps(std::string(hotfix_name))) { + LogError("Error: Could not load skill cap data. But ignoring"); + } LogInfo("Loading guilds"); guild_mgr.LoadGuilds(); diff --git a/world/worlddb.cpp b/world/worlddb.cpp index e1dbd0196..83f0e2f4f 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -215,7 +215,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o float x = atof(row_d[2]); float y = atof(row_d[3]); float z = atof(row_d[4]); - if (x == 0 && y == 0 && z == 0) { GetSafePoints(player_profile_struct.binds[4].zoneId, 0, &x, &y, &z); } + if (x == 0 && y == 0 && z == 0) { content_db.GetSafePoints(player_profile_struct.binds[4].zoneId, 0, &x, &y, &z); } player_profile_struct.binds[4].x = x; player_profile_struct.binds[4].y = y; player_profile_struct.binds[4].z = z; @@ -392,7 +392,11 @@ int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) return zone_id; } -bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc,bool isTitanium) +bool WorldDatabase::GetStartZone( + PlayerProfile_Struct *p_player_profile_struct, + CharCreate_Struct *p_char_create_struct, + bool is_titanium +) { // SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead. // @@ -401,45 +405,63 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* // For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely // reason for no match being found. // - if(!in_pp || !in_cc) + if (!p_player_profile_struct || !p_char_create_struct) { return false; + } + + p_player_profile_struct->x = 0; + p_player_profile_struct->y = 0; + p_player_profile_struct->z = 0; + p_player_profile_struct->heading = 0; + p_player_profile_struct->zone_id = 0; + p_player_profile_struct->binds[0].x = 0; + p_player_profile_struct->binds[0].y = 0; + p_player_profile_struct->binds[0].z = 0; + p_player_profile_struct->binds[0].zoneId = 0; + p_player_profile_struct->binds[0].instance_id = 0; - in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0; - in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0; // see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids - std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i " + std::string query = StringFormat( + "SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i " "AND player_class = %i AND player_deity = %i AND player_race = %i", - in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race); - auto results = QueryDatabase(query); - if(!results.Success()) { + p_char_create_struct->start_zone, + p_char_create_struct->class_, + p_char_create_struct->deity, + p_char_create_struct->race + ); + + auto results = QueryDatabase(query); + if (!results.Success()) { return false; } LogInfo("SoF Start zone query: [{}]\n", query.c_str()); - if (results.RowCount() == 0) { - printf("No start_zones entry in database, using defaults\n"); - isTitanium ? SetTitaniumDefaultStartZone(in_pp, in_cc) : SetSoFDefaultStartZone(in_pp, in_cc); + if (results.RowCount() == 0) { + printf("No start_zones entry in database, using defaults\n"); + is_titanium ? SetTitaniumDefaultStartZone(p_player_profile_struct, p_char_create_struct) : SetSoFDefaultStartZone(p_player_profile_struct, p_char_create_struct); } else { LogInfo("Found starting location in start_zones"); auto row = results.begin(); - in_pp->x = atof(row[0]); - in_pp->y = atof(row[1]); - in_pp->z = atof(row[2]); - in_pp->heading = atof(row[3]); - in_pp->zone_id = atoi(row[4]); - in_pp->binds[0].zoneId = atoi(row[5]); - in_pp->binds[0].x = atof(row[6]); - in_pp->binds[0].y = atof(row[7]); - in_pp->binds[0].z = atof(row[8]); + p_player_profile_struct->x = atof(row[0]); + p_player_profile_struct->y = atof(row[1]); + p_player_profile_struct->z = atof(row[2]); + p_player_profile_struct->heading = atof(row[3]); + p_player_profile_struct->zone_id = atoi(row[4]); + p_player_profile_struct->binds[0].zoneId = atoi(row[5]); + p_player_profile_struct->binds[0].x = atof(row[6]); + p_player_profile_struct->binds[0].y = atof(row[7]); + p_player_profile_struct->binds[0].z = atof(row[8]); } - if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0) - database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z); + if (p_player_profile_struct->x == 0 && p_player_profile_struct->y == 0 && p_player_profile_struct->z == 0) { + content_db.GetSafePoints(p_player_profile_struct->zone_id, 0, &p_player_profile_struct->x, &p_player_profile_struct->y, &p_player_profile_struct->z); + } - if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0) - database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z); + if (p_player_profile_struct->binds[0].x == 0 && p_player_profile_struct->binds[0].y == 0 && p_player_profile_struct->binds[0].z == 0) { + content_db.GetSafePoints(p_player_profile_struct->binds[0].zoneId, 0, &p_player_profile_struct->binds[0].x, &p_player_profile_struct->binds[0].y, &p_player_profile_struct->binds[0].z); + } return true; } @@ -783,4 +805,4 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQEmu::In } return true; -} +} \ No newline at end of file diff --git a/world/worlddb.h b/world/worlddb.h index 06b681ff9..6f08b6fa5 100644 --- a/world/worlddb.h +++ b/world/worlddb.h @@ -29,7 +29,7 @@ struct CharacterSelect_Struct; class WorldDatabase : public SharedDatabase { public: - bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc, bool isTitanium); + bool GetStartZone(PlayerProfile_Struct* p_player_profile_struct, CharCreate_Struct* p_char_create_struct, bool is_titanium); void GetCharSelectInfo(uint32 account_id, EQApplicationPacket **out_app, uint32 client_version_bit); int MoveCharacterToBind(int CharID, uint8 bindnum = 0); @@ -38,6 +38,13 @@ public: bool LoadCharacterCreateAllocations(); bool LoadCharacterCreateCombos(); + + bool StoreCharacter( + uint32 account_id, + PlayerProfile_Struct *p_player_profile_struct, + EQEmu::InventoryProfile *p_inventory_profile + ); + private: void SetTitaniumDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc); void SetSoFDefaultStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc); diff --git a/zone/client.cpp b/zone/client.cpp index dde425475..6c440e4b6 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -5295,8 +5295,9 @@ void Client::SetStartZone(uint32 zoneid, float x, float y, float z) m_pp.binds[4].instance_id = zone->GetInstanceID(); } - if (x == 0 && y == 0 && z ==0) - database.GetSafePoints(m_pp.binds[4].zoneId, 0, &m_pp.binds[4].x, &m_pp.binds[4].y, &m_pp.binds[4].z); + if (x == 0 && y == 0 && z == 0) { + content_db.GetSafePoints(m_pp.binds[4].zoneId, 0, &m_pp.binds[4].x, &m_pp.binds[4].y, &m_pp.binds[4].z); + } else { m_pp.binds[4].x = x; m_pp.binds[4].y = y; diff --git a/zone/command.cpp b/zone/command.cpp index b7db3205e..66be91b64 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -7141,22 +7141,51 @@ void command_summonitem(Client *c, const Seperator *sep) item_status = static_cast(item->MinStatus); } - if (item_status > c->Admin()) + if (item_status > c->Admin()) { c->Message(Chat::Red, "Error: Insufficient status to summon this item."); - else if (sep->argnum == 2 && sep->IsNumber(2)) + } + else if (sep->argnum == 2 && sep->IsNumber(2)) { c->SummonItem(itemid, atoi(sep->arg[2])); - else if (sep->argnum == 3) + } + else if (sep->argnum == 3) { c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3])); - else if (sep->argnum == 4) + } + else if (sep->argnum == 4) { c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); - else if (sep->argnum == 5) + } + else if (sep->argnum == 5) { c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5])); - else if (sep->argnum == 6) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6])); - else if (sep->argnum == 7) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7])); - else if (sep->argnum == 8) - c->SummonItem(itemid, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), atoi(sep->arg[6]), atoi(sep->arg[7]), atoi(sep->arg[8])); + } + else if (sep->argnum == 6) { + c->SummonItem( + itemid, + atoi(sep->arg[2]), + atoi(sep->arg[3]), + atoi(sep->arg[4]), + atoi(sep->arg[5]), + atoi(sep->arg[6])); + } + else if (sep->argnum == 7) { + c->SummonItem( + itemid, + atoi(sep->arg[2]), + atoi(sep->arg[3]), + atoi(sep->arg[4]), + atoi(sep->arg[5]), + atoi(sep->arg[6]), + atoi(sep->arg[7])); + } + else if (sep->argnum == 8) { + c->SummonItem( + itemid, + atoi(sep->arg[2]), + atoi(sep->arg[3]), + atoi(sep->arg[4]), + atoi(sep->arg[5]), + atoi(sep->arg[6]), + atoi(sep->arg[7]), + atoi(sep->arg[8])); + } else { c->SummonItem(itemid); } @@ -7270,7 +7299,7 @@ void command_itemsearch(Client *c, const Seperator *sep) std::string saylink_commands; for (auto &amount : amounts) { saylink_commands += EQEmu::SayLinkEngine::GenerateQuestSaylink( - "#gi " + std::to_string(item->ID) + " " + amount, + "#si " + std::to_string(item->ID) + " " + amount, false, "[" + amount + "] " );