From 899cf32e6b8d5a586ccb18a709e7c40d1a3e22db Mon Sep 17 00:00:00 2001 From: akkadius Date: Tue, 9 Sep 2014 16:03:24 -0500 Subject: [PATCH] Added some DB logging to catch any potential query errors, this logs to eqemu_query_error_log.txt at the root folder, currently no rule toggling for this Corrected some character name reservation logic Adjusted telnet console so it does not throw 'Command Unknown' when simply hitting enter key Adjusted System MSG for worldshutdown to use minutes instead of seconds Added warning for when Shared platinum is disabled at the rule level for players to NOT put platinum in the shared bank when they insert platinum in the shared platinum slot Changed a place in the code where disciplines were trained, someone had uint16 allocated to CharacterID and this was causing issues for characters with large ID's in the database Added a fix for bind points getting overwritten with invalid zone data, setting everything to 0,0,0,0 - Since I've added this change I've had no issues for players Fixed some spell book swap logic in the code, removed swap function. Fixed issue with guild ranks not loading properly Commented out some of the non-working tell-que code Took out some of the auto increment settings in the auto database conversion that don't affect anything anyways Added some additional escape string sequences for queries that needed them Added ThrowDBError logging to catch any potential query issues with saves or load functions --- common/database.cpp | 78 ++++++++++++++++++++++++++--------------- world/client.cpp | 2 +- world/console.cpp | 5 ++- world/zonelist.cpp | 4 +-- world/zoneserver.cpp | 50 +++++++++++++------------- zone/client_packet.cpp | 29 ++++++++------- zone/client_process.cpp | 7 +++- zone/command.cpp | 4 +-- zone/questmgr.cpp | 8 ++--- zone/zonedb.cpp | 42 ++++++++++++---------- zone/zonedb.h | 1 - 11 files changed, 130 insertions(+), 100 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 287e65a9d..e6983b368 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -18,6 +18,10 @@ #include "../common/debug.h" #include "../common/rulesys.h" #include +#include + +using namespace std; + #include #include #include @@ -306,11 +310,21 @@ bool Database::SetAccountStatus(const char* name, int16 status) { bool Database::ReserveName(uint32 account_id, char* name) { std::string query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name); auto results = QueryDatabase(query); ThrowDBError(results.ErrorMessage(), "Database::ReserveName", query); + if (!results.Success() || results.ErrorMessage() != ""){ return false; } 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; return true; } + if (ErrorMessage != ""){ + std::cout << "\nERROR " << query_title << ": " << ErrorMessage << "\n\n" << query << "\n" << std::endl; + + /* Write to file temporarily */ + std::ofstream log("eqemu_query_error_log.txt", std::ios_base::app | std::ios_base::out); + log << "\nERROR " << query_title << ": " << ErrorMessage << "\n\n" << query << "\n"; + log.close(); + + return true; + } return false; } @@ -987,7 +1001,7 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_currency` doesn't exist... creating..."); rquery = StringFormat( " CREATE TABLE `character_currency` ( " - " `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " " `platinum` int(11) UNSIGNED NOT NULL DEFAULT 0, " " `gold` int(11) UNSIGNED NOT NULL DEFAULT 0, " " `silver` int(11) UNSIGNED NOT NULL DEFAULT 0, " @@ -1006,7 +1020,7 @@ bool Database::CheckDatabaseConversions() { " `career_ebon_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " " PRIMARY KEY (`id`), " " KEY `id` (`id`) " - " ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; " + " ) ENGINE=InnoDB DEFAULT CHARSET=latin1; " ); QueryDatabase(rquery); printf(" done...\n"); @@ -1018,13 +1032,13 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_alternate_abilities` doesn't exist... creating..."); rquery = StringFormat( " CREATE TABLE `character_alternate_abilities` ( " - " `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " " `slot` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " " `aa_id` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " " `aa_value` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " " PRIMARY KEY(`id`,`slot`), " " KEY `id` (`id`) " - " ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " + " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " ); QueryDatabase(rquery); printf(" done...\n"); @@ -1046,7 +1060,7 @@ bool Database::CheckDatabaseConversions() { "`heading` float NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`, `is_home`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1063,7 +1077,7 @@ bool Database::CheckDatabaseConversions() { "`value` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`, `lang_id`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1080,7 +1094,7 @@ bool Database::CheckDatabaseConversions() { "`value` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`, `skill_id`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1097,7 +1111,7 @@ bool Database::CheckDatabaseConversions() { "`spell_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`, `slot_id`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1109,12 +1123,12 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_memmed_spells` doesn't exist... creating..."); rquery = StringFormat( "CREATE TABLE `character_memmed_spells` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`id` int(11) UNSIGNED NOT NULL DEFAULT 0, " "`slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " "`spell_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`, `slot_id`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1126,12 +1140,12 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_disciplines` doesn't exist... creating..."); rquery = StringFormat( " CREATE TABLE `character_disciplines` ( " - " `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " " `slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " " `disc_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " " PRIMARY KEY(`id`, `slot_id`), " " KEY `id` (`id`) " - " ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " + " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " ); QueryDatabase(rquery); printf(" done...\n"); @@ -1141,7 +1155,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'," @@ -1164,11 +1178,11 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_tribute` doesn't exist... creating..."); rquery = StringFormat( "CREATE TABLE `character_tribute` ( " - "`id` int(11) unsigned NOT NULL AUTO_INCREMENT, " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " "`tier` tinyint(11) unsigned NOT NULL DEFAULT '0', " "`tribute` int(11) UNSIGNED NOT NULL DEFAULT '0', " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1180,7 +1194,7 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_bandolier` doesn't exist... creating..."); rquery = StringFormat( "CREATE TABLE `character_bandolier` ( " - "`id` int(11) unsigned NOT NULL AUTO_INCREMENT, " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " "`bandolier_id` tinyint(11) unsigned NOT NULL DEFAULT '0', " "`bandolier_slot` tinyint(11) unsigned NOT NULL DEFAULT '0', " "`item_id` int(11) UNSIGNED NOT NULL DEFAULT '0', " @@ -1188,7 +1202,7 @@ bool Database::CheckDatabaseConversions() { "`bandolier_name` varchar(32) NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`,`bandolier_id`, `bandolier_slot`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " ); QueryDatabase(rquery); printf(" done...\n"); @@ -1200,13 +1214,13 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_potionbelt` doesn't exist... creating..."); rquery = StringFormat( "CREATE TABLE `character_potionbelt` ( " - "`id` int(11) unsigned NOT NULL AUTO_INCREMENT, " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " "`potion_id` tinyint(11) unsigned NOT NULL DEFAULT '0', " "`item_id` int(11) UNSIGNED NOT NULL DEFAULT '0', " "`icon` int(11) UNSIGNED NOT NULL DEFAULT '0', " "PRIMARY KEY(`id`,`potion_id`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1218,11 +1232,11 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_inspect_messages` doesn't exist... creating..."); rquery = StringFormat( "CREATE TABLE `character_inspect_messages` ( " - "`id` int(11) unsigned NOT NULL AUTO_INCREMENT, " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " "`inspect_message` varchar(255) NOT NULL DEFAULT '', " "PRIMARY KEY(`id`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" ); QueryDatabase(rquery); printf(" done...\n"); @@ -1234,12 +1248,12 @@ bool Database::CheckDatabaseConversions() { printf("Table: `character_leadership_abilities` doesn't exist... creating..."); rquery = StringFormat( "CREATE TABLE `character_leadership_abilities` (" - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`id` int(11) UNSIGNED NOT NULL DEFAULT 0, " "`slot` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " "`rank` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " "PRIMARY KEY(`id`,`slot`), " "KEY `id` (`id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " ); QueryDatabase(rquery); printf(" done...\n"); @@ -2650,15 +2664,21 @@ uint32 Database::GetGroupID(const char* name){ /* Is this really getting used properly... A half implementation ? Akkadius */ char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf){ + leaderbuf = ""; std::string query = StringFormat("SELECT `groupid` FROM `group_id` WHERE `name = '%s'", name); auto results = QueryDatabase(query); auto row = results.begin(); uint32 group_id = 0; - if (row[0]){ group_id = atoi(row[0]); } + for (auto row = results.begin(); row != results.end(); ++row) { + if (row[0]){ group_id = atoi(row[0]); } + } - query = StringFormat("SELECT `name` FROM `group_id` WHERE `name` != '%s' AND `groupid` = %u", name, group_id); - results = QueryDatabase(query); - row = results.begin(); - if (row[0]){ strcpy(leaderbuf, row[0]); } + if (group_id > 0){ + query = StringFormat("SELECT `leadername` FROM `group_leader` WHERE `gid` = '%u' AND `groupid` = %u LIMIT 1", group_id); + results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + if (row[0]){ strcpy(leaderbuf, row[0]); } + } + } return leaderbuf; } diff --git a/world/client.cpp b/world/client.cpp index c8fea66c9..e7e999ce5 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -486,7 +486,7 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) { outapp->pBuffer = new uchar[1]; outapp->size = 1; - bool valid; + bool valid = false; if(!database.CheckNameFilter(char_name)) { valid = false; } else if (char_name[0] < 'A' && char_name[0] > 'Z') { valid = false; } /* Name must begin with an upper-case letter. */ else if (database.ReserveName(GetAccountID(), char_name)) { valid = true; } diff --git a/world/console.cpp b/world/console.cpp index d5433067e..6caa9ce86 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -113,7 +113,7 @@ bool Console::SendChannelMessage(const ServerChannelMessage_Struct* scm) { break; } case 7: { - SendMessage(1, "%s tells you, '%s'", scm->from, scm->message); + SendMessage(1, "[%s] tells you, '%s'", scm->from, scm->message); ServerPacket* pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1); memcpy(pack->pBuffer, scm, pack->size); ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*) pack->pBuffer; @@ -847,6 +847,9 @@ void Console::ProcessCommand(const char* command) { zoneserver_list.SendPacket(pack); safe_delete(pack); } + else if (strcasecmp(sep.arg[0], "") == 0){ + /* Hit Enter with no command */ + } else { SendMessage(1, "Command unknown."); } diff --git a/world/zonelist.cpp b/world/zonelist.cpp index fdf9db5cf..c97010aa8 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -87,7 +87,7 @@ void ZSList::Process() { CatchSignal(2); } if(reminder && reminder->Check()){ - SendEmoteMessage(0,0,0,15,":SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i seconds...",shutdowntimer->GetRemainingTime()/1000); + SendEmoteMessage(0,0,0,15,":SYSTEM MSG:World coming down, everyone log out now. World will shut down in %i minutes...", ((shutdowntimer->GetRemainingTime()/1000) / 60)); } LinkedListIterator iterator(list); @@ -718,7 +718,7 @@ void ZSList::GetZoneIDList(std::vector &zones) { void ZSList::WorldShutDown(uint32 time, uint32 interval) { if( time > 0 ) { - SendEmoteMessage(0,0,0,15,":SYSTEM MSG:World coming down in %i seconds, everyone log out before this time.",time); + SendEmoteMessage(0,0,0,15,":SYSTEM MSG:World coming down in %i minutes, everyone log out before this time.", (time / 60)); time *= 1000; interval *= 1000; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 4796104a7..c740ff3bc 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -448,31 +448,31 @@ bool ZoneServer::Process() { else if (cle->Online() == CLE_Status_Zoning) { if (!scm->noreply) { - time_t rawtime; - struct tm * timeinfo; - time ( &rawtime ); - timeinfo = localtime ( &rawtime ); - char *telldate=asctime(timeinfo); - - std::string query = StringFormat("SELECT name FROM `character_data` WHERE name = '%s'",scm->deliverto); - auto results = database.QueryDatabase(query); - if (!results.Success()) - break; - - if (results.RowCount() == 0) { - zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to); - break; - } - - query = StringFormat("INSERT INTO tellque " - "(Date, Receiver, Sender, Message) " - "VALUES('%s', '%s', '%s', '%s')", - telldate, scm->deliverto, scm->from, scm->message); - results = database.QueryDatabase(query); - if (results.Success()) - zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "Your message has been added to the %s's que.", scm->to); - else - zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to); + // time_t rawtime; + // struct tm * timeinfo; + // time ( &rawtime ); + // timeinfo = localtime ( &rawtime ); + // char *telldate=asctime(timeinfo); + // + // std::string query = StringFormat("SELECT name FROM `character_data` WHERE name = '%s'",scm->deliverto); + // auto results = database.QueryDatabase(query); + // if (!results.Success()) + // break; + // + // if (results.RowCount() == 0) { + // zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to); + // break; + // } + // + // query = StringFormat("INSERT INTO tellque " + // "(Date, Receiver, Sender, Message) " + // "VALUES('%s', '%s', '%s', '%s')", + // telldate, scm->deliverto, scm->from, scm->message); + // results = database.QueryDatabase(query); + // if (results.Success()) + // zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "Your message has been added to the %s's que.", scm->to); + // else + // zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to); } // zoneserver_list.SendEmoteMessage(scm->from, 0, 0, 0, "You told %s, '%s is not online at this time'", scm->to, scm->to); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 02bedc17c..6865eadfc 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -571,21 +571,20 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) { results = database.QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { m_pp.lastlogin = time(nullptr); - if (row[4]){ + if (atoi(row[4]) > 0){ guild_id = atoi(row[4]); - if (guildrank) { - if (row[5] != nullptr){ guildrank = atoi(row[5]); } - else{ guildrank = GUILD_RANK_NONE; } - } + if (row[5] != nullptr){ guildrank = atoi(row[5]); } + else{ guildrank = GUILD_RANK_NONE; } } - if (RuleB(Character, SharedBankPlat)) - m_pp.platinum_shared = database.GetSharedPlatinum(database.GetAccountIDByChar(cid)); - + if (LFP){ LFP = atoi(row[0]); } if (LFG){ LFG = atoi(row[1]); } if (firstlogon){ firstlogon = atoi(row[3]); } } + if (RuleB(Character, SharedBankPlat)) + m_pp.platinum_shared = database.GetSharedPlatinum(this->AccountID()); + loaditems = database.GetInventory(cid, &m_inv); /* Load Character Inventory */ database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */ database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */ @@ -622,6 +621,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) { /* If we can maintain intoxication across zones, check for it */ if (!RuleB(Character, MaintainIntoxicationAcrossZones)) m_pp.intoxication = 0; + strcpy(name, m_pp.name); strcpy(lastname, m_pp.last_name); /* If PP is set to weird coordinates */ @@ -751,10 +751,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) { aa_points[id] = aa[a]->value; } - if (SPDAT_RECORDS > 0) - { - for (uint32 z = 0; z 0) { + for (uint32 z = 0; z= (uint32)SPDAT_RECORDS) UnmemSpell(z, false); } @@ -5020,7 +5018,8 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app) m_pp.spell_book[swapspell->from_slot] = m_pp.spell_book[swapspell->to_slot]; m_pp.spell_book[swapspell->to_slot] = swapspelltemp; - database.SaveCharacterSpellSwap(this->CharacterID(), swapspelltemp, swapspell->from_slot, swapspell->to_slot); + database.SaveCharacterSpell(this->CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot); + database.SaveCharacterSpell(this->CharacterID(), swapspelltemp, swapspell->to_slot); QueuePacket(app); return; @@ -9573,7 +9572,6 @@ void Client::CompleteConnect() { entity_list.SendUntargetable(this); - client_data_loaded = true; int x; for (x = 0; x < 8; x++) SendWearChange(x); @@ -9659,7 +9657,8 @@ void Client::CompleteConnect() { alternate_currency_loaded = true; ProcessAlternateCurrencyQueue(); - + /* This needs to be set, this determines whether or not data was loaded properly before a save */ + client_data_loaded = true; CalcItemScale(); DoItemEnterZone(); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index bf4c5694b..544200910 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1547,7 +1547,12 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) if (from_bucket == &m_pp.platinum_shared) amount_to_add = 0 - amount_to_take; - database.SetSharedPlatinum(AccountID(),amount_to_add); + database.SetSharedPlatinum(AccountID(),amount_to_add); + } + } + else{ + if (to_bucket == &m_pp.platinum_shared || from_bucket == &m_pp.platinum_shared){ + this->Message(13, "::: WARNING! ::: SHARED BANK IS DISABLED AND YOUR PLATINUM WILL BE DESTROYED IF YOU PUT IT HERE"); } } } diff --git a/zone/command.cpp b/zone/command.cpp index 189f3daf2..c1e304dd1 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2156,8 +2156,8 @@ void command_worldshutdown(Client *c, const Seperator *sep) uint32 interval=0; if (worldserver.Connected()) { if(sep->IsNumber(1) && sep->IsNumber(2) && ((time=atoi(sep->arg[1]))>0) && ((interval=atoi(sep->arg[2]))>0)) { - worldserver.SendEmoteMessage(0,0,15,":SYSTEM MSG:World coming down in %i seconds, everyone log out before this time.",time); - c->Message(0, "Sending shutdown packet now, World will shutdown in: %i Seconds with an interval of: %i",time,interval); + worldserver.SendEmoteMessage(0,0,15,":SYSTEM MSG:World coming down in %i minutes, everyone log out before this time.", (time / 60 )); + c->Message(0, "Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval); ServerPacket* pack = new ServerPacket(ServerOP_ShutdownAll,sizeof(WorldShutDown_Struct)); WorldShutDown_Struct* wsd = (WorldShutDown_Struct*)pack->pBuffer; wsd->time=time*1000; diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 776376bdf..e86e4d601 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -946,7 +946,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { uint16 count; uint16 curspell; - uint16 Char_ID = initiator->CharacterID(); + uint32 Char_ID = initiator->CharacterID(); bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals); bool SpellGlobalCheckResult = 0; @@ -960,7 +960,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { spells[curspell].skill != 52 && ( !RuleB(Spells, UseCHAScribeHack) || spells[curspell].effectid[EFFECT_COUNT - 1] != 10 ) ) - { + { if(IsDiscipline(curspell)){ //we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) { @@ -974,12 +974,12 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { SpellGlobalCheckResult = initiator->SpellGlobalCheck(curspell, Char_ID); if (SpellGlobalCheckResult) { initiator->GetPP().disciplines.values[r] = curspell; - database.SaveCharacterDisc(Char_ID, r, curspell); + database.SaveCharacterDisc(Char_ID, r, curspell); initiator->SendDisciplineUpdate(); initiator->Message(0, "You have learned a new discipline!"); count++; //success counter } - break; //continue the 1st loop + break; //continue the 1st loop } else { initiator->GetPP().disciplines.values[r] = curspell; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 82b38c44e..d6b59a8c4 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -1050,6 +1050,10 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str "`character_spells` " "WHERE `id` = %u ORDER BY `slot_id`", character_id); auto results = database.QueryDatabase(query); int i = 0; + /* Initialize Spells */ + for (i = 0; i < MAX_PP_SPELLBOOK; i++){ + pp->spell_book[i] = 0; + } for (auto row = results.begin(); row != results.end(); ++row) { i = atoi(row[0]); if (i < MAX_PP_SPELLBOOK){ @@ -1241,7 +1245,7 @@ bool ZoneDatabase::LoadCharacterPotions(uint32 character_id, PlayerProfile_Struc } bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp){ - std::string query = StringFormat("SELECT zone_id, instance_id, x, y, z, heading, is_home FROM character_bind WHERE `id` = %u LIMIT 2", character_id); + std::string query = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %u LIMIT 2", character_id); auto results = database.QueryDatabase(query); int i = 0; for (auto row = results.begin(); row != results.end(); ++row) { i = 0; @@ -1274,29 +1278,34 @@ bool ZoneDatabase::SaveCharacterLanguage(uint32 character_id, uint32 lang_id, ui } bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home){ + if (zone_id <= 0){ return false; } /* Save Home Bind Point */ 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, zone_id, instance_id, x, y, z, heading, is_home); LogFile->write(EQEMuLog::Status, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u x: %f y: %f z: %f heading: %f ishome: %u", character_id, zone_id, instance_id, x, y, z, heading, is_home); auto results = QueryDatabase(query); if (!results.RowsAffected()){ std::cout << "ERROR Bind Home Save: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; } + ThrowDBError(results.ErrorMessage(), "ZoneDatabase::SaveCharacterBindPoint", query); return true; } bool ZoneDatabase::SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color){ - std::string query = StringFormat("REPLACE INTO `character_material` (id, slot, color, use_tint) VALUES (%u, %u, %u, 255)", character_id, slot_id, color); QueryDatabase(query); + std::string query = StringFormat("REPLACE INTO `character_material` (id, slot, color, use_tint) VALUES (%u, %u, %u, 255)", character_id, slot_id, color); auto results = QueryDatabase(query); LogFile->write(EQEMuLog::Status, "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); QueryDatabase(query); + 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::Status, "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; } bool ZoneDatabase::SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id){ - std::string query = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, slot_id, disc_id); QueryDatabase(query); - LogFile->write(EQEMuLog::Status, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u value:%u done", character_id, slot_id, disc_id); + 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::Status, "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; } @@ -1317,6 +1326,7 @@ 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::Status, "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; @@ -1325,6 +1335,7 @@ 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; } @@ -1540,8 +1551,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla ")", character_id, // " id, " account_id, // " account_id, " - pp->name, // " `name`, " - pp->last_name, // " last_name, " + EscapeString(pp->name).c_str(), // " `name`, " + EscapeString(pp->last_name).c_str(), // " last_name, " pp->gender, // " gender, " pp->race, // " race, " pp->class_, // " class, " @@ -1565,8 +1576,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla pp->ability_number, // " ability_number, " pp->ability_time_minutes, // " ability_time_minutes, " pp->ability_time_hours, // " ability_time_hours, " - pp->title, // " title, " - pp->suffix, // " suffix, " + EscapeString(pp->title).c_str(), // " title, " + EscapeString(pp->suffix).c_str(), // " suffix, " pp->exp, // " exp, " pp->points, // " points, " pp->mana, // " mana, " @@ -1633,7 +1644,7 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla m_epp->expended_aa ); auto results = database.QueryDatabase(query); - if (!results.RowsAffected()){ std::cout << "ERROR ZoneDatabase:SaveCharacterData: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; } + ThrowDBError(results.ErrorMessage(), "ZoneDatabase:SaveCharacterData", query); LogFile->write(EQEMuLog::Status, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC); return true; } @@ -1675,6 +1686,7 @@ 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::Status, "Saving Currency for character ID: %i, done", character_id); return true; } @@ -1684,19 +1696,11 @@ 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::Status, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level); return true; } -bool ZoneDatabase::SaveCharacterSpellSwap(uint32 character_id, uint32 spell_id, uint32 from_slot, uint32 to_slot){ - std::string rquery = StringFormat("UPDATE `character_spells` SET `slot_id` = %u WHERE `slot_id` = %u AND `id` = %u", - to_slot, from_slot, character_id); - clock_t t = std::clock(); /* Function timer start */ - auto results = QueryDatabase(rquery); - LogFile->write(EQEMuLog::Status, "ZoneDatabase::SaveCharacterSpellSwap for character ID: %u, from_slot: %u to_slot: %u spell: %u time: %f seconds", character_id, from_slot, to_slot, spell_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC); - return true; -} - bool ZoneDatabase::SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id){ std::string query = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, slot_id, spell_id); QueryDatabase(query); return true; } diff --git a/zone/zonedb.h b/zone/zonedb.h index 0405fb3a9..497beb322 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -269,7 +269,6 @@ public: 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 SaveCharacterSpellSwap(uint32 character_id, uint32 spell_id, uint32 from_slot, uint32 to_slot); 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);