Fix character creation tenancy operations

This commit is contained in:
Akkadius 2020-03-31 01:49:42 -05:00
parent 019735c654
commit dae20afcba
14 changed files with 186 additions and 120 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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();
}
};

View File

@ -74,7 +74,7 @@ public:
);
}
static GridEntry Default()
static GridEntry NewEntity()
{
GridEntry entry{};

View File

@ -64,7 +64,7 @@ public:
);
}
static Grid Default()
static Grid NewEntity()
{
Grid entry{};
@ -113,7 +113,7 @@ public:
}
}
return Default();
return NewEntity();
}
};

View File

@ -81,7 +81,7 @@ public:
);
}
static SpawnGroup New()
static SpawnGroup NewEntity()
{
SpawnGroup entry;
@ -155,7 +155,7 @@ public:
}
}
return New();
return NewEntity();
}
};

View File

@ -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) {

View File

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

View File

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

View File

@ -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();

View File

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

View File

@ -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);

View File

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

View File

@ -7141,22 +7141,51 @@ void command_summonitem(Client *c, const Seperator *sep)
item_status = static_cast<int16>(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 + "] "
);