mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-18 11:25:42 +00:00
feat(Core/Scripts): Optimize PlayerScripts by calling only overridden/implemented functions. (#18672)
* feat(Core/Scripts): Optimize PlayerScripts by calling only overridden/implemented functions. * Fix codestyle. * Fix typo * PLAYERHOOK_END is not a hook * Address code review feedback. Co-authored-by: Winfidonarleyan <dowlandtop@yandex.com> * Codestyle fixes * Fix typo Co-authored-by: PkllonG --------- Co-authored-by: Winfidonarleyan <dowlandtop@yandex.com>
This commit is contained in:
committed by
GitHub
parent
fd029f81aa
commit
f792b0d708
File diff suppressed because it is too large
Load Diff
@@ -24,10 +24,186 @@
|
||||
#include "AchievementMgr.h"
|
||||
#include "KillRewarder.h"
|
||||
|
||||
enum PlayerHook {
|
||||
PLAYERHOOK_ON_PLAYER_JUST_DIED,
|
||||
PLAYERHOOK_ON_PLAYER_RELEASED_GHOST,
|
||||
PLAYERHOOK_ON_SEND_INITIAL_PACKETS_BEFORE_ADD_TO_MAP,
|
||||
PLAYERHOOK_ON_BATTLEGROUND_DESERTION,
|
||||
PLAYERHOOK_ON_PLAYER_COMPLETE_QUEST,
|
||||
PLAYERHOOK_ON_PVP_KILL,
|
||||
PLAYERHOOK_ON_PLAYER_PVP_FLAG_CHANGE,
|
||||
PLAYERHOOK_ON_CREATURE_KILL,
|
||||
PLAYERHOOK_ON_CREATURE_KILLED_BY_PET,
|
||||
PLAYERHOOK_ON_PLAYER_KILLED_BY_CREATURE,
|
||||
PLAYERHOOK_ON_LEVEL_CHANGED,
|
||||
PLAYERHOOK_ON_FREE_TALENT_POINTS_CHANGED,
|
||||
PLAYERHOOK_ON_TALENTS_RESET,
|
||||
PLAYERHOOK_ON_AFTER_SPEC_SLOT_CHANGED,
|
||||
PLAYERHOOK_ON_BEFORE_UPDATE,
|
||||
PLAYERHOOK_ON_UPDATE,
|
||||
PLAYERHOOK_ON_MONEY_CHANGED,
|
||||
PLAYERHOOK_ON_BEFORE_LOOT_MONEY,
|
||||
PLAYERHOOK_ON_GIVE_EXP,
|
||||
PLAYERHOOK_ON_REPUTATION_CHANGE,
|
||||
PLAYERHOOK_ON_REPUTATION_RANK_CHANGE,
|
||||
PLAYERHOOK_ON_LEARN_SPELL,
|
||||
PLAYERHOOK_ON_FORGOT_SPELL,
|
||||
PLAYERHOOK_ON_DUEL_REQUEST,
|
||||
PLAYERHOOK_ON_DUEL_START,
|
||||
PLAYERHOOK_ON_DUEL_END,
|
||||
PLAYERHOOK_ON_CHAT,
|
||||
PLAYERHOOK_ON_BEFORE_SEND_CHAT_MESSAGE,
|
||||
PLAYERHOOK_ON_CHAT_WITH_RECEIVER,
|
||||
PLAYERHOOK_ON_CHAT_WITH_GROUP,
|
||||
PLAYERHOOK_ON_CHAT_WITH_GUILD,
|
||||
PLAYERHOOK_ON_CHAT_WITH_CHANNEL,
|
||||
PLAYERHOOK_ON_EMOTE,
|
||||
PLAYERHOOK_ON_TEXT_EMOTE,
|
||||
PLAYERHOOK_ON_SPELL_CAST,
|
||||
PLAYERHOOK_ON_LOAD_FROM_DB,
|
||||
PLAYERHOOK_ON_LOGIN,
|
||||
PLAYERHOOK_ON_BEFORE_LOGOUT,
|
||||
PLAYERHOOK_ON_LOGOUT,
|
||||
PLAYERHOOK_ON_CREATE,
|
||||
PLAYERHOOK_ON_DELETE,
|
||||
PLAYERHOOK_ON_FAILED_DELETE,
|
||||
PLAYERHOOK_ON_SAVE,
|
||||
PLAYERHOOK_ON_BIND_TO_INSTANCE,
|
||||
PLAYERHOOK_ON_UPDATE_ZONE,
|
||||
PLAYERHOOK_ON_UPDATE_AREA,
|
||||
PLAYERHOOK_ON_MAP_CHANGED,
|
||||
PLAYERHOOK_ON_BEFORE_TELEPORT,
|
||||
PLAYERHOOK_ON_UPDATE_FACTION,
|
||||
PLAYERHOOK_ON_ADD_TO_BATTLEGROUND,
|
||||
PLAYERHOOK_ON_QUEUE_RANDOM_DUNGEON,
|
||||
PLAYERHOOK_ON_REMOVE_FROM_BATTLEGROUND,
|
||||
PLAYERHOOK_ON_ACHI_COMPLETE,
|
||||
PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE,
|
||||
PLAYERHOOK_ON_CRITERIA_PROGRESS,
|
||||
PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS,
|
||||
PLAYERHOOK_ON_ACHI_SAVE,
|
||||
PLAYERHOOK_ON_CRITERIA_SAVE,
|
||||
PLAYERHOOK_ON_GOSSIP_SELECT,
|
||||
PLAYERHOOK_ON_GOSSIP_SELECT_CODE,
|
||||
PLAYERHOOK_ON_BEING_CHARMED,
|
||||
PLAYERHOOK_ON_AFTER_SET_VISIBLE_ITEM_SLOT,
|
||||
PLAYERHOOK_ON_AFTER_MOVE_ITEM_FROM_INVENTORY,
|
||||
PLAYERHOOK_ON_EQUIP,
|
||||
PLAYERHOOK_ON_PLAYER_JOIN_BG,
|
||||
PLAYERHOOK_ON_PLAYER_JOIN_ARENA,
|
||||
PLAYERHOOK_GET_CUSTOM_GET_ARENA_TEAM_ID,
|
||||
PLAYERHOOK_GET_CUSTOM_ARENA_PERSONAL_RATING,
|
||||
PLAYERHOOK_ON_GET_MAX_PERSONAL_ARENA_RATING_REQUIREMENT,
|
||||
PLAYERHOOK_ON_LOOT_ITEM,
|
||||
PLAYERHOOK_ON_BEFORE_FILL_QUEST_LOOT_ITEM,
|
||||
PLAYERHOOK_ON_STORE_NEW_ITEM,
|
||||
PLAYERHOOK_ON_CREATE_ITEM,
|
||||
PLAYERHOOK_ON_QUEST_REWARD_ITEM,
|
||||
PLAYERHOOK_CAN_PLACE_AUCTION_BID,
|
||||
PLAYERHOOK_ON_GROUP_ROLL_REWARD_ITEM,
|
||||
PLAYERHOOK_ON_BEFORE_OPEN_ITEM,
|
||||
PLAYERHOOK_ON_BEFORE_QUEST_COMPLETE,
|
||||
PLAYERHOOK_ON_QUEST_COMPUTE_EXP,
|
||||
PLAYERHOOK_ON_BEFORE_DURABILITY_REPAIR,
|
||||
PLAYERHOOK_ON_BEFORE_BUY_ITEM_FROM_VENDOR,
|
||||
PLAYERHOOK_ON_BEFORE_STORE_OR_EQUIP_NEW_ITEM,
|
||||
PLAYERHOOK_ON_AFTER_STORE_OR_EQUIP_NEW_ITEM,
|
||||
PLAYERHOOK_ON_AFTER_UPDATE_MAX_POWER,
|
||||
PLAYERHOOK_ON_AFTER_UPDATE_MAX_HEALTH,
|
||||
PLAYERHOOK_ON_BEFORE_UPDATE_ATTACK_POWER_AND_DAMAGE,
|
||||
PLAYERHOOK_ON_AFTER_UPDATE_ATTACK_POWER_AND_DAMAGE,
|
||||
PLAYERHOOK_ON_BEFORE_INIT_TALENT_FOR_LEVEL,
|
||||
PLAYERHOOK_ON_FIRST_LOGIN,
|
||||
PLAYERHOOK_ON_SET_MAX_LEVEL,
|
||||
PLAYERHOOK_CAN_JOIN_IN_BATTLEGROUND_QUEUE,
|
||||
PLAYERHOOK_SHOULD_BE_REWARDED_WITH_MONEY_INSTEAD_OF_EXP,
|
||||
PLAYERHOOK_ON_BEFORE_TEMP_SUMMON_INIT_STATS,
|
||||
PLAYERHOOK_ON_BEFORE_GUARDIAN_INIT_STATS_FOR_LEVEL,
|
||||
PLAYERHOOK_ON_AFTER_GUARDIAN_INIT_STATS_FOR_LEVEL,
|
||||
PLAYERHOOK_ON_BEFORE_LOAD_PET_FROM_DB,
|
||||
PLAYERHOOK_CAN_JOIN_IN_ARENA_QUEUE,
|
||||
PLAYERHOOK_CAN_BATTLEFIELD_PORT,
|
||||
PLAYERHOOK_CAN_GROUP_INVITE,
|
||||
PLAYERHOOK_CAN_GROUP_ACCEPT,
|
||||
PLAYERHOOK_CAN_SELL_ITEM,
|
||||
PLAYERHOOK_CAN_SEND_MAIL,
|
||||
PLAYERHOOK_PETITION_BUY,
|
||||
PLAYERHOOK_PETITION_SHOW_LIST,
|
||||
PLAYERHOOK_ON_REWARD_KILL_REWARDER,
|
||||
PLAYERHOOK_CAN_GIVE_MAIL_REWARD_AT_GIVE_LEVEL,
|
||||
PLAYERHOOK_ON_DELETE_FROM_DB,
|
||||
PLAYERHOOK_CAN_REPOP_AT_GRAVEYARD,
|
||||
PLAYERHOOK_ON_PLAYER_IS_CLASS,
|
||||
PLAYERHOOK_ON_GET_MAX_SKILL_VALUE,
|
||||
PLAYERHOOK_ON_PLAYER_HAS_ACTIVE_POWER_TYPE,
|
||||
PLAYERHOOK_ON_UPDATE_GATHERING_SKILL,
|
||||
PLAYERHOOK_ON_UPDATE_CRAFTING_SKILL,
|
||||
PLAYERHOOK_ON_UPDATE_FISHING_SKILL,
|
||||
PLAYERHOOK_CAN_AREA_EXPLORE_AND_OUTDOOR,
|
||||
PLAYERHOOK_ON_VICTIM_REWARD_BEFORE,
|
||||
PLAYERHOOK_ON_VICTIM_REWARD_AFTER,
|
||||
PLAYERHOOK_ON_CUSTOM_SCALING_STAT_VALUE_BEFORE,
|
||||
PLAYERHOOK_ON_CUSTOM_SCALING_STAT_VALUE,
|
||||
PLAYERHOOK_CAN_ARMOR_DAMAGE_MODIFIER,
|
||||
PLAYERHOOK_ON_GET_FERAL_AP_BONUS,
|
||||
PLAYERHOOK_CAN_APPLY_WEAPON_DEPENDENT_AURA_DAMAGE_MOD,
|
||||
PLAYERHOOK_CAN_APPLY_EQUIP_SPELL,
|
||||
PLAYERHOOK_CAN_APPLY_EQUIP_SPELLS_ITEM_SET,
|
||||
PLAYERHOOK_CAN_CAST_ITEM_COMBAT_SPELL,
|
||||
PLAYERHOOK_CAN_CAST_ITEM_USE_SPELL,
|
||||
PLAYERHOOK_ON_APPLY_AMMO_BONUSES,
|
||||
PLAYERHOOK_CAN_EQUIP_ITEM,
|
||||
PLAYERHOOK_CAN_UNEQUIP_ITEM,
|
||||
PLAYERHOOK_CAN_USE_ITEM,
|
||||
PLAYERHOOK_CAN_SAVE_EQUIP_NEW_ITEM,
|
||||
PLAYERHOOK_CAN_APPLY_ENCHANTMENT,
|
||||
PLAYERHOOK_PASSED_QUEST_KILLED_MONSTER_CREDIT,
|
||||
PLAYERHOOK_CHECK_ITEM_IN_SLOT_AT_LOAD_INVENTORY,
|
||||
PLAYERHOOK_NOT_AVOID_SATISFY,
|
||||
PLAYERHOOK_NOT_VISIBLE_GLOBALLY_FOR,
|
||||
PLAYERHOOK_ON_GET_ARENA_PERSONAL_RATING,
|
||||
PLAYERHOOK_ON_GET_ARENA_TEAM_ID,
|
||||
PLAYERHOOK_ON_IS_FFA_PVP,
|
||||
PLAYERHOOK_ON_FFA_PVP_STATE_UPDATE,
|
||||
PLAYERHOOK_ON_IS_PVP,
|
||||
PLAYERHOOK_ON_GET_MAX_SKILL_VALUE_FOR_LEVEL,
|
||||
PLAYERHOOK_NOT_SET_ARENA_TEAM_INFO_FIELD,
|
||||
PLAYERHOOK_CAN_JOIN_LFG,
|
||||
PLAYERHOOK_CAN_ENTER_MAP,
|
||||
PLAYERHOOK_CAN_INIT_TRADE,
|
||||
PLAYERHOOK_CAN_SET_TRADE_ITEM,
|
||||
PLAYERHOOK_ON_SET_SERVER_SIDE_VISIBILITY,
|
||||
PLAYERHOOK_ON_SET_SERVER_SIDE_VISIBILITY_DETECT,
|
||||
PLAYERHOOK_ON_PLAYER_RESURRECT,
|
||||
PLAYERHOOK_ON_BEFORE_CHOOSE_GRAVEYARD,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_GROUP_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_GUILD_CHAT,
|
||||
PLAYERHOOK_CAN_PLAYER_USE_CHANNEL_CHAT,
|
||||
PLAYERHOOK_ON_PLAYER_LEARN_TALENTS,
|
||||
PLAYERHOOK_ON_PLAYER_ENTER_COMBAT,
|
||||
PLAYERHOOK_ON_PLAYER_LEAVE_COMBAT,
|
||||
PLAYERHOOK_ON_QUEST_ABANDON,
|
||||
PLAYERHOOK_ON_GET_QUEST_RATE,
|
||||
PLAYERHOOK_ON_CAN_PLAYER_FLY_IN_ZONE,
|
||||
PLAYERHOOK_ANTICHEAT_SET_CAN_FLY_BY_SERVER,
|
||||
PLAYERHOOK_ANTICHEAT_SET_UNDER_ACK_MOUNT,
|
||||
PLAYERHOOK_ANTICHEAT_SET_ROOT_ACK_UPD,
|
||||
PLAYERHOOK_ANTICHEAT_SET_JUMPING_BY_OPCODE,
|
||||
PLAYERHOOK_ANTICHEAT_UPDATE_MOVEMENT_INFO,
|
||||
PLAYERHOOK_ANTICHEAT_HANDLE_DOUBLE_JUMP,
|
||||
PLAYERHOOK_ANTICHEAT_CHECK_MOVEMENT_INFO,
|
||||
PLAYERHOOK_CAN_SEND_ERROR_ALREADY_LOOTED,
|
||||
PLAYERHOOK_ON_AFTER_CREATURE_LOOT,
|
||||
PLAYERHOOK_ON_AFTER_CREATURE_LOOT_MONEY,
|
||||
PLAYERHOOK_END
|
||||
};
|
||||
|
||||
class PlayerScript : public ScriptObject
|
||||
{
|
||||
protected:
|
||||
PlayerScript(const char* name);
|
||||
PlayerScript(const char* name, std::vector<uint16> enabledHooks = std::vector<uint16>());
|
||||
|
||||
public:
|
||||
// Called when a player dies
|
||||
|
||||
@@ -710,30 +710,42 @@ public:
|
||||
typedef std::map<uint32, TScript*> ScriptMap;
|
||||
typedef typename ScriptMap::iterator ScriptMapIterator;
|
||||
|
||||
typedef std::vector<TScript*> ScriptVector;
|
||||
typedef std::vector<std::pair<TScript*,std::vector<uint16>>> ScriptVector;
|
||||
typedef typename ScriptVector::iterator ScriptVectorIterator;
|
||||
|
||||
typedef std::vector<std::vector<TScript*>> EnabledHooksVector;
|
||||
typedef typename EnabledHooksVector::iterator EnabledHooksVectorIterator;
|
||||
|
||||
// The actual list of scripts. This will be accessed concurrently, so it must not be modified
|
||||
// after server startup.
|
||||
static ScriptMap ScriptPointerList;
|
||||
// After database load scripts
|
||||
static ScriptVector ALScripts;
|
||||
// The list of hook types with the list of enabled scripts for this specific hook.
|
||||
// With this approach, we wouldn't call all available hooks in case if we override just one hook.
|
||||
static EnabledHooksVector EnabledHooks;
|
||||
|
||||
static void AddScript(TScript* const script)
|
||||
static void AddScript(TScript* const script, std::vector<uint16> enabledHooks = {})
|
||||
{
|
||||
ASSERT(script);
|
||||
|
||||
if (!_checkMemory(script))
|
||||
return;
|
||||
|
||||
if (EnabledHooks.empty())
|
||||
EnabledHooks.resize(script->GetTotalAvailableHooks());
|
||||
|
||||
if (script->isAfterLoadScript())
|
||||
{
|
||||
ALScripts.push_back(script);
|
||||
ALScripts.emplace_back(script, std::move(enabledHooks));
|
||||
}
|
||||
else
|
||||
{
|
||||
script->checkValidity();
|
||||
|
||||
for (uint16 v : enabledHooks)
|
||||
EnabledHooks[v].emplace_back(script);
|
||||
|
||||
// We're dealing with a code-only script; just add it.
|
||||
ScriptPointerList[_scriptIdCounter++] = script;
|
||||
sScriptMgr->IncreaseScriptCount();
|
||||
@@ -742,9 +754,9 @@ public:
|
||||
|
||||
static void AddALScripts()
|
||||
{
|
||||
for(ScriptVectorIterator it = ALScripts.begin(); it != ALScripts.end(); ++it)
|
||||
for (ScriptVectorIterator it = ALScripts.begin(); it != ALScripts.end(); ++it)
|
||||
{
|
||||
TScript* const script = *it;
|
||||
TScript* const script = (*it).first;
|
||||
|
||||
script->checkValidity();
|
||||
|
||||
@@ -776,6 +788,14 @@ public:
|
||||
// If the script is already assigned -> delete it!
|
||||
if (oldScript)
|
||||
{
|
||||
for (auto& vIt : EnabledHooks)
|
||||
for (size_t i = 0; i < vIt.size(); ++i)
|
||||
if (vIt[i] == oldScript)
|
||||
{
|
||||
vIt.erase(vIt.begin() + i);
|
||||
break;
|
||||
}
|
||||
|
||||
delete oldScript;
|
||||
}
|
||||
|
||||
@@ -798,6 +818,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint16 v : (*it).second)
|
||||
EnabledHooks[v].emplace_back(script);
|
||||
|
||||
// We're dealing with a code-only script; just add it.
|
||||
ScriptPointerList[_scriptIdCounter++] = script;
|
||||
sScriptMgr->IncreaseScriptCount();
|
||||
@@ -842,7 +865,8 @@ private:
|
||||
|
||||
// Instantiate static members of ScriptRegistry.
|
||||
template<class TScript> std::map<uint32, TScript*> ScriptRegistry<TScript>::ScriptPointerList;
|
||||
template<class TScript> std::vector<TScript*> ScriptRegistry<TScript>::ALScripts;
|
||||
template<class TScript> std::vector<std::pair<TScript*,std::vector<uint16>>> ScriptRegistry<TScript>::ALScripts;
|
||||
template<class TScript> std::vector<std::vector<TScript*>> ScriptRegistry<TScript>::EnabledHooks;
|
||||
template<class TScript> uint32 ScriptRegistry<TScript>::_scriptIdCounter = 0;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,4 +69,14 @@ inline bool ReturnValidBool(Optional<bool> ret, bool need = false)
|
||||
return ret && *ret ? need : !need;
|
||||
}
|
||||
|
||||
#define CALL_ENABLED_HOOKS(scriptType, hookType, action) \
|
||||
if (!ScriptRegistry<scriptType>::EnabledHooks[hookType].empty()) \
|
||||
for (auto const& script : ScriptRegistry<scriptType>::EnabledHooks[hookType]) { action; }
|
||||
|
||||
#define CALL_ENABLED_BOOLEAN_HOOKS(scriptType, hookType, action) \
|
||||
if (ScriptRegistry<scriptType>::EnabledHooks[hookType].empty()) \
|
||||
return true; \
|
||||
for (auto const& script : ScriptRegistry<scriptType>::EnabledHooks[hookType]) { if (action) return false; } \
|
||||
return true;
|
||||
|
||||
#endif // _SCRIPT_MGR_MACRO_H_
|
||||
|
||||
@@ -53,8 +53,10 @@ public:
|
||||
|
||||
[[nodiscard]] const std::string& GetName() const { return _name; }
|
||||
|
||||
[[nodiscard]] uint16 GetTotalAvailableHooks() { return _totalAvailableHooks; }
|
||||
|
||||
protected:
|
||||
ScriptObject(const char* name) : _name(std::string(name))
|
||||
ScriptObject(const char* name, uint16 totalAvailableHooks = 0) : _name(std::string(name)), _totalAvailableHooks(totalAvailableHooks)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,6 +64,7 @@ protected:
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
const uint16 _totalAvailableHooks;
|
||||
};
|
||||
|
||||
template<class TObject>
|
||||
|
||||
Reference in New Issue
Block a user