From 22fb22ee5e7bcc7fb063ee419f0752ec85db3b17 Mon Sep 17 00:00:00 2001 From: Splinter Date: Tue, 10 Nov 2009 21:17:01 +0300 Subject: [PATCH 01/14] [8800] Implement item 47499 work. Signed-off-by: VladimirMangos --- sql/mangos.sql | 5 ++++- sql/updates/8800_01_mangos_spell_elixir.sql | 9 +++++++++ sql/updates/Makefile.am | 2 ++ src/game/SpellEffects.cpp | 16 ++++++++++++++++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8800_01_mangos_spell_elixir.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index f2e6a5a5b..246b16e72 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8777_02_mangos_gameobject` bit(1) default NULL + `required_8800_01_mangos_spell_elixir` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -17417,6 +17417,9 @@ INSERT INTO `spell_elixir` VALUES (60346,0x1), (60347,0x2), (62380,0x3), +(67016,0x3), +(67017,0x3), +(67018,0x3), (67019,0x3); diff --git a/sql/updates/8800_01_mangos_spell_elixir.sql b/sql/updates/8800_01_mangos_spell_elixir.sql new file mode 100644 index 000000000..3634c0b85 --- /dev/null +++ b/sql/updates/8800_01_mangos_spell_elixir.sql @@ -0,0 +1,9 @@ +ALTER TABLE db_version CHANGE COLUMN required_8777_02_mangos_gameobject required_8800_01_mangos_spell_elixir bit; + +DELETE FROM `spell_elixir` WHERE `entry` IN (67016,67017,67018); + +/* Flasks added in 3.2.x */ +INSERT INTO `spell_elixir` (`entry`, `mask`) VALUES +(67016,0x3), +(67017,0x3), +(67018,0x3); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index cbb47eae8..6a6263391 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -153,6 +153,7 @@ pkgdata_DATA = \ 8775_03_mangos_gameobject.sql \ 8777_01_mangos_creature.sql \ 8777_02_mangos_gameobject.sql \ + 8800_01_mangos_spell_elixir.sql \ README ## Additional files to include when running 'make dist' @@ -286,4 +287,5 @@ EXTRA_DIST = \ 8775_03_mangos_gameobject.sql \ 8777_01_mangos_creature.sql \ 8777_02_mangos_gameobject.sql \ + 8800_01_mangos_spell_elixir.sql \ README diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 16170daa5..6dd37ae88 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1321,6 +1321,22 @@ void Spell::EffectDummy(uint32 i) return; m_caster->CastSpell(unitTarget,60934,true,NULL); return; + case 67019: // Flask of the North + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + uint32 spell_id; + switch(urand(1, 3)) + { + case 1: spell_id = 67016; break; + case 2: spell_id = 67017; break; + default:spell_id = 67018; break; + } + + m_caster->CastSpell(m_caster, spell_id, true, NULL); + return; + } } break; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 25d6d8913..beb04501a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8799" + #define REVISION_NR "8800" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index f748d660a..004d772b9 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8721_01_characters_guild" - #define REVISION_DB_MANGOS "required_8777_02_mangos_gameobject" + #define REVISION_DB_MANGOS "required_8800_01_mangos_spell_elixir" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From da2cceb9da26282bf541933537f4e08b42d8025e Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Tue, 10 Nov 2009 23:09:32 +0100 Subject: [PATCH 02/14] [8801] Rename accmgr macro to sAccountMgr. Thanks to astriconX for pointing out. --- src/game/AccountMgr.h | 2 +- src/game/AuctionHouseMgr.cpp | 2 +- src/game/Chat.cpp | 2 +- src/game/Level0.cpp | 4 ++-- src/game/Level3.cpp | 22 +++++++++++----------- src/game/World.cpp | 2 +- src/mangosd/CliRunnable.cpp | 8 ++++---- src/shared/revision_nr.h | 2 +- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/game/AccountMgr.h b/src/game/AccountMgr.h index 9bbc358d8..be6cb169b 100644 --- a/src/game/AccountMgr.h +++ b/src/game/AccountMgr.h @@ -55,5 +55,5 @@ class AccountMgr static bool normalizeString(std::string& utf8str); }; -#define accmgr MaNGOS::Singleton::Instance() +#define sAccountMgr MaNGOS::Singleton::Instance() #endif diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index f0c917ecb..83fe25ef3 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -97,7 +97,7 @@ void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction ) else { bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid); - bidder_security = accmgr.GetSecurity(bidder_accId); + bidder_security = sAccountMgr.GetSecurity(bidder_accId); if(bidder_security > SEC_PLAYER ) // not do redundant DB requests { diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 20473b17e..90c883152 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -725,7 +725,7 @@ bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_ac if (target) target_sec = target->GetSecurity(); else if (target_account) - target_sec = accmgr.GetSecurity(target_account); + target_sec = sAccountMgr.GetSecurity(target_account); else return true; // caller must report error for (target==NULL && target_account==0) diff --git a/src/game/Level0.cpp b/src/game/Level0.cpp index 937f1b9cc..687327e01 100644 --- a/src/game/Level0.cpp +++ b/src/game/Level0.cpp @@ -200,14 +200,14 @@ bool ChatHandler::HandleAccountPasswordCommand(const char* args) return false; } - if (!accmgr.CheckPassword (m_session->GetAccountId(), password_old)) + if (!sAccountMgr.CheckPassword (m_session->GetAccountId(), password_old)) { SendSysMessage (LANG_COMMAND_WRONGOLDPASSWORD); SetSentErrorMessage (true); return false; } - AccountOpResult result = accmgr.ChangePassword(m_session->GetAccountId(), password_new); + AccountOpResult result = sAccountMgr.ChangePassword(m_session->GetAccountId(), password_new); switch(result) { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 660e8e78f..55fd52b9e 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -863,7 +863,7 @@ bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args) arg2 = arg1; targetAccountId = targetPlayer->GetSession()->GetAccountId(); - accmgr.GetName(targetAccountId, targetAccountName); + sAccountMgr.GetName(targetAccountId, targetAccountName); } else { @@ -879,7 +879,7 @@ bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args) return false; } - targetAccountId = accmgr.GetId(targetAccountName); + targetAccountId = sAccountMgr.GetId(targetAccountName); if(!targetAccountId) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,targetAccountName.c_str()); @@ -945,7 +945,7 @@ bool ChatHandler::HandleAccountSetPasswordCommand(const char* args) return false; } - uint32 targetAccountId = accmgr.GetId(account_name); + uint32 targetAccountId = sAccountMgr.GetId(account_name); if (!targetAccountId) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); @@ -965,7 +965,7 @@ bool ChatHandler::HandleAccountSetPasswordCommand(const char* args) return false; } - AccountOpResult result = accmgr.ChangePassword(targetAccountId, szPassword1); + AccountOpResult result = sAccountMgr.ChangePassword(targetAccountId, szPassword1); switch(result) { @@ -5027,7 +5027,7 @@ bool ChatHandler::HandleBanInfoAccountCommand(const char* args) return false; } - uint32 accountid = accmgr.GetId(account_name); + uint32 accountid = sAccountMgr.GetId(account_name); if (!accountid) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); @@ -5047,7 +5047,7 @@ bool ChatHandler::HandleBanInfoCharacterCommand(const char* args) uint32 accountid = target ? target->GetSession()->GetAccountId() : sObjectMgr.GetPlayerAccountIdByGUID(target_guid); std::string accountname; - if (!accmgr.GetName(accountid,accountname)) + if (!sAccountMgr.GetName(accountid,accountname)) { PSendSysMessage(LANG_BANINFO_NOCHARACTER); return true; @@ -5206,7 +5206,7 @@ bool ChatHandler::HandleBanListHelper(QueryResult* result) account_name = fields[1].GetCppString(); // "character" case, name need extract from another DB else - accmgr.GetName (account_id,account_name); + sAccountMgr.GetName (account_id,account_name); // No SQL injection. id is uint32. QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id); @@ -5400,7 +5400,7 @@ bool ChatHandler::HandlePDumpLoadCommand(const char *args) return false; } - uint32 account_id = accmgr.GetId(account_name); + uint32 account_id = sAccountMgr.GetId(account_name); if (!account_id) { account_id = atoi(account); // use original string @@ -5412,7 +5412,7 @@ bool ChatHandler::HandlePDumpLoadCommand(const char *args) } } - if (!accmgr.GetName(account_id,account_name)) + if (!sAccountMgr.GetName(account_id,account_name)) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); SetSentErrorMessage(true); @@ -6100,7 +6100,7 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args) return false; account_id = player->GetSession()->GetAccountId(); - accmgr.GetName(account_id,account_name); + sAccountMgr.GetName(account_id,account_name); szExp = szAcc; } else @@ -6114,7 +6114,7 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args) return false; } - account_id = accmgr.GetId(account_name); + account_id = sAccountMgr.GetId(account_name); if (!account_id) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); diff --git a/src/game/World.cpp b/src/game/World.cpp index 0616f46fe..4491e4cf5 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1909,7 +1909,7 @@ bool World::RemoveBanAccount(BanMode mode, std::string nameOrIP) { uint32 account = 0; if (mode == BAN_ACCOUNT) - account = accmgr.GetId (nameOrIP); + account = sAccountMgr.GetId (nameOrIP); else if (mode == BAN_CHARACTER) account = sObjectMgr.GetPlayerAccountIdByPlayerName (nameOrIP); diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index 8c948e841..d84bd79cf 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -71,7 +71,7 @@ bool ChatHandler::HandleAccountDeleteCommand(const char* args) return false; } - uint32 account_id = accmgr.GetId(account_name); + uint32 account_id = sAccountMgr.GetId(account_name); if (!account_id) { PSendSysMessage(LANG_ACCOUNT_NOT_EXIST,account_name.c_str()); @@ -85,7 +85,7 @@ bool ChatHandler::HandleAccountDeleteCommand(const char* args) if(HasLowerSecurityAccount (NULL,account_id,true)) return false; - AccountOpResult result = accmgr.DeleteAccount(account_id); + AccountOpResult result = sAccountMgr.DeleteAccount(account_id); switch(result) { case AOR_OK: @@ -145,7 +145,7 @@ bool ChatHandler::HandleCharacterDeleteCommand(const char* args) } std::string account_name; - accmgr.GetName (account_id,account_name); + sAccountMgr.GetName (account_id,account_name); Player::DeleteFromDB(character_guid, account_id, true); PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id); @@ -223,7 +223,7 @@ bool ChatHandler::HandleAccountCreateCommand(const char* args) std::string account_name = szAcc; std::string password = szPassword; - AccountOpResult result = accmgr.CreateAccount(account_name, password); + AccountOpResult result = sAccountMgr.CreateAccount(account_name, password); switch(result) { case AOR_OK: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index beb04501a..1db10ba5f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8800" + #define REVISION_NR "8801" #endif // __REVISION_NR_H__ From cdd9fe72902bbbc828721525742e9a19bf8f25ec Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 11 Nov 2009 12:54:00 +0100 Subject: [PATCH 03/14] [8802] check spellexistance at playercreateinfo_spells loading --- src/game/ObjectMgr.cpp | 9 ++++++++- src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 4365f2c19..e62dd5133 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2495,8 +2495,15 @@ void ObjectMgr::LoadPlayerInfo() continue; } + uint32 spell_id = fields[2].GetUInt32(); + if (!sSpellStore.LookupEntry(spell_id)) + { + sLog.outErrorDb("Non existing spell %u in `playercreateinfo_spell` table, ignoring.", spell_id); + continue; + } + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; - pInfo->spell.push_back(fields[2].GetUInt32()); + pInfo->spell.push_back(spell_id); bar.step(); ++count; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1db10ba5f..c72b6e980 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8801" + #define REVISION_NR "8802" #endif // __REVISION_NR_H__ From f8ed87c45e2baf24c5c7460f46ac66227da40957 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 11 Nov 2009 17:00:00 +0300 Subject: [PATCH 04/14] [8803] Update racial spell id changes in 3.2.x Characters tables not affected, its not include default spells. --- sql/mangos.sql | 26 +++++++++---------- .../8803_01_mangos_playercreateinfo_spell.sql | 3 +++ ...8803_02_mangos_playercreateinfo_action.sql | 5 ++++ sql/updates/Makefile.am | 4 +++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 sql/updates/8803_01_mangos_playercreateinfo_spell.sql create mode 100644 sql/updates/8803_02_mangos_playercreateinfo_action.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 246b16e72..a0990506b 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8800_01_mangos_spell_elixir` bit(1) default NULL + `required_8803_02_mangos_playercreateinfo_action` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -10420,7 +10420,7 @@ INSERT INTO `playercreateinfo_action` VALUES (8,1,72,6603,0), (8,1,73,78,0), (8,1,74,2764,0), -(8,1,75,26296,0), +(8,1,75,26297,0), (8,1,83,117,128), (8,1,84,6603,0), (8,1,96,6603,0), @@ -10428,7 +10428,7 @@ INSERT INTO `playercreateinfo_action` VALUES (8,3,0,6603,0), (8,3,1,2973,0), (8,3,2,75,0), -(8,3,3,20554,0), +(8,3,3,26297,0), (8,3,10,159,128), (8,3,11,4604,128), (8,4,0,6603,0), @@ -10440,7 +10440,7 @@ INSERT INTO `playercreateinfo_action` VALUES (8,5,0,6603,0), (8,5,1,585,0), (8,5,2,2050,0), -(8,5,3,20554,0), +(8,5,3,26297,0), (8,5,10,159,128), (8,5,11,4540,128), (8,6,0,6603,0), @@ -10449,17 +10449,17 @@ INSERT INTO `playercreateinfo_action` VALUES (8,6,3,45462,0), (8,6,4,45902,0), (8,6,5,47541,0), -(8,6,10,50621,0), +(8,6,10,26297,0), (8,7,0,6603,0), (8,7,1,403,0), (8,7,2,331,0), -(8,7,3,20554,0), +(8,7,3,26297,0), (8,7,10,159,128), (8,7,11,117,128), (8,8,0,6603,0), (8,8,1,133,0), (8,8,2,168,0), -(8,8,3,20554,0), +(8,8,3,26297,0), (8,8,10,159,128), (8,8,11,117,128), (10,2,0,6603,0), @@ -12513,7 +12513,7 @@ INSERT INTO `playercreateinfo_spell` VALUES (8,1,22027,'Remove Insignia'), (8,1,22810,'Opening - No Text'), (8,1,26290,'Bow Specialization'), -(8,1,26296,'Berserking'), +(8,1,26297,'Berserking'), (8,1,32215,'Victorious State'), (8,1,45927,'Summon Friend'), (8,1,58943,'Da Voodoo Shuffle'), @@ -12547,7 +12547,7 @@ INSERT INTO `playercreateinfo_spell` VALUES (8,3,9078,'Cloth'), (8,3,9125,'Generic'), (8,3,13358,'Defensive State (DND)'), -(8,3,20554,'Berserking'), +(8,3,26297,'Berserking'), (8,3,20555,'Regeneration'), (8,3,20557,'Beast Slaying'), (8,3,20558,'Throwing Specialization'), @@ -12632,7 +12632,7 @@ INSERT INTO `playercreateinfo_spell` VALUES (8,5,8386,'Attacking'), (8,5,9078,'Cloth'), (8,5,9125,'Generic'), -(8,5,20554,'Berserking'), +(8,5,26297,'Berserking'), (8,5,20555,'Regeneration'), (8,5,20557,'Beast Slaying'), (8,5,20558,'Throwing Specialization'), @@ -12707,7 +12707,7 @@ INSERT INTO `playercreateinfo_spell` VALUES (8,6,48266,'Blood Presence'), (8,6,49410,'Forceful Deflection'), (8,6,49576,'Death Grip'), -(8,6,50621,'Berserking'), +(8,6,26297,'Berserking'), (8,6,52665,'Sigil'), (8,6,58943,'Da Voodoo Shuffle'), (8,6,59879,'Blood Plague'), @@ -12744,7 +12744,7 @@ INSERT INTO `playercreateinfo_spell` VALUES (8,7,9078,'Cloth'), (8,7,9116,'Shield'), (8,7,9125,'Generic'), -(8,7,20554,'Berserking'), +(8,7,26297,'Berserking'), (8,7,20555,'Regeneration'), (8,7,20557,'Beast Slaying'), (8,7,20558,'Throwing Specialization'), @@ -12785,7 +12785,7 @@ INSERT INTO `playercreateinfo_spell` VALUES (8,8,8386,'Attacking'), (8,8,9078,'Cloth'), (8,8,9125,'Generic'), -(8,8,20554,'Berserking'), +(8,8,26297,'Berserking'), (8,8,20555,'Regeneration'), (8,8,20557,'Beast Slaying'), (8,8,20558,'Throwing Specialization'), diff --git a/sql/updates/8803_01_mangos_playercreateinfo_spell.sql b/sql/updates/8803_01_mangos_playercreateinfo_spell.sql new file mode 100644 index 000000000..9b6306b27 --- /dev/null +++ b/sql/updates/8803_01_mangos_playercreateinfo_spell.sql @@ -0,0 +1,3 @@ +ALTER TABLE db_version CHANGE COLUMN required_8800_01_mangos_spell_elixir required_8803_01_mangos_playercreateinfo_spell bit; + +UPDATE `playercreateinfo_spell` SET `spell` = 26297 WHERE `spell` IN (20554,26296,50621); diff --git a/sql/updates/8803_02_mangos_playercreateinfo_action.sql b/sql/updates/8803_02_mangos_playercreateinfo_action.sql new file mode 100644 index 000000000..077d4d29d --- /dev/null +++ b/sql/updates/8803_02_mangos_playercreateinfo_action.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8803_01_mangos_playercreateinfo_spell required_8803_02_mangos_playercreateinfo_action bit; + +UPDATE `playercreateinfo_action` + SET `action` = 26297 + WHERE `action` IN (20554,26296,50621) AND `type` = 0; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 6a6263391..a7fce4537 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -154,6 +154,8 @@ pkgdata_DATA = \ 8777_01_mangos_creature.sql \ 8777_02_mangos_gameobject.sql \ 8800_01_mangos_spell_elixir.sql \ + 8803_01_mangos_playercreateinfo_spell.sql \ + 8803_02_mangos_playercreateinfo_action.sql \ README ## Additional files to include when running 'make dist' @@ -288,4 +290,6 @@ EXTRA_DIST = \ 8777_01_mangos_creature.sql \ 8777_02_mangos_gameobject.sql \ 8800_01_mangos_spell_elixir.sql \ + 8803_01_mangos_playercreateinfo_spell.sql \ + 8803_02_mangos_playercreateinfo_action.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c72b6e980..670ac9f2c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8802" + #define REVISION_NR "8803" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 004d772b9..68bbe6d0a 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8721_01_characters_guild" - #define REVISION_DB_MANGOS "required_8800_01_mangos_spell_elixir" + #define REVISION_DB_MANGOS "required_8803_02_mangos_playercreateinfo_action" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From fb6f792cf32f40f953d9bf0b502cf3ffff0f214f Mon Sep 17 00:00:00 2001 From: balrok Date: Sun, 18 Oct 2009 04:25:19 -0400 Subject: [PATCH 05/14] [8804] changed some unhandled opcode-errors to debug with this i also introduced a new status for opcodes STATUS_UNHANDLED not sure if i realy found all unhanddled opcodes those are all based on empircal analysis of our serverlog --- src/game/Opcodes.cpp | 10 +++++----- src/game/Opcodes.h | 3 ++- src/game/WorldSession.cpp | 5 +++++ src/shared/revision_nr.h | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index 78fbcef0a..0477efaaf 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -666,7 +666,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode }, /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode}, - /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_UNHANDLED,&WorldSession::Handle_NULL }, /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode }, /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode }, @@ -684,7 +684,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantLeaderOpcode}, /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem }, /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_UNHANDLED,&WorldSession::Handle_NULL }, /*0x293*/ { "SMSG_MEETINGSTONE_LEAVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -772,7 +772,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode }, /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode}, - /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_UNHANDLED,&WorldSession::Handle_NULL }, /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -1066,7 +1066,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_UNHANDLED,&WorldSession::Handle_NULL }, /*0x411*/ { "SMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -1206,7 +1206,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_UNHANDLED,&WorldSession::Handle_NULL }, /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index 66b52fa54..9d32765ab 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -1317,7 +1317,8 @@ enum SessionStatus STATUS_LOGGEDIN, ///< Player in game (_player!=NULL, m_GUID == _player->GetGUID(), inWorld()) STATUS_TRANSFER, ///< Player transferring to another map (_player!=NULL, m_GUID == _player->GetGUID(), !inWorld()) STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, ///< _player!= NULL or _player==NULL && m_playerRecentlyLogout, m_GUID store last _player guid) - STATUS_NEVER ///< Opcode not accepted from client (deprecated or server side only) + STATUS_NEVER, ///< Opcode not accepted from client (deprecated or server side only) + STATUS_UNHANDLED ///< We don' handle this opcode yet }; class WorldPacket; diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 075445d36..10d9c19b8 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -244,6 +244,11 @@ bool WorldSession::Update(uint32 /*diff*/) LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; + case STATUS_UNHANDLED: + sLog.outDebug("SESSION: received not handled opcode %s (0x%.4X)", + LookupOpcodeName(packet->GetOpcode()), + packet->GetOpcode()); + break; } } catch(ByteBufferException &) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 670ac9f2c..83da1e7c8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8803" + #define REVISION_NR "8804" #endif // __REVISION_NR_H__ From eb94d787613370f4fc1a2100c033a0cd414b9244 Mon Sep 17 00:00:00 2001 From: balrok Date: Sun, 1 Nov 2009 10:20:04 -0500 Subject: [PATCH 06/14] [8805] fix freeze with repeatingly calls at logout + HandleMoveWorldportAckOpcode starts in WorldSession::logout inside while(isTeleportedFar)... through coord won't get ever valid there - it will call itself all the time --- src/game/MovementHandler.cpp | 5 +++++ src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 74951decf..7f7ef94d9 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -50,6 +50,11 @@ void WorldSession::HandleMoveWorldportAckOpcode() // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { + sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player got's teleported far to a not valid location. (map:%u, x:%f, y:%f, z:%f) We log him out and don't save him..", loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); + // stop teleportation else we would try this again in the beginning of WorldSession::LogoutPlayer... + GetPlayer()->SetSemaphoreTeleportFar(false); + // player don't gets saved - so his coords will stay at the point where + // he was last saved LogoutPlayer(false); return; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 83da1e7c8..93fd9866e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8804" + #define REVISION_NR "8805" #endif // __REVISION_NR_H__ From 413a44d114e4d17cc229ae9e0ce57594c653e528 Mon Sep 17 00:00:00 2001 From: balrok Date: Sun, 1 Nov 2009 11:22:24 -0500 Subject: [PATCH 07/14] [8806] remove wrong erroroutput for teleportspells they are just handled in a different way - so this errorcheck isn't valid for those spells --- src/game/Spell.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 954fffb19..be4e65aab 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1994,6 +1994,9 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap) SpellTargetPosition const* st = sSpellMgr.GetSpellTargetPosition(m_spellInfo->Id); if(st) { + // teleportspells are handled in another way + if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_TELEPORT_UNITS) + break; if (st->target_mapId == m_caster->GetMapId()) m_targets.setDestination(st->target_X, st->target_Y, st->target_Z); else diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 93fd9866e..ccd0b8d40 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8805" + #define REVISION_NR "8806" #endif // __REVISION_NR_H__ From 4ac1bcc37a184c732e9a2e79cd6639ff301d6a0e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 11 Nov 2009 18:05:14 +0300 Subject: [PATCH 08/14] [8807] Better check `playercreateinfo_action` data at server startup. --- src/game/ObjectMgr.cpp | 9 +++++++- src/game/Player.cpp | 46 ++++++++++++++++++++++++++++------------ src/game/Player.h | 1 + src/shared/revision_nr.h | 2 +- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index e62dd5133..11b577fdd 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2554,8 +2554,15 @@ void ObjectMgr::LoadPlayerInfo() continue; } + uint8 action_button = fields[2].GetUInt8(); + uint32 action = fields[3].GetUInt32(); + uint8 action_type = fields[4].GetUInt8(); + + if (!Player::IsActionButtonDataValid(action_button,action,action_type,NULL)) + continue; + PlayerInfo* pInfo = &playerInfo[current_race][current_class]; - pInfo->action.push_back(PlayerCreateInfoAction(fields[2].GetUInt8(),fields[3].GetUInt32(),fields[4].GetUInt8())); + pInfo->action.push_back(PlayerCreateInfoAction(action_button,action,action_type)); bar.step(); ++count; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 296e7f70d..128d01c1f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -5548,18 +5548,24 @@ void Player::SendInitialActionButtons() const sLog.outDetail( "Action Buttons for '%u' Initialized", GetGUIDLow() ); } -ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) +bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type, Player* player) { if(button >= MAX_ACTION_BUTTONS) { - sLog.outError( "Action %u not added into button %u for player %s: button must be < 144", action, button, GetName() ); - return NULL; + if (player) + sLog.outError( "Action %u not added into button %u for player %s: button must be < %u", action, button, player->GetName(), MAX_ACTION_BUTTONS ); + else + sLog.outError( "Table `playercreateinfo_action` have action %u into button %u : button must be < %u", action, button, MAX_ACTION_BUTTONS ); + return false; } if(action >= MAX_ACTION_BUTTON_ACTION_VALUE) { - sLog.outError( "Action %u not added into button %u for player %s: action must be < %u", action, button, GetName(), MAX_ACTION_BUTTON_ACTION_VALUE ); - return NULL; + if (player) + sLog.outError( "Action %u not added into button %u for player %s: action must be < %u", action, button, player->GetName(), MAX_ACTION_BUTTON_ACTION_VALUE ); + else + sLog.outError( "Table `playercreateinfo_action` have action %u into button %u : action must be < %u", action, button, MAX_ACTION_BUTTON_ACTION_VALUE ); + return false; } switch(type) @@ -5567,27 +5573,41 @@ ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) case ACTION_BUTTON_SPELL: if(!sSpellStore.LookupEntry(action)) { - sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() ); - return NULL; + if (player) + sLog.outError( "Spell action %u not added into button %u for player %s: spell not exist", action, button, player->GetName() ); + else + sLog.outError( "Table `playercreateinfo_action` have spell action %u into button %u: spell not exist", action, button ); + return false; } - if(!HasSpell(action)) + if(player && !player->HasSpell(action)) { - sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() ); - return NULL; + sLog.outError( "Spell action %u not added into button %u for player %s: player don't known this spell", action, button, player->GetName() ); + return false; } break; case ACTION_BUTTON_ITEM: if(!ObjectMgr::GetItemPrototype(action)) { - sLog.outError( "Action %u not added into button %u for player %s: item not exist", action, button, GetName() ); - return NULL; + if (player) + sLog.outError( "Item action %u not added into button %u for player %s: item not exist", action, button, player->GetName() ); + else + sLog.outError( "Table `playercreateinfo_action` have item action %u into button %u: item not exist", action, button ); + return false; } break; default: - break; // pther cases not checked at this moment + break; // other cases not checked at this moment } + return true; +} + +ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) +{ + + if (!IsActionButtonDataValid(button,action,type,this)) + return NULL; // it create new button (NEW state) if need or return existed ActionButton& ab = m_actionButtons[button]; diff --git a/src/game/Player.h b/src/game/Player.h index a6b1ea7f6..79014e91d 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1621,6 +1621,7 @@ class MANGOS_DLL_SPEC Player : public Unit m_cinematic = cine; } + static bool IsActionButtonDataValid(uint8 button, uint32 action, uint8 type, Player* player); ActionButton* addActionButton(uint8 button, uint32 action, uint8 type); void removeActionButton(uint8 button); void SendInitialActionButtons() const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ccd0b8d40..93843a533 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8806" + #define REVISION_NR "8807" #endif // __REVISION_NR_H__ From 5bb8d60a67e4684ead4aac2044a91c3fd3b73724 Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Wed, 11 Nov 2009 22:20:07 +0100 Subject: [PATCH 09/14] Allow disabling tbbmalloc on Unix by using: --with-std-malloc --- configure.ac | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/configure.ac b/configure.ac index e8638b2b9..e380dfb24 100644 --- a/configure.ac +++ b/configure.ac @@ -151,6 +151,26 @@ else AC_MSG_RESULT($DO_MYSQL) fi +## Check for memory allocator +# Use libc-malloc or libtbb-malloc? +AC_MSG_CHECKING(whether to use libc malloc) +MANGOSD_STD_MALLOC=no +AC_ARG_WITH(std-malloc, +[ +Memory allocation options: + + --with-std-malloc Use standard malloc], +[ + if test "$withval" = "yes" ; then + CFLAGS="-DUSE_STANDARD_MALLOC $CFLAGS" + CXXFLAGS="-DUSE_STANDARD_MALLOC $CXXFLAGS" + MANGOSD_STD_MALLOC=yes + elif test "$withval" != "no" ; then + AC_MSG_ERROR(Please choose yes or no) + fi +]) +AC_MSG_RESULT($MANGOSD_STD_MALLOC) + ## Check for options # Include debug info in library? AC_MSG_CHECKING(whether to include debug info in library) From 2ba416f78c5e79ca141ace26b28dac282c5c1cd8 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Thu, 12 Nov 2009 14:37:14 +0100 Subject: [PATCH 10/14] [8808] Add a few more definitions to enum GameObjectFlags Signed-off-by: NoFantasy --- src/game/SharedDefines.h | 6 +++++- src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index c6ce091f5..7f58b26c2 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1194,7 +1194,11 @@ enum GameObjectFlags GO_FLAG_TRANSPORT = 0x00000008, //any kind of transport? Object can transport (elevator, boat, car) GO_FLAG_UNK1 = 0x00000010, // GO_FLAG_NODESPAWN = 0x00000020, //never despawn, typically for doors, they just change state - GO_FLAG_TRIGGERED = 0x00000040 //typically, summoned objects. Triggered by spell or other events + GO_FLAG_TRIGGERED = 0x00000040, //typically, summoned objects. Triggered by spell or other events + GO_FLAG_UNK_8 = 0x00000080, + GO_FLAG_UNK_9 = 0x00000100, //? Seen on type 33, possible meaning "destruct in progress" + GO_FLAG_UNK_10 = 0x00000200, //? Seen on type 33 + GO_FLAG_UNK_11 = 0x00000400 //? Seen on type 33, possibly meaning "destructed" }; enum TextEmotes diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 93843a533..3cfd385e5 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8807" + #define REVISION_NR "8808" #endif // __REVISION_NR_H__ From ec808c9d3d546d15851db818a2c2f4abfb13aec7 Mon Sep 17 00:00:00 2001 From: XTZGZoReX Date: Thu, 12 Nov 2009 16:00:23 +0100 Subject: [PATCH 11/14] [8809] Revert "[8799] Implemented thread safe bg queue updates." This reverts commit 72f7a7ee56c63672faa7786b1d162a7a3b9ab406. This is temporary revert due to bug in ACE_Thread_Mutex. Original code itself in commit has no problem. Conflicts: src/shared/revision_nr.h --- src/game/BattleGround.cpp | 2 +- src/game/BattleGroundHandler.cpp | 291 ++++++++++++++++++------------- src/game/BattleGroundMgr.cpp | 80 +++------ src/game/BattleGroundMgr.h | 20 +-- src/shared/revision_nr.h | 2 +- 5 files changed, 207 insertions(+), 188 deletions(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index fa41ad7ea..9517b206a 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1084,7 +1084,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac { // a player has left the battleground, so there are free slots -> add to queue AddToBGFreeSlotQueue(); - sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, GetQueueId()); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, GetQueueId()); } // Let others know diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 30d98ee3e..903a5de89 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -148,9 +148,8 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) // if we're here, then the conditions to join a bg are met. We can proceed in joining. // _player->GetGroup() was already checked, grp is already initialized - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; - GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, bgTypeId, 0, false, isPremade, 0); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); + GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0); + uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); if (joinAsGroup /* && _player->GetGroup()*/) { sLog.outDebug("Battleground: the following players are joining as group:"); @@ -167,7 +166,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) member->GetSession()->SendPacket(&data); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); - bgQueue.AddPlayer(member, ginfo); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); } sLog.outDebug("Battleground: group end"); @@ -182,11 +181,12 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); SendPacket(&data); - bgQueue.AddPlayer(_player, ginfo); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); } - sBattleGroundMgr.ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); - //we should announce queue status here, if we want + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); + if (!ginfo->IsInvitedToBGInstanceGUID) + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true); } void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ ) @@ -303,6 +303,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) uint8 type; // arenatype if arena uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 + uint32 instanceId; uint32 bgTypeId_; // type id from dbc uint16 unk; // 0x1F90 constant? uint8 action; // enter battle 0x1, leave queue 0x0 @@ -311,130 +312,182 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { - sLog.outError("BattlegroundHandler: invalid bgtype (%u) received.", bgTypeId_); - return; - } - if (!_player->InBattleGroundQueue()) - { - sLog.outError("BattlegroundHandler: Invalid CMSG_BATTLEFIELD_PORT received from player (%u), he is not in bg_queue.", _player->GetGUIDLow()); + sLog.outError("Battleground: invalid bgtype (%u) received.", bgTypeId_); + // update battleground slots for the player to fix his UI and sent data. + // this is a HACK, I don't know why the client starts sending invalid packets in the first place. + // it usually happens with extremely high latency (if debugging / stepping in the code for example) + if (_player->InBattleGroundQueue()) + { + // update all queues, send invitation info if player is invited, queue info if queued + for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + { + BattleGroundQueueTypeId bgQueueTypeId = _player->GetBattleGroundQueueTypeId(i); + if (!bgQueueTypeId) + continue; + BattleGroundTypeId bgTypeId = BattleGroundMgr::BGTemplateId(bgQueueTypeId); + BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; + BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID()); + // if the player is not in queue, continue or no group information - this should never happen + if (itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo) + continue; + + BattleGround * bg = NULL; + // get possibly needed data from groupinfo + uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType; + uint8 status = 0; + + if (!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID) + { + // not invited to bg, get template + bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); + status = STATUS_WAIT_QUEUE; + } + else + { + // get the bg we're invited to + bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId); + status = STATUS_WAIT_JOIN; + } + + // if bg not found, then continue, don't invite if already in the instance + if (!bg || (_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID())) + continue; + + // re - invite player with proper data + WorldPacket data; + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype); + SendPacket(&data); + } + } return; } //get GroupQueueInfo from BattleGroundQueue BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type); - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; - //we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function - GroupQueueInfo ginfo; - if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) + BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; + BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID()); + if (itrPlayerStatus == qpMap.end()) { - sLog.outError("BattlegroundHandler: itrplayerstatus not found."); - return; - } - // if action == 1, then instanceId is required - if (!ginfo.IsInvitedToBGInstanceGUID && action == 1) - { - sLog.outError("BattlegroundHandler: instance not found."); + sLog.outError("Battleground: itrplayerstatus not found."); return; } - BattleGround *bg = sBattleGroundMgr.GetBattleGround(ginfo.IsInvitedToBGInstanceGUID, bgTypeId); + instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID; + // if action == 1, then instanceId is required + if (!instanceId && action == 1) + { + sLog.outError("Battleground: instance not found."); + return; + } + + BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId); // bg template might and must be used in case of leaving queue, when instance is not created yet if (!bg && action == 0) bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); if (!bg) { - sLog.outError("BattlegroundHandler: bg_template not found for type id %u.", bgTypeId); + sLog.outError("Battleground: bg_template not found for type id %u.", bgTypeId); return; } - //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it - if (action == 1 && ginfo.ArenaType == 0) + if (_player->InBattleGroundQueue()) { - //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue - if (!_player->CanJoinToBattleground()) + //we must use temporary variables, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function! + uint32 team = itrPlayerStatus->second.GroupInfo->Team; + uint32 arenaType = itrPlayerStatus->second.GroupInfo->ArenaType; + uint32 isRated = itrPlayerStatus->second.GroupInfo->IsRated; + uint32 rating = itrPlayerStatus->second.GroupInfo->ArenaTeamRating; + uint32 opponentsRating = itrPlayerStatus->second.GroupInfo->OpponentsTeamRating; + + //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it + if (action == 1 && arenaType == 0) { - //send bg command result to show nice message - WorldPacket data2(SMSG_GROUP_JOINED_BATTLEGROUND, 4); - data2 << uint32(0xFFFFFFFE); - _player->GetSession()->SendPacket(&data2); - action = 0; - sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); + //if player is trying to enter battleground (not arena!) and he has deserter debuff, we must just remove him from queue + if (!_player->CanJoinToBattleground()) + { + //send bg command result to show nice message + WorldPacket data2(SMSG_GROUP_JOINED_BATTLEGROUND, 4); + data2 << uint32(0xFFFFFFFE); + _player->GetSession()->SendPacket(&data2); + action = 0; + sLog.outDebug("Battleground: player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); + } + //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue + if (_player->getLevel() > bg->GetMaxLevel()) + { + sLog.outError("Battleground: Player %s (%u) has level higher than maxlevel of battleground! Do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); + action = 0; + } } - //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue - if (_player->getLevel() > bg->GetMaxLevel()) + uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId); + WorldPacket data; + switch( action ) { - sLog.outError("Battleground: Player %s (%u) has level higher than maxlevel of battleground! Do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); - action = 0; - } - } - uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId); - WorldPacket data; - switch( action ) - { - case 1: // port to battleground - if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId)) - return; // cheating? + case 1: // port to battleground + if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId)) + return; // cheating? - _player->SetBattleGroundEntryPoint(); + _player->SetBattleGroundEntryPoint(); - // resurrect the player - if (!_player->isAlive()) - { - _player->ResurrectPlayer(1.0f); - _player->SpawnCorpseBones(); - } - // stop taxi flight at port - if (_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->m_taxi.ClearTaxiDestinations(); - } - - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); - _player->GetSession()->SendPacket(&data); - // remove battleground queue status from BGmgr - bgQueue.RemovePlayer(_player->GetGUID(), false); - // this is still needed here if battleground "jumping" shouldn't add deserter debuff - // also this is required to prevent stuck at old battleground after SetBattleGroundId set to new - if (BattleGround *currentBg = _player->GetBattleGround()) - currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true); - - // set the destination instance id - _player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId); - // set the destination team - _player->SetBGTeam(ginfo.Team); - // bg->HandleBeforeTeleportToBattleGround(_player); - sBattleGroundMgr.SendToBattleGround(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId); - // add only in HandleMoveWorldPortAck() - // bg->AddPlayer(_player,team); - sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); - break; - case 0: // leave queue - // if player leaves rated arena match before match start, it is counted as he played but he lost - if (ginfo.IsRated) - { - ArenaTeam * at = sObjectMgr.GetArenaTeamById(ginfo.Team); - if (at) + // resurrect the player + if (!_player->isAlive()) { - sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), ginfo.OpponentsTeamRating); - at->MemberLost(_player, ginfo.OpponentsTeamRating); - at->SaveToDB(); + _player->ResurrectPlayer(1.0f); + _player->SpawnCorpseBones(); } - } - _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); - bgQueue.RemovePlayer(_player->GetGUID(), true); - // player left queue, we should update it - do not update Arena Queue - if (!ginfo.ArenaType) - sBattleGroundMgr.ScheduleQueueUpdate(ginfo.ArenaTeamRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); - SendPacket(&data); - sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); - break; - default: - sLog.outError("Battleground port: unknown action %u", action); - break; + // stop taxi flight at port + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->m_taxi.ClearTaxiDestinations(); + } + + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); + _player->GetSession()->SendPacket(&data); + // remove battleground queue status from BGmgr + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), false); + // this is still needed here if battleground "jumping" shouldn't add deserter debuff + // also this is required to prevent stuck at old battleground after SetBattleGroundId set to new + if (BattleGround *currentBg = _player->GetBattleGround()) + currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true); + + // set the destination instance id + _player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId); + // set the destination team + _player->SetBGTeam(team); + // bg->HandleBeforeTeleportToBattleGround(_player); + sBattleGroundMgr.SendToBattleGround(_player, instanceId, bgTypeId); + // add only in HandleMoveWorldPortAck() + // bg->AddPlayer(_player,team); + sLog.outDebug("Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); + break; + case 0: // leave queue + // if player leaves rated arena match before match start, it is counted as he played but he lost + if (isRated) + { + ArenaTeam * at = sObjectMgr.GetArenaTeamById(team); + if (at) + { + sLog.outDebug("UPDATING memberLost's personal arena rating for %u by opponents rating: %u, because he has left queue!", GUID_LOPART(_player->GetGUID()), opponentsRating); + at->MemberLost(_player, opponentsRating); + at->SaveToDB(); + } + } + _player->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].RemovePlayer(_player->GetGUID(), true); + // player left queue, we should update it - do not update Arena Queue + if (!arenaType) + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenaType, isRated, rating); + SendPacket(&data); + sLog.outDebug("Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); + break; + default: + sLog.outError("Battleground port: unknown action %u", action); + break; + } } } @@ -491,16 +544,16 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) } //we are sending update to player about queue - he can be invited there! //get GroupQueueInfo for queue status - BattleGroundQueue& bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; - GroupQueueInfo ginfo; - if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo)) + BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; + BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = qpMap.find(_player->GetGUID()); + if (itrPlayerStatus == qpMap.end()) continue; - if (ginfo.IsInvitedToBGInstanceGUID) + if (itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID) { - bg = sBattleGroundMgr.GetBattleGround(ginfo.IsInvitedToBGInstanceGUID, bgTypeId); + bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId); if (!bg) continue; - uint32 remainingTime = getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime); + uint32 remainingTime = getMSTimeDiff(getMSTime(), itrPlayerStatus->second.GroupInfo->RemoveInviteTime); // send status invited to BattleGround sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType); SendPacket(&data); @@ -510,9 +563,9 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); if (!bg) continue; - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, _player->GetBattleGroundQueueIdFromLevel()); + uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(itrPlayerStatus->second.GroupInfo, _player->GetBattleGroundQueueIdFromLevel()); // send status in BattleGround Queue - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(itrPlayerStatus->second.GroupInfo->JoinTime, getMSTime()), arenaType); SendPacket(&data); } } @@ -672,9 +725,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) arenaRating = avg_pers_rating; } - BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; - GroupQueueInfo * ginfo = bgQueue.AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId); - uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); + GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId); + uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel()); if (asGroup) { sLog.outDebug("Battleground: arena join as group start"); @@ -693,11 +745,12 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) member->GetSession()->SendPacket(&data); sBattleGroundMgr.BuildGroupJoinedBattlegroundPacket(&data, bgTypeId); member->GetSession()->SendPacket(&data); - bgQueue.AddPlayer(member, ginfo); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(member, ginfo); sLog.outDebug("Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,member->GetGUIDLow(), member->GetName()); } sLog.outDebug("Battleground: arena join as group end"); - //announce to world ... removed + if (isRated) + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true); } else { @@ -707,10 +760,10 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); SendPacket(&data); - bgQueue.AddPlayer(_player, ginfo); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); sLog.outDebug("Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); } - sBattleGroundMgr.ScheduleQueueUpdate(arenaRating, arenatype, bgQueueTypeId, bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); + sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating); } void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data ) diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 471c5d427..2f23cbd5e 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -177,7 +177,6 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId index++; sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index); - ACE_Guard guard(m_Lock); m_QueuedGroups[queue_id][index].push_back(ginfo); // return ginfo, because it is needed to add players to this group info @@ -187,8 +186,6 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId //add player to playermap void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo) { - ACE_Guard guard(m_Lock); - //if player isn't in queue, he is added, if already is, then values are overwritten, no memory leak PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()]; info.LastOnlineTime = getMSTime(); @@ -251,7 +248,6 @@ uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueue void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount) { //Player *plr = sObjectMgr.GetPlayer(guid); - ACE_Guard guard(m_Lock); int32 queue_id = -1; // signed for proper for-loop finish QueuedPlayersMap::iterator itr; @@ -368,26 +364,6 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou } } -//returns true when player pl_guid is in queue and is invited to bgInstanceGuid -bool BattleGroundQueue::IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime) -{ - ACE_Guard g(m_Lock); - QueuedPlayersMap::const_iterator qItr = m_QueuedPlayers.find(pl_guid); - return ( qItr != m_QueuedPlayers.end() - && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == bgInstanceGuid - && qItr->second.GroupInfo->RemoveInviteTime == removeTime ); -} - -bool BattleGroundQueue::GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo) -{ - ACE_Guard g(m_Lock); - QueuedPlayersMap::const_iterator qItr = m_QueuedPlayers.find(guid); - if (qItr == m_QueuedPlayers.end()) - return false; - *ginfo = *(qItr->second.GroupInfo); - return true; -} - //Announce world message void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue) { @@ -485,7 +461,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID); // create remind invite events - BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->ArenaType, ginfo->RemoveInviteTime); + BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime); plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME)); // create automatic remove events BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime); @@ -756,7 +732,6 @@ should be called from BattleGround::RemovePlayer function in some cases */ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated, uint32 arenaRating) { - ACE_Guard guard(m_Lock); //if no players in queue - do nothing if( m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].empty() && m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].empty() && @@ -1046,15 +1021,17 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId); - if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue or in battleground + if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground { // check if player is invited to this bg - BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId]; - if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime)) + BattleGroundQueue::QueuedPlayersMap const& qpMap = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers; + BattleGroundQueue::QueuedPlayersMap::const_iterator qItr = qpMap.find(m_PlayerGuid); + if( qItr != qpMap.end() && qItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID + && qItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime ) { WorldPacket data; //we must send remaining time in queue - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType); + sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, qItr->second.GroupInfo->ArenaType); plr->GetSession()->SendPacket(&data); } } @@ -1087,19 +1064,22 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) //bg pointer can be NULL! so use it carefully! uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId); - if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue, or in Battleground + if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground { // check if player is in queue for this BG and if we are removing his invite event - BattleGroundQueue &bgQueue = sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId]; - if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime)) + BattleGroundQueue::QueuedPlayersMap& qpMap = sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].m_QueuedPlayers; + BattleGroundQueue::QueuedPlayersMap::iterator qMapItr = qpMap.find(m_PlayerGuid); + if( qMapItr != qpMap.end() && qMapItr->second.GroupInfo + && qMapItr->second.GroupInfo->IsInvitedToBGInstanceGUID == m_BgInstanceGUID + && qMapItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime ) { sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID); plr->RemoveBattleGroundQueueId(m_BgQueueTypeId); - bgQueue.RemovePlayer(m_PlayerGuid, true); + sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].RemovePlayer(m_PlayerGuid, true); //update queues if battleground isn't ended - if (bg && bg->isBattleGround() && bg->GetStatus() != STATUS_WAIT_LEAVE) - sBattleGroundMgr.ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetQueueId()); + if (bg) + sBattleGroundMgr.ScheduleQueueUpdate(m_BgQueueTypeId, m_BgTypeId, bg->GetQueueId()); WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); @@ -1187,24 +1167,18 @@ void BattleGroundMgr::Update(uint32 diff) // update scheduled queues if (!m_QueueUpdateScheduler.empty()) { - std::vector scheduled; - { - //create mutex - ACE_Guard guard(SchedulerLock); - //copy vector and clear the other - scheduled = std::vector(m_QueueUpdateScheduler); - m_QueueUpdateScheduler.clear(); - //release lock - } - + //copy vector and clear the other + // TODO add lock + // TODO maybe std::list would be better and then unlock after end of cycle + std::vector scheduled(m_QueueUpdateScheduler); + m_QueueUpdateScheduler.clear(); + // TODO drop lock for (uint8 i = 0; i < scheduled.size(); i++) { - uint32 arenaRating = scheduled[i] >> 32; - uint8 arenaType = scheduled[i] >> 24 & 255; - BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16 & 255); + BattleGroundQueueTypeId bgQueueTypeId = BattleGroundQueueTypeId(scheduled[i] >> 16); BattleGroundTypeId bgTypeId = BattleGroundTypeId((scheduled[i] >> 8) & 255); BGQueueIdBasedOnLevel queue_id = BGQueueIdBasedOnLevel(scheduled[i] & 255); - m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id, arenaType, arenaRating > 0, arenaRating); + m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id); } } @@ -2034,11 +2008,11 @@ void BattleGroundMgr::ToggleArenaTesting() sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF); } -void BattleGroundMgr::ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) +void BattleGroundMgr::ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) { - ACE_Guard guard(SchedulerLock); + //This method must be atomic, TODO add mutex //we will use only 1 number created of bgTypeId and queue_id - uint64 schedule_id = ((uint64)arenaRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | queue_id; + uint32 schedule_id = (bgQueueTypeId << 16) | (bgTypeId << 8) | queue_id; bool found = false; for (uint8 i = 0; i < m_QueueUpdateScheduler.size(); i++) { diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 36f097cdb..4d72d9656 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -23,7 +23,6 @@ #include "Policies/Singleton.h" #include "Utilities/EventProcessor.h" #include "BattleGround.h" -#include "ace/Recursive_Thread_Mutex.h" typedef std::map BattleGroundSet; @@ -84,19 +83,12 @@ class BattleGroundQueue GroupQueueInfo * AddGroup(Player * leader, BattleGroundTypeId bgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 ArenaRating, uint32 ArenaTeamId = 0); void AddPlayer(Player *plr, GroupQueueInfo *ginfo); void RemovePlayer(const uint64& guid, bool decreaseInvitedCount); - bool IsPlayerInvited(const uint64& pl_guid, const uint32 bgInstanceGuid, const uint32 removeTime); - bool GetPlayerGroupInfoData(const uint64& guid, GroupQueueInfo* ginfo); void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); void DecreaseGroupLength(uint32 queueId, uint32 AsGroup); void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue); - private: - //mutex that should not allow changing private data, nor allowing to update Queue during private data change. - ACE_Recursive_Thread_Mutex m_Lock; - - typedef std::map QueuedPlayersMap; QueuedPlayersMap m_QueuedPlayers; @@ -131,6 +123,8 @@ class BattleGroundQueue //one selection pool for horde, other one for alliance SelectionPool m_SelectionPools[BG_TEAMS_COUNT]; + private: + bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side); uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; @@ -144,8 +138,8 @@ class BattleGroundQueue class BGQueueInviteEvent : public BasicEvent { public: - BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint8 arenaType, uint32 removeTime) : - m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_ArenaType(arenaType), m_RemoveTime(removeTime) + BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID, BattleGroundTypeId BgTypeId, uint32 removeTime) : + m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID), m_BgTypeId(BgTypeId), m_RemoveTime(removeTime) { }; virtual ~BGQueueInviteEvent() {}; @@ -156,7 +150,6 @@ class BGQueueInviteEvent : public BasicEvent uint64 m_PlayerGuid; uint32 m_BgInstanceGUID; BattleGroundTypeId m_BgTypeId; - uint8 m_ArenaType; uint32 m_RemoveTime; }; @@ -226,7 +219,7 @@ class BattleGroundMgr BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID]; - void ScheduleQueueUpdate(uint32 arenaRating, uint8 arenaType, BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); + void ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); uint32 GetMaxRatingDifference() const; uint32 GetRatingDiscardTimer() const; uint32 GetPrematureFinishTime() const; @@ -272,14 +265,13 @@ class BattleGroundMgr static bool IsBGWeekend(BattleGroundTypeId bgTypeId); private: - ACE_Thread_Mutex SchedulerLock; BattleMastersMap mBattleMastersMap; CreatureBattleEventIndexesMap m_CreatureBattleEventIndexMap; GameObjectBattleEventIndexesMap m_GameObjectBattleEventIndexMap; /* Battlegrounds */ BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID]; - std::vector m_QueueUpdateScheduler; + std::vectorm_QueueUpdateScheduler; std::set m_ClientBattleGroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_QUEUES]; //the instanceids just visible for the client uint32 m_NextRatingDiscardUpdate; time_t m_NextAutoDistributionTime; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 3cfd385e5..8bf574e41 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8808" + #define REVISION_NR "8809" #endif // __REVISION_NR_H__ From 25ab89ce976e72070f7bdb36c6520ccbd1219ce6 Mon Sep 17 00:00:00 2001 From: balrok Date: Fri, 13 Nov 2009 13:56:59 +0100 Subject: [PATCH 12/14] [8810] error output at loading when creature_movement has nonexistant spell --- src/game/WaypointManager.cpp | 6 ++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp index e0f60bd2c..993f795d6 100644 --- a/src/game/WaypointManager.cpp +++ b/src/game/WaypointManager.cpp @@ -141,6 +141,12 @@ void WaypointManager::Load() } } + if (be.spell && ! sSpellStore.LookupEntry(be.spell)) + { + sLog.outErrorDb("Table creature_movement references unknown spellid %u. Skipping id %u.", be.spell, id); + continue; + } + if (be.emote) { if (!sEmotesStore.LookupEntry(be.emote)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8bf574e41..2fa6e8b0d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8809" + #define REVISION_NR "8810" #endif // __REVISION_NR_H__ From 33c6241fd8ffcb67cf0156dcef97133b3bab2c4f Mon Sep 17 00:00:00 2001 From: balrok Date: Fri, 13 Nov 2009 20:48:08 +0100 Subject: [PATCH 13/14] [8811] check creature existance at waypoint loading also just set the spellid to 0 if it doesn't exist instead of dorpping the whole movementpoint --- src/game/WaypointManager.cpp | 15 ++++++++++++--- src/shared/revision_nr.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp index 993f795d6..b3b627aeb 100644 --- a/src/game/WaypointManager.cpp +++ b/src/game/WaypointManager.cpp @@ -83,7 +83,10 @@ void WaypointManager::Load() sLog.outString( ">> Paths loaded" ); } - result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement"); + // 0 1 2 3 4 5 + result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2," + // 6 7 8 9 10 11 12 13 14 15 + "waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement"); barGoLink bar( result->GetRowCount() ); do @@ -92,6 +95,12 @@ void WaypointManager::Load() Field *fields = result->Fetch(); uint32 point = fields[15].GetUInt32(); uint32 id = fields[14].GetUInt32(); + if (!sObjectMgr.GetCreatureData(id)) + { + sLog.outErrorDb("Table creature_movement references unknown creature %u. Skipping.", id); + continue; + } + WaypointPath &path = m_pathMap[id]; // the cleanup queries make sure the following is true assert(point >= 1 && point <= path.size()); @@ -143,8 +152,8 @@ void WaypointManager::Load() if (be.spell && ! sSpellStore.LookupEntry(be.spell)) { - sLog.outErrorDb("Table creature_movement references unknown spellid %u. Skipping id %u.", be.spell, id); - continue; + sLog.outErrorDb("Table creature_movement references unknown spellid %u. Skipping id %u with point %u.", be.spell, id, point); + be.spell = 0; } if (be.emote) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2fa6e8b0d..1668a01ca 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8810" + #define REVISION_NR "8811" #endif // __REVISION_NR_H__ From 02b6c5889b8903aa0f0aac40e3659444ce2437c4 Mon Sep 17 00:00:00 2001 From: balrok Date: Fri, 13 Nov 2009 20:51:59 +0100 Subject: [PATCH 14/14] [8812] totems with no spell shouldn't cast anything not all totems must have a spell --- src/game/Totem.cpp | 4 ++++ src/shared/revision_nr.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index e14dba9f3..5811c88d9 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -68,6 +68,10 @@ void Totem::Summon(Unit* owner) AIM_Initialize(); + // there are some totems, which exist just for their visual appeareance + if (!GetSpell()) + return; + switch(m_type) { case TOTEM_PASSIVE: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1668a01ca..1aac25873 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8811" + #define REVISION_NR "8812" #endif // __REVISION_NR_H__