From 198b3371c5555527d5359a15b1937b09d9d1494c Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:14:30 -0800 Subject: [PATCH] chore: Update old character create code (#1291) * create new character fixes Don't use persistentIds, guarantee ids are unique by using do while to generate the id * Update queries to actually use prep stmt * Update UserManager.cpp * Update UserManager.cpp --- dGame/UserManager.cpp | 103 ++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 9820636a..8a58ac69 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -207,7 +207,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) { chars[i]->SaveXMLToDatabase(); chars[i]->GetEntity()->SetCharacter(nullptr); - + delete chars[i]; } @@ -275,60 +275,58 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) } std::stringstream xml; - xml << ""; + + xml << ""; xml << "GetAccountID() << "\" cc=\"0\" gm=\"0\" ft=\"0\" llog=\"" << time(NULL) << "\" "; xml << "ls=\"0\" lzx=\"-626.5847\" lzy=\"613.3515\" lzz=\"-28.6374\" lzrx=\"0.0\" lzry=\"0.7015\" lzrz=\"0.0\" lzrw=\"0.7126\" "; xml << "stt=\"0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;\">"; + xml << ""; + xml << ""; - std::string xmlSave1 = xml.str(); - ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t idforshirt) { - std::stringstream xml2; + LWOOBJID lwoidforshirt = ObjectIDManager::GenerateRandomObjectID(); + LWOOBJID lwoidforpants; - LWOOBJID lwoidforshirt = idforshirt; - GeneralUtils::SetBit(lwoidforshirt, eObjectBits::CHARACTER); - GeneralUtils::SetBit(lwoidforshirt, eObjectBits::PERSISTENT); - xml2 << xmlSave1 << ""; + do { + lwoidforpants = ObjectIDManager::GenerateRandomObjectID(); + } while (lwoidforpants == lwoidforshirt); //Make sure we don't have the same ID for both shirt and pants - std::string xmlSave2 = xml2.str(); + GeneralUtils::SetBit(lwoidforshirt, eObjectBits::CHARACTER); + GeneralUtils::SetBit(lwoidforshirt, eObjectBits::PERSISTENT); + GeneralUtils::SetBit(lwoidforpants, eObjectBits::CHARACTER); + GeneralUtils::SetBit(lwoidforpants, eObjectBits::PERSISTENT); - ObjectIDManager::Instance()->RequestPersistentID([=](uint32_t idforpants) { - LWOOBJID lwoidforpants = idforpants; - GeneralUtils::SetBit(lwoidforpants, eObjectBits::CHARACTER); - GeneralUtils::SetBit(lwoidforpants, eObjectBits::PERSISTENT); + xml << ""; + xml << ""; - std::stringstream xml3; - xml3 << xmlSave2 << ""; + xml << ""; - xml3 << ""; + //Check to see if our name was pre-approved: + bool nameOk = IsNamePreapproved(name); + if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true; - //Check to see if our name was pre-approved: - bool nameOk = IsNamePreapproved(name); - if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true; + std::string_view nameToAssign = !name.empty() && nameOk ? name : predefinedName; + std::string pendingName = !name.empty() && !nameOk ? name : ""; - std::string_view nameToAssign = !name.empty() && nameOk ? name : predefinedName; - std::string pendingName = !name.empty() && !nameOk ? name : ""; + ICharInfo::Info info; + info.name = nameToAssign; + info.pendingName = pendingName; + info.id = objectID; + info.accountId = u->GetAccountID(); - ICharInfo::Info info; - info.name = nameToAssign; - info.pendingName = pendingName; - info.id = objectID; - info.accountId = u->GetAccountID(); + Database::Get()->InsertNewCharacter(info); - Database::Get()->InsertNewCharacter(info); + //Now finally insert our character xml: + Database::Get()->InsertCharacterXml(objectID, xml.str()); - //Now finally insert our character xml: - Database::Get()->InsertCharacterXml(objectID, xml3.str()); - - WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::SUCCESS); - UserManager::RequestCharacterList(sysAddr); - }); - }); - }); + WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::SUCCESS); + UserManager::RequestCharacterList(sysAddr); + }); } void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) { @@ -466,16 +464,18 @@ void UserManager::LoginCharacter(const SystemAddress& sysAddr, uint32_t playerID uint32_t FindCharShirtID(uint32_t shirtColor, uint32_t shirtStyle) { try { - std::string shirtQuery = "select obj.id from Objects as obj JOIN (select * from ComponentsRegistry as cr JOIN ItemComponent as ic on ic.id = cr.component_id where cr.component_type == 11) as icc on icc.id = obj.id where lower(obj._internalNotes) == \"character create shirt\" AND icc.color1 == "; - shirtQuery += std::to_string(shirtColor); - shirtQuery += " AND icc.decal == "; - shirtQuery = shirtQuery + std::to_string(shirtStyle); - auto tableData = CDClientDatabase::ExecuteQuery(shirtQuery); - auto shirtLOT = tableData.getIntField(0, -1); + auto stmt = CDClientDatabase::CreatePreppedStmt( + "select obj.id from Objects as obj JOIN (select * from ComponentsRegistry as cr JOIN ItemComponent as ic on ic.id = cr.component_id where cr.component_type == 11) as icc on icc.id = obj.id where lower(obj._internalNotes) == ? AND icc.color1 == ? AND icc.decal == ?" + ); + stmt.bind(1, "character create shirt"); + stmt.bind(2, static_cast(shirtColor)); + stmt.bind(3, static_cast(shirtStyle)); + auto tableData = stmt.execQuery(); + auto shirtLOT = tableData.getIntField(0, 4069); tableData.finalize(); return shirtLOT; - } catch (const std::exception&) { - LOG("Failed to execute query! Using backup..."); + } catch (const std::exception& ex) { + LOG("Could not look up shirt %i %i: %s", shirtColor, shirtStyle, ex.what()); // in case of no shirt found in CDServer, return problematic red vest. return 4069; } @@ -483,14 +483,17 @@ uint32_t FindCharShirtID(uint32_t shirtColor, uint32_t shirtStyle) { uint32_t FindCharPantsID(uint32_t pantsColor) { try { - std::string pantsQuery = "select obj.id from Objects as obj JOIN (select * from ComponentsRegistry as cr JOIN ItemComponent as ic on ic.id = cr.component_id where cr.component_type == 11) as icc on icc.id = obj.id where lower(obj._internalNotes) == \"cc pants\" AND icc.color1 == "; - pantsQuery += std::to_string(pantsColor); - auto tableData = CDClientDatabase::ExecuteQuery(pantsQuery); - auto pantsLOT = tableData.getIntField(0, -1); + auto stmt = CDClientDatabase::CreatePreppedStmt( + "select obj.id from Objects as obj JOIN (select * from ComponentsRegistry as cr JOIN ItemComponent as ic on ic.id = cr.component_id where cr.component_type == 11) as icc on icc.id = obj.id where lower(obj._internalNotes) == ? AND icc.color1 == ?" + ); + stmt.bind(1, "cc pants"); + stmt.bind(2, static_cast(pantsColor)); + auto tableData = stmt.execQuery(); + auto pantsLOT = tableData.getIntField(0, 2508); tableData.finalize(); return pantsLOT; - } catch (const std::exception&) { - LOG("Failed to execute query! Using backup..."); + } catch (const std::exception& ex) { + LOG("Could not look up pants %i: %s", pantsColor, ex.what()); // in case of no pants color found in CDServer, return red pants. return 2508; }