mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-19 17:38:26 +00:00
More stuff
This commit is contained in:
+176
-172
@@ -35,12 +35,10 @@ extern std::vector<RaceClassCombos> character_create_race_class_combos;
|
||||
|
||||
// solar: the current stuff is at the bottom of this function
|
||||
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
Inventory *inv;
|
||||
|
||||
/* Initialize Player Profile for the small time it is being used for item material */
|
||||
PlayerProfile_Struct pp;
|
||||
memset(&pp, 0, sizeof(PlayerProfile_Struct));
|
||||
|
||||
/* Initialize Variables */
|
||||
for (int i=0; i<10; i++) {
|
||||
strcpy(cs->name[i], "<none>");
|
||||
@@ -50,188 +48,194 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*
|
||||
cs->gohome[i] = 0;
|
||||
}
|
||||
|
||||
int char_num = 0;
|
||||
unsigned long* lengths;
|
||||
/* Get Character Info */
|
||||
std::string cquery = StringFormat(
|
||||
"SELECT "
|
||||
"`id`, " // 0
|
||||
"name, " // 1
|
||||
"gender, " // 2
|
||||
"race, " // 3
|
||||
"class, " // 4
|
||||
"`level`, " // 5
|
||||
"deity, " // 6
|
||||
"last_login, " // 7
|
||||
"time_played, " // 8
|
||||
"hair_color, " // 9
|
||||
"beard_color, " // 10
|
||||
"eye_color_1, " // 11
|
||||
"eye_color_2, " // 12
|
||||
"hair_style, " // 13
|
||||
"beard, " // 14
|
||||
"face, " // 15
|
||||
"drakkin_heritage, " // 16
|
||||
"drakkin_tattoo, " // 17
|
||||
"drakkin_details, " // 18
|
||||
"zone_id " // 19
|
||||
"FROM "
|
||||
"character_data "
|
||||
"WHERE `account_id` = %i LIMIT 10 ", account_id);
|
||||
auto results = database.QueryDatabase(cquery); uint16 char_num = 0;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
printf("id is %i \n", atoi(row[0]));
|
||||
uint32 character_id = atoi(row[0]);
|
||||
strcpy(cs->name[char_num], row[1]);
|
||||
uint8 lvl = atoi(row[5]);
|
||||
cs->level[char_num] = lvl;
|
||||
cs->class_[char_num] = atoi(row[4]);
|
||||
cs->race[char_num] = atoi(row[3]);
|
||||
cs->gender[char_num] = atoi(row[2]);
|
||||
cs->deity[char_num] = atoi(row[6]);
|
||||
cs->zone[char_num] = atoi(row[19]);
|
||||
cs->face[char_num] = atoi(row[15]);
|
||||
cs->haircolor[char_num] = atoi(row[9]);
|
||||
cs->beardcolor[char_num] = atoi(row[10]);
|
||||
cs->eyecolor2[char_num] = atoi(row[12]);
|
||||
cs->eyecolor1[char_num] = atoi(row[11]);
|
||||
cs->hairstyle[char_num] = atoi(row[13]);
|
||||
cs->beard[char_num] = atoi(row[14]);
|
||||
cs->drakkin_heritage[char_num] = atoi(row[16]);
|
||||
cs->drakkin_tattoo[char_num] = atoi(row[17]);
|
||||
cs->drakkin_details[char_num] = atoi(row[18]);
|
||||
|
||||
// Populate character info
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
lengths = mysql_fetch_lengths(result);
|
||||
////////////
|
||||
//////////// This is the current one, the other are for converting
|
||||
////////////
|
||||
if ((lengths[1] == sizeof(PlayerProfile_Struct))) {
|
||||
strcpy(cs->name[char_num], row[0]);
|
||||
PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1];
|
||||
uint8 clas = atoi(row[3]);
|
||||
uint8 lvl = atoi(row[4]);
|
||||
if (RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
|
||||
cs->tutorial[char_num] = 1;
|
||||
|
||||
// Character information
|
||||
if(lvl == 0)
|
||||
cs->level[char_num] = pp->level; //no level in DB, trust PP
|
||||
else
|
||||
cs->level[char_num] = lvl;
|
||||
if(clas == 0)
|
||||
cs->class_[char_num] = pp->class_; //no class in DB, trust PP
|
||||
else
|
||||
cs->class_[char_num] = clas;
|
||||
cs->race[char_num] = pp->race;
|
||||
cs->gender[char_num] = pp->gender;
|
||||
cs->deity[char_num] = pp->deity;
|
||||
cs->zone[char_num] = GetZoneID(row[2]);
|
||||
cs->face[char_num] = pp->face;
|
||||
cs->haircolor[char_num] = pp->haircolor;
|
||||
cs->beardcolor[char_num] = pp->beardcolor;
|
||||
cs->eyecolor2[char_num] = pp->eyecolor2;
|
||||
cs->eyecolor1[char_num] = pp->eyecolor1;
|
||||
cs->hairstyle[char_num] = pp->hairstyle;
|
||||
cs->beard[char_num] = pp->beard;
|
||||
cs->drakkin_heritage[char_num] = pp->drakkin_heritage;
|
||||
cs->drakkin_tattoo[char_num] = pp->drakkin_tattoo;
|
||||
cs->drakkin_details[char_num] = pp->drakkin_details;
|
||||
if (RuleB(World, EnableReturnHomeButton)) {
|
||||
int now = time(nullptr);
|
||||
if ((now - atoi(row[8])) >= RuleI(World, MinOfflineTimeToReturnHome))
|
||||
cs->gohome[char_num] = 1;
|
||||
}
|
||||
|
||||
if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
|
||||
cs->tutorial[char_num] = 1;
|
||||
/*
|
||||
This part creates home city entries for characters created before the home bind point was tracked.
|
||||
Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
|
||||
probably be removed at some point, when most accounts are safely converted.
|
||||
*/
|
||||
|
||||
if(RuleB(World, EnableReturnHomeButton)) {
|
||||
int now = time(nullptr);
|
||||
if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome))
|
||||
cs->gohome[char_num] = 1;
|
||||
}
|
||||
/* Load Character Bind Data */
|
||||
cquery = StringFormat("SELECT zone_id, instance_id, x, y, z, heading FROM character_bind_home WHERE `id` = %i LIMIT 1", character_id);
|
||||
auto results_bind = database.QueryDatabase(cquery); int r = 0;
|
||||
for (auto row_b = results_bind.begin(); row_b != results_bind.end(); ++row_b) {
|
||||
uint8 bind_zone_id = atoi(row_b[r]); r++;
|
||||
uint8 bind_instance_id = atoi(row_b[r]); r++;
|
||||
uint8 bind_x_id = atoi(row_b[r]); r++;
|
||||
uint8 bind_y_id = atoi(row_b[r]); r++;
|
||||
uint8 bind_z_id = atoi(row_b[r]); r++;
|
||||
uint8 bind_heading_id = atoi(row_b[r]); r++;
|
||||
}
|
||||
|
||||
// if (pp->binds[4].zoneId == 0) {
|
||||
// bool altered = false;
|
||||
// MYSQL_RES *result2;
|
||||
// MYSQL_ROW row2;
|
||||
// char startzone[50] = { 0 };
|
||||
//
|
||||
// // check for start zone variable (I didn't even know any variables were still being used...)
|
||||
// if (database.GetVariable("startzone", startzone, 50)) {
|
||||
// uint32 zoneid = database.GetZoneID(startzone);
|
||||
// if (zoneid) {
|
||||
// pp->binds[4].zoneId = zoneid;
|
||||
// GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
// altered = true;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// RunQuery(query,
|
||||
// MakeAnyLenString(&query,
|
||||
// "SELECT zone_id,bind_id,x,y,z FROM start_zones "
|
||||
// "WHERE player_class=%i AND player_deity=%i AND player_race=%i",
|
||||
// pp->class_,
|
||||
// pp->deity,
|
||||
// pp->race
|
||||
// ),
|
||||
// errbuf,
|
||||
// &result2
|
||||
// );
|
||||
// safe_delete_array(query);
|
||||
//
|
||||
// // if there is only one possible start city, set it
|
||||
// if (mysql_num_rows(result2) == 1) {
|
||||
// row2 = mysql_fetch_row(result2);
|
||||
// if (atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there
|
||||
// pp->binds[4].zoneId = (uint32)atoi(row2[1]);
|
||||
// GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
// }
|
||||
// else { // otherwise, use the zone and coordinates given
|
||||
// pp->binds[4].zoneId = (uint32)atoi(row2[0]);
|
||||
// float x = atof(row2[2]);
|
||||
// float y = atof(row2[3]);
|
||||
// float z = atof(row2[4]);
|
||||
// if (x == 0 && y == 0 && z == 0)
|
||||
// GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);
|
||||
//
|
||||
// pp->binds[4].x = x;
|
||||
// pp->binds[4].y = y;
|
||||
// pp->binds[4].z = z;
|
||||
// }
|
||||
// altered = true;
|
||||
// }
|
||||
//
|
||||
// mysql_free_result(result2);
|
||||
// }
|
||||
// }
|
||||
|
||||
// This part creates home city entries for characters created before the home bind point was tracked.
|
||||
// Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
|
||||
// probably be removed at some point, when most accounts are safely converted.
|
||||
if(pp->binds[4].zoneId == 0) {
|
||||
bool altered = false;
|
||||
MYSQL_RES *result2;
|
||||
MYSQL_ROW row2;
|
||||
char startzone[50] = {0};
|
||||
/*
|
||||
Character's equipped items
|
||||
@merth: Haven't done bracer01/bracer02 yet.
|
||||
Also: this needs a second look after items are a little more solid
|
||||
NOTE: items don't have a color, players MAY have a tint, if the
|
||||
use_tint part is set. otherwise use the regular color
|
||||
*/
|
||||
|
||||
// check for start zone variable (I didn't even know any variables were still being used...)
|
||||
if(database.GetVariable("startzone", startzone, 50)) {
|
||||
uint32 zoneid = database.GetZoneID(startzone);
|
||||
if(zoneid) {
|
||||
pp->binds[4].zoneId = zoneid;
|
||||
GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RunQuery(query,
|
||||
MakeAnyLenString(&query,
|
||||
"SELECT zone_id,bind_id,x,y,z FROM start_zones "
|
||||
"WHERE player_class=%i AND player_deity=%i AND player_race=%i",
|
||||
pp->class_,
|
||||
pp->deity,
|
||||
pp->race
|
||||
),
|
||||
errbuf,
|
||||
&result2
|
||||
);
|
||||
safe_delete_array(query);
|
||||
/* Load Character Material Data for Char Select */
|
||||
cquery = StringFormat("SELECT slot, use_tint, color FROM `character_material` WHERE `id` = %u", character_id);
|
||||
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
|
||||
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
|
||||
slot = atoi(row_b[0]);
|
||||
if (atoi(row_b[1]) == 1){ pp.item_tint[slot].rgb.use_tint = 0xFF; }
|
||||
pp.item_tint[slot].color = atoul(row_b[2]);
|
||||
printf("charid: %u \n", character_id);
|
||||
printf("slot: %u \n", slot);
|
||||
printf("use_tint: %u item_tint: %u \n", pp.item_tint[slot].rgb.use_tint, atoul(row_b[2]));
|
||||
cs->cs_colors[char_num][slot].color = atoul(row_b[2]);
|
||||
}
|
||||
|
||||
// if there is only one possible start city, set it
|
||||
if(mysql_num_rows(result2) == 1) {
|
||||
row2 = mysql_fetch_row(result2);
|
||||
if(atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there
|
||||
pp->binds[4].zoneId = (uint32)atoi(row2[1]);
|
||||
GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
}
|
||||
else { // otherwise, use the zone and coordinates given
|
||||
pp->binds[4].zoneId = (uint32)atoi(row2[0]);
|
||||
float x = atof(row2[2]);
|
||||
float y = atof(row2[3]);
|
||||
float z = atof(row2[4]);
|
||||
if(x == 0 && y == 0 && z == 0)
|
||||
GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);
|
||||
/* Load Inventory */
|
||||
Inventory *inv;
|
||||
inv = new Inventory;
|
||||
if (GetInventory(account_id, cs->name[char_num], inv)) {
|
||||
for (uint8 material = 0; material <= 8; material++) {
|
||||
uint32 color = 0;
|
||||
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
|
||||
if (item == 0)
|
||||
continue;
|
||||
|
||||
pp->binds[4].x = x;
|
||||
pp->binds[4].y = y;
|
||||
pp->binds[4].z = z;
|
||||
}
|
||||
altered = true;
|
||||
}
|
||||
cs->equip[char_num][material] = item->GetItem()->Material;
|
||||
|
||||
mysql_free_result(result2);
|
||||
}
|
||||
color = pp.item_tint[material].color;
|
||||
// if (pp.item_tint[material].rgb.use_tint){ color = pp.item_tint[material].color; }
|
||||
// else{ color = item->GetItem()->Color; }
|
||||
|
||||
// update the player profile
|
||||
if(altered) {
|
||||
uint32 char_id = GetCharacterID(cs->name[char_num]);
|
||||
RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2);
|
||||
safe_delete_array(query);
|
||||
if(result2) {
|
||||
row2 = mysql_fetch_row(result2);
|
||||
ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0];
|
||||
// SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5);
|
||||
}
|
||||
mysql_free_result(result2);
|
||||
}
|
||||
} // end of "set start zone" block
|
||||
cs->cs_colors[char_num][material].color = color;
|
||||
|
||||
|
||||
// Character's equipped items
|
||||
// @merth: Haven't done bracer01/bracer02 yet.
|
||||
// Also: this needs a second look after items are a little more solid
|
||||
// NOTE: items don't have a color, players MAY have a tint, if the
|
||||
// use_tint part is set. otherwise use the regular color
|
||||
inv = new Inventory;
|
||||
if(GetInventory(account_id, cs->name[char_num], inv))
|
||||
{
|
||||
for (uint8 material = 0; material <= 8; material++)
|
||||
{
|
||||
uint32 color;
|
||||
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
|
||||
if(item == 0)
|
||||
continue;
|
||||
|
||||
cs->equip[char_num][material] = item->GetItem()->Material;
|
||||
|
||||
if(pp->item_tint[material].rgb.use_tint) // they have a tint (LoY dye)
|
||||
color = pp->item_tint[material].color;
|
||||
else // no tint, use regular item color
|
||||
color = item->GetItem()->Color;
|
||||
|
||||
cs->cs_colors[char_num][material].color = color;
|
||||
|
||||
// the weapons are kept elsewhere
|
||||
if ((material==MaterialPrimary) || (material==MaterialSecondary))
|
||||
{
|
||||
if(strlen(item->GetItem()->IDFile) > 2) {
|
||||
uint32 idfile=atoi(&item->GetItem()->IDFile[2]);
|
||||
if (material==MaterialPrimary)
|
||||
cs->primary[char_num]=idfile;
|
||||
else
|
||||
cs->secondary[char_num]=idfile;
|
||||
}
|
||||
}
|
||||
// the weapons are kept elsewhere
|
||||
if ((material == MaterialPrimary) || (material == MaterialSecondary)) {
|
||||
if (strlen(item->GetItem()->IDFile) > 2) {
|
||||
uint32 idfile = atoi(&item->GetItem()->IDFile[2]);
|
||||
if (material == MaterialPrimary)
|
||||
cs->primary[char_num] = idfile;
|
||||
else
|
||||
cs->secondary[char_num] = idfile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error loading inventory for %s\n", cs->name[char_num]);
|
||||
}
|
||||
safe_delete(inv);
|
||||
if (++char_num > 10)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << std::endl;
|
||||
std::cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct) << std::endl;
|
||||
//DeleteCharacter(row[0]);
|
||||
}
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << std::endl;
|
||||
safe_delete_array(query);
|
||||
return;
|
||||
else {
|
||||
printf("Error loading inventory for %s\n", cs->name[char_num]);
|
||||
}
|
||||
safe_delete(inv);
|
||||
if (++char_num > 10)
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user