├── .editorconfig ├── .git_commit_template.txt ├── .gitattributes ├── .github └── workflows │ ├── build-lua52.yml │ ├── build-luajit.yml │ └── core-build-base.yml ├── .gitignore ├── CMakeLists.txt ├── COMMUNITY_UPDATES.md ├── LICENSE ├── README.md ├── README_CN.md ├── README_ES.md ├── _config.yml ├── conf └── mod_eluna.conf.dist ├── icon.png ├── include.sh ├── sql ├── README.md ├── auth │ └── .gitkeep ├── characters │ └── .gitkeep └── world │ └── .gitkeep └── src ├── ElunaLuaEngine_SC.cpp ├── LuaEngine ├── .editorconfig ├── .github │ └── workflows │ │ ├── build.yml │ │ ├── create-pr.sh │ │ └── documentation.yml ├── BindingMap.h ├── CMakeLists.txt ├── ElunaCompat.cpp ├── ElunaCompat.h ├── ElunaCreatureAI.h ├── ElunaDBCRegistry.cpp ├── ElunaDBCRegistry.h ├── ElunaEventMgr.cpp ├── ElunaEventMgr.h ├── ElunaIncludes.h ├── ElunaInstanceAI.cpp ├── ElunaInstanceAI.h ├── ElunaTemplate.h ├── ElunaUtility.cpp ├── ElunaUtility.h ├── HookHelpers.h ├── Hooks.h ├── HttpManager.cpp ├── HttpManager.h ├── LuaEngine.cpp ├── LuaEngine.h ├── LuaFunctions.cpp ├── docs │ ├── .gitignore │ ├── CONTRIBUTING.md │ ├── DOC_GEN.md │ ├── Eluna.png │ ├── ElunaDoc │ │ ├── .gitignore │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── parser.py │ │ ├── static │ │ │ ├── FiraSans-Medium.woff │ │ │ ├── FiraSans-Regular.woff │ │ │ ├── Heuristica-Italic.woff │ │ │ ├── SourceCodePro-Regular.woff │ │ │ ├── SourceCodePro-Semibold.woff │ │ │ ├── SourceSerifPro-Bold.woff │ │ │ ├── SourceSerifPro-Regular.woff │ │ │ ├── dark.css │ │ │ ├── eluna-logo.png │ │ │ ├── favicon.ico │ │ │ ├── jquery.js │ │ │ ├── main.css │ │ │ ├── main.js │ │ │ └── normalize.css │ │ └── templates │ │ │ ├── _base.html │ │ │ ├── class.html │ │ │ ├── date.js │ │ │ ├── enum.html │ │ │ ├── index.html │ │ │ ├── method.html │ │ │ ├── search-index.js │ │ │ └── sidebar.js │ ├── IMPL_DETAILS.md │ ├── INSTALL.md │ ├── MERGING.md │ └── USAGE.md ├── extensions │ ├── ObjectVariables.ext │ ├── StackTracePlus │ │ ├── LICENSE │ │ ├── README.md │ │ └── StackTracePlus.ext │ └── _Misc.ext ├── hooks │ ├── BattleGroundHooks.cpp │ ├── CreatureHooks.cpp │ ├── GameObjectHooks.cpp │ ├── GossipHooks.cpp │ ├── GroupHooks.cpp │ ├── GuildHooks.cpp │ ├── InstanceHooks.cpp │ ├── ItemHooks.cpp │ ├── PacketHooks.cpp │ ├── PlayerHooks.cpp │ ├── ServerHooks.cpp │ ├── SpellHooks.cpp │ ├── TicketHooks.cpp │ └── VehicleHooks.cpp ├── libs │ ├── httplib.h │ └── rigtorp │ │ └── SPSCQueue.h ├── lmarshal.cpp ├── lmarshal.h └── methods │ ├── AchievementMethods.h │ ├── AuraMethods.h │ ├── BattleGroundMethods.h │ ├── ChatHandlerMethods.h │ ├── CorpseMethods.h │ ├── CreatureMethods.h │ ├── ElunaQueryMethods.h │ ├── GameObjectMethods.h │ ├── GemPropertiesEntryMethods.h │ ├── GlobalMethods.h │ ├── GroupMethods.h │ ├── GuildMethods.h │ ├── ItemMethods.h │ ├── ItemTemplateMethods.h │ ├── MapMethods.h │ ├── ObjectMethods.h │ ├── PlayerMethods.h │ ├── QuestMethods.h │ ├── RollMethods.h │ ├── SpellEntryMethods.h │ ├── SpellInfoMethods.h │ ├── SpellMethods.h │ ├── TicketMethods.h │ ├── UnitMethods.h │ ├── VehicleMethods.h │ ├── WorldObjectMethods.h │ └── WorldPacketMethods.h ├── eluna_loader.cpp └── lualib ├── lua ├── CMakeLists.txt └── lua.hpp └── luajit └── CMakeLists.txt /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 4 5 | tab_width = 4 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | max_line_length = 80 9 | -------------------------------------------------------------------------------- /.git_commit_template.txt: -------------------------------------------------------------------------------- 1 | ### TITLE 2 | ## Type(Scope/Subscope): Commit ultra short explanation 3 | ## |---- Write below the examples with a maximum of 50 characters ----| 4 | ## Example 1: fix(DB/SAI): Missing spell to NPC Hogger 5 | ## Example 2: fix(CORE/Raid): Phase 2 of Ragnaros 6 | ## Example 3: feat(CORE/Commands): New GM command to do something 7 | 8 | 9 | ### DESCRIPTION 10 | ## Explain why this change is being made, what does it fix etc... 11 | ## |---- Write below the examples with a maximum of 72 characters per lines ----| 12 | ## Example: Hogger (id: 492) was not charging player when being engaged. 13 | 14 | 15 | ## Provide links to any issue, commit, pull request or other resource 16 | ## Example 1: Closes issue #23 17 | ## Example 2: Ported from other project's commit (link) 18 | ## Example 3: References taken from wowpedia / wowhead / wowwiki / https://wowgaming.altervista.org/aowow/ 19 | 20 | 21 | 22 | ## ======================================================= 23 | ## EXTRA INFOS 24 | ## ======================================================= 25 | ## "Type" can be: 26 | ## feat (new feature) 27 | ## fix (bug fix) 28 | ## refactor (refactoring production code) 29 | ## style (formatting, missing semi colons, etc; no code change) 30 | ## docs (changes to documentation) 31 | ## test (adding or refactoring tests; no production code change) 32 | ## chore (updating bash scripts, git files etc; no production code change) 33 | ## -------------------- 34 | ## Remember to 35 | ## Capitalize the subject line 36 | ## Use the imperative mood in the subject line 37 | ## Do not end the subject line with a period 38 | ## Separate subject from body with a blank line 39 | ## Use the body to explain what and why rather than how 40 | ## Can use multiple lines with "-" for bullet points in body 41 | ## -------------------- 42 | ## More info here https://www.conventionalcommits.org/en/v1.0.0-beta.2/ 43 | ## ======================================================= 44 | ## "Scope" can be: 45 | ## CORE (core related, c++) 46 | ## DB (database related, sql) 47 | ## ======================================================= 48 | ## "Subscope" is optional and depends on the nature of the commit. 49 | ## ======================================================= 50 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ## AUTO-DETECT 2 | ## Handle line endings automatically for files detected as 3 | ## text and leave all files detected as binary untouched. 4 | ## This will handle all files NOT defined below. 5 | * text=auto eol=lf 6 | 7 | # Text 8 | *.conf text 9 | *.conf.dist text 10 | *.cmake text 11 | 12 | ## Scripts 13 | *.sh text 14 | *.fish text 15 | *.lua text 16 | 17 | ## SQL 18 | *.sql text 19 | 20 | ## C++ 21 | *.c text 22 | *.cc text 23 | *.cxx text 24 | *.cpp text 25 | *.c++ text 26 | *.hpp text 27 | *.h text 28 | *.h++ text 29 | *.hh text 30 | 31 | 32 | ## For documentation 33 | 34 | # Documents 35 | *.doc diff=astextplain 36 | *.DOC diff=astextplain 37 | *.docx diff=astextplain 38 | *.DOCX diff=astextplain 39 | *.dot diff=astextplain 40 | *.DOT diff=astextplain 41 | *.pdf diff=astextplain 42 | *.PDF diff=astextplain 43 | *.rtf diff=astextplain 44 | *.RTF diff=astextplain 45 | 46 | ## DOCUMENTATION 47 | *.markdown text 48 | *.md text 49 | *.mdwn text 50 | *.mdown text 51 | *.mkd text 52 | *.mkdn text 53 | *.mdtxt text 54 | *.mdtext text 55 | *.txt text 56 | AUTHORS text 57 | CHANGELOG text 58 | CHANGES text 59 | CONTRIBUTING text 60 | COPYING text 61 | copyright text 62 | *COPYRIGHT* text 63 | INSTALL text 64 | license text 65 | LICENSE text 66 | NEWS text 67 | readme text 68 | *README* text 69 | TODO text 70 | 71 | ## GRAPHICS 72 | *.ai binary 73 | *.bmp binary 74 | *.eps binary 75 | *.gif binary 76 | *.ico binary 77 | *.jng binary 78 | *.jp2 binary 79 | *.jpg binary 80 | *.jpeg binary 81 | *.jpx binary 82 | *.jxr binary 83 | *.pdf binary 84 | *.png binary 85 | *.psb binary 86 | *.psd binary 87 | *.svg text 88 | *.svgz binary 89 | *.tif binary 90 | *.tiff binary 91 | *.wbmp binary 92 | *.webp binary 93 | 94 | 95 | ## ARCHIVES 96 | *.7z binary 97 | *.gz binary 98 | *.jar binary 99 | *.rar binary 100 | *.tar binary 101 | *.zip binary 102 | 103 | ## EXECUTABLES 104 | *.exe binary 105 | *.pyc binary 106 | -------------------------------------------------------------------------------- /.github/workflows/build-lua52.yml: -------------------------------------------------------------------------------- 1 | name: Build mod-eluna with Lua52 🌙 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | - 'main' 8 | pull_request: 9 | 10 | jobs: 11 | build_lua52: 12 | uses: ./.github/workflows/core-build-base.yml 13 | with: 14 | lua_version: 'lua52' 15 | -------------------------------------------------------------------------------- /.github/workflows/build-luajit.yml: -------------------------------------------------------------------------------- 1 | name: Build mod-eluna with LuaJIT 🌙 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | - 'main' 8 | pull_request: 9 | 10 | jobs: 11 | build_luajit: 12 | uses: ./.github/workflows/core-build-base.yml 13 | with: 14 | lua_version: 'luajit' 15 | -------------------------------------------------------------------------------- /.github/workflows/core-build-base.yml: -------------------------------------------------------------------------------- 1 | name: Build mod-eluna base 🛠️ 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | lua_version: 7 | required: true 8 | type: string 9 | 10 | jobs: 11 | install_and_build: 12 | runs-on: ubuntu-24.04 13 | steps: 14 | - name: Check out AzerothCore 🧑‍💻 15 | uses: actions/checkout@v4 16 | with: 17 | repository: 'azerothcore/azerothcore-wotlk' 18 | ref: 'master' 19 | submodules: 'recursive' 20 | fetch-depth: 0 21 | 22 | - name: Check out module repository 📂 23 | uses: actions/checkout@v4 24 | with: 25 | submodules: 'recursive' 26 | path: 'modules/${{ github.event.repository.name }}' 27 | fetch-depth: 0 28 | ref: ${{ github.event.pull_request.head.sha }} 29 | 30 | - name: Cache compilation artifacts 💾 31 | uses: actions/cache@v4 32 | with: 33 | path: var/ccache 34 | key: ccache:${{ matrix.compiler.CC }}:${{ github.ref }}:${{ github.sha }} 35 | restore-keys: | 36 | ccache:clang-18:${{ github.ref }} 37 | ccache:clang-18 38 | 39 | - name: Install build dependencies 🧰 40 | shell: bash 41 | run: | 42 | sudo apt update 43 | sudo apt-get -y install ccache clang cmake curl google-perftools \ 44 | libmysqlclient-dev make unzip build-essential cmake-data \ 45 | libboost-all-dev libbz2-dev libncurses5-dev libmysql++-dev \ 46 | libreadline6-dev libssl-dev libtool openssl zlib1g-dev 47 | 48 | - name: Build mod-eluna with ${{ inputs.lua_version }} 🏗️ 49 | run: | 50 | rm -rf build 51 | mkdir build && cd build 52 | cmake .. \ 53 | -DCMAKE_C_COMPILER=clang-18 \ 54 | -DCMAKE_CXX_COMPILER=clang++-18 \ 55 | -DSCRIPTS="static" \ 56 | -DMODULES="static" \ 57 | -DWITH_WARNINGS="ON" \ 58 | -DCMAKE_BUILD_TYPE="Release" \ 59 | -DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \ 60 | -DCMAKE_C_COMPILER_LAUNCHER="ccache" \ 61 | -DCMAKE_C_FLAGS="-Werror" \ 62 | -DCMAKE_CXX_FLAGS="-Werror" \ 63 | -DLUA_VERSION=${{ inputs.lua_version }} 64 | make -j$(nproc) 65 | cd .. 66 | 67 | - name: Run Cppcheck for static code analysis 🔍 68 | run: | 69 | sudo apt update -y 70 | sudo apt install -y cppcheck 71 | cd modules/${{ github.event.repository.name }} 72 | cppcheck -j$(nproc) --force --inline-suppr \ 73 | -I src/LuaEngine/ \ 74 | -I src/ \ 75 | --suppress=*:src/lualib/* \ 76 | --suppress=*:src/LuaEngine/libs/* \ 77 | --output-file=report.txt \ 78 | . 79 | if [ -s report.txt ]; then 80 | echo "Cppcheck detected issues 🚨:" 81 | cat report.txt 82 | exit 1 83 | else 84 | echo "No issues detected by cppcheck ✅." 85 | fi 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | 3 | # 4 | #Generic 5 | # 6 | 7 | .directory 8 | .mailmap 9 | *.orig 10 | *.rej 11 | *.*~ 12 | .hg/ 13 | *.kdev* 14 | .DS_Store 15 | CMakeLists.txt.user 16 | *.bak 17 | *.patch 18 | *.diff 19 | *.REMOTE.* 20 | *.BACKUP.* 21 | *.BASE.* 22 | *.LOCAL.* 23 | 24 | # 25 | # IDE & other softwares 26 | # 27 | /.settings/ 28 | /.externalToolBuilders/* 29 | # exclude in all levels 30 | nbproject/ 31 | .sync.ffs_db 32 | *.kate-swp 33 | 34 | # 35 | # Eclipse 36 | # 37 | *.pydevproject 38 | .metadata 39 | .gradle 40 | tmp/ 41 | *.tmp 42 | *.swp 43 | *~.nib 44 | local.properties 45 | .settings/ 46 | .loadpath 47 | .project 48 | .cproject 49 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LUA_VERSION "lua52" CACHE STRING "Lua version to use") 2 | set_property(CACHE LUA_VERSION PROPERTY STRINGS luajit lua51 lua52 lua53 lua54) 3 | MESSAGE(STATUS "Lua version: ${LUA_VERSION}") 4 | 5 | # Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: 6 | if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") 7 | cmake_policy(SET CMP0135 NEW) 8 | endif() 9 | 10 | option(LUA_STATIC "link lua statically" ON) 11 | if (LUA_STATIC) 12 | MESSAGE(STATUS "Lua linking: static") 13 | else() 14 | MESSAGE(STATUS "Lua linking: dynamic") 15 | endif() 16 | 17 | if (LUA_VERSION MATCHES "luajit") 18 | add_subdirectory(src/lualib/luajit) 19 | set(LUAJIT_VERSION true) 20 | else() 21 | add_subdirectory(src/lualib/lua) 22 | set(LUAJIT_VERSION false) 23 | endif() 24 | 25 | set_target_properties(lualib PROPERTIES INTERFACE_COMPILE_DEFINITIONS LUAJIT_VERSION) 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # [![Eluna](src/LuaEngine/docs/Eluna.png)](https://github.com/ElunaLuaEngine/Eluna) 4 | 5 | *Unleash the power of Lua scripting in your AzerothCore server* 6 | 7 | [![Discord](https://img.shields.io/badge/Discord-Join%20Us-7289DA?style=for-the-badge&logo=discord&logoColor=white)](https://discord.com/invite/ZKSVREE7) 8 | [![Lua](https://img.shields.io/badge/Lua-5.2-2C2D72?style=for-the-badge&logo=lua&logoColor=white)](http://www.lua.org/manual/5.2/) 9 | [![AzerothCore](https://img.shields.io/badge/AzerothCore-Integrated-darkgreen?style=for-the-badge)](http://www.azerothcore.org/) 10 | 11 | --- 12 |
13 | 14 | > [!NOTE] 15 | > mod-eluna © is a powerful Lua scripting engine embedded into the AzerothCore emulator. We are committed to continuously improving mod-eluna for both developers and server administrators. 16 | 17 |
18 | 🎯 Table of Contents 19 | 20 | - [Acknowledgements](#-acknowledgements) 21 | - [Support & Resources](#-support--resources) 22 | - [Installation](#-installation) 23 | - [Documentation](#-eluna-documentation) 24 | - [Useful Links](#-useful-links) 25 | - [Community Additions](#%EF%B8%8F-community-additions) 26 | - [Contributing](#-contributing) 27 |
28 | 29 | ## 🌟 Acknowledgements 30 |
31 | 32 | ***Built on the shoulders of giants*** 33 |
34 | 35 | mod-eluna is a fork of the original [Eluna](https://github.com/ElunaLuaEngine/Eluna) project. We extend our heartfelt gratitude to the Eluna team for their work. 36 | 37 | > **Explore More:** 38 | > - [Original Github](https://github.com/ElunaLuaEngine/Eluna) 39 | > - [Eluna Discord](https://discord.gg/bjkCVWqqfX) 40 | 41 | ## 💡 Support & Resources 42 | 43 | ### Need Help? 44 | Feel free to open an issue for installation or scripting problems. 45 | 46 | ### Quick Links 47 | - 📚 [mod-eluna API](https://www.azerothcore.org/eluna/) 48 | - 📖 [Lua Reference](http://www.lua.org/manual/5.2/) 49 | 50 | 51 | 52 | ## ⚡ Installation 53 | 54 | ### Prerequisites 55 | - AzerothCore installation 56 | - Git 57 | - CMake 58 | 59 | ### Quick Install 60 | ```bash 61 | # Navigate to modules directory 62 | cd modules 63 | 64 | # Clone the repository 65 | git clone https://github.com/azerothcore/mod-eluna.git 66 | 67 | # Build using CMake 68 | # You can choose your Lua version during cmake configuration using: 69 | # -DLUA_VERSION={luajit, lua52, lua53, lua54} 70 | # Example: 71 | cmake ../ -DLUA_VERSION=luajit 72 | 73 | # If no Lua version is specified, Lua 5.2 will be used by default 74 | 75 | # Follow your normal build process 76 | ``` 77 | 78 | ## 📚 Eluna Documentation 79 | > [!WARNING] 80 | > Please note that some mod-eluna functions may not be available on Eluna and vice versa. 81 | - [Getting Started](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/USAGE.md) 82 | - [Eluna Features](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/IMPL_DETAILS.md) 83 | 84 | ### AzerothCore 85 | - [mod-eluna API](https://www.azerothcore.org/eluna/) 86 | - [Hooks Documentation](https://github.com/azerothcore/mod-eluna/blob/master/src/LuaEngine/Hooks.h) 87 | 88 | ### Others emulators (TC, MaNGOS, CMaNGOS etc.) 89 | - [Eluna API](https://elunaluaengine.github.io/index.html) 90 | - [Hooks Documentation](https://github.com/ElunaLuaEngine/Eluna/blob/master/hooks/Hooks.h) 91 | 92 | ## 🔗 Useful Links 93 | - [💻 Lua.org](http://www.lua.org/) 94 | - [📜 License](https://github.com/azerothcore/mod-eluna/blob/master/LICENSE) 95 | 96 | - [🎮 MaNGOS](https://www.getmangos.eu/) 97 | - [🎮 cMaNGOS](https://cmangos.net/) 98 | - [🎮 TrinityCore](https://www.trinitycore.org/) 99 | - [🎮 AzerothCore](http://www.azerothcore.org/) 100 | 101 | ## 🛠️ Community Additions 102 | 103 | > [!TIP] 104 | > Our community has contributed numerous valuable features to enhance mod-eluna's capabilities. 105 | 106 |
107 | Click to expand feature list 108 | 109 | ### Player Events 110 | ```lua 111 | PLAYER_EVENT_ON_PET_ADDED_TO_WORLD 112 | PLAYER_EVENT_ON_LEARN_SPELL 113 | PLAYER_EVENT_ON_UPDATE_AREA 114 | ``` 115 | 116 | ### Unit Methods 117 | ```lua 118 | Unit:ModifyThreatPct() 119 | Unit:GetAttackers() 120 | Unit:SetSpeedRate(unitMoveType, speed) 121 | ``` 122 | 123 | ### Miscellaneous Features 124 | ```lua 125 | HttpRequest() 126 | WorldDBQueryAsync 127 | CharDBQueryAsync 128 | AuthDBQueryAsync 129 | ``` 130 |
131 | 132 | > For a complete list of community contributions, check our [Community Updates](https://github.com/azerothcore/mod-eluna/blob/master/COMMUNITY_UPDATES.md). 133 | 134 | ## 🤝 Contributing 135 | 136 | We welcome contributions! Here's how you can help: 137 | 138 | ```mermaid 139 | graph LR 140 | A[Fork Repository] --> B[Create Branch] 141 | B --> C[Make Changes] 142 | C --> D[Submit PR] 143 | D --> E[Review Process] 144 | ``` 145 | 146 |
147 | 148 | --- 149 | Made with ❤️ by the Eluna Community 150 | 151 | [⬆ Back to Top](#) 152 |
153 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | ### [![Eluna](src/LuaEngine/docs/Eluna.png)](https://github.com/ElunaLuaEngine/Eluna) 2 | 3 | ## 关于 4 | 5 | Eluna Lua Engine © 是嵌入到魔兽世界模拟器中的lua引擎。 Eluna支持MaNGOS,CMaNGOS,TrinityCore和AzerothCore。 6 | 我们目前正在努力使Eluna从内到外变得更好。 7 | 8 | 如果您在安装或脚本方面遇到问题,请随时提出问题。 9 | 有关文档和参考,请参阅[Eluna API (AC版)](https://www.azerothcore.org/pages/eluna/index.html) and [Lua 参考手册](http://www.lua.org/manual/5.2/). 10 | 11 | 12 | ## 社区 13 | 14 | 您可以加入官方的Eluna Discord服务器,在那里您将能够找到社区提供的资源,版本和支持: 15 | 16 | 17 | 18 | 19 | 官方的Azerothcore Discord服务器也提供了一个专门用于lua开发的通道: 20 | 21 | 22 | 23 | 24 | # ![logo](https://raw.githubusercontent.com/azerothcore/azerothcore.github.io/master/images/logo-github.png) mod-eluna for AzerothCore 25 | - azerothcore 的最新构建状态:[![Build Status](https://github.com/azerothcore/mod-eluna/workflows/core-build/badge.svg?branch=master&event=push)](https://github.com/azerothcore/mod-eluna) 26 | 27 | [english](README.md) | [中文说明](README_CN.md) | [Español](README_ES.md) 28 | 29 | 一个AzerothCore的[Eluna](https://github.com/ElunaLuaEngine/Eluna)模块。 30 | 31 | 32 | ## 如何安装: 33 | 34 | ### 1) 下载源代码 35 | 36 | 您可以使用 git 获取源代码。 37 | 38 | 39 | #### 使用 git 下载 40 | 41 | 1. 在命令行中打开 `azerothcore-wotlk` 的文件夹。 42 | 2. 进入 **modules** 文件夹: `cd modules` 43 | 3. 使用以下命令下载模块源代码。 44 | ``` 45 | git clone https://github.com/azerothcore/mod-eluna.git mod-eluna 46 | ``` 47 | 48 | ### 2) 构建 49 | 50 | 您需要再次运行 cmake 并重新生成项目。 51 | 52 | AC版的Eluna API: 53 | [https://www.azerothcore.org/pages/eluna/index.html](https://www.azerothcore.org/pages/eluna/index.html) 54 | 55 | 56 | ## 文档 57 | 58 | * [入门指南](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/USAGE.md) 59 | * [Eluna特性](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/IMPL_DETAILS.md) 60 | * [功能文档(AC版本)](https://www.azerothcore.org/pages/eluna/index.html) 61 | * [Hook文档](https://github.com/ElunaLuaEngine/Eluna/blob/master/Hooks.h) 62 | * [Lua参考手册](http://www.lua.org/manual/5.2/) 63 | * [论坛 - 支持, 发布, 指南](https://www.getmangos.eu/forums/forum/119-eluna-central/) 64 | * [示例脚本](https://github.com/ElunaLuaEngine/Scripts) 65 | * [贡献](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/CONTRIBUTING.md) 66 | 67 | 68 | ## 链接 69 | 70 | * [MaNGOS](http://getmangos.eu/) 71 | * [cMaNGOS](http://cmangos.net/) 72 | * [TrinityCore](http://www.trinitycore.org/) 73 | * [AzerothCore](http://www.azerothcore.org/) 74 | * [Lua.org](http://www.lua.org/) 75 | * [License](https://github.com/ElunaLuaEngine/Eluna/blob/master/docs/LICENSE.md) 76 | 77 | 78 | ## 来自Eluna/master的拓展 79 | 80 | - 添加了 HttpRequest 方法. https://github.com/azerothcore/Eluna/pull/2 81 | - 添加玩家注册事件43(当宠物添加到世界中时): `PLAYER_EVENT_ON_PET_ADDED_TO_WORLD` https://github.com/azerothcore/Eluna/pull/3 82 | - 添加聊天处理方法到玩家事件中。 https://github.com/azerothcore/Eluna/pull/23 83 | - 暴露方法 `ModifyThreatPct()`. https://github.com/azerothcore/Eluna/pull/25 84 | - 暴露方法 `Object:IsPlayer()`. https://github.com/azerothcore/Eluna/pull/42 85 | - 添加玩家注册事件44(当玩家学习技能时): `PLAYER_EVENT_ON_LEARN_SPELL`. https://github.com/azerothcore/mod-eluna/pull/46 86 | - 添加玩家注册事件45(当玩家完成成就时): `PLAYER_ON_ACHIEVEMENT_COMPLETE`。 https://github.com/azerothcore/mod-eluna/pull/47 87 | - 添加玩家注册事件51(当玩家获得任务奖励时) `PLAYER_EVENT_ON_QUEST_REWARD_ITEM`。https://github.com/azerothcore/mod-eluna/pull/88 88 | - 添加玩家注册事件52(当玩家创建物品时) `PLAYER_EVENT_ON_CREATE_ITEM`。https://github.com/azerothcore/mod-eluna/pull/88 89 | - 添加玩家注册事件53(当玩家创建物品实例时) `PLAYER_EVENT_ON_STORE_NEW_ITEM`。https://github.com/azerothcore/mod-eluna/pull/88 90 | - 添加玩家注册事件54(当玩家完成任务时) `PLAYER_EVENT_ON_COMPLETE_QUEST`。https://github.com/azerothcore/mod-eluna/pull/90 91 | - 新增参数*商人Id*到方法player:SendListInventory(object, vendorentry)中。 https://github.com/azerothcore/mod-eluna/pull/48 92 | - 添加方法`gameobject:AddLoot()`, 可以在线给**空**的容器中添加战利品。 https://github.com/azerothcore/mod-eluna/pull/52 93 | -------------------------------------------------------------------------------- /README_ES.md: -------------------------------------------------------------------------------- 1 | # Esta traducción proviene de una versión desactualizada. 2 | ## 3 | ## 4 | ## 5 | ## 6 | 7 | # mod-LuaEngine 8 | [English](README.md) | [中文说明](README_CN.md) | [Español](README_ES.md) 9 | 10 | Un módulo de Eluna para AzerothCore. 11 | 12 | Cómo instalar: 13 | 14 | 1. Descargar o clonar este módulo: 15 | > [Descargar archivo zip](https://github.com/azerothcore/mod-eluna-lua-engine/archive/master.zip) 16 | > o clonar `git clone https://github.com/azerothcore/mod-eluna-lua-engine.git` 17 | 2. Póngalo en la carpeta de módulos del Azerothcore. 18 | > $HOME/azerothcore/modules/ 19 | 3. Descargar o clonar el archivo central de ELUNA: 20 | > [Descargar archivo zip](https://github.com/ElunaLuaEngine/Eluna/archive/master.zip) 21 | > o clonar `git clone https://github.com/ElunaLuaEngine/Eluna.git .` 22 | 4. Dentro de la carpeta del módulo de Eluna de Azeroth, se encuentra una carpeta / directorio llamado: `LuaEngine` (mod-eluna-lua-engine/LuaEngine). Debe depositar los ficheros de lua, directamente dentro de esa carpeta. Los archivos directamente, no un directorio y luego los ficheros dentro. Por eso te utiliza el “.” cuando se está clonando, para que no genere un directorio nuevo. 23 | 5. Una vez copiado los ficheros y descargado el modulo, debes volver a compilar. Si seguiste la guía de instalación, debiste haber generado un directorio build, dentro de azerothcore. Dirígete a él y realiza la compilación como lo menciona en la guía. 24 | 25 | Eluna API : 26 | [http://elunaluaengine.github.io/](http://elunaluaengine.github.io/) 27 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-architect -------------------------------------------------------------------------------- /conf/mod_eluna.conf.dist: -------------------------------------------------------------------------------- 1 | [worldserver] 2 | 3 | ################################################################################################### 4 | # ELUNA SETTINGS 5 | # 6 | # Eluna.Enabled 7 | # Description: Enable or disable Eluna LuaEngine 8 | # Default: true - (enabled) 9 | # false - (disabled) 10 | # 11 | # Eluna.TraceBack 12 | # Description: Sets whether to use debug.traceback function on a lua error or not. 13 | # Notice that you can redefine the function. 14 | # Default: false - (use default error output) 15 | # true - (use debug.traceback function) 16 | # 17 | # Eluna.ScriptPath 18 | # Description: Sets the location of the script folder to load scripts from 19 | # The path can be relative or absolute. 20 | # Default: "lua_scripts" 21 | # 22 | # Eluna.PlayerAnnounceReload 23 | # Description: Enable or disable whether the reload announcement is sent to players (Lowest security level). 24 | # Default: false - (disabled) 25 | # true - (enabled) 26 | # 27 | # Eluna.RequirePaths 28 | # Description: Sets the location of additional require paths. 29 | # These paths are absolute and follows the standard Lua require path patterns. 30 | # Below are a set of "standard" paths used by most package managers. 31 | # "/usr/share/%s/?.lua;/usr/local/share/lua/%s/?.lua;/usr/local/share/lua/%s/?/init.lua;/usr/share/lua/%s/?.lua;/usr/share/lua/%s/?/init.lua;" 32 | # Default: "" 33 | # 34 | # Eluna.RequireCPaths 35 | # Description: Sets the location of additional require C paths. 36 | # These paths are absolute and follows the standard Lua require path patterns. 37 | # Below are a set of "standard" paths used by most package managers. 38 | # "/usr/local/lib/lua/%s/?.so;/usr/lib/x86_64-linux-gnu/lua/%s/?.so;/usr/local/lib/lua/%s/loadall.so;" 39 | # Default: "" 40 | 41 | Eluna.Enabled = true 42 | Eluna.TraceBack = false 43 | Eluna.ScriptPath = "lua_scripts" 44 | Eluna.PlayerAnnounceReload = false 45 | Eluna.RequirePaths = "" 46 | Eluna.RequireCPaths = "" 47 | 48 | ################################################################################################### 49 | # LOGGING SYSTEM SETTINGS 50 | # 51 | # Appender config values: Given an appender "name" 52 | # Appender.name 53 | # Description: Defines 'where to log'. 54 | # Format: Type,LogLevel,Flags,optional1,optional2,optional3 55 | # 56 | # Type 57 | # 0 - (None) 58 | # 1 - (Console) 59 | # 2 - (File) 60 | # 3 - (DB) 61 | # 62 | # LogLevel 63 | # 0 - (Disabled) 64 | # 1 - (Fatal) 65 | # 2 - (Error) 66 | # 3 - (Warning) 67 | # 4 - (Info) 68 | # 5 - (Debug) 69 | # 6 - (Trace) 70 | # 71 | # Flags: 72 | # 0 - None 73 | # 1 - Prefix Timestamp to the text 74 | # 2 - Prefix Log Level to the text 75 | # 4 - Prefix Log Filter type to the text 76 | # 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS 77 | # (Only used with Type = 2) 78 | # 16 - Make a backup of existing file before overwrite 79 | # (Only used with Mode = w) 80 | # 81 | # Colors (read as optional1 if Type = Console) 82 | # Format: "fatal error warn info debug trace" 83 | # 0 - BLACK 84 | # 1 - RED 85 | # 2 - GREEN 86 | # 3 - BROWN 87 | # 4 - BLUE 88 | # 5 - MAGENTA 89 | # 6 - CYAN 90 | # 7 - GREY 91 | # 8 - YELLOW 92 | # 9 - LRED 93 | # 10 - LGREEN 94 | # 11 - LBLUE 95 | # 12 - LMAGENTA 96 | # 13 - LCYAN 97 | # 14 - WHITE 98 | # Example: "1 9 3 6 5 8" 99 | # 100 | # File: Name of the file (read as optional1 if Type = File) 101 | # Allows to use one "%s" to create dynamic files 102 | # 103 | # Mode: Mode to open the file (read as optional2 if Type = File) 104 | # a - (Append) 105 | # w - (Overwrite) 106 | # 107 | # MaxFileSize: Maximum file size of the log file before creating a new log file 108 | # (read as optional3 if Type = File) 109 | # Size is measured in bytes expressed in a 64-bit unsigned integer. 110 | # Maximum value is 4294967295 (4 GB). Leave blank for no limit. 111 | # NOTE: Does not work with dynamic filenames. 112 | # Example: 536870912 (512 MB) 113 | # 114 | Appender.ElunaLog=2,5,0,eluna.log,w 115 | Appender.ElunaConsole=1,4,0,"0 9 0 3 5 0" 116 | 117 | # Logger config values: Given a logger "name" 118 | # Logger.name 119 | # Description: Defines 'What to log' 120 | # Format: LogLevel,AppenderList 121 | # 122 | # LogLevel 123 | # 0 - (Disabled) 124 | # 1 - (Fatal) 125 | # 2 - (Error) 126 | # 3 - (Warning) 127 | # 4 - (Info) 128 | # 5 - (Debug) 129 | # 6 - (Trace) 130 | # 131 | # AppenderList: List of appenders linked to logger 132 | # (Using spaces as separator). 133 | # 134 | Logger.eluna=4,ElunaLog ElunaConsole 135 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/icon.png -------------------------------------------------------------------------------- /include.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/include.sh -------------------------------------------------------------------------------- /sql/README.md: -------------------------------------------------------------------------------- 1 | # BEST PRACTICES 2 | 3 | ## Create a new table 4 | 5 | **Example:** 6 | ``` 7 | CREATE TABLE IF NOT EXISTS `table`( 8 | `id` int(11) unsigned NOT NULL, 9 | `active` BOOLEAN DEFAULT NULL, 10 | PRIMARY KEY (`id`) 11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 12 | ``` 13 | 14 | **Boolean datatype in mysql:** 15 | Use "TinyInt(1)"" or "Boolean" (this is the same thing) 16 | 17 | "bit(1)" can also work, but it may require a syntax like b'(0) and b'(1) when inserting (not sure). 18 | 19 | If there are multiple booleans in the same table, bit(1) is better, otherwise it's the same result. 20 | 21 | 22 | ## Resources 23 | 24 | https://www.w3schools.com/sql/sql_datatypes.asp 25 | -------------------------------------------------------------------------------- /sql/auth/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/sql/auth/.gitkeep -------------------------------------------------------------------------------- /sql/characters/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/sql/characters/.gitkeep -------------------------------------------------------------------------------- /sql/world/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/sql/world/.gitkeep -------------------------------------------------------------------------------- /src/LuaEngine/.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | indent_style = space 4 | indent_size = 4 5 | tab_width = 4 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | -------------------------------------------------------------------------------- /src/LuaEngine/.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | 9 | AC-Eluna: 10 | strategy: 11 | fail-fast: false 12 | runs-on: ubuntu-20.04 13 | steps: 14 | - uses: actions/checkout@v2 15 | with: 16 | submodules: recursive 17 | repository: azerothcore/azerothcore-wotlk 18 | ref: 'master' 19 | - uses: actions/checkout@v2 20 | with: 21 | submodules: false 22 | repository: azerothcore/mod-eluna-lua-engine 23 | path: modules/mod-eluna-lua-engine 24 | - uses: actions/checkout@v2 25 | with: 26 | path: modules/mod-eluna-lua-engine/LuaEngine 27 | - name: Configure OS 28 | run: | 29 | # Copy paste of https://github.com/azerothcore/azerothcore-wotlk/blob/master/apps/ci/ci-install.sh 30 | 31 | cat >>conf/config.sh <> ./conf/config.sh 55 | echo "CCOMPILERCXX=\"clang++-11\"" >> ./conf/config.sh 56 | - name: Import db 57 | run: source ./apps/ci/ci-import-db.sh 58 | - name: Build 59 | run: source ./apps/ci/ci-compile.sh 60 | - name: Dry run 61 | run: source ./apps/ci/ci-worldserver-dry-run.sh 62 | - name: Check startup errors 63 | run: source ./apps/ci/ci-error-check.sh 64 | -------------------------------------------------------------------------------- /src/LuaEngine/.github/workflows/create-pr.sh: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/paygoc6/action-pull-request-another-repo 2 | 3 | CLONE_DIR=$(mktemp -d) 4 | 5 | echo "Setting git variables" 6 | export GITHUB_TOKEN=$API_TOKEN_GITHUB 7 | git config --global user.email "$USER_EMAIL" 8 | git config --global user.name "$USER_NAME" 9 | 10 | echo "Cloning destination git repository" 11 | git clone "https://$API_TOKEN_GITHUB@github.com/$DESTINATION_REPO.git" "$CLONE_DIR" 12 | cd "$CLONE_DIR" 13 | git checkout "$DESTINATION_BASE_BRANCH" 14 | git pull origin "$DESTINATION_BASE_BRANCH" 15 | git checkout -b "$DESTINATION_HEAD_BRANCH" 16 | 17 | echo "Copying contents to git repo" 18 | mkdir -p "$CLONE_DIR/$DESTINATION_FOLDER" 19 | cp -r "$SOURCE_FOLDER/." "$CLONE_DIR/$DESTINATION_FOLDER/" 20 | 21 | echo "Adding files" 22 | git add . 23 | if git status | grep -q "Changes to be committed" 24 | then 25 | echo "Adding git commit" 26 | git commit -m "$COMMIT_MESSAGE" 27 | echo "Pushing git commit" 28 | git push -u origin "$DESTINATION_HEAD_BRANCH" 29 | echo "Creating a pull request" 30 | gh pr create -t "$PR_TITLE" \ 31 | -B "$DESTINATION_BASE_BRANCH" \ 32 | -b "" \ 33 | -H "$DESTINATION_HEAD_BRANCH" 34 | else 35 | echo "No changes detected" 36 | fi 37 | -------------------------------------------------------------------------------- /src/LuaEngine/.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | - 'master' 7 | jobs: 8 | Push-Docs-To-AzerothCore-Website: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Check out repository code 12 | uses: actions/checkout@v2 13 | - name: Set up Python 14 | uses: actions/setup-python@v2 15 | with: 16 | python-version: '3.x' 17 | architecture: 'x64' 18 | - name: Install Python dependencies 19 | run: pip install jinja2 typedecorator markdown 20 | - name: Compile documentation 21 | run: | 22 | cd ${{ github.workspace }}/docs/ 23 | python -m ElunaDoc 24 | - name: Create pull request 25 | run: | 26 | chmod +x "${GITHUB_WORKSPACE}/.github/workflows/create-pr.sh" 27 | "${GITHUB_WORKSPACE}/.github/workflows/create-pr.sh" 28 | env: 29 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} 30 | SOURCE_FOLDER: '${{ github.workspace }}/docs/build' 31 | DESTINATION_REPO: 'azerothcore/azerothcore.github.io' 32 | DESTINATION_FOLDER: 'pages/eluna' 33 | DESTINATION_BASE_BRANCH: 'master' 34 | DESTINATION_HEAD_BRANCH: 'eluna-docs' 35 | PR_TITLE: 'chore: update eluna documentation' 36 | COMMIT_MESSAGE: 'chore: update eluna documentation' 37 | USER_EMAIL: 'ax.cocat@gmail.com' 38 | USER_NAME: 'r-o-b-o-t-o' 39 | -------------------------------------------------------------------------------- /src/LuaEngine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | # This program is free software licensed under GPL version 3 4 | # Please see the included DOCS/LICENSE.md for more information 5 | # 6 | 7 | if( ${CMAKE_PROJECT_NAME} STREQUAL "MaNGOS" ) 8 | 9 | if ( USE_COREPCH ) 10 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 11 | include_directories(${CMAKE_SOURCE_DIR}) 12 | endif () 13 | 14 | # Iterates through all the source files and adds them to the solution 15 | file(GLOB sources_localdir *.cpp *.h) 16 | 17 | # Adds all the method headers to its own source group 18 | file(GLOB method_headers *Methods.h) 19 | source_group("Methods" FILES ${method_headers}) 20 | 21 | set(LuaEngine_STAT_SRCS 22 | ${LuaEngine_STAT_SRCS} 23 | ${sources_localdir} 24 | ) 25 | 26 | include_directories( 27 | ${CMAKE_SOURCE_DIR}/dep/zlib 28 | ${CMAKE_SOURCE_DIR}/dep/lualib 29 | ${CMAKE_BINARY_DIR} 30 | ${ACE_INCLUDE_DIR} 31 | ${MYSQL_INCLUDE_DIR} 32 | ${OPENSSL_INCLUDE_DIR} 33 | ) 34 | 35 | add_library(LuaEngine STATIC 36 | ${LuaEngine_STAT_SRCS} 37 | ${game_STAT_SRCS} 38 | ${game_STAT_PCH_SRC} 39 | ) 40 | 41 | include_directories( 42 | ${CMAKE_SOURCE_DIR}/dep/g3dlite 43 | ${CMAKE_SOURCE_DIR}/src/shared 44 | ${CMAKE_SOURCE_DIR}/src/shared/Common 45 | ${CMAKE_SOURCE_DIR}/src/shared/Utilities 46 | ${CMAKE_SOURCE_DIR}/src/shared/Log 47 | ${CMAKE_SOURCE_DIR}/src/shared/DataStores 48 | ${CMAKE_SOURCE_DIR}/src/shared/Threading 49 | ${CMAKE_SOURCE_DIR}/src/framework 50 | ${CMAKE_SOURCE_DIR}/src/framework/Platform 51 | ${CMAKE_SOURCE_DIR}/src/game/BattleGround 52 | ${CMAKE_SOURCE_DIR}/src/game/Server 53 | ${CMAKE_SOURCE_DIR}/src/game/vmap 54 | ${CMAKE_SOURCE_DIR}/src/game/Maps 55 | ${CMAKE_SOURCE_DIR}/src/game/MotionGenerators 56 | ${CMAKE_SOURCE_DIR}/src/game/Tools 57 | ${CMAKE_SOURCE_DIR}/src/game/References 58 | ${CMAKE_SOURCE_DIR}/src/game/WorldHandlers 59 | ${CMAKE_SOURCE_DIR}/src/game/Object 60 | ) 61 | 62 | if( WIN32 ) 63 | if ( MSVC ) 64 | add_custom_command(TARGET LuaEngine 65 | POST_BUILD 66 | COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/lua_scripts/extensions/" 67 | COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/extensions" "${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/lua_scripts/extensions/" 68 | ) 69 | elseif ( MINGW ) 70 | add_custom_command(TARGET LuaEngine 71 | POST_BUILD 72 | COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bin/lua_scripts/extensions/" 73 | COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/extensions" "${CMAKE_BINARY_DIR}/bin/ua_scripts/extensions/" 74 | ) 75 | endif() 76 | endif() 77 | 78 | install(DIRECTORY extensions DESTINATION "${BIN_DIR}/lua_scripts/") 79 | 80 | endif() 81 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaCompat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "ElunaCompat.h" 8 | 9 | #if LUA_VERSION_NUM == 501 10 | const char* luaL_tolstring(lua_State* L, int idx, size_t* len) { 11 | if (!luaL_callmeta(L, idx, "__tostring")) { 12 | int t = lua_type(L, idx), tt = 0; 13 | char const* name = NULL; 14 | switch (t) { 15 | case LUA_TNIL: 16 | lua_pushliteral(L, "nil"); 17 | break; 18 | case LUA_TSTRING: 19 | case LUA_TNUMBER: 20 | lua_pushvalue(L, idx); 21 | break; 22 | case LUA_TBOOLEAN: 23 | if (lua_toboolean(L, idx)) 24 | lua_pushliteral(L, "true"); 25 | else 26 | lua_pushliteral(L, "false"); 27 | break; 28 | default: 29 | tt = luaL_getmetafield(L, idx, "__name"); 30 | name = (tt == LUA_TSTRING) ? lua_tostring(L, -1) : lua_typename(L, t); 31 | lua_pushfstring(L, "%s: %p", name, lua_topointer(L, idx)); 32 | if (tt != LUA_TNIL) 33 | lua_replace(L, -2); 34 | break; 35 | } 36 | } 37 | else { 38 | if (!lua_isstring(L, -1)) 39 | luaL_error(L, "'__tostring' must return a string"); 40 | } 41 | return lua_tolstring(L, -1, len); 42 | } 43 | 44 | int luaL_getsubtable(lua_State* L, int i, const char* name) { 45 | int abs_i = lua_absindex(L, i); 46 | luaL_checkstack(L, 3, "not enough stack slots"); 47 | lua_pushstring(L, name); 48 | lua_gettable(L, abs_i); 49 | if (lua_istable(L, -1)) 50 | return 1; 51 | lua_pop(L, 1); 52 | lua_newtable(L); 53 | lua_pushstring(L, name); 54 | lua_pushvalue(L, -2); 55 | lua_settable(L, abs_i); 56 | return 0; 57 | } 58 | 59 | int lua_absindex(lua_State* L, int i) { 60 | if (i < 0 && i > LUA_REGISTRYINDEX) 61 | i += lua_gettop(L) + 1; 62 | return i; 63 | } 64 | 65 | #if !defined LUAJIT_VERSION 66 | void* luaL_testudata(lua_State* L, int index, const char* tname) { 67 | void* ud = lua_touserdata(L, index); 68 | if (ud) 69 | { 70 | if (lua_getmetatable(L, index)) 71 | { 72 | luaL_getmetatable(L, tname); 73 | if (!lua_rawequal(L, -1, -2)) 74 | ud = NULL; 75 | lua_pop(L, 2); 76 | return ud; 77 | } 78 | } 79 | return NULL; 80 | } 81 | 82 | void luaL_setmetatable(lua_State* L, const char* tname) { 83 | lua_pushstring(L, tname); 84 | lua_rawget(L, LUA_REGISTRYINDEX); 85 | lua_setmetatable(L, -2); 86 | } 87 | #endif 88 | #endif 89 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaCompat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2024 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef ELUNACOMPAT_H 8 | #define ELUNACOMPAT_H 9 | 10 | extern "C" 11 | { 12 | #include "lua.h" 13 | #include "lauxlib.h" 14 | }; 15 | 16 | /* Compatibility layer for compiling with Lua 5.1 or LuaJIT */ 17 | #if LUA_VERSION_NUM == 501 18 | int luaL_getsubtable(lua_State* L, int i, const char* name); 19 | const char* luaL_tolstring(lua_State* L, int idx, size_t* len); 20 | int lua_absindex(lua_State* L, int i); 21 | #define lua_pushglobaltable(L) \ 22 | lua_pushvalue((L), LUA_GLOBALSINDEX) 23 | #define lua_rawlen(L, idx) \ 24 | lua_objlen(L, idx) 25 | #define lua_pushunsigned(L, u) \ 26 | lua_pushinteger(L, u) 27 | #define lua_load(L, buf_read, dec_buf, str, NULL) \ 28 | lua_load(L, buf_read, dec_buf, str) 29 | 30 | #if !defined LUAJIT_VERSION 31 | void* luaL_testudata(lua_State* L, int index, const char* tname); 32 | void luaL_setmetatable(lua_State* L, const char* tname); 33 | #define luaL_setfuncs(L, l, n) luaL_register(L, NULL, l) 34 | #endif 35 | #endif 36 | 37 | #if LUA_VERSION_NUM > 502 38 | #define lua_dump(L, writer, data) \ 39 | lua_dump(L, writer, data, 0) 40 | #define lua_pushunsigned(L, u) \ 41 | lua_pushinteger(L, u) 42 | #endif 43 | #endif 44 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaCreatureAI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_CREATURE_AI_H 8 | #define _ELUNA_CREATURE_AI_H 9 | 10 | #include "LuaEngine.h" 11 | 12 | struct ScriptedAI; 13 | 14 | struct ElunaCreatureAI : ScriptedAI 15 | { 16 | // used to delay the spawn hook triggering on AI creation 17 | bool justSpawned; 18 | // used to delay movementinform hook (WP hook) 19 | std::vector< std::pair > movepoints; 20 | 21 | ElunaCreatureAI(Creature* creature) : ScriptedAI(creature), justSpawned(true) 22 | { 23 | } 24 | ~ElunaCreatureAI() { } 25 | 26 | //Called at World update tick 27 | void UpdateAI(uint32 diff) override 28 | { 29 | if (justSpawned) 30 | { 31 | justSpawned = false; 32 | 33 | JustRespawned(); 34 | } 35 | 36 | if (!movepoints.empty()) 37 | { 38 | for (auto& point : movepoints) 39 | { 40 | if (!sEluna->MovementInform(me, point.first, point.second)) 41 | ScriptedAI::MovementInform(point.first, point.second); 42 | } 43 | movepoints.clear(); 44 | } 45 | 46 | if (!sEluna->UpdateAI(me, diff)) 47 | { 48 | if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)) 49 | ScriptedAI::UpdateAI(diff); 50 | } 51 | } 52 | 53 | // Called for reaction when initially engaged - this will always happen _after_ JustEnteredCombat 54 | // Called at creature aggro either by MoveInLOS or Attack Start 55 | void JustEngagedWith(Unit* target) override 56 | { 57 | if (!sEluna->EnterCombat(me, target)) 58 | ScriptedAI::JustEngagedWith(target); 59 | } 60 | 61 | // Called at any Damage from any attacker (before damage apply) 62 | void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask) override 63 | { 64 | if (!sEluna->DamageTaken(me, attacker, damage)) 65 | { 66 | ScriptedAI::DamageTaken(attacker, damage, damagetype, damageSchoolMask); 67 | } 68 | } 69 | 70 | //Called at creature death 71 | void JustDied(Unit* killer) override 72 | { 73 | if (!sEluna->JustDied(me, killer)) 74 | ScriptedAI::JustDied(killer); 75 | } 76 | 77 | //Called at creature killing another unit 78 | void KilledUnit(Unit* victim) override 79 | { 80 | if (!sEluna->KilledUnit(me, victim)) 81 | ScriptedAI::KilledUnit(victim); 82 | } 83 | 84 | // Called when the creature summon successfully other creature 85 | void JustSummoned(Creature* summon) override 86 | { 87 | if (!sEluna->JustSummoned(me, summon)) 88 | ScriptedAI::JustSummoned(summon); 89 | } 90 | 91 | // Called when a summoned creature is despawned 92 | void SummonedCreatureDespawn(Creature* summon) override 93 | { 94 | if (!sEluna->SummonedCreatureDespawn(me, summon)) 95 | ScriptedAI::SummonedCreatureDespawn(summon); 96 | } 97 | 98 | //Called at waypoint reached or PointMovement end 99 | void MovementInform(uint32 type, uint32 id) override 100 | { 101 | // delayed since hook triggers before actually reaching the point 102 | // and starting new movement would bug 103 | movepoints.push_back(std::make_pair(type, id)); 104 | } 105 | 106 | // Called before EnterCombat even before the creature is in combat. 107 | void AttackStart(Unit* target) override 108 | { 109 | if (!sEluna->AttackStart(me, target)) 110 | ScriptedAI::AttackStart(target); 111 | } 112 | 113 | // Called for reaction at stopping attack at no attackers or targets 114 | void EnterEvadeMode(EvadeReason /*why*/) override 115 | { 116 | if (!sEluna->EnterEvadeMode(me)) 117 | ScriptedAI::EnterEvadeMode(); 118 | } 119 | 120 | // Called when creature is spawned or respawned (for reseting variables) 121 | void JustRespawned() override 122 | { 123 | if (!sEluna->JustRespawned(me)) 124 | ScriptedAI::JustRespawned(); 125 | } 126 | 127 | // Called at reaching home after evade 128 | void JustReachedHome() override 129 | { 130 | if (!sEluna->JustReachedHome(me)) 131 | ScriptedAI::JustReachedHome(); 132 | } 133 | 134 | // Called at text emote receive from player 135 | void ReceiveEmote(Player* player, uint32 emoteId) override 136 | { 137 | if (!sEluna->ReceiveEmote(me, player, emoteId)) 138 | ScriptedAI::ReceiveEmote(player, emoteId); 139 | } 140 | 141 | // called when the corpse of this creature gets removed 142 | void CorpseRemoved(uint32& respawnDelay) override 143 | { 144 | if (!sEluna->CorpseRemoved(me, respawnDelay)) 145 | ScriptedAI::CorpseRemoved(respawnDelay); 146 | } 147 | 148 | void MoveInLineOfSight(Unit* who) override 149 | { 150 | if (!sEluna->MoveInLineOfSight(me, who)) 151 | ScriptedAI::MoveInLineOfSight(who); 152 | } 153 | 154 | // Called when hit by a spell 155 | void SpellHit(Unit* caster, SpellInfo const* spell) override 156 | { 157 | if (!sEluna->SpellHit(me, caster, spell)) 158 | ScriptedAI::SpellHit(caster, spell); 159 | } 160 | 161 | // Called when spell hits a target 162 | void SpellHitTarget(Unit* target, SpellInfo const* spell) override 163 | { 164 | if (!sEluna->SpellHitTarget(me, target, spell)) 165 | ScriptedAI::SpellHitTarget(target, spell); 166 | } 167 | 168 | // Called when the creature is summoned successfully by other creature 169 | void IsSummonedBy(WorldObject* summoner) override 170 | { 171 | if (!summoner->ToUnit() || !sEluna->OnSummoned(me, summoner->ToUnit())) 172 | ScriptedAI::IsSummonedBy(summoner); 173 | } 174 | 175 | void SummonedCreatureDies(Creature* summon, Unit* killer) override 176 | { 177 | if (!sEluna->SummonedCreatureDies(me, summon, killer)) 178 | ScriptedAI::SummonedCreatureDies(summon, killer); 179 | } 180 | 181 | // Called when owner takes damage 182 | void OwnerAttackedBy(Unit* attacker) override 183 | { 184 | if (!sEluna->OwnerAttackedBy(me, attacker)) 185 | ScriptedAI::OwnerAttackedBy(attacker); 186 | } 187 | 188 | // Called when owner attacks something 189 | void OwnerAttacked(Unit* target) override 190 | { 191 | if (!sEluna->OwnerAttacked(me, target)) 192 | ScriptedAI::OwnerAttacked(target); 193 | } 194 | }; 195 | 196 | #endif 197 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaDBCRegistry.cpp: -------------------------------------------------------------------------------- 1 | #include "ElunaDBCRegistry.h" 2 | 3 | std::vector dbcRegistry = { 4 | REGISTER_DBC(GemProperties, GemPropertiesEntry, sGemPropertiesStore), 5 | REGISTER_DBC(Spell, SpellEntry, sSpellStore), 6 | }; 7 | 8 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaDBCRegistry.h: -------------------------------------------------------------------------------- 1 | #ifndef ELUNADBCREGISTRY_H 2 | #define ELUNADBCREGISTRY_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "DBCStores.h" 10 | #include "LuaEngine.h" 11 | 12 | struct DBCDefinition 13 | { 14 | std::string name; 15 | void* storage; 16 | const std::type_info& type; 17 | std::function lookupFunction; 18 | std::function pushFunction; 19 | }; 20 | 21 | extern std::vector dbcRegistry; 22 | 23 | #define REGISTER_DBC(dbcName, entryType, store) \ 24 | { \ 25 | #dbcName, \ 26 | reinterpret_cast(&store), \ 27 | typeid(DBCStorage), \ 28 | [](uint32 id) -> const void* { \ 29 | return store.LookupEntry(id); \ 30 | }, \ 31 | [](lua_State* L, const void* entry) { \ 32 | auto cast_entry = static_cast(entry); \ 33 | Eluna::Push(L, *cast_entry); \ 34 | } \ 35 | } 36 | 37 | #endif // ELUNADBCREGISTRY_H 38 | 39 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaEventMgr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "ElunaEventMgr.h" 8 | #include "LuaEngine.h" 9 | #include "Object.h" 10 | 11 | extern "C" 12 | { 13 | #include "lua.h" 14 | #include "lauxlib.h" 15 | }; 16 | 17 | ElunaEventProcessor::ElunaEventProcessor(Eluna** _E, WorldObject* _obj) : m_time(0), obj(_obj), E(_E) 18 | { 19 | // can be called from multiple threads 20 | if (obj) 21 | { 22 | EventMgr::Guard guard((*E)->eventMgr->GetLock()); 23 | (*E)->eventMgr->processors.insert(this); 24 | } 25 | } 26 | 27 | ElunaEventProcessor::~ElunaEventProcessor() 28 | { 29 | // can be called from multiple threads 30 | { 31 | LOCK_ELUNA; 32 | RemoveEvents_internal(); 33 | } 34 | 35 | if (obj && Eluna::IsInitialized()) 36 | { 37 | EventMgr::Guard guard((*E)->eventMgr->GetLock()); 38 | (*E)->eventMgr->processors.erase(this); 39 | } 40 | } 41 | 42 | void ElunaEventProcessor::Update(uint32 diff) 43 | { 44 | m_time += diff; 45 | for (EventList::iterator it = eventList.begin(); it != eventList.end() && it->first <= m_time; it = eventList.begin()) 46 | { 47 | LuaEvent* luaEvent = it->second; 48 | eventList.erase(it); 49 | 50 | if (luaEvent->state != LUAEVENT_STATE_ERASE) 51 | eventMap.erase(luaEvent->funcRef); 52 | 53 | if (luaEvent->state == LUAEVENT_STATE_RUN) 54 | { 55 | uint32 delay = luaEvent->delay; 56 | bool remove = luaEvent->repeats == 1; 57 | if (!remove) 58 | AddEvent(luaEvent); // Reschedule before calling incase RemoveEvents used 59 | 60 | // Call the timed event 61 | (*E)->OnTimedEvent(luaEvent->funcRef, delay, luaEvent->repeats ? luaEvent->repeats-- : luaEvent->repeats, obj); 62 | 63 | if (!remove) 64 | continue; 65 | } 66 | 67 | // Event should be deleted (executed last time or set to be aborted) 68 | RemoveEvent(luaEvent); 69 | } 70 | } 71 | 72 | void ElunaEventProcessor::SetStates(LuaEventState state) 73 | { 74 | for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) 75 | it->second->SetState(state); 76 | if (state == LUAEVENT_STATE_ERASE) 77 | eventMap.clear(); 78 | } 79 | 80 | void ElunaEventProcessor::RemoveEvents_internal() 81 | { 82 | //if (!final) 83 | //{ 84 | // for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) 85 | // it->second->to_Abort = true; 86 | // return; 87 | //} 88 | 89 | for (EventList::iterator it = eventList.begin(); it != eventList.end(); ++it) 90 | RemoveEvent(it->second); 91 | 92 | eventList.clear(); 93 | eventMap.clear(); 94 | } 95 | 96 | void ElunaEventProcessor::SetState(int eventId, LuaEventState state) 97 | { 98 | if (eventMap.find(eventId) != eventMap.end()) 99 | eventMap[eventId]->SetState(state); 100 | if (state == LUAEVENT_STATE_ERASE) 101 | eventMap.erase(eventId); 102 | } 103 | 104 | void ElunaEventProcessor::AddEvent(LuaEvent* luaEvent) 105 | { 106 | luaEvent->GenerateDelay(); 107 | eventList.insert(std::pair(m_time + luaEvent->delay, luaEvent)); 108 | eventMap[luaEvent->funcRef] = luaEvent; 109 | } 110 | 111 | void ElunaEventProcessor::AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats) 112 | { 113 | AddEvent(new LuaEvent(funcRef, min, max, repeats)); 114 | } 115 | 116 | void ElunaEventProcessor::RemoveEvent(LuaEvent* luaEvent) 117 | { 118 | // Unreference if should and if Eluna was not yet uninitialized and if the lua state still exists 119 | if (luaEvent->state != LUAEVENT_STATE_ERASE && Eluna::IsInitialized() && (*E)->HasLuaState()) 120 | { 121 | // Free lua function ref 122 | luaL_unref((*E)->L, LUA_REGISTRYINDEX, luaEvent->funcRef); 123 | } 124 | delete luaEvent; 125 | } 126 | 127 | EventMgr::EventMgr(Eluna** _E) : globalProcessor(new ElunaEventProcessor(_E, NULL)), E(_E) 128 | { 129 | } 130 | 131 | EventMgr::~EventMgr() 132 | { 133 | { 134 | Guard guard(GetLock()); 135 | if (!processors.empty()) 136 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 137 | (*it)->RemoveEvents_internal(); 138 | globalProcessor->RemoveEvents_internal(); 139 | } 140 | delete globalProcessor; 141 | globalProcessor = NULL; 142 | } 143 | 144 | void EventMgr::SetStates(LuaEventState state) 145 | { 146 | Guard guard(GetLock()); 147 | if (!processors.empty()) 148 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 149 | (*it)->SetStates(state); 150 | globalProcessor->SetStates(state); 151 | } 152 | 153 | void EventMgr::SetState(int eventId, LuaEventState state) 154 | { 155 | Guard guard(GetLock()); 156 | if (!processors.empty()) 157 | for (ProcessorSet::const_iterator it = processors.begin(); it != processors.end(); ++it) // loop processors 158 | (*it)->SetState(eventId, state); 159 | globalProcessor->SetState(eventId, state); 160 | } 161 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaEventMgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_EVENT_MGR_H 8 | #define _ELUNA_EVENT_MGR_H 9 | 10 | #include "ElunaUtility.h" 11 | #include "Common.h" 12 | #include "Util.h" 13 | #include 14 | 15 | #include "Define.h" 16 | 17 | class Eluna; 18 | class EventMgr; 19 | class ElunaEventProcessor; 20 | class WorldObject; 21 | 22 | enum LuaEventState 23 | { 24 | LUAEVENT_STATE_RUN, // On next call run the function normally 25 | LUAEVENT_STATE_ABORT, // On next call unregisters reffed function and erases the data 26 | LUAEVENT_STATE_ERASE, // On next call just erases the data 27 | }; 28 | 29 | struct LuaEvent 30 | { 31 | LuaEvent(int _funcRef, uint32 _min, uint32 _max, uint32 _repeats) : 32 | min(_min), max(_max), delay(0), repeats(_repeats), funcRef(_funcRef), state(LUAEVENT_STATE_RUN) 33 | { 34 | } 35 | 36 | void SetState(LuaEventState _state) 37 | { 38 | if (state != LUAEVENT_STATE_ERASE) 39 | state = _state; 40 | } 41 | 42 | void GenerateDelay() 43 | { 44 | delay = urand(min, max); 45 | } 46 | 47 | uint32 min; // Minimum delay between event calls 48 | uint32 max; // Maximum delay between event calls 49 | uint32 delay; // The currently used waiting time 50 | uint32 repeats; // Amount of repeats to make, 0 for infinite 51 | int funcRef; // Lua function reference ID, also used as event ID 52 | LuaEventState state; // State for next call 53 | }; 54 | 55 | class ElunaEventProcessor 56 | { 57 | friend class EventMgr; 58 | 59 | public: 60 | typedef std::multimap EventList; 61 | typedef std::unordered_map EventMap; 62 | 63 | ElunaEventProcessor(Eluna** _E, WorldObject* _obj); 64 | ~ElunaEventProcessor(); 65 | 66 | void Update(uint32 diff); 67 | // removes all timed events on next tick or at tick end 68 | void SetStates(LuaEventState state); 69 | // set the event to be removed when executing 70 | void SetState(int eventId, LuaEventState state); 71 | void AddEvent(int funcRef, uint32 min, uint32 max, uint32 repeats); 72 | EventMap eventMap; 73 | 74 | private: 75 | void RemoveEvents_internal(); 76 | void AddEvent(LuaEvent* luaEvent); 77 | void RemoveEvent(LuaEvent* luaEvent); 78 | EventList eventList; 79 | uint64 m_time; 80 | WorldObject* obj; 81 | Eluna** E; 82 | }; 83 | 84 | class EventMgr : public ElunaUtil::Lockable 85 | { 86 | public: 87 | typedef std::unordered_set ProcessorSet; 88 | ProcessorSet processors; 89 | ElunaEventProcessor* globalProcessor; 90 | Eluna** E; 91 | 92 | EventMgr(Eluna** _E); 93 | ~EventMgr(); 94 | 95 | // Set the state of all timed events 96 | // Execute only in safe env 97 | void SetStates(LuaEventState state); 98 | 99 | // Sets the eventId's state in all processors 100 | // Execute only in safe env 101 | void SetState(int eventId, LuaEventState state); 102 | }; 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaIncludes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_INCLUDES_H 8 | #define _ELUNA_INCLUDES_H 9 | 10 | // Required 11 | #include "AccountMgr.h" 12 | #include "AuctionHouseMgr.h" 13 | #include "Cell.h" 14 | #include "CellImpl.h" 15 | #include "Chat.h" 16 | #include "Channel.h" 17 | #include "DBCStores.h" 18 | #include "GameEventMgr.h" 19 | #include "GossipDef.h" 20 | #include "GridNotifiers.h" 21 | #include "GridNotifiersImpl.h" 22 | #include "Group.h" 23 | #include "Guild.h" 24 | #include "GuildMgr.h" 25 | #include "Language.h" 26 | #include "Mail.h" 27 | #include "ObjectAccessor.h" 28 | #include "ObjectMgr.h" 29 | #include "Opcodes.h" 30 | #include "Player.h" 31 | #include "Pet.h" 32 | #include "ReputationMgr.h" 33 | #include "ScriptMgr.h" 34 | #include "Spell.h" 35 | #include "SpellAuras.h" 36 | #include "SpellInfo.h" 37 | #include "SpellMgr.h" 38 | #include "TemporarySummon.h" 39 | #include "WorldPacket.h" 40 | #include "WorldSession.h" 41 | #include "MapMgr.h" 42 | #include "Config.h" 43 | #include "GameEventMgr.h" 44 | #include "GitRevision.h" 45 | #include "GroupMgr.h" 46 | #include "ScriptedCreature.h" 47 | #include "SpellInfo.h" 48 | #include "WeatherMgr.h" 49 | #include "Battleground.h" 50 | #include "MotionMaster.h" 51 | #include "DatabaseEnv.h" 52 | #include "Bag.h" 53 | #include "Vehicle.h" 54 | #include "ArenaTeam.h" 55 | #include "WorldSessionMgr.h" 56 | 57 | typedef Opcodes OpcodesList; 58 | 59 | /* 60 | * Note: if you add or change a CORE_NAME or CORE_VERSION #define, 61 | * please update LuaGlobalFunctions::GetCoreName or LuaGlobalFunctions::GetCoreVersion documentation example string. 62 | */ 63 | #define CORE_NAME "AzerothCore" 64 | 65 | #define CORE_VERSION (GitRevision::GetFullVersion()) 66 | #define eWorldSessionMgr (sWorldSessionMgr) 67 | #define eWorld (sWorld) 68 | #define eMapMgr (sMapMgr) 69 | #define eConfigMgr (sConfigMgr) 70 | #define eGuildMgr (sGuildMgr) 71 | #define eObjectMgr (sObjectMgr) 72 | #define eAccountMgr (sAccountMgr) 73 | #define eAuctionMgr (sAuctionMgr) 74 | #define eGameEventMgr (sGameEventMgr) 75 | #define eObjectAccessor() ObjectAccessor:: 76 | 77 | #endif // _ELUNA_INCLUDES_H 78 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaInstanceAI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "ElunaInstanceAI.h" 8 | #include "ElunaUtility.h" 9 | #include "lmarshal.h" 10 | 11 | 12 | void ElunaInstanceAI::Initialize() 13 | { 14 | LOCK_ELUNA; 15 | 16 | ASSERT(!sEluna->HasInstanceData(instance)); 17 | 18 | // Create a new table for instance data. 19 | lua_State* L = sEluna->L; 20 | lua_newtable(L); 21 | sEluna->CreateInstanceData(instance); 22 | 23 | sEluna->OnInitialize(this); 24 | } 25 | 26 | void ElunaInstanceAI::Load(const char* data) 27 | { 28 | LOCK_ELUNA; 29 | 30 | // If we get passed NULL (i.e. `Reload` was called) then use 31 | // the last known save data (or maybe just an empty string). 32 | if (!data) 33 | { 34 | data = lastSaveData.c_str(); 35 | } 36 | else // Otherwise, copy the new data into our buffer. 37 | { 38 | lastSaveData.assign(data); 39 | } 40 | 41 | if (data[0] == '\0') 42 | { 43 | ASSERT(!sEluna->HasInstanceData(instance)); 44 | 45 | // Create a new table for instance data. 46 | lua_State* L = sEluna->L; 47 | lua_newtable(L); 48 | sEluna->CreateInstanceData(instance); 49 | 50 | sEluna->OnLoad(this); 51 | // Stack: (empty) 52 | return; 53 | } 54 | 55 | size_t decodedLength; 56 | const unsigned char* decodedData = ElunaUtil::DecodeData(data, &decodedLength); 57 | lua_State* L = sEluna->L; 58 | 59 | if (decodedData) 60 | { 61 | // Stack: (empty) 62 | 63 | lua_pushcfunction(L, mar_decode); 64 | lua_pushlstring(L, (const char*)decodedData, decodedLength); 65 | // Stack: mar_decode, decoded_data 66 | 67 | // Call `mar_decode` and check for success. 68 | if (lua_pcall(L, 1, 1, 0) == 0) 69 | { 70 | // Stack: data 71 | // Only use the data if it's a table. 72 | if (lua_istable(L, -1)) 73 | { 74 | sEluna->CreateInstanceData(instance); 75 | // Stack: (empty) 76 | sEluna->OnLoad(this); 77 | // WARNING! lastSaveData might be different after `OnLoad` if the Lua code saved data. 78 | } 79 | else 80 | { 81 | ELUNA_LOG_ERROR("Error while loading instance data: Expected data to be a table (type 5), got type {} instead", lua_type(L, -1)); 82 | lua_pop(L, 1); 83 | // Stack: (empty) 84 | 85 | Initialize(); 86 | } 87 | } 88 | else 89 | { 90 | // Stack: error_message 91 | ELUNA_LOG_ERROR("Error while parsing instance data with lua-marshal: {}", lua_tostring(L, -1)); 92 | lua_pop(L, 1); 93 | // Stack: (empty) 94 | 95 | Initialize(); 96 | } 97 | 98 | delete[] decodedData; 99 | } 100 | else 101 | { 102 | ELUNA_LOG_ERROR("Error while decoding instance data: Data is not valid base-64"); 103 | 104 | Initialize(); 105 | } 106 | } 107 | 108 | const char* ElunaInstanceAI::Save() const 109 | { 110 | LOCK_ELUNA; 111 | lua_State* L = sEluna->L; 112 | // Stack: (empty) 113 | 114 | /* 115 | * Need to cheat because this method actually does modify this instance, 116 | * even though it's declared as `const`. 117 | * 118 | * Declaring virtual methods as `const` is BAD! 119 | * Don't dictate to children that their methods must be pure. 120 | */ 121 | ElunaInstanceAI* self = const_cast(this); 122 | 123 | lua_pushcfunction(L, mar_encode); 124 | sEluna->PushInstanceData(L, self, false); 125 | // Stack: mar_encode, instance_data 126 | 127 | if (lua_pcall(L, 1, 1, 0) != 0) 128 | { 129 | // Stack: error_message 130 | ELUNA_LOG_ERROR("Error while saving: {}", lua_tostring(L, -1)); 131 | lua_pop(L, 1); 132 | return NULL; 133 | } 134 | 135 | // Stack: data 136 | size_t dataLength; 137 | const unsigned char* data = (const unsigned char*)lua_tolstring(L, -1, &dataLength); 138 | ElunaUtil::EncodeData(data, dataLength, self->lastSaveData); 139 | 140 | lua_pop(L, 1); 141 | // Stack: (empty) 142 | 143 | return lastSaveData.c_str(); 144 | } 145 | 146 | uint32 ElunaInstanceAI::GetData(uint32 key) const 147 | { 148 | LOCK_ELUNA; 149 | lua_State* L = sEluna->L; 150 | // Stack: (empty) 151 | 152 | sEluna->PushInstanceData(L, const_cast(this), false); 153 | // Stack: instance_data 154 | 155 | Eluna::Push(L, key); 156 | // Stack: instance_data, key 157 | 158 | lua_gettable(L, -2); 159 | // Stack: instance_data, value 160 | 161 | uint32 value = Eluna::CHECKVAL(L, -1, 0); 162 | lua_pop(L, 2); 163 | // Stack: (empty) 164 | 165 | return value; 166 | } 167 | 168 | void ElunaInstanceAI::SetData(uint32 key, uint32 value) 169 | { 170 | LOCK_ELUNA; 171 | lua_State* L = sEluna->L; 172 | // Stack: (empty) 173 | 174 | sEluna->PushInstanceData(L, this, false); 175 | // Stack: instance_data 176 | 177 | Eluna::Push(L, key); 178 | Eluna::Push(L, value); 179 | // Stack: instance_data, key, value 180 | 181 | lua_settable(L, -3); 182 | // Stack: instance_data 183 | 184 | lua_pop(L, 1); 185 | // Stack: (empty) 186 | } 187 | 188 | uint64 ElunaInstanceAI::GetData64(uint32 key) const 189 | { 190 | LOCK_ELUNA; 191 | lua_State* L = sEluna->L; 192 | // Stack: (empty) 193 | 194 | sEluna->PushInstanceData(L, const_cast(this), false); 195 | // Stack: instance_data 196 | 197 | Eluna::Push(L, key); 198 | // Stack: instance_data, key 199 | 200 | lua_gettable(L, -2); 201 | // Stack: instance_data, value 202 | 203 | uint64 value = Eluna::CHECKVAL(L, -1, 0); 204 | lua_pop(L, 2); 205 | // Stack: (empty) 206 | 207 | return value; 208 | } 209 | 210 | void ElunaInstanceAI::SetData64(uint32 key, uint64 value) 211 | { 212 | LOCK_ELUNA; 213 | lua_State* L = sEluna->L; 214 | // Stack: (empty) 215 | 216 | sEluna->PushInstanceData(L, this, false); 217 | // Stack: instance_data 218 | 219 | Eluna::Push(L, key); 220 | Eluna::Push(L, value); 221 | // Stack: instance_data, key, value 222 | 223 | lua_settable(L, -3); 224 | // Stack: instance_data 225 | 226 | lua_pop(L, 1); 227 | // Stack: (empty) 228 | } 229 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaInstanceAI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_INSTANCE_DATA_H 8 | #define _ELUNA_INSTANCE_DATA_H 9 | 10 | #include "LuaEngine.h" 11 | #include "InstanceScript.h" 12 | 13 | /* 14 | * This class is a small wrapper around `InstanceData`, 15 | * allowing instances to be scripted with Eluna. 16 | * 17 | * 18 | * Note 1 19 | * ====== 20 | * 21 | * Instances of `ElunaInstanceAI` are owned by the core, so they 22 | * are not deleted when Eluna is reloaded. Thus `Load` is only called 23 | * by the core once, no matter how many times Eluna is reloaded. 24 | * 25 | * However, when Eluna reloads, all instance data in Eluna is lost. 26 | * So the solution is as follows: 27 | * 28 | * 1. Store the last save data in the member var `lastSaveData`. 29 | * 30 | * At first this is just the data given to us by the core when it calls `Load`, 31 | * but later on once we start saving new data this is from Eluna. 32 | * 33 | * 2. When retrieving instance data from Eluna, check if it's missing. 34 | * 35 | * The data will be missing if Eluna is reloaded, since a new Lua state is created. 36 | * 37 | * 3. If it *is* missing, call `Reload`. 38 | * 39 | * This reloads the last known instance save data into Eluna, and calls the appropriate hooks. 40 | * 41 | * 42 | * Note 2 43 | * ====== 44 | * 45 | * CMaNGOS expects some of these methods to be `const`. However, any of these 46 | * methods are free to call `Save`, resulting in mutation of `lastSaveData`. 47 | * 48 | * Therefore, none of the hooks are `const`-safe, and `const_cast` is used 49 | * to escape from these restrictions. 50 | */ 51 | class ElunaInstanceAI : public InstanceData 52 | { 53 | private: 54 | // The last save data to pass through this class, 55 | // either through `Load` or `Save`. 56 | std::string lastSaveData; 57 | 58 | public: 59 | ElunaInstanceAI(Map* map) : InstanceData(map) 60 | { 61 | } 62 | 63 | void Initialize() override; 64 | 65 | /* 66 | * These are responsible for serializing/deserializing the instance's 67 | * data table to/from the core. 68 | */ 69 | void Load(const char* data) override; 70 | // Simply calls Save, since the functions are a bit different in name and data types on different cores 71 | std::string GetSaveData() override 72 | { 73 | return Save(); 74 | } 75 | const char* Save() const; 76 | 77 | 78 | /* 79 | * Calls `Load` with the last save data that was passed to 80 | * or from Eluna. 81 | * 82 | * See: big documentation blurb at the top of this class. 83 | */ 84 | void Reload() 85 | { 86 | Load(NULL); 87 | } 88 | 89 | /* 90 | * These methods allow non-Lua scripts (e.g. DB, C++) to get/set instance data. 91 | */ 92 | uint32 GetData(uint32 key) const override; 93 | void SetData(uint32 key, uint32 value) override; 94 | 95 | uint64 GetData64(uint32 key) const override; 96 | void SetData64(uint32 key, uint64 value) override; 97 | 98 | /* 99 | * These methods are just thin wrappers around Eluna. 100 | */ 101 | void Update(uint32 diff) override 102 | { 103 | // If Eluna is reloaded, it will be missing our instance data. 104 | // Reload here instead of waiting for the next hook call (possibly never). 105 | // This avoids having to have an empty Update hook handler just to trigger the reload. 106 | if (!sEluna->HasInstanceData(instance)) 107 | Reload(); 108 | 109 | sEluna->OnUpdateInstance(this, diff); 110 | } 111 | 112 | bool IsEncounterInProgress() const override 113 | { 114 | return sEluna->OnCheckEncounterInProgress(const_cast(this)); 115 | } 116 | 117 | void OnPlayerEnter(Player* player) override 118 | { 119 | sEluna->OnPlayerEnterInstance(this, player); 120 | } 121 | 122 | void OnGameObjectCreate(GameObject* gameobject) override 123 | { 124 | sEluna->OnGameObjectCreate(this, gameobject); 125 | } 126 | 127 | void OnCreatureCreate(Creature* creature) override 128 | { 129 | sEluna->OnCreatureCreate(this, creature); 130 | } 131 | }; 132 | 133 | #endif // _ELUNA_INSTANCE_DATA_H 134 | -------------------------------------------------------------------------------- /src/LuaEngine/ElunaUtility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _ELUNA_UTIL_H 8 | #define _ELUNA_UTIL_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "Common.h" 15 | #include "SharedDefines.h" 16 | #include "ObjectGuid.h" 17 | #include "Database/QueryResult.h" 18 | #include "Log.h" 19 | 20 | typedef QueryResult ElunaQuery; 21 | #define GET_GUID GetGUID 22 | #define HIGHGUID_PLAYER HighGuid::Player 23 | #define HIGHGUID_UNIT HighGuid::Unit 24 | #define HIGHGUID_ITEM HighGuid::Item 25 | #define HIGHGUID_GAMEOBJECT HighGuid::GameObject 26 | #define HIGHGUID_PET HighGuid::Pet 27 | #define HIGHGUID_TRANSPORT HighGuid::Transport 28 | #define HIGHGUID_VEHICLE HighGuid::Vehicle 29 | #define HIGHGUID_CONTAINER HighGuid::Container 30 | #define HIGHGUID_DYNAMICOBJECT HighGuid::DynamicObject 31 | #define HIGHGUID_CORPSE HighGuid::Corpse 32 | #define HIGHGUID_MO_TRANSPORT HighGuid::Mo_Transport 33 | #define HIGHGUID_INSTANCE HighGuid::Instance 34 | #define HIGHGUID_GROUP HighGuid::Group 35 | 36 | #define ELUNA_LOG_INFO(...) LOG_INFO("eluna", __VA_ARGS__); 37 | #define ELUNA_LOG_ERROR(...) LOG_ERROR("eluna", __VA_ARGS__); 38 | #define ELUNA_LOG_DEBUG(...) LOG_DEBUG("eluna", __VA_ARGS__); 39 | 40 | #ifndef MAKE_NEW_GUID 41 | #define MAKE_NEW_GUID(l, e, h) ObjectGuid(h, e, l) 42 | #endif 43 | #ifndef GUID_ENPART 44 | #define GUID_ENPART(guid) ObjectGuid(guid).GetEntry() 45 | #endif 46 | #ifndef GUID_LOPART 47 | #define GUID_LOPART(guid) ObjectGuid(guid).GetCounter() 48 | #endif 49 | #ifndef GUID_HIPART 50 | #define GUID_HIPART(guid) ObjectGuid(guid).GetHigh() 51 | #endif 52 | 53 | class Unit; 54 | class WorldObject; 55 | struct FactionTemplateEntry; 56 | 57 | namespace ElunaUtil 58 | { 59 | uint32 GetCurrTime(); 60 | 61 | uint32 GetTimeDiff(uint32 oldMSTime); 62 | 63 | class ObjectGUIDCheck 64 | { 65 | public: 66 | ObjectGUIDCheck(ObjectGuid guid); 67 | bool operator()(WorldObject* object); 68 | 69 | ObjectGuid _guid; 70 | }; 71 | 72 | // Binary predicate to sort WorldObjects based on the distance to a reference WorldObject 73 | class ObjectDistanceOrderPred 74 | { 75 | public: 76 | ObjectDistanceOrderPred(WorldObject const* pRefObj, bool ascending = true); 77 | bool operator()(WorldObject const* pLeft, WorldObject const* pRight) const; 78 | 79 | WorldObject const* m_refObj; 80 | const bool m_ascending; 81 | }; 82 | 83 | // Doesn't get self 84 | class WorldObjectInRangeCheck 85 | { 86 | public: 87 | WorldObjectInRangeCheck(bool nearest, WorldObject const* obj, float range, 88 | uint16 typeMask = 0, uint32 entry = 0, uint32 hostile = 0, uint32 dead = 0); 89 | WorldObject const& GetFocusObject() const; 90 | bool operator()(WorldObject* u); 91 | 92 | WorldObject const* const i_obj; 93 | Unit const* i_obj_unit; 94 | FactionTemplateEntry const* i_obj_fact; 95 | uint32 const i_hostile; // 0 both, 1 hostile, 2 friendly 96 | uint32 const i_entry; 97 | float i_range; 98 | uint16 const i_typeMask; 99 | uint32 const i_dead; // 0 both, 1 alive, 2 dead 100 | bool const i_nearest; 101 | }; 102 | 103 | /* 104 | * Usage: 105 | * Inherit this class, then when needing lock, use 106 | * Guard guard(GetLock()); 107 | * 108 | * The lock is automatically released at end of scope 109 | */ 110 | class Lockable 111 | { 112 | public: 113 | typedef std::mutex LockType; 114 | typedef std::lock_guard Guard; 115 | 116 | LockType& GetLock() { return _lock; } 117 | 118 | private: 119 | LockType _lock; 120 | }; 121 | 122 | /* 123 | * Encodes `data` in Base-64 and store the result in `output`. 124 | */ 125 | void EncodeData(const unsigned char* data, size_t input_length, std::string& output); 126 | 127 | /* 128 | * Decodes `data` from Base-64 and returns a pointer to the result, or `NULL` on error. 129 | * 130 | * The returned result buffer must be `delete[]`ed by the caller. 131 | */ 132 | unsigned char* DecodeData(const char* data, size_t *output_length); 133 | }; 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /src/LuaEngine/HookHelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef _HOOK_HELPERS_H 8 | #define _HOOK_HELPERS_H 9 | 10 | #include "LuaEngine.h" 11 | #include "ElunaUtility.h" 12 | 13 | /* 14 | * Sets up the stack so that event handlers can be called. 15 | * 16 | * Returns the number of functions that were pushed onto the stack. 17 | */ 18 | template 19 | int Eluna::SetupStack(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, int number_of_arguments) 20 | { 21 | ASSERT(number_of_arguments == this->push_counter); 22 | ASSERT(key1.event_id == key2.event_id); 23 | // Stack: [arguments] 24 | 25 | Push(key1.event_id); 26 | this->push_counter = 0; 27 | ++number_of_arguments; 28 | // Stack: [arguments], event_id 29 | 30 | int arguments_top = lua_gettop(L); 31 | int first_argument_index = arguments_top - number_of_arguments + 1; 32 | ASSERT(arguments_top >= number_of_arguments); 33 | 34 | lua_insert(L, first_argument_index); 35 | // Stack: event_id, [arguments] 36 | 37 | bindings1->PushRefsFor(key1); 38 | if (bindings2) 39 | bindings2->PushRefsFor(key2); 40 | // Stack: event_id, [arguments], [functions] 41 | 42 | int number_of_functions = lua_gettop(L) - arguments_top; 43 | return number_of_functions; 44 | } 45 | 46 | /* 47 | * Replace one of the arguments pushed before `SetupStack` with a new value. 48 | */ 49 | template 50 | void Eluna::ReplaceArgument(T value, uint8 index) 51 | { 52 | ASSERT(index < lua_gettop(L) && index > 0); 53 | // Stack: event_id, [arguments], [functions], [results] 54 | 55 | Eluna::Push(L, value); 56 | // Stack: event_id, [arguments], [functions], [results], value 57 | 58 | lua_replace(L, index + 1); 59 | // Stack: event_id, [arguments and value], [functions], [results] 60 | } 61 | 62 | /* 63 | * Call all event handlers registered to the event ID/entry combination and ignore any results. 64 | */ 65 | template 66 | void Eluna::CallAllFunctions(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2) 67 | { 68 | int number_of_arguments = this->push_counter; 69 | // Stack: [arguments] 70 | 71 | int number_of_functions = SetupStack(bindings1, bindings2, key1, key2, number_of_arguments); 72 | // Stack: event_id, [arguments], [functions] 73 | 74 | while (number_of_functions > 0) 75 | { 76 | CallOneFunction(number_of_functions, number_of_arguments, 0); 77 | --number_of_functions; 78 | // Stack: event_id, [arguments], [functions - 1] 79 | } 80 | // Stack: event_id, [arguments] 81 | 82 | CleanUpStack(number_of_arguments); 83 | // Stack: (empty) 84 | } 85 | 86 | /* 87 | * Call all event handlers registered to the event ID/entry combination, 88 | * and returns `default_value` if ALL event handlers returned `default_value`, 89 | * otherwise returns the opposite of `default_value`. 90 | */ 91 | template 92 | bool Eluna::CallAllFunctionsBool(BindingMap* bindings1, BindingMap* bindings2, const K1& key1, const K2& key2, bool default_value/* = false*/) 93 | { 94 | bool result = default_value; 95 | // Note: number_of_arguments here does not count in eventID, which is pushed in SetupStack 96 | int number_of_arguments = this->push_counter; 97 | // Stack: [arguments] 98 | 99 | int number_of_functions = SetupStack(bindings1, bindings2, key1, key2, number_of_arguments); 100 | // Stack: event_id, [arguments], [functions] 101 | 102 | while (number_of_functions > 0) 103 | { 104 | int r = CallOneFunction(number_of_functions, number_of_arguments, 1); 105 | --number_of_functions; 106 | // Stack: event_id, [arguments], [functions - 1], result 107 | 108 | if (lua_isboolean(L, r) && (lua_toboolean(L, r) == 1) != default_value) 109 | result = !default_value; 110 | 111 | lua_pop(L, 1); 112 | // Stack: event_id, [arguments], [functions - 1] 113 | } 114 | // Stack: event_id, [arguments] 115 | 116 | CleanUpStack(number_of_arguments); 117 | // Stack: (empty) 118 | return result; 119 | } 120 | 121 | #endif // _HOOK_HELPERS_H 122 | -------------------------------------------------------------------------------- /src/LuaEngine/HttpManager.h: -------------------------------------------------------------------------------- 1 | #ifndef ELUNA_HTTP_MANAGER_H 2 | #define ELUNA_HTTP_MANAGER_H 3 | 4 | #include 5 | 6 | #include "libs/httplib.h" 7 | #include "libs/rigtorp/SPSCQueue.h" 8 | 9 | struct HttpWorkItem 10 | { 11 | public: 12 | HttpWorkItem(int funcRef, const std::string& httpVerb, const std::string& url, const std::string& body, const std::string &contentType, const httplib::Headers& headers); 13 | 14 | int funcRef; 15 | std::string httpVerb; 16 | std::string url; 17 | std::string body; 18 | std::string contentType; 19 | httplib::Headers headers; 20 | }; 21 | 22 | struct HttpResponse 23 | { 24 | public: 25 | HttpResponse(int funcRef, int statusCode, const std::string& body, const httplib::Headers& headers); 26 | 27 | int funcRef; 28 | int statusCode; 29 | std::string body; 30 | httplib::Headers headers; 31 | }; 32 | 33 | 34 | class HttpManager 35 | { 36 | public: 37 | HttpManager(); 38 | ~HttpManager(); 39 | 40 | void StartHttpWorker(); 41 | void StopHttpWorker(); 42 | void PushRequest(HttpWorkItem* item); 43 | void HandleHttpResponses(); 44 | 45 | private: 46 | void ClearQueues(); 47 | void HttpWorkerThread(); 48 | bool ParseUrl(const std::string& url, std::string& host, std::string& path); 49 | httplib::Result DoRequest(httplib::Client& client, HttpWorkItem* req, const std::string& path); 50 | 51 | rigtorp::SPSCQueue workQueue; 52 | rigtorp::SPSCQueue responseQueue; 53 | std::thread workerThread; 54 | bool startedWorkerThread; 55 | std::atomic_bool cancelationToken; 56 | std::condition_variable condVar; 57 | std::mutex condVarMutex; 58 | std::regex parseUrlRegex; 59 | }; 60 | 61 | #endif // #ifndef ELUNA_HTTP_MANAGER_H 62 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the temporary "build" folder. 2 | build -------------------------------------------------------------------------------- /src/LuaEngine/docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | Eluna uses C for the Lua engine, C++ for the server modifications and system code, Lua for scripting side code and scripts, python for the web documentation generation - but you do not have to be able to code to help. 3 | 4 | You can contribute to Eluna in various ways: 5 | * Improve our documentation: [Documentation generation](DOC_GEN.md) 6 | * Create new features or enhance old features: [Eluna source](https://github.com/ElunaLuaEngine/Eluna) 7 | * Notify us about your concerns, problems and needs regarding Eluna: [Issue tracker](https://github.com/ElunaLuaEngine/Eluna/issues) 8 | * Create and improve Lua scripts, systems, releases and guides: [Eluna forum section](https://www.getmangos.eu/forums/forum/118-eluna-lua-engine/) 9 | 10 | ### Features and documentation 11 | To contribute to the source code and documentation within it, create a pull request for our github repository: 12 | 13 | 1. [Set up git](https://help.github.com/articles/set-up-git/) 14 | 2. [Fork](https://help.github.com/articles/fork-a-repo/) our repository: [Eluna repository](https://github.com/ElunaLuaEngine/Eluna) 15 | 3. Create a branch: `git checkout -b mybranch` 16 | 4. Make your contribution changes 17 | 5. Commit your changes `git commit -a -m "commit message"` 18 | 6. Push your commit to github: `git push` 19 | 7. Open a [pull request](https://help.github.com/articles/using-pull-requests/) 20 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/DOC_GEN.md: -------------------------------------------------------------------------------- 1 | # Documentation generation 2 | Eluna uses a custom made documentation generator to create it's [web documentation](http://elunaluaengine.github.io/). 3 | The generator is written in python by Patman. It works by parsing Eluna's source files for comments and then generates the HTML and javascript for the documentation based on them. 4 | 5 | This page guides you through generating the web documentation locally and explains the standards of the documentation comments for you to help us improve our documentation. To contribute with your documentation changes, create a [pull request](https://help.github.com/articles/using-pull-requests/) 6 | 7 | # Generating locally 8 | - install [python](https://www.python.org/)(2) 9 | - when installing, tick to install the path variable 10 | - you may need restart afterwards for the installation to properly take effect 11 | - install a package manager like [pip](https://pip.pypa.io/en/latest/) 12 | - if you installed pip and it does not work, restart or try easy_install command 13 | - install the dependencies with manager 14 | - [Jinja2](https://pypi.python.org/pypi/Jinja2) 15 | - [typedecorator](https://pypi.python.org/pypi/typedecorator) 16 | - [markdown](https://pypi.python.org/pypi/Markdown) 17 | - Run in cmd `python -m ElunaDoc` when at `\LuaEngine\docs\` 18 | 19 | # Documenting 20 | You can document functions in the Eluna source code. To find examples simply open a method header file like `PlayerMethods.h` and see the comments. 21 | 22 | ## Templates 23 | Here are some basic templates for a function documentation. When defining a parameter or a return value the type and value name are mandatory, unless the parameter type is `...`, which is used for variable arguments; do not include a name in this case. 24 | 25 | ```c++ 26 | /** 27 | * Short description (about 80 characters long). 28 | * 29 | * @param Type paramName 30 | * @return Type returnName 31 | */ 32 | ``` 33 | 34 | ```c++ 35 | /** 36 | * Short description (about 80 characters long). 37 | * 38 | * @param Type paramName = defaultValue : parameter description 39 | * @return Type returnName : return value description 40 | */ 41 | ``` 42 | 43 | This is a template for a function that takes in different parameters. When defining a parameter or a return value, the type and value name are mandatory. 44 | 45 | ```c++ 46 | /** 47 | * Short description (about 80 characters long). 48 | * 49 | * @proto returnValue = (object) 50 | * @proto returnValue = (x, y, z) 51 | * @param [WorldObject] object = defaultValue : parameter description 52 | * @param float x = defaultValue : parameter description 53 | * @param float y = defaultValue : parameter description 54 | * @param float z = defaultValue : parameter description 55 | * @return Type returnName : return value description 56 | */ 57 | ``` 58 | 59 | ## Standard 60 | A documentation comment block will always start with `/**` and end with `*/`. 61 | All lines start with `*` character followed by one space before any content. 62 | 63 | The first paragrph is used as a short description of the function/class, so it should be kept to about 80 characters. The other paragraphs can be as long as desired. 64 | 65 | All paragraphs in the description (including the first) should start with a capital letter and end with a period. 66 | **Paragraphs must be separated by an empty line**, e.g.: 67 | 68 | ```c++ 69 | /** 70 | * This is a short description (about 80 characters). 71 | * 72 | * Here's another paragraph with more info. NOTE THE EMPTY LINE BETWEEN THE PARAGRAPHS. 73 | * This does need to be short, and this line is still part of the same paragraph because 74 | * there is no empty line. 75 | */ 76 | ``` 77 | 78 | The parameter and return value descriptions should start with a lowercase letter and not end with a period. If more than one sentence is needed, start the *first* without a capital letter and end the *last* without a period. 79 | 80 | Any class, enum or function can be referenced (made a link to) with square brackets. 81 | `[Player]` will reference a player. `[WeatherType]` will reference an enum. `[Player:GetName]` will reference a function. 82 | 83 | Use correct indentation with documentation comments. 84 | 85 | ```c++ 86 | /** 87 | * Correct indentation. 88 | */ 89 | ``` 90 | 91 | ```c++ 92 | /** 93 | * Invalid indentation. 94 | */ 95 | ``` 96 | 97 | ## Markdown 98 | You can use [markdown](http://pythonhosted.org//Markdown/) in your descriptions. 99 | For syntax see http://daringfireball.net/projects/markdown/syntax and http://pythonhosted.org//Markdown/#differences 100 | 101 | ``` 102 | /** 103 | * Description. 104 | * 105 | * - list item 106 | * - list item 107 | * - list item 108 | * 109 | * 110 | * // Codeblock 111 | * // Code goes here. 112 | * // Note the 4-space indent. 113 | * 114 | * 115 | * `code line` 116 | * 117 | * *italic* 118 | * **bold** 119 | */ 120 | ``` 121 | 122 | **The above markdown code produces the output below:** 123 | 124 | Description. 125 | 126 | - list item 127 | - list item 128 | - list item 129 | 130 | ``` 131 | // Codeblock 132 | // Code goes here. 133 | // Note the 4-space indent. 134 | ``` 135 | 136 | `code line` 137 | 138 | *italic* 139 | **bold** 140 | 141 | ## Types 142 | Here are some examples of possible types and most commonly used ones: 143 | 144 | ``` 145 | string 146 | uint64 147 | uint32 148 | uint16 149 | uint8 150 | int64 151 | int32 152 | int16 153 | int8 154 | double 155 | float 156 | ... 157 | [EnumName] 158 | [Player] 159 | [Creature] 160 | [GameObject] 161 | [Item] 162 | [Unit] 163 | [WorldObject] 164 | [Object] 165 | ``` 166 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/Eluna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/Eluna.png -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/__init__.py -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/FiraSans-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/FiraSans-Medium.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/FiraSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/FiraSans-Regular.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/Heuristica-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/Heuristica-Italic.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/SourceCodePro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/SourceCodePro-Regular.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/SourceCodePro-Semibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/SourceCodePro-Semibold.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/SourceSerifPro-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/SourceSerifPro-Bold.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/SourceSerifPro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/SourceSerifPro-Regular.woff -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/eluna-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/eluna-logo.png -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/docs/ElunaDoc/static/favicon.ico -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/static/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} 2 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/_base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {% block title %}Eluna API{% endblock %} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 36 | 37 | 47 | 48 |
49 |

50 | {% block document_title %}Title Missing{% endblock %} 51 | 52 | 53 | [-] 54 | [+] 55 | 56 | 57 |

58 | 59 | {% block content %}

Content missing.

{% endblock %} 60 |
61 | 62 | 63 | 64 | 65 | 66 | 96 | 97 | 100 | 101 | 102 | 103 |
Generated on
104 |
©2016 - Eluna Lua Engine
105 | 106 | 107 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/class.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | 3 | 4 | {% block title -%} 5 | {{ current_class.name }} - {{ super() }} 6 | {%- endblock %} 7 | 8 | 9 | {% block description -%} 10 | API documentation for the {{ current_class.name }} class in the Eluna engine. 11 | {%- endblock %} 12 | 13 | 14 | {% block document_title -%} 15 | Class {{ current_class.name }} 16 | {%- endblock %} 17 | 18 | 19 | {% block sidebar %} 20 | {% endblock %} 21 | 22 | 23 | {% block content %} 24 | {{ current_class.description|parse_links }} 25 | 26 |

Methods

27 | 28 | {%- for method in current_class.methods %} 29 | 30 | 34 | 37 | 38 | {%- endfor %} 39 |
31 | 32 | {{ method.name }} 33 | 35 |

{{ method.short_description|parse_links }}

36 |
40 | {% endblock %} -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/date.js: -------------------------------------------------------------------------------- 1 | document.write("{{ currdate }}"); -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/enum.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | 3 | 4 | {% block document_title -%} 5 | Eluna API Documentation 6 | {%- endblock %} 7 | 8 | 9 | {% block content %} 10 |
11 |

12 | The Eluna Lua Engine© API 13 |

14 |

15 | The Eluna Lua Engine© API allows you to add your own Lua code to be executed when certain events (called "hooks") occur. 16 |

17 |

18 | Add a new in-game command, give life to creatures with new AI, or even light players who try to duel on fire! 19 | If the hook exists, you can script it. 20 |

21 | 22 |

23 | About Eluna 24 |

25 |

26 | Eluna is a Lua engine for World of Warcraft emulators. 27 | These pages are for AzerothCore's version, but Eluna also supports 28 | CMaNGOS/MaNGOS and TrinityCore. 29 |

30 |

31 | If you come from the TypeScript / JavaScript world, or would prefer to use a typed language instead of Lua, check out eluna-ts! 32 |

33 |

34 | You can get support in the #eluna-ac channel of AzerothCore's Discord server. 35 |

36 |

37 | You can also join the official Eluna Discord server, where you'll be able to find resources, releases and support provided by the Eluna community. 38 |

39 | 40 |

41 | How to Install 42 |

43 |

44 |

    45 |
  1. If you haven't already, clone AzerothCore from our GitHub repository
  2. 46 |
  3. Go to the modules directory and run the following command:
    git clone https://github.com/azerothcore/mod-eluna.git mod-eluna
  4. 47 |
  5. Run CMake
  6. 48 |
  7. Build AzerothCore
  8. 49 |
50 |

51 | 52 | 58 | 59 |

60 | About this Documentation 61 |

62 |

63 | The layout, CSS, and Javascript code for this documentation was borrowed from doc.rust-lang.org. 64 |

65 |

66 | The documentation generator was originally written by Patman64 and is maintained by the Eluna team. 67 |

68 |
69 | 70 |

Classes

71 | 72 | {%- for class in classes %} 73 | 74 | 84 | 87 | 88 | {%- endfor %} 89 |
75 | {%- if class.fully_documented %} 76 | 77 | {%- elif class.fully_undocumented %} 78 | 79 | {%- else %} 80 | 81 | {%- endif %} 82 | {{ class.name }} 83 | 85 |

{{ class.short_description|parse_links }}

86 |
90 | {% endblock %} 91 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/method.html: -------------------------------------------------------------------------------- 1 | {% extends '_base.html' %} 2 | 3 | 4 | {% block title -%} 5 | {{ current_class.name }}:{{ current_method.name }} - Eluna 6 | {%- endblock %} 7 | 8 | 9 | {% block description -%} 10 | API documentation for the {{ current_class.name }}:{{ current_method.name }} method in the Eluna engine. 11 | {%- endblock %} 12 | 13 | 14 | {% block document_title -%} 15 | Method 16 | 17 | {{- current_class.name -}} 18 | : 19 | {{- current_method.name -}} 20 | 21 | {%- endblock %} 22 | 23 | 24 | {% block sidebar %} 25 |

{{ current_class.name }} Methods

26 | 27 | 38 | {% endblock %} 39 | 40 | 41 | {% block content %} 42 |
43 | {%- if current_method.documented %} 44 | {{ current_method.description|parse_links }} 45 | {%- else %} 46 |

This method is undocumented. Use at your own risk.

47 |

For temporary documentation, please check the LuaFunctions source file.

48 | {%- endif %} 49 | 50 |

51 | Synopsis 52 |

53 | {%- for prototype in current_method.prototypes %} 54 |

55 | {{ prototype }} 56 |

57 | {%- endfor %} 58 | 59 |

60 | Arguments 61 |

62 |

63 | {%- if current_method.parameters|length > 0 %} 64 | {%- for param in current_method.parameters %} 65 |

66 |
{{ param.data_type|escape|parse_data_type }} {{ param.name if param.data_type != '...' }} {{- ' (' + param.default_value + ')' if param.default_value }}
67 |
{{ param.description|parse_links if param.description else 'See method description.' }}
68 |
69 | {%- endfor %} 70 | {%- elif not current_method.documented %} 71 | Unknown. 72 | {%- else %} 73 | None. 74 | {%- endif %} 75 |

76 | 77 |

78 | Returns 79 |

80 |

81 | {%- if current_method.returned|length > 0 %} 82 | {%- for returned in current_method.returned %} 83 |

84 |
{{ returned.data_type|escape|parse_data_type }} {{ returned.name }}
85 |
{{ returned.description|parse_links if returned.description else 'See method description.' }}
86 |
87 | {%- endfor %} 88 | {%- elif not current_method.documented %} 89 | Unknown. 90 | {%- else %} 91 | Nothing. 92 | {%- endif %} 93 |

94 |
95 | {% endblock %} 96 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/search-index.js: -------------------------------------------------------------------------------- 1 | var searchIndex = {}; 2 | 3 | {% for class in classes -%} 4 | searchIndex["{{ class.name }}"] = { 5 | "items": [ 6 | [0, "", "{{ class.name }}", "{{ class.short_description|replace('\n', ' ')|replace('\"', '"')|parse_links|replace('"', '\\"') }}"], 7 | {%- for method in class.methods %} 8 | [3, "{{ method.name }}", "", "{{ method.short_description|replace('\n', ' ')|replace('\"', '"')|parse_links|replace('"', '\\"') }}"], 9 | {%- endfor %} 10 | ], 11 | "paths": [] 12 | }; 13 | {%- endfor %} 14 | 15 | initSearch(searchIndex); -------------------------------------------------------------------------------- /src/LuaEngine/docs/ElunaDoc/templates/sidebar.js: -------------------------------------------------------------------------------- 1 | document.write(` 2 | {%- for method in current_class.methods %} 3 | {{ method.name }} 4 | {%- endfor %} 5 | `); -------------------------------------------------------------------------------- /src/LuaEngine/docs/IMPL_DETAILS.md: -------------------------------------------------------------------------------- 1 | # Eluna features 2 | This article contains information about features and important notes regarding Eluna. 3 | 4 | ## Settings 5 | Eluna has some settings in the server configuration file. 6 | It is important that you use the new configuration file that you get from compiling after adding Eluna. If the new configuration file is not used you will not receive any error log or output to console. 7 | 8 | The configuration file includes at least the following settings: 9 | - enable and disable Eluna 10 | - enable and disable traceback function - this adds extra debug information if you have the default Eluna extensions. 11 | - configure script folder location 12 | - configure Eluna logging settings 13 | 14 | ## Reloading 15 | To make testing easier it is good to know that Eluna scripts can be reloaded by using the command `.reload eluna`. 16 | However this command should be used for development purposes __ONLY__. If you are having issues getting something working __restart__ the server. 17 | 18 | It is important to know that reloading does not trigger for example the login hook for players that are already logged in when reloading. 19 | 20 | ## Script loading 21 | Eluna loads scripts from the `lua_scripts` folder by default. You can configure the folder name and location in the server configuration file. 22 | Any hidden folders are not loaded. All script files must have an unique name, otherwise an error is printed and only the first file found is loaded. 23 | 24 | The loading order is not guaranteed to be alphabetic. 25 | Any file having `.ext` extension, for example `test.ext`, is loaded before normal lua files. 26 | 27 | Instead of the ext special feature however it is recommended to use the basic lua `require` function. 28 | The whole script folder structure is added automatically to the lua require path so using require is as simple as providing the file name without any extension for example `require("runfirst")` to require the file `runfirst.lua`. 29 | 30 | ## Automatic conversion 31 | In C++ level code you have types like `Unit` and `Creature` and `Player`. 32 | When in code you have an object of type `Unit` you need to convert it to a `Creature` or a `Player` object to be able to access the methods of the subclass. 33 | 34 | In Eluna this is automatic. All objects are automatically converted to the correct type and you will always have full access to all member functions of an object. 35 | 36 | ## Storing userdata 37 | Storing userdata objects over time that are memory managed by C++ is a bad idea. 38 | For example you should never save a player to a global variable and then try access it in a timed event. The reason is that the player object in C++ is a pointer to an object that C++ can delete at any time. When time passes the player may have logged out and using the pointer after player object no longer exists can be catastrophic. 39 | 40 | To prevent users from doing this objects that are memory managed by C++ are automatically turned into nil when they are no longer safe to be accessed - this means usually after the hooked function ends. 41 | Instead of storing the object itself you can use store guids `player:GetGUID()` and fetch the object by the guid with `map:GetWorldObject(guid)`. 42 | 43 | Any userdata object that is memory managed by lua is safe to store over time. These objects include but are not limited to: query results, worldpackets, uint64 and int64 numbers. 44 | 45 | ## Userdata metamethods 46 | All userdata objects in Eluna have tostring metamethod implemented. 47 | This allows you to print the player object for example and to use `tostring(player)`. 48 | 49 | The userdata uses metatables that contain the methods and functions it uses. 50 | These tables are globally accessible by using the type name. For example `Player` is a global table containing all Player methods. 51 | 52 | You can define new methods in lua for a class using these global tables. 53 | ```lua 54 | function Player:CustomFunc(param1) 55 | -- self is the player the method is used on 56 | self:SendBroadcastMessage(param1) 57 | end 58 | 59 | function GameObject:CustomFunc(param1) 60 | -- self is the gameobject the method is used on 61 | print(self:GetName()) 62 | end 63 | 64 | -- Example use: 65 | player:CustomFunc("test") 66 | gob:CustomFunc("test2") 67 | ``` 68 | 69 | It is recommended that in normal code these global tables and their names (variables starting with capital letters like Player, Creature, GameObject, Spell..) are avoided so they are not unintentionally edited or deleted causing other scripts possibly not to function. 70 | 71 | ## Database 72 | Database is a great thing, but it has it's own issues. 73 | 74 | ### Querying 75 | Database queries are slow. The whole server has to wait for the script to fetch the data from disk before continuing. Compared to reading cache or RAM reading from disk is the same as going to the moon to fetch the data (no pun intended). 76 | 77 | Depending on what you need, prefer database Execute over Query when not selecting anything from the database. Database Executes are made asynchronously and they will not keep the server waiting. 78 | 79 | Move all database queries possible to the script loading, server startup or similar one time event and use cache tables to manage the data in scripts. 80 | 81 | ### Types 82 | __Database types should be followed strictly.__ 83 | Mysql does math in bigint and decimal formats which is why a simple select like `SELECT 1;` actually returns a bigint. 84 | If you fetch a bigint or decimal using a function for a smaller type it is possible the value is read incorrectly. 85 | 86 | For example the same code for fetching the result of `SELECT 1;` returned 1 on one machine and 0 on another. Using the correct function, in this case GetInt64, the right result was returned on both. https://github.com/ElunaLuaEngine/Eluna/issues/89#issuecomment-64121361 87 | 88 | | base type | defined type | database type | 89 | |---------------------------|--------------|-----------------------| 90 | | char | int8 | tinyint(3) | 91 | | short int | int16 | smallint(5) | 92 | | (long int / int) | int32 | mediumint(8) | 93 | | (long int / int) | int32 | int(10) | 94 | | long long int | int64 | bigint(20) | 95 | | unsigned char | uint8 | tinyint(3) unsigned | 96 | | unsigned short int | uint16 | smallint(5) unsigned | 97 | | unsigned (long int / int) | uint32 | mediumint(8) unsigned | 98 | | unsigned (long int / int) | uint32 | int(10) unsigned | 99 | | unsigned long long int | uint64 | bigint(20) unsigned | 100 | | float | float | float | 101 | | double | double | double and decimal | 102 | | std::string | std::string | any text type | 103 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/INSTALL.md: -------------------------------------------------------------------------------- 1 | # Installing and updating 2 | This page will help you get a cMaNGOS and a TrinityCore source with Eluna. 3 | 4 | If you are looking to get MaNGOS source with Eluna head over to [MaNGOS forum](http://getmangos.eu/) for the installation and updating instructions - however read this page also as it contains important information. 5 | 6 | If you are having trouble with the installation or updating the core source, head over to our [support forum](../README.md#documentation). 7 | If you are looking for a way to merge eluna with a fork of the official repositories see [merging](MERGING.md). 8 | 9 | ### Requirements and dependencies: 10 | **Eluna uses `C++11` so you need a compiler that supports it.** 11 | **Eluna can use ACE or BOOST for filesystem library.** 12 | Additionally see you desired core's documentation and installation instructions for it's requirements and dependencies. 13 | 14 | ### Installation 15 | 1. Open [git bash](http://git-scm.com/) and navigate to where you want the core source 16 | 2. Choose the git address of your desired core and patch below and clone the core with `git clone
`. 17 | For example `git clone https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git` 18 | * TrinityCore WoTLK: `https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git` 19 | * cMaNGOS Classic: `https://github.com/ElunaLuaEngine/ElunaMangosClassic.git` 20 | * cMaNGOS TBC: `https://github.com/ElunaLuaEngine/ElunaMangosTbc.git` 21 | * cMaNGOS WoTLK: `https://github.com/ElunaLuaEngine/ElunaMangosWotlk.git` 22 | 3. Navigate to the newly created source folder with `git bash` 23 | 4. Use the git command `git submodule init` followed by `git submodule update` 24 | * If you really do not get how to use git bash (and do try!) you can navigate to the `LuaEngine` folder and clone the [eluna repository](https://github.com/ElunaLuaEngine/Eluna) there. This is not recommended though. 25 | 4. Continue compiling the core normally using the official instructions 26 | * [TrinityCore](http://collab.kpsn.org/display/tc/Installation+Guide) 27 | * [cMaNGOS](https://github.com/cmangos/issues/wiki/Installation-Instructions) 28 | 29 | __Important!__ After compiling use the new configuration files. They contain Eluna settings and without them Eluna may not function correctly. For example you do not get any error messages or error log. 30 | 31 | After installing Eluna you should check out these: 32 | - [Eluna getting started](USAGE.md) 33 | - [Eluna features](IMPL_DETAILS.md) 34 | 35 | ### Updating 36 | Updating is essentially handled in the same manner as you would normally update the core and database. 37 | To get the newest core source code open `git bash` and navigate to your local source folder. 38 | Then execute use `git pull` followed by `git submodule init` and `git submodule update`. 39 | After updating the source you need to recompile the core normally. Simply use `CMake` if needed and compile. 40 | To update the databases refer to the core's or database's official updating documents: 41 | * [TrinityCore](http://collab.kpsn.org/display/tc/Databases+Installation) 42 | * [cMaNGOS](https://github.com/cmangos/issues/wiki/Installation-Instructions) 43 | -------------------------------------------------------------------------------- /src/LuaEngine/docs/MERGING.md: -------------------------------------------------------------------------------- 1 | # Merging Eluna 2 | Eluna can be added to various sources by applying the core changes required for Eluna to function. 3 | Below you find the guides for merging Eluna with each core or a fork of it. 4 | If you choose to merge you should be able to maintain and update yourself - we do not maintain your core. View Unofficial Merging below. 5 | We also do not fix any merging errors you may have, but you are free to ask about them on the [support forum](../README.md#documentation) and we may assist. 6 | 7 | We recommend using the [installation guide](INSTALL.md) especially if you are not familiar with git and updating the code. 8 | It allows you to simply use `git pull` followed by `git submodule update` to update your source and we will handle the merging and maintenance with the official core source. Naturally you still need to handle updating the database as instructed by the core's wiki or instructions. 9 | 10 | ### Merging Eluna with MaNGOS 11 | Eluna is merged with [official MaNGOS](http://getmangos.eu/) by default. 12 | 13 | ### Merging Eluna with cMaNGOS 14 | ``` 15 | git clone https://github.com/cmangos/mangos-wotlk.git 16 | cd mangos-wotlk 17 | git pull --recurse-submodules https://github.com/ElunaLuaEngine/ElunaMangosWotlk.git 18 | ``` 19 | Steps explained: 20 | 1. clone the core or fork source or get the it by other means 21 | 2. navigate to the source folder 22 | 3. pull the Eluna fork. This will fetch the repository and merge it with your source. 23 | * `--recurse-submodules` will automatically pull the submodules (Eluna repository). You may need to use `git submodule init` followed by `git submodule update` if your Eluna folder is empty 24 | * it is important that you choose the correct Eluna fork for your core andpatch: 25 | * [Eluna cMaNGOS Classic](https://github.com/ElunaLuaEngine/ElunaMangosClassic) 26 | * [Eluna cMaNGOS TBC](https://github.com/ElunaLuaEngine/ElunaMangosTbc) 27 | * [Eluna cMaNGOS WotLK](https://github.com/ElunaLuaEngine/ElunaMangosWotlk) 28 | 29 | ### Merging Eluna with TrinityCore 30 | ``` 31 | git clone https://github.com/TrinityCore/TrinityCore.git -b3.3.5 32 | cd TrinityCore 33 | git pull --recurse-submodules https://github.com/ElunaLuaEngine/ElunaTrinityWotlk.git 34 | ``` 35 | Steps explained: 36 | 1. clone the core or fork source or get the it by other means 37 | 2. navigate to the source folder 38 | 3. pull the Eluna fork. This will fetch the repository and merge it with your source. 39 | * `--recurse-submodules` will automatically pull the submodules (Eluna repository). You may need to use `git submodule init` followed by `git submodule update` if your Eluna folder is empty 40 | * it is important that you choose the correct Eluna fork for your core and patch: 41 | * [Eluna TrinityCore WotLK](https://github.com/ElunaLuaEngine/ElunaTrinityWotlk) 42 | * [Eluna TrinityCore Cataclysm](https://github.com/ElunaLuaEngine/ElunaTrinityCata) 43 | -------------------------------------------------------------------------------- /src/LuaEngine/extensions/ObjectVariables.ext: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | -- This program is free software licensed under GPL version 3 4 | -- Please see the included DOCS/LICENSE.md for more information 5 | -- 6 | 7 | -- filename.ext files are loaded before normal .lua files 8 | 9 | -- 10 | -- This extension allows saving data to specific object for it's lifetime in current runtime session 11 | -- Supports Map, Player, Creature, GameObject 12 | -- 13 | -- SetData sets a value 14 | -- obj:SetData(key, val) 15 | -- 16 | -- GetData gets the data table or a specific value by key from it 17 | -- local tbl = obj:GetData() 18 | -- local val = obj:GetData(key) 19 | -- 20 | 21 | local pairs = pairs 22 | 23 | local variableStores = { 24 | Map = {}, 25 | Player = {}, 26 | Creature = {}, 27 | GameObject = {}, 28 | } 29 | 30 | local function DestroyMapData(event, obj) 31 | local map = obj:GetMapId() 32 | local inst = obj:GetInstanceId() 33 | for k,v in pairs(variableStores) do 34 | local mapdata = v[map] 35 | if mapdata then 36 | mapdata[inst] = nil 37 | end 38 | end 39 | end 40 | 41 | local function DestroyObjData(event, obj) 42 | local otype = obj:GetObjectType() 43 | local guid = otype == "Map" and 1 or obj:GetGUIDLow() 44 | 45 | if otype == "Player" then 46 | variableStores[otype][guid] = nil 47 | return 48 | end 49 | 50 | local map = obj:GetMapId() 51 | local inst = obj:GetInstanceId() 52 | local mapdata = variableStores[otype][map] 53 | if mapdata then 54 | local instancedata = mapdata[inst] 55 | if instancedata then 56 | instancedata[guid] = nil 57 | end 58 | end 59 | end 60 | 61 | local function GetData(self, field) 62 | local otype = self:GetObjectType() 63 | local guid = otype == "Map" and 1 or self:GetGUIDLow() 64 | local varStore = variableStores[otype] 65 | 66 | if otype == "Player" then 67 | varStore[guid] = varStore[guid] or {} 68 | if field ~= nil then 69 | return varStore[guid][field] 70 | end 71 | return varStore[guid] 72 | end 73 | 74 | local map = self:GetMapId() 75 | local inst = self:GetInstanceId() 76 | varStore[map] = varStore[map] or {} 77 | varStore[map][inst] = varStore[map][inst] or {} 78 | varStore[map][inst][guid] = varStore[map][inst][guid] or {} 79 | 80 | if field ~= nil then 81 | return varStore[map][inst][guid][field] 82 | end 83 | return varStore[map][inst][guid] 84 | end 85 | 86 | local function SetData(self, field, val) 87 | local otype = self:GetObjectType() 88 | local guid = otype == "Map" and 1 or self:GetGUIDLow() 89 | local varStore = variableStores[otype] 90 | 91 | if otype == "Player" then 92 | varStore[guid] = varStore[guid] or {} 93 | varStore[guid][field] = val 94 | return 95 | end 96 | 97 | local map = self:GetMapId() 98 | local inst = self:GetInstanceId() 99 | varStore[map] = varStore[map] or {} 100 | varStore[map][inst] = varStore[map][inst] or {} 101 | varStore[map][inst][guid] = varStore[map][inst][guid] or {} 102 | 103 | varStore[map][inst][guid][field] = val 104 | end 105 | 106 | for k,v in pairs(variableStores) do 107 | _G[k].GetData = GetData 108 | _G[k].SetData = SetData 109 | end 110 | 111 | RegisterPlayerEvent(4, DestroyObjData) -- logout 112 | RegisterServerEvent(31, DestroyObjData) -- creature delete 113 | RegisterServerEvent(32, DestroyObjData) -- gameobject delete 114 | RegisterServerEvent(17, DestroyMapData) -- map create 115 | RegisterServerEvent(18, DestroyMapData) -- map destroy 116 | -------------------------------------------------------------------------------- /src/LuaEngine/extensions/StackTracePlus/LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azerothcore/mod-eluna/6f9da64fd4ebee45c6d3da70dfa7d9b3daeddcbe/src/LuaEngine/extensions/StackTracePlus/LICENSE -------------------------------------------------------------------------------- /src/LuaEngine/extensions/StackTracePlus/README.md: -------------------------------------------------------------------------------- 1 | # StackTracePlus # 2 | 3 | [![Build Status](https://travis-ci.org/ignacio/StackTracePlus.png?branch=master)](https://travis-ci.org/ignacio/StackTracePlus) 4 | 5 | [StackTracePlus](https://github.com/ignacio/StackTracePlus) provides enhanced stack traces for [Lua 5.1, Lua 5.2][1] and [LuaJIT][2]. 6 | 7 | StackTracePlus can be used as a replacement for debug.traceback. It gives detailed information about locals, tries to guess 8 | function names when they're not available, etc, so, instead of 9 | 10 | lua5.1.exe: D:\trunk_git\sources\stacktraceplus\test\test.lua:10: attempt to concatenate a nil value 11 | stack traceback: 12 | D:\trunk_git\sources\stacktraceplus\test\test.lua:10: in function 13 | (tail call): ? 14 | D:\trunk_git\sources\stacktraceplus\test\test.lua:15: in main chunk 15 | [C]: ? 16 | 17 | you'll get 18 | 19 | lua5.1.exe: D:\trunk_git\sources\stacktraceplus\test\test.lua:10: attempt to concatenate a nil value 20 | Stack Traceback 21 | =============== 22 | (2) C function 'function: 00A8F418' 23 | (3) Lua function 'g' at file 'D:\trunk_git\sources\stacktraceplus\test\test.lua:10' (best guess) 24 | Local variables: 25 | fun = table module 26 | str = string: "hey" 27 | tb = table: 027DCBE0 {dummy:1, blah:true, foo:bar} 28 | (*temporary) = nil 29 | (*temporary) = string: "text" 30 | (*temporary) = string: "attempt to concatenate a nil value" 31 | (4) tail call 32 | (5) main chunk of file 'D:\trunk_git\sources\stacktraceplus\test\test.lua' at line 15 33 | (6) C function 'function: 002CA480' 34 | 35 | ## Usage # 36 | 37 | StackTracePlus can be used as a replacement for `debug.traceback`, as an `xpcall` error handler or even from C code. Note that 38 | only the Lua 5.1 interpreter allows the traceback function to be replaced "on the fly". LuaJIT and Lua 5.2 always calls luaL_traceback internally so there is no easy way to override that. 39 | 40 | ```lua 41 | local STP = require "StackTracePlus" 42 | 43 | debug.traceback = STP.stacktrace 44 | function test() 45 | local s = "this is a string" 46 | local n = 42 47 | local t = { foo = "bar" } 48 | local co = coroutine 49 | local cr = coroutine.create 50 | 51 | error("an error") 52 | end 53 | test() 54 | ``` 55 | 56 | That script will output (only with Lua 5.1): 57 | 58 | lua5.1: example.lua:11: an error 59 | Stack Traceback 60 | =============== 61 | (2) C function 'function: 006B5758' 62 | (3) global C function 'error' 63 | (4) Lua global 'test' at file 'example.lua:11' 64 | Local variables: 65 | s = string: "this is a string" 66 | n = number: 42 67 | t = table: 006E5220 {foo:bar} 68 | co = coroutine table 69 | cr = C function: 003C7080 70 | (5) main chunk of file 'example.lua' at line 14 71 | (6) C function 'function: 00637B30' 72 | 73 | **StackTracePlus** is aware of the usual Lua libraries, like *coroutine*, *table*, *string*, *io*, etc and functions like 74 | *print*, *pcall*, *assert*, and so on. 75 | 76 | You can also make STP aware of your own tables and functions by calling *add_known_function* and *add_known_table*. 77 | 78 | ```lua 79 | local STP = require "StackTracePlus" 80 | 81 | debug.traceback = STP.stacktrace 82 | local my_table = { 83 | f = function() end 84 | } 85 | function my_function() 86 | end 87 | 88 | function test(data, func) 89 | local s = "this is a string" 90 | 91 | error("an error") 92 | end 93 | 94 | STP.add_known_table(my_table, "A description for my_table") 95 | STP.add_known_function(my_function, "A description for my_function") 96 | 97 | test( my_table, my_function ) 98 | ``` 99 | 100 | Will output: 101 | 102 | lua5.1: ..\test\example2.lua:13: an error 103 | Stack Traceback 104 | =============== 105 | (2) C function 'function: 0073AAA8' 106 | (3) global C function 'error' 107 | (4) Lua global 'test' at file '..\test\example2.lua:13' 108 | Local variables: 109 | data = A description for my_table 110 | func = Lua function 'A description for my_function' (defined at line 7 of chunk ..\test\example2.lua) 111 | s = string: "this is a string" 112 | (5) main chunk of file '..\test\example2.lua' at line 19 113 | (6) C function 'function: 00317B30' 114 | 115 | 116 | ## Installation # 117 | The easiest way to install is with [LuaRocks][3]. 118 | 119 | - luarocks install stacktraceplus 120 | 121 | If you don't want to use LuaRocks, just copy StackTracePlus.lua to Lua's path. 122 | 123 | ## License # 124 | **StackTracePlus** is available under the MIT license. 125 | 126 | [1]: http://www.lua.org/ 127 | [2]: http://luajit.org/ 128 | [3]: http://luarocks.org/ 129 | -------------------------------------------------------------------------------- /src/LuaEngine/extensions/_Misc.ext: -------------------------------------------------------------------------------- 1 | -- 2 | -- Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | -- This program is free software licensed under GPL version 3 4 | -- Please see the included DOCS/LICENSE.md for more information 5 | -- 6 | 7 | -- filename.ext files are loaded before normal .lua files 8 | 9 | -- Randomize random 10 | math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6))) 11 | 12 | -- Set debug.traceback to use StackTracePlus to print full stack trace 13 | local trace = require("StackTracePlus") 14 | debug.traceback = trace.stacktrace 15 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/BattleGroundHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | using namespace Hooks; 14 | 15 | #define START_HOOK(EVENT) \ 16 | if (!IsEnabled())\ 17 | return;\ 18 | auto key = EventKey(EVENT);\ 19 | if (!BGEventBindings->HasBindingsFor(key))\ 20 | return;\ 21 | LOCK_ELUNA 22 | 23 | void Eluna::OnBGStart(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) 24 | { 25 | START_HOOK(BG_EVENT_ON_START); 26 | Push(bg); 27 | Push(bgId); 28 | Push(instanceId); 29 | CallAllFunctions(BGEventBindings, key); 30 | } 31 | 32 | void Eluna::OnBGEnd(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId, TeamId winner) 33 | { 34 | START_HOOK(BG_EVENT_ON_END); 35 | Push(bg); 36 | Push(bgId); 37 | Push(instanceId); 38 | Push(winner); 39 | CallAllFunctions(BGEventBindings, key); 40 | } 41 | 42 | void Eluna::OnBGCreate(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) 43 | { 44 | START_HOOK(BG_EVENT_ON_CREATE); 45 | Push(bg); 46 | Push(bgId); 47 | Push(instanceId); 48 | CallAllFunctions(BGEventBindings, key); 49 | } 50 | 51 | void Eluna::OnBGDestroy(BattleGround* bg, BattleGroundTypeId bgId, uint32 instanceId) 52 | { 53 | START_HOOK(BG_EVENT_ON_PRE_DESTROY); 54 | Push(bg); 55 | Push(bgId); 56 | Push(instanceId); 57 | CallAllFunctions(BGEventBindings, key); 58 | } 59 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/GameObjectHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaEventMgr.h" 13 | #include "ElunaTemplate.h" 14 | 15 | using namespace Hooks; 16 | 17 | #define START_HOOK(EVENT, ENTRY) \ 18 | if (!IsEnabled())\ 19 | return;\ 20 | auto key = EntryKey(EVENT, ENTRY);\ 21 | if (!GameObjectEventBindings->HasBindingsFor(key))\ 22 | return;\ 23 | LOCK_ELUNA 24 | 25 | #define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ 26 | if (!IsEnabled())\ 27 | return RETVAL;\ 28 | auto key = EntryKey(EVENT, ENTRY);\ 29 | if (!GameObjectEventBindings->HasBindingsFor(key))\ 30 | return RETVAL;\ 31 | LOCK_ELUNA 32 | 33 | void Eluna::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, GameObject* pTarget) 34 | { 35 | START_HOOK(GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); 36 | Push(pCaster); 37 | Push(spellId); 38 | Push(effIndex); 39 | Push(pTarget); 40 | CallAllFunctions(GameObjectEventBindings, key); 41 | } 42 | 43 | void Eluna::UpdateAI(GameObject* pGameObject, uint32 diff) 44 | { 45 | pGameObject->elunaEvents->Update(diff); 46 | START_HOOK(GAMEOBJECT_EVENT_ON_AIUPDATE, pGameObject->GetEntry()); 47 | Push(pGameObject); 48 | Push(diff); 49 | CallAllFunctions(GameObjectEventBindings, key); 50 | } 51 | 52 | bool Eluna::OnQuestAccept(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest) 53 | { 54 | START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, pGameObject->GetEntry(), false); 55 | Push(pPlayer); 56 | Push(pGameObject); 57 | Push(pQuest); 58 | return CallAllFunctionsBool(GameObjectEventBindings, key); 59 | } 60 | 61 | bool Eluna::OnQuestReward(Player* pPlayer, GameObject* pGameObject, Quest const* pQuest, uint32 opt) 62 | { 63 | START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_QUEST_REWARD, pGameObject->GetEntry(), false); 64 | Push(pPlayer); 65 | Push(pGameObject); 66 | Push(pQuest); 67 | Push(opt); 68 | return CallAllFunctionsBool(GameObjectEventBindings, key); 69 | } 70 | 71 | void Eluna::GetDialogStatus(const Player* pPlayer, const GameObject* pGameObject) 72 | { 73 | START_HOOK(GAMEOBJECT_EVENT_ON_DIALOG_STATUS, pGameObject->GetEntry()); 74 | Push(pPlayer); 75 | Push(pGameObject); 76 | CallAllFunctions(GameObjectEventBindings, key); 77 | } 78 | 79 | void Eluna::OnDestroyed(GameObject* pGameObject, WorldObject* attacker) 80 | { 81 | START_HOOK(GAMEOBJECT_EVENT_ON_DESTROYED, pGameObject->GetEntry()); 82 | Push(pGameObject); 83 | Push(attacker); 84 | CallAllFunctions(GameObjectEventBindings, key); 85 | } 86 | 87 | void Eluna::OnDamaged(GameObject* pGameObject, WorldObject* attacker) 88 | { 89 | START_HOOK(GAMEOBJECT_EVENT_ON_DAMAGED, pGameObject->GetEntry()); 90 | Push(pGameObject); 91 | Push(attacker); 92 | CallAllFunctions(GameObjectEventBindings, key); 93 | } 94 | 95 | void Eluna::OnLootStateChanged(GameObject* pGameObject, uint32 state) 96 | { 97 | START_HOOK(GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, pGameObject->GetEntry()); 98 | Push(pGameObject); 99 | Push(state); 100 | CallAllFunctions(GameObjectEventBindings, key); 101 | } 102 | 103 | void Eluna::OnGameObjectStateChanged(GameObject* pGameObject, uint32 state) 104 | { 105 | START_HOOK(GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, pGameObject->GetEntry()); 106 | Push(pGameObject); 107 | Push(state); 108 | CallAllFunctions(GameObjectEventBindings, key); 109 | } 110 | 111 | void Eluna::OnSpawn(GameObject* pGameObject) 112 | { 113 | START_HOOK(GAMEOBJECT_EVENT_ON_SPAWN, pGameObject->GetEntry()); 114 | Push(pGameObject); 115 | CallAllFunctions(GameObjectEventBindings, key); 116 | } 117 | 118 | void Eluna::OnAddToWorld(GameObject* pGameObject) 119 | { 120 | START_HOOK(GAMEOBJECT_EVENT_ON_ADD, pGameObject->GetEntry()); 121 | Push(pGameObject); 122 | CallAllFunctions(GameObjectEventBindings, key); 123 | } 124 | 125 | void Eluna::OnRemoveFromWorld(GameObject* pGameObject) 126 | { 127 | START_HOOK(GAMEOBJECT_EVENT_ON_REMOVE, pGameObject->GetEntry()); 128 | Push(pGameObject); 129 | CallAllFunctions(GameObjectEventBindings, key); 130 | } 131 | 132 | bool Eluna::OnGameObjectUse(Player* pPlayer, GameObject* pGameObject) 133 | { 134 | START_HOOK_WITH_RETVAL(GAMEOBJECT_EVENT_ON_USE, pGameObject->GetEntry(), false); 135 | Push(pGameObject); 136 | Push(pPlayer); 137 | return CallAllFunctionsBool(GameObjectEventBindings, key); 138 | } 139 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/GossipHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK(BINDINGS, EVENT, ENTRY) \ 17 | if (!IsEnabled())\ 18 | return;\ 19 | auto key = EntryKey(EVENT, ENTRY);\ 20 | if (!BINDINGS->HasBindingsFor(key))\ 21 | return;\ 22 | LOCK_ELUNA 23 | 24 | #define START_HOOK_WITH_RETVAL(BINDINGS, EVENT, ENTRY, RETVAL) \ 25 | if (!IsEnabled())\ 26 | return RETVAL;\ 27 | auto key = EntryKey(EVENT, ENTRY);\ 28 | if (!BINDINGS->HasBindingsFor(key))\ 29 | return RETVAL;\ 30 | LOCK_ELUNA 31 | 32 | bool Eluna::OnGossipHello(Player* pPlayer, GameObject* pGameObject) 33 | { 34 | START_HOOK_WITH_RETVAL(GameObjectGossipBindings, GOSSIP_EVENT_ON_HELLO, pGameObject->GetEntry(), false); 35 | pPlayer->PlayerTalkClass->ClearMenus(); 36 | Push(pPlayer); 37 | Push(pGameObject); 38 | return CallAllFunctionsBool(GameObjectGossipBindings, key, true); 39 | } 40 | 41 | bool Eluna::OnGossipSelect(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action) 42 | { 43 | START_HOOK_WITH_RETVAL(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry(), false); 44 | pPlayer->PlayerTalkClass->ClearMenus(); 45 | Push(pPlayer); 46 | Push(pGameObject); 47 | Push(sender); 48 | Push(action); 49 | return CallAllFunctionsBool(GameObjectGossipBindings, key, true); 50 | } 51 | 52 | bool Eluna::OnGossipSelectCode(Player* pPlayer, GameObject* pGameObject, uint32 sender, uint32 action, const char* code) 53 | { 54 | START_HOOK_WITH_RETVAL(GameObjectGossipBindings, GOSSIP_EVENT_ON_SELECT, pGameObject->GetEntry(), false); 55 | pPlayer->PlayerTalkClass->ClearMenus(); 56 | Push(pPlayer); 57 | Push(pGameObject); 58 | Push(sender); 59 | Push(action); 60 | Push(code); 61 | return CallAllFunctionsBool(GameObjectGossipBindings, key, true); 62 | } 63 | 64 | void Eluna::HandleGossipSelectOption(Player* pPlayer, uint32 menuId, uint32 sender, uint32 action, const std::string& code) 65 | { 66 | START_HOOK(PlayerGossipBindings, GOSSIP_EVENT_ON_SELECT, menuId); 67 | pPlayer->PlayerTalkClass->ClearMenus(); 68 | 69 | Push(pPlayer); // receiver 70 | Push(pPlayer); // sender, just not to mess up the amount of args. 71 | Push(sender); 72 | Push(action); 73 | if (code.empty()) 74 | Push(); 75 | else 76 | Push(code); 77 | 78 | CallAllFunctions(PlayerGossipBindings, key); 79 | } 80 | 81 | bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/) 82 | { 83 | START_HOOK_WITH_RETVAL(ItemGossipBindings, GOSSIP_EVENT_ON_HELLO, pItem->GetEntry(), true); 84 | pPlayer->PlayerTalkClass->ClearMenus(); 85 | Push(pPlayer); 86 | Push(pItem); 87 | return CallAllFunctionsBool(ItemGossipBindings, key, true); 88 | } 89 | 90 | void Eluna::HandleGossipSelectOption(Player* pPlayer, Item* pItem, uint32 sender, uint32 action, const std::string& code) 91 | { 92 | START_HOOK(ItemGossipBindings, GOSSIP_EVENT_ON_SELECT, pItem->GetEntry()); 93 | pPlayer->PlayerTalkClass->ClearMenus(); 94 | 95 | Push(pPlayer); 96 | Push(pItem); 97 | Push(sender); 98 | Push(action); 99 | if (code.empty()) 100 | Push(); 101 | else 102 | Push(code); 103 | 104 | CallAllFunctions(ItemGossipBindings, key); 105 | } 106 | 107 | bool Eluna::OnGossipHello(Player* pPlayer, Creature* pCreature) 108 | { 109 | START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_HELLO, pCreature->GetEntry(), false); 110 | pPlayer->PlayerTalkClass->ClearMenus(); 111 | Push(pPlayer); 112 | Push(pCreature); 113 | return CallAllFunctionsBool(CreatureGossipBindings, key, true); 114 | } 115 | 116 | bool Eluna::OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action) 117 | { 118 | START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), false); 119 | auto originalMenu = *pPlayer->PlayerTalkClass; 120 | pPlayer->PlayerTalkClass->ClearMenus(); 121 | Push(pPlayer); 122 | Push(pCreature); 123 | Push(sender); 124 | Push(action); 125 | auto preventDefault = CallAllFunctionsBool(CreatureGossipBindings, key, true); 126 | if (!preventDefault) { 127 | *pPlayer->PlayerTalkClass = originalMenu; 128 | } 129 | return preventDefault; 130 | } 131 | 132 | bool Eluna::OnGossipSelectCode(Player* pPlayer, Creature* pCreature, uint32 sender, uint32 action, const char* code) 133 | { 134 | START_HOOK_WITH_RETVAL(CreatureGossipBindings, GOSSIP_EVENT_ON_SELECT, pCreature->GetEntry(), false); 135 | auto originalMenu = *pPlayer->PlayerTalkClass; 136 | pPlayer->PlayerTalkClass->ClearMenus(); 137 | Push(pPlayer); 138 | Push(pCreature); 139 | Push(sender); 140 | Push(action); 141 | Push(code); 142 | auto preventDefault = CallAllFunctionsBool(CreatureGossipBindings, key, true); 143 | if (!preventDefault) { 144 | *pPlayer->PlayerTalkClass = originalMenu; 145 | } 146 | return preventDefault; 147 | } 148 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/GroupHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | using namespace Hooks; 14 | 15 | #define START_HOOK(EVENT) \ 16 | if (!IsEnabled())\ 17 | return;\ 18 | auto key = EventKey(EVENT);\ 19 | if (!GroupEventBindings->HasBindingsFor(key))\ 20 | return;\ 21 | LOCK_ELUNA 22 | 23 | void Eluna::OnAddMember(Group* group, ObjectGuid guid) 24 | { 25 | START_HOOK(GROUP_EVENT_ON_MEMBER_ADD); 26 | Push(group); 27 | Push(guid); 28 | CallAllFunctions(GroupEventBindings, key); 29 | } 30 | 31 | void Eluna::OnInviteMember(Group* group, ObjectGuid guid) 32 | { 33 | START_HOOK(GROUP_EVENT_ON_MEMBER_INVITE); 34 | Push(group); 35 | Push(guid); 36 | CallAllFunctions(GroupEventBindings, key); 37 | } 38 | 39 | void Eluna::OnRemoveMember(Group* group, ObjectGuid guid, uint8 method) 40 | { 41 | START_HOOK(GROUP_EVENT_ON_MEMBER_REMOVE); 42 | Push(group); 43 | Push(guid); 44 | Push(method); 45 | CallAllFunctions(GroupEventBindings, key); 46 | } 47 | 48 | void Eluna::OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid) 49 | { 50 | START_HOOK(GROUP_EVENT_ON_LEADER_CHANGE); 51 | Push(group); 52 | Push(newLeaderGuid); 53 | Push(oldLeaderGuid); 54 | CallAllFunctions(GroupEventBindings, key); 55 | } 56 | 57 | void Eluna::OnDisband(Group* group) 58 | { 59 | START_HOOK(GROUP_EVENT_ON_DISBAND); 60 | Push(group); 61 | CallAllFunctions(GroupEventBindings, key); 62 | } 63 | 64 | void Eluna::OnCreate(Group* group, ObjectGuid leaderGuid, GroupType groupType) 65 | { 66 | START_HOOK(GROUP_EVENT_ON_CREATE); 67 | Push(group); 68 | Push(leaderGuid); 69 | Push(groupType); 70 | CallAllFunctions(GroupEventBindings, key); 71 | } 72 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/GuildHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | using namespace Hooks; 14 | 15 | #define START_HOOK(EVENT) \ 16 | if (!IsEnabled())\ 17 | return;\ 18 | auto key = EventKey(EVENT);\ 19 | if (!GuildEventBindings->HasBindingsFor(key))\ 20 | return;\ 21 | LOCK_ELUNA 22 | 23 | void Eluna::OnAddMember(Guild* guild, Player* player, uint32 plRank) 24 | { 25 | START_HOOK(GUILD_EVENT_ON_ADD_MEMBER); 26 | Push(guild); 27 | Push(player); 28 | Push(plRank); 29 | CallAllFunctions(GuildEventBindings, key); 30 | } 31 | 32 | void Eluna::OnRemoveMember(Guild* guild, Player* player, bool isDisbanding) 33 | { 34 | START_HOOK(GUILD_EVENT_ON_REMOVE_MEMBER); 35 | Push(guild); 36 | Push(player); 37 | Push(isDisbanding); 38 | CallAllFunctions(GuildEventBindings, key); 39 | } 40 | 41 | void Eluna::OnMOTDChanged(Guild* guild, const std::string& newMotd) 42 | { 43 | START_HOOK(GUILD_EVENT_ON_MOTD_CHANGE); 44 | Push(guild); 45 | Push(newMotd); 46 | CallAllFunctions(GuildEventBindings, key); 47 | } 48 | 49 | void Eluna::OnInfoChanged(Guild* guild, const std::string& newInfo) 50 | { 51 | START_HOOK(GUILD_EVENT_ON_INFO_CHANGE); 52 | Push(guild); 53 | Push(newInfo); 54 | CallAllFunctions(GuildEventBindings, key); 55 | } 56 | 57 | void Eluna::OnCreate(Guild* guild, Player* leader, const std::string& name) 58 | { 59 | START_HOOK(GUILD_EVENT_ON_CREATE); 60 | Push(guild); 61 | Push(leader); 62 | Push(name); 63 | CallAllFunctions(GuildEventBindings, key); 64 | } 65 | 66 | void Eluna::OnDisband(Guild* guild) 67 | { 68 | START_HOOK(GUILD_EVENT_ON_DISBAND); 69 | Push(guild); 70 | CallAllFunctions(GuildEventBindings, key); 71 | } 72 | 73 | void Eluna::OnMemberWitdrawMoney(Guild* guild, Player* player, uint32& amount, bool isRepair) 74 | { 75 | START_HOOK(GUILD_EVENT_ON_MONEY_WITHDRAW); 76 | Push(guild); 77 | Push(player); 78 | Push(amount); 79 | Push(isRepair); // isRepair not a part of Mangos, implement? 80 | int amountIndex = lua_gettop(L) - 1; 81 | int n = SetupStack(GuildEventBindings, key, 4); 82 | 83 | while (n > 0) 84 | { 85 | int r = CallOneFunction(n--, 4, 1); 86 | 87 | if (lua_isnumber(L, r)) 88 | { 89 | amount = CHECKVAL(L, r); 90 | // Update the stack for subsequent calls. 91 | ReplaceArgument(amount, amountIndex); 92 | } 93 | 94 | lua_pop(L, 1); 95 | } 96 | 97 | CleanUpStack(4); 98 | } 99 | 100 | void Eluna::OnMemberDepositMoney(Guild* guild, Player* player, uint32& amount) 101 | { 102 | START_HOOK(GUILD_EVENT_ON_MONEY_DEPOSIT); 103 | Push(guild); 104 | Push(player); 105 | Push(amount); 106 | int amountIndex = lua_gettop(L); 107 | int n = SetupStack(GuildEventBindings, key, 3); 108 | 109 | while (n > 0) 110 | { 111 | int r = CallOneFunction(n--, 3, 1); 112 | 113 | if (lua_isnumber(L, r)) 114 | { 115 | amount = CHECKVAL(L, r); 116 | // Update the stack for subsequent calls. 117 | ReplaceArgument(amount, amountIndex); 118 | } 119 | 120 | lua_pop(L, 1); 121 | } 122 | 123 | CleanUpStack(3); 124 | } 125 | 126 | void Eluna::OnItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId, 127 | bool isDestBank, uint8 destContainer, uint8 destSlotId) 128 | { 129 | START_HOOK(GUILD_EVENT_ON_ITEM_MOVE); 130 | Push(guild); 131 | Push(player); 132 | Push(pItem); 133 | Push(isSrcBank); 134 | Push(srcContainer); 135 | Push(srcSlotId); 136 | Push(isDestBank); 137 | Push(destContainer); 138 | Push(destSlotId); 139 | CallAllFunctions(GuildEventBindings, key); 140 | } 141 | 142 | void Eluna::OnEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank) 143 | { 144 | START_HOOK(GUILD_EVENT_ON_EVENT); 145 | Push(guild); 146 | Push(eventType); 147 | Push(playerGuid1); 148 | Push(playerGuid2); 149 | Push(newRank); 150 | CallAllFunctions(GuildEventBindings, key); 151 | } 152 | 153 | void Eluna::OnBankEvent(Guild* guild, uint8 eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) 154 | { 155 | START_HOOK(GUILD_EVENT_ON_BANK_EVENT); 156 | Push(guild); 157 | Push(eventType); 158 | Push(tabId); 159 | Push(playerGuid); 160 | Push(itemOrMoney); 161 | Push(itemStackCount); 162 | Push(destTabId); 163 | CallAllFunctions(GuildEventBindings, key); 164 | } 165 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/InstanceHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | #include "ElunaInstanceAI.h" 14 | 15 | using namespace Hooks; 16 | 17 | #define START_HOOK(EVENT, AI) \ 18 | if (!IsEnabled())\ 19 | return;\ 20 | auto mapKey = EntryKey(EVENT, AI->instance->GetId());\ 21 | auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ 22 | if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ 23 | return;\ 24 | LOCK_ELUNA;\ 25 | PushInstanceData(L, AI);\ 26 | Push(AI->instance) 27 | 28 | #define START_HOOK_WITH_RETVAL(EVENT, AI, RETVAL) \ 29 | if (!IsEnabled())\ 30 | return RETVAL;\ 31 | auto mapKey = EntryKey(EVENT, AI->instance->GetId());\ 32 | auto instanceKey = EntryKey(EVENT, AI->instance->GetInstanceId());\ 33 | if (!MapEventBindings->HasBindingsFor(mapKey) && !InstanceEventBindings->HasBindingsFor(instanceKey))\ 34 | return RETVAL;\ 35 | LOCK_ELUNA;\ 36 | PushInstanceData(L, AI);\ 37 | Push(AI->instance) 38 | 39 | void Eluna::OnInitialize(ElunaInstanceAI* ai) 40 | { 41 | START_HOOK(INSTANCE_EVENT_ON_INITIALIZE, ai); 42 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 43 | } 44 | 45 | void Eluna::OnLoad(ElunaInstanceAI* ai) 46 | { 47 | START_HOOK(INSTANCE_EVENT_ON_LOAD, ai); 48 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 49 | } 50 | 51 | void Eluna::OnUpdateInstance(ElunaInstanceAI* ai, uint32 diff) 52 | { 53 | START_HOOK(INSTANCE_EVENT_ON_UPDATE, ai); 54 | Push(diff); 55 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 56 | } 57 | 58 | void Eluna::OnPlayerEnterInstance(ElunaInstanceAI* ai, Player* player) 59 | { 60 | START_HOOK(INSTANCE_EVENT_ON_PLAYER_ENTER, ai); 61 | Push(player); 62 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 63 | } 64 | 65 | void Eluna::OnCreatureCreate(ElunaInstanceAI* ai, Creature* creature) 66 | { 67 | START_HOOK(INSTANCE_EVENT_ON_CREATURE_CREATE, ai); 68 | Push(creature); 69 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 70 | } 71 | 72 | void Eluna::OnGameObjectCreate(ElunaInstanceAI* ai, GameObject* gameobject) 73 | { 74 | START_HOOK(INSTANCE_EVENT_ON_GAMEOBJECT_CREATE, ai); 75 | Push(gameobject); 76 | CallAllFunctions(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 77 | } 78 | 79 | bool Eluna::OnCheckEncounterInProgress(ElunaInstanceAI* ai) 80 | { 81 | START_HOOK_WITH_RETVAL(INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS, ai, false); 82 | return CallAllFunctionsBool(MapEventBindings, InstanceEventBindings, mapKey, instanceKey); 83 | } 84 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/ItemHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK(EVENT, ENTRY) \ 17 | if (!IsEnabled())\ 18 | return;\ 19 | auto key = EntryKey(EVENT, ENTRY);\ 20 | if (!ItemEventBindings->HasBindingsFor(key))\ 21 | return;\ 22 | LOCK_ELUNA 23 | 24 | #define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ 25 | if (!IsEnabled())\ 26 | return RETVAL;\ 27 | auto key = EntryKey(EVENT, ENTRY);\ 28 | if (!ItemEventBindings->HasBindingsFor(key))\ 29 | return RETVAL;\ 30 | LOCK_ELUNA 31 | 32 | void Eluna::OnDummyEffect(WorldObject* pCaster, uint32 spellId, SpellEffIndex effIndex, Item* pTarget) 33 | { 34 | START_HOOK(ITEM_EVENT_ON_DUMMY_EFFECT, pTarget->GetEntry()); 35 | Push(pCaster); 36 | Push(spellId); 37 | Push(effIndex); 38 | Push(pTarget); 39 | CallAllFunctions(ItemEventBindings, key); 40 | } 41 | 42 | bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest) 43 | { 44 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_QUEST_ACCEPT, pItem->GetEntry(), false); 45 | Push(pPlayer); 46 | Push(pItem); 47 | Push(pQuest); 48 | return CallAllFunctionsBool(ItemEventBindings, key); 49 | } 50 | 51 | bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) 52 | { 53 | ObjectGuid guid = pItem->GET_GUID(); 54 | bool castSpell = true; 55 | 56 | if (!OnItemUse(pPlayer, pItem, targets)) 57 | castSpell = false; 58 | 59 | pItem = pPlayer->GetItemByGuid(guid); 60 | if (pItem) 61 | { 62 | if (!OnItemGossip(pPlayer, pItem, targets)) 63 | castSpell = false; 64 | pItem = pPlayer->GetItemByGuid(guid); 65 | } 66 | 67 | if (pItem && castSpell) 68 | return true; 69 | 70 | // Send equip error that shows no message 71 | // This is a hack fix to stop spell casting visual bug when a spell is not cast on use 72 | WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, 18); 73 | data << uint8(59); // EQUIP_ERR_NONE / EQUIP_ERR_CANT_BE_DISENCHANTED 74 | data << guid; 75 | data << ObjectGuid(uint64(0)); 76 | data << uint8(0); 77 | pPlayer->GetSession()->SendPacket(&data); 78 | return false; 79 | } 80 | 81 | bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets) 82 | { 83 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_USE, pItem->GetEntry(), true); 84 | Push(pPlayer); 85 | Push(pItem); 86 | 87 | if (GameObject* target = targets.GetGOTarget()) 88 | Push(target); 89 | else if (Item* target = targets.GetItemTarget()) 90 | Push(target); 91 | else if (Corpse* target = targets.GetCorpseTarget()) 92 | Push(target); 93 | else if (Unit* target = targets.GetUnitTarget()) 94 | Push(target); 95 | else if (WorldObject* target = targets.GetObjectTarget()) 96 | Push(target); 97 | else 98 | Push(); 99 | 100 | return CallAllFunctionsBool(ItemEventBindings, key, true); 101 | } 102 | 103 | bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) 104 | { 105 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_EXPIRE, pProto->ItemId, false); 106 | Push(pPlayer); 107 | Push(pProto->ItemId); 108 | return CallAllFunctionsBool(ItemEventBindings, key); 109 | } 110 | 111 | bool Eluna::OnRemove(Player* pPlayer, Item* pItem) 112 | { 113 | START_HOOK_WITH_RETVAL(ITEM_EVENT_ON_REMOVE, pItem->GetEntry(), false); 114 | Push(pPlayer); 115 | Push(pItem); 116 | return CallAllFunctionsBool(ItemEventBindings, key); 117 | } 118 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/PacketHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK_SERVER(EVENT) \ 17 | if (!IsEnabled())\ 18 | return;\ 19 | auto key = EventKey(EVENT);\ 20 | if (!ServerEventBindings->HasBindingsFor(key))\ 21 | return;\ 22 | LOCK_ELUNA 23 | 24 | #define START_HOOK_PACKET(EVENT, OPCODE) \ 25 | if (!IsEnabled())\ 26 | return;\ 27 | auto key = EntryKey(EVENT, OPCODE);\ 28 | if (!PacketEventBindings->HasBindingsFor(key))\ 29 | return;\ 30 | LOCK_ELUNA 31 | 32 | bool Eluna::OnPacketSend(WorldSession* session, const WorldPacket& packet) 33 | { 34 | bool result = true; 35 | Player* player = NULL; 36 | if (session) 37 | player = session->GetPlayer(); 38 | OnPacketSendAny(player, packet, result); 39 | OnPacketSendOne(player, packet, result); 40 | return result; 41 | } 42 | void Eluna::OnPacketSendAny(Player* player, const WorldPacket& packet, bool& result) 43 | { 44 | START_HOOK_SERVER(SERVER_EVENT_ON_PACKET_SEND); 45 | Push(new WorldPacket(packet)); 46 | Push(player); 47 | int n = SetupStack(ServerEventBindings, key, 2); 48 | 49 | while (n > 0) 50 | { 51 | int r = CallOneFunction(n--, 2, 1); 52 | 53 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 54 | result = false; 55 | 56 | lua_pop(L, 1); 57 | } 58 | 59 | CleanUpStack(2); 60 | } 61 | 62 | void Eluna::OnPacketSendOne(Player* player, const WorldPacket& packet, bool& result) 63 | { 64 | START_HOOK_PACKET(PACKET_EVENT_ON_PACKET_SEND, packet.GetOpcode()); 65 | Push(new WorldPacket(packet)); 66 | Push(player); 67 | int n = SetupStack(PacketEventBindings, key, 2); 68 | 69 | while (n > 0) 70 | { 71 | int r = CallOneFunction(n--, 2, 1); 72 | 73 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 74 | result = false; 75 | 76 | lua_pop(L, 1); 77 | } 78 | 79 | CleanUpStack(2); 80 | } 81 | 82 | bool Eluna::OnPacketReceive(WorldSession* session, WorldPacket& packet) 83 | { 84 | bool result = true; 85 | Player* player = NULL; 86 | if (session) 87 | player = session->GetPlayer(); 88 | OnPacketReceiveAny(player, packet, result); 89 | OnPacketReceiveOne(player, packet, result); 90 | return result; 91 | } 92 | 93 | void Eluna::OnPacketReceiveAny(Player* player, WorldPacket& packet, bool& result) 94 | { 95 | START_HOOK_SERVER(SERVER_EVENT_ON_PACKET_RECEIVE); 96 | Push(new WorldPacket(packet)); 97 | Push(player); 98 | int n = SetupStack(ServerEventBindings, key, 2); 99 | 100 | while (n > 0) 101 | { 102 | int r = CallOneFunction(n--, 2, 2); 103 | 104 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 105 | result = false; 106 | 107 | if (lua_isuserdata(L, r + 1)) 108 | if (WorldPacket* data = CHECKOBJ(L, r + 1, false)) 109 | packet = *data; 110 | 111 | lua_pop(L, 2); 112 | } 113 | 114 | CleanUpStack(2); 115 | } 116 | 117 | void Eluna::OnPacketReceiveOne(Player* player, WorldPacket& packet, bool& result) 118 | { 119 | START_HOOK_PACKET(PACKET_EVENT_ON_PACKET_RECEIVE, packet.GetOpcode()); 120 | Push(new WorldPacket(packet)); 121 | Push(player); 122 | int n = SetupStack(PacketEventBindings, key, 2); 123 | 124 | while (n > 0) 125 | { 126 | int r = CallOneFunction(n--, 2, 2); 127 | 128 | if (lua_isboolean(L, r + 0) && !lua_toboolean(L, r + 0)) 129 | result = false; 130 | 131 | if (lua_isuserdata(L, r + 1)) 132 | if (WorldPacket* data = CHECKOBJ(L, r + 1, false)) 133 | packet = *data; 134 | 135 | lua_pop(L, 2); 136 | } 137 | 138 | CleanUpStack(2); 139 | } 140 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/SpellHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK(EVENT, ENTRY) \ 17 | if (!IsEnabled())\ 18 | return;\ 19 | auto key = EntryKey(EVENT, ENTRY);\ 20 | if (!SpellEventBindings->HasBindingsFor(key))\ 21 | return;\ 22 | LOCK_ELUNA 23 | 24 | #define START_HOOK_WITH_RETVAL(EVENT, ENTRY, RETVAL) \ 25 | if (!IsEnabled())\ 26 | return RETVAL;\ 27 | auto key = EntryKey(EVENT, ENTRY);\ 28 | if (!SpellEventBindings->HasBindingsFor(key))\ 29 | return RETVAL;\ 30 | LOCK_ELUNA 31 | 32 | void Eluna::OnSpellCastCancel(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool bySelf) 33 | { 34 | START_HOOK(SPELL_EVENT_ON_CAST_CANCEL, spellInfo->Id); 35 | Push(caster); 36 | Push(spell); 37 | Push(bySelf); 38 | 39 | CallAllFunctions(SpellEventBindings, key); 40 | } 41 | 42 | void Eluna::OnSpellCast(Unit* caster, Spell* spell, SpellInfo const* spellInfo, bool skipCheck) 43 | { 44 | START_HOOK(SPELL_EVENT_ON_CAST, spellInfo->Id); 45 | Push(caster); 46 | Push(spell); 47 | Push(skipCheck); 48 | 49 | CallAllFunctions(SpellEventBindings, key); 50 | } 51 | 52 | void Eluna::OnSpellPrepare(Unit* caster, Spell* spell, SpellInfo const* spellInfo) 53 | { 54 | START_HOOK(SPELL_EVENT_ON_PREPARE, spellInfo->Id); 55 | Push(caster); 56 | Push(spell); 57 | 58 | CallAllFunctions(SpellEventBindings, key); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/TicketHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaIncludes.h" 12 | #include "ElunaTemplate.h" 13 | 14 | using namespace Hooks; 15 | 16 | #define START_HOOK(EVENT) \ 17 | if (!IsEnabled())\ 18 | return;\ 19 | auto key = EventKey(EVENT);\ 20 | if (!TicketEventBindings->HasBindingsFor(key))\ 21 | return;\ 22 | LOCK_ELUNA 23 | 24 | #define START_HOOK(EVENT) \ 25 | if (!IsEnabled())\ 26 | return;\ 27 | auto key = EventKey(EVENT);\ 28 | if (!TicketEventBindings->HasBindingsFor(key))\ 29 | return;\ 30 | LOCK_ELUNA 31 | 32 | void Eluna::OnTicketCreate(GmTicket* ticket) 33 | { 34 | START_HOOK(TICKET_EVENT_ON_CREATE); 35 | Push(ticket); 36 | CallAllFunctions(TicketEventBindings, key); 37 | } 38 | 39 | void Eluna::OnTicketUpdateLastChange(GmTicket* ticket) 40 | { 41 | START_HOOK(TICKET_EVENT_UPDATE_LAST_CHANGE); 42 | Push(ticket); 43 | CallAllFunctions(TicketEventBindings, key); 44 | } 45 | 46 | void Eluna::OnTicketClose(GmTicket* ticket) 47 | { 48 | START_HOOK(TICKET_EVENT_ON_CLOSE); 49 | Push(ticket); 50 | CallAllFunctions(TicketEventBindings, key); 51 | } 52 | 53 | void Eluna::OnTicketResolve(GmTicket* ticket) 54 | { 55 | START_HOOK(TICKET_EVENT_ON_RESOLVE); 56 | Push(ticket); 57 | CallAllFunctions(TicketEventBindings, key); 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/LuaEngine/hooks/VehicleHooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #include "Hooks.h" 8 | #include "HookHelpers.h" 9 | #include "LuaEngine.h" 10 | #include "BindingMap.h" 11 | #include "ElunaTemplate.h" 12 | 13 | using namespace Hooks; 14 | 15 | #define START_HOOK(EVENT) \ 16 | if (!IsEnabled())\ 17 | return;\ 18 | auto key = EventKey(EVENT);\ 19 | if (!VehicleEventBindings->HasBindingsFor(key))\ 20 | return;\ 21 | LOCK_ELUNA 22 | 23 | void Eluna::OnInstall(Vehicle* vehicle) 24 | { 25 | START_HOOK(VEHICLE_EVENT_ON_INSTALL); 26 | Push(vehicle); 27 | CallAllFunctions(VehicleEventBindings, key); 28 | } 29 | 30 | void Eluna::OnUninstall(Vehicle* vehicle) 31 | { 32 | START_HOOK(VEHICLE_EVENT_ON_UNINSTALL); 33 | Push(vehicle); 34 | CallAllFunctions(VehicleEventBindings, key); 35 | } 36 | 37 | void Eluna::OnInstallAccessory(Vehicle* vehicle, Creature* accessory) 38 | { 39 | START_HOOK(VEHICLE_EVENT_ON_INSTALL_ACCESSORY); 40 | Push(vehicle); 41 | Push(accessory); 42 | CallAllFunctions(VehicleEventBindings, key); 43 | } 44 | 45 | void Eluna::OnAddPassenger(Vehicle* vehicle, Unit* passenger, int8 seatId) 46 | { 47 | START_HOOK(VEHICLE_EVENT_ON_ADD_PASSENGER); 48 | Push(vehicle); 49 | Push(passenger); 50 | Push(seatId); 51 | CallAllFunctions(VehicleEventBindings, key); 52 | } 53 | 54 | void Eluna::OnRemovePassenger(Vehicle* vehicle, Unit* passenger) 55 | { 56 | START_HOOK(VEHICLE_EVENT_ON_REMOVE_PASSENGER); 57 | Push(vehicle); 58 | Push(passenger); 59 | CallAllFunctions(VehicleEventBindings, key); 60 | } 61 | -------------------------------------------------------------------------------- /src/LuaEngine/lmarshal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | extern "C" { 8 | #include "lua.h" 9 | } 10 | 11 | int mar_encode(lua_State* L); 12 | int mar_decode(lua_State* L); 13 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/AchievementMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef ACHIEVEMENTMETHODS_H 8 | #define ACHIEVEMENTMETHODS_H 9 | 10 | namespace LuaAchievement 11 | { 12 | /** 13 | * Returns the [Achievement]'s ID. 14 | * 15 | * @return uint32 id 16 | */ 17 | int GetId(lua_State* L, AchievementEntry* const achievement) 18 | { 19 | Eluna::Push(L, achievement->ID); 20 | return 1; 21 | } 22 | 23 | /** 24 | * Returns the [Achievement]'s name. 25 | * 26 | * enum LocaleConstant 27 | * { 28 | * LOCALE_enUS = 0, 29 | * LOCALE_koKR = 1, 30 | * LOCALE_frFR = 2, 31 | * LOCALE_deDE = 3, 32 | * LOCALE_zhCN = 4, 33 | * LOCALE_zhTW = 5, 34 | * LOCALE_esES = 6, 35 | * LOCALE_esMX = 7, 36 | * LOCALE_ruRU = 8 37 | * }; 38 | * 39 | * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [Achievement] name in 40 | * @return string name 41 | */ 42 | int GetName(lua_State* L, AchievementEntry* const achievement) 43 | { 44 | uint8 locale = Eluna::CHECKVAL(L, 2, DEFAULT_LOCALE); 45 | if (locale >= TOTAL_LOCALES) 46 | { 47 | return luaL_argerror(L, 2, "valid LocaleConstant expected"); 48 | } 49 | 50 | Eluna::Push(L, achievement->name[locale]); 51 | return 1; 52 | } 53 | }; 54 | #endif 55 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/AuraMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef AURAMETHODS_H 8 | #define AURAMETHODS_H 9 | 10 | /*** 11 | * The persistent effect of a [Spell] that remains on a [Unit] after the [Spell] 12 | * has been cast. 13 | * 14 | * As an example, if you cast a damage-over-time spell on a target, an [Aura] is 15 | * put on the target that deals damage continuously. 16 | * 17 | * [Aura]s on your player are displayed in-game as a series of icons to the left 18 | * of the mini-map. 19 | * 20 | * Inherits all methods from: none 21 | */ 22 | namespace LuaAura 23 | { 24 | /** 25 | * Returns the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 26 | * 27 | * @return [Unit] caster 28 | */ 29 | int GetCaster(lua_State* L, Aura* aura) 30 | { 31 | Eluna::Push(L, aura->GetCaster()); 32 | return 1; 33 | } 34 | 35 | /** 36 | * Returns the GUID of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 37 | * 38 | * @return string caster_guid : the GUID of the Unit as a decimal string 39 | */ 40 | int GetCasterGUID(lua_State* L, Aura* aura) 41 | { 42 | Eluna::Push(L, aura->GetCasterGUID()); 43 | return 1; 44 | } 45 | 46 | /** 47 | * Returns the level of the [Unit] that casted the [Spell] that caused this [Aura] to be applied. 48 | * 49 | * @return uint32 caster_level 50 | */ 51 | int GetCasterLevel(lua_State* L, Aura* aura) 52 | { 53 | Eluna::Push(L, aura->GetCaster()->GetLevel()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Returns the amount of time left until the [Aura] expires. 59 | * 60 | * @return int32 duration : amount of time left in milliseconds 61 | */ 62 | int GetDuration(lua_State* L, Aura* aura) 63 | { 64 | Eluna::Push(L, aura->GetDuration()); 65 | return 1; 66 | } 67 | 68 | /** 69 | * Returns the ID of the [Spell] that caused this [Aura] to be applied. 70 | * 71 | * @return uint32 aura_id 72 | */ 73 | int GetAuraId(lua_State* L, Aura* aura) 74 | { 75 | Eluna::Push(L, aura->GetId()); 76 | return 1; 77 | } 78 | 79 | /** 80 | * Returns the amount of time this [Aura] lasts when applied. 81 | * 82 | * To determine how much time has passed since this Aura was applied, 83 | * subtract the result of [Aura]:GetDuration from the result of this method. 84 | * 85 | * @return int32 max_duration : the maximum duration of the Aura, in milliseconds 86 | */ 87 | int GetMaxDuration(lua_State* L, Aura* aura) 88 | { 89 | Eluna::Push(L, aura->GetMaxDuration()); 90 | return 1; 91 | } 92 | 93 | /** 94 | * Returns the number of times the [Aura] has "stacked". 95 | * 96 | * This is the same as the number displayed on the [Aura]'s icon in-game. 97 | * 98 | * @return uint32 stack_amount 99 | */ 100 | int GetStackAmount(lua_State* L, Aura* aura) 101 | { 102 | Eluna::Push(L, aura->GetStackAmount()); 103 | return 1; 104 | } 105 | 106 | /** 107 | * Returns the [Unit] that the [Aura] has been applied to. 108 | * 109 | * @return [Unit] owner 110 | */ 111 | int GetOwner(lua_State* L, Aura* aura) 112 | { 113 | Eluna::Push(L, aura->GetOwner()); 114 | return 1; 115 | } 116 | 117 | /** 118 | * Change the amount of time before the [Aura] expires. 119 | * 120 | * @param int32 duration : the new duration of the Aura, in milliseconds 121 | */ 122 | int SetDuration(lua_State* L, Aura* aura) 123 | { 124 | int32 duration = Eluna::CHECKVAL(L, 2); 125 | aura->SetDuration(duration); 126 | return 0; 127 | } 128 | 129 | /** 130 | * Change the maximum amount of time before the [Aura] expires. 131 | * 132 | * This does not affect the current duration of the [Aura], but if the [Aura] 133 | * is reset to the maximum duration, it will instead change to `duration`. 134 | * 135 | * @param int32 duration : the new maximum duration of the Aura, in milliseconds 136 | */ 137 | int SetMaxDuration(lua_State* L, Aura* aura) 138 | { 139 | int32 duration = Eluna::CHECKVAL(L, 2); 140 | aura->SetMaxDuration(duration); 141 | return 0; 142 | } 143 | 144 | /** 145 | * Change the amount of times the [Aura] has "stacked" on the [Unit]. 146 | * 147 | * If `amount` is greater than or equal to the current number of stacks, 148 | * then the [Aura] has its duration reset to the maximum duration. 149 | * 150 | * @param uint32 amount 151 | */ 152 | int SetStackAmount(lua_State* L, Aura* aura) 153 | { 154 | uint8 amount = Eluna::CHECKVAL(L, 2); 155 | aura->SetStackAmount(amount); 156 | return 0; 157 | } 158 | 159 | /** 160 | * Remove this [Aura] from the [Unit] it is applied to. 161 | */ 162 | int Remove(lua_State* L, Aura* aura) 163 | { 164 | aura->Remove(); 165 | Eluna::CHECKOBJ(L, 1)->Invalidate(); 166 | return 0; 167 | } 168 | }; 169 | #endif 170 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/BattleGroundMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef BATTLEGROUNDMETHODS_H 8 | #define BATTLEGROUNDMETHODS_H 9 | 10 | /*** 11 | * Contains the state of a battleground, e.g. Warsong Gulch, Arathi Basin, etc. 12 | * 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaBattleGround 16 | { 17 | /** 18 | * Returns the name of the [BattleGround]. 19 | * 20 | * @return string name 21 | */ 22 | int GetName(lua_State* L, BattleGround* bg) 23 | { 24 | Eluna::Push(L, bg->GetName()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the amount of alive players in the [BattleGround] by the team ID. 30 | * 31 | * @param [Team] team : team ID 32 | * @return uint32 count 33 | */ 34 | int GetAlivePlayersCountByTeam(lua_State* L, BattleGround* bg) 35 | { 36 | uint32 team = Eluna::CHECKVAL(L, 2); 37 | 38 | Eluna::Push(L, bg->GetAlivePlayersCountByTeam((TeamId)team)); 39 | return 1; 40 | } 41 | 42 | /** 43 | * Returns the [Map] of the [BattleGround]. 44 | * 45 | * @return [Map] map 46 | */ 47 | int GetMap(lua_State* L, BattleGround* bg) 48 | { 49 | Eluna::Push(L, bg->GetBgMap()); 50 | return 1; 51 | } 52 | 53 | /** 54 | * Returns the bonus honor given by amount of kills in the specific [BattleGround]. 55 | * 56 | * @param uint32 kills : amount of kills 57 | * @return uint32 bonusHonor 58 | */ 59 | int GetBonusHonorFromKillCount(lua_State* L, BattleGround* bg) 60 | { 61 | uint32 kills = Eluna::CHECKVAL(L, 2); 62 | 63 | Eluna::Push(L, bg->GetBonusHonorFromKill(kills)); 64 | return 1; 65 | } 66 | 67 | /** 68 | * Returns the end time of the [BattleGround]. 69 | * 70 | * @return uint32 endTime 71 | */ 72 | int GetEndTime(lua_State* L, BattleGround* bg) 73 | { 74 | Eluna::Push(L, bg->GetEndTime()); 75 | return 1; 76 | } 77 | 78 | /** 79 | * Returns the amount of free slots for the selected team in the specific [BattleGround]. 80 | * 81 | * @param [Team] team : team ID 82 | * @return uint32 freeSlots 83 | */ 84 | int GetFreeSlotsForTeam(lua_State* L, BattleGround* bg) 85 | { 86 | uint32 team = Eluna::CHECKVAL(L, 2); 87 | 88 | Eluna::Push(L, bg->GetFreeSlotsForTeam((TeamId)team)); 89 | return 1; 90 | } 91 | 92 | /** 93 | * Returns the instance ID of the [BattleGround]. 94 | * 95 | * @return uint32 instanceId 96 | */ 97 | int GetInstanceId(lua_State* L, BattleGround* bg) 98 | { 99 | Eluna::Push(L, bg->GetInstanceID()); 100 | return 1; 101 | } 102 | 103 | /** 104 | * Returns the map ID of the [BattleGround]. 105 | * 106 | * @return uint32 mapId 107 | */ 108 | int GetMapId(lua_State* L, BattleGround* bg) 109 | { 110 | Eluna::Push(L, bg->GetMapId()); 111 | return 1; 112 | } 113 | 114 | /** 115 | * Returns the type ID of the [BattleGround]. 116 | * 117 | * @return [BattleGroundTypeId] typeId 118 | */ 119 | int GetTypeId(lua_State* L, BattleGround* bg) 120 | { 121 | Eluna::Push(L, bg->GetBgTypeID()); 122 | return 1; 123 | } 124 | 125 | /** 126 | * Returns the max allowed [Player] level of the specific [BattleGround]. 127 | * 128 | * @return uint32 maxLevel 129 | */ 130 | int GetMaxLevel(lua_State* L, BattleGround* bg) 131 | { 132 | Eluna::Push(L, bg->GetMaxLevel()); 133 | return 1; 134 | } 135 | 136 | /** 137 | * Returns the minimum allowed [Player] level of the specific [BattleGround]. 138 | * 139 | * @return uint32 minLevel 140 | */ 141 | int GetMinLevel(lua_State* L, BattleGround* bg) 142 | { 143 | Eluna::Push(L, bg->GetMinLevel()); 144 | return 1; 145 | } 146 | 147 | /** 148 | * Returns the maximum allowed [Player] count of the specific [BattleGround]. 149 | * 150 | * @return uint32 maxPlayerCount 151 | */ 152 | int GetMaxPlayers(lua_State* L, BattleGround* bg) 153 | { 154 | Eluna::Push(L, bg->GetMaxPlayersPerTeam() * 2); 155 | return 1; 156 | } 157 | 158 | /** 159 | * Returns the minimum allowed [Player] count of the specific [BattleGround]. 160 | * 161 | * @return uint32 minPlayerCount 162 | */ 163 | int GetMinPlayers(lua_State* L, BattleGround* bg) 164 | { 165 | Eluna::Push(L, bg->GetMaxPlayersPerTeam() * 2); 166 | return 1; 167 | } 168 | 169 | /** 170 | * Returns the maximum allowed [Player] count per team of the specific [BattleGround]. 171 | * 172 | * @return uint32 maxTeamPlayerCount 173 | */ 174 | int GetMaxPlayersPerTeam(lua_State* L, BattleGround* bg) 175 | { 176 | Eluna::Push(L, bg->GetMaxPlayersPerTeam()); 177 | return 1; 178 | } 179 | 180 | /** 181 | * Returns the minimum allowed [Player] count per team of the specific [BattleGround]. 182 | * 183 | * @return uint32 minTeamPlayerCount 184 | */ 185 | int GetMinPlayersPerTeam(lua_State* L, BattleGround* bg) 186 | { 187 | Eluna::Push(L, bg->GetMinPlayersPerTeam()); 188 | return 1; 189 | } 190 | 191 | /** 192 | * Returns the winning team of the specific [BattleGround]. 193 | * 194 | * @return [Team] team 195 | */ 196 | int GetWinner(lua_State* L, BattleGround* bg) 197 | { 198 | Eluna::Push(L, bg->GetWinner()); 199 | return 1; 200 | } 201 | 202 | /** 203 | * Returns the status of the specific [BattleGround]. 204 | * 205 | * @return [BattleGroundStatus] status 206 | */ 207 | int GetStatus(lua_State* L, BattleGround* bg) 208 | { 209 | Eluna::Push(L, bg->GetStatus()); 210 | return 1; 211 | } 212 | }; 213 | #endif 214 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/ChatHandlerMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CHATHANDLERMETHODS_H 8 | #define CHATHANDLERMETHODS_H 9 | 10 | #include "Chat.h" 11 | 12 | namespace LuaChatHandler 13 | { 14 | /** 15 | * Sends text to the chat handler 16 | * 17 | * @proto (text) 18 | * @proto (entry) 19 | * @param string text : text to display in chat or console 20 | * @param uint32 entry : id of the string to display 21 | */ 22 | int SendSysMessage(lua_State* L, ChatHandler* handler) 23 | { 24 | if (lua_isnumber(L, 2)) 25 | { 26 | uint32 entry = Eluna::CHECKVAL(L, 2); 27 | handler->SendSysMessage(entry); 28 | } 29 | else 30 | { 31 | std::string text = Eluna::CHECKVAL(L, 2); 32 | handler->SendSysMessage(text); 33 | } 34 | return 0; 35 | } 36 | 37 | /** 38 | * Returns `true` if the [ChatHandler] comes from the console, `false` if it comes from a player 39 | * 40 | * @return bool isConsole 41 | */ 42 | int IsConsole(lua_State* L, ChatHandler* handler) 43 | { 44 | Eluna::Push(L, handler->IsConsole()); 45 | return 1; 46 | } 47 | 48 | /** 49 | * Returns the [Player] associated with the handler. Returns `nil` in the case of a console handler 50 | * 51 | * @return [Player] player 52 | */ 53 | int GetPlayer(lua_State* L, ChatHandler* handler) 54 | { 55 | Eluna::Push(L, handler->GetPlayer()); 56 | return 1; 57 | } 58 | 59 | /** 60 | * Sends a message to all connected players 61 | * 62 | * @param string text : text to send 63 | */ 64 | int SendGlobalSysMessage(lua_State* L, ChatHandler* handler) 65 | { 66 | std::string text = Eluna::CHECKVAL(L, 2); 67 | handler->SendGlobalSysMessage(text.c_str()); 68 | return 0; 69 | } 70 | 71 | /** 72 | * Sends a message to all connected Game Masters 73 | * 74 | * @param string text : text to send 75 | */ 76 | int SendGlobalGMSysMessage(lua_State* L, ChatHandler* handler) 77 | { 78 | std::string text = Eluna::CHECKVAL(L, 2); 79 | handler->SendGlobalGMSysMessage(text.c_str()); 80 | return 0; 81 | } 82 | 83 | /** 84 | * Checks if the current security level is lower than the specified [Player]'s account 85 | * 86 | * @param [Player] player 87 | * @param [bool] strong = false : Forces non-player accounts (security level greater than `0`) to go through the regular check if set to `true`.
Also, if set to `true`, the current security level will be considered as lower than the [Player]'s security level if the two levels are equal 88 | * @return [bool] lower 89 | */ 90 | int HasLowerSecurity(lua_State* L, ChatHandler* handler) 91 | { 92 | Player* player = Eluna::CHECKOBJ(L, 2); 93 | bool strong = Eluna::CHECKVAL(L, 3); 94 | Eluna::Push(L, handler->HasLowerSecurity(player, ObjectGuid::Empty, strong)); 95 | return 1; 96 | } 97 | 98 | /** 99 | * Checks if the current security level is lower than the specified `account`'s level 100 | * 101 | * @param [uint32] account : the target account ID to compare security levels with 102 | * @param [bool] strong = false : Forces non-player accounts (security level greater than `0`) to go through the regular check if set to `true`.
Also, if set to `true`, the current security level will be considered as lower than the `account`'s security level if the two levels are equal 103 | * @return [bool] lower 104 | */ 105 | int HasLowerSecurityAccount(lua_State* L, ChatHandler* handler) 106 | { 107 | uint32 account = Eluna::CHECKVAL(L, 2); 108 | bool strong = Eluna::CHECKVAL(L, 3); 109 | Eluna::Push(L, handler->HasLowerSecurityAccount(nullptr, account, strong)); 110 | return 1; 111 | } 112 | 113 | /** 114 | * Returns the selected [Player] 115 | * 116 | * @return [Player] player 117 | */ 118 | int GetSelectedPlayer(lua_State* L, ChatHandler* handler) 119 | { 120 | Eluna::Push(L, handler->getSelectedPlayer()); 121 | return 1; 122 | } 123 | 124 | /** 125 | * Returns the selected [Creature] 126 | * 127 | * @return [Creature] creature 128 | */ 129 | int GetSelectedCreature(lua_State* L, ChatHandler* handler) 130 | { 131 | Eluna::Push(L, handler->getSelectedCreature()); 132 | return 1; 133 | } 134 | 135 | /** 136 | * Returns the selected [Unit] 137 | * 138 | * @return [Unit] unit 139 | */ 140 | int GetSelectedUnit(lua_State* L, ChatHandler* handler) 141 | { 142 | Eluna::Push(L, handler->getSelectedUnit()); 143 | return 1; 144 | } 145 | 146 | /** 147 | * Returns the selected [WorldObject] 148 | * 149 | * @return [WorldObject] object 150 | */ 151 | int GetSelectedObject(lua_State* L, ChatHandler* handler) 152 | { 153 | Eluna::Push(L, handler->getSelectedObject()); 154 | return 1; 155 | } 156 | 157 | /** 158 | * Returns the selected [Player] or the current [Player] if nothing is targeted or the target is not a player 159 | * 160 | * @return [Player] player 161 | */ 162 | int GetSelectedPlayerOrSelf(lua_State* L, ChatHandler* handler) 163 | { 164 | Eluna::Push(L, handler->getSelectedPlayerOrSelf()); 165 | return 1; 166 | } 167 | 168 | /** 169 | * Checks if the `securityLevel` is available 170 | * 171 | * @param [uint32] securityLevel 172 | * @return [bool] isAvailable 173 | */ 174 | int IsAvailable(lua_State* L, ChatHandler* handler) 175 | { 176 | uint32 securityLevel = Eluna::CHECKVAL(L, 2); 177 | Eluna::Push(L, handler->IsAvailable(securityLevel)); 178 | return 1; 179 | } 180 | 181 | /** 182 | * Returns `true` if other previously called [ChatHandler] methods sent an error 183 | * 184 | * @return [bool] sentErrorMessage 185 | */ 186 | int HasSentErrorMessage(lua_State* L, ChatHandler* handler) 187 | { 188 | Eluna::Push(L, handler->HasSentErrorMessage()); 189 | return 1; 190 | } 191 | } 192 | #endif 193 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/CorpseMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef CORPSEMETHODS_H 8 | #define CORPSEMETHODS_H 9 | 10 | /*** 11 | * The remains of a [Player] that has died. 12 | * 13 | * Inherits all methods from: [Object], [WorldObject] 14 | */ 15 | namespace LuaCorpse 16 | { 17 | /** 18 | * Returns the GUID of the [Player] that left the [Corpse] behind. 19 | * 20 | * @return ObjectGuid ownerGUID 21 | */ 22 | int GetOwnerGUID(lua_State* L, Corpse* corpse) 23 | { 24 | Eluna::Push(L, corpse->GetOwnerGUID()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the time when the [Player] became a ghost and spawned this [Corpse]. 30 | * 31 | * @return uint32 ghostTime 32 | */ 33 | int GetGhostTime(lua_State* L, Corpse* corpse) 34 | { 35 | Eluna::Push(L, corpse->GetGhostTime()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the [CorpseType] of a [Corpse]. 41 | * 42 | * enum CorpseType 43 | * { 44 | * CORPSE_BONES = 0, 45 | * CORPSE_RESURRECTABLE_PVE = 1, 46 | * CORPSE_RESURRECTABLE_PVP = 2 47 | * }; 48 | * 49 | * @return [CorpseType] corpseType 50 | */ 51 | int GetType(lua_State* L, Corpse* corpse) 52 | { 53 | Eluna::Push(L, corpse->GetType()); 54 | return 1; 55 | } 56 | 57 | /** 58 | * Sets the "ghost time" to the current time. 59 | * 60 | * See [Corpse:GetGhostTime]. 61 | */ 62 | int ResetGhostTime(lua_State* /*L*/, Corpse* corpse) 63 | { 64 | corpse->ResetGhostTime(); 65 | return 0; 66 | } 67 | 68 | /** 69 | * Saves the [Corpse] to the database. 70 | */ 71 | int SaveToDB(lua_State* /*L*/, Corpse* corpse) 72 | { 73 | corpse->SaveToDB(); 74 | return 0; 75 | } 76 | }; 77 | #endif 78 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/GemPropertiesEntryMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef GEMPROPERTIESENTRYMETHODS_H 8 | #define GEMPROPERTIESENTRYMETHODS_H 9 | 10 | namespace LuaGemPropertiesEntry 11 | { 12 | 13 | /** 14 | * Returns the ID of a [GemPropertiesEntry]. 15 | * 16 | * This method retrieves the ID from a given GemPropertiesEntry instance 17 | * and pushes it onto the Lua stack. 18 | * 19 | * @return uint32 id : The ID of the specified GemPropertiesEntry. 20 | */ 21 | int GetId(lua_State* L, GemPropertiesEntry* gemProperties) 22 | { 23 | Eluna::Push(L, gemProperties->ID); 24 | return 1; 25 | } 26 | 27 | /** 28 | * Returns the spell item enchantment of a [GemPropertiesEntry]. 29 | * 30 | * This function retrieves the `spellitemenchantement` attribute from the provided `GemPropertiesEntry`. 31 | * 32 | * @return uint32 spellitemenchantement : The spell item enchantment ID. 33 | */ 34 | int GetSpellItemEnchantement(lua_State* L, GemPropertiesEntry* entry) 35 | { 36 | Eluna::Push(L, entry->spellitemenchantement); 37 | return 1; 38 | } 39 | } 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/ItemTemplateMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef ITEMTEMPLATEMETHODS_H 8 | #define ITEMTEMPLATEMETHODS_H 9 | 10 | #include "Chat.h" 11 | 12 | namespace LuaItemTemplate 13 | { 14 | /** 15 | * Returns the [ItemTemplate]'s ID. 16 | * 17 | * @return uint32 itemId 18 | */ 19 | int GetItemId(lua_State* L, ItemTemplate* itemTemplate) 20 | { 21 | Eluna::Push(L, itemTemplate->ItemId); 22 | return 1; 23 | } 24 | 25 | /** 26 | * Returns the [ItemTemplate]'s class. 27 | * 28 | * @return uint32 class 29 | */ 30 | int GetClass(lua_State* L, ItemTemplate* itemTemplate) 31 | { 32 | Eluna::Push(L, itemTemplate->Class); 33 | return 1; 34 | } 35 | 36 | /** 37 | * Returns the [ItemTemplate]'s subclass. 38 | * 39 | * @return uint32 subClass 40 | */ 41 | int GetSubClass(lua_State* L, ItemTemplate* itemTemplate) 42 | { 43 | Eluna::Push(L, itemTemplate->SubClass); 44 | return 1; 45 | } 46 | 47 | /** 48 | * Returns the [ItemTemplate]'s name in the [Player]'s locale. 49 | * 50 | * @param [LocaleConstant] locale = DEFAULT_LOCALE : locale to return the [ItemTemplate] name in (it's optional default: LOCALE_enUS) 51 | * 52 | * @return string name 53 | */ 54 | int GetName(lua_State* L, ItemTemplate* itemTemplate) 55 | { 56 | uint32 loc_idx = Eluna::CHECKVAL(L, 2, LocaleConstant::LOCALE_enUS); 57 | 58 | const ItemLocale* itemLocale = eObjectMgr->GetItemLocale(itemTemplate->ItemId); 59 | std::string name = itemTemplate->Name1; 60 | 61 | if (itemLocale && !itemLocale->Name[loc_idx].empty()) 62 | name = itemLocale->Name[loc_idx]; 63 | 64 | Eluna::Push(L, name); 65 | return 1; 66 | } 67 | 68 | /** 69 | * Returns the [ItemTemplate]'s display ID. 70 | * 71 | * @return uint32 displayId 72 | */ 73 | int GetDisplayId(lua_State* L, ItemTemplate* itemTemplate) 74 | { 75 | Eluna::Push(L, itemTemplate->DisplayInfoID); 76 | return 1; 77 | } 78 | 79 | /** 80 | * Returns the [ItemTemplate]'s quality. 81 | * 82 | * @return uint32 quality 83 | */ 84 | int GetQuality(lua_State* L, ItemTemplate* itemTemplate) 85 | { 86 | Eluna::Push(L, itemTemplate->Quality); 87 | return 1; 88 | } 89 | 90 | /** 91 | * Returns the [ItemTemplate]'s flags. 92 | * 93 | * @return uint32 flags 94 | */ 95 | int GetFlags(lua_State* L, ItemTemplate* itemTemplate) 96 | { 97 | Eluna::Push(L, itemTemplate->Flags); 98 | return 1; 99 | } 100 | 101 | /** 102 | * Returns the [ItemTemplate]'s extra flags. 103 | * 104 | * @return uint32 flags 105 | */ 106 | int GetExtraFlags(lua_State* L, ItemTemplate* itemTemplate) 107 | { 108 | Eluna::Push(L, itemTemplate->Flags2); 109 | return 1; 110 | } 111 | 112 | /** 113 | * Returns the [ItemTemplate]'s default purchase count. 114 | * 115 | * @return uint32 buyCount 116 | */ 117 | int GetBuyCount(lua_State* L, ItemTemplate* itemTemplate) 118 | { 119 | Eluna::Push(L, itemTemplate->BuyCount); 120 | return 1; 121 | } 122 | 123 | /** 124 | * Returns the [ItemTemplate]'s purchase price. 125 | * 126 | * @return int32 buyPrice 127 | */ 128 | int GetBuyPrice(lua_State* L, ItemTemplate* itemTemplate) 129 | { 130 | Eluna::Push(L, itemTemplate->BuyPrice); 131 | return 1; 132 | } 133 | 134 | /** 135 | * Returns the [ItemTemplate]'s sell price. 136 | * 137 | * @return uint32 sellPrice 138 | */ 139 | int GetSellPrice(lua_State* L, ItemTemplate* itemTemplate) 140 | { 141 | Eluna::Push(L, itemTemplate->SellPrice); 142 | return 1; 143 | } 144 | 145 | /** 146 | * Returns the [ItemTemplate]'s inventory type. 147 | * 148 | * @return uint32 inventoryType 149 | */ 150 | int GetInventoryType(lua_State* L, ItemTemplate* itemTemplate) 151 | { 152 | Eluna::Push(L, itemTemplate->InventoryType); 153 | return 1; 154 | } 155 | 156 | /** 157 | * Returns the [Player] classes allowed to use this [ItemTemplate]. 158 | * 159 | * @return uint32 allowableClass 160 | */ 161 | int GetAllowableClass(lua_State* L, ItemTemplate* itemTemplate) 162 | { 163 | Eluna::Push(L, itemTemplate->AllowableClass); 164 | return 1; 165 | } 166 | 167 | /** 168 | * Returns the [Player] races allowed to use this [ItemTemplate]. 169 | * 170 | * @return uint32 allowableRace 171 | */ 172 | int GetAllowableRace(lua_State* L, ItemTemplate* itemTemplate) 173 | { 174 | Eluna::Push(L, itemTemplate->AllowableRace); 175 | return 1; 176 | } 177 | 178 | /** 179 | * Returns the [ItemTemplate]'s item level. 180 | * 181 | * @return uint32 itemLevel 182 | */ 183 | int GetItemLevel(lua_State* L, ItemTemplate* itemTemplate) 184 | { 185 | Eluna::Push(L, itemTemplate->ItemLevel); 186 | return 1; 187 | } 188 | 189 | /** 190 | * Returns the minimum level required to use this [ItemTemplate]. 191 | * 192 | * @return uint32 requiredLevel 193 | */ 194 | int GetRequiredLevel(lua_State* L, ItemTemplate* itemTemplate) 195 | { 196 | Eluna::Push(L, itemTemplate->RequiredLevel); 197 | return 1; 198 | } 199 | 200 | /** 201 | * Returns the icon is used by this [ItemTemplate]. 202 | * 203 | * @return string itemIcon 204 | */ 205 | int GetIcon(lua_State* L, ItemTemplate* itemTemplate) 206 | { 207 | uint32 display_id = itemTemplate->DisplayInfoID; 208 | 209 | ItemDisplayInfoEntry const* displayInfo = sItemDisplayInfoStore.LookupEntry(display_id); 210 | const char* icon = displayInfo->inventoryIcon; 211 | 212 | Eluna::Push(L, icon); 213 | return 1; 214 | } 215 | } 216 | 217 | #endif 218 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/QuestMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef QUESTMETHODS_H 8 | #define QUESTMETHODS_H 9 | 10 | /*** 11 | * Inherits all methods from: none 12 | */ 13 | namespace LuaQuest 14 | { 15 | /** 16 | * Returns 'true' if the [Quest] has the specified flag, false otherwise. 17 | * Below flags are based off of 3.3.5a. Subject to change. 18 | * 19 | *
 20 |      * enum QuestFlags
 21 |      * {
 22 |      *     // Flags used at server and sent to client
 23 |      *     QUEST_FLAGS_NONE                    = 0x0,
 24 |      *     QUEST_FLAGS_STAY_ALIVE              = 0x1,       // Not used currently
 25 |      *     QUEST_FLAGS_PARTY_ACCEPT            = 0x2,       // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
 26 |      *     QUEST_FLAGS_EXPLORATION             = 0x4,       // Not used currently
 27 |      *     QUEST_FLAGS_SHARABLE                = 0x8,       // Can be shared: Player::CanShareQuest()
 28 |      *     QUEST_FLAGS_HAS_CONDITION           = 0x10,      // Not used currently
 29 |      *     QUEST_FLAGS_HIDE_REWARD_POI         = 0x20,      // Not used currently: Unsure of content
 30 |      *     QUEST_FLAGS_RAID                    = 0x40,      // Not used currently
 31 |      *     QUEST_FLAGS_TBC                     = 0x80,      // Not used currently: Available if TBC expansion enabled only
 32 |      *     QUEST_FLAGS_NO_MONEY_FROM_XP        = 0x100,     // Not used currently: Experience is not converted to gold at max level
 33 |      *     QUEST_FLAGS_HIDDEN_REWARDS          = 0x200,     // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
 34 |      *     QUEST_FLAGS_TRACKING                = 0x400,     // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
 35 |      *     QUEST_FLAGS_DEPRECATE_REPUTATION    = 0x800,     // Not used currently
 36 |      *     QUEST_FLAGS_DAILY                   = 0x1000,    // Used to know quest is Daily one
 37 |      *     QUEST_FLAGS_FLAGS_PVP               = 0x2000,    // Having this quest in log forces PvP flag
 38 |      *     QUEST_FLAGS_UNAVAILABLE             = 0x4000,    // Used on quests that are not generically available
 39 |      *     QUEST_FLAGS_WEEKLY                  = 0x8000,
 40 |      *     QUEST_FLAGS_AUTOCOMPLETE            = 0x10000,   // auto complete
 41 |      *     QUEST_FLAGS_DISPLAY_ITEM_IN_TRACKER = 0x20000,   // Displays usable item in quest tracker
 42 |      *     QUEST_FLAGS_OBJ_TEXT                = 0x40000,   // use Objective text as Complete text
 43 |      *     QUEST_FLAGS_AUTO_ACCEPT             = 0x80000,   // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future.
 44 |      *
 45 |      *     // ... 4.x added flags up to 0x80000000 - all unknown for now
 46 |      * };
 47 |      * 
48 | * 49 | * @param [QuestFlags] flag : all available flags can be seen above 50 | * @return bool hasFlag 51 | */ 52 | int HasFlag(lua_State* L, Quest* quest) 53 | { 54 | uint32 flag = Eluna::CHECKVAL(L, 2); 55 | Eluna::Push(L, quest->HasFlag(flag)); 56 | return 1; 57 | } 58 | 59 | /** 60 | * Returns 'true' if the [Quest] is a daily quest, false otherwise. 61 | * 62 | * @return bool isDaily 63 | */ 64 | int IsDaily(lua_State* L, Quest* quest) 65 | { 66 | Eluna::Push(L, quest->IsDaily()); 67 | return 1; 68 | } 69 | 70 | /** 71 | * Returns 'true' if the [Quest] is repeatable, false otherwise. 72 | * 73 | * @return bool isRepeatable 74 | */ 75 | int IsRepeatable(lua_State* L, Quest* quest) 76 | { 77 | Eluna::Push(L, quest->IsRepeatable()); 78 | return 1; 79 | } 80 | 81 | /** 82 | * Returns entry ID of the [Quest]. 83 | * 84 | * @return uint32 entryId 85 | */ 86 | int GetId(lua_State* L, Quest* quest) 87 | { 88 | Eluna::Push(L, quest->GetQuestId()); 89 | return 1; 90 | } 91 | 92 | /** 93 | * Returns the [Quest]'s level. 94 | * 95 | * @return uint32 level 96 | */ 97 | int GetLevel(lua_State* L, Quest* quest) 98 | { 99 | Eluna::Push(L, quest->GetQuestLevel()); 100 | return 1; 101 | } 102 | 103 | /** 104 | * Returns the minimum level required to pick up the [Quest]. 105 | * 106 | * @return uint32 minLevel 107 | */ 108 | int GetMinLevel(lua_State* L, Quest* quest) 109 | { 110 | Eluna::Push(L, quest->GetMinLevel()); 111 | return 1; 112 | } 113 | 114 | /** 115 | * Returns the next [Quest] entry ID. 116 | * 117 | * @return int32 entryId 118 | */ 119 | int GetNextQuestId(lua_State* L, Quest* quest) 120 | { 121 | Eluna::Push(L, quest->GetNextQuestId()); 122 | return 1; 123 | } 124 | 125 | /** 126 | * Returns the previous [Quest] entry ID. 127 | * 128 | * @return int32 entryId 129 | */ 130 | int GetPrevQuestId(lua_State* L, Quest* quest) 131 | { 132 | Eluna::Push(L, quest->GetPrevQuestId()); 133 | return 1; 134 | } 135 | 136 | /** 137 | * Returns the next [Quest] entry ID in the specific [Quest] chain. 138 | * 139 | * @return int32 entryId 140 | */ 141 | int GetNextQuestInChain(lua_State* L, Quest* quest) 142 | { 143 | Eluna::Push(L, quest->GetNextQuestInChain()); 144 | return 1; 145 | } 146 | 147 | /** 148 | * Returns the [Quest]'s flags. 149 | * 150 | * @return [QuestFlags] flags 151 | */ 152 | int GetFlags(lua_State* L, Quest* quest) 153 | { 154 | Eluna::Push(L, quest->GetFlags()); 155 | return 1; 156 | } 157 | 158 | /** 159 | * Returns the [Quest]'s type. 160 | * 161 | * TODO: Document types available. 162 | * 163 | * @return uint32 type 164 | */ 165 | int GetType(lua_State* L, Quest* quest) 166 | { 167 | Eluna::Push(L, quest->GetType()); 168 | return 1; 169 | } 170 | 171 | /*int GetMaxLevel(lua_State* L, Quest* quest) 172 | { 173 | Eluna::Push(L, quest->GetMaxLevel()); 174 | return 1; 175 | }*/ 176 | }; 177 | #endif 178 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/RollMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef ROLLMETHODS_H 8 | #define ROLLMETHODS_H 9 | 10 | #include "Group.h" 11 | 12 | namespace LuaRoll 13 | { 14 | /** 15 | * Returns the rolled [Item]'s GUID. 16 | * 17 | * @return ObjectGuid guid 18 | */ 19 | int GetItemGUID(lua_State* L, Roll* roll) 20 | { 21 | Eluna::Push(L, roll->itemGUID.GetCounter()); 22 | return 1; 23 | } 24 | 25 | /** 26 | * Returns the rolled [Item]'s entry. 27 | * 28 | * @return uint32 entry 29 | */ 30 | int GetItemId(lua_State* L, Roll* roll) 31 | { 32 | Eluna::Push(L, roll->itemid); 33 | return 1; 34 | } 35 | 36 | /** 37 | * Returns the rolled [Item]'s random property ID. 38 | * 39 | * @return int32 randomPropId 40 | */ 41 | int GetItemRandomPropId(lua_State* L, Roll* roll) 42 | { 43 | Eluna::Push(L, roll->itemRandomPropId); 44 | return 1; 45 | } 46 | 47 | /** 48 | * Returns the rolled [Item]'s random suffix ID. 49 | * 50 | * @return uint32 randomSuffix 51 | */ 52 | int GetItemRandomSuffix(lua_State* L, Roll* roll) 53 | { 54 | Eluna::Push(L, roll->itemRandomSuffix); 55 | return 1; 56 | } 57 | 58 | /** 59 | * Returns the rolled [Item]'s count. 60 | * 61 | * @return uint8 count 62 | */ 63 | int GetItemCount(lua_State* L, Roll* roll) 64 | { 65 | Eluna::Push(L, roll->itemCount); 66 | return 1; 67 | } 68 | 69 | /** 70 | * Returns the vote type for a [Player] on this [Roll]. 71 | * See [Roll:GetPlayerVoteGUIDs] to obtain the GUIDs of the [Player]s who rolled. 72 | * 73 | *
 74 |      * enum RollVote
 75 |      * {
 76 |      *     PASS              = 0,
 77 |      *     NEED              = 1,
 78 |      *     GREED             = 2,
 79 |      *     DISENCHANT        = 3,
 80 |      *     NOT_EMITED_YET    = 4,
 81 |      *     NOT_VALID         = 5
 82 |      * };
 83 |      * 
84 | * 85 | * @param ObjectGuid guid 86 | * @return [RollVote] vote 87 | */ 88 | int GetPlayerVote(lua_State* L, Roll* roll) 89 | { 90 | ObjectGuid guid = Eluna::CHECKVAL(L, 2); 91 | 92 | bool found = false; 93 | for (std::pair& pair : roll->playerVote) 94 | { 95 | if (pair.first == guid) 96 | { 97 | Eluna::Push(L, pair.second); 98 | found = true; 99 | } 100 | } 101 | 102 | if (!found) 103 | { 104 | Eluna::Push(L); 105 | } 106 | 107 | return 1; 108 | } 109 | 110 | /** 111 | * Returns the GUIDs of the [Player]s who rolled. 112 | * See [Roll:GetPlayerVote] to obtain the vote type of a [Player]. 113 | * 114 | * @return table guids 115 | */ 116 | int GetPlayerVoteGUIDs(lua_State* L, Roll* roll) 117 | { 118 | lua_newtable(L); 119 | int table = lua_gettop(L); 120 | uint32 i = 1; 121 | for (std::pair& pair : roll->playerVote) 122 | { 123 | Eluna::Push(L, pair.first); 124 | lua_rawseti(L, table, i); 125 | ++i; 126 | } 127 | 128 | lua_settop(L, table); // push table to top of stack 129 | return 1; 130 | } 131 | 132 | /** 133 | * Returns the total number of players who rolled. 134 | * 135 | * @return uint8 playersCount 136 | */ 137 | int GetTotalPlayersRolling(lua_State* L, Roll* roll) 138 | { 139 | Eluna::Push(L, roll->totalPlayersRolling); 140 | return 1; 141 | } 142 | 143 | /** 144 | * Returns the total number of players who rolled need. 145 | * 146 | * @return uint8 playersCount 147 | */ 148 | int GetTotalNeed(lua_State* L, Roll* roll) 149 | { 150 | Eluna::Push(L, roll->totalNeed); 151 | return 1; 152 | } 153 | 154 | /** 155 | * Returns the total number of players who rolled greed. 156 | * 157 | * @return uint8 playersCount 158 | */ 159 | int GetTotalGreed(lua_State* L, Roll* roll) 160 | { 161 | Eluna::Push(L, roll->totalGreed); 162 | return 1; 163 | } 164 | 165 | /** 166 | * Returns the total number of players who passed. 167 | * 168 | * @return uint8 playersCount 169 | */ 170 | int GetTotalPass(lua_State* L, Roll* roll) 171 | { 172 | Eluna::Push(L, roll->totalPass); 173 | return 1; 174 | } 175 | 176 | /** 177 | * Returns the rolled [Item]'s slot in the loot window. 178 | * 179 | * @return uint8 slot 180 | */ 181 | int GetItemSlot(lua_State* L, Roll* roll) 182 | { 183 | Eluna::Push(L, roll->itemSlot); 184 | return 1; 185 | } 186 | 187 | /** 188 | * Returns the mask applied to this [Roll]. 189 | * 190 | *
191 |      * enum RollMask
192 |      * {
193 |      *     ROLL_FLAG_TYPE_PASS                 = 0x01,
194 |      *     ROLL_FLAG_TYPE_NEED                 = 0x02,
195 |      *     ROLL_FLAG_TYPE_GREED                = 0x04,
196 |      *     ROLL_FLAG_TYPE_DISENCHANT           = 0x08,
197 |      * 
198 |      *     ROLL_ALL_TYPE_NO_DISENCHANT         = 0x07,
199 |      *     ROLL_ALL_TYPE_MASK                  = 0x0F
200 |      * };
201 |      * 
202 | * 203 | * @return [RollMask] rollMask 204 | */ 205 | int GetRollVoteMask(lua_State* L, Roll* roll) 206 | { 207 | Eluna::Push(L, roll->rollVoteMask); 208 | return 1; 209 | } 210 | } 211 | 212 | #endif 213 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/SpellMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef SPELLMETHODS_H 8 | #define SPELLMETHODS_H 9 | 10 | /*** 11 | * An instance of a spell, created when the spell is cast by a [Unit]. 12 | * 13 | * Inherits all methods from: none 14 | */ 15 | namespace LuaSpell 16 | { 17 | /** 18 | * Returns `true` if the [Spell] is automatically repeating, `false` otherwise. 19 | * 20 | * @return bool isAutoRepeating 21 | */ 22 | int IsAutoRepeat(lua_State* L, Spell* spell) 23 | { 24 | Eluna::Push(L, spell->IsAutoRepeat()); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the [Unit] that casted the [Spell]. 30 | * 31 | * @return [Unit] caster 32 | */ 33 | int GetCaster(lua_State* L, Spell* spell) 34 | { 35 | Eluna::Push(L, spell->GetCaster()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the cast time of the [Spell]. 41 | * 42 | * @return int32 castTime 43 | */ 44 | int GetCastTime(lua_State* L, Spell* spell) 45 | { 46 | Eluna::Push(L, spell->GetCastTime()); 47 | return 1; 48 | } 49 | 50 | /** 51 | * Returns the entry ID of the [Spell]. 52 | * 53 | * @return uint32 entryId 54 | */ 55 | int GetEntry(lua_State* L, Spell* spell) 56 | { 57 | Eluna::Push(L, spell->m_spellInfo->Id); 58 | return 1; 59 | } 60 | 61 | /** 62 | * Returns the power cost of the [Spell]. 63 | * 64 | * @return uint32 powerCost 65 | */ 66 | int GetPowerCost(lua_State* L, Spell* spell) 67 | { 68 | Eluna::Push(L, spell->GetPowerCost()); 69 | return 1; 70 | } 71 | 72 | /** 73 | * Returns the reagents needed for the [Spell]. 74 | * 75 | * @return table reagents : a table containing the [ItemTemplate]s and amount of reagents needed for the [Spell] 76 | */ 77 | int GetReagentCost(lua_State* L, Spell* spell) 78 | { 79 | auto spellInfo = spell->GetSpellInfo(); 80 | auto reagents = spellInfo->Reagent; 81 | auto reagentCounts = spellInfo->ReagentCount; 82 | lua_newtable(L); 83 | for (auto i = 0; i < MAX_SPELL_REAGENTS; ++i) 84 | { 85 | if (reagents[i] <= 0) 86 | continue; 87 | auto reagent = eObjectMgr->GetItemTemplate(reagents[i]); 88 | auto count = reagentCounts[i]; 89 | Eluna::Push(L, reagent); 90 | Eluna::Push(L, count); 91 | lua_settable(L, -3); 92 | } 93 | return 1; 94 | } 95 | 96 | /** 97 | * Returns the spell duration of the [Spell]. 98 | * 99 | * @return int32 duration 100 | */ 101 | int GetDuration(lua_State* L, Spell* spell) 102 | { 103 | Eluna::Push(L, spell->GetSpellInfo()->GetDuration()); 104 | return 1; 105 | } 106 | 107 | /** 108 | * Returns the target destination coordinates of the [Spell]. 109 | * 110 | * @return float x : x coordinate of the [Spell] 111 | * @return float y : y coordinate of the [Spell] 112 | * @return float z : z coordinate of the [Spell] 113 | */ 114 | int GetTargetDest(lua_State* L, Spell* spell) 115 | { 116 | if (!spell->m_targets.HasDst()) 117 | return 3; 118 | float x, y, z; 119 | spell->m_targets.GetDstPos()->GetPosition(x, y, z); 120 | 121 | Eluna::Push(L, x); 122 | Eluna::Push(L, y); 123 | Eluna::Push(L, z); 124 | return 3; 125 | } 126 | 127 | /** 128 | * Returns the target [Object] of the [Spell]. 129 | * 130 | * The target can be any of the following [Object] types: 131 | * - [Player] 132 | * - [Creature] 133 | * - [GameObject] 134 | * - [Item] 135 | * - [Corpse] 136 | * 137 | * @return [Object] target 138 | */ 139 | int GetTarget(lua_State* L, Spell* spell) 140 | { 141 | if (GameObject* target = spell->m_targets.GetGOTarget()) 142 | Eluna::Push(L, target); 143 | else if (Item* target = spell->m_targets.GetItemTarget()) 144 | Eluna::Push(L, target); 145 | else if (Corpse* target = spell->m_targets.GetCorpseTarget()) 146 | Eluna::Push(L, target); 147 | else if (Unit* target = spell->m_targets.GetUnitTarget()) 148 | Eluna::Push(L, target); 149 | else if (WorldObject* target = spell->m_targets.GetObjectTarget()) 150 | Eluna::Push(L, target); 151 | return 1; 152 | } 153 | 154 | /** 155 | * Sets the [Spell] to automatically repeat. 156 | * 157 | * @param bool repeat : set variable to 'true' for spell to automatically repeat 158 | */ 159 | int SetAutoRepeat(lua_State* L, Spell* spell) 160 | { 161 | bool repeat = Eluna::CHECKVAL(L, 2); 162 | spell->SetAutoRepeat(repeat); 163 | return 0; 164 | } 165 | 166 | /** 167 | * Casts the [Spell]. 168 | * 169 | * @param bool skipCheck = false : skips initial checks to see if the [Spell] can be casted or not, this is optional 170 | */ 171 | int Cast(lua_State* L, Spell* spell) 172 | { 173 | bool skipCheck = Eluna::CHECKVAL(L, 2, false); 174 | spell->cast(skipCheck); 175 | return 0; 176 | } 177 | 178 | /** 179 | * Cancels the [Spell]. 180 | */ 181 | int Cancel(lua_State* /*L*/, Spell* spell) 182 | { 183 | spell->cancel(); 184 | return 0; 185 | } 186 | 187 | /** 188 | * Finishes the [Spell]. 189 | */ 190 | int Finish(lua_State* /*L*/, Spell* spell) 191 | { 192 | spell->finish(); 193 | return 0; 194 | } 195 | }; 196 | #endif 197 | -------------------------------------------------------------------------------- /src/LuaEngine/methods/VehicleMethods.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 - 2016 Eluna Lua Engine 3 | * This program is free software licensed under GPL version 3 4 | * Please see the included DOCS/LICENSE.md for more information 5 | */ 6 | 7 | #ifndef VEHICLEMETHODS_H 8 | #define VEHICLEMETHODS_H 9 | 10 | /*** 11 | * Inherits all methods from: none 12 | */ 13 | namespace LuaVehicle 14 | { 15 | /** 16 | * Returns true if the [Unit] passenger is on board 17 | * 18 | * @param [Unit] passenger 19 | * @return bool isOnBoard 20 | */ 21 | int IsOnBoard(lua_State* L, Vehicle* vehicle) 22 | { 23 | Unit* passenger = Eluna::CHECKOBJ(L, 2); 24 | Eluna::Push(L, passenger->IsOnVehicle(vehicle->GetBase())); 25 | return 1; 26 | } 27 | 28 | /** 29 | * Returns the [Vehicle]'s owner 30 | * 31 | * @return [Unit] owner 32 | */ 33 | int GetOwner(lua_State* L, Vehicle* vehicle) 34 | { 35 | Eluna::Push(L, vehicle->GetBase()); 36 | return 1; 37 | } 38 | 39 | /** 40 | * Returns the [Vehicle]'s entry 41 | * 42 | * @return uint32 entry 43 | */ 44 | int GetEntry(lua_State* L, Vehicle* vehicle) 45 | { 46 | Eluna::Push(L, vehicle->GetVehicleInfo()->m_ID); 47 | return 1; 48 | } 49 | 50 | /** 51 | * Returns the [Vehicle]'s passenger in the specified seat 52 | * 53 | * @param int8 seat 54 | * @return [Unit] passenger 55 | */ 56 | int GetPassenger(lua_State* L, Vehicle* vehicle) 57 | { 58 | int8 seatId = Eluna::CHECKVAL(L, 2); 59 | Eluna::Push(L, vehicle->GetPassenger(seatId)); 60 | return 1; 61 | } 62 | 63 | /** 64 | * Adds [Unit] passenger to a specified seat in the [Vehicle] 65 | * 66 | * @param [Unit] passenger 67 | * @param int8 seat 68 | */ 69 | int AddPassenger(lua_State* L, Vehicle* vehicle) 70 | { 71 | Unit* passenger = Eluna::CHECKOBJ(L, 2); 72 | int8 seatId = Eluna::CHECKVAL(L, 3); 73 | 74 | vehicle->AddPassenger(passenger, seatId); 75 | return 0; 76 | } 77 | 78 | /** 79 | * Removes [Unit] passenger from the [Vehicle] 80 | * 81 | * @param [Unit] passenger 82 | */ 83 | int RemovePassenger(lua_State* L, Vehicle* vehicle) 84 | { 85 | Unit* passenger = Eluna::CHECKOBJ(L, 2); 86 | vehicle->RemovePassenger(passenger); 87 | return 0; 88 | } 89 | } 90 | 91 | #endif // VEHICLEMETHODS_H 92 | -------------------------------------------------------------------------------- /src/eluna_loader.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the 6 | * Free Software Foundation; either version 2 of the License, or (at your 7 | * option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program. If not, see . 16 | */ 17 | 18 | // From SC 19 | void AddSC_ElunaLuaEngine(); 20 | 21 | // Add all 22 | void Addmod_elunaScripts() 23 | { 24 | AddSC_ElunaLuaEngine(); 25 | } 26 | -------------------------------------------------------------------------------- /src/lualib/lua/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # BSD-3-Clause 2 | # Copyright (c) 2022, Rochet2 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 8 | # * Redistributions of source code must retain the above copyright notice, this 9 | # list of conditions and the following disclaimer. 10 | # 11 | # * Redistributions in binary form must reproduce the above copyright notice, 12 | # this list of conditions and the following disclaimer in the documentation 13 | # and/or other materials provided with the distribution. 14 | # 15 | # * Neither the name of the copyright holder nor the names of its 16 | # contributors may be used to endorse or promote products derived from 17 | # this software without specific prior written permission. 18 | # 19 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | project ( lua C ) 31 | 32 | # LUA_VERSION must be one of lua51, lua52, lua53, lua54 33 | 34 | include(FetchContent) 35 | FetchContent_Declare( 36 | lua51 37 | URL https://www.lua.org/ftp/lua-5.1.5.tar.gz 38 | URL_HASH SHA256=2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333 39 | ) 40 | FetchContent_Declare( 41 | lua52 42 | URL https://www.lua.org/ftp/lua-5.2.4.tar.gz 43 | URL_HASH SHA256=b9e2e4aad6789b3b63a056d442f7b39f0ecfca3ae0f1fc0ae4e9614401b69f4b 44 | ) 45 | FetchContent_Declare( 46 | lua53 47 | URL https://www.lua.org/ftp/lua-5.3.6.tar.gz 48 | URL_HASH SHA256=fc5fd69bb8736323f026672b1b7235da613d7177e72558893a0bdcd320466d60 49 | ) 50 | FetchContent_Declare( 51 | lua54 52 | URL https://www.lua.org/ftp/lua-5.4.4.tar.gz 53 | URL_HASH SHA256=164c7849653b80ae67bec4b7473b884bf5cc8d2dca05653475ec2ed27b9ebf61 54 | ) 55 | FetchContent_MakeAvailable(${LUA_VERSION}) 56 | 57 | # Easen warnings 58 | string(REGEX REPLACE "( |^)/W[0-9]( |$)" "\\1/W2\\2" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 59 | string(REGEX REPLACE "( |^)/W[0-9]( |$)" "\\1/W2\\2" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 60 | 61 | set(LUA_SOURCE_FOLDER "${${LUA_VERSION}_SOURCE_DIR}/src") 62 | 63 | file(GLOB LOCAL_SOURCES_H ${LUA_SOURCE_FOLDER}/*.h) 64 | file(GLOB LOCAL_SOURCES_C ${LUA_SOURCE_FOLDER}/*.c) 65 | # Compile lua as C++ so it uses exceptions instead of longjmp 66 | # Disabled for now as some libraries expect lua to be C 67 | # set_source_files_properties(${LOCAL_SOURCES_H} ${LOCAL_SOURCES_C} PROPERTIES LANGUAGE CXX ) 68 | list(REMOVE_ITEM LOCAL_SOURCES_C ${LUA_SOURCE_FOLDER}/lua.c) 69 | list(REMOVE_ITEM LOCAL_SOURCES_C ${LUA_SOURCE_FOLDER}/luac.c) 70 | 71 | if (LUA_STATIC) 72 | add_library(lualib STATIC ${LOCAL_SOURCES_H} ${LOCAL_SOURCES_C}) 73 | set_property(TARGET lualib PROPERTY POSITION_INDEPENDENT_CODE ON) 74 | else() 75 | add_library(lualib SHARED ${LOCAL_SOURCES_H} ${LOCAL_SOURCES_C}) 76 | set_property(TARGET lualib PROPERTY POSITION_INDEPENDENT_CODE ON) 77 | endif() 78 | 79 | set_target_properties(lualib PROPERTIES LINKER_LANGUAGE C) 80 | target_include_directories(lualib PUBLIC "${LUA_SOURCE_FOLDER}" "${CMAKE_CURRENT_SOURCE_DIR}") 81 | 82 | if (WIN32) 83 | set_target_properties(lualib PROPERTIES OUTPUT_NAME ${LUA_VERSION}) 84 | install(TARGETS lualib DESTINATION "${CMAKE_INSTALL_PREFIX}") 85 | if (NOT LUA_STATIC) 86 | install(FILES $ DESTINATION "${CMAKE_INSTALL_PREFIX}" OPTIONAL) 87 | endif() 88 | else() 89 | set_target_properties(lualib PROPERTIES PUBLIC_HEADER "${LOCAL_SOURCES_H};${CMAKE_CURRENT_SOURCE_DIR}/lua.hpp") 90 | install(TARGETS lualib 91 | DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" 92 | PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_PREFIX}/include" 93 | ) 94 | endif() 95 | 96 | if (WIN32) 97 | target_compile_definitions(lualib PRIVATE _CRT_SECURE_NO_WARNINGS) 98 | if (NOT LUA_STATIC) 99 | target_compile_definitions(lualib PRIVATE LUA_BUILD_AS_DLL) 100 | endif() 101 | elseif (APPLE) 102 | target_compile_definitions(lualib PUBLIC LUA_USE_MACOSX) 103 | target_compile_options(lualib PRIVATE -Wno-deprecated-declarations -Wno-empty-body) 104 | target_link_libraries(lualib readline) 105 | elseif (UNIX) 106 | target_compile_definitions(lualib PUBLIC LUA_USE_LINUX) 107 | target_link_libraries(lualib ${CMAKE_DL_LIBS} m readline) 108 | set_target_properties(lualib PROPERTIES OUTPUT_NAME ${LUA_VERSION}) 109 | endif() 110 | 111 | add_executable(lua_interpreter ${LUA_SOURCE_FOLDER}/lua.c) 112 | target_link_libraries(lua_interpreter lualib) 113 | target_compile_definitions(lua_interpreter PRIVATE _CRT_SECURE_NO_WARNINGS) 114 | set_target_properties(lua_interpreter PROPERTIES OUTPUT_NAME ${LUA_VERSION}_interpreter) 115 | if (WIN32) 116 | install(TARGETS lua_interpreter DESTINATION "${CMAKE_INSTALL_PREFIX}") 117 | install(FILES $ DESTINATION "${CMAKE_INSTALL_PREFIX}" OPTIONAL) 118 | else() 119 | install(TARGETS lua_interpreter DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") 120 | endif() 121 | 122 | add_executable(lua_compiler ${LUA_SOURCE_FOLDER}/luac.c) 123 | target_link_libraries(lua_compiler lualib) 124 | target_compile_definitions(lua_compiler PRIVATE _CRT_SECURE_NO_WARNINGS) 125 | set_target_properties(lua_compiler PROPERTIES OUTPUT_NAME ${LUA_VERSION}_compiler) 126 | if (WIN32) 127 | install(TARGETS lua_compiler DESTINATION "${CMAKE_INSTALL_PREFIX}") 128 | install(FILES $ DESTINATION "${CMAKE_INSTALL_PREFIX}" OPTIONAL) 129 | else() 130 | install(TARGETS lua_compiler DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") 131 | endif() -------------------------------------------------------------------------------- /src/lualib/lua/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | 11 | --------------------------------------------------------------------------------