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;
}