diff --git a/changelog.txt b/changelog.txt index 2e220770e..3a72ea152 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 11/24/2014 == +Trevius: Added Rule NPC:EnableMeritBasedFaction (disabled by default) - Allows faction gain to work similar to experience. + == 11/22/2014 == Trevius: Grouping with Mercenaries is now considerably less buggy. Trevius: Fixed an issue with Spell Globals related to high Character IDs. diff --git a/common/database.cpp b/common/database.cpp index 12ef93223..241c4d171 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -48,6 +48,7 @@ #include "guilds.h" #include "string_util.h" #include "extprofile.h" + extern Client client; #ifdef _WINDOWS @@ -322,20 +323,6 @@ bool Database::ReserveName(uint32 account_id, char* name) { return true; } -bool Database::ThrowDBError(std::string ErrorMessage, std::string query_title, std::string query){ - if (ErrorMessage != ""){ - std::cout << "\nERROR " << query_title << ": " << ErrorMessage << "\n\n" << query << "\n" << std::endl; - - /* Write to log file */ - std::ofstream log("eqemu_query_error_log.txt", std::ios_base::app | std::ios_base::out); - log << "ERROR " << query_title << ": " << ErrorMessage << "\n" << query << "\n"; - log.close(); - - return true; - } - return false; -} - /* Delete the character with the name "name" returns false on failure, true otherwise @@ -354,39 +341,39 @@ bool Database::DeleteCharacter(char *name) { for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); } if (charid <= 0){ std::cerr << "Database::DeleteCharacter :: Character not found, stopping delete...\n"; return false; } - query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `timers` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `inventory` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `char_recipe_list` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `adventure_stats` WHERE `player_id` ='%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `zone_flags` WHERE `charID` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `titles` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `player_titlesets` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `keyring` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `faction_values` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `instance_list_player` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_data` WHERE `id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_skills` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_languages` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_bind` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_currency` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_data` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_spells` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_disciplines` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_material` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_bandolier` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_potionbelt` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); - query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::DeleteCharacter", query); + query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `timers` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `inventory` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `char_recipe_list` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `adventure_stats` WHERE `player_id` ='%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `zone_flags` WHERE `charID` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `titles` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `player_titlesets` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `keyring` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `faction_values` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `instance_list_player` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_data` WHERE `id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_skills` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_languages` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_bind` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_currency` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_data` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_spells` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_disciplines` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_material` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_bandolier` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_potionbelt` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); #ifdef BOTS query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid); #else @@ -674,14 +661,13 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe pp->RestTimer // " RestTimer) " ); auto results = QueryDatabase(query); - ThrowDBError(results.ErrorMessage(), "Database::SaveCharacterCreate Character Data", query); /* Save Bind Points */ query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i), " "(%u, %u, %u, %f, %f, %f, %f, %i)", character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading, 0, character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 1 - ); results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::SaveCharacterCreate Bind Point", query); + ); results = QueryDatabase(query); /* Save Skills */ int firstquery = 0; @@ -696,7 +682,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe } } } - results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::SaveCharacterCreate Starting Skills", query); + results = QueryDatabase(query); /* Save Language */ firstquery = 0; @@ -711,7 +697,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe } } } - results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::SaveCharacterCreate Starting Languages", query); + results = QueryDatabase(query); return true; } @@ -910,10 +896,31 @@ static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50) } bool Database::CheckDatabaseConversions() { + CheckDatabaseConvertPPDeblob(); + CheckDatabaseConvertBotsPostPPDeblob(); + CheckDatabaseConvertCorpseDeblob(); + + /* Fetch Automatic Database Upgrade Script */ + if (!std::ifstream("db_update.pl")){ + std::cout << "Pulling down automatic database upgrade script...\n" << std::endl; +#ifdef _WIN32 + system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl'); if ($response->is_success){ open(FILE, '> db_update.pl'); print FILE $response->decoded_content; close(FILE); }\""); +#else + system("wget -O db_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl"); +#endif + } + + /* Run Automatic Database Upgrade Script */ + system("perl db_update.pl ran_from_world"); + + return true; +} + +bool Database::CheckDatabaseConvertPPDeblob(){ unsigned int lengths; unsigned int lengths_e; std::string squery; - PlayerProfile_Struct* pp; + Convert::PlayerProfile_Struct* pp; ExtendedProfile_Struct* e_pp; uint32 pplen = 0; uint32 i; @@ -924,26 +931,26 @@ bool Database::CheckDatabaseConversions() { int runconvert = 0; /* Check For Legacy Storage Method */ - std::string rquery = StringFormat("SHOW TABLES LIKE 'character_'"); + std::string rquery = StringFormat("SHOW TABLES LIKE 'character_'"); auto results = QueryDatabase(rquery); if (results.RowCount() == 1){ - runconvert = 1; + runconvert = 1; printf("\n\n::: Legacy Character Data Binary Blob Storage Detected... \n"); printf("----------------------------------------------------------\n\n"); - printf(" Database currently has character data being stored via \n"); + printf(" Database currently has character data being stored via \n"); printf(" the legacy character storage method and will proceed with converting...\n\n"); printf(" It is recommended that you backup your database \n"); printf(" before continuing the automatic conversion process...\n\n"); printf("----------------------------------------------------------\n\n"); std::cout << "Press ENTER to continue....." << std::endl << std::endl; - std::cin.ignore(1); + std::cin.ignore(1); } // runconvert = 0; // printppdebug = 1; if (runconvert == 1){ - printf("Running character binary blob to database conversion... \n"); + printf("Running character binary blob to database conversion... \n"); /* Get the number of characters */ rquery = StringFormat("SELECT COUNT(`id`) FROM `character_`"); results = QueryDatabase(rquery); @@ -1061,9 +1068,8 @@ bool Database::CheckDatabaseConversions() { "UNIQUE KEY `name` (`name`), " "KEY `account_id` (`account_id`) " ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_currency` */ @@ -1093,9 +1099,8 @@ bool Database::CheckDatabaseConversions() { " PRIMARY KEY (`id`), " " KEY `id` (`id`) " " ) ENGINE=InnoDB DEFAULT CHARSET=latin1; " - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_alternate_abilities` */ @@ -1112,9 +1117,8 @@ bool Database::CheckDatabaseConversions() { " PRIMARY KEY(`id`,`slot`), " " KEY `id` (`id`) " " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_bind` */ @@ -1134,10 +1138,9 @@ bool Database::CheckDatabaseConversions() { "`heading` float NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`, `is_home`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_languages` */ @@ -1153,9 +1156,8 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`, `lang_id`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_skills` */ @@ -1163,7 +1165,7 @@ bool Database::CheckDatabaseConversions() { results = QueryDatabase(rquery); if (results.RowCount() == 0){ printf("Table: `character_skills` doesn't exist... creating..."); - rquery = StringFormat( + rquery = StringFormat( "CREATE TABLE `character_skills` ( " "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " "`skill_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " @@ -1171,9 +1173,8 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`, `skill_id`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_spells` */ @@ -1189,11 +1190,10 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`, `slot_id`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); - } + } /* Check for table `character_memmed_spells` */ rquery = StringFormat("SHOW TABLES LIKE 'character_memmed_spells'"); results = QueryDatabase(rquery); @@ -1207,10 +1207,9 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`, `slot_id`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); - printf(" done...\n"); + printf(" done...\n"); } /* Check for table `character_disciplines` */ rquery = StringFormat("SHOW TABLES LIKE 'character_disciplines'"); @@ -1224,10 +1223,9 @@ bool Database::CheckDatabaseConversions() { " `disc_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " " PRIMARY KEY(`id`, `slot_id`), " " KEY `id` (`id`) " - " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); + " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_material` */ @@ -1235,7 +1233,7 @@ bool Database::CheckDatabaseConversions() { results = QueryDatabase(rquery); if (results.RowCount() == 0){ printf("Table: `character_material` doesn't exist... creating..."); - rquery = StringFormat( + rquery = StringFormat( "CREATE TABLE `character_material` ( " "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT," "`slot` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," @@ -1247,11 +1245,10 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`, `slot`)," "KEY `id` (`id`)" ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); - } + } /* Check for table `character_tribute` */ rquery = StringFormat("SHOW TABLES LIKE 'character_tribute'"); results = QueryDatabase(rquery); @@ -1264,9 +1261,8 @@ bool Database::CheckDatabaseConversions() { "`tribute` int(11) UNSIGNED NOT NULL DEFAULT '0', " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_bandolier` */ @@ -1285,9 +1281,8 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`,`bandolier_id`, `bandolier_slot`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_potionbelt` */ @@ -1304,9 +1299,8 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`,`potion_id`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_potionbelt` */ @@ -1323,7 +1317,6 @@ bool Database::CheckDatabaseConversions() { ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Check for table `character_leadership_abilities` */ @@ -1339,590 +1332,588 @@ bool Database::CheckDatabaseConversions() { "PRIMARY KEY(`id`,`slot`), " "KEY `id` (`id`) " ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); + ); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Table create", rquery); printf(" done...\n"); } /* Done */ printf("Starting conversion...\n\n"); - } - // Testing account = 11001 - int char_iter_count = 0; - rquery = StringFormat("SELECT `id` FROM `character_`"); - results = QueryDatabase(rquery); - uint8 firstlogon = 0; - uint8 lfg = 0; - uint8 lfp = 0; - std::string mailkey; - uint8 xtargets = 0; - std::string inspectmessage; + int char_iter_count = 0; + rquery = StringFormat("SELECT `id` FROM `character_`"); + results = QueryDatabase(rquery); - for (auto row = results.begin(); row != results.end(); ++row) { - char_iter_count++; - squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", atoi(row[0])); - auto results2 = QueryDatabase(squery); - auto row2 = results2.begin(); - pp = (PlayerProfile_Struct*)row2[1]; - e_pp = (ExtendedProfile_Struct*)row2[11]; - character_id = atoi(row[0]); - account_id = atoi(row2[4]); - /* Convert some data from the character_ table that is still relevant */ - firstlogon = atoi(row2[5]); - lfg = atoi(row2[6]); - lfp = atoi(row2[7]); - mailkey = row2[8]; - xtargets = atoi(row2[9]); - inspectmessage = row2[10]; + uint8 firstlogon = 0; + uint8 lfg = 0; + uint8 lfp = 0; + std::string mailkey; + uint8 xtargets = 0; + std::string inspectmessage; - /* Verify PP Integrity */ - lengths = results2.LengthOfColumn(1); - if (lengths == sizeof(PlayerProfile_Struct)) { /* If PP is the size it is expected to be */ - memcpy(pp, row2[1], sizeof(PlayerProfile_Struct)); - } - /* Continue of PP Size does not match (Usually a created character never logged in) */ - else { - // printf("%s ID: %i profile mismatch, not converting. PP %u - Profile Length %u \n", row2[2] ? row2[2] : "Unknown", character_id, sizeof(PlayerProfile_Struct), lengths); - std::cout << (row2[2] ? row2[2] : "Unknown") << " ID: " << character_id << " size mismatch. Expected Size: " << sizeof(PlayerProfile_Struct) << " Seen: " << lengths << std::endl; - continue; - } + for (auto row = results.begin(); row != results.end(); ++row) { + char_iter_count++; + squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", atoi(row[0])); + auto results2 = QueryDatabase(squery); + auto row2 = results2.begin(); + pp = (Convert::PlayerProfile_Struct*)row2[1]; + e_pp = (ExtendedProfile_Struct*)row2[11]; + character_id = atoi(row[0]); + account_id = atoi(row2[4]); + /* Convert some data from the character_ table that is still relevant */ + firstlogon = atoi(row2[5]); + lfg = atoi(row2[6]); + lfp = atoi(row2[7]); + mailkey = row2[8]; + xtargets = atoi(row2[9]); + inspectmessage = row2[10]; - lengths_e = results2.LengthOfColumn(11); - if (lengths_e == sizeof(ExtendedProfile_Struct)) { - memcpy(e_pp, row2[11], sizeof(ExtendedProfile_Struct)); - } - if (e_pp->expended_aa > 4000000){ e_pp->expended_aa = 0; } - - /* Loading Status on conversion */ - if (runconvert == 1){ - std::cout << "\r" << char_iter_count << "/" << number_of_characters << " " << std::flush; - loadbar(char_iter_count, number_of_characters, 50); - - /* Run inspect message convert */ - if (inspectmessage != ""){ - std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)" - "VALUES (%u, '%s')", - character_id, - EscapeString(inspectmessage).c_str() - ); - auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Character Inspect Message Convert", rquery); + /* Verify PP Integrity */ + lengths = results2.LengthOfColumn(1); + if (lengths == sizeof(Convert::PlayerProfile_Struct)) { /* If PP is the size it is expected to be */ + memcpy(pp, row2[1], sizeof(Convert::PlayerProfile_Struct)); + } + /* Continue of PP Size does not match (Usually a created character never logged in) */ + else { + // printf("%s ID: %i profile mismatch, not converting. PP %u - Profile Length %u \n", row2[2] ? row2[2] : "Unknown", character_id, sizeof(PlayerProfile_Struct), lengths); + std::cout << (row2[2] ? row2[2] : "Unknown") << " ID: " << character_id << " size mismatch. Expected Size: " << sizeof(Convert::PlayerProfile_Struct) << " Seen: " << lengths << std::endl; + continue; } - /* Run Currency Convert */ - std::string rquery = StringFormat("REPLACE INTO `character_currency` (id, platinum, gold, silver, copper," - "platinum_bank, gold_bank, silver_bank, copper_bank," - "platinum_cursor, gold_cursor, silver_cursor, copper_cursor, " - "radiant_crystals, career_radiant_crystals, ebon_crystals, career_ebon_crystals)" - "VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", - character_id, - pp->platinum, - pp->gold, - pp->silver, - pp->copper, - pp->platinum_bank, - pp->gold_bank, - pp->silver_bank, - pp->copper_bank, - pp->platinum_cursor, - pp->gold_cursor, - pp->silver_cursor, - pp->copper_cursor, - pp->currentRadCrystals, - pp->careerRadCrystals, - pp->currentEbonCrystals, - pp->careerEbonCrystals - ); - auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Character Currency Convert", rquery); + lengths_e = results2.LengthOfColumn(11); + if (lengths_e == sizeof(ExtendedProfile_Struct)) { + memcpy(e_pp, row2[11], sizeof(ExtendedProfile_Struct)); + } + if (e_pp->expended_aa > 4000000){ e_pp->expended_aa = 0; } - if (pp->tribute_time_remaining < 0 || pp->tribute_time_remaining == 4294967295){ pp->tribute_time_remaining = 0; } + /* Loading Status on conversion */ + if (runconvert == 1){ + std::cout << "\r" << char_iter_count << "/" << number_of_characters << " " << std::flush; + loadbar(char_iter_count, number_of_characters, 50); - /* Run Character Data Convert */ - rquery = StringFormat( - "REPLACE INTO `character_data` (" - "id," - "account_id," - "`name`," - "last_name," - "gender," - "race," - "class," - "`level`," - "deity," - "birthday," - "last_login," - "time_played," - "pvp_status," - "level2," - "anon," - "gm," - "intoxication," - "hair_color," - "beard_color," - "eye_color_1," - "eye_color_2," - "hair_style," - "beard," - "ability_time_seconds," - "ability_number," - "ability_time_minutes," - "ability_time_hours," - "title," - "suffix," - "exp," - "points," - "mana," - "cur_hp," - "str," - "sta," - "cha," - "dex," - "`int`," - "agi," - "wis," - "face," - "y," - "x," - "z," - "heading," - "pvp2," - "pvp_type," - "autosplit_enabled," - "zone_change_count," - "drakkin_heritage," - "drakkin_tattoo," - "drakkin_details," - "toxicity," - "hunger_level," - "thirst_level," - "ability_up," - "zone_id," - "zone_instance," - "leadership_exp_on," - "ldon_points_guk," - "ldon_points_mir," - "ldon_points_mmc," - "ldon_points_ruj," - "ldon_points_tak," - "ldon_points_available," - "tribute_time_remaining," - "show_helm," - "career_tribute_points," - "tribute_points," - "tribute_active," - "endurance," - "group_leadership_exp," - "raid_leadership_exp," - "group_leadership_points," - "raid_leadership_points," - "air_remaining," - "pvp_kills," - "pvp_deaths," - "pvp_current_points," - "pvp_career_points," - "pvp_best_kill_streak," - "pvp_worst_death_streak," - "pvp_current_kill_streak," - "aa_points_spent," - "aa_exp," - "aa_points," - "group_auto_consent," - "raid_auto_consent," - "guild_auto_consent," - "RestTimer," - "firstlogon," - "lfg," - "lfp," - "mailkey," - "xtargets," - "e_aa_effects," - "e_percent_to_aa," - "e_expended_aa_spent" - ")" - "VALUES (" - "%u," // id - "%u," // account_id - "'%s'," // `name` - "'%s'," // last_name - "%u," // gender - "%u," // race - "%u," // class - "%u," // `level` - "%u," // deity - "%u," // birthday - "%u," // last_login - "%u," // time_played - "%u," // pvp_status - "%u," // level2 - "%u," // anon - "%u," // gm - "%u," // intoxication - "%u," // hair_color - "%u," // beard_color - "%u," // eye_color_1 - "%u," // eye_color_2 - "%u," // hair_style - "%u," // beard - "%u," // ability_time_seconds - "%u," // ability_number - "%u," // ability_time_minutes - "%u," // ability_time_hours - "'%s'," // title - "'%s'," // suffix - "%u," // exp - "%u," // points - "%u," // mana - "%u," // cur_hp - "%u," // str - "%u," // sta - "%u," // cha - "%u," // dex - "%u," // `int` - "%u," // agi - "%u," // wis - "%u," // face - "%f," // y - "%f," // x - "%f," // z - "%f," // heading - "%u," // pvp2 - "%u," // pvp_type - "%u," // autosplit_enabled - "%u," // zone_change_count - "%u," // drakkin_heritage - "%u," // drakkin_tattoo - "%u," // drakkin_details - "%i," // toxicity - "%u," // hunger_level - "%u," // thirst_level - "%u," // ability_up - "%u," // zone_id - "%u," // zone_instance - "%u," // leadership_exp_on - "%u," // ldon_points_guk - "%u," // ldon_points_mir - "%u," // ldon_points_mmc - "%u," // ldon_points_ruj - "%u," // ldon_points_tak - "%u," // ldon_points_available - "%u," // tribute_time_remaining - "%u," // show_helm - "%u," // career_tribute_points - "%u," // tribute_points - "%u," // tribute_active - "%u," // endurance - "%u," // group_leadership_exp - "%u," // raid_leadership_exp - "%u," // group_leadership_points - "%u," // raid_leadership_points - "%u," // air_remaining - "%u," // pvp_kills - "%u," // pvp_deaths - "%u," // pvp_current_points - "%u," // pvp_career_points - "%u," // pvp_best_kill_streak - "%u," // pvp_worst_death_streak - "%u," // pvp_current_kill_streak - "%u," // aa_points_spent - "%u," // aa_exp - "%u," // aa_points - "%u," // group_auto_consent - "%u," // raid_auto_consent - "%u," // guild_auto_consent - "%u," // RestTimer - "%u," // First Logon - References online status for EVENT_CONNECT/EVENT_DISCONNECt - "%u," // Looking for Group - "%u," // Looking for P? - "'%s'," // Mailkey - "%u," // X Targets - "%u," // AA Effects - "%u," // Percent to AA - "%u" // e_expended_aa_spent - ")", - character_id, - account_id, - EscapeString(pp->name).c_str(), - EscapeString(pp->last_name).c_str(), - pp->gender, - pp->race, - pp->class_, - pp->level, - pp->deity, - pp->birthday, - pp->lastlogin, - pp->timePlayedMin, - pp->pvp, - pp->level2, - pp->anon, - pp->gm, - pp->intoxication, - pp->haircolor, - pp->beardcolor, - pp->eyecolor1, - pp->eyecolor2, - pp->hairstyle, - pp->beard, - pp->ability_time_seconds, - pp->ability_number, - pp->ability_time_minutes, - pp->ability_time_hours, - EscapeString(pp->title).c_str(), - EscapeString(pp->suffix).c_str(), - pp->exp, - pp->points, - pp->mana, - pp->cur_hp, - pp->STR, - pp->STA, - pp->CHA, - pp->DEX, - pp->INT, - pp->AGI, - pp->WIS, - pp->face, - pp->y, - pp->x, - pp->z, - pp->heading, - pp->pvp2, - pp->pvptype, - pp->autosplit, - pp->zone_change_count, - pp->drakkin_heritage, - pp->drakkin_tattoo, - pp->drakkin_details, - pp->toxicity, - pp->hunger_level, - pp->thirst_level, - pp->ability_up, - pp->zone_id, - pp->zoneInstance, - pp->leadAAActive == 0 ? 0 : 1, - pp->ldon_points_guk, - pp->ldon_points_mir, - pp->ldon_points_mmc, - pp->ldon_points_ruj, - pp->ldon_points_tak, - pp->ldon_points_available, - pp->tribute_time_remaining, - pp->showhelm, - pp->career_tribute_points, - pp->tribute_points, - pp->tribute_active, - pp->endurance, - pp->group_leadership_exp, - pp->raid_leadership_exp, - pp->group_leadership_points, - pp->raid_leadership_points, - pp->air_remaining, - pp->PVPKills, - pp->PVPDeaths, - pp->PVPCurrentPoints, - pp->PVPCareerPoints, - pp->PVPBestKillStreak, - pp->PVPWorstDeathStreak, - pp->PVPCurrentKillStreak, - pp->aapoints_spent, - pp->expAA, - pp->aapoints, - pp->groupAutoconsent, - pp->raidAutoconsent, - pp->guildAutoconsent, - pp->RestTimer, - firstlogon, - lfg, - lfp, - mailkey.c_str(), - xtargets, - e_pp->aa_effects, - e_pp->perAA, - e_pp->expended_aa - ); - results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Character Data Convert", rquery); - + /* Run inspect message convert */ + if (inspectmessage != ""){ + std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)" + "VALUES (%u, '%s')", + character_id, + EscapeString(inspectmessage).c_str() + ); + auto results = QueryDatabase(rquery); + } - /* + /* Run Currency Convert */ + std::string rquery = StringFormat("REPLACE INTO `character_currency` (id, platinum, gold, silver, copper," + "platinum_bank, gold_bank, silver_bank, copper_bank," + "platinum_cursor, gold_cursor, silver_cursor, copper_cursor, " + "radiant_crystals, career_radiant_crystals, ebon_crystals, career_ebon_crystals)" + "VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", + character_id, + pp->platinum, + pp->gold, + pp->silver, + pp->copper, + pp->platinum_bank, + pp->gold_bank, + pp->silver_bank, + pp->copper_bank, + pp->platinum_cursor, + pp->gold_cursor, + pp->silver_cursor, + pp->copper_cursor, + pp->currentRadCrystals, + pp->careerRadCrystals, + pp->currentEbonCrystals, + pp->careerEbonCrystals + ); + auto results = QueryDatabase(rquery); + + if (pp->tribute_time_remaining < 0 || pp->tribute_time_remaining == 4294967295){ pp->tribute_time_remaining = 0; } + + /* Run Character Data Convert */ + rquery = StringFormat( + "REPLACE INTO `character_data` (" + "id," + "account_id," + "`name`," + "last_name," + "gender," + "race," + "class," + "`level`," + "deity," + "birthday," + "last_login," + "time_played," + "pvp_status," + "level2," + "anon," + "gm," + "intoxication," + "hair_color," + "beard_color," + "eye_color_1," + "eye_color_2," + "hair_style," + "beard," + "ability_time_seconds," + "ability_number," + "ability_time_minutes," + "ability_time_hours," + "title," + "suffix," + "exp," + "points," + "mana," + "cur_hp," + "str," + "sta," + "cha," + "dex," + "`int`," + "agi," + "wis," + "face," + "y," + "x," + "z," + "heading," + "pvp2," + "pvp_type," + "autosplit_enabled," + "zone_change_count," + "drakkin_heritage," + "drakkin_tattoo," + "drakkin_details," + "toxicity," + "hunger_level," + "thirst_level," + "ability_up," + "zone_id," + "zone_instance," + "leadership_exp_on," + "ldon_points_guk," + "ldon_points_mir," + "ldon_points_mmc," + "ldon_points_ruj," + "ldon_points_tak," + "ldon_points_available," + "tribute_time_remaining," + "show_helm," + "career_tribute_points," + "tribute_points," + "tribute_active," + "endurance," + "group_leadership_exp," + "raid_leadership_exp," + "group_leadership_points," + "raid_leadership_points," + "air_remaining," + "pvp_kills," + "pvp_deaths," + "pvp_current_points," + "pvp_career_points," + "pvp_best_kill_streak," + "pvp_worst_death_streak," + "pvp_current_kill_streak," + "aa_points_spent," + "aa_exp," + "aa_points," + "group_auto_consent," + "raid_auto_consent," + "guild_auto_consent," + "RestTimer," + "firstlogon," + "lfg," + "lfp," + "mailkey," + "xtargets," + "e_aa_effects," + "e_percent_to_aa," + "e_expended_aa_spent" + ")" + "VALUES (" + "%u," // id + "%u," // account_id + "'%s'," // `name` + "'%s'," // last_name + "%u," // gender + "%u," // race + "%u," // class + "%u," // `level` + "%u," // deity + "%u," // birthday + "%u," // last_login + "%u," // time_played + "%u," // pvp_status + "%u," // level2 + "%u," // anon + "%u," // gm + "%u," // intoxication + "%u," // hair_color + "%u," // beard_color + "%u," // eye_color_1 + "%u," // eye_color_2 + "%u," // hair_style + "%u," // beard + "%u," // ability_time_seconds + "%u," // ability_number + "%u," // ability_time_minutes + "%u," // ability_time_hours + "'%s'," // title + "'%s'," // suffix + "%u," // exp + "%u," // points + "%u," // mana + "%u," // cur_hp + "%u," // str + "%u," // sta + "%u," // cha + "%u," // dex + "%u," // `int` + "%u," // agi + "%u," // wis + "%u," // face + "%f," // y + "%f," // x + "%f," // z + "%f," // heading + "%u," // pvp2 + "%u," // pvp_type + "%u," // autosplit_enabled + "%u," // zone_change_count + "%u," // drakkin_heritage + "%u," // drakkin_tattoo + "%u," // drakkin_details + "%i," // toxicity + "%u," // hunger_level + "%u," // thirst_level + "%u," // ability_up + "%u," // zone_id + "%u," // zone_instance + "%u," // leadership_exp_on + "%u," // ldon_points_guk + "%u," // ldon_points_mir + "%u," // ldon_points_mmc + "%u," // ldon_points_ruj + "%u," // ldon_points_tak + "%u," // ldon_points_available + "%u," // tribute_time_remaining + "%u," // show_helm + "%u," // career_tribute_points + "%u," // tribute_points + "%u," // tribute_active + "%u," // endurance + "%u," // group_leadership_exp + "%u," // raid_leadership_exp + "%u," // group_leadership_points + "%u," // raid_leadership_points + "%u," // air_remaining + "%u," // pvp_kills + "%u," // pvp_deaths + "%u," // pvp_current_points + "%u," // pvp_career_points + "%u," // pvp_best_kill_streak + "%u," // pvp_worst_death_streak + "%u," // pvp_current_kill_streak + "%u," // aa_points_spent + "%u," // aa_exp + "%u," // aa_points + "%u," // group_auto_consent + "%u," // raid_auto_consent + "%u," // guild_auto_consent + "%u," // RestTimer + "%u," // First Logon - References online status for EVENT_CONNECT/EVENT_DISCONNECt + "%u," // Looking for Group + "%u," // Looking for P? + "'%s'," // Mailkey + "%u," // X Targets + "%u," // AA Effects + "%u," // Percent to AA + "%u" // e_expended_aa_spent + ")", + character_id, + account_id, + EscapeString(pp->name).c_str(), + EscapeString(pp->last_name).c_str(), + pp->gender, + pp->race, + pp->class_, + pp->level, + pp->deity, + pp->birthday, + pp->lastlogin, + pp->timePlayedMin, + pp->pvp, + pp->level2, + pp->anon, + pp->gm, + pp->intoxication, + pp->haircolor, + pp->beardcolor, + pp->eyecolor1, + pp->eyecolor2, + pp->hairstyle, + pp->beard, + pp->ability_time_seconds, + pp->ability_number, + pp->ability_time_minutes, + pp->ability_time_hours, + EscapeString(pp->title).c_str(), + EscapeString(pp->suffix).c_str(), + pp->exp, + pp->points, + pp->mana, + pp->cur_hp, + pp->STR, + pp->STA, + pp->CHA, + pp->DEX, + pp->INT, + pp->AGI, + pp->WIS, + pp->face, + pp->y, + pp->x, + pp->z, + pp->heading, + pp->pvp2, + pp->pvptype, + pp->autosplit, + pp->zone_change_count, + pp->drakkin_heritage, + pp->drakkin_tattoo, + pp->drakkin_details, + pp->toxicity, + pp->hunger_level, + pp->thirst_level, + pp->ability_up, + pp->zone_id, + pp->zoneInstance, + pp->leadAAActive == 0 ? 0 : 1, + pp->ldon_points_guk, + pp->ldon_points_mir, + pp->ldon_points_mmc, + pp->ldon_points_ruj, + pp->ldon_points_tak, + pp->ldon_points_available, + pp->tribute_time_remaining, + pp->showhelm, + pp->career_tribute_points, + pp->tribute_points, + pp->tribute_active, + pp->endurance, + pp->group_leadership_exp, + pp->raid_leadership_exp, + pp->group_leadership_points, + pp->raid_leadership_points, + pp->air_remaining, + pp->PVPKills, + pp->PVPDeaths, + pp->PVPCurrentPoints, + pp->PVPCareerPoints, + pp->PVPBestKillStreak, + pp->PVPWorstDeathStreak, + pp->PVPCurrentKillStreak, + pp->aapoints_spent, + pp->expAA, + pp->aapoints, + pp->groupAutoconsent, + pp->raidAutoconsent, + pp->guildAutoconsent, + pp->RestTimer, + firstlogon, + lfg, + lfp, + mailkey.c_str(), + xtargets, + e_pp->aa_effects, + e_pp->perAA, + e_pp->expended_aa + ); + results = QueryDatabase(rquery); + + + /* We set a first entry variable because we need the first initial piece of the query to be declared This is to speed up the INSERTS and trim down the amount of individual sends during the process. The speed difference is dramatic - */ - /* Run AA Convert */ - int first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_AA_ARRAY; i++){ - if (pp->aa_array[i].AA > 0 && pp->aa_array[i].value > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)" - " VALUES (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); - first_entry = 1; - } else { - rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); - } - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "AA Convert", rquery); } - - /* Run Bind Home Convert */ - if(pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) { - rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" - " VALUES (%u, %u, %u, %f, %f, %f, %f, 1)", - character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading); - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Bind Home Convert", rquery); } - } - - /* Run Bind Convert */ - if(pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) { - rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" - " VALUES (%u, %u, %u, %f, %f, %f, %f, 0)", - character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading); - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Bind Convert", rquery); } - } - /* Run Language Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_LANGUAGE; i++){ - if (pp->languages[i] > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Language Convert", rquery); } - /* Run Skill Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_SKILL; i++){ - if (pp->skills[i] > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Skills Convert Convert", rquery); } - /* Run Spell Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){ - if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->spell_book[i]); - } - } - // std::cout << rquery << "\n"; - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Spell Convert", rquery); } - /* Run Max Memmed Spell Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){ - if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->mem_spells[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Memmed Spells Convert", rquery); } - /* Run Discipline Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_DISCIPLINES; i++){ - if(pp->disciplines.values[i] > 0 && pp->disciplines.values[i] < 60000){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Discipline Convert", rquery); } - /* Run Material Color Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < _MaterialCount; i++){ - if (pp->item_tint[i].color > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Material Convert", rquery); } - /* Run Tribute Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ - if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Tribute Convert", rquery); } - /* Run Bandolier Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){ - if(strlen(pp->bandoliers[i].name) < 32) { - for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){ - if (pp->bandoliers[i].items[si].item_id > 0){ - if (first_entry != 1) { - rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); + */ + /* Run AA Convert */ + int first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_AA_ARRAY; i++){ + if (pp->aa_array[i].AA > 0 && pp->aa_array[i].value > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)" + " VALUES (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); + first_entry = 1; + } + else { + rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); } } } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Bandolier Convert", rquery); } - /* Run Potion Belt Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){ - if (pp->potionbelt.items[i].item_id > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Bind Home Convert */ + if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) { + rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + " VALUES (%u, %u, %u, %f, %f, %f, %f, 1)", + character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading); + if (rquery != ""){ results = QueryDatabase(rquery); } } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Potion Belt Convert", rquery); } - /* Run Leadership AA Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){ - if(pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); - first_entry = 1; + + /* Run Bind Convert */ + if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) { + rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + " VALUES (%u, %u, %u, %f, %f, %f, %f, 0)", + character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading); + if (rquery != ""){ results = QueryDatabase(rquery); } + } + /* Run Language Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_LANGUAGE; i++){ + if (pp->languages[i] > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]); } - rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); } - } - if (rquery != ""){ results = QueryDatabase(rquery); ThrowDBError(results.ErrorMessage(), "Character Leadership AA Convert", rquery); } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Skill Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_SKILL; i++){ + if (pp->skills[i] > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Spell Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){ + if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->spell_book[i]); + } + } + // std::cout << rquery << "\n"; + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Max Memmed Spell Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){ + if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->mem_spells[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Discipline Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_DISCIPLINES; i++){ + if (pp->disciplines.values[i] > 0 && pp->disciplines.values[i] < 60000){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Material Color Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < _MaterialCount; i++){ + if (pp->item_tint[i].color > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Tribute Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ + if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Bandolier Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){ + if (strlen(pp->bandoliers[i].name) < 32) { + for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){ + if (pp->bandoliers[i].items[si].item_id > 0){ + if (first_entry != 1) { + rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); + } + } + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Potion Belt Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){ + if (pp->potionbelt.items[i].item_id > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); + + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Leadership AA Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){ + if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + } + } + if (runconvert == 1){ + std::string rquery = StringFormat("RENAME TABLE `character_` TO `character_old`"); QueryDatabase(rquery); + printf("\n\nRenaming `character_` table to `character_old`, this is a LARGE table so when you don't need it anymore, I would suggest deleting it yourself...\n"); + printf("\n\nCharacter blob conversion complete, continuing world bootup...\n"); } } - if (runconvert == 1){ - std::string rquery = StringFormat("RENAME TABLE `character_` TO `character_old`"); QueryDatabase(rquery); - printf("\n\nRenaming `character_` table to `character_old`, this is a LARGE table so when you don't need it anymore, I would suggest deleting it yourself...\n"); - printf("\n\nCharacter blob conversion complete, continuing world bootup...\n"); - } - + return true; +} +bool Database::CheckDatabaseConvertBotsPostPPDeblob(){ #ifdef BOTS - int runbotsconvert = 0; /* Check For Legacy Bot References */ - rquery = StringFormat("SHOW CREATE VIEW `vwBotCharacterMobs`"); - results = QueryDatabase(rquery); + std::string rquery = StringFormat("SHOW CREATE VIEW `vwBotCharacterMobs`"); + auto results = QueryDatabase(rquery); if (results.RowCount() == 1){ auto row = results.begin(); std::string table_check = row[1]; @@ -1940,9 +1931,6 @@ bool Database::CheckDatabaseConversions() { std::cin.ignore(1); } } - else{ - ThrowDBError(results.ErrorMessage(), "Bot View Discovery", rquery); - } if (runbotsconvert == 1){ printf("Running bot views/function database conversion... \n"); @@ -1950,7 +1938,6 @@ bool Database::CheckDatabaseConversions() { /* Update view `vwbotcharactermobs` */ rquery = StringFormat("DROP VIEW `vwBotCharacterMobs`;"); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Drop View `vwBotCharacterMobs`", rquery); rquery = StringFormat( "CREATE VIEW `vwBotCharacterMobs` AS\n" @@ -1973,13 +1960,11 @@ bool Database::CheckDatabaseConversions() { "FROM bots AS b;" ); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Create View `vwBotCharacterMobs`", rquery); /* Update function `GetMobType` */ rquery = StringFormat("DROP FUNCTION IF EXISTS `GetMobType`;"); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Drop Function `GetMobType`", rquery); rquery = StringFormat( "CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)\n" @@ -1998,13 +1983,11 @@ bool Database::CheckDatabaseConversions() { "END" ); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Create Function `GetMobType`", rquery); /* Update view `vwgroups` */ rquery = StringFormat("DROP VIEW IF EXISTS `vwGroups`;"); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Drop View `vwGroups`", rquery); rquery = StringFormat( "CREATE VIEW `vwGroups` AS\n" @@ -2018,13 +2001,11 @@ bool Database::CheckDatabaseConversions() { "LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;" ); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Create View `vwGroups`", rquery); /* Update view `vwbotgroups` */ rquery = StringFormat("DROP VIEW IF EXISTS `vwBotGroups`;"); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Drop View `vwBotGroups`", rquery); rquery = StringFormat( "CREATE VIEW `vwBotGroups` AS\n" @@ -2040,13 +2021,11 @@ bool Database::CheckDatabaseConversions() { "ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;" ); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Create View `vwBotGroups`", rquery); /* Update view `vwguildmembers` */ rquery = StringFormat("DROP VIEW IF EXISTS `vwGuildMembers`;"); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Drop View `vwGuildMembers`", rquery); rquery = StringFormat( "CREATE VIEW `vwGuildMembers` AS\n" @@ -2075,7 +2054,6 @@ bool Database::CheckDatabaseConversions() { "FROM `botguildmembers` AS bm;" ); results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "Create View `vwGuildMembers`", rquery); } if (runbotsconvert == 1){ @@ -2083,20 +2061,348 @@ bool Database::CheckDatabaseConversions() { } #endif + return true; +} - /* Fetch Automatic Database Upgrade Script */ - if (!std::ifstream("db_update.pl")){ - std::cout << "Pulling down automatic database upgrade script...\n" << std::endl; -#ifdef _WIN32 - system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl'); if ($response->is_success){ open(FILE, '> db_update.pl'); print FILE $response->decoded_content; close(FILE); }\""); -#else - system("wget -O db_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl"); -#endif +bool Database::CheckDatabaseConvertCorpseDeblob(){ + Convert::DBPlayerCorpse_Struct_temp* dbpc; + Convert::classic_db_temp::DBPlayerCorpse_Struct_temp* dbpc_c; + uint32 in_datasize; + bool is_sof = false; + std::string c_type; + std::string scquery; + int8 first_entry = 0; + + std::string query = StringFormat("SHOW TABLES LIKE 'player_corpses'"); + auto results = QueryDatabase(query); + if (results.RowCount() != 0){ + query = StringFormat( + "CREATE TABLE `character_corpse_items` ( " + "`corpse_id` int(11) unsigned NOT NULL, " + "`equip_slot` int(11) unsigned NOT NULL, " + "`item_id` int(11) unsigned DEFAULT NULL, " + "`charges` int(11) unsigned DEFAULT NULL, " + "`aug_1` int(11) unsigned DEFAULT '0', " + "`aug_2` int(11) unsigned DEFAULT '0', " + "`aug_3` int(11) unsigned DEFAULT '0', " + "`aug_4` int(11) unsigned DEFAULT '0', " + "`aug_5` int(11) unsigned DEFAULT '0', " + "`attuned` smallint(5) NOT NULL DEFAULT '0', " + "PRIMARY KEY(`corpse_id`, `equip_slot`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); + results = QueryDatabase(query); + query = StringFormat("RENAME TABLE `player_corpses` TO `character_corpses`"); + results = QueryDatabase(query); + query = StringFormat( + " ALTER TABLE `character_corpses` \n" + " ADD COLUMN `is_locked` tinyint(11) NULL DEFAULT 0 AFTER `WasAtGraveyard`, \n" + " ADD COLUMN `exp` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `size` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `level` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `race` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `gender` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `class` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `deity` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `texture` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `helm_texture` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `copper` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `silver` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `gold` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `platinum` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `hair_color` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `beard_color` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `eye_color_1` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `eye_color_2` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `hair_style` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `face` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `beard` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `drakkin_heritage` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `drakkin_tattoo` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `drakkin_details` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_1` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_2` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_3` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_4` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_5` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_6` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_7` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_8` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_9` int(11) UNSIGNED NULL DEFAULT 0, \n" + " CHANGE COLUMN `zoneid` `zone_id` smallint(5) NOT NULL DEFAULT 0 AFTER `charname`, \n" + " CHANGE COLUMN `instanceid` `instance_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `zone_id`, \n" + " CHANGE COLUMN `timeofdeath` `time_of_death` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `data`, \n" + " CHANGE COLUMN `rezzed` `is_rezzed` tinyint(3) UNSIGNED NULL DEFAULT 0 AFTER `time_of_death`, \n" + " CHANGE COLUMN `IsBurried` `is_buried` tinyint(3) NOT NULL DEFAULT 0 AFTER `is_rezzed`; \n" + + ); + results = QueryDatabase(query); + query = StringFormat( + " ALTER TABLE `character_corpses` \n" + " CHANGE COLUMN `WasAtGraveyard` `was_at_graveyard` tinyint(3) NOT NULL DEFAULT 0 AFTER `is_buried` \n" + ); + results = QueryDatabase(query); } - /* Run Automatic Database Upgrade Script */ - system("perl db_update.pl ran_from_world"); + std::string rquery = StringFormat("SHOW COLUMNS FROM `character_corpses` LIKE 'data'"); + results = QueryDatabase(rquery); + if (results.RowCount() != 0){ + rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses"); + results = QueryDatabase(rquery); + for (auto row = results.begin(); row != results.end(); ++row) { + std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", atoi(row[0])); + auto results2 = QueryDatabase(squery); + for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) { + in_datasize = results2.LengthOfColumn(2); + dbpc = (Convert::DBPlayerCorpse_Struct_temp*)row2[2]; + dbpc_c = (Convert::classic_db_temp::DBPlayerCorpse_Struct_temp*)row2[2]; + if (dbpc == nullptr) + continue; + if (dbpc_c == nullptr) + continue; + + + /* SoF+ */ + uint32 esize1 = (sizeof(Convert::DBPlayerCorpse_Struct_temp) + (dbpc->itemcount * sizeof(Convert::player_lootitem_temp::ServerLootItem_Struct_temp))); + uint32 esize2 = (sizeof(Convert::classic_db_temp::DBPlayerCorpse_Struct_temp) + (dbpc_c->itemcount * sizeof(Convert::player_lootitem_temp::ServerLootItem_Struct_temp))); + + /* SoF */ + if (in_datasize == esize1) { + is_sof = true; + c_type = "SOF"; + } + /* Classic */ + if (in_datasize == esize2) { + is_sof = false; + c_type = "Legacy"; + } + if (in_datasize != esize2 && in_datasize != esize1) { + // std::cout << "[Error] in Corpse Size - OLD SIZE: " << esize1 << " SOF SIZE: " << esize2 << " db_blob_datasize: " << in_datasize << std::endl; + is_sof = false; + c_type = "NULL"; + continue; + } + std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << atoi(row2[0]) << std::endl; + + if (is_sof){ + scquery = StringFormat("UPDATE `character_corpses` SET \n" + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`drakkin_heritage` = %u,\n" + "`drakkin_tattoo` = %u,\n" + "`drakkin_details` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n" + "WHERE `id` = %u \n", + dbpc->locked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color, + atoi(row2[0]) + ); + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + + first_entry = 0; + scquery = ""; + /* Print Items */ + for (unsigned int i = 0; i < dbpc->itemcount; i++) { + if (first_entry != 1){ + scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc->items[i].equipSlot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug1, + dbpc->items[i].aug2, + dbpc->items[i].aug3, + dbpc->items[i].aug4, + dbpc->items[i].aug5 + ); + first_entry = 1; + } + else{ + scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc->items[i].equipSlot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug1, + dbpc->items[i].aug2, + dbpc->items[i].aug3, + dbpc->items[i].aug4, + dbpc->items[i].aug5 + ); + } + } + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + } + else{ + /* Classic Converter */ + scquery = StringFormat("UPDATE `character_corpses` SET \n" + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n" + "WHERE `id` = %u \n", + dbpc_c->locked, + dbpc_c->exp, + dbpc_c->size, + dbpc_c->level, + dbpc_c->race, + dbpc_c->gender, + dbpc_c->class_, + dbpc_c->deity, + dbpc_c->texture, + dbpc_c->helmtexture, + dbpc_c->copper, + dbpc_c->silver, + dbpc_c->gold, + dbpc_c->plat, + dbpc_c->haircolor, + dbpc_c->beardcolor, + dbpc_c->eyecolor1, + dbpc_c->eyecolor2, + dbpc_c->hairstyle, + dbpc_c->face, + dbpc_c->beard, + dbpc_c->item_tint[0].color, + dbpc_c->item_tint[1].color, + dbpc_c->item_tint[2].color, + dbpc_c->item_tint[3].color, + dbpc_c->item_tint[4].color, + dbpc_c->item_tint[5].color, + dbpc_c->item_tint[6].color, + dbpc_c->item_tint[7].color, + dbpc_c->item_tint[8].color, + atoi(row2[0]) + ); + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + + first_entry = 0; + scquery = ""; + + /* Print Items */ + for (unsigned int i = 0; i < dbpc_c->itemcount; i++) { + if (first_entry != 1){ + scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc_c->items[i].equipSlot, + dbpc_c->items[i].item_id, + dbpc_c->items[i].charges, + dbpc_c->items[i].aug1, + dbpc_c->items[i].aug2, + dbpc_c->items[i].aug3, + dbpc_c->items[i].aug4, + dbpc_c->items[i].aug5 + ); + first_entry = 1; + } + else{ + scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc_c->items[i].equipSlot, + dbpc_c->items[i].item_id, + dbpc_c->items[i].charges, + dbpc_c->items[i].aug1, + dbpc_c->items[i].aug2, + dbpc_c->items[i].aug3, + dbpc_c->items[i].aug4, + dbpc_c->items[i].aug5 + ); + } + } + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + } + } + } + QueryDatabase(StringFormat("ALTER TABLE `character_corpses` DROP COLUMN `data`")); + } return true; } @@ -3641,9 +3947,7 @@ bool Database::RemoveClientsFromInstance(uint16 instance_id) return results.Success(); } -bool Database::CheckInstanceExists(uint16 instance_id) -{ - +bool Database::CheckInstanceExists(uint16 instance_id) { std::string query = StringFormat("SELECT * FROM instance_list where id=%u", instance_id); auto results = QueryDatabase(query); @@ -3656,15 +3960,12 @@ bool Database::CheckInstanceExists(uint16 instance_id) return true; } -void Database::BuryCorpsesInInstance(uint16 instance_id) -{ - - std::string query = StringFormat("UPDATE player_corpses SET IsBurried=1, instanceid=0 WHERE instanceid=%u", instance_id); +void Database::BuryCorpsesInInstance(uint16 instance_id) { + std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1, `instance_id` =0 WHERE `instance_id` = %u", instance_id); auto results = QueryDatabase(query); } -uint16 Database::GetInstanceVersion(uint16 instance_id) -{ +uint16 Database::GetInstanceVersion(uint16 instance_id) { if(instance_id == 0) return 0; @@ -3681,8 +3982,7 @@ uint16 Database::GetInstanceVersion(uint16 instance_id) return atoi(row[0]); } -uint16 Database::GetInstanceID(const char* zone, uint32 charid, int16 version) -{ +uint16 Database::GetInstanceID(const char* zone, uint32 charid, int16 version) { std::string query = StringFormat("SELECT instance_list.id FROM instance_list, instance_list_player " "WHERE instance_list.zone=%u AND instance_list.version=%u AND instance_list.id=instance_list_player.id AND " diff --git a/common/database.h b/common/database.h index 9b388c84a..9be14f1cb 100644 --- a/common/database.h +++ b/common/database.h @@ -93,13 +93,417 @@ struct ExtendedProfile_Struct; struct GuildMember_Struct; class PTimerList; +#pragma pack(1) + +/* Conversion Structs */ + +namespace Convert { + struct BindStruct { + /*000*/ uint32 zoneId; + /*004*/ float x; + /*008*/ float y; + /*012*/ float z; + /*016*/ float heading; + }; + struct Color_Struct + { + union + { + struct + { + uint8 blue; + uint8 green; + uint8 red; + uint8 use_tint; // if there's a tint this is FF + } rgb; + uint32 color; + }; + }; + struct AA_Array + { + uint32 AA; + uint32 value; + }; + struct SpellBuff_Struct + { + /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise + /*001*/ uint8 level; + /*002*/ uint8 bard_modifier; + /*003*/ uint8 effect; //not real + /*004*/ uint32 spellid; + /*008*/ uint32 duration; + /*012*/ uint32 counters; + /*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages + /*020*/ + }; + struct Tribute_Struct { + uint32 tribute; + uint32 tier; + }; + struct Disciplines_Struct { + uint32 values[MAX_PP_DISCIPLINES]; + }; + struct GroupLeadershipAA_Struct { + union { + struct { + uint32 groupAAMarkNPC; + uint32 groupAANPCHealth; + uint32 groupAADelegateMainAssist; + uint32 groupAADelegateMarkNPC; + uint32 groupAA4; + uint32 groupAA5; + uint32 groupAAInspectBuffs; + uint32 groupAA7; + uint32 groupAASpellAwareness; + uint32 groupAAOffenseEnhancement; + uint32 groupAAManaEnhancement; + uint32 groupAAHealthEnhancement; + uint32 groupAAHealthRegeneration; + uint32 groupAAFindPathToPC; + uint32 groupAAHealthOfTargetsTarget; + uint32 groupAA15; + }; + uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY]; + }; + }; + + struct RaidLeadershipAA_Struct { + union { + struct { + uint32 raidAAMarkNPC; + uint32 raidAANPCHealth; + uint32 raidAADelegateMainAssist; + uint32 raidAADelegateMarkNPC; + uint32 raidAA4; + uint32 raidAA5; + uint32 raidAA6; + uint32 raidAASpellAwareness; + uint32 raidAAOffenseEnhancement; + uint32 raidAAManaEnhancement; + uint32 raidAAHealthEnhancement; + uint32 raidAAHealthRegeneration; + uint32 raidAAFindPathToPC; + uint32 raidAAHealthOfTargetsTarget; + uint32 raidAA14; + uint32 raidAA15; + }; + uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY]; + }; + }; + + struct LeadershipAA_Struct { + union { + struct { + Convert::GroupLeadershipAA_Struct group; + Convert::RaidLeadershipAA_Struct raid; + }; + uint32 ranks[MAX_LEADERSHIP_AA_ARRAY]; + }; + }; + typedef struct + { + /*00*/ char Name[64]; + /*64*/ uint32 Level; + /*68*/ uint32 Race; + /*72*/ uint32 Class; + /*76*/ uint32 Zone; + /*80*/ uint32 Time; + /*84*/ uint32 Points; + /*88*/ + } PVPStatsEntry_Struct; + struct BandolierItem_Struct { + uint32 item_id; + uint32 icon; + char item_name[64]; + }; + struct Bandolier_Struct { + char name[32]; + Convert::BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE]; + }; + struct PotionBelt_Struct { + Convert::BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE]; + }; + struct SuspendedMinion_Struct + { + /*000*/ uint16 SpellID; + /*002*/ uint32 HP; + /*006*/ uint32 Mana; + /*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT]; + /*510*/ uint32 Items[_MaterialCount]; + /*546*/ char Name[64]; + /*610*/ + }; + + struct PlayerProfile_Struct { + /*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum + /*0004*/ char name[64]; // Name of player sizes not right + /*0068*/ char last_name[32]; // Last name of player sizes not right + /*0100*/ uint32 gender; // Player Gender - 0 Male, 1 Female + /*0104*/ uint32 race; // Player race + /*0108*/ uint32 class_; // Player class + /*0112*/ uint32 unknown0112; // + /*0116*/ uint32 level; // Level of player (might be one byte) + /*0120*/ Convert::BindStruct binds[5]; // Bind points (primary is first, home city is fifth) + /*0220*/ uint32 deity; // deity + /*0224*/ uint32 guild_id; + /*0228*/ uint32 birthday; // characters bday + /*0232*/ uint32 lastlogin; // last login or zone time + /*0236*/ uint32 timePlayedMin; // in minutes + /*0240*/ uint8 pvp; + /*0241*/ uint8 level2; //no idea why this is here, but thats how it is on live + /*0242*/ uint8 anon; // 2=roleplay, 1=anon, 0=not anon + /*0243*/ uint8 gm; + /*0244*/ uint8 guildrank; + /*0245*/ uint8 guildbanker; + /*0246*/ uint8 unknown0246[6]; // + /*0252*/ uint32 intoxication; + /*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms + /*0292*/ uint32 abilitySlotRefresh; + /*0296*/ uint8 haircolor; // Player hair color + /*0297*/ uint8 beardcolor; // Player beard color + /*0298*/ uint8 eyecolor1; // Player left eye color + /*0299*/ uint8 eyecolor2; // Player right eye color + /*0300*/ uint8 hairstyle; // Player hair style + /*0301*/ uint8 beard; // Beard type + /*0302*/ uint8 ability_time_seconds; //The following four spots are unknown right now..... + /*0303*/ uint8 ability_number; //ability used + /*0304*/ uint8 ability_time_minutes; + /*0305*/ uint8 ability_time_hours; //place holder + /*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag? + /*0312*/ uint32 item_material[_MaterialCount]; // Item texture/material of worn/held items + /*0348*/ uint8 unknown0348[44]; + /*0392*/ Convert::Color_Struct item_tint[_MaterialCount]; + /*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY]; + /*2348*/ float unknown2384; //seen ~128, ~47 + /*2352*/ char servername[32]; // length probably not right + /*2384*/ char title[32]; // length might be wrong + /*2416*/ char suffix[32]; // length might be wrong + /*2448*/ uint32 guildid2; // + /*2452*/ uint32 exp; // Current Experience + /*2456*/ uint32 unknown2492; + /*2460*/ uint32 points; // Unspent Practice points + /*2464*/ uint32 mana; // current mana + /*2468*/ uint32 cur_hp; // current hp + /*2472*/ uint32 unknown2508; // 0x05 + /*2476*/ uint32 STR; // Strength + /*2480*/ uint32 STA; // Stamina + /*2484*/ uint32 CHA; // Charisma + /*2488*/ uint32 DEX; // Dexterity + /*2492*/ uint32 INT; // Intelligence + /*2496*/ uint32 AGI; // Agility + /*2500*/ uint32 WIS; // Wisdom + /*2504*/ uint8 face; // Player face + /*2505*/ uint8 unknown2541[47]; // ? + /*2552*/ uint8 languages[MAX_PP_LANGUAGE]; + /*2580*/ uint8 unknown2616[4]; + /*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK]; + /*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff + /*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL]; + /*4668*/ uint8 unknown4704[32]; // + /*4700*/ float y; // Player y position + /*4704*/ float x; // Player x position + /*4708*/ float z; // Player z position + /*4712*/ float heading; // Direction player is facing + /*4716*/ uint8 unknown4752[4]; // + /*4720*/ int32 platinum; // Platinum Pieces on player + /*4724*/ int32 gold; // Gold Pieces on player + /*4728*/ int32 silver; // Silver Pieces on player + /*4732*/ int32 copper; // Copper Pieces on player + /*4736*/ int32 platinum_bank; // Platinum Pieces in Bank + /*4740*/ int32 gold_bank; // Gold Pieces in Bank + /*4744*/ int32 silver_bank; // Silver Pieces in Bank + /*4748*/ int32 copper_bank; // Copper Pieces in Bank + /*4752*/ int32 platinum_cursor; // Platinum on cursor + /*4756*/ int32 gold_cursor; // Gold on cursor + /*4760*/ int32 silver_cursor; // Silver on cursor + /*4764*/ int32 copper_cursor; // Copper on cursor + /*4768*/ int32 platinum_shared; // Platinum shared between characters + /*4772*/ uint8 unknown4808[24]; + /*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer + /*5196*/ uint8 unknown5132[184]; + /*5380*/ uint32 pvp2; // + /*5384*/ uint32 unknown5420; // + /*5388*/ uint32 pvptype; // + /*5392*/ uint32 unknown5428; // + /*5396*/ uint32 ability_down; // Guessing + /*5400*/ uint8 unknown5436[8]; // + /*5408*/ uint32 autosplit; //not used right now + /*5412*/ uint8 unknown5448[8]; + /*5420*/ uint32 zone_change_count; // Number of times user has zoned in their career (guessing) + /*5424*/ uint8 unknown5460[16]; // + /*5440*/ uint32 drakkin_heritage; // + /*5444*/ uint32 drakkin_tattoo; // + /*5448*/ uint32 drakkin_details; // + /*5452*/ uint32 expansions; // expansion setting, bit field of expansions avaliable + /*5456*/ int32 toxicity; //from drinking potions, seems to increase by 3 each time you drink + /*5460*/ char unknown5496[16]; // + /*5476*/ int32 hunger_level; + /*5480*/ int32 thirst_level; + /*5484*/ uint32 ability_up; + /*5488*/ char unknown5524[16]; + /*5504*/ uint16 zone_id; // Current zone of the player + /*5506*/ uint16 zoneInstance; // Instance ID + /*5508*/ Convert::SpellBuff_Struct buffs[BUFF_COUNT]; // Buffs currently on the player + /*6008*/ char groupMembers[6][64];// + /*6392*/ char unknown6428[656]; + /*7048*/ uint32 entityid; + /*7052*/ uint32 leadAAActive; + /*7056*/ uint32 unknown7092; + /*7060*/ int32 ldon_points_guk; //client uses these as signed + /*7064*/ int32 ldon_points_mir; + /*7068*/ int32 ldon_points_mmc; + /*7072*/ int32 ldon_points_ruj; + /*7076*/ int32 ldon_points_tak; + /*7080*/ int32 ldon_points_available; + /*7084*/ int32 ldon_wins_guk; + /*7088*/ int32 ldon_wins_mir; + /*7092*/ int32 ldon_wins_mmc; + /*7096*/ int32 ldon_wins_ruj; + /*7100*/ int32 ldon_wins_tak; + /*7104*/ int32 ldon_losses_guk; + /*7108*/ int32 ldon_losses_mir; + /*7112*/ int32 ldon_losses_mmc; + /*7116*/ int32 ldon_losses_ruj; + /*7120*/ int32 ldon_losses_tak; + /*7124*/ uint8 unknown7160[72]; + /*7196*/ uint32 tribute_time_remaining; //in miliseconds + /*7200*/ uint32 showhelm; + /*7204*/ uint32 career_tribute_points; + /*7208*/ uint32 unknown7244; + /*7212*/ uint32 tribute_points; + /*7216*/ uint32 unknown7252; + /*7220*/ uint32 tribute_active; //1=active + /*7224*/ Convert::Tribute_Struct tributes[EmuConstants::TRIBUTE_SIZE]; + /*7264*/ Convert::Disciplines_Struct disciplines; + /*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use) + /*7744*/ char unknown7780[160]; + /*7904*/ uint32 endurance; + /*7908*/ uint32 group_leadership_exp; //0-1000 + /*7912*/ uint32 raid_leadership_exp; //0-2000 + /*7916*/ uint32 group_leadership_points; + /*7920*/ uint32 raid_leadership_points; + /*7924*/ Convert::LeadershipAA_Struct leader_abilities; + /*8052*/ uint8 unknown8088[132]; + /*8184*/ uint32 air_remaining; + /*8188*/ uint32 PVPKills; + /*8192*/ uint32 PVPDeaths; + /*8196*/ uint32 PVPCurrentPoints; + /*8200*/ uint32 PVPCareerPoints; + /*8204*/ uint32 PVPBestKillStreak; + /*8208*/ uint32 PVPWorstDeathStreak; + /*8212*/ uint32 PVPCurrentKillStreak; + /*8216*/ Convert::PVPStatsEntry_Struct PVPLastKill; + /*8304*/ Convert::PVPStatsEntry_Struct PVPLastDeath; + /*8392*/ uint32 PVPNumberOfKillsInLast24Hours; + /*8396*/ Convert::PVPStatsEntry_Struct PVPRecentKills[50]; + /*12796*/ uint32 aapoints_spent; + /*12800*/ uint32 expAA; + /*12804*/ uint32 aapoints; //avaliable, unspent + /*12808*/ uint8 unknown12844[36]; + /*12844*/ Convert::Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT]; + /*14124*/ uint8 unknown14160[4506]; + /*18630*/ Convert::SuspendedMinion_Struct SuspendedMinion; // No longer in use + /*19240*/ uint32 timeentitledonaccount; + /*19244*/ Convert::PotionBelt_Struct potionbelt; //there should be 3 more of these + /*19532*/ uint8 unknown19568[8]; + /*19540*/ uint32 currentRadCrystals; // Current count of radiant crystals + /*19544*/ uint32 careerRadCrystals; // Total count of radiant crystals ever + /*19548*/ uint32 currentEbonCrystals;// Current count of ebon crystals + /*19552*/ uint32 careerEbonCrystals; // Total count of ebon crystals ever + /*19556*/ uint8 groupAutoconsent; // 0=off, 1=on + /*19557*/ uint8 raidAutoconsent; // 0=off, 1=on + /*19558*/ uint8 guildAutoconsent; // 0=off, 1=on + /*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005) + /*19564*/ uint32 RestTimer; + /*19568*/ + }; + + + namespace player_lootitem_temp + { + struct ServerLootItem_Struct_temp { + uint32 item_id; + int16 equipSlot; + uint8 charges; + uint16 lootslot; + uint32 aug1; + uint32 aug2; + uint32 aug3; + uint32 aug4; + uint32 aug5; + }; + } + + struct DBPlayerCorpse_Struct_temp { + uint32 crc; + bool locked; + uint32 itemcount; + uint32 exp; + float size; + uint8 level; + uint8 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + Color_Struct item_tint[9]; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + uint32 drakkin_heritage; + uint32 drakkin_tattoo; + uint32 drakkin_details; + player_lootitem_temp::ServerLootItem_Struct_temp items[0]; + }; + + namespace classic_db_temp { + struct DBPlayerCorpse_Struct_temp { + uint32 crc; + bool locked; + uint32 itemcount; + uint32 exp; + float size; + uint8 level; + uint8 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + Color_Struct item_tint[9]; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + player_lootitem_temp::ServerLootItem_Struct_temp items[0]; + }; + } +} + +#pragma pack() + class Database : public DBcore { public: Database(); Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port); bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port); ~Database(); - bool ThrowDBError(std::string ErrorMessage, std::string query_title, std::string query); /* @@ -221,7 +625,11 @@ public: void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid); void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0); - bool CheckDatabaseConversions(); + /* Database Conversions*/ + bool CheckDatabaseConversions(); + bool CheckDatabaseConvertPPDeblob(); + bool CheckDatabaseConvertCorpseDeblob(); + bool CheckDatabaseConvertBotsPostPPDeblob(); /* * Database Variables diff --git a/common/dbcore.cpp b/common/dbcore.cpp index fb038db2e..84d2528f0 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -4,6 +4,7 @@ #include #endif +#include #include #include #include @@ -113,6 +114,16 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo #ifdef _EQDEBUG std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; #endif + + /* Implement Logging at the Root */ + if (mysql_errno(&mysql) > 0 && strlen(query) > 0){ + std::cout << "\n[MYSQL ERR] " << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << " [Query]: \n" << query << "\n" << std::endl; + /* Write to log file */ + std::ofstream log("eqemu_query_error_log.txt", std::ios_base::app | std::ios_base::out); + log << "[MYSQL ERR] " << mysql_error(&mysql) << "\n" << query << "\n"; + log.close(); + } + return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer); } @@ -126,7 +137,6 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); - #if DEBUG_MYSQL_QUERIES >= 1 if (requestResult.Success()) { @@ -145,95 +155,6 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo return requestResult; } -bool DBcore::RunQuery(const char* query, uint32 querylen, char* errbuf, MYSQL_RES** result, uint32* affected_rows, uint32* last_insert_id, uint32* errnum, bool retry) { - if (errnum) - *errnum = 0; - if (errbuf) - errbuf[0] = 0; - bool ret = false; - LockMutex lock(&MDatabase); - if (pStatus != Connected) - Open(); - - if (mysql_real_query(&mysql, query, querylen)) { - if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) - pStatus = Error; - if (mysql_errno(&mysql) == CR_SERVER_LOST || mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) { - if (retry) { - std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl; - ret = RunQuery(query, querylen, errbuf, result, affected_rows, last_insert_id, errnum, false); - if (ret) - std::cout << "Reconnection to database successful." << std::endl; - } - else { - pStatus = Error; - if (errnum) - *errnum = mysql_errno(&mysql); - if (errbuf) - snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); - std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; - ret = false; - } - } - else { - if (errnum) - *errnum = mysql_errno(&mysql); - if (errbuf) - snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); -#ifdef _EQDEBUG - std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; -#endif - ret = false; - } - } - else { - if (result && mysql_field_count(&mysql)) { - *result = mysql_store_result(&mysql); -#ifdef _EQDEBUG - DBMemLeak::Alloc(*result, query); -#endif - } - else if (result) - *result = 0; - if (affected_rows) - *affected_rows = mysql_affected_rows(&mysql); - if (last_insert_id) - *last_insert_id = (uint32)mysql_insert_id(&mysql); - if (result) { - if (*result) { - ret = true; - } - else { -#ifdef _EQDEBUG - std::cout << "DB Query Error: No Result" << std::endl; -#endif - if (errnum) - *errnum = UINT_MAX; - if (errbuf) - strcpy(errbuf, "DBcore::RunQuery: No Result"); - ret = false; - } - } - else { - ret = true; - } - } -#if DEBUG_MYSQL_QUERIES >= 1 - if (ret) { - std::cout << "query successful"; - if (result && (*result)) - std::cout << ", " << (int) mysql_num_rows(*result) << " rows returned"; - if (affected_rows) - std::cout << ", " << (*affected_rows) << " rows affected"; - std::cout<< std::endl; - } - else { - std::cout << "QUERY: query FAILED" << std::endl; - } -#endif - return ret; -} - void DBcore::TransactionBegin() { QueryDatabase("START TRANSACTION"); } diff --git a/common/dbcore.h b/common/dbcore.h index 9dd5aef5e..0cdceb61b 100644 --- a/common/dbcore.h +++ b/common/dbcore.h @@ -23,7 +23,6 @@ public: DBcore(); ~DBcore(); eStatus GetStatus() { return pStatus; } - bool RunQuery(const char* query, uint32 querylen, char* errbuf = 0, MYSQL_RES** result = 0, uint32* affected_rows = 0, uint32* last_insert_id = 0, uint32* errnum = 0, bool retry = true); MySQLRequestResult QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce = true); MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true); void TransactionBegin(); diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 368cdf931..62a166c67 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -5209,17 +5209,17 @@ struct MercenaryMerchantResponse_Struct { }; struct ServerLootItem_Struct { - uint32 item_id; - int16 equipSlot; - uint8 charges; - uint16 lootslot; - uint32 aug1; - uint32 aug2; - uint32 aug3; - uint32 aug4; - uint32 aug5; - uint8 minlevel; - uint8 maxlevel; + uint32 item_id; // uint32 item_id; + int16 equip_slot; // int16 equip_slot; + uint16 charges; // uint8 charges; + uint16 lootslot; // uint16 lootslot; + uint32 aug_1; // uint32 aug_1; + uint32 aug_2; // uint32 aug_2; + uint32 aug_3; // uint32 aug_3; + uint32 aug_4; // uint32 aug_4; + uint32 aug_5; // uint32 aug_5; + uint8 min_level; // + uint8 max_level; // }; //Found in client near a ref to the string: diff --git a/common/shareddb.cpp b/common/shareddb.cpp index b0f29c74b..d543db87f 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1215,11 +1215,11 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges) } int32 SharedDatabase::DeleteStalePlayerCorpses() { - if(RuleB(Zone, EnableShadowrest)) - { - std::string query = StringFormat("UPDATE player_corpses SET IsBurried = 1 WHERE IsBurried = 0 AND " - "(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) > %d AND NOT timeofdeath = 0", - (RuleI(Character, CorpseDecayTimeMS) / 1000)); + if(RuleB(Zone, EnableShadowrest)) { + std::string query = StringFormat( + "UPDATE `character_corpses` SET `is_buried` = 1 WHERE `is_buried` = 0 AND " + "(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > %d AND NOT time_of_death = 0", + (RuleI(Character, CorpseDecayTimeMS) / 1000)); auto results = QueryDatabase(query); if (!results.Success()) return -1; @@ -1227,8 +1227,9 @@ int32 SharedDatabase::DeleteStalePlayerCorpses() { return results.RowsAffected(); } - std::string query = StringFormat("DELETE FROM player_corpses WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) > %d " - "AND NOT timeofdeath = 0", (RuleI(Character, CorpseDecayTimeMS) / 1000)); + std::string query = StringFormat( + "DELETE FROM `character_corpses` WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > %d " + "AND NOT time_of_death = 0", (RuleI(Character, CorpseDecayTimeMS) / 1000)); auto results = QueryDatabase(query); if (!results.Success()) return -1; @@ -1236,16 +1237,6 @@ int32 SharedDatabase::DeleteStalePlayerCorpses() { return results.RowsAffected(); } -int32 SharedDatabase::DeleteStalePlayerBackups() { - // 1209600 seconds = 2 weeks - const std::string query = "DELETE FROM player_corpses_backup WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) > 1209600"; - auto results = QueryDatabase(query); - if (!results.Success()) - return -1; - - return results.RowsAffected(); -} - bool SharedDatabase::GetCommandSettings(std::map &commands) { const std::string query = "SELECT command, access FROM commands"; @@ -1915,7 +1906,7 @@ const LootDrop_Struct* SharedDatabase::GetLootDrop(uint32 lootdrop_id) { void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) { std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id); - auto results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "SharedDatabase::LoadCharacterInspectMessage", query); + auto results = QueryDatabase(query); auto row = results.begin(); memcpy(message, "", sizeof(InspectMessage_Struct)); for (auto row = results.begin(); row != results.end(); ++row) { @@ -1925,7 +1916,7 @@ void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMes void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) { std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, EscapeString(message->text).c_str()); - auto results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "SharedDatabase::SaveCharacterInspectMessage", query); + auto results = QueryDatabase(query); } void SharedDatabase::GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message) { diff --git a/common/shareddb.h b/common/shareddb.h index 14793f792..0b0dcf839 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -41,7 +41,6 @@ public: uint8 GetGMSpeed(uint32 account_id); bool SetHideMe(uint32 account_id, uint8 hideme); int32 DeleteStalePlayerCorpses(); - int32 DeleteStalePlayerBackups(); void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message); void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message); void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message); diff --git a/utils/sql/git/optional/2014_11_24_EnableMeritBasedFaction.sql b/utils/sql/git/optional/2014_11_24_EnableMeritBasedFaction.sql new file mode 100644 index 000000000..67e1b1888 --- /dev/null +++ b/utils/sql/git/optional/2014_11_24_EnableMeritBasedFaction.sql @@ -0,0 +1 @@ +INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'NPC:EnableMeritBasedFaction', 'false', 'If set to true, faction will given in the same way as experience (solo/group/raid).'); \ No newline at end of file diff --git a/world/adventure.cpp b/world/adventure.cpp index 5f61aa5e9..ffb64779c 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -376,7 +376,7 @@ void Adventure::MoveCorpsesToGraveyard() std::list dbid_list; std::list charid_list; - std::string query = StringFormat("SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()); + std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instanceid=%d", GetInstanceID()); auto results = database.QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); @@ -392,7 +392,7 @@ void Adventure::MoveCorpsesToGraveyard() float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); float z = GetTemplate()->graveyard_z; - query = StringFormat("UPDATE player_corpses " + query = StringFormat("UPDATE character_corpses " "SET zoneid = %d, instanceid = 0, " "x = %f, y = %f, z = %f WHERE instanceid = %d", GetTemplate()->graveyard_zone_id, diff --git a/world/net.cpp b/world/net.cpp index eb2721c92..ee1158520 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -336,9 +336,6 @@ int main(int argc, char** argv) { _log(WORLD__INIT, "Reboot zone modes %s",holdzones ? "ON" : "OFF"); _log(WORLD__INIT, "Deleted %i stale player corpses from database", database.DeleteStalePlayerCorpses()); - if (RuleB(World, DeleteStaleCorpeBackups) == true) { - _log(WORLD__INIT, "Deleted %i stale player backups from database", database.DeleteStalePlayerBackups()); - } _log(WORLD__INIT, "Loading adventures..."); if(!adventure_manager.LoadAdventureTemplates()) diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 955c0b897..cd01e01b2 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -142,14 +142,14 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 1); - auto results_bset = QueryDatabase(query); ThrowDBError(results_bset.ErrorMessage(), "WorldDatabase::GetCharSelectInfo Set Home Point", query); + auto results_bset = QueryDatabase(query); } /* If no regular bind set, set it */ if (has_bind == 0){ std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" " VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, pp.binds[0].zoneId, 0, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z, pp.binds[0].heading, 0); - auto results_bset = QueryDatabase(query); ThrowDBError(results_bset.ErrorMessage(), "WorldDatabase::GetCharSelectInfo Set Bind Point", query); + auto results_bset = QueryDatabase(query); } } /* Bind End */ diff --git a/zone/client.cpp b/zone/client.cpp index 9b10cb174..9541959ba 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2582,38 +2582,6 @@ void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 } } -void Client::LogLoot(Client* player, Corpse* corpse, const Item_Struct* item){ - char* logtext; - char itemid[100]; - char itemname[100]; - char coinloot[100]; - if (item!=0){ - memset(itemid,0,sizeof(itemid)); - memset(itemname,0,sizeof(itemid)); - itoa(item->ID,itemid,10); - sprintf(itemname,"%s",item->Name); - logtext=itemname; - - strcat(logtext,"("); - strcat(logtext,itemid); - strcat(logtext,") Looted"); - database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),corpse->orgname,"Looting Item",logtext,4); - } - else{ - if ((corpse->GetPlatinum() + corpse->GetGold() + corpse->GetSilver() + corpse->GetCopper())>0) { - memset(coinloot,0,sizeof(coinloot)); - sprintf(coinloot,"%i PP %i GP %i SP %i CP",corpse->GetPlatinum(),corpse->GetGold(),corpse->GetSilver(),corpse->GetCopper()); - logtext=coinloot; - strcat(logtext," Looted"); - if (corpse->GetPlatinum()>10000) - database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),corpse->orgname,"Excessive Loot!",logtext,9); - else - database.logevents(player->AccountName(),player->AccountID(),player->admin,player->GetName(),corpse->orgname,"Looting Money",logtext,5); - } - } -} - - bool Client::BindWound(Mob* bindmob, bool start, bool fail){ EQApplicationPacket* outapp = 0; if(!fail) { @@ -4969,7 +4937,7 @@ void Client::SummonAndRezzAllCorpses() entity_list.RemoveAllCorpsesByCharID(CharacterID()); - int CorpseCount = database.SummonAllPlayerCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), + int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), GetX(), GetY(), GetZ(), GetHeading()); if(CorpseCount <= 0) { @@ -5007,7 +4975,7 @@ void Client::SummonAllCorpses(float dest_x, float dest_y, float dest_z, float de entity_list.RemoveAllCorpsesByCharID(CharacterID()); - int CorpseCount = database.SummonAllPlayerCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), + int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); if(CorpseCount <= 0) { @@ -5051,7 +5019,7 @@ void Client::DepopPlayerCorpse(uint32 dbid) void Client::BuryPlayerCorpses() { - database.BuryAllPlayerCorpses(CharacterID()); + database.BuryAllCharacterCorpses(CharacterID()); } void Client::NotifyNewTitlesAvailable() diff --git a/zone/client.h b/zone/client.h index 3e54771ad..dcf665bab 100644 --- a/zone/client.h +++ b/zone/client.h @@ -335,7 +335,6 @@ public: bool CheckAccess(int16 iDBLevel, int16 iDefaultLevel); void CheckQuests(const char* zonename, const char* message, uint32 npc_id, uint32 item_id, Mob* other); - void LogLoot(Client* player,Corpse* corpse,const Item_Struct* item); bool AutoAttackEnabled() const { return auto_attack; } bool AutoFireEnabled() const { return auto_fire; } void MakeCorpse(uint32 exploss); @@ -1031,9 +1030,9 @@ void SetConsumption(int32 in_hunger, int32 in_thirst); void DepopAllCorpses(); void DepopPlayerCorpse(uint32 dbid); void BuryPlayerCorpses(); - uint32 GetCorpseCount() { return database.GetPlayerCorpseCount(CharacterID()); } - uint32 GetCorpseID(int corpse) { return database.GetPlayerCorpseID(CharacterID(), corpse); } - uint32 GetCorpseItemAt(int corpse_id, int slot_id) { return database.GetPlayerCorpseItemAt(corpse_id, slot_id); } + uint32 GetCorpseCount() { return database.GetCharacterCorpseCount(CharacterID()); } + uint32 GetCorpseID(int corpse) { return database.GetCharacterCorpseID(CharacterID(), corpse); } + uint32 GetCorpseItemAt(int corpse_id, int slot_id) { return database.GetCharacterCorpseItemAt(corpse_id, slot_id); } void SuspendMinion(); void Doppelganger(uint16 spell_id, Mob *target, const char *name_override, int pet_count, int pet_duration); void NotifyNewTitlesAvailable(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 238f324f2..000ed8fcc 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4827,7 +4827,7 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) else Message(0, "This corpse will decay in %i minutes and %i seconds.", min, sec); - Message(0, "This corpse %s be resurrected.", tcorpse->Rezzed() ? "cannot" : "can"); + Message(0, "This corpse %s be resurrected.", tcorpse->IsRezzed() ? "cannot" : "can"); /* hour = 0; @@ -6175,8 +6175,8 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) char *escSearchString = new char[129]; database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name)); - std::string query = StringFormat("SELECT charname, zoneid, x, y, z, timeofdeath, rezzed, IsBurried " - "FROM player_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", + std::string query = StringFormat("SELECT charname, zoneid, x, y, z, time_of_death, rezzed, IsBurried " + "FROM character_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", escSearchString, maxResults); safe_delete_array(escSearchString); auto results = database.QueryDatabase(query); @@ -6193,7 +6193,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) else Message(clientMessageYellow, "There are %i corpse(s) that match the search string '%s'.", results.RowCount(), gmscs->Name); - char charName[64], timeOfDeath[20]; + char charName[64], time_of_death[20]; std::string popupText = "", - charName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, timeOfDeath, + charName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, time_of_death, corpseRezzed ? "Yes" : "No", corpseBuried ? "Yes" : "No"); if (popupText.size() > 4000) { diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 13973df91..c4eb01f4a 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -2173,7 +2173,7 @@ void Client::HandleRespawnFromHover(uint32 Option) _log(SPELLS__REZ, "Found corpse. Marking corpse as rezzed."); - corpse->Rezzed(true); + corpse->IsRezzed(true); corpse->CompleteRezz(); } } diff --git a/zone/command.cpp b/zone/command.cpp index ce3d67fd6..27516d5a5 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -8456,7 +8456,7 @@ void command_setgraveyard(Client *c, const Seperator *sep) zoneid = database.GetZoneID(sep->arg[1]); if(zoneid > 0) { - graveyard_id = database.NewGraveyardRecord(zoneid, t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); if(graveyard_id > 0) { c->Message(0, "Successfuly added a new record for this graveyard!"); @@ -8519,7 +8519,7 @@ void command_summonburriedplayercorpse(Client *c, const Seperator *sep) return; } - Corpse* PlayerCorpse = database.SummonBurriedPlayerCorpse(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); if(!PlayerCorpse) c->Message(0, "Your target doesn't have any burried corpses."); @@ -8538,7 +8538,7 @@ void command_getplayerburriedcorpsecount(Client *c, const Seperator *sep) return; } - uint32 CorpseCount = database.GetPlayerBurriedCorpseCount(t->CharacterID()); + uint32 CorpseCount = database.GetCharacterBuriedCorpseCount(t->CharacterID()); if(CorpseCount > 0) c->Message(0, "Your target has a total of %u burried corpses.", CorpseCount); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 8df695a84..8be978350 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -63,131 +63,81 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) { safe_delete(outapp); } -Corpse* Corpse::LoadFromDBData(uint32 in_dbid, uint32 in_charid, char* in_charname, uchar* in_data, uint32 in_datasize, float in_x, float in_y, float in_z, float in_heading, char* timeofdeath, bool rezzed, bool wasAtGraveyard) { - if (in_datasize < sizeof(classic_db::DBPlayerCorpse_Struct)) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: in_datasize < sizeof(DBPlayerCorpse_Struct)"); - return 0; - } - classic_db::DBPlayerCorpse_Struct* dbpc = (classic_db::DBPlayerCorpse_Struct*) in_data; - bool isSoF = true; +Corpse* Corpse::LoadFromDBData(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard) +{ + uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid); + char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))]; + PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer; + database.LoadCharacterCorpseData(in_dbid, pcs); - uint32 esize1 = (sizeof(DBPlayerCorpse_Struct) + (dbpc->itemcount * sizeof(player_lootitem::ServerLootItem_Struct))); - uint32 esize2 = (sizeof(classic_db::DBPlayerCorpse_Struct) + (dbpc->itemcount * sizeof(player_lootitem::ServerLootItem_Struct))); - if (in_datasize != esize1) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: in_datasize (%i) != expected size (%i) Continuing on...", in_datasize, esize1); - if (in_datasize != esize2) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: in_datasize (%i) != expected size (%i) Your corpse is done broke, sir.", in_datasize, esize2); - return 0; - } - else - { - isSoF = false; - } + /* Load Items */ + ItemList itemlist; + ServerLootItem_Struct* tmp = 0; + for (unsigned int i = 0; i < pcs->itemcount; i++) { + tmp = new ServerLootItem_Struct; + memcpy(tmp, &pcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); + tmp->equip_slot = CorpseToServerSlot(tmp->equip_slot); + itemlist.push_back(tmp); } - if(isSoF) - { - DBPlayerCorpse_Struct* dbpcs = (DBPlayerCorpse_Struct*) in_data; - if (dbpcs->crc != CRC32::Generate(&((uchar*) dbpcs)[4], in_datasize - 4)) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: crc failure"); - return 0; - } - ItemList itemlist; - ServerLootItem_Struct* tmp = 0; - for (unsigned int i=0; i < dbpcs->itemcount; i++) { - tmp = new ServerLootItem_Struct; - memcpy(tmp, &dbpcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); - tmp->equipSlot = CorpseToServerSlot(tmp->equipSlot); // temp hack until corpse blobs are removed - itemlist.push_back(tmp); - } + /* Create Corpse Entity */ + Corpse* pc = new Corpse( + in_dbid, // uint32 in_dbid + in_charid, // uint32 in_charid + in_charname.c_str(), // char* in_charname + &itemlist, // ItemList* in_itemlist + pcs->copper, // uint32 in_copper + pcs->silver, // uint32 in_silver + pcs->gold, // uint32 in_gold + pcs->plat, // uint32 in_plat + in_x, // float in_x + in_y, // float in_y + in_z, // float in_z + in_heading, // float in_heading + pcs->size, // float in_size + pcs->gender, // uint8 in_gender + pcs->race, // uint16 in_race + pcs->class_, // uint8 in_class + pcs->deity, // uint8 in_deity + pcs->level, // uint8 in_level + pcs->texture, // uint8 in_texture + pcs->helmtexture, // uint8 in_helmtexture + pcs->exp, // uint32 in_rezexp + was_at_graveyard // bool wasAtGraveyard + ); + if (pcs->locked) + pc->Lock(); - // Little hack to account for the fact the race in the corpse struct is a uint8 and Froglok/Drakkin race number > 255 - // and to maintain backwards compatability with existing corpses in the database. - uint16 RealRace; + /* Load Item Tints */ + // memcpy(pc->item_tint, pcs->item_tint, sizeof(pc->item_tint)); + pc->item_tint[0].color = pcs->item_tint[0].color; + pc->item_tint[1].color = pcs->item_tint[1].color; + pc->item_tint[2].color = pcs->item_tint[2].color; + pc->item_tint[3].color = pcs->item_tint[3].color; + pc->item_tint[4].color = pcs->item_tint[4].color; + pc->item_tint[5].color = pcs->item_tint[5].color; + pc->item_tint[6].color = pcs->item_tint[6].color; + pc->item_tint[7].color = pcs->item_tint[7].color; + pc->item_tint[8].color = pcs->item_tint[8].color; - switch(dbpcs->race) { - case 254: - RealRace = DRAKKIN; - break; - case 255: - RealRace = FROGLOK; - break; - default: - RealRace = dbpc->race; - } - Corpse* pc = new Corpse(in_dbid, in_charid, in_charname, &itemlist, dbpcs->copper, dbpcs->silver, dbpcs->gold, dbpcs->plat, in_x, in_y, in_z, in_heading, dbpcs->size, dbpcs->gender, RealRace, dbpcs->class_, dbpcs->deity, dbpcs->level, dbpcs->texture, dbpcs->helmtexture, dbpcs->exp, wasAtGraveyard); - if (dbpcs->locked) - pc->Lock(); + /* Load Physical Appearance */ + pc->haircolor = pcs->haircolor; + pc->beardcolor = pcs->beardcolor; + pc->eyecolor1 = pcs->eyecolor1; + pc->eyecolor2 = pcs->eyecolor2; + pc->hairstyle = pcs->hairstyle; + pc->luclinface = pcs->face; + pc->beard = pcs->beard; + pc->drakkin_heritage = pcs->drakkin_heritage; + pc->drakkin_tattoo = pcs->drakkin_tattoo; + pc->drakkin_details = pcs->drakkin_details; + pc->IsRezzed(rezzed); + pc->become_npc = false; - // load tints - memcpy(pc->item_tint, dbpcs->item_tint, sizeof(pc->item_tint)); - // appearance - pc->haircolor = dbpcs->haircolor; - pc->beardcolor = dbpcs->beardcolor; - pc->eyecolor1 = dbpcs->eyecolor1; - pc->eyecolor2 = dbpcs->eyecolor2; - pc->hairstyle = dbpcs->hairstyle; - pc->luclinface = dbpcs->face; - pc->beard = dbpcs->beard; - pc->drakkin_heritage = dbpcs->drakkin_heritage; - pc->drakkin_tattoo = dbpcs->drakkin_tattoo; - pc->drakkin_details = dbpcs->drakkin_details; - pc->Rezzed(rezzed); - pc->become_npc = false; - return pc; - } - else - { - if (dbpc->crc != CRC32::Generate(&((uchar*) dbpc)[4], in_datasize - 4)) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: crc failure"); - return 0; - } - ItemList itemlist; - ServerLootItem_Struct* tmp = 0; - for (unsigned int i=0; i < dbpc->itemcount; i++) { - tmp = new ServerLootItem_Struct; - memcpy(tmp, &dbpc->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); - tmp->equipSlot = CorpseToServerSlot(tmp->equipSlot); // temp hack until corpse blobs are removed - itemlist.push_back(tmp); - } + safe_delete_array(pcs); - // Little hack to account for the fact the race in the corpse struct is a uint8 and Froglok/Drakkin race number > 255 - // and to maintain backwards compatability with existing corpses in the database. - uint16 RealRace; - - switch(dbpc->race) { - case 254: - RealRace = DRAKKIN; - break; - case 255: - RealRace = FROGLOK; - break; - default: - RealRace = dbpc->race; - } - - Corpse* pc = new Corpse(in_dbid, in_charid, in_charname, &itemlist, dbpc->copper, dbpc->silver, dbpc->gold, dbpc->plat, in_x, in_y, in_z, in_heading, dbpc->size, dbpc->gender, RealRace, dbpc->class_, dbpc->deity, dbpc->level, dbpc->texture, dbpc->helmtexture,dbpc->exp, wasAtGraveyard); - if (dbpc->locked) - pc->Lock(); - - // load tints - memcpy(pc->item_tint, dbpc->item_tint, sizeof(pc->item_tint)); - // appearance - pc->haircolor = dbpc->haircolor; - pc->beardcolor = dbpc->beardcolor; - pc->eyecolor1 = dbpc->eyecolor1; - pc->eyecolor2 = dbpc->eyecolor2; - pc->hairstyle = dbpc->hairstyle; - pc->luclinface = dbpc->face; - pc->beard = dbpc->beard; - pc->drakkin_heritage = 0; - pc->drakkin_tattoo = 0; - pc->drakkin_details = 0; - pc->Rezzed(rezzed); - pc->become_npc = false; - return pc; - } + return pc; } // To be used on NPC death and ZoneStateLoad @@ -208,10 +158,10 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP { corpse_graveyard_timer.Disable(); memset(item_tint, 0, sizeof(item_tint)); - pIsChanged = false; - p_PlayerCorpse = false; - pLocked = false; - BeingLootedBy = 0xFFFFFFFF; + is_corpse_changed = false; + is_player_corpse = false; + is_locked = false; + being_looted_by = 0xFFFFFFFF; if (in_itemlist) { itemlist = *in_itemlist; in_itemlist->clear(); @@ -221,9 +171,9 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP npctype_id = in_npctypeid; SetPKItem(0); - charid = 0; - dbid = 0; - p_depop = false; + char_id = 0; + corpse_db_id = 0; + player_corpse_depop = false; strcpy(orgname, in_npc->GetName()); strcpy(name, in_npc->GetName()); // Added By Hogie @@ -233,119 +183,121 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP break; } } - if(IsEmpty()) - { + if(IsEmpty()) { corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000); } - if(in_npc->HasPrivateCorpse()) - { + if(in_npc->HasPrivateCorpse()) { corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000); } // Added By Hogie -- End - for (int i=0; irezzexp = 0; } -// To be used on PC death -// Mongrel: added see_invis and see_invis_undead -Corpse::Corpse(Client* client, int32 in_rezexp) -// vesuvias - appearence fix -: Mob -( - "Unnamed_Corpse", - "", - 0, - 0, - client->GetGender(), - client->GetRace(), - client->GetClass(), - BT_Humanoid, // bodytype added - client->GetDeity(), - client->GetLevel(), - 0, - client->GetSize(), - 0, - client->GetHeading(), // heading - client->GetX(), - client->GetY(), - client->GetZ(), - 0, - client->GetTexture(), - client->GetHelmTexture(), - 0, // AC - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, // CHA - client->GetPP().haircolor, - client->GetPP().beardcolor, - client->GetPP().eyecolor1, - client->GetPP().eyecolor2, - client->GetPP().hairstyle, - client->GetPP().face, - client->GetPP().beard, - client->GetPP().drakkin_heritage, - client->GetPP().drakkin_tattoo, - client->GetPP().drakkin_details, - 0, - 0xff, // aa title - 0, - 0, - 0, - 0, - 0, - 0, - 0, // qglobal - 0, // maxlevel - 0 // scalerate -), +Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( + "Unnamed_Corpse", // const char* in_name, + "", // const char* in_lastname, + 0, // int32 in_cur_hp, + 0, // int32 in_max_hp, + client->GetGender(), // uint8 in_gender, + client->GetRace(), // uint16 in_race, + client->GetClass(), // uint8 in_class, + BT_Humanoid, // bodyType in_bodytype, + client->GetDeity(), // uint8 in_deity, + client->GetLevel(), // uint8 in_level, + 0, // uint32 in_npctype_id, + client->GetSize(), // float in_size, + 0, // float in_runspeed, + client->GetHeading(), // float in_heading, + client->GetX(), // float in_x_pos, + client->GetY(), // float in_y_pos, + client->GetZ(), // float in_z_pos, + 0, // uint8 in_light, + client->GetTexture(), // uint8 in_texture, + client->GetHelmTexture(), // uint8 in_helmtexture, + 0, // uint16 in_ac, + 0, // uint16 in_atk, + 0, // uint16 in_str, + 0, // uint16 in_sta, + 0, // uint16 in_dex, + 0, // uint16 in_agi, + 0, // uint16 in_int, + 0, // uint16 in_wis, + 0, // uint16 in_cha, + client->GetPP().haircolor, // uint8 in_haircolor, + client->GetPP().beardcolor, // uint8 in_beardcolor, + client->GetPP().eyecolor1, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? + client->GetPP().eyecolor2, // uint8 in_eyecolor2, + client->GetPP().hairstyle, // uint8 in_hairstyle, + client->GetPP().face, // uint8 in_luclinface, + client->GetPP().beard, // uint8 in_beard, + client->GetPP().drakkin_heritage, // uint32 in_drakkin_heritage, + client->GetPP().drakkin_tattoo, // uint32 in_drakkin_tattoo, + client->GetPP().drakkin_details, // uint32 in_drakkin_details, + 0, // uint32 in_armor_tint[_MaterialCount], + 0xff, // uint8 in_aa_title, + 0, // uint8 in_see_invis, // see through invis + 0, // uint8 in_see_invis_undead, // see through invis vs. undead + 0, // uint8 in_see_hide, + 0, // uint8 in_see_improved_hide, + 0, // int32 in_hp_regen, + 0, // int32 in_mana_regen, + 0, // uint8 in_qglobal, + 0, // uint8 in_maxlevel, + 0 // uint32 in_scalerate + ), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_res_timer(RuleI(Character, CorpseResTimeMS)), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)), - loot_cooldown_timer(10) + loot_cooldown_timer(10) { int i; + PlayerProfile_Struct *pp = &client->GetPP(); ItemInst *item; + /* Check if Zone has Graveyard First */ if(!zone->HasGraveyard()) { corpse_graveyard_timer.Disable(); } memset(item_tint, 0, sizeof(item_tint)); - for (i=0; iCharacterID(); - dbid = 0; - p_depop = false; + is_player_corpse = true; + is_locked = false; + being_looted_by = 0xFFFFFFFF; + char_id = client->CharacterID(); + corpse_db_id = 0; + player_corpse_depop = false; copper = 0; silver = 0; gold = 0; platinum = 0; - strcpy(orgname, pp->name); - strcpy(name, pp->name); - //become_npc was not being initialized which led to some pretty funky things with newly created corpses + strcpy(orgname, pp->name); + strcpy(name, pp->name); + + /* become_npc was not being initialized which led to some pretty funky things with newly created corpses */ become_npc = false; SetPKItem(0); - if(!RuleB(Character, LeaveNakedCorpses) || RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) { + /* Check Rule to see if we can leave corpses */ + if(!RuleB(Character, LeaveNakedCorpses) || + RuleB(Character, LeaveCorpses) && + GetLevel() >= RuleI(Character, DeathItemLossLevel)) { // cash // Let's not move the cash when 'RespawnFromHover = true' && 'client->GetClientVersion() < EQClientSoF' since the client doesn't. // (change to first client that supports 'death hover' mode, if not SoF.) @@ -366,8 +318,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) // worn + inventory + cursor std::list removed_list; bool cursor = false; - for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) - { + for(i = MAIN_BEGIN; i < EmuConstants::MAP_POSSESSIONS_SIZE; i++) { if(i == MainAmmo && client->GetClientVersion() >= EQClientSoF) { item = client->GetInv().GetItem(MainPowerSource); if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) { @@ -393,8 +344,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) iter_queue it; for(it=client->GetInv().cursor_begin(),i=8001; it!=client->GetInv().cursor_end(); ++it,i++) { item = *it; - if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) - { + if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent)) { std::list slot_list = MoveItemToCorpse(client, item, i); removed_list.merge(slot_list); cursor = true; @@ -419,7 +369,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) ++iter; } ss << ")"; - database.RunQuery(ss.str().c_str(), ss.str().length()); + database.QueryDatabase(ss.str().c_str()); } if(cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false) @@ -435,14 +385,14 @@ Corpse::Corpse(Client* client, int32 in_rezexp) client->CalcBonuses(); // will only affect offline profile viewing of dead characters..unneeded overhead client->Save(); - Rezzed(false); + IsRezzed(false); Save(); database.TransactionCommit(); return; } //end "not leaving naked corpses" - Rezzed(false); + IsRezzed(false); Save(); } @@ -458,16 +408,13 @@ std::list Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 returnlist.push_back(equipslot); // Qualified bag slot iterations. processing bag slots that don't exist is probably not a good idea. - if(item->IsType(ItemClassContainer) && ((equipslot >= EmuConstants::GENERAL_BEGIN && equipslot <= MainCursor))) // Limit the bag check to inventory and cursor slots. - { - for(bagindex = SUB_BEGIN; bagindex <= EmuConstants::ITEM_CONTAINER_SIZE; bagindex++) - { + if(item->IsType(ItemClassContainer) && ((equipslot >= EmuConstants::GENERAL_BEGIN && equipslot <= MainCursor))) { + for(bagindex = SUB_BEGIN; bagindex <= EmuConstants::ITEM_CONTAINER_SIZE; bagindex++) { // For empty bags in cursor queue, slot was previously being resolved as SLOT_INVALID (-1) interior_slot = Inventory::CalcSlotId(equipslot, bagindex); interior_item = client->GetInv().GetItem(interior_slot); - if(interior_item) - { + if(interior_item) { AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4)); returnlist.push_back(Inventory::CalcSlotId(equipslot, bagindex)); client->DeleteItemInInventory(interior_slot, 0, true, false); @@ -480,11 +427,57 @@ std::list Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 // To be called from LoadFromDBData // Mongrel: added see_invis and see_invis_undead -Corpse::Corpse(uint32 in_dbid, uint32 in_charid, char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard) - : Mob("Unnamed_Corpse","",0,0,in_gender, in_race, in_class, BT_Humanoid, in_deity, in_level,0, in_size, 0, in_heading, in_x, in_y, in_z,0,in_texture,in_helmtexture, - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0xff, - 0,0,0,0,0,0,0,0,0), +Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard) +: Mob("Unnamed_Corpse", +"", +0, +0, +in_gender, +in_race, +in_class, +BT_Humanoid, +in_deity, +in_level, +0, +in_size, +0, +in_heading, +in_x, +in_y, +in_z, +0, +in_texture, +in_helmtexture, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0xff, +0, +0, +0, +0, +0, +0, +0, +0, +0), corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_res_timer(RuleI(Character, CorpseResTimeMS)), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -492,20 +485,20 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, char* in_charname, ItemList* in loot_cooldown_timer(10) { - //we really should be loading the decay timer here... LoadPlayerCorpseDecayTime(in_dbid); if(!zone->HasGraveyard() || wasAtGraveyard) corpse_graveyard_timer.Disable(); memset(item_tint, 0, sizeof(item_tint)); - pIsChanged = false; - p_PlayerCorpse = true; - pLocked = false; - BeingLootedBy = 0xFFFFFFFF; - dbid = in_dbid; - p_depop = false; - charid = in_charid; + + is_corpse_changed = false; + is_player_corpse = true; + is_locked = false; + being_looted_by = 0xFFFFFFFF; + corpse_db_id = in_dbid; + player_corpse_depop = false; + char_id = in_charid; itemlist = *in_itemlist; in_itemlist->clear(); @@ -516,13 +509,15 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, char* in_charname, ItemList* in this->gold = in_gold; this->platinum = in_plat; rezzexp = in_rezexp; - for (int i=0; iCountItems(); - uint32 tmpsize = sizeof(DBPlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct)); - DBPlayerCorpse_Struct* dbpc = (DBPlayerCorpse_Struct*) new uchar[tmpsize]; + uint32 tmpsize = sizeof(PlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct)); + + PlayerCorpse_Struct* dbpc = (PlayerCorpse_Struct*) new uchar[tmpsize]; memset(dbpc, 0, tmpsize); dbpc->itemcount = tmp; dbpc->size = this->size; - dbpc->locked = pLocked; + dbpc->locked = is_locked; dbpc->copper = this->copper; dbpc->silver = this->silver; dbpc->gold = this->gold; dbpc->plat = this->platinum; - - // Little hack to account for the fact the race in the corpse struct is a uint8 and Froglok/Drakkin race number > 255 - // and to maintain backwards compatability with existing corpses in the database. - uint16 CorpseRace; - - switch(race) { - case DRAKKIN: - CorpseRace = 254; - break; - case FROGLOK: - CorpseRace = 255; - break; - default: - CorpseRace = race; - } - - dbpc->race = CorpseRace; + dbpc->race = this->race; dbpc->class_ = class_; dbpc->gender = gender; dbpc->deity = deity; @@ -604,56 +586,52 @@ bool Corpse::Save() { dbpc->drakkin_details = drakkin_details; uint32 x = 0; - ItemList::iterator cur,end; + ItemList::iterator cur, end; cur = itemlist.begin(); end = itemlist.end(); - for(; cur != end; ++cur) { + for (; cur != end; ++cur) { ServerLootItem_Struct* item = *cur; - item->equipSlot = ServerToCorpseSlot(item->equipSlot); // temp hack until corpse blobs are removed - memcpy((char*) &dbpc->items[x++], (char*) item, sizeof(player_lootitem::ServerLootItem_Struct)); + item->equip_slot = ServerToCorpseSlot(item->equip_slot); // temp hack until corpse blobs are removed + memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(ServerLootItem_Struct)); } - dbpc->crc = CRC32::Generate(&((uchar*) dbpc)[4], tmpsize - 4); - - if (dbid == 0) - { - dbid = database.CreatePlayerCorpse(charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), (uchar*) dbpc, tmpsize, x_pos, y_pos, z_pos, heading); - if(RuleB(Zone, UsePlayerCorpseBackups) == true) - database.CreatePlayerCorpseBackup(dbid, charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), (uchar*) dbpc, tmpsize, x_pos, y_pos, z_pos, heading); + /* Create New Corpse*/ + if (corpse_db_id == 0) { + corpse_db_id = database.SaveCharacterCorpse(char_id, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading); } - else - dbid = database.UpdatePlayerCorpse(dbid, charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), (uchar*) dbpc, tmpsize, x_pos, y_pos, z_pos, heading,Rezzed()); + /* Update Corpse Data */ + else{ + corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed()); + } + safe_delete_array(dbpc); - if (dbid == 0) { - std::cout << "Error: Failed to save player corpse '" << this->GetName() << "'" << std::endl; - return false; - } + return true; } void Corpse::Delete() { - if (IsPlayerCorpse() && dbid != 0) - database.DeletePlayerCorpse(dbid); - dbid = 0; - - p_depop = true; + if (IsPlayerCorpse() && corpse_db_id != 0) + database.DeleteCharacterCorpse(corpse_db_id); + + corpse_db_id = 0; + player_corpse_depop = true; } void Corpse::Bury() { - if (IsPlayerCorpse() && dbid != 0) - database.BuryPlayerCorpse(dbid); - dbid = 0; + if (IsPlayerCorpse() && corpse_db_id != 0) + database.BuryCharacterCorpse(corpse_db_id); + corpse_db_id = 0; - p_depop = true; + player_corpse_depop = true; } void Corpse::Depop() { if (IsNPCCorpse()) - p_depop = true; + player_corpse_depop = true; } void Corpse::DepopCorpse() { - p_depop = true; + player_corpse_depop = true; } uint32 Corpse::CountItems() { @@ -663,22 +641,22 @@ uint32 Corpse::CountItems() { void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5) { if (!database.GetItem(itemnum)) return; - pIsChanged = true; + + is_corpse_changed = true; ServerLootItem_Struct* item = new ServerLootItem_Struct; memset(item, 0, sizeof(ServerLootItem_Struct)); item->item_id = itemnum; item->charges = charges; - item->equipSlot = slot; - item->aug1=aug1; - item->aug2=aug2; - item->aug3=aug3; - item->aug4=aug4; - item->aug5=aug5; + item->equip_slot = slot; + item->aug_1=aug1; + item->aug_2=aug2; + item->aug_3=aug3; + item->aug_4=aug4; + item->aug_5=aug5; itemlist.push_back(item); } -ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) -{ +ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) { ServerLootItem_Struct *sitem = 0, *sitem2; // find the item @@ -686,24 +664,21 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** cur = itemlist.begin(); end = itemlist.end(); for(; cur != end; ++cur) { - if((*cur)->lootslot == lootslot) - { + if((*cur)->lootslot == lootslot) { sitem = *cur; break; } } - if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equipSlot)) - { - int16 bagstart = Inventory::CalcSlotId(sitem->equipSlot, SUB_BEGIN); + if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) { + int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_BEGIN); cur = itemlist.begin(); end = itemlist.end(); for(; cur != end; ++cur) { sitem2 = *cur; - if(sitem2->equipSlot >= bagstart && sitem2->equipSlot < bagstart + 10) - { - bag_item_data[sitem2->equipSlot - bagstart] = sitem2; + if(sitem2->equip_slot >= bagstart && sitem2->equip_slot < bagstart + 10) { + bag_item_data[sitem2->equip_slot - bagstart] = sitem2; } } } @@ -717,8 +692,7 @@ uint32 Corpse::GetWornItem(int16 equipSlot) const { end = itemlist.end(); for(; cur != end; ++cur) { ServerLootItem_Struct* item = *cur; - if (item->equipSlot == equipSlot) - { + if (item->equip_slot == equipSlot) { return item->item_id; } } @@ -726,9 +700,7 @@ uint32 Corpse::GetWornItem(int16 equipSlot) const { return 0; } -void Corpse::RemoveItem(uint16 lootslot) -{ - +void Corpse::RemoveItem(uint16 lootslot) { if (lootslot == 0xFFFF) return; @@ -737,29 +709,25 @@ void Corpse::RemoveItem(uint16 lootslot) end = itemlist.end(); for(; cur != end; ++cur) { ServerLootItem_Struct* sitem = *cur; - if (sitem->lootslot == lootslot) - { + if (sitem->lootslot == lootslot) { RemoveItem(sitem); return; } } } -void Corpse::RemoveItem(ServerLootItem_Struct* item_data) -{ - uint8 material; - +void Corpse::RemoveItem(ServerLootItem_Struct* item_data){ + uint8 material; ItemList::iterator cur,end; cur = itemlist.begin(); end = itemlist.end(); for(; cur != end; ++cur) { ServerLootItem_Struct* sitem = *cur; - if (sitem == item_data) - { - pIsChanged = true; + if (sitem == item_data) { + is_corpse_changed = true; itemlist.erase(cur); - material = Inventory::CalcMaterialFromSlot(sitem->equipSlot); + material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); if(material != _MaterialInvalid) SendWearChange(material); @@ -775,7 +743,7 @@ void Corpse::SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 this->silver = in_silver; this->gold = in_gold; this->platinum = in_platinum; - pIsChanged = true; + is_corpse_changed = true; } void Corpse::RemoveCash() { @@ -783,7 +751,7 @@ void Corpse::RemoveCash() { this->silver = 0; this->gold = 0; this->platinum = 0; - pIsChanged = true; + is_corpse_changed = true; } bool Corpse::IsEmpty() const { @@ -793,13 +761,12 @@ bool Corpse::IsEmpty() const { } bool Corpse::Process() { - if (p_depop) + if (player_corpse_depop) return false; - if(corpse_delay_timer.Check()) - { + if(corpse_delay_timer.Check()) { for (int i=0; iHasGraveyard()) { Save(); - p_depop = true; - database.GraveyardPlayerCorpse(dbid, zone->graveyard_zoneid(), + player_corpse_depop = true; + database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->graveyard_x(), zone->graveyard_y(), zone->graveyard_z(), zone->graveyard_heading()); corpse_graveyard_timer.Disable(); ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; - spc->player_corpse_id = dbid; + spc->player_corpse_id = corpse_db_id; spc->zone_id = zone->graveyard_zoneid(); worldserver.SendPacket(pack); safe_delete(pack); LogFile->write(EQEMuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid())); - dbid = 0; + corpse_db_id = 0; } corpse_graveyard_timer.Disable(); @@ -835,10 +802,10 @@ bool Corpse::Process() { if(!RuleB(Zone, EnableShadowrest)) Delete(); else { - if(database.BuryPlayerCorpse(dbid)) { + if(database.BuryCharacterCorpse(corpse_db_id)) { Save(); - p_depop = true; - dbid = 0; + player_corpse_depop = true; + corpse_db_id = 0; LogFile->write(EQEMuLog::Debug, "Tagged %s player corpse has burried.", this->GetName()); } else @@ -864,10 +831,10 @@ void Corpse::SetDecayTimer(uint32 decaytime) { bool Corpse::CanMobLoot(int charid) { uint8 z=0; for(int i=0; i= MAX_LOOTERS) return; if(them == nullptr || !them->IsClient()) return; - looters[slot] = them->CastToClient()->CharacterID(); + allowed_looters[slot] = them->CastToClient()->CharacterID(); } // @merth: this function needs some work void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) { // Added 12/08. Started compressing loot struct on live. char tmp[10]; - if(p_depop) { + if(player_corpse_depop) { SendLootReqErrorPacket(client, 0); return; } - if(IsPlayerCorpse() && dbid == 0) { + if(IsPlayerCorpse() && corpse_db_id == 0) { // SendLootReqErrorPacket(client, 0); client->Message(13, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!"); std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl; // return; } - if(pLocked && client->Admin() < 100) { + if(is_locked && client->Admin() < 100) { SendLootReqErrorPacket(client, 0); client->Message(13, "Error: Corpse locked by GM."); return; } - if(BeingLootedBy == 0) { BeingLootedBy = 0xFFFFFFFF; } + if(being_looted_by == 0) { being_looted_by = 0xFFFFFFFF; } - if(this->BeingLootedBy != 0xFFFFFFFF) { + if(this->being_looted_by != 0xFFFFFFFF) { // lets double check.... - Entity* looter = entity_list.GetID(this->BeingLootedBy); - if(looter == 0) { this->BeingLootedBy = 0xFFFFFFFF; } + Entity* looter = entity_list.GetID(this->being_looted_by); + if(looter == 0) { this->being_looted_by = 0xFFFFFFFF; } } uint8 tCanLoot = 1; bool lootcoin = false; if(database.GetVariable("LootCoin", tmp, 9)) { lootcoin = (atoi(tmp) == 1); } - if(this->BeingLootedBy != 0xFFFFFFFF && this->BeingLootedBy != client->GetID()) { + if(this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) { SendLootReqErrorPacket(client, 0); tCanLoot = 0; } - else if(IsPlayerCorpse() && charid == client->CharacterID()) { tCanLoot = 2; } + else if(IsPlayerCorpse() && char_id == client->CharacterID()) { tCanLoot = 2; } else if((IsNPCCorpse() || become_npc) && CanMobLoot(client->CharacterID())) { tCanLoot = 2; } else if(GetPKItem() == -1 && CanMobLoot(client->CharacterID())) { tCanLoot = 3; } //pvp loot all items, variable cash else if(GetPKItem() == 1 && CanMobLoot(client->CharacterID())) { tCanLoot = 4; } //pvp loot 1 item, variable cash @@ -933,7 +899,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(tCanLoot == 1) { if(client->Admin() < 100 || !client->GetGM()) { SendLootReqErrorPacket(client, 2); } } if(tCanLoot >= 2 || (tCanLoot == 1 && client->Admin() >= 100 && client->GetGM())) { - this->BeingLootedBy = client->GetID(); + this->being_looted_by = client->GetID(); EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct)); moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer; @@ -941,28 +907,6 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a d->unknown1 = 0x42; d->unknown2 = 0xef; if(tCanLoot == 2 || (tCanLoot >= 3 && lootcoin)) { // dont take the coin off if it's a gm peeking at the corpse - if(zone->lootvar != 0) { - int admin = client->Admin(); - if(zone->lootvar == 7) { client->LogLoot(client, this, 0); } - else if((admin >= 10) && (admin < 20)) { - if((zone->lootvar < 8) && (zone->lootvar > 5)) { client->LogLoot(client, this, 0); } - } - else if(admin <= 20) { - if((zone->lootvar < 8) && (zone->lootvar > 4)) { client->LogLoot(client, this, 0); } - } - else if(admin <= 80) { - if((zone->lootvar < 8) && (zone->lootvar > 3)) { client->LogLoot(client, this, 0); } - } - else if(admin <= 100) { - if((zone->lootvar < 9) && (zone->lootvar > 2)) { client->LogLoot(client, this, 0); } - } - else if(admin <= 150) { - if(((zone->lootvar < 8) && (zone->lootvar > 1)) || (zone->lootvar == 9)) { client->LogLoot(client, this, 0); } - } - else if (admin <= 255) { - if((zone->lootvar < 8) && (zone->lootvar > 0)) { client->LogLoot(client, this, 0); } - } - } if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) { d->copper = 0; @@ -1018,12 +962,12 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a // Dont display the item if it's in a bag // Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse. - if(!IsPlayerCorpse() || item_data->equipSlot <= MainCursor || item_data->equipSlot == MainPowerSource || tCanLoot>=3 || - (item_data->equipSlot >= 8000 && item_data->equipSlot <= 8999)) { + if(!IsPlayerCorpse() || item_data->equip_slot <= MainCursor || item_data->equip_slot == MainPowerSource || tCanLoot>=3 || + (item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) { if(i < corpselootlimit) { item = database.GetItem(item_data->item_id); if(client && item) { - ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug1, item_data->aug2, item_data->aug3, item_data->aug4, item_data->aug5); + ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5); if(inst) { // MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot); @@ -1038,7 +982,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a } } - if(IsPlayerCorpse() && (charid == client->CharacterID() || client->GetGM())) { + if(IsPlayerCorpse() && (char_id == client->CharacterID() || client->GetGM())) { if(i > corpselootlimit) { client->Message(15, "*** This corpse contains more items than can be displayed! ***"); client->Message(0, "Remove items and re-loot corpse to access remaining inventory."); @@ -1070,54 +1014,51 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(client->GetClientVersion() >= EQClientSoD) { SendLootReqErrorPacket(client, 6); } } -void Corpse::LootItem(Client* client, const EQApplicationPacket* app) -{ - //this gets sent out no matter what as a sort of 'ack', so send it here. +void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { + /* This gets sent no matter what as a sort of ACK */ client->QueuePacket(app); - if(!loot_cooldown_timer.Check()) - { + if (!loot_cooldown_timer.Check()) { SendEndLootErrorPacket(client); //unlock corpse for others - if (this->BeingLootedBy = client->GetID()) { - BeingLootedBy = 0xFFFFFFFF; + if (this->being_looted_by = client->GetID()) { + being_looted_by = 0xFFFFFFFF; } return; } - // To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. - if(RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) - { + /* To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. */ + if (RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) { client->Message(13, "You may not loot an item while you have an item on your cursor."); SendEndLootErrorPacket(client); - //unlock corpse for others - if (this->BeingLootedBy = client->GetID()) { - BeingLootedBy = 0xFFFFFFFF; + /* Unlock corpse for others */ + if (this->being_looted_by = client->GetID()) { + being_looted_by = 0xFFFFFFFF; } return; } LootingItem_Struct* lootitem = (LootingItem_Struct*)app->pBuffer; - if (this->BeingLootedBy != client->GetID()) { + if (this->being_looted_by != client->GetID()) { client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client"); SendEndLootErrorPacket(client); return; } - if (IsPlayerCorpse() && !CanMobLoot(client->CharacterID()) && !become_npc && (charid != client->CharacterID() && client->Admin() < 150)) { + if (IsPlayerCorpse() && !CanMobLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) { client->Message(13, "Error: This is a player corpse and you dont own it."); SendEndLootErrorPacket(client); return; } - if (pLocked && client->Admin() < 100) { + if (is_locked && client->Admin() < 100) { SendLootReqErrorPacket(client, 0); client->Message(13, "Error: Corpse locked by GM."); return; } - if(IsPlayerCorpse() && (charid != client->CharacterID()) && CanMobLoot(client->CharacterID()) && GetPKItem()==0){ + if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanMobLoot(client->CharacterID()) && GetPKItem() == 0){ client->Message(13, "Error: You cannot loot any more items from this corpse."); SendEndLootErrorPacket(client); - BeingLootedBy = 0xFFFFFFFF; + being_looted_by = 0xFFFFFFFF; return; } const Item_Struct* item = 0; @@ -1125,50 +1066,46 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10]; memset(bag_item_data, 0, sizeof(bag_item_data)); - if(GetPKItem()>1) + if (GetPKItem() > 1){ item = database.GetItem(GetPKItem()); - else if(GetPKItem()==-1 || GetPKItem()==1) + } + else if (GetPKItem() == -1 || GetPKItem() == 1){ item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward - else + } + else{ item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN, bag_item_data); + } - if (GetPKItem()<=1 && item_data != 0) - { + if (GetPKItem()<=1 && item_data != 0) { item = database.GetItem(item_data->item_id); } - if (item != 0) - { - if(item_data) - inst = database.CreateItem(item, item_data?item_data->charges:0, item_data->aug1, item_data->aug2, item_data->aug3, item_data->aug4, item_data->aug5); - else + if (item != 0) { + if (item_data){ + inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5); + } + else { inst = database.CreateItem(item); + } } - if (client && inst) - { - - if (client->CheckLoreConflict(item)) - { - client->Message_StringID(0,LOOT_LORE_ERROR); + if (client && inst) { + if (client->CheckLoreConflict(item)) { + client->Message_StringID(0, LOOT_LORE_ERROR); SendEndLootErrorPacket(client); - BeingLootedBy = 0; + being_looted_by = 0; delete inst; return; } - if(inst->IsAugmented()) - { - for (int i = AUG_BEGIN; iIsAugmented()) { + for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) { ItemInst *itm = inst->GetAugment(i); - if(itm) - { - if(client->CheckLoreConflict(itm->GetItem())) - { - client->Message_StringID(0,LOOT_LORE_ERROR); + if (itm) { + if (client->CheckLoreConflict(itm->GetItem())) { + client->Message_StringID(0, LOOT_LORE_ERROR); SendEndLootErrorPacket(client); - BeingLootedBy = 0; + being_looted_by = 0; delete inst; return; } @@ -1187,90 +1124,58 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args); parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0); - if ((RuleB(Character, EnableDiscoveredItems))) - { - if(client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID)) + if ((RuleB(Character, EnableDiscoveredItems))) { + if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID)) client->DiscoverItem(inst->GetItem()->ID); } - if (zone->lootvar != 0) - { - int admin=client->Admin(); - if (zone->lootvar==7){ - client->LogLoot(client,this,item); - } - else if ((admin>=10) && (admin<20)){ - if ((zone->lootvar<8) && (zone->lootvar>5)) - client->LogLoot(client,this,item); - } - else if (admin<=20){ - if ((zone->lootvar<8) && (zone->lootvar>4)) - client->LogLoot(client,this,item); - } - else if (admin<=80){ - if ((zone->lootvar<8) && (zone->lootvar>3)) - client->LogLoot(client,this,item); - } - else if (admin<=100){ - if ((zone->lootvar<9) && (zone->lootvar>2)) - client->LogLoot(client,this,item); - } - else if (admin<=150){ - if (((zone->lootvar<8) && (zone->lootvar>1)) || (zone->lootvar==9)) - client->LogLoot(client,this,item); - } - else if (admin<=255){ - if ((zone->lootvar<8) && (zone->lootvar>0)) - client->LogLoot(client,this,item); - } - } - - if(zone->adv_data) - { + if (zone->adv_data) { ServerZoneAdventureDataReply_Struct *ad = (ServerZoneAdventureDataReply_Struct*)zone->adv_data; - if(ad->type == Adventure_Collect && !IsPlayerCorpse()) - { - if(ad->data_id == inst->GetItem()->ID) - { + if (ad->type == Adventure_Collect && !IsPlayerCorpse()) { + if (ad->data_id == inst->GetItem()->ID) { zone->DoAdventureCountIncrease(); } } } - // first add it to the looter - this will do the bag contents too - if(lootitem->auto_loot) - { - if(!client->AutoPutLootInInventory(*inst, true, true, bag_item_data)) + /* First add it to the looter - this will do the bag contents too */ + if (lootitem->auto_loot) { + if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data)) client->PutLootInInventory(MainCursor, *inst, bag_item_data); } - else - { + else { client->PutLootInInventory(MainCursor, *inst, bag_item_data); } - // Update any tasks that have an activity to loot this item. - if(RuleB(TaskSystem, EnableTaskSystem)) + + /* Update any tasks that have an activity to loot this item */ + if (RuleB(TaskSystem, EnableTaskSystem)) client->UpdateTasksForItem(ActivityLoot, item->ID); - // now remove it from the corpse - if(item_data) - RemoveItem(item_data->lootslot); - // remove bag contents too - if (item->ItemClass == ItemClassContainer && (GetPKItem()!=-1 || GetPKItem()!=1)) - { - for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) - { - if (bag_item_data[i]) - { - RemoveItem(bag_item_data[i]); + + /* Remove it from Corpse */ + if (item_data){ + /* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */ + database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id); + /* Delete Item Instance */ + RemoveItem(item_data->lootslot); + } + + /* Remove Bag Contents */ + if (item->ItemClass == ItemClassContainer && (GetPKItem() != -1 || GetPKItem() != 1)) { + for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) { + if (bag_item_data[i]) { + /* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */ + database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id); + /* Delete Item Instance */ + RemoveItem(bag_item_data[i]); } } } - if(GetPKItem()!=-1) + if (GetPKItem() != -1){ SetPKItem(0); + } - //now send messages to all interested parties - - //creates a link for the item + /* Send message with item link to groups and such */ char *link = 0, *link2 = 0; //just like a db query :-) client->MakeItemLink(link2, inst); MakeAnyLenString(&link, "%c" "%s" "%s" "%c", @@ -1294,17 +1199,18 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) } safe_delete_array(link); } - else - { + else { SendEndLootErrorPacket(client); safe_delete(inst); return; } - if (IsPlayerCorpse()) + if (IsPlayerCorpse()){ client->SendItemLink(inst); - else + } + else{ client->SendItemLink(inst, true); + } safe_delete(inst); } @@ -1317,15 +1223,14 @@ void Corpse::EndLoot(Client* client, const EQApplicationPacket* app) { safe_delete(outapp); //client->Save(); //inventory operations auto-commit - this->BeingLootedBy = 0xFFFFFFFF; + this->being_looted_by = 0xFFFFFFFF; if (this->IsEmpty()) Delete(); else Save(); } -void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) -{ +void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { Mob::FillSpawnStruct(ns, ForWho); ns->spawn.max_hp = 120; @@ -1336,8 +1241,7 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) ns->spawn.NPC = 2; } -void Corpse::QueryLoot(Client* to) { - +void Corpse::QueryLoot(Client* to) { int x = 0, y = 0; // x = visible items, y = total items to->Message(0, "Coin: %ip, %ig, %is, %ic", platinum, gold, silver, copper); @@ -1351,7 +1255,7 @@ void Corpse::QueryLoot(Client* to) { ServerLootItem_Struct* sitem = *cur; if (IsPlayerCorpse()) { - if (sitem->equipSlot >= EmuConstants::GENERAL_BAGS_BEGIN && sitem->equipSlot <= EmuConstants::CURSOR_BAG_END) + if (sitem->equip_slot >= EmuConstants::GENERAL_BAGS_BEGIN && sitem->equip_slot <= EmuConstants::CURSOR_BAG_END) sitem->lootslot = 0xFFFF; else x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF; @@ -1359,7 +1263,7 @@ void Corpse::QueryLoot(Client* to) { const Item_Struct* item = database.GetItem(sitem->item_id); if (item) - to->Message((sitem->lootslot == 0xFFFF), "LootSlot: %i (EquipSlot: %i) Item: %s (%d), Count: %i", static_cast(sitem->lootslot), sitem->equipSlot, item->Name, item->ID, sitem->charges); + to->Message((sitem->lootslot == 0xFFFF), "LootSlot: %i (EquipSlot: %i) Item: %s (%d), Count: %i", static_cast(sitem->lootslot), sitem->equip_slot, item->Name, item->ID, sitem->charges); else to->Message((sitem->lootslot == 0xFFFF), "Error: 0x%04x", sitem->item_id); @@ -1389,8 +1293,7 @@ void Corpse::QueryLoot(Client* to) { } } -bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) -{ +bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) { uint32 dist2 = 10000; // pow(100, 2); if (!spell) { if (this->GetCharID() == client->CharacterID()) { @@ -1398,13 +1301,11 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) client->Message(13, "That corpse is locked by a GM."); return false; } - if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) - { + if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) { GMMove(client->GetX(), client->GetY(), client->GetZ()); - pIsChanged = true; + is_corpse_changed = true; } - else - { + else { client->Message(0, "Corpse is too far away."); return false; } @@ -1413,25 +1314,20 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) { bool consented = false; std::list::iterator itr; - for(itr = client->consent_list.begin(); itr != client->consent_list.end(); ++itr) - { - if(strcmp(this->GetOwnerName(), itr->c_str()) == 0) - { - if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) - { + for(itr = client->consent_list.begin(); itr != client->consent_list.end(); ++itr) { + if(strcmp(this->GetOwnerName(), itr->c_str()) == 0) { + if (!CheckDistance || (DistNoRootNoZ(*client) <= dist2)) { GMMove(client->GetX(), client->GetY(), client->GetZ()); - pIsChanged = true; + is_corpse_changed = true; } - else - { + else { client->Message(0, "Corpse is too far away."); return false; } consented = true; } } - if(!consented) - { + if(!consented) { client->Message(0, "You do not have permission to move this corpse."); return false; } @@ -1439,7 +1335,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) } else { GMMove(client->GetX(), client->GetY(), client->GetZ()); - pIsChanged = true; + is_corpse_changed = true; } Save(); return true; @@ -1447,7 +1343,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) void Corpse::CompleteRezz(){ rezzexp = 0; - pIsChanged = true; + is_corpse_changed = true; this->Save(); } @@ -1458,539 +1354,10 @@ void Corpse::Spawn() { safe_delete(app); } -bool ZoneDatabase::DeleteGraveyard(uint32 zone_id, uint32 graveyard_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - uint32 query_length = 0; - uint32 affected_rows = 0; - - query_length = sprintf(query,"UPDATE zone SET graveyard_id=0 WHERE zoneidnumber=%u AND version=0", zone_id); - - if (!RunQuery(query, query_length, errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in DeleteGraveyard query " << errbuf << std::endl; - return false; - } - - if (affected_rows == 0) { - std::cerr << "Error2 in DeleteGraveyard query: affected_rows = 0" << std::endl; - return false; - } - - query_length = sprintf(query,"DELETE FROM graveyard WHERE id=%u", graveyard_id); - - if (!RunQuery(query, query_length, errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error3 in DeleteGraveyard query " << errbuf << std::endl; - return false; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error4 in DeleteGraveyard query: affected_rows = 0" << std::endl; - return false; - } - - return true; -} -uint32 ZoneDatabase::AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - - end += sprintf(end,"UPDATE zone SET graveyard_id=%u WHERE zoneidnumber=%u AND version=0", graveyard_id, zone_id); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in AddGraveyardIDToZone query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in AddGraveyardIDToZone query: affected_rows = 0" << std::endl; - return 0; - } - - return zone_id; -} -uint32 ZoneDatabase::NewGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - uint32 new_graveyard_id = 0; - - end += sprintf(end,"INSERT INTO graveyard SET zone_id=%u, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f", graveyard_zoneid, graveyard_x, graveyard_y, graveyard_z, graveyard_heading); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows, &new_graveyard_id)) { - safe_delete_array(query); - std::cerr << "Error1 in NewGraveyardRecord query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in NewGraveyardRecord query: affected_rows = 0" << std::endl; - return 0; - } - - if(new_graveyard_id <= 0) { - std::cerr << "Error3 in NewGraveyardRecord query: new_graveyard_id <= 0" << std::endl; - return 0; - } - - return new_graveyard_id; -} -uint32 ZoneDatabase::GraveyardPlayerCorpse(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - - // We probably don't want a graveyard located in an instance. - end += sprintf(end,"Update player_corpses SET zoneid=%u, instanceid=0, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, WasAtGraveyard=1 WHERE id=%d", zoneid, x, y, z, heading, dbid); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in GraveyardPlayerCorpse query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in GraveyardPlayerCorpse query: affected_rows = 0" << std::endl; - return 0; - } - return dbid; -} -uint32 ZoneDatabase::UpdatePlayerCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading, bool rezzed) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256+(datasize*2)]; - char* end = query; - uint32 affected_rows = 0; - - end += sprintf(end, "Update player_corpses SET data="); - *end++ = '\''; - end += DoEscapeString(end, (char*)data, datasize); - *end++ = '\''; - end += sprintf(end,", charname='%s', zoneid=%u, instanceid=%u, charid=%d, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f WHERE id=%d", charname, zoneid, instanceid, charid, x, y, z, heading, dbid); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in UpdatePlayerCorpse query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in UpdatePlayerCorpse query: affected_rows = 0" << std::endl; - return 0; - } - if(rezzed){ - if (!RunQuery(query, MakeAnyLenString(&query, "update player_corpses set rezzed = 1 WHERE id=%d",dbid), errbuf)) { - std::cerr << "Error in UpdatePlayerCorpse/Rezzed query: " << errbuf << std::endl; - } - safe_delete_array(query); - } - return dbid; -} - -void ZoneDatabase::MarkCorpseAsRezzed(uint32 dbid) -{ - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - - if(!database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET rezzed = 1 WHERE id = %i", dbid), errbuf)) - { - LogFile->write(EQEMuLog::Error, "MarkCorpseAsRezzed failed: %s, %s", query, errbuf); - } - safe_delete_array(query); -} - -uint32 ZoneDatabase::CreatePlayerCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256+(datasize*2)]; - char* end = query; - //MYSQL_RES *result; - //MYSQL_ROW row; - uint32 affected_rows = 0; - uint32 last_insert_id = 0; - - end += sprintf(end, "Insert into player_corpses SET data="); - *end++ = '\''; - end += DoEscapeString(end, (char*)data, datasize); - *end++ = '\''; - end += sprintf(end,", charname='%s', zoneid=%u, instanceid=%u, charid=%d, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, timeofdeath=Now(), IsBurried=0", charname, zoneid, instanceid, charid, x, y, z, heading); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows, &last_insert_id)) { - safe_delete_array(query); - std::cerr << "Error1 in CreatePlayerCorpse query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in CreatePlayerCorpse query: affected_rows = 0" << std::endl; - return 0; - } - - if (last_insert_id == 0) { - std::cerr << "Error3 in CreatePlayerCorpse query: last_insert_id = 0" << std::endl; - return 0; - } - - return last_insert_id; -} - -bool ZoneDatabase::CreatePlayerCorpseBackup(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256+(datasize*2)]; - char* end = query; - uint32 affected_rows = 0; - uint32 last_insert_id = 0; - bool result = false; - DBPlayerCorpse_Struct* dbpcs = (DBPlayerCorpse_Struct*) data; - - if (dbid != 0) { - if(RuleB(Character, LeaveCorpses) == true && dbpcs->level >= RuleI(Character, DeathItemLossLevel)){ - end += sprintf(end, "Insert into player_corpses_backup SET data="); - *end++ = '\''; - end += DoEscapeString(end, (char*)data, datasize); - *end++ = '\''; - end += sprintf(end,", charname='%s', zoneid=%u, instanceid=%u, charid=%d, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, timeofdeath=Now(), IsBurried=0, id=%u", charname, zoneid, instanceid, charid, x, y, z, heading, dbid); - - if (RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - if (affected_rows == 1) - result = true; - else - std::cerr << "Error in CreatePlayerCorpseBackup query: affected_rows != 1" << std::endl; - } - else - std::cerr << "Error in CreatePlayerCorpseBackup query " << errbuf << std::endl; - } - safe_delete_array(query); - } - else { - std::cerr << "Error in CreatePlayerCorpseBackup: dbid = 0" << std::endl; - } - return result; -} - -uint32 ZoneDatabase::GetPlayerBurriedCorpseCount(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 CorpseCount = 0; - - if (RunQuery(query, MakeAnyLenString(&query, "select count(*) from player_corpses where charid = '%u' and IsBurried = 1", char_id), errbuf, &result)) { - row = mysql_fetch_row(result); - CorpseCount = atoi(row[0]); - mysql_free_result(result); - } - else { - std::cerr << "Error in GetPlayerBurriedCorpseCount query '" << query << "' " << errbuf << std::endl; - } - - safe_delete_array(query); - - return CorpseCount; -} - -uint32 ZoneDatabase::GetPlayerCorpseCount(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 CorpseCount = 0; - - if (RunQuery(query, MakeAnyLenString(&query, "select count(*) from player_corpses where charid = '%u'", char_id), errbuf, &result)) { - row = mysql_fetch_row(result); - CorpseCount = atoi(row[0]); - mysql_free_result(result); - } - else { - std::cerr << "Error in GetPlayerCorpseCount query '" << query << "' " << errbuf << std::endl; - } - - safe_delete_array(query); - - return CorpseCount; -} - -uint32 ZoneDatabase::GetPlayerCorpseID(uint32 char_id, uint8 corpse) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 id = 0; - - if (RunQuery(query, MakeAnyLenString(&query, "select id from player_corpses where charid = '%u'", char_id), errbuf, &result)) { - for (int i=0; iGetWornItem(slotid); - tmp->DepopCorpse(); - } - return itemid; -} - -Corpse* ZoneDatabase::SummonBurriedPlayerCorpse(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - Corpse* NewCorpse = 0; - unsigned long* lengths; - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u' AND IsBurried=1 ORDER BY timeofdeath LIMIT 1", char_id), errbuf, &result)) { - row = mysql_fetch_row(result); - lengths = mysql_fetch_lengths(result); - if(row) { - NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), char_id, row[1], (uchar*) row[2], lengths[2], dest_x, dest_y, dest_z, dest_heading, row[3],atoi(row[4])==1, false); - if(NewCorpse) { - entity_list.AddCorpse(NewCorpse); - NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - NewCorpse->Spawn(); - if(!UnburyPlayerCorpse(NewCorpse->GetDBID(), dest_zoneid, dest_instanceid, dest_x, dest_y, dest_z, dest_heading)) - LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); - } - else - LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse from a burried player corpse for character id %u.", char_id); - } - - mysql_free_result(result); - } - else { - std::cerr << "Error in SummonBurriedPlayerCorpse query '" << query << "' " << errbuf << std::endl; - } - - safe_delete_array(query); - - return NewCorpse; -} - -bool ZoneDatabase::SummonAllPlayerCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, - float dest_x, float dest_y, float dest_z, float dest_heading) -{ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - Corpse* NewCorpse = 0; - int CorpseCount = 0; - unsigned long* lengths; - - if(!RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid = %i, instanceid = %i, x = %f, y = %f, z = %f, " - "heading = %f, IsBurried = 0, WasAtGraveyard = 0 WHERE charid = %i", - dest_zoneid, dest_instanceid, dest_x, dest_y, dest_z, dest_heading, char_id), errbuf)) - LogFile->write(EQEMuLog::Error, "Error moving corpses, Query = %s, Error = %s\n", query, errbuf); - - safe_delete_array(query); - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u'" - "ORDER BY timeofdeath", char_id), errbuf, &result)) - { - while((row = mysql_fetch_row(result))) - { - lengths = mysql_fetch_lengths(result); - NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), char_id, row[1], (uchar*) row[2], lengths[2], dest_x, dest_y, - dest_z, dest_heading, row[3],atoi(row[4])==1, false); - if(NewCorpse) { - entity_list.AddCorpse(NewCorpse); - NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - NewCorpse->Spawn(); - ++CorpseCount; - } - else - LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse for character id %u.", char_id); - } - - mysql_free_result(result); - } - else - LogFile->write(EQEMuLog::Error, "Error in SummonAllPlayerCorpses Query = %s, Error = %s\n", query, errbuf); - - safe_delete_array(query); - - return (CorpseCount > 0); -} - -bool ZoneDatabase::UnburyPlayerCorpse(uint32 dbid, uint32 new_zoneid, uint16 new_instanceid, float new_x, float new_y, float new_z, float new_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - bool Result = false; - - end += sprintf(end, "UPDATE player_corpses SET IsBurried=0, zoneid=%u, instanceid=%u, x=%f, y=%f, z=%f, heading=%f, timeofdeath=Now(), WasAtGraveyard=0 WHERE id=%u", new_zoneid, new_instanceid, new_x, new_y, new_z, new_heading, dbid); - - if (RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - if (affected_rows == 1) - Result = true; - else - std::cerr << "Error2 in UnburyPlayerCorpse query: affected_rows NOT EQUAL to 1, as expected." << std::endl; - } - else - std::cerr << "Error1 in UnburyPlayerCorpse query " << errbuf << std::endl; - - safe_delete_array(query); - - return Result; -} - -Corpse* ZoneDatabase::LoadPlayerCorpse(uint32 player_corpse_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - Corpse* NewCorpse = 0; - unsigned long* lengths; - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charid, charname, x, y, z, heading, data, timeofdeath, rezzed, WasAtGraveyard FROM player_corpses WHERE id='%u'", player_corpse_id), errbuf, &result)) { - row = mysql_fetch_row(result); - lengths = mysql_fetch_lengths(result); - if(row && lengths) - { - NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), atoi(row[1]), row[2], (uchar*) row[7], lengths[7], atof(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), row[8],atoi(row[9])==1, atoi(row[10])); - entity_list.AddCorpse(NewCorpse); - } - mysql_free_result(result); - } - else { - std::cerr << "Error in LoadPlayerCorpse query '" << query << "' " << errbuf << std::endl; - std::cerr << "Note that if your missing the 'rezzed' field you can add it with:\nALTER TABLE `player_corpses` ADD `rezzed` TINYINT UNSIGNED DEFAULT \"0\";\n"; - } - - safe_delete_array(query); - - return NewCorpse; -} - -bool ZoneDatabase::LoadPlayerCorpses(uint32 iZoneID, uint16 iInstanceID) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 query_length = 0; - - unsigned long* lengths; - - if(!RuleB(Zone, EnableShadowrest)) - query_length = MakeAnyLenString(&query, "SELECT id, charid, charname, x, y, z, heading, data, timeofdeath, rezzed, WasAtGraveyard FROM player_corpses WHERE zoneid='%u' AND instanceid='%u'", iZoneID, iInstanceID); - else - query_length = MakeAnyLenString(&query, "SELECT id, charid, charname, x, y, z, heading, data, timeofdeath, rezzed, 0 FROM player_corpses WHERE zoneid='%u' AND instanceid='%u' AND IsBurried=0", iZoneID, iInstanceID); - - if (RunQuery(query, query_length, errbuf, &result)) { - safe_delete_array(query); - while ((row = mysql_fetch_row(result))) { - lengths = mysql_fetch_lengths(result); - entity_list.AddCorpse(Corpse::LoadFromDBData(atoi(row[0]), atoi(row[1]), row[2], (uchar*) row[7], lengths[7], atof(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), row[8],atoi(row[9])==1, atoi(row[10]))); - } - mysql_free_result(result); - } - else { - std::cerr << "Error in LoadPlayerCorpses query '" << query << "' " << errbuf << std::endl; - std::cerr << "Note that if your missing the 'rezzed' field you can add it with:\nALTER TABLE `player_corpses` ADD `rezzed` TINYINT UNSIGNED DEFAULT \"0\";\n"; - safe_delete_array(query); - return false; - } - - return true; -} - -uint32 ZoneDatabase::GetFirstCorpseID(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 CorpseID = 0; - - MakeAnyLenString(&query, "SELECT id FROM player_corpses WHERE charid='%u' AND IsBurried=0 ORDER BY timeofdeath LIMIT 1", char_id); - if (RunQuery(query, strlen(query), errbuf, &result)) { - if (mysql_num_rows(result)!= 0){ - row = mysql_fetch_row(result); - CorpseID = atoi(row[0]); - mysql_free_result(result); - } - } - else { - std::cerr << "Error in GetFirstCorpseID query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return 0; - } - - safe_delete_array(query); - return CorpseID; -} - -bool ZoneDatabase::BuryPlayerCorpse(uint32 dbid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET IsBurried = 1 WHERE id=%d", dbid), errbuf)) { - std::cerr << "Error in BuryPlayerCorpse query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - - safe_delete_array(query); - return true; -} - -bool ZoneDatabase::BuryAllPlayerCorpses(uint32 charid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET IsBurried = 1 WHERE charid=%d", charid), errbuf)) { - std::cerr << "Error in BuryPlayerCorpse query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - - safe_delete_array(query); - return true; -} - -bool ZoneDatabase::DeletePlayerCorpse(uint32 dbid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "Delete from player_corpses where id=%d", dbid), errbuf)) { - std::cerr << "Error in DeletePlayerCorpse query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - - safe_delete_array(query); - return true; -} - -// these functions operate with a material slot, which is from 0 to 8 uint32 Corpse::GetEquipment(uint8 material_slot) const { int invslot; - if(material_slot > EmuConstants::MATERIAL_END) - { + if(material_slot > EmuConstants::MATERIAL_END) { return NO_ITEM; } @@ -2004,14 +1371,12 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const { uint32 Corpse::GetEquipmentColor(uint8 material_slot) const { const Item_Struct *item; - if(material_slot > EmuConstants::MATERIAL_END) - { + if(material_slot > EmuConstants::MATERIAL_END) { return 0; } item = database.GetItem(GetEquipment(material_slot)); - if(item != NO_ITEM) - { + if(item != NO_ITEM) { return item_tint[material_slot].rgb.use_tint ? item_tint[material_slot].color : item->Color; @@ -2020,56 +1385,32 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const { return 0; } -void Corpse::AddLooter(Mob* who) -{ - for (int i=0; iCastToClient()->CharacterID(); +void Corpse::AddLooter(Mob* who) { + for (int i=0; iCastToClient()->CharacterID(); break; } } } -void Corpse::LoadPlayerCorpseDecayTime(uint32 dbid){ - if(!dbid) +void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){ + if(!corpse_db_id) return; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) FROM player_corpses WHERE id=%d and not timeofdeath=0", dbid), errbuf, &result)) { - safe_delete_array(query); - while ((row = mysql_fetch_row(result))) { - if(atoi(row[0]) > 0 && RuleI(Character, CorpseDecayTimeMS) > (atoi(row[0]) * 1000)) { - corpse_decay_timer.SetTimer(RuleI(Character, CorpseDecayTimeMS) - (atoi(row[0]) * 1000)); - /* - if(RuleI(Character, CorpseResTimeMS) > (atoi(row[0]) * 1000)) { - corpse_res_timer.SetTimer(RuleI(Character, CorpseResTimeMS) - (atoi(row[0]) * 1000)); - } - else { - corpse_res_timer.Disable(); - can_rez = false; - } - */ - } - else { - corpse_decay_timer.SetTimer(2000); - //corpse_res_timer.SetTimer(300000); - } - if(atoi(row[0]) > 0 && RuleI(Zone, GraveyardTimeMS) > (atoi(row[0]) * 1000)) { - corpse_graveyard_timer.SetTimer(RuleI(Zone, GraveyardTimeMS) - (atoi(row[0]) * 1000)); - } - else { - corpse_graveyard_timer.SetTimer(3000); - } - } - mysql_free_result(result); + uint32 active_corpse_decay_timer = database.GetCharacterCorpseDecayTimer(corpse_db_id); + if (active_corpse_decay_timer > 0 && RuleI(Character, CorpseDecayTimeMS) > (active_corpse_decay_timer * 1000)) { + corpse_decay_timer.SetTimer(RuleI(Character, CorpseDecayTimeMS) - (active_corpse_decay_timer * 1000)); + } + else { + corpse_decay_timer.SetTimer(2000); + } + if (active_corpse_decay_timer > 0 && RuleI(Zone, GraveyardTimeMS) > (active_corpse_decay_timer * 1000)) { + corpse_graveyard_timer.SetTimer(RuleI(Zone, GraveyardTimeMS) - (active_corpse_decay_timer * 1000)); + } + else { + corpse_graveyard_timer.SetTimer(3000); } - else - safe_delete_array(query); } /* @@ -2177,28 +1518,4 @@ int16 Corpse::CorpseToServerSlot(int16 corpse_slot) return corpse_slot; } */ -} - -/* -void Corpse::CastRezz(uint16 spellid, Mob* Caster){ - if(Rezzed()){ - if(Caster && Caster->IsClient()) - Caster->Message(13,"This character has already been resurrected."); - return; - } - - APPLAYER* outapp = new APPLAYER(OP_RezzRequest, sizeof(Resurrect_Struct)); - Resurrect_Struct* rezz = (Resurrect_Struct*) outapp->pBuffer; - memcpy(rezz->your_name,this->orgname,30); - memcpy(rezz->corpse_name,this->name,30); - memcpy(rezz->rezzer_name,Caster->GetName(),30); - memcpy(rezz->zone,zone->GetShortName(),15); - rezz->spellid = spellid; - rezz->x = this->x_pos; - rezz->y = this->y_pos; - rezz->z = (float)this->z_pos; - worldserver.RezzPlayer(outapp, rezzexp, OP_RezzRequest); - //DumpPacket(outapp); - safe_delete(outapp); -} -*/ +} \ No newline at end of file diff --git a/zone/corpse.h b/zone/corpse.h index 2d1eecc98..f365dd041 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -26,64 +26,64 @@ class NPC; #define MAX_LOOTERS 72 -class Corpse : public Mob -{ +class Corpse : public Mob { public: - static void SendEndLootErrorPacket(Client* client); - static void SendLootReqErrorPacket(Client* client, uint8 response = 2); - static Corpse* LoadFromDBData(uint32 in_corpseid, uint32 in_charid, char* in_charname, uchar* in_data, uint32 in_datasize, float in_x, float in_y, float in_z, float in_heading, char* timeofdeath, bool rezzed = false, bool wasAtGraveyard = false); + static void SendEndLootErrorPacket(Client* client); + static void SendLootReqErrorPacket(Client* client, uint8 response = 2); + Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000); Corpse(Client* client, int32 in_rezexp); - Corpse(uint32 in_corpseid, uint32 in_charid, char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard = false); + Corpse(uint32 in_corpseid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture, uint32 in_rezexp, bool wasAtGraveyard = false); ~Corpse(); + static Corpse* LoadFromDBData(uint32 in_dbid, uint32 in_charid, std::string in_charname, float in_x, float in_y, float in_z, float in_heading, std::string time_of_death, bool rezzed, bool was_at_graveyard); //abstract virtual function implementations requird by base abstract class - virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; } - virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; } - virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, - ExtraAttackOptions *opts = nullptr) { return false; } - virtual bool HasRaid() { return false; } - virtual bool HasGroup() { return false; } - virtual Raid* GetRaid() { return 0; } - virtual Group* GetGroup() { return 0; } + virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; } + virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; } + virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, + bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } + virtual bool HasRaid() { return false; } + virtual bool HasGroup() { return false; } + virtual Raid* GetRaid() { return 0; } + virtual Group* GetGroup() { return 0; } - void LoadPlayerCorpseDecayTime(uint32 dbid); + void LoadPlayerCorpseDecayTime(uint32 dbid); - bool IsCorpse() const { return true; } - bool IsPlayerCorpse() const { return p_PlayerCorpse; } - bool IsNPCCorpse() const { return !p_PlayerCorpse; } - bool IsBecomeNPCCorpse() const { return become_npc; } - bool Process(); - bool Save(); - uint32 GetCharID() { return charid; } - uint32 SetCharID(uint32 iCharID) { if (IsPlayerCorpse()) { return (charid=iCharID); } return 0xFFFFFFFF; }; - uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); } - uint32 GetResTime() { if (!corpse_res_timer.Enabled()) return 0; else return corpse_res_timer.GetRemainingTime(); } - void CalcCorpseName(); - inline void Lock() { pLocked = true; } - inline void UnLock() { pLocked = false; } - inline bool IsLocked() { return pLocked; } - inline void ResetLooter() { BeingLootedBy = 0xFFFFFFFF; } - inline bool IsBeingLooted() { return (BeingLootedBy != 0xFFFFFFFF); } - inline uint32 GetDBID() { return dbid; } + bool IsCorpse() const { return true; } + bool IsPlayerCorpse() const { return is_player_corpse; } + bool IsNPCCorpse() const { return !is_player_corpse; } + bool IsBecomeNPCCorpse() const { return become_npc; } + bool Process(); + bool Save(); + uint32 GetCharID() { return char_id; } + uint32 SetCharID(uint32 iCharID) { if (IsPlayerCorpse()) { return (char_id = iCharID); } return 0xFFFFFFFF; }; + uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); } + uint32 GetResTime() { if (!corpse_res_timer.Enabled()) return 0; else return corpse_res_timer.GetRemainingTime(); } + void CalcCorpseName(); + inline void Lock() { is_locked = true; } + inline void UnLock() { is_locked = false; } + inline bool IsLocked() { return is_locked; } + inline void ResetLooter() { being_looted_by = 0xFFFFFFFF; } + inline bool IsBeingLooted() { return (being_looted_by != 0xFFFFFFFF); } + inline uint32 GetDBID() { return corpse_db_id; } inline char* GetOwnerName() { return orgname;} - void SetDecayTimer(uint32 decaytime); - bool IsEmpty() const; - void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0); - uint32 GetWornItem(int16 equipSlot) const; - ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0); - void RemoveItem(uint16 lootslot); - void RemoveItem(ServerLootItem_Struct* item_data); - void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum); - void RemoveCash(); - void QueryLoot(Client* to); - uint32 CountItems(); - void Delete(); - void Bury(); - virtual void Depop(); - virtual void DepopCorpse(); + void SetDecayTimer(uint32 decaytime); + bool IsEmpty() const; + void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0); + uint32 GetWornItem(int16 equipSlot) const; + ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0); + void RemoveItem(uint16 lootslot); + void RemoveItem(ServerLootItem_Struct* item_data); + void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum); + void RemoveCash(); + void QueryLoot(Client* to); + uint32 CountItems(); + void Delete(); + void Bury(); + virtual void Depop(); + virtual void DepopCorpse(); uint32 GetCopper() { return copper; } uint32 GetSilver() { return silver; } @@ -97,19 +97,19 @@ public: bool Summon(Client* client, bool spell, bool CheckDistance); void CastRezz(uint16 spellid, Mob* Caster); void CompleteRezz(); - void SetPKItem(int32 id) { pkitem = id; } - int32 GetPKItem() { return pkitem; } - bool CanMobLoot(int charid); - void AllowMobLoot(Mob *them, uint8 slot); - void AddLooter(Mob *who); - bool Rezzed() { return rez; } - void Rezzed(bool in_rez) { rez = in_rez; } + void SetPKItem(int32 id) { player_kill_item = id; } + int32 GetPKItem() { return player_kill_item; } + bool CanMobLoot(int charid); + void AllowMobLoot(Mob *them, uint8 slot); + void AddLooter(Mob *who); + bool IsRezzed() { return rez; } + void IsRezzed(bool in_rez) { rez = in_rez; } void Spawn(); char orgname[64]; - uint32 GetEquipment(uint8 material_slot) const; // returns item id - uint32 GetEquipmentColor(uint8 material_slot) const; - inline int GetRezzExp() { return rezzexp; } + uint32 GetEquipment(uint8 material_slot) const; // returns item id + uint32 GetEquipmentColor(uint8 material_slot) const; + inline int GetRezzExp() { return rezzexp; } // these are a temporary work-around until corpse inventory is removed from the database blob static int16 ServerToCorpseSlot(int16 server_slot); // encode @@ -119,24 +119,25 @@ protected: std::list MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot); private: - bool p_PlayerCorpse; bool pIsChanged; - bool pLocked; - int32 pkitem; - uint32 dbid; - uint32 charid; + bool is_player_corpse; + bool is_corpse_changed; + bool is_locked; + int32 player_kill_item; + uint32 corpse_db_id; + uint32 char_id; ItemList itemlist; uint32 copper; uint32 silver; uint32 gold; uint32 platinum; - bool p_depop; - uint32 BeingLootedBy; + bool player_corpse_depop; + uint32 being_looted_by; uint32 rezzexp; bool rez; bool can_rez; bool become_npc; - int looters[MAX_LOOTERS]; // People allowed to loot the corpse, character id - Timer corpse_decay_timer; + int allowed_looters[MAX_LOOTERS]; // People allowed to loot the corpse, character id + Timer corpse_decay_timer; Timer corpse_res_timer; Timer corpse_delay_timer; Timer corpse_graveyard_timer; diff --git a/zone/doors.cpp b/zone/doors.cpp index 5ff7eae26..4af1d3eae 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -50,7 +50,7 @@ Doors::Doors(const Door* door) incline = door->incline; opentype = door->opentype; guild_id = door->guild_id; - lockpick = door->lockpick; + lockpick = door->lock_pick; keyitem = door->keyitem; nokeyring = door->nokeyring; trigger_door = door->trigger_door; @@ -678,7 +678,7 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name into[rowIndex].heading = (float)atof(row[7]); into[rowIndex].opentype = atoi(row[8]); into[rowIndex].guild_id = atoi(row[9]); - into[rowIndex].lockpick = atoi(row[10]); + into[rowIndex].lock_pick = atoi(row[10]); into[rowIndex].keyitem = atoi(row[11]); into[rowIndex].nokeyring = atoi(row[12]); into[rowIndex].trigger_door = atoi(row[13]); diff --git a/zone/entity.cpp b/zone/entity.cpp index ed5b99219..122e24582 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1678,7 +1678,7 @@ int EntityList::RezzAllCorpsesByCharID(uint32 charid) while (it != corpse_list.end()) { if (it->second->GetCharID() == charid) { RezzExp += it->second->GetRezzExp(); - it->second->Rezzed(true); + it->second->IsRezzed(true); it->second->CompleteRezz(); } ++it; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 8cc9e4cff..76b077e2d 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -858,7 +858,7 @@ void Client::PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootI { if(bag_item_data[i] == nullptr) continue; - const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug1, bag_item_data[i]->aug2, bag_item_data[i]->aug3, bag_item_data[i]->aug4, bag_item_data[i]->aug5); + const ItemInst *bagitem = database.CreateItem(bag_item_data[i]->item_id, bag_item_data[i]->charges, bag_item_data[i]->aug_1, bag_item_data[i]->aug_2, bag_item_data[i]->aug_3, bag_item_data[i]->aug_4, bag_item_data[i]->aug_5); interior_slot = Inventory::CalcSlotId(slot_id, i); mlog(INVENTORY__SLOTS, "Putting bag loot item %s (%d) into slot %d (bag slot %d)", inst.GetItem()->Name, inst.GetItem()->ID, interior_slot, i); PutLootInInventory(interior_slot, *bagitem); diff --git a/zone/loottables.cpp b/zone/loottables.cpp index b2ebec5ff..0c66778bd 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -195,13 +195,13 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge item->item_id = item2->ID; item->charges = charges; - item->aug1 = 0; - item->aug2 = 0; - item->aug3 = 0; - item->aug4 = 0; - item->aug5 = 0; - item->minlevel = minlevel; - item->maxlevel = maxlevel; + item->aug_1 = 0; + item->aug_2 = 0; + item->aug_3 = 0; + item->aug_4 = 0; + item->aug_5 = 0; + item->min_level = minlevel; + item->max_level = maxlevel; if (equipit) { uint8 eslot = 0xFF; char newid[20]; @@ -339,7 +339,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge if (found) { CalcBonuses(); // This is less than ideal for bulk adding of items } - item->equipSlot = item2->Slots; + item->equip_slot = item2->Slots; } if(itemlist != nullptr) diff --git a/zone/lua_corpse.cpp b/zone/lua_corpse.cpp index 6498458ae..beada7e9a 100644 --- a/zone/lua_corpse.cpp +++ b/zone/lua_corpse.cpp @@ -44,7 +44,7 @@ uint32 Lua_Corpse::GetDBID() { bool Lua_Corpse::IsRezzed() { Lua_Safe_Call_Bool(); - return self->Rezzed(); + return self->IsRezzed(); } const char* Lua_Corpse::GetOwnerName() { diff --git a/zone/merc.cpp b/zone/merc.cpp index 94d129b14..2ecd0849e 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4338,7 +4338,7 @@ Corpse* Merc::GetGroupMemberCorpse() { if(g->members[i] && g->members[i]->IsClient()) { corpse = entity_list.GetCorpseByOwnerWithinRange(g->members[i]->CastToClient(), this, RuleI(Mercs, ResurrectRadius)); - if(corpse && !corpse->Rezzed()) { + if(corpse && !corpse->IsRezzed()) { return corpse; } } @@ -6367,4 +6367,4 @@ uint32 Merc::CalcUpkeepCost(uint32 templateID , uint8 level, uint8 currency_type } return cost; -} \ No newline at end of file +} diff --git a/zone/npc.cpp b/zone/npc.cpp index 2e5ac4825..eae42b670 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -429,7 +429,7 @@ ServerLootItem_Struct* NPC::GetItem(int slot_id) { end = itemlist.end(); for(; cur != end; ++cur) { ServerLootItem_Struct* item = *cur; - if (item->equipSlot == slot_id) { + if (item->equip_slot == slot_id) { return item; } } @@ -446,7 +446,7 @@ void NPC::RemoveItem(uint32 item_id, uint16 quantity, uint16 slot) { itemlist.erase(cur); return; } - else if (item->item_id == item_id && item->equipSlot == slot && quantity >= 1) { + else if (item->item_id == item_id && item->equip_slot == slot && quantity >= 1) { //std::cout<<"NPC::RemoveItem"<<" equipSlot:"<equipSlot<<" quantity:"<< quantity<charges <= quantity) itemlist.erase(cur); @@ -471,9 +471,9 @@ void NPC::CheckMinMaxLevel(Mob *them) if(!(*cur)) return; - if(themlevel < (*cur)->minlevel || themlevel > (*cur)->maxlevel) + if(themlevel < (*cur)->min_level || themlevel > (*cur)->max_level) { - material = Inventory::CalcMaterialFromSlot((*cur)->equipSlot); + material = Inventory::CalcMaterialFromSlot((*cur)->equip_slot); if(material != 0xFF) SendWearChange(material); @@ -508,15 +508,15 @@ void NPC::QueryLoot(Client* to) { if (item) if (to->GetClientVersion() >= EQClientRoF) { - to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(*cur)->minlevel, (*cur)->maxlevel, (int) item->ID,0x12, item->ID, item->Name, 0x12); + to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12); } else if (to->GetClientVersion() >= EQClientSoF) { - to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X00000000000000000000000000000000000000000000%s%c",(*cur)->minlevel, (*cur)->maxlevel, (int) item->ID,0x12, item->ID, item->Name, 0x12); + to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X00000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12); } else { - to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X000000000000000000000000000000000000000%s%c",(*cur)->minlevel, (*cur)->maxlevel, (int) item->ID,0x12, item->ID, item->Name, 0x12); + to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12); } else LogFile->write(EQEMuLog::Error, "Database error, invalid item"); diff --git a/zone/perl_player_corpse.cpp b/zone/perl_player_corpse.cpp index 366299ea2..af5c79f16 100644 --- a/zone/perl_player_corpse.cpp +++ b/zone/perl_player_corpse.cpp @@ -780,7 +780,7 @@ XS(XS_Corpse_IsRezzed) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->Rezzed(); + RETVAL = THIS->IsRezzed(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index dc9d6d8f6..e014c01cd 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1744,7 +1744,7 @@ bool QuestManager::summonburriedplayercorpse(uint32 char_id, float dest_x, float bool Result = false; if(char_id > 0) { - Corpse* PlayerCorpse = database.SummonBurriedPlayerCorpse(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); + Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); if(PlayerCorpse) { Result = true; } @@ -1767,7 +1767,7 @@ uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) { uint32 Result = 0; if(char_id > 0) { - Result = database.GetPlayerBurriedCorpseCount(char_id); + Result = database.GetCharacterBuriedCorpseCount(char_id); } return Result; } @@ -1781,7 +1781,7 @@ bool QuestManager::buryplayercorpse(uint32 char_id) uint32 PlayerCorpse = database.GetFirstCorpseID(char_id); if(PlayerCorpse > 0) { - database.BuryPlayerCorpse(PlayerCorpse); + database.BuryCharacterCorpse(PlayerCorpse); Corpse* corpse = entity_list.GetCorpseByDBID(PlayerCorpse); if(corpse) { diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 25cbb8ccf..8d8562157 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -736,8 +736,6 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in //clear out old stuff.. spawn_conditions.clear(); - - std::string query = StringFormat("SELECT id, onchange, value " "FROM spawn_conditions " "WHERE zone = '%s'", zone_name); diff --git a/zone/spells.cpp b/zone/spells.cpp index 06c28adaa..69ded563c 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3806,9 +3806,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r void Corpse::CastRezz(uint16 spellid, Mob* Caster) { - _log(SPELLS__REZ, "Corpse::CastRezz spellid %i, Rezzed() is %i, rezzexp is %i", spellid,Rezzed(),rezzexp); + _log(SPELLS__REZ, "Corpse::CastRezz spellid %i, Rezzed() is %i, rezzexp is %i", spellid,IsRezzed(),rezzexp); - if(Rezzed()){ + if(IsRezzed()){ if(Caster && Caster->IsClient()) Caster->Message(13,"This character has already been resurrected."); @@ -3838,7 +3838,7 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster) rezz->unknown020 = 0x00000000; rezz->unknown088 = 0x00000000; // We send this to world, because it needs to go to the player who may not be in this zone. - worldserver.RezzPlayer(outapp, rezzexp, dbid, OP_RezzRequest); + worldserver.RezzPlayer(outapp, rezzexp, corpse_db_id, OP_RezzRequest); _pkt(SPELLS__REZ, outapp); safe_delete(outapp); } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index eb717f89a..bae01e70f 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -704,7 +704,7 @@ void WorldServer::Process() { _log(SPELLS__REZ, "Found corpse. Marking corpse as rezzed."); // I don't know why Rezzed is not set to true in CompleteRezz(). - corpse->Rezzed(true); + corpse->IsRezzed(true); corpse->CompleteRezz(); } } @@ -1382,7 +1382,7 @@ void WorldServer::Process() { case ServerOP_SpawnPlayerCorpse: { SpawnPlayerCorpse_Struct* s = (SpawnPlayerCorpse_Struct*)pack->pBuffer; - Corpse* NewCorpse = database.LoadPlayerCorpse(s->player_corpse_id); + Corpse* NewCorpse = database.LoadCharacterCorpse(s->player_corpse_id); if(NewCorpse) NewCorpse->Spawn(); else diff --git a/zone/zone.cpp b/zone/zone.cpp index 521684a0d..ecf10bcb5 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -917,7 +917,7 @@ bool Zone::Init(bool iStaticZone) { } LogFile->write(EQEMuLog::Status, "Loading player corpses..."); - if (!database.LoadPlayerCorpses(zoneid, instanceid)) { + if (!database.LoadCharacterCorpses(zoneid, instanceid)) { LogFile->write(EQEMuLog::Error, "Loading player corpses failed."); return false; } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 3599a3ff0..11d76e4af 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -7,6 +7,7 @@ #include "../common/rulesys.h" #include "../common/rdtsc.h" #include "zone.h" +#include "corpse.h" #include "client.h" #include "merc.h" #include "groups.h" @@ -1236,7 +1237,6 @@ bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, u if (!results.RowsAffected()) { LogFile->write(EQEMuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str()); } - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterBindPoint", query); return true; } @@ -1247,14 +1247,12 @@ bool ZoneDatabase::SaveCharacterMaterialColor(uint32 character_id, uint32 slot_i std::string query = StringFormat("REPLACE INTO `character_material` (id, slot, red, green, blue, color, use_tint) VALUES (%u, %u, %u, %u, %u, %u, 255)", character_id, slot_id, red, green, blue, color); auto results = QueryDatabase(query); LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterMaterialColor for character ID: %i, slot_id: %u color: %u done", character_id, slot_id, color); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterMaterialColor", query); return true; } bool ZoneDatabase::SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value){ std::string query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, skill_id, value); auto results = QueryDatabase(query); LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterSkill for character ID: %i, skill_id:%u value:%u done", character_id, skill_id, value); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterSkill", query); return true; } @@ -1262,7 +1260,6 @@ bool ZoneDatabase::SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 std::string query = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, slot_id, disc_id); auto results = QueryDatabase(query); LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u done", character_id, slot_id, disc_id); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterDisc", query); return true; } @@ -1285,7 +1282,6 @@ bool ZoneDatabase::SaveCharacterBandolier(uint32 character_id, uint8 bandolier_i DoEscapeString(bandolier_name_esc, bandolier_name, strlen(bandolier_name)); std::string query = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%u, %u, %u, %u, %u,'%s')", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name_esc); auto results = QueryDatabase(query); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterBandolier", query); LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterBandolier for character ID: %i, bandolier_id: %u, bandolier_slot: %u item_id: %u, icon:%u band_name:%s done", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name); if (!results.RowsAffected()){ std::cout << "ERROR Bandolier Save: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; } return true; @@ -1294,7 +1290,6 @@ bool ZoneDatabase::SaveCharacterBandolier(uint32 character_id, uint8 bandolier_i bool ZoneDatabase::SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon) { std::string query = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%u, %u, %u, %u)", character_id, potion_id, item_id, icon); auto results = QueryDatabase(query); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterPotionBelt", query); if (!results.RowsAffected()){ std::cout << "ERROR Potionbelt Save: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; } return true; } @@ -1311,7 +1306,6 @@ bool ZoneDatabase::SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_ } } auto results = QueryDatabase(query); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterLeadershipAA", query); return true; } @@ -1603,7 +1597,6 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla m_epp->expended_aa ); auto results = database.QueryDatabase(query); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase:SaveCharacterData", query); LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC); return true; } @@ -1645,7 +1638,6 @@ bool ZoneDatabase::SaveCharacterCurrency(uint32 character_id, PlayerProfile_Stru pp->currentEbonCrystals, pp->careerEbonCrystals); auto results = database.QueryDatabase(query); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterCurrency", query); LogFile->write(EQEMuLog::Debug, "Saving Currency for character ID: %i, done", character_id); return true; } @@ -1655,7 +1647,6 @@ bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 cur " VALUES (%u, %u, %u)", character_id, aa_id, current_level); auto results = QueryDatabase(rquery); - ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterAA", rquery); LogFile->write(EQEMuLog::Debug, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level); return true; } @@ -3328,3 +3319,667 @@ bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::listlocked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color, + db_id + ); + auto results = QueryDatabase(query); + + return db_id; +} + +void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) { + std::string query = StringFormat("UPDATE `character_corpses` SET `is_rezzed` = 1 WHERE `id` = %i", db_id); + auto results = QueryDatabase(query); +} + +uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading) { + /* Dump Basic Corpse Data */ + std::string query = StringFormat("INSERT INTO `character_corpses` SET \n" + "`charname` = '%s',\n" + "`zone_id` = %u,\n" + "`instance_id` = %u,\n" + "`charid` = %d,\n" + "`x` = %1.1f,\n" + "`y` = %1.1f,\n" + "`z` = %1.1f,\n" + "`heading` = %1.1f,\n" + "`time_of_death` = NOW(),\n" + "`is_buried` = 0," + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`drakkin_heritage` = %u,\n" + "`drakkin_tattoo` = %u,\n" + "`drakkin_details` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n", + EscapeString(charname).c_str(), + zoneid, + instanceid, + charid, + x, + y, + z, + heading, + dbpc->locked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color + ); + auto results = QueryDatabase(query); + uint32 last_insert_id = results.LastInsertedID(); + + /* Dump Items from Inventory */ + uint8 first_entry = 0; + for (unsigned int i = 0; i < dbpc->itemcount; i++) { + if (first_entry != 1){ + query = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + last_insert_id, + dbpc->items[i].equip_slot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug_1, + dbpc->items[i].aug_2, + dbpc->items[i].aug_3, + dbpc->items[i].aug_4, + dbpc->items[i].aug_5 + ); + first_entry = 1; + } + else{ + query = query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + last_insert_id, + dbpc->items[i].equip_slot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug_1, + dbpc->items[i].aug_2, + dbpc->items[i].aug_3, + dbpc->items[i].aug_4, + dbpc->items[i].aug_5 + ); + } + } + auto sc_results = QueryDatabase(query); + return last_insert_id; +} + +uint32 ZoneDatabase::GetCharacterBuriedCorpseCount(uint32 char_id) { + std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 1", char_id); + auto results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + return atoi(row[0]); + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseCount(uint32 char_id) { + std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u'", char_id); + auto results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + return atoi(row[0]); + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) { + std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u'", char_id); + auto results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + for (int i = 0; i < corpse; i++) { + return atoll(row[0]); + } + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseItemCount(uint32 corpse_id){ + std::string query = StringFormat("SELECT COUNT(*) FROM character_corpse_items WHERE `corpse_id` = %u", + corpse_id + ); + auto results = QueryDatabase(query); + auto row = results.begin(); + if (results.Success() && results.RowsAffected() != 0){ + return atoi(row[0]); + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid) { + Corpse* tmp = LoadCharacterCorpse(corpse_id); + uint32 itemid = 0; + + if (tmp) { + itemid = tmp->GetWornItem(slotid); + tmp->DepopCorpse(); + } + return itemid; +} + +bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs){ + std::string query = StringFormat( + "SELECT \n" + "is_locked, \n" + "exp, \n" + "size, \n" + "`level`, \n" + "race, \n" + "gender, \n" + "class, \n" + "deity, \n" + "texture, \n" + "helm_texture, \n" + "copper, \n" + "silver, \n" + "gold, \n" + "platinum, \n" + "hair_color, \n" + "beard_color, \n" + "eye_color_1, \n" + "eye_color_2, \n" + "hair_style, \n" + "face, \n" + "beard, \n" + "drakkin_heritage,\n" + "drakkin_tattoo, \n" + "drakkin_details, \n" + "wc_1, \n" + "wc_2, \n" + "wc_3, \n" + "wc_4, \n" + "wc_5, \n" + "wc_6, \n" + "wc_7, \n" + "wc_8, \n" + "wc_9 \n" + "FROM \n" + "character_corpses\n" + "WHERE `id` = %u LIMIT 1\n", + corpse_id + ); + auto results = QueryDatabase(query); + uint16 i = 0; + for (auto row = results.begin(); row != results.end(); ++row) { + pcs->locked = atoi(row[i++]); // is_locked, + pcs->exp = atoll(row[i++]); // exp, + pcs->size = atoi(row[i++]); // size, + pcs->level = atoi(row[i++]); // `level`, + pcs->race = atoi(row[i++]); // race, + pcs->gender = atoi(row[i++]); // gender, + pcs->class_ = atoi(row[i++]); // class, + pcs->deity = atoi(row[i++]); // deity, + pcs->texture = atoi(row[i++]); // texture, + pcs->helmtexture = atoi(row[i++]); // helm_texture, + pcs->copper = atoll(row[i++]); // copper, + pcs->silver = atoll(row[i++]); // silver, + pcs->gold = atoll(row[i++]); // gold, + pcs->plat = atoll(row[i++]); // platinum, + pcs->haircolor = atoi(row[i++]); // hair_color, + pcs->beardcolor = atoi(row[i++]); // beard_color, + pcs->eyecolor1 = atoi(row[i++]); // eye_color_1, + pcs->eyecolor2 = atoi(row[i++]); // eye_color_2, + pcs->hairstyle = atoi(row[i++]); // hair_style, + pcs->face = atoi(row[i++]); // face, + pcs->beard = atoi(row[i++]); // beard, + pcs->drakkin_heritage = atoll(row[i++]); // drakkin_heritage, + pcs->drakkin_tattoo = atoll(row[i++]); // drakkin_tattoo, + pcs->drakkin_details = atoll(row[i++]); // drakkin_details, + pcs->item_tint[0].color = atoll(row[i++]); // wc_1, + pcs->item_tint[1].color = atoll(row[i++]); // wc_2, + pcs->item_tint[2].color = atoll(row[i++]); // wc_3, + pcs->item_tint[3].color = atoll(row[i++]); // wc_4, + pcs->item_tint[4].color = atoll(row[i++]); // wc_5, + pcs->item_tint[5].color = atoll(row[i++]); // wc_6, + pcs->item_tint[6].color = atoll(row[i++]); // wc_7, + pcs->item_tint[7].color = atoll(row[i++]); // wc_8, + pcs->item_tint[8].color = atoll(row[i++]); // wc_9 + } + query = StringFormat( + "SELECT \n" + "equip_slot, \n" + "item_id, \n" + "charges, \n" + "aug_1, \n" + "aug_2, \n" + "aug_3, \n" + "aug_4, \n" + "aug_5, \n" + "attuned \n" + "FROM \n" + "character_corpse_items \n" + "WHERE `corpse_id` = %u\n" + // "ORDER BY `equip_slot`" + , + corpse_id + ); + results = QueryDatabase(query); + + i = 0; + pcs->itemcount = results.RowCount(); + uint16 r = 0; + for (auto row = results.begin(); row != results.end(); ++row) { + memset(&pcs->items[i], 0, sizeof (player_lootitem::ServerLootItem_Struct)); + pcs->items[i].equip_slot = atoi(row[r++]); // equip_slot, + pcs->items[i].item_id = atoll(row[r++]); // item_id, + pcs->items[i].charges = atoi(row[r++]); // charges, + pcs->items[i].aug_1 = atoi(row[r++]); // aug_1, + pcs->items[i].aug_2 = atoi(row[r++]); // aug_2, + pcs->items[i].aug_3 = atoi(row[r++]); // aug_3, + pcs->items[i].aug_4 = atoi(row[r++]); // aug_4, + pcs->items[i].aug_5 = atoi(row[r++]); // aug_5, + r = 0; + i++; + } + + return true; +} + +Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, float dest_x, float dest_y, float dest_z, float dest_heading) { + Corpse* NewCorpse = 0; + std::string query = StringFormat( + "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 1 ORDER BY `time_of_death` LIMIT 1", + char_id + ); + auto results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + NewCorpse = Corpse::LoadFromDBData( + atoll(row[0]), // uint32 in_dbid + char_id, // uint32 in_charid + row[1], // char* in_charname + dest_x, // float in_x + dest_y, // float in_y + dest_z, // float in_z + dest_heading, // float in_heading + row[2], // char* time_of_death + atoi(row[3]) == 1, // bool rezzed + false // bool was_at_graveyard + ); + if (NewCorpse) { + entity_list.AddCorpse(NewCorpse); + NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + NewCorpse->Spawn(); + if (!UnburyCharacterCorpse(NewCorpse->GetDBID(), dest_zone_id, dest_instance_id, dest_x, dest_y, dest_z, dest_heading)) + LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); + } + } + + return NewCorpse; +} + +bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, float dest_x, float dest_y, float dest_z, float dest_heading) { + Corpse* NewCorpse = 0; + int CorpseCount = 0; + + std::string query = StringFormat( + "UPDATE character_corpses SET zone_id = %i, instance_id = %i, x = %f, y = %f, z = %f, heading = %f, is_buried = 0, was_at_graveyard = 0 WHERE charid = %i", + dest_zone_id, dest_instance_id, dest_x, dest_y, dest_z, dest_heading, char_id + ); + auto results = QueryDatabase(query); + + query = StringFormat( + "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u'" + "ORDER BY time_of_death", + char_id + ); + results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + NewCorpse = Corpse::LoadFromDBData( + atoll(row[0]), + char_id, + row[1], + dest_x, + dest_y, + dest_z, + dest_heading, + row[2], + atoi(row[3]) == 1, + false); + if (NewCorpse) { + entity_list.AddCorpse(NewCorpse); + NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + NewCorpse->Spawn(); + ++CorpseCount; + } + else{ + LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse for character id %u.", char_id); + } + } + + return (CorpseCount > 0); +} + +bool ZoneDatabase::UnburyCharacterCorpse(uint32 db_id, uint32 new_zone_id, uint16 new_instance_id, float new_x, float new_y, float new_z, float new_heading) { + std::string query = StringFormat( + "UPDATE `character_corpses` SET `is_buried` = 0, `zone_id` = %u, `instance_id` = %u, `x` = %f, `y` = %f, `z` = %f, `heading` = %f, `time_of_death` = Now(), `was_at_graveyard` = 0 WHERE `id` = %u", + new_zone_id, new_instance_id, new_x, new_y, new_z, new_heading, db_id + ); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + return false; +} + +Corpse* ZoneDatabase::LoadCharacterCorpse(uint32 player_corpse_id) { + Corpse* NewCorpse = 0; + std::string query = StringFormat( + "SELECT `id`, `charid`, `charname`, `x`, `y`, `z`, `heading`, `time_of_death`, `is_rezzed`, `was_at_graveyard` FROM `character_corpses` WHERE `id` = '%u' LIMIT 1", + player_corpse_id + ); + auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + NewCorpse = Corpse::LoadFromDBData( + atoll(row[0]), // id uint32 in_dbid + atoll(row[1]), // charid uint32 in_charid + row[2], // char_name + atof(row[3]), // x float in_x + atof(row[4]), // y float in_y + atof(row[5]), // z float in_z + atof(row[6]), // heading float in_heading + row[7], // time_of_death char* time_of_death + atoi(row[8]) == 1, // is_rezzed bool rezzed + atoi(row[9]) // was_at_graveyard bool was_at_graveyard + ); + entity_list.AddCorpse(NewCorpse); + } + return NewCorpse; +} + +bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) { + std::string query; + if (!RuleB(Zone, EnableShadowrest)){ + query = StringFormat("SELECT id, charid, charname, x, y, z, heading, time_of_death, is_rezzed, was_at_graveyard FROM character_corpses WHERE zone_id='%u' AND instance_id='%u'", zone_id, instance_id); + } + else{ + query = StringFormat("SELECT id, charid, charname, x, y, z, heading, time_of_death, is_rezzed, 0 as was_at_graveyard FROM character_corpses WHERE zone_id='%u' AND instance_id='%u' AND is_buried=0", zone_id, instance_id); + } + + auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + // std::cout << row[0] << std::endl; + // std::cout << row[1] << std::endl; + // std::cout << row[2] << std::endl; + // std::cout << row[3] << std::endl; + // std::cout << row[4] << std::endl; + // std::cout << row[5] << std::endl; + // std::cout << row[6] << std::endl; + // std::cout << row[7] << std::endl; + // std::cout << row[8] << std::endl; + // std::cout << row[9] << std::endl; + + entity_list.AddCorpse( + Corpse::LoadFromDBData( + atoll(row[0]), // id uint32 in_dbid + atoll(row[1]), // charid uint32 in_charid + row[2], // char_name + atof(row[3]), // x float in_x + atof(row[4]), // y float in_y + atof(row[5]), // z float in_z + atof(row[6]), // heading float in_heading + row[7], // time_of_death char* time_of_death + atoi(row[8]) == 1, // is_rezzed bool rezzed + atoi(row[9])) + ); + } + + return true; +} + +uint32 ZoneDatabase::GetFirstCorpseID(uint32 char_id) { + std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 0 ORDER BY `time_of_death` LIMIT 1", char_id); + auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + return atoi(row[0]); + } + return 0; +} + +bool ZoneDatabase::ClearCorpseItems(uint32 db_id){ + std::string query = StringFormat("DELETE FROM `character_corpse_items` WHERE `corpse_id` = %u", db_id); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + return false; +} + +bool ZoneDatabase::DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id){ + std::string query = StringFormat("DELETE FROM `character_corpse_items` WHERE `corpse_id` = %u AND equip_slot = %u AND item_id = %u", db_id, equip_slot, item_id); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + return false; +} + +bool ZoneDatabase::BuryCharacterCorpse(uint32 db_id) { + std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1 WHERE `id` = %u", db_id); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + ClearCorpseItems(db_id); + return true; + } + return false; +} + +bool ZoneDatabase::BuryAllCharacterCorpses(uint32 char_id) { + std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = %u", char_id); + auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + BuryCharacterCorpse(atoi(row[0])); + return true; + } + return false; +} + +bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) { + std::string query = StringFormat("DELETE FROM `character_corpses` WHERE `id` = %d", db_id); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + return false; +} diff --git a/zone/zonedb.h b/zone/zonedb.h index db796e481..33554aac3 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -214,7 +214,7 @@ public: ZoneDatabase(const char* host, const char* user, const char* passwd, const char* database,uint32 port); virtual ~ZoneDatabase(); - /* Objects and World Containers */ + /* Objects and World Containers */ void LoadWorldContainer(uint32 parentid, ItemInst* container); void SaveWorldContainer(uint32 zone_id, uint32 parent_id, const ItemInst* container); void DeleteWorldContainer(uint32 parent_id,uint32 zone_id); @@ -223,23 +223,24 @@ public: void DeleteObject(uint32 id); Ground_Spawns* LoadGroundSpawns(uint32 zone_id, int16 version, Ground_Spawns* gs); - /* Traders */ + /* Traders */ void SaveTraderItem(uint32 char_id,uint32 itemid,uint32 uniqueid, int32 charges,uint32 itemcost,uint8 slot); void UpdateTraderItemCharges(int char_id, uint32 ItemInstID, int32 charges); - void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice); - ItemInst* LoadSingleTraderItem(uint32 char_id, int uniqueid); + void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice); void DeleteTraderItem(uint32 char_id); void DeleteTraderItem(uint32 char_id,uint16 slot_id); + + ItemInst* LoadSingleTraderItem(uint32 char_id, int uniqueid); Trader_Struct* LoadTraderItem(uint32 char_id); TraderCharges_Struct* LoadTraderItemWithCharges(uint32 char_id); - /* Buyer/Barter */ + /* Buyer/Barter */ void AddBuyLine(uint32 CharID, uint32 BuySlot, uint32 ItemID, const char *ItemName, uint32 Quantity, uint32 Price); void RemoveBuyLine(uint32 CharID, uint32 BuySlot); void DeleteBuyLines(uint32 CharID); void UpdateBuyLine(uint32 CharID, uint32 BuySlot, uint32 Quantity); - /* General Character Related Stuff */ + /* General Character Related Stuff */ bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs); uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs); @@ -249,7 +250,7 @@ public: void SavePetInfo(Client *c); void RemoveTempFactions(Client *c); - /* Character Data Loaders */ + /* Character Data Loaders */ bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list); bool LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp); bool LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp); @@ -265,14 +266,14 @@ public: bool LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp); bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); - /* Character Data Saves */ + /* Character Data Saves */ bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home); bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level); bool SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); bool SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color); + bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color); bool SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value); bool SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value); bool SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id); @@ -281,120 +282,125 @@ public: bool SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon); bool SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); - /* Character Data Deletes */ + /* Character Data Deletes */ bool DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); bool DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool DeleteCharacterDisc(uint32 character_id, uint32 slot_id); + bool DeleteCharacterDisc(uint32 character_id, uint32 slot_id); bool DeleteCharacterBandolier(uint32 character_id, uint32 band_id); bool DeleteCharacterLeadershipAAs(uint32 character_id); bool DeleteCharacterAAs(uint32 character_id); bool DeleteCharacterDye(uint32 character_id); - /* Character Inventory */ + /* Character Inventory */ bool NoRentExpired(const char* name); - /* Corpses */ - bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); - uint32 CreatePlayerCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading); - bool CreatePlayerCorpseBackup(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading); - uint32 UpdatePlayerCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading, bool rezzed = false); - void MarkCorpseAsRezzed(uint32 dbid); - bool BuryPlayerCorpse(uint32 dbid); - bool BuryAllPlayerCorpses(uint32 charid); - bool DeletePlayerCorpse(uint32 dbid); - uint32 GetPlayerBurriedCorpseCount(uint32 char_id); - Corpse* SummonBurriedPlayerCorpse(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - bool SummonAllPlayerCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - Corpse* LoadPlayerCorpse(uint32 player_corpse_id); - bool UnburyPlayerCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, float new_x, float new_y, float new_z, float new_heading); - bool LoadPlayerCorpses(uint32 iZoneID, uint16 iInstanceID); - uint32 GraveyardPlayerCorpse(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading); - uint32 NewGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading); - uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id); - bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id); - uint32 GetFirstCorpseID(uint32 char_id); - uint32 GetPlayerCorpseCount(uint32 char_id); - uint32 GetPlayerCorpseID(uint32 char_id, uint8 corpse); - uint32 GetPlayerCorpseItemAt(uint32 corpse_id, uint16 slotid); - uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type); + /* Corpses */ + bool ClearCorpseItems(uint32 db_id); + bool DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id); + uint32 GetCharacterCorpseItemCount(uint32 corpse_id); + bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs); + Corpse* LoadCharacterCorpse(uint32 player_corpse_id); + Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); + void MarkCorpseAsRezzed(uint32 dbid); + bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); + bool BuryCharacterCorpse(uint32 dbid); + bool BuryAllCharacterCorpses(uint32 charid); + bool DeleteCharacterCorpse(uint32 dbid); + bool SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); + bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); + bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, float new_x, float new_y, float new_z, float new_heading); + bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID); + bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id); + uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id); + uint32 GetCharacterBuriedCorpseCount(uint32 char_id); + uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading); + uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading); + uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id); + uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading); + uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading, bool rezzed = false); + uint32 GetFirstCorpseID(uint32 char_id); + uint32 GetCharacterCorpseCount(uint32 char_id); + uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse); + uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid); + uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type); - /* Faction */ - bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0); - bool GetFactionData(FactionMods* fd, uint32 class_mod, uint32 race_mod, uint32 deity_mod, int32 faction_id); //needed for factions Dec, 16 2001 - bool GetFactionName(int32 faction_id, char* name, uint32 buflen); // needed for factions Dec, 16 2001 - bool GetFactionIdsForNPC(uint32 nfl_id, std::list *faction_list, int32* primary_faction = 0); // improve faction handling - bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001 - bool LoadFactionData(); + /* Faction */ + bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0); + bool GetFactionData(FactionMods* fd, uint32 class_mod, uint32 race_mod, uint32 deity_mod, int32 faction_id); //needed for factions Dec, 16 2001 + bool GetFactionName(int32 faction_id, char* name, uint32 buflen); // needed for factions Dec, 16 2001 + bool GetFactionIdsForNPC(uint32 nfl_id, std::list *faction_list, int32* primary_faction = 0); // improve faction handling + bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001 + bool LoadFactionData(); - /* AAs */ - bool LoadAAEffects(); - bool LoadAAEffects2(); - bool LoadSwarmSpells(); - SendAA_Struct* GetAASkillVars(uint32 skill_id); - uint8 GetTotalAALevels(uint32 skill_id); - uint32 GetSizeAA(); - uint32 CountAAs(); - void LoadAAs(SendAA_Struct **load); - uint32 CountAAEffects(); - void FillAAEffects(SendAA_Struct* aa_struct); + /* AAs */ + bool LoadAAEffects(); + bool LoadAAEffects2(); + bool LoadSwarmSpells(); + SendAA_Struct*GetAASkillVars(uint32 skill_id); + uint8 GetTotalAALevels(uint32 skill_id); + uint32 GetSizeAA(); + uint32 CountAAs(); + void LoadAAs(SendAA_Struct **load); + uint32 CountAAEffects(); + void FillAAEffects(SendAA_Struct* aa_struct); - /* Zone related */ - bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename); - bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd); - bool LoadStaticZonePoints(LinkedList* zone_point_list,const char* zonename, uint32 version); - bool UpdateZoneSafeCoords(const char* zonename, float x, float y, float z); - uint8 GetUseCFGSafeCoords(); - int getZoneShutDownDelay(uint32 zoneID, uint32 version); + /* Zone related */ + bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename); + bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd); + bool LoadStaticZonePoints(LinkedList* zone_point_list,const char* zonename, uint32 version); + bool UpdateZoneSafeCoords(const char* zonename, float x, float y, float z); + uint8 GetUseCFGSafeCoords(); + int getZoneShutDownDelay(uint32 zoneID, uint32 version); - /* Spawns and Spawn Points */ - bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list); - bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); - bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); - Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); - bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); - void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft); - uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); - void UpdateSpawn2Status(uint32 id, uint8 new_status); + /* Spawns and Spawn Points */ + bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list); + bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); + bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); + Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); + bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); + void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft); + uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); + void UpdateSpawn2Status(uint32 id, uint8 new_status); - /* Grids/Paths */ - uint32 GetFreeGrid(uint16 zoneid); - void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too,uint16 zoneid); - void DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num,uint16 zoneid); -// uint32 AddWP(Client *c, uint32 sg2, uint16 grid_num, uint8 wp_num, float xpos, float ypos, float zpos, uint32 pause, float xpos1, float ypos1, float zpos1, int type1, int type2,uint16 zoneid); - void AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading); - uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading); - void ModifyGrid(Client *c, bool remove, uint32 id, uint8 type = 0, uint8 type2 = 0,uint16 zoneid = 0); - void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, float xpos, float ypos, float zpos, uint32 script=0,uint16 zoneid =0); - uint8 GetGridType(uint32 grid,uint32 zoneid); - uint8 GetGridType2(uint32 grid, uint16 zoneid); - bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp); - void AssignGrid(Client *client, float x, float y, uint32 id); - int GetHighestGrid(uint32 zoneid); - int GetHighestWaypoint(uint32 zoneid, uint32 gridid); + /* Grids/Paths */ + uint32 GetFreeGrid(uint16 zoneid); + void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too, uint16 zoneid); + void DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uint16 zoneid); + void AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading); + uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading); + void ModifyGrid(Client *c, bool remove, uint32 id, uint8 type = 0, uint8 type2 = 0, uint16 zoneid = 0); + void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, float xpos, float ypos, float zpos, uint32 script = 0, uint16 zoneid = 0); + uint8 GetGridType(uint32 grid, uint32 zoneid); + uint8 GetGridType2(uint32 grid, uint16 zoneid); + bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp); + void AssignGrid(Client *client, float x, float y, uint32 id); + int GetHighestGrid(uint32 zoneid); + int GetHighestWaypoint(uint32 zoneid, uint32 gridid); - /* NPCs */ - const NPCType* GetNPCType(uint32 id); - uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete - uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra); - uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime); - uint32 DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn); - uint32 DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn); - uint32 AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); - uint32 AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); - uint32 UpdateNPCTypeAppearance(Client *client, NPC* spawn); - bool SetSpecialAttkFlag(uint8 id, const char* flag); - bool GetPetEntry(const char *pet_type, PetRecord *into); - bool GetPoweredPetEntry(const char *pet_type, int16 petpower, PetRecord *into); - bool GetBasePetItems(int32 equipmentset, uint32 *items); - void AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat); - void AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop); - uint32 GetMaxNPCSpellsID(); - uint32 GetMaxNPCSpellsEffectsID(); - DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID); - DBnpcspellseffects_Struct* GetNPCSpellsEffects(uint32 iDBSpellsEffectsID); + /* NPCs */ + + uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete + uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra); + uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime); + uint32 DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn); + uint32 DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn); + uint32 AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); + uint32 AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); + uint32 UpdateNPCTypeAppearance(Client *client, NPC* spawn); + bool SetSpecialAttkFlag(uint8 id, const char* flag); + bool GetPetEntry(const char *pet_type, PetRecord *into); + bool GetPoweredPetEntry(const char *pet_type, int16 petpower, PetRecord *into); + bool GetBasePetItems(int32 equipmentset, uint32 *items); + void AddLootTableToNPC(NPC* npc, uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat); + void AddLootDropToNPC(NPC* npc, uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop); + uint32 GetMaxNPCSpellsID(); + uint32 GetMaxNPCSpellsEffectsID(); - /* Mercs */ + DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID); + DBnpcspellseffects_Struct* GetNPCSpellsEffects(uint32 iDBSpellsEffectsID); + const NPCType* GetNPCType(uint32 id); + + /* Mercs */ const NPCType* GetMercType(uint32 id, uint16 raceid, uint32 clientlevel); void LoadMercEquipment(Merc *merc); void SaveMercBuffs(Merc *merc); @@ -403,10 +409,8 @@ public: bool LoadCurrentMerc(Client *c); bool SaveMerc(Merc *merc); bool DeleteMerc(uint32 merc_id); - //void LoadMercTypesForMercMerchant(NPC *merchant); - //void LoadMercsForMercMerchant(NPC *merchant); - /* Petitions */ + /* Petitions */ void UpdateBug(BugStruct* bug); void UpdateBug(PetitionBug_Struct* bug); void DeletePetitionFromDB(Petition* wpet); @@ -414,23 +418,23 @@ public: void InsertPetitionToDB(Petition* wpet); void RefreshPetitionsFromDB(); - /* Merchants */ + /* Merchants */ void SaveMerchantTemp(uint32 npcid, uint32 slot, uint32 item, uint32 charges); void DeleteMerchantTemp(uint32 npcid, uint32 slot); - /* Tradeskills */ + /* Tradeskills */ bool GetTradeRecipe(const ItemInst* container, uint8 c_type, uint32 some_id, uint32 char_id, DBTradeskillRecipe_Struct *spec); bool GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id, uint32 char_id, DBTradeskillRecipe_Struct *spec); uint32 GetZoneForage(uint32 ZoneID, uint8 skill); /* for foraging */ uint32 GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id, uint8 &npc_chance); void UpdateRecipeMadecount(uint32 recipe_id, uint32 char_id, uint32 madecount); - bool EnableRecipe(uint32 recipe_id); - bool DisableRecipe(uint32 recipe_id); + bool EnableRecipe(uint32 recipe_id); + bool DisableRecipe(uint32 recipe_id); - /* Tribute */ + /* Tribute */ bool LoadTributes(); - /* Doors */ + /* Doors */ bool DoorIsOpen(uint8 door_id,const char* zone_name); void SetDoorPlace(uint8 value,uint8 door_id,const char* zone_name); bool LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version); @@ -441,34 +445,34 @@ public: int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version); int32 GetDoorsCountPlusOne(const char *zone_name, int16 version); int32 GetDoorsDBCountPlusOne(const char *zone_name, int16 version); - void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); + void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); - /* Blocked Spells */ + /* Blocked Spells */ int32 GetBlockedSpellsCount(uint32 zoneid); bool LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked* into, uint32 zoneid); - /* Traps */ + /* Traps */ bool LoadTraps(const char* zonename, int16 version); char* GetTrapMessage(uint32 trap_id); - /* Time */ + /* Time */ uint32 GetZoneTZ(uint32 zoneid, uint32 version); bool SetZoneTZ(uint32 zoneid, uint32 version, uint32 tz); - /* Group */ + /* Group */ void RefreshGroupFromDB(Client *c); uint8 GroupCount(uint32 groupid); - /* Raid */ + /* Raid */ uint8 RaidGroupCount(uint32 raidid, uint32 groupid); - /* Instancing */ + /* Instancing */ void ListAllInstances(Client* c, uint32 charid); - /* QGlobals */ + /* QGlobals */ void QGlobalPurge(); - /* Alternate Currency */ + /* Alternate Currency */ void LoadAltCurrencyValues(uint32 char_id, std::map ¤cy); void UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, uint32 value); diff --git a/zone/zonedump.h b/zone/zonedump.h index fc9b7b152..6d7e67b04 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -35,11 +35,9 @@ spawn2 mediumblob, npcs mediumblob, npc_loot mediumblob, gmspawntype mediumblob, struct NPCType { char name[64]; - char lastname[70]; - + char lastname[70]; int32 cur_hp; - int32 max_hp; - + int32 max_hp; float size; float runspeed; uint8 gender; @@ -91,7 +89,7 @@ struct NPCType uint32 min_dmg; uint32 max_dmg; int16 attack_count; - char special_abilities[512]; + char special_abilities[512]; uint16 d_meele_texture1; uint16 d_meele_texture2; char ammo_idfile[30]; @@ -130,38 +128,30 @@ struct NPCType uint8 probability; }; -/* -Below are the blob structures for saving player corpses to the database --Quagmire - -create table player_corpses (id int(11) unsigned not null auto_increment primary key, charid int(11) unsigned not null, -charname varchar(30) not null, zonename varchar(16)not null, x float not null, y float not null, z float not null, -heading float not null, data blob not null, time timestamp(14), index zonename (zonename)); -*/ - -namespace player_lootitem -{ +namespace player_lootitem { struct ServerLootItem_Struct { - uint32 item_id; - int16 equipSlot; - uint8 charges; - uint16 lootslot; - uint32 aug1; - uint32 aug2; - uint32 aug3; - uint32 aug4; - uint32 aug5; + uint32 item_id; + int16 equip_slot; + uint16 charges; + uint16 lootslot; + uint32 aug_1; + uint32 aug_2; + uint32 aug_3; + uint32 aug_4; + uint32 aug_5; + uint8 min_level; // + uint8 max_level; // }; } -struct DBPlayerCorpse_Struct { +struct PlayerCorpse_Struct { uint32 crc; bool locked; uint32 itemcount; uint32 exp; float size; uint8 level; - uint8 race; + uint32 race; uint8 gender; uint8 class_; uint8 deity; @@ -183,39 +173,9 @@ struct DBPlayerCorpse_Struct { uint32 drakkin_tattoo; uint32 drakkin_details; player_lootitem::ServerLootItem_Struct items[0]; + //std::list items; }; -namespace classic_db -{ - struct DBPlayerCorpse_Struct { - uint32 crc; - bool locked; - uint32 itemcount; - uint32 exp; - float size; - uint8 level; - uint8 race; - uint8 gender; - uint8 class_; - uint8 deity; - uint8 texture; - uint8 helmtexture; - uint32 copper; - uint32 silver; - uint32 gold; - uint32 plat; - Color_Struct item_tint[9]; - uint8 haircolor; - uint8 beardcolor; - uint8 eyecolor1; - uint8 eyecolor2; - uint8 hairstyle; - uint8 face; - uint8 beard; - player_lootitem::ServerLootItem_Struct items[0]; - }; -} - struct Door { uint32 db_id; uint8 door_id; @@ -228,7 +188,7 @@ struct Door { int incline; uint8 opentype; uint32 guild_id; - uint16 lockpick; + uint16 lock_pick; uint32 keyitem; uint8 nokeyring; uint8 trigger_door;
NameZoneXYZDate" "RezzedBuried
 " @@ -6208,13 +6208,13 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) float CorpseY = atof(row[3]); float CorpseZ = atof(row[4]); - strn0cpy(timeOfDeath, row[5], sizeof(timeOfDeath)); + strn0cpy(time_of_death, row[5], sizeof(time_of_death)); bool corpseRezzed = atoi(row[6]); bool corpseBuried = atoi(row[7]); popupText += StringFormat("
%s%s%8.0f%8.0f%8.0f%s%s%s