aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAI.cpp2
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h2
-rwxr-xr-xsrc/server/game/Accounts/AccountMgr.cpp31
-rwxr-xr-xsrc/server/game/Achievements/AchievementMgr.cpp44
-rwxr-xr-xsrc/server/game/Addons/AddonMgr.cpp9
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.cpp3
-rwxr-xr-xsrc/server/game/Chat/Chat.h12
-rwxr-xr-xsrc/server/game/Chat/Commands/Level0.cpp2
-rwxr-xr-xsrc/server/game/Chat/Commands/Level2.cpp126
-rwxr-xr-xsrc/server/game/Chat/Commands/Level3.cpp72
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp21
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h19
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.cpp2
-rwxr-xr-xsrc/server/game/DataStores/DBCStructure.h3
-rwxr-xr-xsrc/server/game/Entities/Corpse/Corpse.cpp16
-rwxr-xr-xsrc/server/game/Entities/Corpse/Corpse.h2
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp3
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h5
-rwxr-xr-xsrc/server/game/Entities/Creature/TemporarySummon.cpp10
-rwxr-xr-xsrc/server/game/Entities/Creature/TemporarySummon.h6
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.cpp7
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.h4
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp16
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp27
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h7
-rwxr-xr-xsrc/server/game/Entities/Object/Updates/UpdateData.cpp2
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.cpp31
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.h2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp168
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h6
-rwxr-xr-xsrc/server/game/Entities/Totem/Totem.cpp2
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.cpp4
-rwxr-xr-xsrc/server/game/Entities/Unit/StatSystem.cpp5
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp335
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h6
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp12
-rwxr-xr-xsrc/server/game/Grids/Grid.h7
-rwxr-xr-xsrc/server/game/Grids/GridStates.cpp2
-rwxr-xr-xsrc/server/game/Grids/NGrid.h22
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.cpp6
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.h2
-rwxr-xr-xsrc/server/game/Groups/Group.cpp180
-rwxr-xr-xsrc/server/game/Instances/InstanceSaveMgr.cpp21
-rwxr-xr-xsrc/server/game/Maps/Map.cpp55
-rwxr-xr-xsrc/server/game/Maps/Map.h2
-rwxr-xr-xsrc/server/game/Miscellaneous/Language.h3
-rw-r--r--src/server/game/Movement/MovementStructures.h2
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/CharacterHandler.cpp151
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/MiscHandler.cpp54
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/MovementHandler.cpp31
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/NPCHandler.cpp96
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp85
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/QueryHandler.cpp1
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/SpellHandler.cpp47
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp46
-rwxr-xr-xsrc/server/game/Server/WorldSession.h46
-rwxr-xr-xsrc/server/game/Server/WorldSocket.cpp27
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp20
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp1
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp44
-rwxr-xr-xsrc/server/game/Spells/Spell.h2
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp30
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp7
-rwxr-xr-xsrc/server/game/Tickets/TicketMgr.cpp5
-rwxr-xr-xsrc/server/game/World/World.cpp5
-rw-r--r--src/server/scripts/Commands/cs_account.cpp35
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp10
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/blasted_lands.cpp15
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp8
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp2
-rw-r--r--src/server/scripts/Kalimdor/desolace.cpp55
-rw-r--r--src/server/scripts/Kalimdor/durotar.cpp4
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp8
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp5
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp3
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp1
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp4
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp4
-rw-r--r--src/server/scripts/Outland/blades_edge_mountains.cpp25
-rw-r--r--src/server/scripts/Outland/netherstorm.cpp32
-rw-r--r--src/server/scripts/Outland/shadowmoon_valley.cpp25
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp53
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp49
-rw-r--r--src/server/scripts/World/areatrigger_scripts.cpp166
-rw-r--r--src/server/scripts/World/go_scripts.cpp54
-rw-r--r--src/server/scripts/World/item_scripts.cpp41
-rw-r--r--src/server/scripts/World/npcs_special.cpp10
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.cpp5
-rwxr-xr-xsrc/server/shared/Database/DatabaseWorkerPool.h9
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.cpp45
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h43
-rwxr-xr-xsrc/server/shared/Database/Implementation/LoginDatabase.cpp11
-rwxr-xr-xsrc/server/shared/Database/Implementation/LoginDatabase.h11
-rwxr-xr-xsrc/server/shared/Database/Implementation/WorldDatabase.cpp6
-rwxr-xr-xsrc/server/shared/Database/Implementation/WorldDatabase.h2
-rwxr-xr-xsrc/server/shared/Database/MySQLConnection.h1
-rwxr-xr-xsrc/server/shared/Logging/Log.cpp14
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp2
-rwxr-xr-xsrc/server/shared/Packets/ByteBuffer.h4
-rwxr-xr-xsrc/server/shared/Threading/Callback.h121
-rwxr-xr-xsrc/server/shared/Threading/LockedQueue.h7
106 files changed, 1980 insertions, 950 deletions
diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp
index 08f8d7a3d77..b11e6363bc4 100755
--- a/src/server/game/AI/EventAI/CreatureEventAI.cpp
+++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp
@@ -840,7 +840,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
me->Mount(action.mount.modelId);
}
else
- me->Unmount();
+ me->Dismount();
break;
}
diff --git a/src/server/game/AI/EventAI/CreatureEventAI.h b/src/server/game/AI/EventAI/CreatureEventAI.h
index 2fc26bcbd3e..9cc8c8f9c4a 100755
--- a/src/server/game/AI/EventAI/CreatureEventAI.h
+++ b/src/server/game/AI/EventAI/CreatureEventAI.h
@@ -108,7 +108,7 @@ enum EventAI_ActionType
ACTION_T_SET_SHEATH = 40, // Sheath (0-passive, 1-melee, 2-ranged)
ACTION_T_FORCE_DESPAWN = 41, // No Params
ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue, format(0-flat, 1-percent from max health)
- ACTION_T_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to unmount)
+ ACTION_T_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount)
ACTION_T_SET_PHASE_MASK = 97,
ACTION_T_SET_STAND_STATE = 98,
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index dded086b584..34d465a5e7e 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -994,7 +994,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
(*itr)->ToUnit()->Mount(e.action.morphOrMount.model);
}
else
- (*itr)->ToUnit()->Unmount();
+ (*itr)->ToUnit()->Dismount();
}
delete targets;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index bab5c272f15..b12ef959847 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -409,7 +409,7 @@ enum SMART_ACTION
SMART_ACTION_SET_SHEATH = 40, // Sheath (0-unarmed, 1-melee, 2-ranged)
SMART_ACTION_FORCE_DESPAWN = 41, // timer
SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue(+pct, -flat)
- SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to unmount)
+ SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount)
SMART_ACTION_SET_INGAME_PHASE_MASK = 44, // mask
SMART_ACTION_SET_DATA = 45, // Field, Data (only creature TODO)
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index ebe9a9af36b..6c3dd69c0da 100755
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -37,8 +37,16 @@ AccountOpResult CreateAccount(std::string username, std::string password)
if (GetId(username))
return AOR_NAME_ALREDY_EXIST; // username does already exist
- LoginDatabase.PExecute("INSERT INTO account(username, sha_pass_hash, joindate) VALUES('%s', '%s', NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str());
- LoginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_ADD_ACCOUNT);
+
+ stmt->setString(0, username);
+ stmt->setString(1, CalculateShaPassHash(username, password));
+
+ LoginDatabase.Execute(stmt);
+
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_ADD_REALM_CHARS);
+
+ LoginDatabase.Execute(stmt);
return AOR_OK; // everything's fine
}
@@ -104,11 +112,13 @@ AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::s
normalizeString(newUsername);
normalizeString(newPassword);
- std::string safeNewUsername = newUsername;
- LoginDatabase.EscapeString(safeNewUsername);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_USERNAME);
- LoginDatabase.PExecute("UPDATE account SET v='0', s='0', username='%s', sha_pass_hash='%s' WHERE id='%d'", safeNewUsername.c_str(),
- CalculateShaPassHash(newUsername, newPassword).c_str(), accountId);
+ stmt->setString(0, newUsername);
+ stmt->setString(1, CalculateShaPassHash(newUsername, newPassword));
+ stmt->setUInt32(2, accountId);
+
+ LoginDatabase.Execute(stmt);
return AOR_OK;
}
@@ -126,9 +136,12 @@ AccountOpResult ChangePassword(uint32 accountId, std::string newPassword)
normalizeString(username);
normalizeString(newPassword);
- // also reset s and v to force update at next realmd login
- LoginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'",
- CalculateShaPassHash(username, newPassword).c_str(), accountId);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_PASSWORD);
+
+ stmt->setString(0, CalculateShaPassHash(username, newPassword));
+ stmt->setUInt32(1, accountId);
+
+ LoginDatabase.Execute(stmt);
return AOR_OK;
}
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 0221afd2113..b6b3651d0ef 100755
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -567,7 +567,13 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
{
// we will remove not existed criteria for all characters
sLog->outError("Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id);
- CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u", id);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA);
+
+ stmt->setUInt16(0, uint16(id));
+
+ CharacterDatabase.Execute(stmt);
+
continue;
}
@@ -997,6 +1003,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
}
+ if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
+ if (!data->Meets(GetPlayer(), unit))
+ continue;
+
SetCriteriaProgress(achievementCriteria, 1);
break;
}
@@ -1426,6 +1436,18 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL:
+ case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL:
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD:
break; // Not implemented yet :(
}
@@ -1966,7 +1988,7 @@ bool AchievementMgr::HasAchieved(uint32 achievementId) const
return m_completedAchievements.find(achievementId) != m_completedAchievements.end();
}
-bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit* unit)
+bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 /*miscValue1*/, uint64 /*miscValue2*/, Unit* unit)
{
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL))
return false;
@@ -2275,17 +2297,23 @@ void AchievementGlobalMgr::LoadCompletedAchievements()
{
Field* fields = result->Fetch();
- uint32 achievement_id = fields[0].GetUInt32();
- const AchievementEntry* achievement = sAchievementStore.LookupEntry(achievement_id);
+ uint32 achievementId = fields[0].GetUInt32();
+ const AchievementEntry* achievement = sAchievementStore.LookupEntry(achievementId);
if (!achievement)
{
- // we will remove not existed achievement for all characters
- sLog->outError("Non-existing achievement %u data removed from table `character_achievement`.", achievement_id);
- CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE achievement = %u", achievement_id);
+ // Remove non existent achievements from all characters
+ sLog->outError("Non-existing achievement %u data removed from table `character_achievement`.", achievementId);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEVMENT);
+
+ stmt->setUInt16(0, uint16(achievementId));
+
+ CharacterDatabase.Execute(stmt);
+
continue;
}
else if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
- m_allCompletedAchievements.insert(achievement_id);
+ m_allCompletedAchievements.insert(achievementId);
} while (result->NextRow());
sLog->outString(">> Loaded %lu completed achievements in %u ms", (unsigned long)m_allCompletedAchievements.size(), GetMSTimeDiffToNow(oldMSTime));
diff --git a/src/server/game/Addons/AddonMgr.cpp b/src/server/game/Addons/AddonMgr.cpp
index 9d5bdd159f7..ff6d16bef4d 100755
--- a/src/server/game/Addons/AddonMgr.cpp
+++ b/src/server/game/Addons/AddonMgr.cpp
@@ -70,8 +70,13 @@ void LoadFromDB()
void SaveAddon(AddonInfo const& addon)
{
std::string name = addon.Name;
- CharacterDatabase.EscapeString(name);
- CharacterDatabase.PExecute("INSERT INTO addons (name, crc) VALUES ('%s', %u)", name.c_str(), addon.CRC);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_ADDON);
+
+ stmt->setString(0, name);
+ stmt->setUInt32(1, addon.CRC);
+
+ CharacterDatabase.Execute(stmt);
m_knownAddons.push_back(SavedAddon(addon.Name, addon.CRC));
}
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index b1d0765aa6e..5a628c248a8 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -834,7 +834,6 @@ void Battleground::EndBattleground(uint32 winner)
uint32 winner_kills = player->GetRandomWinner() ? BG_REWARD_WINNER_HONOR_LAST : BG_REWARD_WINNER_HONOR_FIRST;
uint32 loser_kills = player->GetRandomWinner() ? BG_REWARD_LOSER_HONOR_LAST : BG_REWARD_LOSER_HONOR_FIRST;
- uint32 winner_arena = player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST;
// remove temporary currency bonus auras before rewarding player
player->RemoveAura(SPELL_HONORABLE_DEFENDER_25Y);
@@ -847,7 +846,7 @@ void Battleground::EndBattleground(uint32 winner)
{
UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winner_kills));
/*if (CanAwardArenaPoints())
- player->ModifyConquestPoints(winner_arena);*/
+ player->ModifyConquestPoints(player->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST);*/
if (!player->GetRandomWinner())
player->SetRandomWinner(true);
}
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 24652fcc6d5..d9190265bbb 100755
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -154,8 +154,8 @@ class ChatHandler
bool HandleCastTargetCommand(const char *args);
bool HandleCastDestCommand(const char *args);
- bool HandleCharacterCustomizeCommand(const char * args);
- bool HandleCharacterChangeFactionCommand(const char * args);
+ bool HandleCharacterCustomizeCommand(const char* args);
+ bool HandleCharacterChangeFactionCommand(const char* args);
bool HandleCharacterChangeRaceCommand(const char * args);
bool HandleCharacterDeletedDeleteCommand(const char* args);
bool HandleCharacterDeletedListCommand(const char* args);
@@ -163,7 +163,7 @@ class ChatHandler
bool HandleCharacterDeletedOldCommand(const char* args);
bool HandleCharacterEraseCommand(const char* args);
bool HandleCharacterLevelCommand(const char* args);
- bool HandleCharacterRenameCommand(const char * args);
+ bool HandleCharacterRenameCommand(const char* args);
bool HandleCharacterReputationCommand(const char* args);
bool HandleCharacterTitlesCommand(const char* args);
@@ -215,9 +215,9 @@ class ChatHandler
bool HandleResetAllCommand(const char * args);
bool HandleResetHonorCommand(const char * args);
bool HandleResetLevelCommand(const char * args);
- bool HandleResetSpellsCommand(const char * args);
+ bool HandleResetSpellsCommand(const char* args);
bool HandleResetStatsCommand(const char * args);
- bool HandleResetTalentsCommand(const char * args);
+ bool HandleResetTalentsCommand(const char* args);
bool HandleSendItemsCommand(const char* args);
bool HandleSendMailCommand(const char* args);
@@ -355,7 +355,7 @@ class ChatHandler
bool HandleBanHelper(BanMode mode, char const* args);
bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
bool HandleUnBanHelper(BanMode mode, char const* args);
- void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
+ void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel);
void HandleLearnSkillRecipesHelper(Player* player, uint32 skill_id);
// Stores informations about a deleted character
diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp
index 97173f75652..7ff7a82bf58 100755
--- a/src/server/game/Chat/Commands/Level0.cpp
+++ b/src/server/game/Chat/Commands/Level0.cpp
@@ -122,7 +122,7 @@ bool ChatHandler::HandleDismountCommand(const char* /*args*/)
return false;
}
- m_session->GetPlayer()->Unmount();
+ m_session->GetPlayer()->Dismount();
m_session->GetPlayer()->RemoveAurasByType(SPELL_AURA_MOUNTED);
return true;
}
diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp
index d31ddc9aa33..d33e248121f 100755
--- a/src/server/game/Chat/Commands/Level2.cpp
+++ b/src/server/game/Chat/Commands/Level2.cpp
@@ -63,11 +63,11 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
return false;
- uint32 account_id = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
+ uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
// find only player from same account if any
if (!target)
- if (WorldSession* session = sWorld->FindSession(account_id))
+ if (WorldSession* session = sWorld->FindSession(accountId))
target = session->GetPlayer();
uint32 notspeaktime = (uint32) atoi(delayStr);
@@ -76,21 +76,30 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (HasLowerSecurity (target, target_guid, true))
return false;
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_MUTE_TIME);
+
if (target)
{
- //! Target is online, mute will be in effect right away.
- int64 mutetime = time(NULL) + notspeaktime * MINUTE;
- target->GetSession()->m_muteTime = mutetime;
- LoginDatabase.PExecute("UPDATE account SET mutetime = " SI64FMTD " WHERE id = '%u'", mutetime, account_id);
+ // Target is online, mute will be in effect right away.
+ int64 muteTime = time(NULL) + notspeaktime * MINUTE;
+ target->GetSession()->m_muteTime = muteTime;
+
+ stmt->setInt64(0, muteTime);
+
ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str());
}
else
{
- //! Target is offline, mute will be in effect starting from the next login.
+ // Target is offline, mute will be in effect starting from the next login.
int32 muteTime = -int32(notspeaktime * MINUTE);
- LoginDatabase.PExecute("UPDATE account SET mutetime = %d WHERE id = %u", muteTime, account_id);
+
+ stmt->setInt64(0, muteTime);
}
+ stmt->setUInt32(1, accountId);
+
+ LoginDatabase.Execute(stmt);
+
std::string nameLink = playerLink(target_name);
PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str());
@@ -107,11 +116,11 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
return false;
- uint32 account_id = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
+ uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid);
// find only player from same account if any
if (!target)
- if (WorldSession* session = sWorld->FindSession(account_id))
+ if (WorldSession* session = sWorld->FindSession(accountId))
target = session->GetPlayer();
// must have strong lesser security level
@@ -130,7 +139,12 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
target->GetSession()->m_muteTime = 0;
}
- LoginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_MUTE_TIME);
+
+ stmt->setInt64(0, 0);
+ stmt->setUInt32(1, accountId);
+
+ LoginDatabase.Execute(stmt);
if (target)
ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
@@ -443,9 +457,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
bool ChatHandler::HandleCharacterRenameCommand(const char* args)
{
Player* target;
- uint64 target_guid;
- std::string target_name;
- if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
+ uint64 targetGuid;
+ std::string targetName;
+ if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
if (target)
@@ -460,13 +474,19 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args)
else
{
// check offline security
- if (HasLowerSecurity(NULL, target_guid))
+ if (HasLowerSecurity(NULL, targetGuid))
return false;
- std::string oldNameLink = playerLink(target_name);
+ std::string oldNameLink = playerLink(targetName);
+
+ PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
- PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid));
+ stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+
+ CharacterDatabase.Execute(stmt);
}
return true;
@@ -476,80 +496,102 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args)
bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
{
Player* target;
- uint64 target_guid;
- std::string target_name;
- if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
+ uint64 targetGuid;
+ std::string targetName;
+ if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
+
+ stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
+
if (target)
{
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow());
+
+ stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
- std::string oldNameLink = playerLink(target_name);
+ std::string oldNameLink = playerLink(targetName);
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
}
+ CharacterDatabase.Execute(stmt);
+
return true;
}
-bool ChatHandler::HandleCharacterChangeFactionCommand(const char * args)
+bool ChatHandler::HandleCharacterChangeFactionCommand(const char* args)
{
Player* target;
- uint64 target_guid;
- std::string target_name;
+ uint64 targetGuid;
+ std::string targetName;
- if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
+ if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
+
+ stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
+
if (target)
{
- // TODO : add text into database
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION);
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '64' WHERE guid = %u", target->GetGUIDLow());
+
+ stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
- std::string oldNameLink = playerLink(target_name);
+ std::string oldNameLink = playerLink(targetName);
- // TODO : add text into database
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '64' WHERE guid = %u", GUID_LOPART(target_guid));
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
}
+ CharacterDatabase.Execute(stmt);
+
return true;
}
bool ChatHandler::HandleCharacterChangeRaceCommand(const char * args)
{
Player* target;
- uint64 target_guid;
- std::string target_name;
- if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
+ uint64 targetGuid;
+ std::string targetName;
+ if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
+
+ stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
+
if (target)
{
// TODO : add text into database
PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE);
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '128' WHERE guid = %u", target->GetGUIDLow());
+
+ stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
- std::string oldNameLink = playerLink(target_name);
+ std::string oldNameLink = playerLink(targetName);
// TODO : add text into database
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '128' WHERE guid = %u", GUID_LOPART(target_guid));
+ PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
}
+ CharacterDatabase.Execute(stmt);
+
return true;
}
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 9276c536101..855cced3a9e 100755
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -2177,28 +2177,33 @@ bool ChatHandler::HandleHoverCommand(const char *args)
return true;
}
-void ChatHandler::HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel)
+void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel)
{
if (player)
{
- player->GiveLevel(newlevel);
+ player->GiveLevel(newLevel);
player->InitTalentForLevel();
player->SetUInt32Value(PLAYER_XP, 0);
if (needReportToTarget(player))
{
- if (oldlevel == newlevel)
+ if (oldLevel == newLevel)
ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_PROGRESS_RESET, GetNameLink().c_str());
- else if (oldlevel < newlevel)
- ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP, GetNameLink().c_str(), newlevel);
+ else if (oldLevel < newLevel)
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_UP, GetNameLink().c_str(), newLevel);
else // if (oldlevel > newlevel)
- ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN, GetNameLink().c_str(), newlevel);
+ ChatHandler(player).PSendSysMessage(LANG_YOURS_LEVEL_DOWN, GetNameLink().c_str(), newLevel);
}
}
else
{
- // update level and XP at level, all other will be updated at loading
- CharacterDatabase.PExecute("UPDATE characters SET level = '%u', xp = 0 WHERE guid = '%u'", newlevel, GUID_LOPART(player_guid));
+ // Update level and reset XP, everything else will be updated at login
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_LEVEL);
+
+ stmt->setUInt8(0, uint8(newLevel));
+ stmt->setUInt32(1, GUID_LOPART(playerGuid));
+
+ CharacterDatabase.Execute(stmt);
}
}
@@ -2560,12 +2565,12 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)
return true;
}
-bool ChatHandler::HandleResetSpellsCommand(const char * args)
+bool ChatHandler::HandleResetSpellsCommand(const char* args)
{
Player* target;
- uint64 target_guid;
- std::string target_name;
- if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
+ uint64 targetGuid;
+ std::string targetName;
+ if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
if (target)
@@ -2578,19 +2583,25 @@ bool ChatHandler::HandleResetSpellsCommand(const char * args)
}
else
{
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", uint32(AT_LOGIN_RESET_SPELLS), GUID_LOPART(target_guid));
- PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, target_name.c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
+
+ stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+
+ CharacterDatabase.Execute(stmt);
+
+ PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str());
}
return true;
}
-bool ChatHandler::HandleResetTalentsCommand(const char * args)
+bool ChatHandler::HandleResetTalentsCommand(const char* args)
{
Player* target;
- uint64 target_guid;
- std::string target_name;
- if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
+ uint64 targetGuid;
+ std::string targetName;
+ if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
{
// Try reset talents as Hunter Pet
Creature* creature = getSelectedCreature();
@@ -2628,11 +2639,16 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args)
target->SendTalentsInfoData(true);
return true;
}
- else if (target_guid)
+ else if (targetGuid)
{
- uint32 at_flags = AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS;
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'", at_flags, GUID_LOPART(target_guid));
- std::string nameLink = playerLink(target_name);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
+
+ stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+
+ CharacterDatabase.Execute(stmt);
+
+ std::string nameLink = playerLink(targetName);
PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
return true;
}
@@ -2673,7 +2689,11 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
return false;
}
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'", atLogin, atLogin);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ALL_AT_LOGIN_FLAGS);
+
+ stmt->setUInt16(0, uint16(atLogin));
+
+ CharacterDatabase.Execute(stmt);
TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
@@ -3278,7 +3298,8 @@ bool ChatHandler::HandleBanListCharacterCommand(const char *args)
bool ChatHandler::HandleBanListAccountCommand(const char *args)
{
- LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_OLD_BANS);
+ LoginDatabase.Execute(stmt);
char* cFilter = strtok((char*)args, " ");
std::string filter = cFilter ? cFilter : "";
@@ -3383,7 +3404,8 @@ bool ChatHandler::HandleBanListHelper(QueryResult result)
bool ChatHandler::HandleBanListIPCommand(const char *args)
{
- LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate");
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_OLD_IP_BANS);
+ LoginDatabase.Execute(stmt);
char* cFilter = strtok((char*)args, " ");
std::string filter = cFilter ? cFilter : "";
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 2db85542132..fcdee61d68a 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -52,7 +52,7 @@ struct LocalDB2Data
};
template<class T>
-inline void LoadDB2(uint32& availableDb2Locales, StoreProblemList1& errlist, DB2Storage<T>& storage, const std::string& db2_path, const std::string& filename)
+inline void LoadDB2(StoreProblemList1& errlist, DB2Storage<T>& storage, const std::string& db2_path, const std::string& filename)
{
// compatibility format and C++ structure sizes
ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDB2_assert_print(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename));
@@ -60,14 +60,10 @@ inline void LoadDB2(uint32& availableDb2Locales, StoreProblemList1& errlist, DB2
++DB2FilesCount;
std::string db2_filename = db2_path + filename;
- if (storage.Load(db2_filename.c_str()))
- {
- }
- else
+ if (!storage.Load(db2_filename.c_str()))
{
// sort problematic db2 to (1) non compatible and (2) nonexistent
- FILE * f = fopen(db2_filename.c_str(), "rb");
- if (f)
+ if (FILE * f = fopen(db2_filename.c_str(), "rb"))
{
char buf[100];
snprintf(buf, 100,"(exist, but have %d fields instead " SIZEFMTD ") Wrong client version DBC file?", storage.GetFieldCount(), strlen(storage.GetFormat()));
@@ -84,12 +80,11 @@ void LoadDB2Stores(const std::string& dataPath)
std::string db2Path = dataPath + "dbc/";
StoreProblemList1 bad_db2_files;
- uint32 availableDb2Locales = 0xFFFFFFFF;
- LoadDB2(availableDb2Locales, bad_db2_files, sItemStore, db2Path, "Item.db2");
- LoadDB2(availableDb2Locales, bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2");
- LoadDB2(availableDb2Locales, bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2");
- LoadDB2(availableDb2Locales, bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2");
+ LoadDB2(bad_db2_files, sItemStore, db2Path, "Item.db2");
+ LoadDB2(bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2");
+ LoadDB2(bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2");
+ LoadDB2(bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2");
// error checks
if (bad_db2_files.size() >= DB2FilesCount)
{
@@ -110,7 +105,7 @@ void LoadDB2Stores(const std::string& dataPath)
if (!sItemStore.LookupEntry(72068) || // last item added in 4.2.2 (14545)
!sItemExtendedCostStore.LookupEntry(3652) ) // last item extended cost added in 4.2.2 (14545)
{
- sLog->outString("");
+ sLog->outString();
sLog->outError("Please extract correct db2 files from client 4.2.2 14545.");
exit(1);
}
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 1af24eb16d3..9dd97f936ef 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -82,14 +82,14 @@ enum AchievementFlags
enum AchievementCriteriaCondition
{
- ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
- ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, // reset progress on death
- ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
- ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP = 3, // requires you to be on specific map, reset at change
- ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
- ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk
- ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
- ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
+ ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0,
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH = 1, // reset progress on death
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK1 = 2, // only used in "Complete a daily quest every day for five consecutive days"
+ ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP = 3, // requires you to be on specific map, reset at change
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
+ ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT = 9, // requires the player not to be hit by specific spell
+ ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk
};
#define MAX_ADDITIONAL_CRITERIA_CONDITIONS 3
@@ -179,7 +179,7 @@ enum AchievementCriteriaFlags
enum AchievementCriteriaTimedTypes
{
ACHIEVEMENT_TIMED_TYPE_EVENT = 1, // Timer is started by internal event with id in timerStartEvent
- ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by acceting quest with entry in timerStartEvent
+ ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by accepting quest with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER = 5, // Timer is started by casting a spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET = 6, // Timer is started by being target of spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent
@@ -539,6 +539,7 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_EJECTABLE = 0x00000020, // ejectable
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100,
+ VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000,
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 789d2f26309..89061f1a19b 100755
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -748,7 +748,7 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction)
return NULL;
}
-char const* GetPetName(uint32 petfamily, uint32 dbclang)
+char const* GetPetName(uint32 petfamily, uint32 /*dbclang*/)
{
if (!petfamily)
return NULL;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 87a20633d8d..994a7978272 100755
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -2184,7 +2184,8 @@ struct VehicleSeatEntry
bool CanEnterOrExit() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT; }
bool CanSwitchFromSeat() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH; }
bool IsUsableByOverride() const { return (m_flags & VEHICLE_SEAT_FLAG_UNCONTROLLED)
- || (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3)); }
+ || (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 |
+ VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4)); }
bool IsEjectable() const { return m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE; }
};
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 5953518c65b..64317af2018 100755
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -26,7 +26,7 @@
#include "GossipDef.h"
#include "World.h"
-Corpse::Corpse(CorpseType type) : WorldObject()
+Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES)
, m_type(type)
{
m_objectType |= TYPEMASK_CORPSE;
@@ -39,9 +39,6 @@ Corpse::Corpse(CorpseType type) : WorldObject()
m_time = time(NULL);
lootForBody = false;
-
- if (type != CORPSE_BONES)
- m_isWorldObject = true;
}
Corpse::~Corpse()
@@ -162,21 +159,12 @@ void Corpse::DeleteFromDB(SQLTransaction& trans)
trans->Append(stmt);
}
-bool Corpse::LoadFromDB(uint32 guid, Field* fields)
+bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields)
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
uint32 ownerGuid = fields[16].GetUInt32();
- m_type = CorpseType(fields[12].GetUInt8());
- if (m_type >= MAX_CORPSE_TYPE)
- {
- sLog->outError("Corpse (guid: %u, owner: %u) have wrong corpse type (%u), not loading.", guid, ownerGuid, m_type);
- return false;
- }
- if (m_type != CORPSE_BONES)
- m_isWorldObject = true;
-
float posX = fields[0].GetFloat();
float posY = fields[1].GetFloat();
float posZ = fields[2].GetFloat();
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index 2e45606b88f..a704e2243eb 100755
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -59,7 +59,7 @@ class Corpse : public WorldObject, public GridObject<Corpse>
bool Create(uint32 guidlow, Player* owner);
void SaveToDB();
- bool LoadFromDB(uint32 guid, Field* fields);
+ bool LoadCorpseFromDB(uint32 guid, Field* fields);
void DeleteBonesFromWorld();
void DeleteFromDB(SQLTransaction& trans);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 8065e66216e..1c88e19406f 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -137,7 +137,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
return true;
}
-Creature::Creature(): Unit(), MapCreature(),
+Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapCreature(),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0),
m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
@@ -160,6 +160,7 @@ m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL)
ResetLootMode(); // restore default loot mode
TriggerJustRespawned = false;
+ m_isTempWorldObject = false;
}
Creature::~Creature()
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index ae1c3ac59c6..6abeebbed50 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -442,7 +442,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
{
public:
- explicit Creature();
+ explicit Creature(bool isWorldObject = false);
virtual ~Creature();
void AddToWorld();
@@ -709,6 +709,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
uint32 GetGUIDTransport() { return guid_transport; }
void FarTeleportTo(Map* map, float X, float Y, float Z, float O);
+
+ bool m_isTempWorldObject; //true when possessed
+
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData* data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp
index b17606b83cc..1b06f0f0b6a 100755
--- a/src/server/game/Entities/Creature/TemporarySummon.cpp
+++ b/src/server/game/Entities/Creature/TemporarySummon.cpp
@@ -22,8 +22,8 @@
#include "ObjectMgr.h"
#include "TemporarySummon.h"
-TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner) :
-Creature(), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
+TempSummon::TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) :
+Creature(isWorldObject), m_Properties(properties), m_type(TEMPSUMMON_MANUAL_DESPAWN),
m_timer(0), m_lifetime(0)
{
m_summonerGUID = owner ? owner->GetGUID() : 0;
@@ -272,7 +272,7 @@ void TempSummon::RemoveFromWorld()
Creature::RemoveFromWorld();
}
-Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner) : TempSummon(properties, owner)
+Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : TempSummon(properties, owner, isWorldObject)
, m_owner(owner)
{
ASSERT(m_owner);
@@ -306,7 +306,7 @@ bool Minion::IsGuardianPet() const
return isPet() || (m_Properties && m_Properties->Category == SUMMON_CATEGORY_PET);
}
-Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner)
+Guardian::Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject) : Minion(properties, owner, isWorldObject)
, m_bonusSpellDamage(0)
{
memset(m_statFromOwner, 0, sizeof(float)*MAX_STATS);
@@ -340,7 +340,7 @@ void Guardian::InitSummon()
m_owner->ToPlayer()->CharmSpellInitialize();
}
-Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner)
+Puppet::Puppet(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false) //maybe true?
{
ASSERT(owner->GetTypeId() == TYPEID_PLAYER);
m_owner = (Player*)owner;
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 1982dec4bb8..69ae8349155 100755
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -24,7 +24,7 @@
class TempSummon : public Creature
{
public:
- explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner);
+ explicit TempSummon(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
virtual ~TempSummon() {}
void Update(uint32 time);
virtual void InitStats(uint32 lifetime);
@@ -48,7 +48,7 @@ class TempSummon : public Creature
class Minion : public TempSummon
{
public:
- Minion(SummonPropertiesEntry const* properties, Unit* owner);
+ Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
void InitStats(uint32 duration);
void RemoveFromWorld();
Unit* GetOwner() { return m_owner; }
@@ -64,7 +64,7 @@ class Minion : public TempSummon
class Guardian : public Minion
{
public:
- Guardian(SummonPropertiesEntry const* properties, Unit* owner);
+ Guardian(SummonPropertiesEntry const* properties, Unit* owner, bool isWorldObject);
void InitStats(uint32 duration);
bool InitStatsForLevel(uint8 level);
void InitSummon();
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index 9fe1a2ba296..7c100c98f76 100755
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -27,7 +27,7 @@
#include "GridNotifiersImpl.h"
#include "ScriptMgr.h"
-DynamicObject::DynamicObject() : WorldObject(),
+DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
_aura(NULL), _removedAura(NULL), _caster(NULL), _duration(0), _isViewpoint(false)
{
m_objectType |= TYPEMASK_DYNAMICOBJECT;
@@ -79,7 +79,7 @@ void DynamicObject::RemoveFromWorld()
}
}
-bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, bool active, DynamicObjectType type)
+bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type)
{
SetMap(caster->GetMap());
Relocate(pos);
@@ -105,8 +105,7 @@ bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spe
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
SetUInt32Value(DYNAMICOBJECT_CASTTIME, getMSTime());
- m_isWorldObject = active;
- if (active)
+ if (IsWorldObject())
setActive(true); //must before add to map to be put in world container
if (!GetMap()->AddToMap(this))
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h
index c178fe98d14..bd8c15cdba4 100755
--- a/src/server/game/Entities/DynamicObject/DynamicObject.h
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.h
@@ -35,13 +35,13 @@ enum DynamicObjectType
class DynamicObject : public WorldObject, public GridObject<DynamicObject>
{
public:
- DynamicObject();
+ DynamicObject(bool isWorldObject);
~DynamicObject();
void AddToWorld();
void RemoveFromWorld();
- bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, bool active, DynamicObjectType type);
+ bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type);
void Update(uint32 p_time);
void Remove();
void SetDuration(int32 newDuration);
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 8ca60d6a4e4..357024b061c 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -30,7 +30,7 @@
#include "CreatureAISelector.h"
#include "Group.h"
-GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue), m_AI(NULL)
+GameObject::GameObject() : WorldObject(false), m_goValue(new GameObjectValue), m_AI(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
@@ -770,8 +770,18 @@ void GameObject::DeleteFromDB()
{
sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
sObjectMgr->DeleteGOData(m_DBTableGuid);
- WorldDatabase.PExecute("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
- WorldDatabase.PExecute("DELETE FROM game_event_gameobject WHERE guid = '%u'", m_DBTableGuid);
+
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
+
+ stmt->setUInt32(0, m_DBTableGuid);
+
+ WorldDatabase.Execute(stmt);
+
+ stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_EVENT_GAMEOBJECT);
+
+ stmt->setUInt32(0, m_DBTableGuid);
+
+ WorldDatabase.Execute(stmt);
}
GameObject* GameObject::GetGameObject(WorldObject& object, uint64 guid)
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 2820755f00c..590a78ea533 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -82,7 +82,7 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1)
WorldObject::~WorldObject()
{
// this may happen because there are many !create/delete
- if (m_isWorldObject && m_currMap)
+ if (IsWorldObject() && m_currMap)
{
if (GetTypeId() == TYPEID_CORPSE)
{
@@ -1174,8 +1174,8 @@ void MovementInfo::OutDebug()
sLog->outString("splineElevation: %f", splineElevation);
}
-WorldObject::WorldObject(): WorldLocation(),
-m_isWorldObject(false), m_name(""), m_isActive(false), m_zoneScript(NULL),
+WorldObject::WorldObject(bool isWorldObject): WorldLocation(),
+m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL),
m_transport(NULL), m_currMap(NULL), m_InstanceId(0),
m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0)
{
@@ -1191,6 +1191,17 @@ void WorldObject::SetWorldObject(bool on)
GetMap()->AddObjectToSwitchList(this, on);
}
+bool WorldObject::IsWorldObject() const
+{
+ if (m_isWorldObject)
+ return true;
+
+ if (ToCreature() && ToCreature()->m_isTempWorldObject)
+ return true;
+
+ return false;
+}
+
void WorldObject::setActive(bool on)
{
if (m_isActive == on)
@@ -2004,7 +2015,7 @@ void WorldObject::SetMap(Map* map)
m_currMap = map;
m_mapId = map->GetId();
m_InstanceId = map->GetInstanceId();
- if (m_isWorldObject)
+ if (IsWorldObject())
m_currMap->AddWorldObject(this);
}
@@ -2012,7 +2023,7 @@ void WorldObject::ResetMap()
{
ASSERT(m_currMap);
ASSERT(!IsInWorld());
- if (m_isWorldObject)
+ if (IsWorldObject())
m_currMap->RemoveWorldObject(this);
m_currMap = NULL;
//maybe not for corpse
@@ -2102,10 +2113,10 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
switch (mask)
{
case UNIT_MASK_SUMMON:
- summon = new TempSummon(properties, summoner);
+ summon = new TempSummon(properties, summoner, false);
break;
case UNIT_MASK_GUARDIAN:
- summon = new Guardian(properties, summoner);
+ summon = new Guardian(properties, summoner, false);
break;
case UNIT_MASK_PUPPET:
summon = new Puppet(properties, summoner);
@@ -2114,7 +2125,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
summon = new Totem(properties, summoner);
break;
case UNIT_MASK_MINION:
- summon = new Minion(properties, summoner);
+ summon = new Minion(properties, summoner, false);
break;
default:
return NULL;
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index ab6b534cac0..0e2cc2fa873 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -561,7 +561,7 @@ class FlaggedValuesArray32
class WorldObject : public Object, public WorldLocation
{
protected:
- explicit WorldObject();
+ explicit WorldObject(bool isWorldObject); //note: here it means if it is in grid object list or world object list
public:
virtual ~WorldObject();
@@ -800,6 +800,9 @@ class WorldObject : public Object, public WorldLocation
bool isActiveObject() const { return m_isActive; }
void setActive(bool isActiveObject);
void SetWorldObject(bool apply);
+ bool IsPermanentWorldObject() const { return m_isWorldObject; }
+ bool IsWorldObject() const;
+
template<class NOTIFIER> void VisitNearbyObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitAll(GetPositionX(), GetPositionY(), radius, notifier); }
template<class NOTIFIER> void VisitNearbyGridObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitGrid(GetPositionX(), GetPositionY(), radius, notifier); }
template<class NOTIFIER> void VisitNearbyWorldObject(float const& radius, NOTIFIER& notifier) const { if (IsInWorld()) GetMap()->VisitWorld(GetPositionX(), GetPositionY(), radius, notifier); }
@@ -812,7 +815,6 @@ class WorldObject : public Object, public WorldLocation
double rand_chance() const { return GetMap()->mtRand.randExc(100.0);}
#endif
- bool m_isWorldObject;
uint32 LastUsedScriptID;
// Transports
@@ -830,6 +832,7 @@ class WorldObject : public Object, public WorldLocation
protected:
std::string m_name;
bool m_isActive;
+ const bool m_isWorldObject;
ZoneScript* m_zoneScript;
// transports
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp
index a2aba642048..b1ad0c84fad 100755
--- a/src/server/game/Entities/Object/Updates/UpdateData.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp
@@ -25,7 +25,7 @@
#include "World.h"
#include "zlib.h"
-UpdateData::UpdateData(uint16 map) : m_blockCount(0), m_map(map)
+UpdateData::UpdateData(uint16 map) : m_map(map), m_blockCount(0)
{
}
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index afc94880812..6a42a0e4b3a 100755
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -33,7 +33,7 @@
#define PET_XP_FACTOR 0.05f
-Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner),
+Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner, true),
m_usedTalentCount(0), m_removed(false), m_owner(owner),
m_petType(type), m_duration(0),
m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL)
@@ -50,8 +50,6 @@ m_auraRaidUpdateMask(0), m_loading(false), m_declinedname(NULL)
m_name = "Pet";
m_regenTimer = PET_FOCUS_REGEN_INTERVAL;
-
- m_isWorldObject = true;
}
Pet::~Pet()
@@ -1205,24 +1203,29 @@ void Pet::_SaveAuras(SQLTransaction& trans)
}
}
-bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
+bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
// do pet spell book cleanup
if (state == PETSPELL_UNCHANGED) // spell load case
{
- sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request, deleting for all pets in `pet_spell`.", spell_id);
- CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE spell = '%u'", spell_id);
+ sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request, deleting for all pets in `pet_spell`.", spellId);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_PET_SPELL);
+
+ stmt->setUInt32(0, spellId);
+
+ CharacterDatabase.Execute(stmt);
}
else
- sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request.", spell_id);
+ sLog->outError("Pet::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
return false;
}
- PetSpellMap::iterator itr = m_spells.find(spell_id);
+ PetSpellMap::iterator itr = m_spells.find(spellId);
if (itr != m_spells.end())
{
if (itr->second.state == PETSPELL_REMOVED)
@@ -1261,7 +1264,7 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe
newspell.active = active;
// talent: unlearn all other talent ranks (high and low)
- if (TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
+ if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
{
@@ -1269,7 +1272,7 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[i];
- if (!rankSpellId || rankSpellId == spell_id)
+ if (!rankSpellId || rankSpellId == spellId)
continue;
// skip unknown ranks
@@ -1310,17 +1313,17 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe
}
}
- m_spells[spell_id] = newspell;
+ m_spells[spellId] = newspell;
if (spellInfo->IsPassive() && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState))))
- CastSpell(this, spell_id, true);
+ CastSpell(this, spellId, true);
else
m_charmInfo->AddSpellToActionBar(spellInfo);
if (newspell.active == ACT_ENABLED)
ToggleAutocast(spellInfo, true);
- uint32 talentCost = GetTalentSpellCost(spell_id);
+ uint32 talentCost = GetTalentSpellCost(spellId);
if (talentCost)
{
int32 free_points = GetMaxTalentPointsForLevel(getLevel());
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 96ff2835604..18ce1221178 100755
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -181,7 +181,7 @@ class Pet : public Guardian
void _LoadSpells();
void _SaveSpells(SQLTransaction& trans);
- bool addSpell(uint32 spell_id, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
+ bool addSpell(uint32 spellId, ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id);
void learnSpellHighRank(uint32 spellid);
void InitLevelupSpellsForLevel();
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e1494a094c4..ce0b4667e9b 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -630,7 +630,7 @@ UpdateMask Player::updateVisualBits;
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
-Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputationMgr(this)
+Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -842,7 +842,6 @@ Player::Player (WorldSession* session): Unit(), m_achievementMgr(this), m_reputa
m_grantableLevels = 0;
m_ControlledByPlayer = true;
- m_isWorldObject = true;
sWorld->IncreasePlayerCount();
@@ -1844,7 +1843,7 @@ void Player::setDeathState(DeathState s)
//clear aura case after resurrection by another way (spells will be applied before next death)
SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
}
-bool Player::BuildEnumData(QueryResult result, ByteBuffer* data)
+bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* data)
{
// 0 1 2 3 4 5 6 7
// "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
@@ -1865,7 +1864,7 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data)
uint32 playerBytes = fields[5].GetUInt32();
uint32 playerFlags = fields[14].GetUInt32();
uint32 atLoginFlags = fields[15].GetUInt32();
- uint32 zone = fields[8].GetUInt32();
+ uint32 zone = fields[8].GetUInt16();
uint32 petDisplayId = 0;
uint32 petLevel = 0;
uint32 petFamily = 0;
@@ -3454,19 +3453,24 @@ void Player::AddNewMailDeliverTime(time_t deliver_time)
}
}
-bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
+bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spell_id);
- CharacterDatabase.PExecute("DELETE FROM character_talent WHERE spell = '%u'", spell_id);
+ sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
+
+ stmt->setUInt32(0, spellId);
+
+ CharacterDatabase.Execute(stmt);
}
else
- sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spell_id);
+ sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
return false;
}
@@ -3476,19 +3480,24 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- sLog->outError("Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spell_id);
- CharacterDatabase.PExecute("DELETE FROM character_talent WHERE spell = '%u'", spell_id);
+ sLog->outError("Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spellId);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
+
+ stmt->setUInt32(0, spellId);
+
+ CharacterDatabase.Execute(stmt);
}
else
- sLog->outError("Player::addTalent: Broken spell #%u learning not allowed.", spell_id);
+ sLog->outError("Player::addTalent: Broken spell #%u learning not allowed.", spellId);
return false;
}
- PlayerTalentMap::iterator itr = m_talents[spec]->find(spell_id);
+ PlayerTalentMap::iterator itr = m_talents[spec]->find(spellId);
if (itr != m_talents[spec]->end())
itr->second->state = PLAYERSPELL_UNCHANGED;
- else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
+ else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
{
@@ -3496,7 +3505,7 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[rank];
- if (!rankSpellId || rankSpellId == spell_id)
+ if (!rankSpellId || rankSpellId == spellId)
continue;
itr = m_talents[spec]->find(rankSpellId);
@@ -3511,25 +3520,30 @@ bool Player::AddTalent(uint32 spell_id, uint8 spec, bool learning)
newtalent->state = state;
newtalent->spec = spec;
- (*m_talents[spec])[spell_id] = newtalent;
+ (*m_talents[spec])[spellId] = newtalent;
return true;
}
return false;
}
-bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled, bool loading /*=false*/)
+bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spell_id);
- CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'", spell_id);
+ sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
+
+ stmt->setUInt32(0, spellId);
+
+ CharacterDatabase.Execute(stmt);
}
else
- sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spell_id);
+ sLog->outError("Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId);
return false;
}
@@ -3539,11 +3553,16 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
// do character spell book cleanup (all characters)
if (!IsInWorld() && !learning) // spell load case
{
- sLog->outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spell_id);
- CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'", spell_id);
+ sLog->outError("Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spellId);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL);
+
+ stmt->setUInt32(0, spellId);
+
+ CharacterDatabase.Execute(stmt);
}
else
- sLog->outError("Player::addSpell: Broken spell #%u learning not allowed.", spell_id);
+ sLog->outError("Player::addSpell: Broken spell #%u learning not allowed.", spellId);
return false;
}
@@ -3554,18 +3573,18 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
bool disabled_case = false;
bool superceded_old = false;
- PlayerSpellMap::iterator itr = m_spells.find(spell_id);
+ PlayerSpellMap::iterator itr = m_spells.find(spellId);
// Remove temporary spell if found to prevent conflicts
if (itr != m_spells.end() && itr->second->state == PLAYERSPELL_TEMPORARY)
- RemoveTemporarySpell(spell_id);
+ RemoveTemporarySpell(spellId);
else if (itr != m_spells.end())
{
uint32 next_active_spell_id = 0;
// fix activate state for non-stackable low rank (and find next spell for !active case)
if (!spellInfo->IsStackableWithRanks() && spellInfo->IsRanked())
{
- if (uint32 next = sSpellMgr->GetNextSpellInChain(spell_id))
+ if (uint32 next = sSpellMgr->GetNextSpellInChain(spellId))
{
if (HasSpell(next))
{
@@ -3608,7 +3627,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if (active)
{
if (spellInfo->IsPassive() && IsNeedCastPassiveSpellAtLearn(spellInfo))
- CastSpell (this, spell_id, true);
+ CastSpell (this, spellId, true);
}
else if (IsInWorld())
{
@@ -3616,14 +3635,14 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
{
// update spell ranks in spellbook and action bar
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
- data << uint32(spell_id);
+ data << uint32(spellId);
data << uint32(next_active_spell_id);
GetSession()->SendPacket(&data);
}
else
{
WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint32(spell_id);
+ data << uint32(spellId);
GetSession()->SendPacket(&data);
}
}
@@ -3667,7 +3686,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if (!disabled_case) // skip new spell adding if spell already known (disabled spells case)
{
// talent: unlearn all other talent ranks (high and low)
- if (TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
+ if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
{
@@ -3675,7 +3694,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
{
// skip learning spell and no rank spell case
uint32 rankSpellId = talentInfo->RankID[rank];
- if (!rankSpellId || rankSpellId == spell_id)
+ if (!rankSpellId || rankSpellId == spellId)
continue;
removeSpell(rankSpellId, false, false);
@@ -3683,7 +3702,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
}
}
// non talent spell: learn low ranks (recursive call)
- else if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spell_id))
+ else if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spellId))
{
if (!IsInWorld() || disabled) // at spells loading, no output, but allow save
addSpell(prev_spell, active, true, true, disabled);
@@ -3716,7 +3735,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
data << uint32(itr2->first);
- data << uint32(spell_id);
+ data << uint32(spellId);
GetSession()->SendPacket(&data);
}
@@ -3731,7 +3750,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
if (IsInWorld()) // not send spell (re-/over-)learn packets at loading
{
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
- data << uint32(spell_id);
+ data << uint32(spellId);
data << uint32(itr2->first);
GetSession()->SendPacket(&data);
}
@@ -3746,31 +3765,31 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
}
}
- m_spells[spell_id] = newspell;
+ m_spells[spellId] = newspell;
// return false if spell disabled
if (newspell->disabled)
return false;
}
- uint32 talentCost = GetTalentSpellCost(spell_id);
+ uint32 talentCost = GetTalentSpellCost(spellId);
// cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned)
// note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive
if (!loading && talentCost > 0 && spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
{
// ignore stance requirement for talent learn spell (stance set for spell only for client spell description show)
- CastSpell(this, spell_id, true);
+ CastSpell(this, spellId, true);
}
// also cast passive spells (including all talents without SPELL_EFFECT_LEARN_SPELL) with additional checks
else if (spellInfo->IsPassive())
{
if (IsNeedCastPassiveSpellAtLearn(spellInfo))
- CastSpell(this, spell_id, true);
+ CastSpell(this, spellId, true);
}
else if (spellInfo->HasEffect(SPELL_EFFECT_SKILL_STEP))
{
- CastSpell(this, spell_id, true);
+ CastSpell(this, spellId, true);
return false;
}
@@ -3787,9 +3806,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
// add dependent skills
uint16 maxskill = GetMaxSkillValueForLevel();
- SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spell_id);
+ SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spellId);
- SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spell_id);
+ SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellId);
if (spellLearnSkill)
{
@@ -3847,7 +3866,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
}
// learn dependent spells
- SpellLearnSpellMapBounds spell_bounds = sSpellMgr->GetSpellLearnSpellMapBounds(spell_id);
+ SpellLearnSpellMapBounds spell_bounds = sSpellMgr->GetSpellLearnSpellMapBounds(spellId);
for (SpellLearnSpellMap::const_iterator itr2 = spell_bounds.first; itr2 != spell_bounds.second; ++itr2)
{
@@ -3869,7 +3888,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS, _spell_idx->second->skillId);
}
- GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spell_id);
+ GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL, spellId);
}
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
@@ -4959,8 +4978,14 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame
case CHAR_DELETE_UNLINK:
- CharacterDatabase.PExecute("UPDATE characters SET deleteInfos_Name=name, deleteInfos_Account=account, deleteDate='" UI64FMTD "', name='', account=0 WHERE guid=%u", uint64(time(NULL)), guid);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_DELETE_INFO);
+
+ stmt->setUInt32(0, guid);
+
+ CharacterDatabase.Execute(stmt);
break;
+ }
default:
sLog->outError("Player::DeleteFromDB: Unsupported delete method: %u.", charDelete_method);
}
@@ -5880,11 +5905,13 @@ float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
float Player::OCTRegenHPPerSpirit()
{
+ /*
uint8 level = getLevel();
uint32 pclass = getClass();
if (level > GT_MAX_LEVEL)
level = GT_MAX_LEVEL;
+ */
// Formula from PaperDollFrame script
float spirit = GetStat(STAT_SPIRIT);
@@ -7454,7 +7481,14 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)
zone = sMapMgr->GetZoneId(map, posx, posy, posz);
if (zone > 0)
- CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ZONE);
+
+ stmt->setUInt16(0, uint16(zone));
+ stmt->setUInt32(1, guidLow);
+
+ CharacterDatabase.Execute(stmt);
+ }
}
return zone;
@@ -12337,7 +12371,13 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
DestroyItem(slot, i, update);
if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
- CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
+
+ stmt->setUInt32(0, pItem->GetGUIDLow());
+
+ CharacterDatabase.Execute(stmt);
+ }
RemoveEnchantmentDurations(pItem);
RemoveItemDurations(pItem);
@@ -16491,7 +16531,13 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
if (ObjectMgr::CheckPlayerName(m_name) != CHAR_NAME_SUCCESS ||
(AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && sObjectMgr->IsReservedName(m_name)))
{
- CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid ='%u'", uint32(AT_LOGIN_RENAME), guid);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_AT_LOGIN_FLAG);
+
+ stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
+ stmt->setUInt32(1, guid);
+
+ CharacterDatabase.Execute(stmt);
+
return false;
}
@@ -17507,29 +17553,33 @@ void Player::_LoadMailedItems(Mail* mail)
{
Field* fields = result->Fetch();
- uint32 item_guid_low = fields[11].GetUInt32();
- uint32 item_template = fields[12].GetUInt32();
+ uint32 itemGuid = fields[11].GetUInt32();
+ uint32 itemTemplate = fields[12].GetUInt32();
- mail->AddItem(item_guid_low, item_template);
+ mail->AddItem(itemGuid, itemTemplate);
- ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item_template);
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemTemplate);
if (!proto)
{
- sLog->outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), item_guid_low, item_template, mail->messageID);
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
+ sLog->outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), itemGuid, itemTemplate, mail->messageID);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM);
+ stmt->setUInt32(0, itemGuid);
+ CharacterDatabase.Execute(stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
- stmt->setUInt32(0, item_guid_low);
+ stmt->setUInt32(0, itemGuid);
CharacterDatabase.Execute(stmt);
continue;
}
Item* item = NewItemOrBag(proto);
- if (!item->LoadFromDB(item_guid_low, MAKE_NEW_GUID(fields[13].GetUInt32(), 0, HIGHGUID_PLAYER), fields, item_template))
+ if (!item->LoadFromDB(itemGuid, MAKE_NEW_GUID(fields[13].GetUInt32(), 0, HIGHGUID_PLAYER), fields, itemTemplate))
{
- sLog->outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);
- CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
+ sLog->outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, itemGuid);
+ CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", itemGuid);
item->FSetState(ITEM_REMOVED);
SQLTransaction temp = SQLTransaction(NULL);
@@ -20208,7 +20258,7 @@ bool Player::ActivateTaxiPathTo(uint32 taxi_path_id, uint32 spellid /*= 0*/)
void Player::CleanupAfterTaxiFlight()
{
m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
- Unmount();
+ Dismount();
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
getHostileRefManager().setOnlineOfflineState(true);
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 40c14055a31..e1cee49db76 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1122,7 +1122,7 @@ class Player : public Unit, public GridObject<Player>
void Update(uint32 time);
- static bool BuildEnumData(QueryResult result, ByteBuffer* data);
+ static bool BuildEnumData(PreparedQueryResult result, ByteBuffer* data);
void SetInWater(bool apply);
@@ -1665,7 +1665,7 @@ class Player : public Unit, public GridObject<Player>
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask);
void SendInitialSpells();
- bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled, bool loading = false);
+ bool addSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false);
void learnSpell(uint32 spell_id, bool dependent);
void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true);
void resetSpells(bool myClassOnly = false);
@@ -1689,7 +1689,7 @@ class Player : public Unit, public GridObject<Player>
void LearnTalent(uint32 talentId, uint32 talentRank);
void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank);
- bool AddTalent(uint32 spell, uint8 spec, bool learning);
+ bool AddTalent(uint32 spellId, uint8 spec, bool learning);
bool HasTalent(uint32 spell_id, uint8 spec) const;
uint32 CalculateTalentsPoints() const;
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 97629e802d4..fc368b1f109 100755
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -25,7 +25,7 @@
#include "SpellMgr.h"
#include "SpellInfo.h"
-Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner)
+Totem::Totem(SummonPropertiesEntry const* properties, Unit* owner) : Minion(properties, owner, false)
{
m_unitTypeMask |= UNIT_MASK_TOTEM;
m_duration = 0;
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 47ac5d57e00..e445f405bbf 100755
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -633,7 +633,8 @@ void Transport::BuildStopMovePacket(Map const* targetMap)
uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim)
{
Map* map = GetMap();
- Creature* creature = new Creature;
+ //make it world object so it will not be unloaded with grid
+ Creature* creature = new Creature(true);
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, GetPhaseMask(), entry, 0, GetGOInfo()->faction, 0, 0, 0, 0))
{
@@ -666,7 +667,6 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
map->AddToMap(creature);
m_NPCPassengerSet.insert(creature);
- creature->SetWorldObject(true); //so it will not be unloaded with grid
if (tguid == 0)
{
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index c73850d44c2..66f690e8bed 100755
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -281,12 +281,10 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
uint16 index = UNIT_FIELD_ATTACK_POWER;
- uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
if (ranged)
{
index = UNIT_FIELD_RANGED_ATTACK_POWER;
- index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
switch (getClass())
{
@@ -392,7 +390,6 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
attPowerMod += int32(GetArmor() / (*iter)->GetAmount());
}
- float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
Pet* pet = GetPet(); //update pet's AP
@@ -932,7 +929,6 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
}
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
@@ -1283,7 +1279,6 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 4f0dd7697eb..05a4420e16b 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -144,7 +144,7 @@ _hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo)
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
-Unit::Unit(): WorldObject(),
+Unit::Unit(bool isWorldObject): WorldObject(isWorldObject),
m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false),
m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0),
m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL),
@@ -11967,7 +11967,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
}
-void Unit::Unmount()
+void Unit::Dismount()
{
if (!IsMounted())
return;
@@ -11988,7 +11988,7 @@ void Unit::Unmount()
data.appendPackGUID(GetGUID());
SendMessageToSet(&data, true);
- // unmount as a vehicle
+ // dismount as a vehicle
if (GetTypeId() == TYPEID_PLAYER && GetVehicleKit())
{
// Send other players that we are no longer a vehicle
@@ -12110,7 +12110,7 @@ void Unit::SetInCombatState(bool PvP, Unit* enemy)
}
if (!(creature->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_MOUNTED_COMBAT))
- Unmount();
+ Dismount();
}
for (Unit::ControlList::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
@@ -14369,6 +14369,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (procTriggered.empty())
return;
+ // Note: must SetCantProc(false) before return
if (procExtra & (PROC_EX_INTERNAL_TRIGGERED | PROC_EX_INTERNAL_CANT_PROC))
SetCantProc(true);
@@ -14393,6 +14394,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (GetTypeId() == TYPEID_PLAYER && i->spellProcEvent && i->spellProcEvent->cooldown)
cooldown = i->spellProcEvent->cooldown;
+ // Note: must SetCantProc(false) before return
if (spellInfo->AttributesEx3 & SPELL_ATTR3_DISABLE_PROC)
SetCantProc(true);
@@ -14405,176 +14407,179 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
}
if (!handled)
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
- if (!(i->effMask & (1<<effIndex)))
- continue;
-
- AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
- ASSERT(triggeredByAura);
-
- switch (triggeredByAura->GetAuraType())
+ for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
- case SPELL_AURA_PROC_TRIGGER_SPELL:
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- // Don`t drop charge or add cooldown for not started trigger
- if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
- break;
- }
- case SPELL_AURA_PROC_TRIGGER_DAMAGE:
- {
- // target has to be valid
- if (!target)
- return;
-
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
- uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
- CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
- DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
- SendSpellNonMeleeDamageLog(&damageInfo);
- DealSpellDamage(&damageInfo, true);
- takeCharges = true;
- break;
- }
- case SPELL_AURA_MANA_SHIELD:
- case SPELL_AURA_DUMMY:
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
- break;
- }
- case SPELL_AURA_OBS_MOD_POWER:
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
- break;
- case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
- break;
- case SPELL_AURA_MOD_MELEE_HASTE:
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
- break;
- }
- case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
- takeCharges = true;
- break;
- }
- case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (!(i->effMask & (1<<effIndex)))
+ continue;
- HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
- takeCharges = true;
- break;
- }
- case SPELL_AURA_RAID_PROC_FROM_CHARGE:
- {
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
- (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ AuraEffect* triggeredByAura = i->aura->GetEffect(effIndex);
+ ASSERT(triggeredByAura);
- HandleAuraRaidProcFromCharge(triggeredByAura);
- takeCharges = true;
- break;
- }
- case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
+ switch (triggeredByAura->GetAuraType())
{
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ case SPELL_AURA_PROC_TRIGGER_SPELL:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ // Don`t drop charge or add cooldown for not started trigger
+ if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ }
+ case SPELL_AURA_PROC_TRIGGER_DAMAGE:
+ {
+ // target has to be valid
+ if (!target)
+ break;
- if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
- break;
- }
- case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
- // Skip melee hits or instant cast spells
- if (procSpell && procSpell->CalcCastTime() != 0)
- takeCharges = true;
- break;
- case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
- // Skip Melee hits and spells ws wrong school
- if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
+ uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
+ CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
+ DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ SendSpellNonMeleeDamageLog(&damageInfo);
+ DealSpellDamage(&damageInfo, true);
takeCharges = true;
- break;
- case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
- case SPELL_AURA_MOD_POWER_COST_SCHOOL:
- // Skip melee hits and spells ws wrong school or zero cost
- if (procSpell &&
- (procSpell->ManaCost != 0 || procSpell->ManaCostPercentage != 0) && // Cost check
- (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
- takeCharges = true;
- break;
- case SPELL_AURA_MECHANIC_IMMUNITY:
- // Compare mechanic
- if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
- takeCharges = true;
- break;
- case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
- // Compare mechanic
- if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
- takeCharges = true;
- break;
- case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
- // Compare casters
- if (triggeredByAura->GetCasterGUID() == target->GetGUID())
- takeCharges = true;
- break;
- case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
- sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ break;
+ }
+ case SPELL_AURA_MANA_SHIELD:
+ case SPELL_AURA_DUMMY:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s dummy aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (HandleDummyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ }
+ case SPELL_AURA_OBS_MOD_POWER:
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (HandleObsModEnergyAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (HandleModDamagePctTakenAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MOD_MELEE_HASTE:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s haste aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (HandleHasteAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ }
+ case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (HandleOverrideClassScriptAuraProc(target, damage, triggeredByAura, procSpell, cooldown))
+ takeCharges = true;
+ break;
+ }
+ case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+
+ HandleAuraRaidProcFromChargeWithValue(triggeredByAura);
takeCharges = true;
- break;
- // CC Auras which use their amount amount to drop
- // Are there any more auras which need this?
- case SPELL_AURA_MOD_CONFUSE:
- case SPELL_AURA_MOD_FEAR:
- case SPELL_AURA_MOD_STUN:
- case SPELL_AURA_MOD_ROOT:
- case SPELL_AURA_TRANSFORM:
- {
- // chargeable mods are breaking on hit
- if (useCharges)
+ break;
+ }
+ case SPELL_AURA_RAID_PROC_FROM_CHARGE:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)",
+ (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+
+ HandleAuraRaidProcFromCharge(triggeredByAura);
takeCharges = true;
- else
+ break;
+ }
+ case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
+ {
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell %u (triggered with value by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+
+ if (HandleProcTriggerSpell(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ }
+ case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
+ // Skip melee hits or instant cast spells
+ if (procSpell && procSpell->CalcCastTime() != 0)
+ takeCharges = true;
+ break;
+ case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
+ // Skip Melee hits and spells ws wrong school
+ if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
+ case SPELL_AURA_MOD_POWER_COST_SCHOOL:
+ // Skip melee hits and spells ws wrong school or zero cost
+ if (procSpell &&
+ (procSpell->ManaCost != 0 || procSpell->ManaCostPercentage != 0) && // Cost check
+ (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MECHANIC_IMMUNITY:
+ // Compare mechanic
+ if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MOD_MECHANIC_RESISTANCE:
+ // Compare mechanic
+ if (procSpell && procSpell->Mechanic == uint32(triggeredByAura->GetMiscValue()))
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MOD_DAMAGE_FROM_CASTER:
+ // Compare casters
+ if (triggeredByAura->GetCasterGUID() == target->GetGUID())
+ takeCharges = true;
+ break;
+ case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
+ sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
+ if (procSpell && HandleSpellCritChanceAuraProc(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
+ takeCharges = true;
+ break;
+ // CC Auras which use their amount amount to drop
+ // Are there any more auras which need this?
+ case SPELL_AURA_MOD_CONFUSE:
+ case SPELL_AURA_MOD_FEAR:
+ case SPELL_AURA_MOD_STUN:
+ case SPELL_AURA_MOD_ROOT:
+ case SPELL_AURA_TRANSFORM:
{
- // Spell own direct damage at apply wont break the CC
- if (procSpell && (procSpell->Id == triggeredByAura->GetId()))
+ // chargeable mods are breaking on hit
+ if (useCharges)
+ takeCharges = true;
+ else
{
- Aura* aura = triggeredByAura->GetBase();
- // called from spellcast, should not have ticked yet
- if (aura->GetDuration() == aura->GetMaxDuration())
- break;
+ // Spell own direct damage at apply wont break the CC
+ if (procSpell && (procSpell->Id == triggeredByAura->GetId()))
+ {
+ Aura* aura = triggeredByAura->GetBase();
+ // called from spellcast, should not have ticked yet
+ if (aura->GetDuration() == aura->GetMaxDuration())
+ break;
+ }
+ int32 damageLeft = triggeredByAura->GetAmount();
+ // No damage left
+ if (damageLeft < int32(damage))
+ i->aura->Remove();
+ else
+ triggeredByAura->SetAmount(damageLeft - damage);
}
- int32 damageLeft = triggeredByAura->GetAmount();
- // No damage left
- if (damageLeft < int32(damage))
- i->aura->Remove();
- else
- triggeredByAura->SetAmount(damageLeft - damage);
+ break;
}
- break;
- }
- //case SPELL_AURA_ADD_FLAT_MODIFIER:
- //case SPELL_AURA_ADD_PCT_MODIFIER:
- // HandleSpellModAuraProc
- //break;
- default:
- // nothing do, just charges counter
- takeCharges = true;
- break;
- }
- }
+ //case SPELL_AURA_ADD_FLAT_MODIFIER:
+ //case SPELL_AURA_ADD_PCT_MODIFIER:
+ // HandleSpellModAuraProc
+ //break;
+ default:
+ // nothing do, just charges counter
+ takeCharges = true;
+ break;
+ } // switch (triggeredByAura->GetAuraType())
+ } // for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ } // if (!handled)
+
// Remove charge (aura can be removed by triggers)
if (useCharges && takeCharges)
i->aura->DropCharge(AURA_REMOVE_BY_EXPIRE);
@@ -15908,9 +15913,9 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
if (!charmer)
return false;
- // unmount players when charmed
+ // dismount players when charmed
if (GetTypeId() == TYPEID_PLAYER)
- Unmount();
+ Dismount();
ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
ASSERT((type == CHARM_TYPE_VEHICLE) == IsVehicle());
@@ -17056,7 +17061,7 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
InterruptNonMeleeSpells(false);
player->StopCastingCharm();
player->StopCastingBindSight();
- Unmount();
+ Dismount();
RemoveAurasByType(SPELL_AURA_MOUNTED);
// drop flag at invisible in bg
@@ -17156,7 +17161,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
// Vehicle just died, we die too
if (vehicle->GetBase()->getDeathState() == JUST_DIED)
setDeathState(JUST_DIED);
- // If for other reason we as minion are exiting the vehicle (ejected, master unmounted) - unsummon
+ // If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
else
ToTempSummon()->UnSummon(2000); // Approximation
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 951682cc5ee..3254a03b79a 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -66,7 +66,7 @@ enum SpellAuraInterruptFlags
AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement
AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning
AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat
- AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by unmounting
+ AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by dismounting
AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water
AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water
AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing
@@ -1443,7 +1443,7 @@ class Unit : public WorldObject
bool IsMounted() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT); }
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0);
- void Unmount();
+ void Dismount();
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
void DealDamageMods(Unit* pVictim, uint32 &damage, uint32* absorb);
@@ -2235,7 +2235,7 @@ class Unit : public WorldObject
}
protected:
- explicit Unit ();
+ explicit Unit (bool isWorldObject);
UnitAI* i_AI, *i_disabledAI;
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 00e67dc3507..020fcc2531e 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -5217,7 +5217,7 @@ void ObjectMgr::LoadInstanceEncounters()
{
if (itr != dungeonLastBosses.end())
{
- sLog->outErrorDb("Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName, itr->second->id, itr->second->encounterName[0]);
+ sLog->outErrorDb("Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName, itr->second->id, itr->second->encounterName);
continue;
}
@@ -6795,9 +6795,15 @@ void ObjectMgr::LoadCorpses()
{
Field* fields = result->Fetch();
uint32 guid = fields[16].GetUInt32();
+ CorpseType type = CorpseType(fields[13].GetUInt8());
+ if (type >= MAX_CORPSE_TYPE)
+ {
+ sLog->outError("Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type);
+ continue;
+ }
- Corpse* corpse = new Corpse();
- if (!corpse->LoadFromDB(guid, fields))
+ Corpse* corpse = new Corpse(type);
+ if (!corpse->LoadCorpseFromDB(guid, fields))
{
delete corpse;
continue;
diff --git a/src/server/game/Grids/Grid.h b/src/server/game/Grids/Grid.h
index 448c4cb35fd..7e66cf1080a 100755
--- a/src/server/game/Grids/Grid.h
+++ b/src/server/game/Grids/Grid.h
@@ -100,7 +100,12 @@ class Grid
/** Returns the number of object within the grid.
*/
- unsigned int ActiveObjectsInGrid(void) const { return /*m_activeGridObjects.size()+*/i_objects.template Count<ACTIVE_OBJECT>(); }
+ //unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count<ACTIVE_OBJECT>(); }
+ template<class T>
+ uint32 GetWorldObjectCountInGrid() const
+ {
+ return i_objects.template Count<T>();
+ }
/** Inserts a container type object into the grid.
*/
diff --git a/src/server/game/Grids/GridStates.cpp b/src/server/game/Grids/GridStates.cpp
index 5f88516c9ac..4e63388c356 100755
--- a/src/server/game/Grids/GridStates.cpp
+++ b/src/server/game/Grids/GridStates.cpp
@@ -31,7 +31,7 @@ void ActiveState::Update(Map &m, NGridType &grid, GridInfo & info, const uint32
info.UpdateTimeTracker(t_diff);
if (info.getTimeTracker().Passed())
{
- if (grid.ActiveObjectsInGrid() == 0 && !m.ActiveObjectsNearGrid(grid))
+ if (!grid.GetWorldObjectCountInNGrid<Player>() && !m.ActiveObjectsNearGrid(grid))
{
ObjectGridStoper worker;
TypeContainerVisitor<ObjectGridStoper, GridTypeMapContainer> visitor(worker);
diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h
index 97a47f7d272..c87fd7e6129 100755
--- a/src/server/game/Grids/NGrid.h
+++ b/src/server/game/Grids/NGrid.h
@@ -158,14 +158,28 @@ class NGrid
GetGridType(x, y).Visit(visitor);
}
- unsigned int ActiveObjectsInGrid(void) const
+ //This gets the player count in grid
+ //I disable this to avoid confusion (active object usually means something else)
+ /*
+ uint32 GetActiveObjectCountInGrid() const
{
- unsigned int count=0;
- for (unsigned int x=0; x < N; ++x)
- for (unsigned int y=0; y < N; ++y)
+ uint32 count = 0;
+ for (uint32 x = 0; x < N; ++x)
+ for (uint32 y = 0; y < N; ++y)
count += i_cells[x][y].ActiveObjectsInGrid();
return count;
}
+ */
+
+ template<class T>
+ uint32 GetWorldObjectCountInNGrid() const
+ {
+ uint32 count = 0;
+ for (uint32 x = 0; x < N; ++x)
+ for (uint32 y = 0; y < N; ++y)
+ count += i_cells[x][y].template GetWorldObjectCountInGrid<T>();
+ return count;
+ }
private:
uint32 i_gridId;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index ca61a82e840..99d402b4add 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -344,7 +344,7 @@ bool AnyDeadUnitObjectInRangeCheck::operator()(Creature* u)
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Player* u)
{
return AnyDeadUnitObjectInRangeCheck::operator()(u)
- && i_spellInfo->CheckTarget(i_searchObj, u, true)
+ && (i_spellInfo->CheckTarget(i_searchObj, u, true) == SPELL_CAST_OK)
&& i_searchObj->IsTargetMatchingCheck(u, i_check);
}
@@ -352,14 +352,14 @@ bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Corpse* u)
{
Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID());
return owner && AnyDeadUnitObjectInRangeCheck::operator()(u)
- && i_spellInfo->CheckTarget(i_searchObj, owner, true)
+ && (i_spellInfo->CheckTarget(i_searchObj, owner, true) == SPELL_CAST_OK)
&& i_searchObj->IsTargetMatchingCheck(owner, i_check);
}
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
{
return AnyDeadUnitObjectInRangeCheck::operator()(u)
- && i_spellInfo->CheckTarget(i_searchObj, u, true)
+ && (i_spellInfo->CheckTarget(i_searchObj, u, true) == SPELL_CAST_OK)
&& i_searchObj->IsTargetMatchingCheck(u, i_check);
}
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index bdabc7a4bcc..0e9cf082573 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -43,7 +43,7 @@ namespace Trinity
std::set<Unit*> i_visibleNow;
Player::ClientGUIDs vis_guids;
- VisibleNotifier(Player &player) : i_player(player), vis_guids(player.m_clientGUIDs), i_data(player.GetMapId()) {}
+ VisibleNotifier(Player &player) : i_player(player), i_data(player.GetMapId()), vis_guids(player.m_clientGUIDs) {}
template<class T> void Visit(GridRefManager<T> &m);
void SendToSelf(void);
};
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 459cbc73623..39951e0c6c7 100755
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -123,12 +123,30 @@ bool Group::Create(Player* leader)
sGroupMgr->RegisterGroupDbStoreId(m_dbStoreId, this);
- // store group in database
- CharacterDatabase.PExecute("INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty) "
- "VALUES ('%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '" UI64FMTD "', '%u', '%u', '%u')",
- m_dbStoreId, GUID_LOPART(m_leaderGuid), uint32(m_lootMethod),
- GUID_LOPART(m_looterGuid), uint32(m_lootThreshold), m_targetIcons[0], m_targetIcons[1], m_targetIcons[2], m_targetIcons[3], m_targetIcons[4], m_targetIcons[5], m_targetIcons[6],
- m_targetIcons[7], uint8(m_groupType), uint32(m_dungeonDifficulty), m_raidDifficulty);
+ // Store group in database
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GROUP);
+
+ uint8 index = 0;
+
+ stmt->setUInt32(index++, m_dbStoreId);
+ stmt->setUInt32(index++, GUID_LOPART(m_leaderGuid));
+ stmt->setUInt8(index++, uint8(m_lootMethod));
+ stmt->setUInt32(index++, GUID_LOPART(m_looterGuid));
+ stmt->setUInt8(index++, uint8(m_lootThreshold));
+ stmt->setUInt32(index++, uint32(m_targetIcons[0]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[1]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[2]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[3]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[4]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[5]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[6]));
+ stmt->setUInt32(index++, uint32(m_targetIcons[7]));
+ stmt->setUInt8(index++, uint8(m_groupType));
+ stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
+ stmt->setUInt32(index++, uint8(m_raidDifficulty));
+
+ CharacterDatabase.Execute(stmt);
+
ASSERT(AddMember(leader)); // If the leader can't be added to a new group because it appears full, something is clearly wrong.
@@ -200,7 +218,15 @@ void Group::ConvertToLFG()
m_groupType = GroupType(m_groupType | GROUPTYPE_LFG | GROUPTYPE_UNK1);
m_lootMethod = NEED_BEFORE_GREED;
if (!isBGGroup())
- CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_dbStoreId);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_TYPE);
+
+ stmt->setUInt8(0, uint8(m_groupType));
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
+ }
+
SendUpdate();
}
@@ -211,7 +237,15 @@ void Group::ConvertToRaid()
_initRaidSubGroupsCounter();
if (!isBGGroup())
- CharacterDatabase.PExecute("UPDATE groups SET groupType='%u' WHERE guid='%u'", uint8(m_groupType), m_dbStoreId);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_TYPE);
+
+ stmt->setUInt8(0, uint8(m_groupType));
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
+ }
+
SendUpdate();
// update quest related GO states (quest activity dependent from raid membership)
@@ -343,8 +377,18 @@ bool Group::AddMember(Player* player)
// insert into the table if we're not a battleground group
if (!isBGGroup())
- CharacterDatabase.PExecute("INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(%u, %u, %u, %u, %u)",
- m_dbStoreId, GUID_LOPART(member.guid), member.flags, member.group, member.roles);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GROUP_MEMBER);
+
+ stmt->setUInt32(0, m_dbStoreId);
+ stmt->setUInt32(1, GUID_LOPART(member.guid));
+ stmt->setUInt8(2, member.flags);
+ stmt->setUInt8(3, member.group);
+ stmt->setUInt8(4, member.roles);
+
+ CharacterDatabase.Execute(stmt);
+
+ }
SendUpdate();
sScriptMgr->OnGroupAddMember(this, player->GetGUID());
@@ -435,7 +479,11 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
}
// Remove player from group in DB
- CharacterDatabase.PExecute("DELETE FROM group_member WHERE memberGuid=%u", GUID_LOPART(guid));
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER);
+
+ stmt->setUInt32(0, GUID_LOPART(guid));
+
+ CharacterDatabase.Execute(stmt);
// Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player)
@@ -530,14 +578,24 @@ void Group::ChangeLeader(uint64 guid)
}
// Same in the database
- CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = '%u'))",
- m_dbStoreId, player->GetGUIDLow());
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING);
+
+ stmt->setUInt32(0, m_dbStoreId);
+ stmt->setUInt32(1, player->GetGUIDLow());
+
+ CharacterDatabase.Execute(stmt);
// Copy the permanent binds from the new leader to the group
Player::ConvertInstancesToGroup(player, this, true);
- // update the group leader
- CharacterDatabase.PExecute("UPDATE groups SET leaderGuid='%u' WHERE guid='%u'", player->GetGUIDLow(), m_dbStoreId);
+ // Update the group leader
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_LEADER);
+
+ stmt->setUInt32(0, player->GetGUIDLow());
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
}
m_leaderGuid = player->GetGUID();
@@ -1322,7 +1380,14 @@ bool Group::_setMembersGroup(uint64 guid, uint8 group)
SubGroupCounterIncrease(group);
if (!isBGGroup())
- CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid));
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_MEMBER_SUBGROUP);
+
+ stmt->setUInt8(0, group);
+ stmt->setUInt32(1, GUID_LOPART(guid));
+
+ CharacterDatabase.Execute(stmt);
+ }
return true;
}
@@ -1366,7 +1431,14 @@ void Group::ChangeMembersGroup(uint64 guid, uint8 group)
// Preserve new sub group in database for non-raid groups
if (!isBGGroup())
- CharacterDatabase.PExecute("UPDATE group_member SET subgroup='%u' WHERE memberGuid='%u'", group, GUID_LOPART(guid));
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_MEMBER_SUBGROUP);
+
+ stmt->setUInt8(0, group);
+ stmt->setUInt32(1, GUID_LOPART(guid));
+
+ CharacterDatabase.Execute(stmt);
+ }
// In case the moved player is online, update the player object with the new sub group references
if (Player* player = ObjectAccessor::FindPlayer(guid))
@@ -1554,7 +1626,14 @@ void Group::SetDungeonDifficulty(Difficulty difficulty)
{
m_dungeonDifficulty = difficulty;
if (!isBGGroup())
- CharacterDatabase.PExecute("UPDATE groups SET difficulty = %u WHERE guid ='%u'", m_dungeonDifficulty, m_dbStoreId);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_DIFFICULTY);
+
+ stmt->setUInt8(0, uint8(m_dungeonDifficulty));
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
+ }
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1571,7 +1650,14 @@ void Group::SetRaidDifficulty(Difficulty difficulty)
{
m_raidDifficulty = difficulty;
if (!isBGGroup())
- CharacterDatabase.PExecute("UPDATE groups SET raiddifficulty = %u WHERE guid ='%u'", m_raidDifficulty, m_dbStoreId);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_RAID_DIFFICULTY);
+
+ stmt->setUInt8(0, uint8(m_raidDifficulty));
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
+ }
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1609,9 +1695,9 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
{
- InstanceSave* p = itr->second.save;
+ InstanceSave* instanceSave = itr->second.save;
const MapEntry* entry = sMapStore.LookupEntry(itr->first);
- if (!entry || entry->IsRaid() != isRaid || (!p->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
+ if (!entry || entry->IsRaid() != isRaid || (!instanceSave->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND))
{
++itr;
continue;
@@ -1629,10 +1715,10 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
bool isEmpty = true;
// if the map is loaded, reset it
- Map* map = sMapMgr->FindMap(p->GetMapId(), p->GetInstanceId());
- if (map && map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !p->CanReset()))
+ Map* map = sMapMgr->FindMap(instanceSave->GetMapId(), instanceSave->GetInstanceId());
+ if (map && map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !instanceSave->CanReset()))
{
- if (p->CanReset())
+ if (instanceSave->CanReset())
isEmpty = ((InstanceMap*)map)->Reset(method);
else
isEmpty = !map->HavePlayers();
@@ -1641,25 +1727,32 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
if (SendMsgTo)
{
if (isEmpty)
- SendMsgTo->SendResetInstanceSuccess(p->GetMapId());
+ SendMsgTo->SendResetInstanceSuccess(instanceSave->GetMapId());
else
- SendMsgTo->SendResetInstanceFailed(0, p->GetMapId());
+ SendMsgTo->SendResetInstanceFailed(0, instanceSave->GetMapId());
}
if (isEmpty || method == INSTANCE_RESET_GROUP_DISBAND || method == INSTANCE_RESET_CHANGE_DIFFICULTY)
{
// do not reset the instance, just unbind if others are permanently bound to it
- if (p->CanReset())
- p->DeleteFromDB();
+ if (instanceSave->CanReset())
+ instanceSave->DeleteFromDB();
else
- CharacterDatabase.PExecute("DELETE FROM group_instance WHERE instance = '%u'", p->GetInstanceId());
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE);
+
+ stmt->setUInt32(0, instanceSave->GetInstanceId());
+
+ CharacterDatabase.Execute(stmt);
+ }
+
// i don't know for sure if hash_map iterators
m_boundInstances[diff].erase(itr);
itr = m_boundInstances[diff].begin();
// this unloads the instance save unless online players are bound to it
// (eg. permanent binds or GM solo binds)
- p->RemoveGroup(this);
+ instanceSave->RemoveGroup(this);
}
else
++itr;
@@ -1712,7 +1805,15 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, boo
InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
if (!load && (!bind.save || permanent != bind.perm || save != bind.save))
- CharacterDatabase.PExecute("REPLACE INTO group_instance (guid, instance, permanent) VALUES (%u, %u, %u)", m_dbStoreId, save->GetInstanceId(), permanent);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_GROUP_INSTANCE);
+
+ stmt->setUInt32(0, m_dbStoreId);
+ stmt->setUInt32(1, save->GetInstanceId());
+ stmt->setBool(2, permanent);
+
+ CharacterDatabase.Execute(stmt);
+ }
if (bind.save != save)
{
@@ -1736,7 +1837,15 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload)
if (itr != m_boundInstances[difficulty].end())
{
if (!unload)
- CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u AND instance=%u", m_dbStoreId, itr->second.save->GetInstanceId());
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_INSTANCE_BY_GUID);
+
+ stmt->setUInt32(0, m_dbStoreId);
+ stmt->setUInt32(1, itr->second.save->GetInstanceId());
+
+ CharacterDatabase.Execute(stmt);
+ }
+
itr->second.save->RemoveGroup(this); // save can become invalid
m_boundInstances[difficulty].erase(itr);
}
@@ -1965,7 +2074,12 @@ void Group::SetGroupMemberFlag(uint64 guid, bool apply, GroupMemberFlags flag)
ToggleGroupMemberFlag(slot, flag, apply);
// Preserve the new setting in the db
- CharacterDatabase.PExecute("UPDATE group_member SET memberFlags='%u' WHERE memberGuid='%u'", slot->flags, GUID_LOPART(guid));
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GROUP_MEMBER_FLAG);
+
+ stmt->setUInt8(0, slot->flags);
+ stmt->setUInt32(0, GUID_LOPART(guid));
+
+ CharacterDatabase.Execute(stmt);
// Broadcast the changes to the group
SendUpdate();
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 7a2368161d8..9d5ffb6542a 100755
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -138,7 +138,14 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
{
// save the resettime for normal instances only when they get unloaded
if (time_t resettime = itr->second->GetResetTimeForDB())
- CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId);
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_INSTANCE_RESETTIME);
+
+ stmt->setUInt32(0, uint32(resettime));
+ stmt->setUInt32(1, InstanceId);
+
+ CharacterDatabase.Execute(stmt);
+ }
delete itr->second;
m_instanceSaveById.erase(itr);
@@ -573,13 +580,19 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
if (period < DAY)
period = DAY;
- uint64 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff;
+ uint32 next_reset = ((resetTime + MINUTE) / DAY * DAY) + period + diff;
SetResetTimeFor(mapid, difficulty, next_reset);
ScheduleReset(true, time_t(next_reset-3600), InstResetEvent(1, mapid, difficulty, 0));
- // update it in the DB
- CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '%u' WHERE mapid = '%d' AND difficulty = '%d'", uint32(next_reset), mapid, difficulty);
+ // Update it in the DB
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_GLOBAL_INSTANCE_RESETTIME);
+
+ stmt->setUInt32(0, next_reset);
+ stmt->setUInt16(1, uint16(mapid));
+ stmt->setUInt8(2, uint8(difficulty));
+
+ CharacterDatabase.Execute(stmt);
}
// note: this isn't fast but it's meant to be executed very rarely
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 46c0ca1d8f5..1b7afd36ca8 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -30,6 +30,7 @@
#include "MapManager.h"
#include "ObjectMgr.h"
#include "Group.h"
+#include "LFGMgr.h"
union u_map_magic
{
@@ -58,7 +59,7 @@ Map::~Map()
while (!i_worldObjects.empty())
{
WorldObject* obj = *i_worldObjects.begin();
- ASSERT(obj->m_isWorldObject);
+ ASSERT(obj->IsWorldObject());
//ASSERT(obj->GetTypeId() == TYPEID_CORPSE);
obj->RemoveFromWorld();
obj->ResetMap();
@@ -237,7 +238,7 @@ template<class T>
void Map::AddToGrid(T* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
- if (obj->m_isWorldObject)
+ if (obj->IsWorldObject())
grid->GetGridType(cell.CellX(), cell.CellY()).template AddWorldObject<T>(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).template AddGridObject<T>(obj);
@@ -247,7 +248,7 @@ template<>
void Map::AddToGrid(Creature* obj, Cell const& cell)
{
NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
- if (obj->m_isWorldObject)
+ if (obj->IsWorldObject())
grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
else
grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
@@ -255,9 +256,9 @@ void Map::AddToGrid(Creature* obj, Cell const& cell)
obj->SetCurrentCell(cell);
}
-template<class T>
-void Map::SwitchGridContainers(T* obj, bool on)
+void Map::SwitchGridContainers(Creature* obj, bool on)
{
+ ASSERT(!obj->IsPermanentWorldObject());
CellCoord p = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY());
if (!p.IsCoordValid())
{
@@ -277,15 +278,18 @@ void Map::SwitchGridContainers(T* obj, bool on)
obj->RemoveFromGrid(); //This step is not really necessary but we want to do ASSERT in remove/add
if (on)
- grid.AddWorldObject<T>(obj);
+ {
+ grid.AddWorldObject(obj);
+ AddWorldObject(obj);
+ }
else
- grid.AddGridObject<T>(obj);
- obj->m_isWorldObject = on;
+ {
+ grid.AddGridObject(obj);
+ RemoveWorldObject(obj);
+ }
+ obj->m_isTempWorldObject = on;
}
-template void Map::SwitchGridContainers(Creature*, bool);
-//template void Map::SwitchGridContainers(DynamicObject*, bool);
-
template<class T>
void Map::DeleteFromWorld(T* obj)
{
@@ -908,8 +912,15 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll)
const uint32 y = ngrid.getY();
{
- if (!unloadAll && ActiveObjectsNearGrid(ngrid))
- return false;
+ if (!unloadAll)
+ {
+ //pets, possessed creatures (must be active), transport passengers
+ if (ngrid.GetWorldObjectCountInNGrid<Creature>())
+ return false;
+
+ if (ActiveObjectsNearGrid(ngrid))
+ return false;
+ }
sLog->outDebug(LOG_FILTER_MAPS, "Unloading grid[%u, %u] for map %u", x, y, GetId());
@@ -1974,15 +1985,8 @@ void Map::RemoveAllObjectsInRemoveList()
bool on = itr->second;
i_objectsToSwitch.erase(itr);
- switch (obj->GetTypeId())
- {
- case TYPEID_UNIT:
- if (!obj->ToCreature()->isPet())
- SwitchGridContainers(obj->ToCreature(), on);
- break;
- default:
- break;
- }
+ if (obj->GetTypeId() == TYPEID_UNIT && !obj->IsPermanentWorldObject())
+ SwitchGridContainers(obj->ToCreature(), on);
}
//sLog->outDebug(LOG_FILTER_MAPS, "Object remover 1 check.");
@@ -2318,6 +2322,13 @@ bool InstanceMap::AddPlayerToMap(Player* player)
ASSERT(playerBind->save == mapSave);
}
}
+
+ if (group && group->isLFGGroup())
+ if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true))
+ if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
+ if (LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin())))
+ if (dungeon->map == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM)
+ player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
}
// for normal instances cancel the reset schedule when the
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 8c4703a9f3a..542d9119830 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -405,7 +405,7 @@ class Map : public GridRefManager<NGridType>
void RemoveFromActive(Creature* obj);
- template<class T> void SwitchGridContainers(T* obj, bool active);
+ void SwitchGridContainers(Creature* creature, bool toWorldContainer);
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitFirstFound(const float &x, const float &y, float radius, NOTIFIER &notifier);
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER &notifier);
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index a6ff663b302..a5935e1de9f 100755
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -946,8 +946,9 @@ enum TrinityStrings
LANG_GOINFO_NAME = 5027,
LANG_GOINFO_LOOTID = 5028,
LANG_COMMAND_LOOKUP_MAX_RESULTS = 5029,
- // Room for more Trinity strings 5030-9999
LANG_FLEE = 5030,
+ LANG_NPCINFO_AIINFO = 5031,
+ // Room for more Trinity strings 5032-9999
// Level requirement notifications
LANG_SAY_REQ = 6604,
diff --git a/src/server/game/Movement/MovementStructures.h b/src/server/game/Movement/MovementStructures.h
index 1313f897acb..33d8282d918 100644
--- a/src/server/game/Movement/MovementStructures.h
+++ b/src/server/game/Movement/MovementStructures.h
@@ -1367,6 +1367,8 @@ MovementStatusElements* GetMovementStatusElementsSequence(Opcodes opcode)
return MovementStartSwimSequence;
case MSG_MOVE_STOP_ASCEND:
return MovementStopAscendSequence;
+ default:
+ break;
}
return NULL;
}
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 3fb75b09a47..6bf9486c1ca 100755
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -197,7 +197,7 @@ bool LoginQueryHolder::Initialize()
return res;
}
-void WorldSession::HandleCharEnum(QueryResult result)
+void WorldSession::HandleCharEnum(PreparedQueryResult result)
{
WorldPacket data(SMSG_CHAR_ENUM, 270);
@@ -304,35 +304,16 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/)
CharacterDatabase.Execute(stmt);
/// get all the data necessary for loading all characters (along with their pets) on the account
- _charEnumCallback =
- CharacterDatabase.AsyncPQuery(
- !sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) ?
- // ------- Query Without Declined Names --------
- // 0 1 2 3 4 5 6 7
- "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
- // 8 9 10 11 12 13 14
- "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
- // 15 16 17 18 19 20
- "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_banned.guid "
- "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
- "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
- "LEFT JOIN character_banned ON characters.guid = character_banned.guid AND character_banned.active = 1 "
- "WHERE characters.account = '%u' ORDER BY characters.guid"
- :
- // --------- Query With Declined Names ---------
- // 0 1 2 3 4 5 6 7
- "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
- // 8 9 10 11 12 13 14
- "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
- // 15 16 17 18 19 20 21
- "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_banned.guid, character_declinedname.genitive "
- "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
- "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
- "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
- "LEFT JOIN character_banned ON characters.guid = character_banned.guid AND character_banned.active = 1 "
- "WHERE characters.account = '%u' ORDER BY characters.guid",
- PET_SAVE_AS_CURRENT, GetAccountId()
- );
+
+ if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_ENUM_DECLINED_NAME);
+ else
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_ENUM);
+
+ stmt->setUInt8(0, PET_SAVE_AS_CURRENT);
+ stmt->setUInt32(1, GetAccountId());
+
+ _charEnumCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
@@ -485,7 +466,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
This is much more efficient than synchronous requests on packet handler, and much less DoS prone.
It also prevents data syncrhonisation errors.
*/
- switch (createInfo->Stage)
+ switch (_charCreateCallback.GetStage())
{
case 0:
{
@@ -495,8 +476,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_NAME_IN_USE);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
@@ -507,8 +487,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
_charCreateCallback.FreeResult();
_charCreateCallback.SetFutureResult(LoginDatabase.AsyncQuery(stmt));
-
- createInfo->Stage++;
+ _charCreateCallback.NextStage();
}
break;
case 1:
@@ -529,8 +508,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_ACCOUNT_LIMIT);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
@@ -542,8 +520,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
_charCreateCallback.FreeResult();
_charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
-
- createInfo->Stage++;
+ _charCreateCallback.NextStage();
}
break;
case 2:
@@ -559,8 +536,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_SERVER_LIMIT);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
}
@@ -576,11 +552,11 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
stmt->setUInt32(0, GetAccountId());
stmt->setUInt32(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
_charCreateCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
- createInfo->Stage++;
+ _charCreateCallback.NextStage();
return;
}
- createInfo->Stage++;
+ _charCreateCallback.NextStage();
HandleCharCreateCallback(PreparedQueryResult(NULL), createInfo); // Will jump to case 3
}
break;
@@ -614,8 +590,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
}
@@ -642,8 +617,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_PVP_TEAMS_VIOLATION);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
}
@@ -675,8 +649,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_UNIQUE_CLASS_LIMIT);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
}
@@ -697,8 +670,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_LEVEL_REQUIREMENT);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
@@ -719,8 +691,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
data << uint8(CHAR_CREATE_ERROR);
SendPacket(&data);
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
return;
}
@@ -761,8 +732,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte
sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass());
delete createInfo;
- _charCreateCallback.SetParam(NULL);
- _charCreateCallback.FreeResult();
+ _charCreateCallback.Reset();
}
break;
}
@@ -858,7 +828,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data)
playerGuid = BitConverter::ToUInt64(bytes);
- sLog->outDebug(LOG_FILTER_NETWORKIO, "Character (Guid: %u) logging in", playerGuid);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "Character (Guid: %u) logging in", GUID_LOPART(playerGuid));
if (!CharCanLogin(GUID_LOPART(playerGuid)))
{
@@ -888,7 +858,7 @@ void WorldSession::HandleLoadScreenOpcode(WorldPacket& recvPacket)
// TODO: Do something with this packet
}
-void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
+void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
{
uint64 playerGuid = holder->GetGuid();
@@ -1201,13 +1171,13 @@ void WorldSession::HandleShowingCloakOpcode(WorldPacket& recv_data)
void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
{
uint64 guid;
- std::string newname;
+ std::string newName;
recv_data >> guid;
- recv_data >> newname;
+ recv_data >> newName;
// prevent character rename to invalid name
- if (!normalizePlayerName(newname))
+ if (!normalizePlayerName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_NO_NAME);
@@ -1215,7 +1185,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
return;
}
- uint8 res = ObjectMgr::CheckPlayerName(newname, true);
+ uint8 res = ObjectMgr::CheckPlayerName(newName, true);
if (res != CHAR_NAME_SUCCESS)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
@@ -1225,7 +1195,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
}
// check name limitations
- if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname))
+ if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_RESERVED);
@@ -1233,21 +1203,22 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
return;
}
- std::string escaped_newname = newname;
- CharacterDatabase.EscapeString(escaped_newname);
-
- // make sure that the character belongs to the current account, that rename at login is enabled
+ // Ensure that the character belongs to the current account, that rename at login is enabled
// and that there is no character with the desired new name
- _charRenameCallback.SetParam(newname);
- _charRenameCallback.SetFutureResult(
- CharacterDatabase.AsyncPQuery(
- "SELECT guid, name FROM characters WHERE guid = %d AND account = %d AND (at_login & %d) = %d AND NOT EXISTS (SELECT NULL FROM characters WHERE name = '%s')",
- GUID_LOPART(guid), GetAccountId(), AT_LOGIN_RENAME, AT_LOGIN_RENAME, escaped_newname.c_str()
- )
- );
+ _charRenameCallback.SetParam(newName);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_FREE_NAME);
+
+ stmt->setUInt32(0, GUID_LOPART(guid));
+ stmt->setUInt32(1, GetAccountId());
+ stmt->setUInt16(2, AT_LOGIN_RENAME);
+ stmt->setUInt16(3, AT_LOGIN_RENAME);
+ stmt->setString(4, newName);
+
+ _charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
-void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std::string newname)
+void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName)
{
if (!result)
{
@@ -1257,22 +1228,38 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std:
return;
}
- uint32 guidLow = result->Fetch()[0].GetUInt32();
+ Field* fields = result->Fetch();
+
+ uint32 guidLow = fields[0].GetUInt32();
+ std::string oldName = fields[1].GetString();
+
uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
- std::string oldname = result->Fetch()[1].GetString();
- CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
- CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
+ // Update name and at_login flag in the db
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_NAME);
+
+ stmt->setString(0, newName);
+ stmt->setUInt16(1, AT_LOGIN_RENAME);
+ stmt->setUInt32(2, guidLow);
- sLog->outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
+ CharacterDatabase.Execute(stmt);
+
+ // Removed declined name from db
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
- WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
+ stmt->setUInt32(0, guidLow);
+
+ CharacterDatabase.Execute(stmt);
+
+ sLog->outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), guidLow, newName.c_str());
+
+ WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newName.size()+1));
data << uint8(RESPONSE_SUCCESS);
data << uint64(guid);
- data << newname;
+ data << newName;
SendPacket(&data);
- sWorld->UpdateCharacterNameData(guidLow, newname);
+ sWorld->UpdateCharacterNameData(guidLow, newName);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
index 7be1722a906..8ed29666b37 100755
--- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
@@ -538,24 +538,23 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket & recv_data)
if (!normalizePlayerName(friendName))
return;
- CharacterDatabase.EscapeString(friendName); // prevent SQL injection - normal name must not be changed by this call
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to add friend : '%s'", GetPlayer()->GetName(), friendName.c_str());
- sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to add friend : '%s'",
- GetPlayer()->GetName(), friendName.c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUID_RACE_ACC_BY_NAME);
+
+ stmt->setString(0, friendName);
_addFriendCallback.SetParam(friendNote);
- _addFriendCallback.SetFutureResult(
- CharacterDatabase.AsyncPQuery("SELECT guid, race, account FROM characters WHERE name = '%s'", friendName.c_str())
- );
+ _addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
-void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult result, std::string friendNote)
+void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string friendNote)
{
if (!GetPlayer())
return;
uint64 friendGuid;
- uint32 friendAcctid;
+ uint32 friendAccountId;
uint32 team;
FriendsResult friendResult;
@@ -564,11 +563,13 @@ void WorldSession::HandleAddFriendOpcodeCallBack(QueryResult result, std::string
if (result)
{
- friendGuid = MAKE_NEW_GUID((*result)[0].GetUInt32(), 0, HIGHGUID_PLAYER);
- team = Player::TeamForRace((*result)[1].GetUInt8());
- friendAcctid = (*result)[2].GetUInt32();
+ Field* fields = result->Fetch();
+
+ friendGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ team = Player::TeamForRace(fields[1].GetUInt8());
+ friendAccountId = fields[2].GetUInt32();
- if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAcctid, realmID)))
+ if (!AccountMgr::IsPlayerAccount(GetSecurity()) || sWorld->getBoolConfig(CONFIG_ALLOW_GM_FRIEND) || AccountMgr::IsPlayerAccount(AccountMgr::GetSecurity(friendAccountId, realmID)))
{
if (friendGuid)
{
@@ -620,22 +621,24 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_IGNORE");
- std::string IgnoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
+ std::string ignoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
- recv_data >> IgnoreName;
+ recv_data >> ignoreName;
- if (!normalizePlayerName(IgnoreName))
+ if (!normalizePlayerName(ignoreName))
return;
- CharacterDatabase.EscapeString(IgnoreName); // prevent SQL injection - normal name must not be changed by this call
-
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to Ignore: '%s'",
- GetPlayer()->GetName(), IgnoreName.c_str());
+ GetPlayer()->GetName(), ignoreName.c_str());
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUID_BY_NAME);
- _addIgnoreCallback = CharacterDatabase.AsyncPQuery("SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
+ stmt->setString(0, ignoreName);
+
+ _addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
}
-void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult result)
+void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
{
if (!GetPlayer())
return;
@@ -713,9 +716,12 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data)
sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", type.c_str());
sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", content.c_str());
- CharacterDatabase.EscapeString(type);
- CharacterDatabase.EscapeString(content);
- CharacterDatabase.PExecute ("INSERT INTO bugreport (type, content) VALUES('%s', '%s')", type.c_str(), content.c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_BUG_REPORT);
+
+ stmt->setString(0, type);
+ stmt->setString(1, content);
+
+ CharacterDatabase.Execute(stmt);
}
void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
@@ -1612,7 +1618,7 @@ void WorldSession::HandleCancelMountAuraOpcode(WorldPacket & /*recv_data*/)
return;
}
- _player->Unmount();
+ _player->Dismount();
_player->RemoveAurasByType(SPELL_AURA_MOUNTED);
}
diff --git a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
index 4b825ea4248..01d7e98a560 100755
--- a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
@@ -295,7 +295,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
// if we boarded a transport, add us to it
if (plMover && !plMover->GetTransport())
{
- // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
+ // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
if ((*iter)->GetGUID() == movementInfo.t_guid)
@@ -593,19 +593,22 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
HaveSpline = false;
MovementStatusElements *sequence = GetMovementStatusElementsSequence(data.GetOpcode());
- if(sequence == NULL)
+ if (sequence == NULL)
return;
- uint8 guid[8];
- uint8 tguid[8];
- *(uint64*)guid = 0;
- *(uint64*)tguid = 0;
- for(uint32 i=0; i < MSE_COUNT; i++)
+
+ BytesGuid guid;
+ BytesGuid tguid;
+
+ guid.guid = 0;
+ tguid.guid = 0;
+
+ for (uint32 i = 0; i < MSE_COUNT; i++)
{
MovementStatusElements element = sequence[i];
if (element >= MSEGuidByte0 && element <= MSEGuidByte7)
{
- data.ReadByteMask(guid[element - MSEGuidByte0]);
+ data.ReadByteMask(guid.bytes[element - MSEGuidByte0]);
continue;
}
@@ -613,13 +616,13 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
element <= MSETransportGuidByte7)
{
if (HaveTransportData)
- data.ReadByteMask(tguid[element - MSETransportGuidByte0]);
+ data.ReadByteMask(tguid.bytes[element - MSETransportGuidByte0]);
continue;
}
if (element >= MSEGuidByte0_2 && element <= MSEGuidByte7_2)
{
- data.ReadByteSeq(guid[element - MSEGuidByte0_2]);
+ data.ReadByteSeq(guid.bytes[element - MSEGuidByte0_2]);
continue;
}
@@ -627,7 +630,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
element <= MSETransportGuidByte7_2)
{
if (HaveTransportData)
- data.ReadByteSeq(tguid[element - MSETransportGuidByte0_2]);
+ data.ReadByteSeq(tguid.bytes[element - MSETransportGuidByte0_2]);
continue;
}
@@ -738,8 +741,8 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
}
}
- mi->guid = *(uint64*)guid;
- mi->t_guid = *(uint64*)tguid;
+ mi->guid = guid.guid;
+ mi->t_guid = tguid.guid;
if (HaveTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX)
if (GetPlayer()->GetTransport())
@@ -901,4 +904,4 @@ void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi)
WPError(false, "Incorrect sequence element detected at ReadMovementInfo");
}
}
-} \ No newline at end of file
+}
diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
index a1986bc352a..220d11367f6 100755
--- a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
@@ -520,14 +520,17 @@ void WorldSession::HandleListStabledPetsOpcode(WorldPacket & recv_data)
void WorldSession::SendStablePet(uint64 guid)
{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOTS_DETAIL);
+
+ stmt->setUInt32(0, _player->GetGUIDLow());
+ stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
+ stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
+
_sendStabledPetCallback.SetParam(guid);
- _sendStabledPetCallback.SetFutureResult(
- CharacterDatabase.AsyncPQuery("SELECT owner, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot",
- _player->GetGUIDLow(), PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT)
- );
+ _sendStabledPetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
-void WorldSession::SendStablePetCallback(QueryResult result, uint64 guid)
+void WorldSession::SendStablePetCallback(PreparedQueryResult result, uint64 guid)
{
if (!GetPlayer())
return;
@@ -619,39 +622,43 @@ void WorldSession::HandleStablePet(WorldPacket & recv_data)
return;
}
- _stablePetCallback = CharacterDatabase.AsyncPQuery("SELECT owner, slot, id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot ",
- _player->GetGUIDLow(), PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOTS);
+
+ stmt->setUInt32(0, _player->GetGUIDLow());
+ stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
+ stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
+ _stablePetCallback = CharacterDatabase.AsyncQuery(stmt);
}
-void WorldSession::HandleStablePetCallback(QueryResult result)
+void WorldSession::HandleStablePetCallback(PreparedQueryResult result)
{
if (!GetPlayer())
return;
- uint32 free_slot = 1;
+ uint8 freeSlot = 1;
if (result)
{
do
{
Field* fields = result->Fetch();
- uint32 slot = fields[1].GetUInt32();
+ uint8 slot = fields[1].GetUInt8();
// slots ordered in query, and if not equal then free
- if (slot != free_slot)
+ if (slot != freeSlot)
break;
// this slot not free, skip
- ++free_slot;
+ ++freeSlot;
}
while (result->NextRow());
}
WorldPacket data(SMSG_STABLE_RESULT, 1);
- if (free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots)
+ if (freeSlot > 0 && freeSlot <= GetPlayer()->m_stableSlots)
{
- _player->RemovePet(_player->GetPet(), PetSaveMode(free_slot));
+ _player->RemovePet(_player->GetPet(), PetSaveMode(freeSlot));
SendStableResult(STABLE_SUCCESS_STABLE);
}
else
@@ -676,32 +683,36 @@ void WorldSession::HandleUnstablePet(WorldPacket & recv_data)
if (GetPlayer()->HasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_ENTRY);
+
+ stmt->setUInt32(0, _player->GetGUIDLow());
+ stmt->setUInt32(1, petnumber);
+ stmt->setUInt8(2, PET_SAVE_FIRST_STABLE_SLOT);
+ stmt->setUInt8(3, PET_SAVE_LAST_STABLE_SLOT);
+
_unstablePetCallback.SetParam(petnumber);
- _unstablePetCallback.SetFutureResult(
- CharacterDatabase.AsyncPQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'",
- _player->GetGUIDLow(), petnumber, PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT)
- );
+ _unstablePetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
-void WorldSession::HandleUnstablePetCallback(QueryResult result, uint32 petnumber)
+void WorldSession::HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId)
{
if (!GetPlayer())
return;
- uint32 creature_id = 0;
+ uint32 petEntry = 0;
if (result)
{
Field* fields = result->Fetch();
- creature_id = fields[0].GetUInt32();
+ petEntry = fields[0].GetUInt32();
}
- if (!creature_id)
+ if (!petEntry)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}
- CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature_id);
+ CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
if (!creatureInfo || !creatureInfo->isTameable(_player->CanTameExoticPets()))
{
// if problem in exotic pet
@@ -723,11 +734,11 @@ void WorldSession::HandleUnstablePetCallback(QueryResult result, uint32 petnumbe
if (pet)
_player->RemovePet(pet, PET_SAVE_AS_DELETED);
- Pet* newpet = new Pet(_player, HUNTER_PET);
- if (!newpet->LoadPetFromDB(_player, creature_id, petnumber))
+ Pet* newPet = new Pet(_player, HUNTER_PET);
+ if (!newPet->LoadPetFromDB(_player, petEntry, petId))
{
- delete newpet;
- newpet = NULL;
+ delete newPet;
+ newPet = NULL;
SendStableResult(STABLE_ERR_STABLE);
return;
}
@@ -777,9 +788,9 @@ void WorldSession::HandleStableSwapPet(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_STABLE_SWAP_PET.");
uint64 npcGUID;
- uint32 pet_number;
+ uint32 petId;
- recv_data >> npcGUID >> pet_number;
+ recv_data >> npcGUID >> petId;
if (!CheckStableMaster(npcGUID))
{
@@ -799,15 +810,18 @@ void WorldSession::HandleStableSwapPet(WorldPacket & recv_data)
return;
}
- // find swapped pet slot in stable
- _stableSwapCallback.SetParam(pet_number);
- _stableSwapCallback.SetFutureResult(
- CharacterDatabase.PQuery("SELECT slot, entry FROM character_pet WHERE owner = '%u' AND id = '%u'",
- _player->GetGUIDLow(), pet_number)
- );
+ // Find swapped pet slot in stable
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOT_BY_ID);
+
+ stmt->setUInt32(0, _player->GetGUIDLow());
+ stmt->setUInt32(1, petId);
+
+ _stableSwapCallback.SetParam(petId);
+ _stableSwapCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
-void WorldSession::HandleStableSwapPetCallback(QueryResult result, uint32 petnumber)
+void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId)
{
if (!GetPlayer())
return;
@@ -820,16 +834,16 @@ void WorldSession::HandleStableSwapPetCallback(QueryResult result, uint32 petnum
Field* fields = result->Fetch();
- uint32 slot = fields[0].GetUInt8();
- uint32 creature_id = fields[1].GetUInt32();
+ uint32 slot = fields[0].GetUInt8();
+ uint32 petEntry = fields[1].GetUInt32();
- if (!creature_id)
+ if (!petEntry)
{
SendStableResult(STABLE_ERR_STABLE);
return;
}
- CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature_id);
+ CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
if (!creatureInfo || !creatureInfo->isTameable(_player->CanTameExoticPets()))
{
// if problem in exotic pet
@@ -847,7 +861,7 @@ void WorldSession::HandleStableSwapPetCallback(QueryResult result, uint32 petnum
// summon unstabled pet
Pet* newpet = new Pet(_player);
- if (!newpet->LoadPetFromDB(_player, creature_id, petnumber))
+ if (!newpet->LoadPetFromDB(_player, petEntry, petId))
{
delete newpet;
SendStableResult(STABLE_ERR_STABLE);
diff --git a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
index 2e9b88bd3f0..fed84728efd 100755
--- a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
@@ -372,18 +372,18 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode MSG_PETITION_RENAME"); // ok
- uint64 petitionguid;
+ uint64 petitionGuid;
uint32 type;
- std::string newname;
+ std::string newName;
- recv_data >> petitionguid; // guid
- recv_data >> newname; // new name
+ recv_data >> petitionGuid; // guid
+ recv_data >> newName; // new name
- Item* item = _player->GetItemByGuid(petitionguid);
+ Item* item = _player->GetItemByGuid(petitionGuid);
if (!item)
return;
- QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ QueryResult result = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid));
if (result)
{
@@ -392,46 +392,48 @@ void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
}
else
{
- sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid));
return;
}
if (type == GUILD_CHARTER_TYPE)
{
- if (sGuildMgr->GetGuildByName(newname))
+ if (sGuildMgr->GetGuildByName(newName))
{
- Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, newname);
+ Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_EXISTS_S, newName);
return;
}
- if (sObjectMgr->IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
+ if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
{
- Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, newname);
+ Guild::SendCommandResult(this, GUILD_CREATE_S, ERR_GUILD_NAME_INVALID, newName);
return;
}
}
else
{
- if (sArenaTeamMgr->GetArenaTeamByName(newname))
+ if (sArenaTeamMgr->GetArenaTeamByName(newName))
{
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newName, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
return;
}
- if (sObjectMgr->IsReservedName(newname) || !ObjectMgr::IsValidCharterName(newname))
+ if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
{
- SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newName, "", ERR_ARENA_TEAM_NAME_INVALID);
return;
}
}
- std::string db_newname = newname;
- CharacterDatabase.EscapeString(db_newname);
- CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'",
- db_newname.c_str(), GUID_LOPART(petitionguid));
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PETITION_NAME);
+
+ stmt->setString(0, newName);
+ stmt->setUInt32(1, GUID_LOPART(petitionGuid));
+
+ CharacterDatabase.Execute(stmt);
- sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid), newname.c_str());
- WorldPacket data(MSG_PETITION_RENAME, (8+newname.size()+1));
- data << uint64(petitionguid);
- data << newname;
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionGuid), newName.c_str());
+ WorldPacket data(MSG_PETITION_RENAME, (8+newName.size()+1));
+ data << uint64(petitionGuid);
+ data << newName;
SendPacket(&data);
}
@@ -440,34 +442,34 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
sLog->outDebug(LOG_FILTER_NETWORKIO, "Received opcode CMSG_PETITION_SIGN"); // ok
Field* fields;
- uint64 petitionguid;
+ uint64 petitionGuid;
uint8 unk;
- recv_data >> petitionguid; // petition guid
+ recv_data >> petitionGuid; // petition guid
recv_data >> unk;
QueryResult result = CharacterDatabase.PQuery(
"SELECT ownerguid, "
" (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
" type "
- "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
+ "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionGuid), GUID_LOPART(petitionGuid));
if (!result)
{
- sLog->outError("Petition %u is not found for player %u %s", GUID_LOPART(petitionguid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName());
+ sLog->outError("Petition %u is not found for player %u %s", GUID_LOPART(petitionGuid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName());
return;
}
fields = result->Fetch();
- uint64 ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ uint64 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
uint8 signs = fields[1].GetUInt8();
uint32 type = fields[2].GetUInt32();
- uint32 plguidlo = _player->GetGUIDLow();
- if (GUID_LOPART(ownerguid) == plguidlo)
+ uint32 playerGuid = _player->GetGUIDLow();
+ if (GUID_LOPART(ownerGuid) == playerGuid)
return;
// not let enemies sign guild charter
- if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(ownerguid))
+ if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(ownerGuid))
{
if (type != GUILD_CHARTER_TYPE)
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
@@ -519,12 +521,12 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
//client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
//not allow sign another player from already sign player account
- result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid));
+ result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionGuid));
if (result)
{
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
- data << uint64(petitionguid);
+ data << uint64(petitionGuid);
data << uint64(_player->GetGUID());
data << (uint32)PETITION_SIGN_ALREADY_SIGNED;
@@ -532,17 +534,24 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
SendPacket(&data);
// update for owner if online
- if (Player* owner = ObjectAccessor::FindPlayer(ownerguid))
+ if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
owner->GetSession()->SendPacket(&data);
return;
}
- CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(ownerguid), GUID_LOPART(petitionguid), plguidlo, GetAccountId());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_PETITION_SIGNATURE);
+
+ stmt->setUInt32(0, GUID_LOPART(ownerGuid));
+ stmt->setUInt32(1, GUID_LOPART(petitionGuid));
+ stmt->setUInt32(2, playerGuid);
+ stmt->setUInt32(3, GetAccountId());
+
+ CharacterDatabase.Execute(stmt);
- sLog->outDebug(LOG_FILTER_NETWORKIO, "PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid), _player->GetName(), plguidlo, GetAccountId());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionGuid), _player->GetName(), playerGuid, GetAccountId());
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
- data << uint64(petitionguid);
+ data << uint64(petitionGuid);
data << uint64(_player->GetGUID());
data << uint32(PETITION_SIGN_OK);
@@ -555,7 +564,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
// item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
// update for owner if online
- if (Player* owner = ObjectAccessor::FindPlayer(ownerguid))
+ if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
owner->GetSession()->SendPacket(&data);
}
diff --git a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
index 7de5ee61115..a02618eb43a 100755
--- a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
@@ -169,7 +169,6 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
{
- const int GO_DATA_FIELDS_NUMBER = 32;
uint32 entry;
recv_data >> entry;
uint64 guid;
diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
index 30c096d1e3f..59e852b6080 100755
--- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
@@ -213,26 +213,26 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
sLog->outDetail("bagIndex: %u, slot: %u", bagIndex, slot);
- Item* pItem = pUser->GetItemByPos(bagIndex, slot);
- if (!pItem)
+ Item* item = pUser->GetItemByPos(bagIndex, slot);
+ if (!item)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
return;
}
- ItemTemplate const* proto = pItem->GetTemplate();
+ ItemTemplate const* proto = item->GetTemplate();
if (!proto)
{
- pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL);
+ pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
return;
}
// Verify that the bag is an actual bag or wrapped item that can be used "normally"
- if (!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE) && !pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
+ if (!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
{
- pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, pItem, NULL);
+ pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
sLog->outError("Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!",
- pUser->GetName(), pUser->GetGUIDLow(), pItem->GetGUIDLow(), proto->ItemId);
+ pUser->GetName(), pUser->GetGUIDLow(), item->GetGUIDLow(), proto->ItemId);
return;
}
@@ -244,43 +244,48 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
if (!lockInfo)
{
- pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL);
- sLog->outError("WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", pItem->GetGUIDLow(), lockId);
+ pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
+ sLog->outError("WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", item->GetGUIDLow(), lockId);
return;
}
// was not unlocked yet
- if (pItem->IsLocked())
+ if (item->IsLocked())
{
- pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL);
+ pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL);
return;
}
}
- if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))// wrapped?
+ if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))// wrapped?
{
- QueryResult result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
+ QueryResult result = CharacterDatabase.PQuery("SELECT entry, flags FROM character_gifts WHERE item_guid = '%u'", item->GetGUIDLow());
if (result)
{
Field* fields = result->Fetch();
uint32 entry = fields[0].GetUInt32();
uint32 flags = fields[1].GetUInt32();
- pItem->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0);
- pItem->SetEntry(entry);
- pItem->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
- pItem->SetState(ITEM_CHANGED, pUser);
+ item->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0);
+ item->SetEntry(entry);
+ item->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
+ item->SetState(ITEM_CHANGED, pUser);
}
else
{
- sLog->outError("Wrapped item %u don't have record in character_gifts table and will deleted", pItem->GetGUIDLow());
- pUser->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
+ sLog->outError("Wrapped item %u don't have record in character_gifts table and will deleted", item->GetGUIDLow());
+ pUser->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
return;
}
- CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", pItem->GetGUIDLow());
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
+
+ stmt->setUInt32(0, item->GetGUIDLow());
+
+ CharacterDatabase.Execute(stmt);
}
else
- pUser->SendLoot(pItem->GetGUID(), LOOT_CORPSE);
+ pUser->SendLoot(item->GetGUID(), LOOT_CORPSE);
}
void WorldSession::HandleGameObjectUseOpcode(WorldPacket & recv_data)
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 8087307dab6..13ecf15a971 100755
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -241,7 +241,18 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
///- Retrieve packets from the receive queue and call the appropriate handlers
/// not process packets if socket already closed
WorldPacket* packet = NULL;
- while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
+ //! Delete packet after processing by default
+ bool deletePacket = true;
+ //! To prevent infinite loop
+ WorldPacket* firstDelayedPacket = NULL;
+ //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all
+ //! *properly timed* packets, and we're now at the part of the queue where we find
+ //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite
+ //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session
+ //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session.
+ while (m_Socket && !m_Socket->IsClosed() &&
+ !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
+ _recvQueue.next(packet, updater))
{
const OpcodeHandler* opHandle = opcodeTable[packet->GetOpcode()];
try
@@ -252,8 +263,20 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!_player)
{
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
+ //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
+ //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
if (!m_playerRecentlyLogout)
- LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN", "the player has not logged in yet");
+ {
+ //! Prevent infinite loop
+ if (!firstDelayedPacket)
+ firstDelayedPacket = packet;
+ //! Because checking a bool is faster than reallocating memory
+ deletePacket = false;
+ QueuePacket(packet);
+ //! Log
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. "
+ "Player is currently not in world yet.", opHandle->name, packet->GetOpcode());
+ }
}
else if (_player->IsInWorld())
{
@@ -331,7 +354,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
}
}
- delete packet;
+ if (deletePacket)
+ delete packet;
}
ProcessQueryCallbacks();
@@ -355,6 +379,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!m_Socket)
return false; //Will remove this session from the world session map
}
+
return true;
}
@@ -514,7 +539,13 @@ void WorldSession::LogoutPlayer(bool Save)
///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline
//No SQL injection as AccountId is uint32
- CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", GetAccountId());
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ACCOUNT_ONLINE);
+
+ stmt->setUInt32(0, GetAccountId());
+
+ CharacterDatabase.Execute(stmt);
+
sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
}
@@ -888,7 +919,7 @@ void WorldSession::InitializeQueryCallbackParameters()
void WorldSession::ProcessQueryCallbacks()
{
- QueryResult result;
+ PreparedQueryResult result;
//! HandleCharEnumOpcode
if (_charEnumCallback.ready())
@@ -900,9 +931,8 @@ void WorldSession::ProcessQueryCallbacks()
if (_charCreateCallback.IsReady())
{
- PreparedQueryResult pResult;
- _charCreateCallback.GetResult(pResult);
- HandleCharCreateCallback(pResult, _charCreateCallback.GetParam());
+ _charCreateCallback.GetResult(result);
+ HandleCharCreateCallback(result, _charCreateCallback.GetParam());
// Don't call FreeResult() here, the callback handler will do that depending on the events in the callback chain
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index d3afe11ba42..b634aef39c4 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -80,6 +80,12 @@ struct AccountData
std::string Data;
};
+union BytesGuid
+{
+ uint8 bytes[8];
+ uint64 guid;
+};
+
enum PartyOperation
{
PARTY_OP_INVITE = 0,
@@ -188,7 +194,7 @@ class CharacterCreateInfo
protected:
CharacterCreateInfo(std::string name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId,
WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair),
- OutfitId(outfitId), Data(data), CharCount(0), Stage(0)
+ OutfitId(outfitId), Data(data), CharCount(0)
{}
/// User specified variables
@@ -207,9 +213,6 @@ class CharacterCreateInfo
/// Server side data
uint8 CharCount;
- /// Internal
- uint8 Stage; // Stage of the callback chain
-
private:
virtual ~CharacterCreateInfo(){};
};
@@ -308,7 +311,7 @@ class WorldSession
// Pet
void SendPetNameQuery(uint64 guid, uint32 petnumber);
void SendStablePet(uint64 guid);
- void SendStablePetCallback(QueryResult result, uint64 guid);
+ void SendStablePetCallback(PreparedQueryResult result, uint64 guid);
void SendStableResult(uint8 guid);
bool CheckStableMaster(uint64 guid);
@@ -405,7 +408,7 @@ class WorldSession
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo* createInfo);
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
void HandleLoadScreenOpcode(WorldPacket& recvPacket);
- void HandleCharEnum(QueryResult result);
+ void HandleCharEnum(PreparedQueryResult result);
void HandlePlayerLogin(LoginQueryHolder * holder);
void HandleCharFactionOrRaceChange(WorldPacket& recv_data);
void HandleRandomizeCharNameOpcode(WorldPacket& recv_data);
@@ -477,10 +480,10 @@ class WorldSession
void HandleEmoteOpcode(WorldPacket& recvPacket);
void HandleContactListOpcode(WorldPacket& recvPacket);
void HandleAddFriendOpcode(WorldPacket& recvPacket);
- void HandleAddFriendOpcodeCallBack(QueryResult result, std::string friendNote);
+ void HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std::string friendNote);
void HandleDelFriendOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
- void HandleAddIgnoreOpcodeCallBack(QueryResult result);
+ void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result);
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
void HandleBugOpcode(WorldPacket& recvPacket);
@@ -596,13 +599,13 @@ class WorldSession
void HandleBinderActivateOpcode(WorldPacket& recvPacket);
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
void HandleStablePet(WorldPacket& recvPacket);
- void HandleStablePetCallback(QueryResult result);
+ void HandleStablePetCallback(PreparedQueryResult result);
void HandleUnstablePet(WorldPacket& recvPacket);
- void HandleUnstablePetCallback(QueryResult result, uint32 petnumber);
+ void HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId);
void HandleBuyStableSlot(WorldPacket& recvPacket);
void HandleStableRevivePet(WorldPacket& recvPacket);
void HandleStableSwapPet(WorldPacket& recvPacket);
- void HandleStableSwapPetCallback(QueryResult result, uint32 petnumber);
+ void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId);
void HandleDuelAcceptedOpcode(WorldPacket& recvPacket);
void HandleDuelCancelledOpcode(WorldPacket& recvPacket);
@@ -756,7 +759,7 @@ class WorldSession
void HandleSetActionBarToggles(WorldPacket& recv_data);
void HandleCharRenameOpcode(WorldPacket& recv_data);
- void HandleChangePlayerNameOpcodeCallBack(QueryResult result, std::string newname);
+ void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName);
void HandleSetPlayerDeclinedNames(WorldPacket& recv_data);
void HandleTotemDestroyed(WorldPacket& recv_data);
@@ -905,16 +908,15 @@ class WorldSession
void InitializeQueryCallbackParameters();
void ProcessQueryCallbacks();
- ACE_Future_Set<QueryResult> _nameQueryCallbacks;
- QueryResultFuture _charEnumCallback;
- QueryResultFuture _addIgnoreCallback;
- QueryResultFuture _stablePetCallback;
- QueryCallback<QueryResult, std::string> _charRenameCallback;
- QueryCallback<QueryResult, std::string> _addFriendCallback;
- QueryCallback<QueryResult, uint32> _unstablePetCallback;
- QueryCallback<QueryResult, uint32> _stableSwapCallback;
- QueryCallback<QueryResult, uint64> _sendStabledPetCallback;
- QueryCallback<PreparedQueryResult, CharacterCreateInfo*> _charCreateCallback;
+ PreparedQueryResultFuture _charEnumCallback;
+ PreparedQueryResultFuture _addIgnoreCallback;
+ PreparedQueryResultFuture _stablePetCallback;
+ QueryCallback<PreparedQueryResult, std::string> _charRenameCallback;
+ QueryCallback<PreparedQueryResult, std::string> _addFriendCallback;
+ QueryCallback<PreparedQueryResult, uint32> _unstablePetCallback;
+ QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
+ QueryCallback<PreparedQueryResult, uint64> _sendStabledPetCallback;
+ QueryCallback<PreparedQueryResult, CharacterCreateInfo*, true> _charCreateCallback;
QueryResultHolderFuture _charLoginCallback;
private:
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 447da4b6d20..99317eb22b0 100755
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -922,7 +922,19 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
K.SetHexStr (fields[1].GetCString());
- time_t mutetime = time_t (fields[7].GetUInt64());
+ int64 mutetime = fields[7].GetInt64();
+ //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now.
+ if (mutetime < 0)
+ {
+ mutetime = time(NULL) + llabs(mutetime);
+
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_MUTE_TIME);
+
+ stmt->setInt64(0, mutetime);
+ stmt->setUInt32(1, id);
+
+ LoginDatabase.Execute(stmt);
+ }
locale = LocaleConstant (fields[8].GetUInt8());
if (locale >= TOTAL_LOCALES)
@@ -1005,14 +1017,13 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
isRecruiter = true;
// Update the last_ip in the database
- // No SQL injection, username escaped.
- LoginDatabase.EscapeString (address);
- LoginDatabase.PExecute ("UPDATE account "
- "SET last_ip = '%s' "
- "WHERE username = '%s'",
- address.c_str(),
- safe_account.c_str());
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(LOGIN_UPDATE_LAST_IP);
+
+ stmt->setString(0, address);
+ stmt->setString(1, account);
+
+ CharacterDatabase.Execute(stmt);
// NOTE ATM the socket is single-threaded, have this in mind ...
ACE_NEW_RETURN (m_Session, WorldSession (id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 9c4341ec59a..916fca7e1ce 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2821,7 +2821,7 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
}
else
{
- target->Unmount();
+ target->Dismount();
//some mounts like Headless Horseman's Mount or broom stick are skill based spell
// need to remove ALL arura related to mounts, this will stop client crash with broom stick
// and never endless flying after using Headless Horseman's Mount
@@ -4784,10 +4784,13 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
break;
case 63322: // Saronite Vapors
{
- int32 mana = int32(GetAmount() * pow(2.0f, GetBase()->GetStackAmount())); // mana restore - bp * 2^stackamount
- int32 damage = mana * 2; // damage
- caster->CastCustomSpell(target, 63337, &mana, NULL, NULL, true);
- caster->CastCustomSpell(target, 63338, &damage, NULL, NULL, true);
+ if (caster)
+ {
+ int32 mana = int32(GetAmount() * pow(2.0f, GetBase()->GetStackAmount())); // mana restore - bp * 2^stackamount
+ int32 damage = mana * 2; // damage
+ caster->CastCustomSpell(target, 63337, &mana, NULL, NULL, true);
+ caster->CastCustomSpell(target, 63338, &damage, NULL, NULL, true);
+ }
break;
}
case 71563:
@@ -4795,9 +4798,8 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount);
break;
case 59628: // Tricks of the Trade
- if (!caster->GetMisdirectionTarget())
- break;
- target->SetReducedThreatPercent(100,caster->GetMisdirectionTarget()->GetGUID());
+ if (caster && caster->GetMisdirectionTarget())
+ target->SetReducedThreatPercent(100, caster->GetMisdirectionTarget()->GetGUID());
break;
}
}
@@ -5198,7 +5200,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (!(mode & AURA_EFFECT_HANDLE_REAL))
break;
// Sentry Totem
- if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER)
+ if (GetId() == 6495 && caster && caster->GetTypeId() == TYPEID_PLAYER)
{
if (apply)
{
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index ffe3b0084a9..66fd5177654 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1342,6 +1342,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (removeMode != AURA_REMOVE_BY_EXPIRE)
break;
target->CastSpell(target, 32612, true, NULL, GetEffect(1));
+ target->CombatStop();
break;
case 74396: // Fingers of Frost
// Remove the IGNORE_AURASTATE aura
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 7ac3e04bc3b..3ce6a398a46 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2034,7 +2034,7 @@ uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur)
float max_dis = m_spellInfo->GetMaxRange(true);
float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
float x, y, z, angle;
- angle = (float)rand_norm() * static_cast<float>(M_PI * 70.0f / 180.0f) - static_cast<float>(M_PI * 35.0f / 180.0f);
+ angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle);
m_targets.SetDst(x, y, z, m_caster->GetOrientation());
break;
@@ -3255,6 +3255,12 @@ void Spell::handle_immediate()
m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
SendChannelStart(duration);
}
+ else if (duration == -1)
+ {
+ m_spellState = SPELL_STATE_CASTING;
+ m_caster->AddInterruptMask(m_spellInfo->ChannelInterruptFlags);
+ SendChannelStart(duration);
+ }
}
PrepareTargetProcessing();
@@ -3280,7 +3286,6 @@ void Spell::handle_immediate()
if (m_spellInfo->IsRangedWeaponSpell() && m_spellInfo->IsChanneled())
TakeAmmo();
-
if (m_spellState != SPELL_STATE_CASTING)
finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
}
@@ -3479,9 +3484,9 @@ void Spell::update(uint32 difftime)
{
case SPELL_STATE_PREPARING:
{
- if (m_timer)
+ if (m_timer > 0)
{
- if (difftime >= m_timer)
+ if (difftime >= (uint32)m_timer)
m_timer = 0;
else
m_timer -= difftime;
@@ -3490,10 +3495,11 @@ void Spell::update(uint32 difftime)
if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
// don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
cast(!m_casttime);
- } break;
+ break;
+ }
case SPELL_STATE_CASTING:
{
- if (m_timer > 0)
+ if (m_timer)
{
// check if there are alive targets left
if (!UpdateChanneledTargetList())
@@ -3503,10 +3509,13 @@ void Spell::update(uint32 difftime)
finish();
}
- if (difftime >= m_timer)
- m_timer = 0;
- else
- m_timer -= difftime;
+ if (m_timer > 0)
+ {
+ if (difftime >= (uint32)m_timer)
+ m_timer = 0;
+ else
+ m_timer -= difftime;
+ }
}
if (m_timer == 0)
@@ -3548,10 +3557,10 @@ void Spell::update(uint32 difftime)
finish();
}
- } break;
+ break;
+ }
default:
- {
- }break;
+ break;
}
}
@@ -3783,7 +3792,7 @@ void Spell::SendSpellStart()
data << uint8(m_cast_count); // pending spell cast?
data << uint32(m_spellInfo->Id); // spellId
data << uint32(castFlags); // cast flags
- data << uint32(m_timer); // delay?
+ data << int32(m_timer); // delay?
m_targets.Write(data);
@@ -5607,7 +5616,8 @@ SpellCastResult Spell::CheckRange(bool strict)
if (m_spellInfo->RangeEntry)
{
- // self cast is used for triggered spells, no range checking needed
+ // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
+ // these are triggered by other spells - possibly we should omit range check in that case?
if (m_spellInfo->RangeEntry->ID == 1)
return SPELL_CAST_OK;
@@ -6184,7 +6194,7 @@ void Spell::Delayed() // only called in DealDamage()
AddPctN(delaytime, -delayReduce);
- if (int32(m_timer) + delaytime > m_casttime)
+ if (m_timer + delaytime > m_casttime)
{
delaytime = m_casttime - m_timer;
m_timer = m_casttime;
@@ -6219,7 +6229,7 @@ void Spell::DelayedChannel()
AddPctN(delaytime, -delayReduce);
- if (int32(m_timer) <= delaytime)
+ if (m_timer <= delaytime)
{
delaytime = m_timer;
m_timer = 0;
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index f9a48bf6a87..b3357783477 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -646,7 +646,7 @@ class Spell
// -------------------------------------------
uint32 m_spellState;
- uint32 m_timer;
+ int32 m_timer;
TriggerCastFlags _triggeredCastFlags;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index be8db537065..d0518191bb3 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2176,19 +2176,9 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
&& effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- //! it's possible for spells with this spell effect to either have a target or no target
- //! in case of a target, we will execute this handler on SPELL_EFFECT_HANDLE_HIT_TARGET
- //! with all relevant variables, and we will skip SPELL_EFFECT_HANDLE_HIT
- if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
- {
- if (GetSpellInfo()->Effects[effIndex].TargetA.GetTarget() != 0 ||
- GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() != 0)
- return;
- }
-
WorldObject* target = NULL;
- // call events for target if present
+ // call events for object target if present
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
{
if (unitTarget)
@@ -2196,9 +2186,15 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
else if (gameObjTarget)
target = gameObjTarget;
}
- // call event with no target or focus target when no targets could be found due to no dbc entry
- else if (!m_spellInfo->Effects[effIndex].GetProvidedTargetMask())
+ else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
{
+ // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
+ // this check was requested by scripters, but it has some downsides:
+ // now it's impossible to script (using sEventScripts) a cast which misses all targets
+ // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
+ if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
+ return;
+ // some spells have no target entries in dbc and they use focus target
if (focusObject)
target = focusObject;
// TODO: there should be a possibility to pass dest target to event script
@@ -2619,8 +2615,8 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
// Caster not in world, might be spell triggered from aura removal
if (!caster->IsInWorld())
return;
- DynamicObject* dynObj = new DynamicObject();
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *m_targets.GetDst(), radius, false, DYNAMIC_OBJECT_AREA_SPELL))
+ DynamicObject* dynObj = new DynamicObject(false);
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_AREA_SPELL))
{
delete dynObj;
return;
@@ -3468,8 +3464,8 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
if (!m_caster->IsInWorld())
return;
- DynamicObject* dynObj = new DynamicObject();
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *m_targets.GetDst(), radius, true, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
+ DynamicObject* dynObj = new DynamicObject(true);
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
{
delete dynObj;
return;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 21c32ca57b2..dde8c6869e4 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3149,6 +3149,9 @@ void SpellMgr::LoadDbcDataCorrections()
case 64904: // Hymn of Hope
spellInfo->EffectApplyAuraName[EFFECT_1] = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT;
break;
+ case 19465: // Improved Stings (Rank 2)
+ spellInfo->EffectImplicitTargetA[EFFECT_2] = TARGET_UNIT_CASTER;
+ break;
case 30421: // Nether Portal - Perseverence
spellInfo->EffectBasePoints[2] += 30000;
break;
@@ -3227,6 +3230,10 @@ void SpellMgr::LoadDbcDataCorrections()
// this needs research on modifier applying rules, does not seem to be in Attributes fields
spellInfo->EffectSpellClassMask[0] = flag96(0x00000040, 0x00000000, 0x00000000);
break;
+ case 63163: // Apply Enchanted Bridle (Argent Tournament)
+ spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1
+ spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0)
+ break;
case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc
case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc
case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 10c1f4a1dfd..c657248c595 100755
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -207,7 +207,10 @@ void TicketMgr::ResetTickets()
sTicketMgr->RemoveTicket(itr->second->GetId());
_lastTicketId = 0;
- CharacterDatabase.PExecute("TRUNCATE TABLE gm_tickets");
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GM_TICKETS);
+
+ CharacterDatabase.Execute(stmt);
}
void TicketMgr::LoadTickets()
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 891d8602cae..853c03af07b 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -2698,7 +2698,10 @@ void World::InitRandomBGResetTime()
void World::ResetDailyQuests()
{
sLog->outDetail("Daily quests reset for all characters.");
- CharacterDatabase.Execute("DELETE FROM character_queststatus_daily");
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_QUEST_STATUS_DAILY);
+ CharacterDatabase.Execute(stmt);
+
for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if (itr->second->GetPlayer())
itr->second->GetPlayer()->ResetDailyQuestStatus();
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index ae3250ad7b7..bcef7ac9ba9 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -81,8 +81,13 @@ public:
return false;
}
- // No SQL injection
- LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'", expansion, accountId);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_EXPANSION);
+
+ stmt->setUInt8(0, uint8(expansion));
+ stmt->setUInt32(1, accountId);
+
+ LoginDatabase.Execute(stmt);
+
handler->PSendSysMessage(LANG_ACCOUNT_ADDON, expansion);
return true;
}
@@ -242,17 +247,25 @@ public:
}
std::string param = (char*)args;
- if (param == "on")
- {
- LoginDatabase.PExecute("UPDATE account SET locked = '1' WHERE id = '%d'", handler->GetSession()->GetAccountId());
- handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
- return true;
- }
- if (param == "off")
+ if (!param.empty())
{
- LoginDatabase.PExecute("UPDATE account SET locked = '0' WHERE id = '%d'", handler->GetSession()->GetAccountId());
- handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_ACCOUNT_LOCK);
+
+ if (param == "on")
+ {
+ stmt->setBool(0, true); // locked
+ handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
+ }
+ else if (param == "off")
+ {
+ stmt->setBool(0, false); // unlocked
+ handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
+ }
+
+ stmt->setUInt32(1, handler->GetSession()->GetAccountId());
+
+ LoginDatabase.Execute(stmt);
return true;
}
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index b9ac21cc040..a5aa2a516f3 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -552,15 +552,13 @@ public:
handler->PSendSysMessage(LANG_NPCINFO_PHASEMASK, target->GetPhaseMask());
handler->PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor());
handler->PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
+ handler->PSendSysMessage(LANG_NPCINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str());
- if ((npcflags & UNIT_NPC_FLAG_VENDOR))
- {
+ if (npcflags & UNIT_NPC_FLAG_VENDOR)
handler->SendSysMessage(LANG_NPCINFO_VENDOR);
- }
- if ((npcflags & UNIT_NPC_FLAG_TRAINER))
- {
+
+ if (npcflags & UNIT_NPC_FLAG_TRAINER)
handler->SendSysMessage(LANG_NPCINFO_TRAINER);
- }
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
index ebd30aa2f5d..8179c9fccaa 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp
@@ -248,7 +248,7 @@ public:
me->Mount(MODEL_DEATH_KNIGHT_MOUNT);
break;
case 10:
- me->Unmount();
+ me->Dismount();
break;
}
}
@@ -378,7 +378,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
DoScriptText(SAY_TREE2, me);
- me->Unmount();
+ me->Dismount();
uiStage = 0;
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
index 18316d67cd4..3ee71ce3609 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp
@@ -526,13 +526,13 @@ public:
NPCChangeTarget(uiOrbazGUID);
NPCChangeTarget(uiThassarianGUID);
- me->Unmount();
+ me->Dismount();
me->CastSpell(me, SPELL_THE_MIGHT_OF_MOGRAINE, true); // need to fix, on player only
if (Creature* temp = Unit::GetCreature(*me, uiKoltiraGUID))
- temp->Unmount();
+ temp->Dismount();
if (Creature* temp = Unit::GetCreature(*me, uiThassarianGUID))
- temp->Unmount();
+ temp->Dismount();
bIsBattle = true;
break;
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
index f45c943b0f1..7dc357f692a 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
@@ -149,7 +149,7 @@ class boss_mandokir : public CreatureScript
if (!CombatStart)
{
//At combat Start Mandokir is mounted so we must unmount it first
- me->Unmount();
+ me->Dismount();
//And summon his raptor
me->SummonCreature(14988, me->getVictim()->GetPositionX(), me->getVictim()->GetPositionY(), me->getVictim()->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);
diff --git a/src/server/scripts/EasternKingdoms/blasted_lands.cpp b/src/server/scripts/EasternKingdoms/blasted_lands.cpp
index 048fd8dfd2a..38a577b9ba9 100644
--- a/src/server/scripts/EasternKingdoms/blasted_lands.cpp
+++ b/src/server/scripts/EasternKingdoms/blasted_lands.cpp
@@ -72,6 +72,13 @@ public:
/*######
## npc_fallen_hero_of_horde
######*/
+
+enum HeroesOfOld
+{
+ QUEST_HEROES_OF_OLD = 2702,
+ NPC_THUND_SPLITHOOF = 7750,
+};
+
#define GOSSIP_H_F1 "Why are you here?"
#define GOSSIP_H_F2 "Continue story..."
@@ -159,6 +166,14 @@ public:
return true;
}
+ bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest)
+ {
+ if (quest->GetQuestId() == QUEST_HEROES_OF_OLD)
+ creature->SummonCreature(NPC_THUND_SPLITHOOF, -10630.3f, -2987.05f, 28.96f, 4.54f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 9000000);
+
+ return true;
+ }
+
};
void AddSC_blasted_lands()
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
index 1a43472365a..798ea3925dc 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
@@ -34,7 +34,8 @@ enum Spells
H_SPELL_MIND_BLAST = 58850,
SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target.
H_SPELL_SLEEP = 58849,
- SPELL_VAMPIRIC_TOUCH = 52723 //Heals the caster for half the damage dealt by a melee attack.
+ SPELL_VAMPIRIC_TOUCH = 52723, //Heals the caster for half the damage dealt by a melee attack.
+ SPELL_KILL_CREDIT = 58630 // Non-existing spell as encounter credit, created in spell_dbc
};
enum Yells
@@ -237,9 +238,8 @@ public:
{
instance->SetData(DATA_MAL_GANIS_EVENT, DONE);
- // give achievement credit to players. criteria use spell 58630 which doesn't exist.
- if (instance)
- instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58630);
+ // give achievement credit and LFG rewards to players. criteria use spell 58630 which doesn't exist, but it was created in spell_dbc
+ DoCast(me, SPELL_KILL_CREDIT);
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
index 1f0342b3804..65ae3287381 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
@@ -498,7 +498,7 @@ public:
}
void DoUnmount()
{
- me->Unmount();
+ me->Dismount();
me->SetSpeed(MOVE_RUN, SPEED_RUN);
}
void EnterCombat(Unit* /*who*/)
diff --git a/src/server/scripts/Kalimdor/desolace.cpp b/src/server/scripts/Kalimdor/desolace.cpp
index 71372f1d9e4..5badc7fe725 100644
--- a/src/server/scripts/Kalimdor/desolace.cpp
+++ b/src/server/scripts/Kalimdor/desolace.cpp
@@ -25,6 +25,9 @@ EndScriptData */
/* ContentData
npc_aged_dying_ancient_kodo
+go_iruxos
+npc_dalinda_malem
+go_demon_portal
EndContentData */
#include "ScriptPCH.h"
@@ -168,22 +171,28 @@ public:
};
/*######
-## go_iruxos. Quest 5381
+## go_iruxos
+## Hand of Iruxos
######*/
+enum
+{
+ QUEST_HAND_IRUXOS = 5381,
+ NPC_DEMON_SPIRIT = 11876,
+};
+
class go_iruxos : public GameObjectScript
{
-public:
- go_iruxos() : GameObjectScript("go_iruxos") { }
+ public:
+ go_iruxos() : GameObjectScript("go_iruxos") { }
- bool OnGossipHello(Player* player, GameObject* /*pGO*/)
- {
- if (player->GetQuestStatus(5381) == QUEST_STATUS_INCOMPLETE)
- player->SummonCreature(11876, player->GetInnPosX(), player->GetInnPosY(), player->GetInnPosZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (player->GetQuestStatus(QUEST_HAND_IRUXOS) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_SPIRIT, 25.0f, true))
+ player->SummonCreature(NPC_DEMON_SPIRIT, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
return true;
- }
-
+ }
};
/*######
@@ -254,7 +263,34 @@ public:
DoMeleeAttackIfReady();
}
};
+};
+
+/*######
+## go_demon_portal
+######*/
+enum DemonPortal
+{
+ NPC_DEMON_GUARDIAN = 11937,
+
+ QUEST_PORTAL_OF_THE_LEGION = 5581,
+};
+
+class go_demon_portal : public GameObjectScript
+{
+ public:
+ go_demon_portal() : GameObjectScript("go_demon_portal") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true))
+ {
+ if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0))
+ guardian->AI()->AttackStart(player);
+ }
+
+ return true;
+ }
};
void AddSC_desolace()
@@ -262,4 +298,5 @@ void AddSC_desolace()
new npc_aged_dying_ancient_kodo();
new go_iruxos();
new npc_dalinda();
+ new go_demon_portal();
}
diff --git a/src/server/scripts/Kalimdor/durotar.cpp b/src/server/scripts/Kalimdor/durotar.cpp
index 1f64353901c..d6d2d633890 100644
--- a/src/server/scripts/Kalimdor/durotar.cpp
+++ b/src/server/scripts/Kalimdor/durotar.cpp
@@ -400,7 +400,7 @@ class npc_troll_volunteer : public CreatureScript
DoCast(me, SPELL_TURNIN);
DoCast(me, SPELL_QUEST_CREDIT);
me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK);
- me->Unmount();
+ me->Dismount();
Talk(SAY_VOLUNTEER_END);
me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
}
@@ -447,7 +447,7 @@ class spell_mount_check : public SpellScriptLoader
target->Mount(mountid);
}
else if (!owner->IsMounted() && target->IsMounted())
- target->Unmount();
+ target->Dismount();
target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN));
target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK));
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
index fd84c1eec8a..f73e9779248 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp
@@ -54,8 +54,10 @@ enum eSpells
SPELL_BLACK_KNIGHT_RES = 67693,
- SPELL_LEAP = 67749,
- SPELL_LEAP_H = 67880
+ SPELL_LEAP = 67749,
+ SPELL_LEAP_H = 67880,
+
+ SPELL_KILL_CREDIT = 68663
};
enum eModels
@@ -288,6 +290,8 @@ public:
void JustDied(Unit* /*killer*/)
{
+ DoCast(me, SPELL_KILL_CREDIT);
+
if (instance)
instance->SetData(BOSS_BLACK_KNIGHT, DONE);
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
index 2fbe381fed5..2f6a01e73d7 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
@@ -839,7 +839,8 @@ public:
if (target && me->IsInRange(target, 5.0f, 30.0f, false))
{
DoCast(target, SPELL_MULTI_SHOT);
- } else
+ }
+ else
{
Map::PlayerList const& players = me->GetMap()->GetPlayers();
if (me->GetMap()->IsDungeon() && !players.isEmpty())
@@ -849,7 +850,7 @@ public:
Player* player = itr->getSource();
if (player && !player->isGameMaster() && me->IsInRange(player, 5.0f, 30.0f, false))
{
- DoCast(target, SPELL_MULTI_SHOT);
+ DoCast(player, SPELL_MULTI_SHOT);
break;
}
}
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp
index e552341fd1e..d877bbd0842 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp
@@ -237,7 +237,8 @@ public:
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (Player* player = i->getSource())
player->DeMorph();
- instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, SPELL_ACHIEVEMENT_CHECK);
+
+ DoCast(me, SPELL_ACHIEVEMENT_CHECK);
instance->SetData(DATA_THARON_JA_EVENT, DONE);
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
index eacb800f15a..1e29ec55dc8 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
@@ -215,7 +215,6 @@ class mob_corrupted_soul_fragment : public CreatureScript
if (Creature* bronjahm = ObjectAccessor::GetCreature(*me, BronjahmGUID))
me->CastSpell(bronjahm, SPELL_CONSUME_SOUL, true);
- summ->GetMotionMaster()->MoveIdle();
summ->UnSummon();
}
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index dc2d34326a7..3712bd748a5 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -173,7 +173,11 @@ public:
DoScriptText(YELL_DEAD_2, me);
if (instance)
+ {
+ // Ingvar has MOB_INGVAR_UNDEAD id in this moment, so we have to update encounter state for his original id
+ instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, MOB_INGVAR_HUMAN, me);
instance->SetData(DATA_INGVAR_EVENT, DONE);
+ }
}
void KilledUnit(Unit* /*victim*/)
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
index 7b459e7410d..f31271b825e 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
@@ -218,7 +218,7 @@ public:
void JustReachedHome()
{
me->SetFlying(false);
- me->Unmount();
+ me->Dismount();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
if (Unit::GetCreature((*me), m_uiGraufGUID) == NULL)
me->SummonCreature(CREATURE_GRAUF, Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 3.0f);
@@ -285,7 +285,7 @@ public:
{
Phase = SKADI;
me->SetFlying(false);
- me->Unmount();
+ me->Dismount();
if (Creature* pGrauf = me->SummonCreature(CREATURE_GRAUF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3*IN_MILLISECONDS))
{
pGrauf->GetMotionMaster()->MoveFall(0);
diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp
index f94a7d2725c..87304a3f721 100644
--- a/src/server/scripts/Outland/blades_edge_mountains.cpp
+++ b/src/server/scripts/Outland/blades_edge_mountains.cpp
@@ -30,6 +30,7 @@ npc_daranelle
npc_overseer_nuaar
npc_saikkal_the_elder
go_legion_obelisk
+go_thunderspike
EndContentData */
#include "ScriptPCH.h"
@@ -537,9 +538,30 @@ public:
};
/*######
-## AddSC
+## go_thunderspike
######*/
+enum TheThunderspike
+{
+ NPC_GOR_GRIMGUT = 21319,
+ QUEST_THUNDERSPIKE = 10526,
+};
+
+class go_thunderspike : public GameObjectScript
+{
+ public:
+ go_thunderspike() : GameObjectScript("go_thunderspike") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (player->GetQuestStatus(QUEST_THUNDERSPIKE) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_GOR_GRIMGUT, 25.0f, true))
+ if (Creature* gorGrimgut = go->SummonCreature(NPC_GOR_GRIMGUT, -2413.4f, 6914.48f, 25.01f, 3.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000))
+ gorGrimgut->AI()->AttackStart(player);
+
+ return true;
+ }
+};
+
void AddSC_blades_edge_mountains()
{
new mobs_bladespire_ogre();
@@ -550,4 +572,5 @@ void AddSC_blades_edge_mountains()
new go_legion_obelisk();
new npc_bloodmaul_brutebane();
new npc_ogre_brute();
+ new go_thunderspike();
}
diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp
index 5f2626c0039..e5ee8d19c59 100644
--- a/src/server/scripts/Outland/netherstorm.cpp
+++ b/src/server/scripts/Outland/netherstorm.cpp
@@ -29,6 +29,7 @@ go_manaforge_control_console
npc_commander_dawnforge
npc_bessy
npc_maxx_a_million
+go_captain_tyralius_prison
EndContentData */
#include "ScriptPCH.h"
@@ -1046,6 +1047,36 @@ public:
}
};
+/*######
+## go_captain_tyralius_prison
+######*/
+
+enum CaptainTyralius
+{
+ NPC_CAPTAIN_TYRALIUS = 20787,
+ SAY_FREE = 0,
+};
+
+class go_captain_tyralius_prison : public GameObjectScript
+{
+ public:
+ go_captain_tyralius_prison() : GameObjectScript("go_captain_tyralius_prison") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (Creature* tyralius = go->FindNearestCreature(NPC_CAPTAIN_TYRALIUS, 1.0f))
+ {
+ go->UseDoorOrButton();
+
+ player->KilledMonsterCredit(NPC_CAPTAIN_TYRALIUS, 0);
+
+ tyralius->AI()->Talk(SAY_FREE);
+ tyralius->ForcedDespawn(8000);
+ }
+ return true;
+ }
+};
+
void AddSC_netherstorm()
{
new go_manaforge_control_console();
@@ -1056,4 +1087,5 @@ void AddSC_netherstorm()
new mob_phase_hunter();
new npc_bessy();
new npc_maxx_a_million_escort();
+ new go_captain_tyralius_prison();
}
diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp
index 610cf684a77..ecbdb921567 100644
--- a/src/server/scripts/Outland/shadowmoon_valley.cpp
+++ b/src/server/scripts/Outland/shadowmoon_valley.cpp
@@ -635,26 +635,31 @@ public:
# npc_karynaku
####*/
-enum eKarynaku
+enum Karynaku
{
QUEST_ALLY_OF_NETHER = 10870,
+ QUEST_ZUHULED_THE_WACK = 10866,
- TAXI_PATH_ID = 649
+ NPC_ZUHULED_THE_WACKED = 11980,
+
+ TAXI_PATH_ID = 649,
};
class npc_karynaku : public CreatureScript
{
-public:
- npc_karynaku() : CreatureScript("npc_karynaku") { }
+ public:
+ npc_karynaku() : CreatureScript("npc_karynaku") { }
- bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest)
- {
- if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER)
- player->ActivateTaxiPathTo(TAXI_PATH_ID); //player->ActivateTaxiPathTo(649);
+ bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
+ {
+ if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER)
+ player->ActivateTaxiPathTo(TAXI_PATH_ID);
- return true;
- }
+ if (quest->GetQuestId() == QUEST_ZUHULED_THE_WACK)
+ creature->SummonCreature(NPC_ZUHULED_THE_WACKED, -4204.94f, 316.397f, 122.508f, 1.309f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000);
+ return true;
+ }
};
/*####
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 260b0c57563..298e9b6410e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -26,6 +26,8 @@
#include "SpellAuraEffects.h"
#include "SkillDiscovery.h"
#include "GridNotifiers.h"
+#include "Group.h"
+#include "LFGMgr.h"
class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader
{
@@ -564,6 +566,9 @@ class spell_creature_permanent_feign_death : public SpellScriptLoader
Unit* target = GetTarget();
target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+
+ if (target->GetTypeId() == TYPEID_UNIT)
+ target->ToCreature()->SetReactState(REACT_PASSIVE);
}
void Register()
@@ -1419,6 +1424,53 @@ public:
}
};
+class spell_gen_luck_of_the_draw : public SpellScriptLoader
+{
+ public:
+ spell_gen_luck_of_the_draw() : SpellScriptLoader("spell_gen_luck_of_the_draw") { }
+
+ class spell_gen_luck_of_the_draw_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript);
+
+ // cheap hax to make it have update calls
+ void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude)
+ {
+ isPeriodic = true;
+ amplitude = 5 * IN_MILLISECONDS;
+ }
+
+ void Update(AuraEffect* /*effect*/)
+ {
+ if (GetUnitOwner()->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID()).begin()));
+ Group* group = GetUnitOwner()->ToPlayer()->GetGroup();
+ Map const* map = GetUnitOwner()->GetMap();
+ if (group && group->isLFGGroup())
+ if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true))
+ if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
+ if (dungeon->map == map->GetId() && dungeon->difficulty == map->GetDifficulty())
+ if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM)
+ return; // in correct dungeon
+
+ Remove(AURA_REMOVE_BY_DEFAULT);
+ }
+
+ void Register()
+ {
+ DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_gen_luck_of_the_draw_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_luck_of_the_draw_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_luck_of_the_draw_AuraScript();
+ }
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -1451,4 +1503,5 @@ void AddSC_generic_spell_scripts()
new spell_gen_vehicle_scaling();
new spell_gen_oracle_wolvar_reputation();
new spell_gen_damage_reduction_aura();
+ new spell_gen_luck_of_the_draw();
}
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 3b2cc5f5e00..ecdbd582b76 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1026,6 +1026,54 @@ public:
}
};
+// http://old01.wowhead.com/quest=9452 - Red Snapper - Very Tasty!
+enum RedSnapperVeryTasty
+{
+ SPELL_CAST_NET = 29866,
+ ITEM_RED_SNAPPER = 23614,
+ NPC_ANGRY_MURLOC = 17102,
+};
+
+class spell_q9452_cast_net: public SpellScriptLoader
+{
+ public:
+ spell_q9452_cast_net() : SpellScriptLoader("spell_q9452_cast_net") { }
+
+ class spell_q9452_cast_net_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q9452_cast_net_SpellScript)
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+
+ if (!caster)
+ return;
+
+ switch (urand(0, 2))
+ {
+ case 0: case 1:
+ caster->AddItem(ITEM_RED_SNAPPER, 1);
+ break;
+ case 2:
+ if (Creature* murloc = caster->SummonCreature(NPC_ANGRY_MURLOC, caster->GetPositionX()+5, caster->GetPositionY(), caster->GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 120000))
+ murloc->AI()->AttackStart(caster);
+ break;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHit += SpellEffectFn(spell_q9452_cast_net_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q9452_cast_net_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -1050,4 +1098,5 @@ void AddSC_quest_spell_scripts()
new spell_q12805_lifeblood_dummy();
new spell_q13280_13283_plant_battle_standard();
new spell_q14112_14145_chum_the_water();
+ new spell_q9452_cast_net();
}
diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp
index 517746dac55..7d1ed17ed29 100644
--- a/src/server/scripts/World/areatrigger_scripts.cpp
+++ b/src/server/scripts/World/areatrigger_scripts.cpp
@@ -29,6 +29,9 @@ at_legion_teleporter 4560 Teleporter TO Invasion Point: Cataclysm
at_stormwright_shelf q12741
at_last_rites q12019
at_sholazar_waygate q12548
+at_nats_landing q11209
+at_bring_your_orphan_to q910 q910 q1800 q1479 q1687 q1558 q10951 q10952
+at_brewfest
EndContentData */
#include "ScriptPCH.h"
@@ -257,6 +260,166 @@ class AreaTrigger_at_sholazar_waygate : public AreaTriggerScript
}
};
+/*######
+## at_nats_landing
+######*/
+
+enum NatsLanding
+{
+ QUEST_NATS_BARGAIN = 11209,
+ SPELL_FISH_PASTE = 42644,
+ NPC_LURKING_SHARK = 23928
+};
+
+class AreaTrigger_at_nats_landing : public AreaTriggerScript
+{
+ public:
+ AreaTrigger_at_nats_landing() : AreaTriggerScript("at_nats_landing") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/)
+ {
+ if (!player->isAlive() || !player->HasAura(SPELL_FISH_PASTE))
+ return false;
+
+ if (player->GetQuestStatus(QUEST_NATS_BARGAIN) == QUEST_STATUS_INCOMPLETE)
+ {
+ if (!player->FindNearestCreature(NPC_LURKING_SHARK, 20.0f))
+ {
+ if (Creature* shark = player->SummonCreature(NPC_LURKING_SHARK, -4246.243f, -3922.356f, -7.488f, 5.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 100000))
+ shark->AI()->AttackStart(player);
+
+ return false;
+ }
+ }
+ return true;
+ }
+};
+
+/*######
+## at_bring_your_orphan_to
+######*/
+
+enum BringYourOrphanTo
+{
+ QUEST_DOWN_AT_THE_DOCKS = 910,
+ QUEST_GATEWAY_TO_THE_FRONTIER = 911,
+ QUEST_LORDAERON_THRONE_ROOM = 1800,
+ QUEST_BOUGHT_OF_ETERNALS = 1479,
+ QUEST_SPOOKY_LIGHTHOUSE = 1687,
+ QUEST_STONEWROUGHT_DAM = 1558,
+ QUEST_DARK_PORTAL_H = 10951,
+ QUEST_DARK_PORTAL_A = 10952,
+
+ AT_DOWN_AT_THE_DOCKS = 3551,
+ AT_GATEWAY_TO_THE_FRONTIER = 3549,
+ AT_LORDAERON_THRONE_ROOM = 3547,
+ AT_BOUGHT_OF_ETERNALS = 3546,
+ AT_SPOOKY_LIGHTHOUSE = 3552,
+ AT_STONEWROUGHT_DAM = 3548,
+ AT_DARK_PORTAL = 4356,
+
+ AURA_ORPHAN_OUT = 58818,
+};
+
+class AreaTrigger_at_bring_your_orphan_to : public AreaTriggerScript
+{
+ public:
+ AreaTrigger_at_bring_your_orphan_to() : AreaTriggerScript("at_bring_your_orphan_to") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* trigger)
+ {
+ uint32 questId = 0;
+
+ if (player->isDead() || !player->HasAura(AURA_ORPHAN_OUT))
+ return false;
+
+ switch (trigger->id)
+ {
+ case AT_DOWN_AT_THE_DOCKS:
+ questId = QUEST_DOWN_AT_THE_DOCKS;
+ break;
+ case AT_GATEWAY_TO_THE_FRONTIER:
+ questId = QUEST_GATEWAY_TO_THE_FRONTIER;
+ break;
+ case AT_LORDAERON_THRONE_ROOM:
+ questId = QUEST_LORDAERON_THRONE_ROOM;
+ break;
+ case AT_BOUGHT_OF_ETERNALS:
+ questId = QUEST_BOUGHT_OF_ETERNALS;
+ break;
+ case AT_SPOOKY_LIGHTHOUSE:
+ questId = QUEST_SPOOKY_LIGHTHOUSE;
+ break;
+ case AT_STONEWROUGHT_DAM:
+ questId = QUEST_STONEWROUGHT_DAM;
+ break;
+ case AT_DARK_PORTAL:
+ questId = player->GetTeam() == ALLIANCE ? QUEST_DARK_PORTAL_A : QUEST_DARK_PORTAL_H;
+ break;
+ }
+
+ if (questId && player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
+ player->AreaExploredOrEventHappens(questId);
+
+ return true;
+ }
+};
+
+/*######
+## at_brewfest
+######*/
+
+enum Brewfest
+{
+ NPC_TAPPER_SWINDLEKEG = 24711,
+ NPC_IPFELKOFER_IRONKEG = 24710,
+
+ AT_BREWFEST_DUROTAR = 4829,
+ AT_BREWFEST_DUN_MOROGH = 4820,
+
+ SAY_WELCOME = 4,
+
+ AREATRIGGER_TALK_COOLDOWN = 5, // in seconds
+};
+
+class AreaTrigger_at_brewfest : public AreaTriggerScript
+{
+ public:
+ AreaTrigger_at_brewfest() : AreaTriggerScript("at_brewfest")
+ {
+ // Initialize for cooldown
+ _triggerTimes[AT_BREWFEST_DUROTAR] = _triggerTimes[AT_BREWFEST_DUN_MOROGH] = 0;
+ }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* trigger)
+ {
+ uint32 triggerId = trigger->id;
+ // Second trigger happened too early after first, skip for now
+ if (sWorld->GetGameTime() - _triggerTimes[triggerId] < AREATRIGGER_TALK_COOLDOWN)
+ return false;
+
+ switch (triggerId)
+ {
+ case AT_BREWFEST_DUROTAR:
+ if (Creature* tapper = player->FindNearestCreature(NPC_TAPPER_SWINDLEKEG, 20.0f))
+ tapper->AI()->Talk(SAY_WELCOME, player->GetGUID());
+ break;
+ case AT_BREWFEST_DUN_MOROGH:
+ if (Creature* ipfelkofer = player->FindNearestCreature(NPC_IPFELKOFER_IRONKEG, 20.0f))
+ ipfelkofer->AI()->Talk(SAY_WELCOME, player->GetGUID());
+ break;
+ default:
+ break;
+ }
+
+ _triggerTimes[triggerId] = sWorld->GetGameTime();
+ return false;
+ }
+
+ private:
+ std::map<uint32, time_t> _triggerTimes;
+};
+
void AddSC_areatrigger_scripts()
{
new AreaTrigger_at_coilfang_waterfall();
@@ -265,4 +428,7 @@ void AddSC_areatrigger_scripts()
new AreaTrigger_at_scent_larkorwi();
new AreaTrigger_at_last_rites();
new AreaTrigger_at_sholazar_waygate();
+ new AreaTrigger_at_nats_landing();
+ new AreaTrigger_at_bring_your_orphan_to();
+ new AreaTrigger_at_brewfest();
}
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 44c3ab9bdc9..e93dd2751e6 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -16,13 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: GO_Scripts
-SD%Complete: 100
-SDComment: Quest support: 4285, 4287, 4288(crystal pylons), 4296, 6481, 10990, 10991, 10992, Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089, 12843, 12982, 2936. Soulwell
-SDCategory: Game Objects
-EndScriptData */
-
/* ContentData
go_cat_figurine (the "trap" version of GO, two different exist)
go_northern_crystal_pylon
@@ -48,6 +41,15 @@ go_table_theka
go_soulwell
go_bashir_crystalforge
go_ethereal_teleport_pad
+go_soulwell
+go_dragonflayer_cage
+go_tadpole_cage
+go_black_cage
+go_amberpine_outhouse
+go_hive_pod
+go_gjalerbron_cage
+go_large_gjalerbron_cage
+go_veil_skith_cage
EndContentData */
#include "ScriptPCH.h"
@@ -1179,6 +1181,7 @@ public:
/*######
## Quest 1126: Hive in the Tower
+## go_hive_pod
######*/
enum eHives
@@ -1278,6 +1281,42 @@ class go_large_gjalerbron_cage : public GameObjectScript
}
};
+/*########
+#### go_veil_skith_cage
+#####*/
+
+enum MissingFriends
+{
+ QUEST_MISSING_FRIENDS = 10852,
+ NPC_CAPTIVE_CHILD = 22314,
+ SAY_FREE_0 = 0,
+};
+
+class go_veil_skith_cage : public GameObjectScript
+{
+ public:
+ go_veil_skith_cage() : GameObjectScript("go_veil_skith_cage") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (player->GetQuestStatus(QUEST_MISSING_FRIENDS) == QUEST_STATUS_INCOMPLETE)
+ {
+ std::list<Creature*> childrenList;
+ GetCreatureListWithEntryInGrid(childrenList, go, NPC_CAPTIVE_CHILD, INTERACTION_DISTANCE);
+ for (std::list<Creature*>::const_iterator itr = childrenList.begin(); itr != childrenList.end(); ++itr)
+ {
+ go->UseDoorOrButton();
+ player->KilledMonsterCredit(NPC_CAPTIVE_CHILD, (*itr)->GetGUID());
+ (*itr)->ForcedDespawn(5000);
+ (*itr)->GetMotionMaster()->MovePoint(1, go->GetPositionX()+5, go->GetPositionY(), go->GetPositionZ());
+ (*itr)->AI()->Talk(SAY_FREE_0);
+ (*itr)->GetMotionMaster()->Clear();
+ }
+ }
+ return false;
+ }
+};
+
void AddSC_go_scripts()
{
new go_cat_figurine;
@@ -1319,4 +1358,5 @@ void AddSC_go_scripts()
new go_massive_seaforium_charge;
new go_gjalerbron_cage;
new go_large_gjalerbron_cage;
+ new go_veil_skith_cage;
}
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
index 4099c03384c..9bfa77271f5 100644
--- a/src/server/scripts/World/item_scripts.cpp
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -24,7 +24,6 @@ SDCategory: Items
EndScriptData */
/* ContentData
-item_draenei_fishing_net(i23654) Hacklike implements chance to spawn item or creature
item_nether_wraith_beacon(i31742) Summons creatures for quest Becoming a Spellfire Tailor (q10832)
item_flying_machine(i34060, i34061) Engineering crafted flying machines
item_gor_dreks_ointment(i30175) Protecting Our Own(q10488)
@@ -81,45 +80,6 @@ public:
};
/*#####
-# item_draenei_fishing_net
-#####*/
-
-class item_draenei_fishing_net : public ItemScript
-{
-public:
- item_draenei_fishing_net() : ItemScript("item_draenei_fishing_net") { }
-
- //This is just a hack and should be removed from here.
- //Creature/Item are in fact created before spell are sucessfully casted, without any checks at all to ensure proper/expected behavior.
- bool OnUse(Player* player, Item* /*pItem*/, SpellCastTargets const& /*targets*/)
- {
- if (player->GetQuestStatus(9452) == QUEST_STATUS_INCOMPLETE)
- {
- if (urand(0, 99) < 35)
- {
- Creature* Murloc = player->SummonCreature(17102, player->GetPositionX(), player->GetPositionY()+20, player->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
- if (Murloc)
- Murloc->AI()->AttackStart(player);
- }
- else
- {
- ItemPosCountVec dest;
- uint32 itemId = 23614;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, 1);
- if (msg == EQUIP_ERR_OK)
- {
- if (Item* item = player->StoreNewItem(dest, itemId, true))
- player->SendNewItem(item, 1, false, true);
- }
- else
- player->SendEquipError(msg, NULL, NULL, itemId);
- }
- }
- return false;
- }
-};
-
-/*#####
# item_nether_wraith_beacon
#####*/
@@ -452,7 +412,6 @@ public:
void AddSC_item_scripts()
{
new item_only_for_flight();
- new item_draenei_fishing_net();
new item_nether_wraith_beacon();
new item_gor_dreks_ointment();
new item_incendiary_explosives();
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 38a56f7b64a..03fc07c9582 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -2026,6 +2026,16 @@ public:
{
DoCast(me, 59907, false); // Spell for Lightwell Charges
}
+
+ void EnterEvadeMode()
+ {
+ if (!me->isAlive())
+ return;
+
+ me->DeleteThreatList();
+ me->CombatStop(true);
+ me->ResetPlayerDamageReq();
+ }
};
CreatureAI* GetAI(Creature* creature) const
diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp
index 2b3e82764cf..14170845211 100644
--- a/src/server/shared/DataStores/DB2FileLoader.cpp
+++ b/src/server/shared/DataStores/DB2FileLoader.cpp
@@ -370,9 +370,6 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable)
if (strlen(format) != fieldCount)
return NULL;
- // each string field at load have array of string for each locale
- size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
-
char* stringPool= new char[stringSize];
memcpy(stringPool, stringTable, stringSize);
@@ -408,4 +405,4 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable)
}
return stringPool;
-} \ No newline at end of file
+}
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
index adf5902a591..a128eda3b70 100755
--- a/src/server/shared/Database/DatabaseWorkerPool.h
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -92,7 +92,7 @@ class DatabaseWorkerPool
++m_connectionCount[IDX_SYNCH];
}
- sLog->outSQLDriver("Databasepool opened succesfuly. %u total connections running.", (m_connectionCount[IDX_SYNCH] + m_connectionCount[IDX_ASYNC]));
+ sLog->outSQLDriver("Databasepool opened successfully. %u total connections running.", (m_connectionCount[IDX_SYNCH] + m_connectionCount[IDX_ASYNC]));
return res;
}
@@ -158,6 +158,7 @@ class DatabaseWorkerPool
}
//! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously.
+ //! Statement must be prepared with CONNECTION_ASYNC flag.
void Execute(PreparedStatement* stmt)
{
PreparedStatementTask* task = new PreparedStatementTask(stmt);
@@ -195,6 +196,7 @@ class DatabaseWorkerPool
}
//! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished.
+ //! Statement must be prepared with the CONNECTION_SYNCH flag.
void DirectExecute(PreparedStatement* stmt)
{
T* t = GetFreeConnection();
@@ -203,7 +205,7 @@ class DatabaseWorkerPool
}
/**
- Syncrhonous query (with resultset) methods.
+ Synchronous query (with resultset) methods.
*/
//! Directly executes an SQL query in string format that will block the calling thread until finished.
@@ -256,6 +258,7 @@ class DatabaseWorkerPool
//! Directly executes an SQL query in prepared format that will block the calling thread until finished.
//! Returns reference counted auto pointer, no need for manual memory management in upper level code.
+ //! Statement must be prepared with CONNECTION_SYNCH flag.
PreparedQueryResult Query(PreparedStatement* stmt)
{
T* t = GetFreeConnection();
@@ -297,6 +300,7 @@ class DatabaseWorkerPool
//! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
+ //! Statement must be prepared with CONNECTION_ASYNC flag.
PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt)
{
PreparedQueryResultFuture res;
@@ -308,6 +312,7 @@ class DatabaseWorkerPool
//! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture
//! return object as soon as the query is executed.
//! The return value is then processed in ProcessQueryCallback methods.
+ //! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag.
QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder)
{
QueryResultHolderFuture res;
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 70a5b69ae9d..c48adb8c70a 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -26,7 +26,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_ADD_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_EXPIRED_BANS, "UPDATE character_banned SET active = 0 WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate <> bandate", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_GET_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_SYNCH);
+ PREPARE_STATEMENT(CHAR_GET_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_BOTH);
PREPARE_STATEMENT(CHAR_GET_CHECK_NAME, "SELECT 1 FROM characters WHERE name = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_GET_SUM_CHARS, "SELECT COUNT(guid) FROM characters WHERE account = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_GET_CHAR_CREATE_INFO, "SELECT level, race, class FROM characters WHERE account = ? LIMIT 0, ?", CONNECTION_ASYNC);
@@ -36,6 +36,15 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_GET_GUID_BY_NAME_FILTER, "SELECT guid, name FROM characters WHERE name LIKE CONCAT('%', ?, '%')", CONNECTION_SYNCH)
PREPARE_STATEMENT(CHAR_GET_BANINFO_LIST, "SELECT bandate, unbandate, bannedby, banreason FROM character_banned WHERE guid = ? ORDER BY unbandate", CONNECTION_SYNCH)
PREPARE_STATEMENT(CHAR_GET_BANNED_NAME, "SELECT characters.name FROM characters, character_banned WHERE character_banned.guid = ? AND character_banned.guid = characters.guid", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_GET_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? ORDER BY c.guid", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? ORDER BY c.guid", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_PET_SLOTS, "SELECT owner, slot FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_PET_SLOTS_DETAIL, "SELECT owner, id, entry, level, name FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_PET_ENTRY, "SELECT entry FROM character_pet WHERE owner = ? AND id = ? AND slot >= ? AND slot <= ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_PET_SLOT_BY_ID, "SELECT slot, entry FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_FREE_NAME, "SELECT guid, name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_GET_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC);
// Start LoginQueryHolder content
PREPARE_STATEMENT(CHAR_LOAD_PLAYER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
@@ -86,6 +95,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_ADD_MAIL, "INSERT INTO mail(id, messageType, stationery, mailTemplateId, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_MAIL, "DELETE FROM mail WHERE id = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_ADD_MAIL_ITEM, "INSERT INTO mail_items(mail_id, item_guid, receiver) VALUES (?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_INVALID_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC);
PREPARE_STATEMENT(CHAR_DEL_EMPTY_EXPIRED_MAIL, "DELETE FROM mail WHERE expire_time < ? AND has_items = 0 AND body = ''", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_GET_EXPIRED_MAIL, "SELECT id, messageType, sender, receiver, has_items, expire_time, cod, checked, mailTemplateId FROM mail WHERE expire_time < ?", CONNECTION_SYNCH)
PREPARE_STATEMENT(CHAR_GET_EXPIRED_MAIL_ITEMS, "SELECT item_guid, itemEntry, mail_id FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid LEFT JOIN mail mm ON mi.mail_id = mm.id WHERE mm.id IS NOT NULL AND mm.expire_time < ?", CONNECTION_SYNCH)
@@ -111,6 +121,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_LOAD_PLAYER_NAME_CLASS, "SELECT name, class FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_LOAD_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH);
PREPARE_STATEMENT(CHAR_GET_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_NAME, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
// Guild handling
// 0: uint32, 1: string, 2: uint32, 3: string, 4: string, 5: uint64, 6-10: uint32, 11: uint64
@@ -319,4 +331,35 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"conquestPoints=?,totalHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
"watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,latency=?,speccount=?,activespec=?,exploredZones=?,"
"equipmentCache=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC);
+
+ PREPARE_STATEMENT(CHAR_UPDATE_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_ALL_AT_LOGIN_FLAGS, "UPDATE characters SET at_login = at_login | ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_ADD_BUG_REPORT, "INSERT INTO bugreport (type, content) VALUES(?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petitionguid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_ADD_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_ADD_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_ADD_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND (permanent = 1 OR instance IN (SELECT instance FROM character_instance WHERE guid = ?))", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GROUP_LEADER, "UPDATE groups SET leaderGuid = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GROUP_TYPE, "UPDATE groups SET groupType = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GROUP_MEMBER_SUBGROUP, "UPDATE group_member SET subgroup = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GROUP_MEMBER_FLAG, "UPDATE group_member SET memberFlags = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_tickets", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_INVALID_SPELL, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_ZONE, "UPDATE characters SET zone = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_LEVEL, "UPDATE characters SET level = ?, xp = 0 WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, "DELETE FROM character_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_INVALID_ACHIEVMENT, "DELETE FROM character_achievement WHERE achievement = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_ADD_ADDON, "INSERT INTO addons (name, crc) VALUES (?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_INVALID_PET_SPELL, "DELETE FROM pet_spell WHERE spell = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE, "DELETE FROM group_instance WHERE instance = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_DEL_GROUP_INSTANCE_BY_GUID, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_ADD_GROUP_INSTANCE, "REPLACE INTO group_instance (guid, instance, permanent) VALUES (?, ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_INSTANCE_RESETTIME, "UPDATE instance SET resettime = ? WHERE id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(CHAR_UPDATE_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index c84ea5544fa..7461e87f6d9 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -56,6 +56,15 @@ enum CharacterDatabaseStatements
CHAR_GET_GUID_BY_NAME_FILTER,
CHAR_GET_BANINFO_LIST,
CHAR_GET_BANNED_NAME,
+ CHAR_GET_ENUM,
+ CHAR_GET_ENUM_DECLINED_NAME,
+ CHAR_GET_PET_SLOTS,
+ CHAR_GET_PET_SLOTS_DETAIL,
+ CHAR_GET_PET_ENTRY,
+ CHAR_GET_PET_SLOT_BY_ID,
+ CHAR_GET_FREE_NAME,
+ CHAR_GET_GUID_RACE_ACC_BY_NAME,
+ CHAR_DEL_QUEST_STATUS_DAILY,
CHAR_LOAD_PLAYER,
CHAR_LOAD_PLAYER_GROUP,
CHAR_LOAD_PLAYER_BOUNDINSTANCES,
@@ -95,6 +104,7 @@ enum CharacterDatabaseStatements
CHAR_ADD_MAIL,
CHAR_DEL_MAIL,
CHAR_ADD_MAIL_ITEM,
+ CHAR_DEL_INVALID_MAIL_ITEM,
CHAR_DEL_EMPTY_EXPIRED_MAIL,
CHAR_GET_EXPIRED_MAIL,
CHAR_GET_EXPIRED_MAIL_ITEMS,
@@ -120,6 +130,8 @@ enum CharacterDatabaseStatements
CHAR_LOAD_PLAYER_NAME_CLASS,
CHAR_LOAD_MATCH_MAKER_RATING,
CHAR_GET_CHARACTER_COUNT,
+ CHAR_UPDATE_NAME,
+ CHAR_DEL_DECLINED_NAME,
CHAR_ADD_GUILD,
CHAR_DEL_GUILD,
@@ -269,6 +281,7 @@ enum CharacterDatabaseStatements
CHAR_LOAD_GM_TICKETS,
CHAR_ADD_GM_TICKET,
CHAR_DEL_GM_TICKET,
+ CHAR_DEL_ALL_GM_TICKETS,
CHAR_DEL_PLAYER_GM_TICKETS,
CHAR_ADD_GM_SURVEY,
@@ -280,6 +293,36 @@ enum CharacterDatabaseStatements
CHAR_ADD_CHARACTER,
CHAR_UPD_CHARACTER,
+ CHAR_UPDATE_AT_LOGIN_FLAG,
+ CHAR_UPDATE_ALL_AT_LOGIN_FLAGS,
+ CHAR_ADD_BUG_REPORT,
+ CHAR_UPD_PETITION_NAME,
+ CHAR_ADD_PETITION_SIGNATURE,
+ CHAR_UPD_ACCOUNT_ONLINE,
+ CHAR_ADD_GROUP,
+ CHAR_ADD_GROUP_MEMBER,
+ CHAR_DEL_GROUP_MEMBER,
+ CHAR_DEL_GROUP_INSTANCE_PERM_BINDING,
+ CHAR_UPDATE_GROUP_LEADER,
+ CHAR_UPDATE_GROUP_TYPE,
+ CHAR_UPDATE_GROUP_MEMBER_SUBGROUP,
+ CHAR_UPDATE_GROUP_MEMBER_FLAG,
+ CHAR_UPDATE_GROUP_DIFFICULTY,
+ CHAR_UPDATE_GROUP_RAID_DIFFICULTY,
+ CHAR_DEL_INVALID_SPELL,
+ CHAR_UPDATE_DELETE_INFO,
+ CHAR_UPDATE_ZONE,
+ CHAR_UPDATE_LEVEL,
+ CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA,
+ CHAR_DEL_INVALID_ACHIEVMENT,
+ CHAR_ADD_ADDON,
+ CHAR_DEL_INVALID_PET_SPELL,
+ CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE,
+ CHAR_DEL_GROUP_INSTANCE_BY_GUID,
+ CHAR_ADD_GROUP_INSTANCE,
+ CHAR_UPDATE_INSTANCE_RESETTIME,
+ CHAR_UPDATE_GLOBAL_INSTANCE_RESETTIME,
+
MAX_CHARACTERDATABASE_STATEMENTS,
};
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp
index 13cfe09914d..713d4a31e6d 100755
--- a/src/server/shared/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp
@@ -45,4 +45,15 @@ void LoginDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(LOGIN_DEL_REALMCHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ? AND realmid = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(LOGIN_ADD_REALMCHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(LOGIN_GET_SUM_REALMCHARS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_ADD_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, joindate) VALUES(?, ?, NOW())", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_ADD_REALM_CHARS, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_DEL_OLD_BANS, "DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_DEL_OLD_IP_BANS, "DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_UPDATE_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_UPDATE_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_ADD_LOG, "INSERT INTO logs (time, realm, type, string) VALUES (UNIX_TIMESTAMP(), ? , ?, ?)", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_UPDATE_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_UPDATE_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_UPDATE_MUTE_TIME, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(LOGIN_UPDATE_LAST_IP, "UPDATE account SET last_ip = ? WHERE username = ?", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h
index b5f927ffe28..98d9c505fa0 100755
--- a/src/server/shared/Database/Implementation/LoginDatabase.h
+++ b/src/server/shared/Database/Implementation/LoginDatabase.h
@@ -65,6 +65,17 @@ enum LoginDatabaseStatements
LOGIN_DEL_REALMCHARACTERS,
LOGIN_ADD_REALMCHARACTERS,
LOGIN_GET_SUM_REALMCHARS,
+ LOGIN_ADD_ACCOUNT,
+ LOGIN_ADD_REALM_CHARS,
+ LOGIN_DEL_OLD_BANS,
+ LOGIN_DEL_OLD_IP_BANS,
+ LOGIN_UPDATE_EXPANSION,
+ LOGIN_UPDATE_ACCOUNT_LOCK,
+ LOGIN_ADD_LOG,
+ LOGIN_UPDATE_USERNAME,
+ LOGIN_UPDATE_PASSWORD,
+ LOGIN_UPDATE_MUTE_TIME,
+ LOGIN_UPDATE_LAST_IP,
MAX_LOGINDATABASE_STATEMENTS,
};
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index ebf60e3d20e..5df8299310f 100755
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -26,6 +26,8 @@ void WorldDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(WORLD_DEL_CRELINKED_RESPAWN, "DELETE FROM linked_respawn WHERE guid = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(WORLD_REP_CRELINKED_RESPAWN, "REPLACE INTO linked_respawn (guid, linkedGuid) VALUES (?, ?)", CONNECTION_ASYNC)
PREPARE_STATEMENT(WORLD_LOAD_CRETEXT, "SELECT entry, groupid, id, text, type, language, probability, emote, duration, sound FROM creature_text", CONNECTION_SYNCH)
- PREPARE_STATEMENT(WORLD_LOAD_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH)
- PREPARE_STATEMENT(WORLD_LOAD_SMARTAI_WP, "SELECT entry, pointid, position_x, position_y, position_z FROM waypoints ORDER BY entry, pointid", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(WORLD_LOAD_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(WORLD_LOAD_SMARTAI_WP, "SELECT entry, pointid, position_x, position_y, position_z FROM waypoints ORDER BY entry, pointid", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(WORLD_DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?", CONNECTION_ASYNC);
+ PREPARE_STATEMENT(WORLD_DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?", CONNECTION_ASYNC);
}
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 274ea4350c9..94d6365c081 100755
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -48,6 +48,8 @@ enum WorldDatabaseStatements
WORLD_LOAD_CRETEXT,
WORLD_LOAD_SMART_SCRIPTS,
WORLD_LOAD_SMARTAI_WP,
+ WORLD_DEL_GAMEOBJECT,
+ WORLD_DEL_EVENT_GAMEOBJECT,
MAX_WORLDDATABASE_STATEMENTS,
};
diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h
index 03846c47ecd..2e134cfa814 100755
--- a/src/server/shared/Database/MySQLConnection.h
+++ b/src/server/shared/Database/MySQLConnection.h
@@ -33,6 +33,7 @@ enum ConnectionFlags
{
CONNECTION_ASYNC = 0x1,
CONNECTION_SYNCH = 0x2,
+ CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH,
};
struct MySQLConnectionInfo
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index b786fb93b8e..f5cbbec0412 100755
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -370,13 +370,17 @@ void Log::outDB(LogTypes type, const char * str)
if (!str || type >= MAX_LOG_TYPES)
return;
- std::string new_str(str);
- if (new_str.empty())
+ std::string logStr(str);
+ if (logStr.empty())
return;
- LoginDatabase.EscapeString(new_str);
- LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, string) "
- "VALUES (" UI64FMTD ", %u, %u, '%s');", uint64(time(0)), realm, type, new_str.c_str());
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_ADD_LOG);
+
+ stmt->setInt32(0, realm);
+ stmt->setInt32(1, type);
+ stmt->setString(2, logStr);
+
+ LoginDatabase.Execute(stmt);
}
void Log::outString(const char * str, ...)
diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp
index 2f669f9a428..adb58936c75 100644
--- a/src/server/shared/Packets/ByteBuffer.cpp
+++ b/src/server/shared/Packets/ByteBuffer.cpp
@@ -73,7 +73,7 @@ void BitStream::Print()
for (uint32 i = 0; i < GetLength(); ++i)
ss << uint32(GetBit(i)) << " ";
- sLog->outDebug(LOG_FILTER_NETWORKIO, ss.str().c_str());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "%s", ss.str().c_str());
}
ByteBuffer::ByteBuffer(size_t res, bool init): _rpos(0), _wpos(0), _bitpos(8), _curbitval(0)
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index bf4cf01b2be..ea64fe5434e 100755
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -57,7 +57,7 @@ class BitStream
WriteBits(val, len);
}
- BitStream(BitStream const& bs) : _rpos(bs._rpos), _wpos(bs._wpos), _data(bs._data) {}
+ BitStream(BitStream const& bs) : _data(bs._data), _rpos(bs._rpos), _wpos(bs._wpos) {}
void Clear();
uint8 GetBit(uint32 bit);
@@ -104,7 +104,7 @@ class ByteBuffer
// copy constructor
ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
- _storage(buf._storage), _bitpos(buf._bitpos), _curbitval(buf._curbitval)
+ _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf._storage)
{
}
diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h
index b179b215253..6ec2f49c8ff 100755
--- a/src/server/shared/Threading/Callback.h
+++ b/src/server/shared/Threading/Callback.h
@@ -29,107 +29,178 @@ typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
issued the request. <ParamType> is variable type of parameter that is used as parameter
for the callback function.
*/
-template <typename Result, typename ParamType>
+#define CALLBACK_STAGE_INVALID uint8(-1)
+
+template <typename Result, typename ParamType, bool chain = false>
class QueryCallback
{
public:
- QueryCallback() {}
+ QueryCallback() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
+ //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
- result = value;
+ _result = value;
}
ACE_Future<Result> GetFutureResult()
{
- return result;
+ return _result;
}
int IsReady()
{
- return result.ready();
+ return _result.ready();
}
void GetResult(Result& res)
{
- result.get(res);
+ _result.get(res);
}
void FreeResult()
{
- result.cancel();
+ _result.cancel();
}
void SetParam(ParamType value)
{
- param = value;
+ _param = value;
}
ParamType GetParam()
{
- return param;
+ return _param;
+ }
+
+ //! Resets the stage of the callback chain
+ void ResetStage()
+ {
+ if (!chain)
+ return;
+
+ _stage = 0;
+ }
+
+ //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
+ void NextStage()
+ {
+ if (!chain)
+ return;
+
+ ++_stage;
+ }
+
+ //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
+ uint8 GetStage()
+ {
+ return _stage;
+ }
+
+ //! Resets all underlying variables (param, result and stage)
+ void Reset()
+ {
+ SetParam(NULL);
+ FreeResult();
+ ResetStage();
}
private:
- ACE_Future<Result> result;
- ParamType param;
+ ACE_Future<Result> _result;
+ ParamType _param;
+ uint8 _stage;
};
-template <typename Result, typename ParamType1, typename ParamType2>
+template <typename Result, typename ParamType1, typename ParamType2, bool chain = false>
class QueryCallback_2
{
public:
- QueryCallback_2() {}
+ QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
+ //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
{
- result = value;
+ _result = value;
}
ACE_Future<Result> GetFutureResult()
{
- return result;
+ return _result;
}
int IsReady()
{
- return result.ready();
+ return _result.ready();
}
void GetResult(Result& res)
{
- result.get(res);
+ _result.get(res);
}
void FreeResult()
{
- result.cancel();
+ _result.cancel();
}
void SetFirstParam(ParamType1 value)
{
- param_1 = value;
+ _param_1 = value;
}
void SetSecondParam(ParamType2 value)
{
- param_2 = value;
+ _param_2 = value;
}
ParamType1 GetFirstParam()
{
- return param_1;
+ return _param_1;
}
ParamType2 GetSecondParam()
{
- return param_2;
+ return _param_2;
+ }
+
+ //! Resets the stage of the callback chain
+ void ResetStage()
+ {
+ if (!chain)
+ return;
+
+ _stage = 0;
+ }
+
+ //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
+ void NextStage()
+ {
+ if (!chain)
+ return;
+
+ ++_stage;
+ }
+
+ //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
+ uint8 GetStage()
+ {
+ return _stage;
+ }
+
+ //! Resets all underlying variables (param, result and stage)
+ void Reset()
+ {
+ SetFirstParam(NULL);
+ SetSecondParam(NULL);
+ FreeResult();
+ ResetStage();
}
private:
- ACE_Future<Result> result;
- ParamType1 param_1;
- ParamType2 param_2;
+ ACE_Future<Result> _result;
+ ParamType1 _param_1;
+ ParamType2 _param_2;
+ uint8 _stage;
};
#endif \ No newline at end of file
diff --git a/src/server/shared/Threading/LockedQueue.h b/src/server/shared/Threading/LockedQueue.h
index 92eab440684..4d2ddd33f5f 100755
--- a/src/server/shared/Threading/LockedQueue.h
+++ b/src/server/shared/Threading/LockedQueue.h
@@ -98,13 +98,16 @@ namespace ACE_Based
return true;
}
- //! Peeks at the top of the queue. Remember to unlock after use.
- T& peek()
+ //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
+ T& peek(bool autoUnlock = false)
{
lock();
T& result = _queue.front();
+ if (autoUnlock)
+ unlock();
+
return result;
}