1 Star 0 Fork 0

saf/Eluna

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
PlayerHooks.cpp 16.02 KB
一键复制 编辑 原始数据 按行查看 历史
Niam5 提交于 2023-10-14 23:41 . Fix builds
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
/*
* Copyright (C) 2010 - 2016 Eluna Lua Engine <http://emudevs.com/>
* This program is free software licensed under GPL version 3
* Please see the included DOCS/LICENSE.md for more information
*/
#include "Hooks.h"
#include "HookHelpers.h"
#include "LuaEngine.h"
#include "BindingMap.h"
#include "ElunaIncludes.h"
#include "ElunaTemplate.h"
using namespace Hooks;
#define START_HOOK(EVENT) \
if (!IsEnabled())\
return;\
auto key = EventKey<PlayerEvents>(EVENT);\
if (!PlayerEventBindings->HasBindingsFor(key))\
return;\
LOCK_ELUNA
#define START_HOOK_WITH_RETVAL(EVENT, RETVAL) \
if (!IsEnabled())\
return RETVAL;\
auto key = EventKey<PlayerEvents>(EVENT);\
if (!PlayerEventBindings->HasBindingsFor(key))\
return RETVAL;\
LOCK_ELUNA
void Eluna::OnLearnTalents(Player* pPlayer, uint32 talentId, uint32 talentRank, uint32 spellid)
{
START_HOOK(PLAYER_EVENT_ON_LEARN_TALENTS);
Push(pPlayer);
Push(talentId);
Push(talentRank);
Push(spellid);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnSkillChange(Player* pPlayer, uint32 skillId, uint32 skillValue)
{
START_HOOK(PLAYER_EVENT_ON_SKILL_CHANGE);
Push(pPlayer);
Push(skillId);
Push(skillValue);
int valueIndex = lua_gettop(L) - 1;
int n = SetupStack(PlayerEventBindings, key, 3);
while (n > 0)
{
int r = CallOneFunction(n--, 3, 1);
if (lua_isnumber(L, r))
{
skillValue = CHECKVAL<uint32>(L, r);
// Update the stack for subsequent calls.
ReplaceArgument(skillValue, valueIndex);
}
lua_pop(L, 1);
}
CleanUpStack(3);
}
void Eluna::OnLearnSpell(Player* pPlayer, uint32 spellId)
{
START_HOOK(PLAYER_EVENT_ON_LEARN_SPELL);
Push(pPlayer);
Push(spellId);
CallAllFunctions(PlayerEventBindings, key);
}
bool Eluna::OnCommand(Player* player, const char* text)
{
// If from console, player is NULL
if (!player || player->GetSession()->GetSecurity() >= SEC_ADMINISTRATOR)
{
std::string reload = text;
std::transform(reload.begin(), reload.end(), reload.begin(), ::tolower);
if (reload.find("reload eluna") == 0)
{
ReloadEluna();
return false;
}
}
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_COMMAND, true);
Push(player);
Push(text);
return CallAllFunctionsBool(PlayerEventBindings, key, true);
}
void Eluna::OnLootItem(Player* pPlayer, Item* pItem, uint32 count, ObjectGuid guid)
{
START_HOOK(PLAYER_EVENT_ON_LOOT_ITEM);
Push(pPlayer);
Push(pItem);
Push(count);
Push(guid);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnLootMoney(Player* pPlayer, uint32 amount)
{
START_HOOK(PLAYER_EVENT_ON_LOOT_MONEY);
Push(pPlayer);
Push(amount);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnFirstLogin(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_FIRST_LOGIN);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnRepop(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_REPOP);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnResurrect(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_RESURRECT);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnQuestAbandon(Player* pPlayer, uint32 questId)
{
START_HOOK(PLAYER_EVENT_ON_QUEST_ABANDON);
Push(pPlayer);
Push(questId);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnQuestStatusChanged(Player* pPlayer, uint32 questId, uint8 status)
{
START_HOOK(PLAYER_EVENT_ON_QUEST_STATUS_CHANGED);
Push(pPlayer);
Push(questId);
Push(status);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnEquip(Player* pPlayer, Item* pItem, uint8 bag, uint8 slot)
{
START_HOOK(PLAYER_EVENT_ON_EQUIP);
Push(pPlayer);
Push(pItem);
Push(bag);
Push(slot);
CallAllFunctions(PlayerEventBindings, key);
}
InventoryResult Eluna::OnCanUseItem(const Player* pPlayer, uint32 itemEntry)
{
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CAN_USE_ITEM, EQUIP_ERR_OK);
InventoryResult result = EQUIP_ERR_OK;
Push(pPlayer);
Push(itemEntry);
int n = SetupStack(PlayerEventBindings, key, 2);
while (n > 0)
{
int r = CallOneFunction(n--, 2, 1);
if (lua_isnumber(L, r))
result = (InventoryResult)CHECKVAL<uint32>(L, r);
lua_pop(L, 1);
}
CleanUpStack(2);
return result;
}
void Eluna::OnPlayerEnterCombat(Player* pPlayer, Unit* pEnemy)
{
START_HOOK(PLAYER_EVENT_ON_ENTER_COMBAT);
Push(pPlayer);
Push(pEnemy);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnPlayerLeaveCombat(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_LEAVE_COMBAT);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnPVPKill(Player* pKiller, Player* pKilled)
{
START_HOOK(PLAYER_EVENT_ON_KILL_PLAYER);
Push(pKiller);
Push(pKilled);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnCreatureKill(Player* pKiller, Creature* pKilled)
{
START_HOOK(PLAYER_EVENT_ON_KILL_CREATURE);
Push(pKiller);
Push(pKilled);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnPlayerKilledByCreature(Creature* pKiller, Player* pKilled)
{
START_HOOK(PLAYER_EVENT_ON_KILLED_BY_CREATURE);
Push(pKiller);
Push(pKilled);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnPlayerKilledByEnvironment(Player* pKilled, uint8 damageType)
{
START_HOOK(PLAYER_EVENT_ON_ENVIRONMENTAL_DEATH);
Push(pKilled);
Push(damageType);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnLevelChanged(Player* pPlayer, uint8 oldLevel)
{
START_HOOK(PLAYER_EVENT_ON_LEVEL_CHANGE);
Push(pPlayer);
Push(oldLevel);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnFreeTalentPointsChanged(Player* pPlayer, uint32 newPoints)
{
START_HOOK(PLAYER_EVENT_ON_TALENTS_CHANGE);
Push(pPlayer);
Push(newPoints);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnTalentsReset(Player* pPlayer, bool noCost)
{
START_HOOK(PLAYER_EVENT_ON_TALENTS_RESET);
Push(pPlayer);
Push(noCost);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnMoneyChanged(Player* pPlayer, int32& amount)
{
START_HOOK(PLAYER_EVENT_ON_MONEY_CHANGE);
Push(pPlayer);
Push(amount);
int amountIndex = lua_gettop(L);
int n = SetupStack(PlayerEventBindings, key, 2);
while (n > 0)
{
int r = CallOneFunction(n--, 2, 1);
if (lua_isnumber(L, r))
{
amount = CHECKVAL<int32>(L, r);
// Update the stack for subsequent calls.
ReplaceArgument(amount, amountIndex);
}
lua_pop(L, 1);
}
CleanUpStack(2);
}
#ifdef CATA
void Eluna::OnMoneyChanged(Player* pPlayer, int64& amount)
{
START_HOOK(PLAYER_EVENT_ON_MONEY_CHANGE);
Push(pPlayer);
Push(amount);
int amountIndex = lua_gettop(L);
int n = SetupStack(PlayerEventBindings, key, 2);
while (n > 0)
{
int r = CallOneFunction(n--, 2, 1);
if (lua_isnumber(L, r))
{
amount = CHECKVAL<int32>(L, r);
// Update the stack for subsequent calls.
ReplaceArgument(amount, amountIndex);
}
lua_pop(L, 1);
}
CleanUpStack(2);
}
#endif
void Eluna::OnGiveXP(Player* pPlayer, uint32& amount, Unit* pVictim)
{
START_HOOK(PLAYER_EVENT_ON_GIVE_XP);
Push(pPlayer);
Push(amount);
Push(pVictim);
int amountIndex = lua_gettop(L) - 1;
int n = SetupStack(PlayerEventBindings, key, 3);
while (n > 0)
{
int r = CallOneFunction(n--, 3, 1);
if (lua_isnumber(L, r))
{
amount = CHECKVAL<uint32>(L, r);
// Update the stack for subsequent calls.
ReplaceArgument(amount, amountIndex);
}
lua_pop(L, 1);
}
CleanUpStack(3);
}
void Eluna::OnReputationChange(Player* pPlayer, uint32 factionID, int32& standing, bool incremental)
{
START_HOOK(PLAYER_EVENT_ON_REPUTATION_CHANGE);
Push(pPlayer);
Push(factionID);
Push(standing);
Push(incremental);
int standingIndex = lua_gettop(L) - 1;
int n = SetupStack(PlayerEventBindings, key, 4);
while (n > 0)
{
int r = CallOneFunction(n--, 4, 1);
if (lua_isnumber(L, r))
{
standing = CHECKVAL<int32>(L, r);
// Update the stack for subsequent calls.
ReplaceArgument(standing, standingIndex);
}
lua_pop(L, 1);
}
CleanUpStack(4);
}
void Eluna::OnDuelRequest(Player* pTarget, Player* pChallenger)
{
START_HOOK(PLAYER_EVENT_ON_DUEL_REQUEST);
Push(pTarget);
Push(pChallenger);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnDuelStart(Player* pStarter, Player* pChallenger)
{
START_HOOK(PLAYER_EVENT_ON_DUEL_START);
Push(pStarter);
Push(pChallenger);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnDuelEnd(Player* pWinner, Player* pLoser, DuelCompleteType type)
{
START_HOOK(PLAYER_EVENT_ON_DUEL_END);
Push(pWinner);
Push(pLoser);
Push(type);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnEmote(Player* pPlayer, uint32 emote)
{
START_HOOK(PLAYER_EVENT_ON_EMOTE);
Push(pPlayer);
Push(emote);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnTextEmote(Player* pPlayer, uint32 textEmote, uint32 emoteNum, ObjectGuid guid)
{
START_HOOK(PLAYER_EVENT_ON_TEXT_EMOTE);
Push(pPlayer);
Push(textEmote);
Push(emoteNum);
Push(guid);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnSpellCast(Player* pPlayer, Spell* pSpell, bool skipCheck)
{
START_HOOK(PLAYER_EVENT_ON_SPELL_CAST);
Push(pPlayer);
Push(pSpell);
Push(skipCheck);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnLogin(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_LOGIN);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnLogout(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_LOGOUT);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnCreate(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_CHARACTER_CREATE);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnDelete(uint32 guidlow)
{
START_HOOK(PLAYER_EVENT_ON_CHARACTER_DELETE);
Push(guidlow);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnSave(Player* pPlayer)
{
START_HOOK(PLAYER_EVENT_ON_SAVE);
Push(pPlayer);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnBindToInstance(Player* pPlayer, Difficulty difficulty, uint32 mapid, bool permanent)
{
START_HOOK(PLAYER_EVENT_ON_BIND_TO_INSTANCE);
Push(pPlayer);
Push(difficulty);
Push(mapid);
Push(permanent);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnUpdateZone(Player* pPlayer, uint32 newZone, uint32 newArea)
{
START_HOOK(PLAYER_EVENT_ON_UPDATE_ZONE);
Push(pPlayer);
Push(newZone);
Push(newArea);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnUpdateArea(Player* pPlayer, uint32 oldArea, uint32 newArea)
{
START_HOOK(PLAYER_EVENT_ON_UPDATE_AREA);
Push(pPlayer);
Push(oldArea);
Push(newArea);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnMapChanged(Player* player)
{
START_HOOK(PLAYER_EVENT_ON_MAP_CHANGE);
Push(player);
CallAllFunctions(PlayerEventBindings, key);
}
void Eluna::OnAchievementComplete(Player* player, uint32 achievementId)
{
START_HOOK(PLAYER_EVENT_ON_ACHIEVEMENT_COMPLETE);
Push(player);
Push(achievementId);
CallAllFunctions(PlayerEventBindings, key);
}
bool Eluna::OnTradeInit(Player* trader, Player* tradee)
{
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_TRADE_INIT, true);
Push(trader);
Push(tradee);
return CallAllFunctionsBool(PlayerEventBindings, key, true);
}
bool Eluna::OnTradeAccept(Player* trader, Player* tradee)
{
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_TRADE_ACCEPT, true);
Push(trader);
Push(tradee);
return CallAllFunctionsBool(PlayerEventBindings, key, true);
}
bool Eluna::OnSendMail(Player* sender, ObjectGuid recipientGuid)
{
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_SEND_MAIL, true);
Push(sender);
Push(recipientGuid);
return CallAllFunctionsBool(PlayerEventBindings, key, true);
}
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg)
{
if (lang == LANG_ADDON)
return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, NULL);
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CHAT, true);
bool result = true;
Push(pPlayer);
Push(msg);
Push(type);
Push(lang);
int n = SetupStack(PlayerEventBindings, key, 4);
while (n > 0)
{
int r = CallOneFunction(n--, 4, 2);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
result = false;
if (lua_isstring(L, r + 1))
msg = std::string(lua_tostring(L, r + 1));
lua_pop(L, 2);
}
CleanUpStack(4);
return result;
}
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Group* pGroup)
{
if (lang == LANG_ADDON)
return OnAddonMessage(pPlayer, type, msg, NULL, NULL, pGroup, NULL);
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_GROUP_CHAT, true);
bool result = true;
Push(pPlayer);
Push(msg);
Push(type);
Push(lang);
Push(pGroup);
int n = SetupStack(PlayerEventBindings, key, 5);
while (n > 0)
{
int r = CallOneFunction(n--, 5, 2);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
result = false;
if (lua_isstring(L, r + 1))
msg = std::string(lua_tostring(L, r + 1));
lua_pop(L, 2);
}
CleanUpStack(5);
return result;
}
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Guild* pGuild)
{
if (lang == LANG_ADDON)
return OnAddonMessage(pPlayer, type, msg, NULL, pGuild, NULL, NULL);
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_GUILD_CHAT, true);
bool result = true;
Push(pPlayer);
Push(msg);
Push(type);
Push(lang);
Push(pGuild);
int n = SetupStack(PlayerEventBindings, key, 5);
while (n > 0)
{
int r = CallOneFunction(n--, 5, 2);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
result = false;
if (lua_isstring(L, r + 1))
msg = std::string(lua_tostring(L, r + 1));
lua_pop(L, 2);
}
CleanUpStack(5);
return result;
}
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Channel* pChannel)
{
if (lang == LANG_ADDON)
return OnAddonMessage(pPlayer, type, msg, NULL, NULL, NULL, pChannel);
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_CHANNEL_CHAT, true);
bool result = true;
Push(pPlayer);
Push(msg);
Push(type);
Push(lang);
Push(pChannel->GetChannelId());
int n = SetupStack(PlayerEventBindings, key, 5);
while (n > 0)
{
int r = CallOneFunction(n--, 5, 2);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
result = false;
if (lua_isstring(L, r + 1))
msg = std::string(lua_tostring(L, r + 1));
lua_pop(L, 2);
}
CleanUpStack(5);
return result;
}
bool Eluna::OnChat(Player* pPlayer, uint32 type, uint32 lang, std::string& msg, Player* pReceiver)
{
if (lang == LANG_ADDON)
return OnAddonMessage(pPlayer, type, msg, pReceiver, NULL, NULL, NULL);
START_HOOK_WITH_RETVAL(PLAYER_EVENT_ON_WHISPER, true);
bool result = true;
Push(pPlayer);
Push(msg);
Push(type);
Push(lang);
Push(pReceiver);
int n = SetupStack(PlayerEventBindings, key, 5);
while (n > 0)
{
int r = CallOneFunction(n--, 5, 2);
if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0))
result = false;
if (lua_isstring(L, r + 1))
msg = std::string(lua_tostring(L, r + 1));
lua_pop(L, 2);
}
CleanUpStack(5);
return result;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/cwero/Eluna.git
git@gitee.com:cwero/Eluna.git
cwero
Eluna
Eluna
master

搜索帮助