mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-23 04:52:29 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b83fafb745 | |||
| bcc42edb16 | |||
| 0eba5f2990 | |||
| c70bdc6b70 | |||
| 6a25f30441 | |||
| 825dbc9e9a | |||
| a5f35bf32a | |||
| c09ab507dd | |||
| 483ca9996b | |||
| 122f1cd02d | |||
| e0d4f9ecd1 | |||
| cb72ad4d0f | |||
| 98f4e570e7 | |||
| 6532a81b80 | |||
| b0f591540c | |||
| ac07e7d578 | |||
| 40ef387496 | |||
| c9a79af79b | |||
| 1a71237dc2 | |||
| f990292660 | |||
| e72f1e855f | |||
| 3bc9e4bc24 | |||
| 22aef8ad79 | |||
| bf84fcd908 | |||
| 0c5779d2de | |||
| 2270bd267d | |||
| feec425be9 | |||
| dd5ef6523f | |||
| c69b9a95b7 |
-98
@@ -1,98 +0,0 @@
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Build Linux
|
||||
|
||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||
concurrency:
|
||||
limit: 1
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /var/lib/cache-release
|
||||
|
||||
steps:
|
||||
- name: Build Linux X64
|
||||
image: akkadius/eqemu-server:v11
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
commands:
|
||||
- ./utils/scripts/build/linux-build.sh
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /home/eqemu/.ccache/
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: exec
|
||||
name: Build Windows
|
||||
|
||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||
concurrency:
|
||||
limit: 1
|
||||
|
||||
platform:
|
||||
os: windows
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: Build Windows X64
|
||||
environment:
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
commands:
|
||||
- .\utils\scripts\build\windows-build.ps1
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Publish Artifacts to Github
|
||||
|
||||
steps:
|
||||
- name: Upload Artifacts
|
||||
image: akkadius/eqemu-build-releaser:v3
|
||||
environment:
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
GH_RELEASE_GITHUB_API_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
commands:
|
||||
- ./utils/scripts/build/should-release/should-release
|
||||
- rclone config create remote ftp env_auth true > /dev/null
|
||||
- |
|
||||
rclone copy remote: --include "eqemu-server*.zip" .
|
||||
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
|
||||
- |
|
||||
rclone delete remote: --include "eqemu-server*.zip"
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
|
||||
depends_on:
|
||||
- Build Windows
|
||||
- Build Linux
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Matches multiple files with brace expansion notation
|
||||
# Set default charset
|
||||
[*.{js,py}]
|
||||
charset = utf-8
|
||||
|
||||
[*.cpp]
|
||||
indent_style = tab
|
||||
[*.h]
|
||||
indent_style = tab
|
||||
|
||||
# Tab indentation (no size specified)
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
+17
-44
@@ -17,57 +17,30 @@
|
||||
*.out
|
||||
*.app
|
||||
|
||||
.bash_history
|
||||
|
||||
# CMake
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
[Bb]uild*/
|
||||
[Bb]uild/
|
||||
[Bb]uild32/
|
||||
[Bb]uild64/
|
||||
[Bb]uild_32/
|
||||
[Bb]uild_64/
|
||||
deploy/server/
|
||||
x64/
|
||||
x86/
|
||||
log/
|
||||
logs/
|
||||
vcpkg/
|
||||
perl/
|
||||
|
||||
.idea/*
|
||||
*cbp
|
||||
docker/db
|
||||
|
||||
submodules/*
|
||||
cmake-build-debug/
|
||||
|
||||
.nfs.*
|
||||
|
||||
# Visual Studio and CMAKE Generated Files
|
||||
/.vs/
|
||||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
*.cmake
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.dir/
|
||||
libs/
|
||||
bin/
|
||||
/Win32
|
||||
/x64
|
||||
/client_files/**/CMakeFiles/
|
||||
|
||||
.idea
|
||||
|
||||
# Clangd Generated Files.
|
||||
compile_flags.txt
|
||||
.cache/
|
||||
|
||||
# vscode generated settings
|
||||
.vscode/
|
||||
|
||||
# Build pipeline
|
||||
!utils/scripts/build/
|
||||
!utils/scripts/build/should-release/should-release
|
||||
!utils/scripts/build/should-release/should-release.exe
|
||||
|
||||
# CMake Files
|
||||
cmake-build-relwithdebinfo/*
|
||||
# Protobuf generated files
|
||||
*.pb.cc
|
||||
*.pb.h
|
||||
protobuf/csharp/*
|
||||
protobuf/go/*
|
||||
protobuf/java/*
|
||||
protobuf/python/*
|
||||
.vscode
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
[submodule "submodules/glm"]
|
||||
path = submodules/glm
|
||||
url = https://github.com/g-truc/glm.git
|
||||
[submodule "submodules/fmt"]
|
||||
path = submodules/fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
[submodule "submodules/libuv"]
|
||||
path = submodules/libuv
|
||||
url = https://github.com/libuv/libuv.git
|
||||
[submodule "submodules/cereal"]
|
||||
path = submodules/cereal
|
||||
url = https://github.com/USCiLab/cereal.git
|
||||
[submodule "submodules/websocketpp"]
|
||||
path = submodules/websocketpp
|
||||
url = https://github.com/zaphoyd/websocketpp.git
|
||||
[submodule "submodules/recastnavigation"]
|
||||
path = submodules/recastnavigation
|
||||
url = https://github.com/EQEmu/recastnavigation.git
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.8
|
||||
- g++-4.8
|
||||
- libmysqlclient-dev
|
||||
- libperl-dev
|
||||
- libboost-dev
|
||||
- liblua5.1-0-dev
|
||||
- zlib1g-dev
|
||||
- uuid-dev
|
||||
- libssl-dev
|
||||
install:
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi
|
||||
script:
|
||||
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
||||
- make -j2
|
||||
- ./bin/tests
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- stable
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
channels: "irc.eqemulator.net#eqemucoders"
|
||||
os: linux
|
||||
@@ -1,64 +0,0 @@
|
||||
# Guide To Building From Source Without Installer
|
||||
|
||||
This guide is far from exhaustive, you should expect to have some experience with building C++ code before considering compiling the code from scratch. You should instead consider using the installer scripts if you don't want to hack on the code directly.
|
||||
|
||||
### CMake
|
||||
|
||||
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source.
|
||||
|
||||
### Dependencies
|
||||
|
||||
The following libraries are required to build from source:
|
||||
- [boost](https://www.boost.org/ "boost")
|
||||
- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead)
|
||||
- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb")
|
||||
|
||||
The following libraries are not strictly required but in many cased recommended.
|
||||
- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client)
|
||||
- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver)
|
||||
- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting)
|
||||
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
|
||||
|
||||
##### Windows
|
||||
For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies.
|
||||
|
||||
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
|
||||
|
||||
You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake.
|
||||
|
||||
##### Linux
|
||||
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
|
||||
|
||||
sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev
|
||||
|
||||
### Running CMake
|
||||
|
||||
##### Windows
|
||||
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
|
||||
|
||||
Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
|
||||
|
||||
##### Linux
|
||||
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
||||
|
||||
### Building
|
||||
|
||||
##### Windows
|
||||
Inside the build directory a file EQEmu.sln should be produced by a successful run of the CMake command. You can either open this with Visual Studio or build it directly with MSBuild via the command line.
|
||||
|
||||
msbuild EQEmu.sln /p:Configuration=Release
|
||||
|
||||
##### Linux
|
||||
From the build directory you can simply call make to build.
|
||||
|
||||
For example.
|
||||
|
||||
make -j4
|
||||
-932
@@ -1,932 +0,0 @@
|
||||
## [22.4.2] - 02/18/2023
|
||||
|
||||
### Content
|
||||
|
||||
* Added optional SQL 2023_02_17_fix_sseru_mischief_doors.sql to fix sseru/mischief doors ([#2955](https://github.com/EQEmu/Server/pull/2955)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||
|
||||
### Logging
|
||||
|
||||
* Remove noisy raid/group/forage errors ([#2952](https://github.com/EQEmu/Server/pull/2952)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||
|
||||
### MySQL
|
||||
|
||||
* Add keepalives to UCS and Loginserver ([#2953](https://github.com/EQEmu/Server/pull/2953)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||
|
||||
### Player Events
|
||||
|
||||
* Add logging category to hold processing batch logs ([#2954](https://github.com/EQEmu/Server/pull/2954)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
||||
|
||||
### Tradeskills
|
||||
|
||||
* Fix regression caused by #2932 ([#2956](https://github.com/EQEmu/Server/pull/2956)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
||||
|
||||
## [22.4.1] - 02/17/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Set Taunt to enabled for SK/Paladin Bots by Default. ([#2941](https://github.com/EQEmu/Server/pull/2941)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-17
|
||||
|
||||
### DevTools
|
||||
|
||||
* Fix NPC targetting dev tools display window ([#2943](https://github.com/EQEmu/Server/pull/2943)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
|
||||
### Fixes
|
||||
|
||||
* Issue with AssignRaidToInstance that was using the groups repository instead of raid ([#2947](https://github.com/EQEmu/Server/pull/2947)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
* Missing comma in schema list breaking dumps ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
|
||||
### Player Events
|
||||
|
||||
* Fix issue with item instances not being validated properly before accessing causing crashes on handin ([#2945](https://github.com/EQEmu/Server/pull/2945)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
* Fix rare out of bound issue when loading event types ([#2946](https://github.com/EQEmu/Server/pull/2946)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
* Turn off KILLED_NPC (trash) off by default ([#2948](https://github.com/EQEmu/Server/pull/2948)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
|
||||
## [22.4.0] - 02/17/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add Additional HeroicAgi/Dex Modifiers. ([#2838](https://github.com/EQEmu/Server/pull/2838)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||
* Add Additional HeroicStr modifiers. ([#2837](https://github.com/EQEmu/Server/pull/2837)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||
* Add IsBot() to methods in attack.cpp where applicable. ([#2840](https://github.com/EQEmu/Server/pull/2840)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||
* Add Lore Check for Augments. ([#2874](https://github.com/EQEmu/Server/pull/2874)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-12
|
||||
* Add Pet Power Support for Temp Pets. ([#2853](https://github.com/EQEmu/Server/pull/2853)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-11
|
||||
* Add Support for TryTriggerOnCastFocusEffect ([#2864](https://github.com/EQEmu/Server/pull/2864)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||
* Add TotalDominationBonus modifiers. ([#2852](https://github.com/EQEmu/Server/pull/2852)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||
* ST_AreaClientOnly spells to land on Bots ([#2849](https://github.com/EQEmu/Server/pull/2849)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||
* Update ResistSpell to use temp_level_diff client formula ([#2851](https://github.com/EQEmu/Server/pull/2851)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||
|
||||
### Bots & Mercenaries
|
||||
|
||||
* Add 100% Hit chance if sitting while attacked. ([#2839](https://github.com/EQEmu/Server/pull/2839)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||
* Add Support for TrySympatheticProc ([#2866](https://github.com/EQEmu/Server/pull/2866)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||
|
||||
### CI
|
||||
|
||||
* Fix Windows stderr not bubbling properly ([#2925](https://github.com/EQEmu/Server/pull/2925)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
|
||||
### Code
|
||||
|
||||
* Add IsOfClientBot() virtual method. ([#2845](https://github.com/EQEmu/Server/pull/2845)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||
* Doors EVENT_CLICK_DOOR syntax adjustment ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Remove Unused Mod Hooks ([#2856](https://github.com/EQEmu/Server/pull/2856)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
|
||||
### Crash
|
||||
|
||||
* Crash fix where invalid input to #heromodel would crash zone ([#2937](https://github.com/EQEmu/Server/pull/2937)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||
* Fix Bot Crash in Bot::Bot Constructor. ([#2868](https://github.com/EQEmu/Server/pull/2868)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-12
|
||||
* Fix Crash in FindType ([#2867](https://github.com/EQEmu/Server/pull/2867)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||
* Fix crash in Mob::CommonDamage when attacker was null ([#2872](https://github.com/EQEmu/Server/pull/2872)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
||||
* Fix crash issue with dropping items and order of operations ([#2939](https://github.com/EQEmu/Server/pull/2939)) ([joligario](https://github.com/joligario)) 2023-02-16
|
||||
* Fix issue where long short names overflow file_name ([Akkadius](https://github.com/Akkadius)) 2023-02-09
|
||||
* Fix potential crash in Mob::CommonDamage ([#2848](https://github.com/EQEmu/Server/pull/2848)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
||||
|
||||
### Doors
|
||||
|
||||
* Fix issue where NPC's wouldn't open doors because door param overflow ([#2934](https://github.com/EQEmu/Server/pull/2934)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||
|
||||
### Feature
|
||||
|
||||
* Add IsOfClientBotMerc() virtual method. ([#2843](https://github.com/EQEmu/Server/pull/2843)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
||||
|
||||
### Fixes
|
||||
|
||||
* Another doors fix ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Fix CheckNumHitsRemaining() with 1H Blunt ([#2846](https://github.com/EQEmu/Server/pull/2846)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-07
|
||||
* Fix Door opening regression caused by #2880 ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Fix EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE regression caused by #2897 ([#2928](https://github.com/EQEmu/Server/pull/2928)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Fix HP_EVENT regression ([#2927](https://github.com/EQEmu/Server/pull/2927)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Fix crash in EVENT_DISCOVER_ITEM ([#2933](https://github.com/EQEmu/Server/pull/2933)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-15
|
||||
* Fix crash where dropped items crash Lua logic ([#2936](https://github.com/EQEmu/Server/pull/2936)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||
* Fix for interrupting item casts to no longer lock the client if cast time of item greater than 0 ([#2921](https://github.com/EQEmu/Server/pull/2921)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-13
|
||||
* Fix issue where Lore groundspawn pickups will desync ROF2+ ([#2929](https://github.com/EQEmu/Server/pull/2929)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Fix issue with EVENT_HP firing regression from #2904 ([#2924](https://github.com/EQEmu/Server/pull/2924)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
* Replace uses of SPELL_UNKNOWN with IsValidSpell() ([#2938](https://github.com/EQEmu/Server/pull/2938)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-16
|
||||
* Self Only Spells will no longer check target level or buff restrictions ([#2931](https://github.com/EQEmu/Server/pull/2931)) ([noudess](https://github.com/noudess)) 2023-02-15
|
||||
|
||||
### Groundspawns
|
||||
|
||||
* Fix issue where groundspawns appear floating high off the ground ([#2930](https://github.com/EQEmu/Server/pull/2930)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||
|
||||
### Logging
|
||||
|
||||
* Add raw opcode when emu translated opcode is not found (OP_Unknown) via (C->S) ([#2847](https://github.com/EQEmu/Server/pull/2847)) ([Akkadius](https://github.com/Akkadius)) 2023-02-08
|
||||
* Implement Player Event Logging system ([#2833](https://github.com/EQEmu/Server/pull/2833)) ([Akkadius](https://github.com/Akkadius)) 2023-02-13
|
||||
|
||||
### Quest API
|
||||
|
||||
* (Performance) Check equip or scale item events exist before export and execute ([#2898](https://github.com/EQEmu/Server/pull/2898)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_AA_BUY or EVENT_AA_GAIN exist before export and execute ([#2892](https://github.com/EQEmu/Server/pull/2892)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_AGGRO, EVENT_ATTACK, or EVENT_COMBAT exist before export and execute ([#2901](https://github.com/EQEmu/Server/pull/2901)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_COMBINE, EVENT_COMBINE_SUCCESS, EVENT_COMBINE_FAILURE, or EVENT_COMBINE_VALIDATE exist before export and execute ([#2896](https://github.com/EQEmu/Server/pull/2896)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_DEATH, EVENT_DEATH_COMPLETE, or EVENT_DEATH_ZONE exist before export and execute ([#2909](https://github.com/EQEmu/Server/pull/2909)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_ENVIRONMENTAL_DAMAGE exists before export and execute ([#2899](https://github.com/EQEmu/Server/pull/2899)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_FEIGN_DEATH exists before export and execute ([#2916](https://github.com/EQEmu/Server/pull/2916)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_ITEM_TICK or EVENT_WEAPON_PROC exist before export and execute ([#2914](https://github.com/EQEmu/Server/pull/2914)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_LANGUAGE_SKILL_UP, EVENT_SKILL_UP, or EVENT_USE_SKILL exist before export and execute ([#2894](https://github.com/EQEmu/Server/pull/2894)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_PAYLOAD or EVENT_SIGNAL exist before export and execute ([#2902](https://github.com/EQEmu/Server/pull/2902)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_SLAY exists before export and execute ([#2910](https://github.com/EQEmu/Server/pull/2910)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event EVENT_WAYPOINT_ARRIVE or EVENT_WAYPOINT_DEPART exist before export and execute ([#2905](https://github.com/EQEmu/Server/pull/2905)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_AGGRO_SAY, EVENT_SAY, and EVENT_PROXIMITY_SAY ([#2882](https://github.com/EQEmu/Server/pull/2882)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_BOT_CREATE ([#2886](https://github.com/EQEmu/Server/pull/2886)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_CLICK_DOOR and EVENT_CLICK_OBJECT ([#2880](https://github.com/EQEmu/Server/pull/2880)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_DESPAWN and EVENT_DESPAWN_ZONE ([#2887](https://github.com/EQEmu/Server/pull/2887)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_DISCOVER_ITEM ([#2912](https://github.com/EQEmu/Server/pull/2912)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_DUEL_LOSE and EVENT_DUEL_WIN ([#2915](https://github.com/EQEmu/Server/pull/2915)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_ENTER_ZONE and EVENT_ZONE ([#2900](https://github.com/EQEmu/Server/pull/2900)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_GM_COMMAND ([#2890](https://github.com/EQEmu/Server/pull/2890)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_GROUP_CHANGE ([#2884](https://github.com/EQEmu/Server/pull/2884)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_HP ([#2904](https://github.com/EQEmu/Server/pull/2904)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_KILLED_MERIT ([#2911](https://github.com/EQEmu/Server/pull/2911)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_LEVEL_UP and EVENT_LEVEL_DOWN ([#2889](https://github.com/EQEmu/Server/pull/2889)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_POPUP_RESPONSE ([#2881](https://github.com/EQEmu/Server/pull/2881)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_RESPAWN ([#2917](https://github.com/EQEmu/Server/pull/2917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_TICK ([#2919](https://github.com/EQEmu/Server/pull/2919)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_TIMER ([#2903](https://github.com/EQEmu/Server/pull/2903)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_TRADE ([#2906](https://github.com/EQEmu/Server/pull/2906)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_UNHANDLED_OPCODE ([#2918](https://github.com/EQEmu/Server/pull/2918)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_WARP ([#2907](https://github.com/EQEmu/Server/pull/2907)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute area events ([#2888](https://github.com/EQEmu/Server/pull/2888)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check merchant events exist before export and execute ([#2893](https://github.com/EQEmu/Server/pull/2893)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check spell or cast events exist before export and execute ([#2897](https://github.com/EQEmu/Server/pull/2897)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check task events exist before export and execute ([#2883](https://github.com/EQEmu/Server/pull/2883)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_CONNECT and EVENT_DISCONNECT ([#2913](https://github.com/EQEmu/Server/pull/2913)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* (Performance) Check event exists before export and execute EVENT_TEST_BUFF ([#2920](https://github.com/EQEmu/Server/pull/2920)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Add $target export to EVENT_INSPECT in Perl ([#2891](https://github.com/EQEmu/Server/pull/2891)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Add Additional XP Events EVENT_AA_EXP_GAIN, EVENT_EXP_GAIN ([#2865](https://github.com/EQEmu/Server/pull/2865)) ([Valorith](https://github.com/Valorith)) 2023-02-13
|
||||
* Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua. ([#2871](https://github.com/EQEmu/Server/pull/2871)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Add EVENT_DROP_ITEM_CLIENT to Perl/Lua ([#2869](https://github.com/EQEmu/Server/pull/2869)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Add Recipe-based methods to Perl/Lua. ([#2844](https://github.com/EQEmu/Server/pull/2844)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-08
|
||||
* Export $door to EVENT_CLICKDOOR in Perl ([#2861](https://github.com/EQEmu/Server/pull/2861)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||
* Export $hate_entity to EVENT_HATE_LIST in Perl ([#2885](https://github.com/EQEmu/Server/pull/2885)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export $item and $augment to augment events in Perl ([#2895](https://github.com/EQEmu/Server/pull/2895)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export $item and $corpse to EVENT_LOOT and EVENT_LOOT_ZONE in Perl ([#2878](https://github.com/EQEmu/Server/pull/2878)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export $item to Client/Bot Equip Events in Perl ([#2860](https://github.com/EQEmu/Server/pull/2860)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||
* Export $item to EVENT_DISCOVER_ITEM in Perl ([#2863](https://github.com/EQEmu/Server/pull/2863)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||
* Export $item to EVENT_PLAYER_PICKUP in Perl. ([#2875](https://github.com/EQEmu/Server/pull/2875)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export $item to Fishing and Forage Events in Perl ([#2876](https://github.com/EQEmu/Server/pull/2876)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export $killed_npc to EVENT_NPC_SLAY to Perl ([#2879](https://github.com/EQEmu/Server/pull/2879)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export $object to EVENT_CLICK_OBJECT in Perl ([#2862](https://github.com/EQEmu/Server/pull/2862)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
||||
* Export $spawned to EVENT_SPAWN_ZONE in Perl ([#2877](https://github.com/EQEmu/Server/pull/2877)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export target to EVENT_TARGET_CHANGE in Perl/Lua. ([#2870](https://github.com/EQEmu/Server/pull/2870)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Export targets to EVENT_CONSIDER and EVENT_CONSIDER_CORPSE ([#2908](https://github.com/EQEmu/Server/pull/2908)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
* Fix SetSimpleRoamBox in Perl to have optional params again ([#2935](https://github.com/EQEmu/Server/pull/2935)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Group/Raid Experience Rules ([#2850](https://github.com/EQEmu/Server/pull/2850)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
||||
|
||||
### Tradeskills
|
||||
|
||||
* Check if combine would result in lore conflict ([#2932](https://github.com/EQEmu/Server/pull/2932)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-16
|
||||
|
||||
### Windows
|
||||
|
||||
* Fix MSVC compilation bug via workaround ([#2926](https://github.com/EQEmu/Server/pull/2926)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
||||
|
||||
## [22.3.0] - 02/06/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add GetAugmentIDsBySlotID & AddItem with table ref Methods. ([#2805](https://github.com/EQEmu/Server/pull/2805)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-29
|
||||
|
||||
### Commands
|
||||
|
||||
* #list now searches without case sensitivity ([#2825](https://github.com/EQEmu/Server/pull/2825)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
* Remove extraneous else from #weather ([#2819](https://github.com/EQEmu/Server/pull/2819)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix IsUnderwaterOnly crash where npc data references can be stale ([#2830](https://github.com/EQEmu/Server/pull/2830)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
* Fix command crash with #npcedit weapon when second weapon not passed ni ([#2829](https://github.com/EQEmu/Server/pull/2829)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
* Fix crash in bot command botdyearmor ([#2832](https://github.com/EQEmu/Server/pull/2832)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
### DB Updates
|
||||
|
||||
* Add Windows MySQL path auto detection for users where the path is not found ([#2836](https://github.com/EQEmu/Server/pull/2836)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
### Doors
|
||||
|
||||
* Have NPCs trigger double doors ([#2821](https://github.com/EQEmu/Server/pull/2821)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
* Remove door dev tools spam on client controlled doors ([#2824](https://github.com/EQEmu/Server/pull/2824)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Min/Max Status to Merchants ([#2806](https://github.com/EQEmu/Server/pull/2806)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||
|
||||
### Fixes
|
||||
|
||||
* #reload aa will now refresh the AA table properly for every client when changes are made ([#2814](https://github.com/EQEmu/Server/pull/2814)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
||||
* #reload static should now properly fill the entity_lists for… ([#2815](https://github.com/EQEmu/Server/pull/2815)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
||||
* BuffLevelRestrictions were restricting group buffs if mob targeted ([#2809](https://github.com/EQEmu/Server/pull/2809)) ([noudess](https://github.com/noudess)) 2023-01-29
|
||||
* Fix does_augment_fit_slot method. ([#2817](https://github.com/EQEmu/Server/pull/2817)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-01
|
||||
* Fix NPC ghosting at safe coordinates ([#2823](https://github.com/EQEmu/Server/pull/2823)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
* Fixing % based mob see invis ([#2802](https://github.com/EQEmu/Server/pull/2802)) ([fryguy503](https://github.com/fryguy503)) 2023-01-29
|
||||
* Resolve issue with max buff count being 25 in ROF2. ([#2800](https://github.com/EQEmu/Server/pull/2800)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-28
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Post revert build fix for https://github.com/EQEmu/Server/commit/54050924d81d1f83268fe01f9c2b36fe10626601 ([Akkadius](https://github.com/Akkadius)) 2023-02-01
|
||||
|
||||
### Lua
|
||||
|
||||
* Resolve stoi Exception ([#2736](https://github.com/EQEmu/Server/pull/2736)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
### Pathing
|
||||
|
||||
* Improvements to handling tight corridors pathing, clipping detection and recovery ([#2826](https://github.com/EQEmu/Server/pull/2826)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Augment Slot support to does_augment_fit ([#2813](https://github.com/EQEmu/Server/pull/2813)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-31
|
||||
* Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua. ([#2804](https://github.com/EQEmu/Server/pull/2804)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||
* Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. ([#2810](https://github.com/EQEmu/Server/pull/2810)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-30
|
||||
* Add EVENT_TASKACCEPTED to Player scope ([#2822](https://github.com/EQEmu/Server/pull/2822)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
||||
* Add GetItemCooldown to return the time remaining on items… ([#2811](https://github.com/EQEmu/Server/pull/2811)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-30
|
||||
* Add LDoN Methods to Perl/Lua ([#2799](https://github.com/EQEmu/Server/pull/2799)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
||||
* Add Override Parameters to ScaleNPC() in Perl/Lua. ([#2816](https://github.com/EQEmu/Server/pull/2816)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
||||
* Add rule AlternateAugmentationSealer for using a different bagtype ([#2831](https://github.com/EQEmu/Server/pull/2831)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-06
|
||||
* Default ScaleNPC to always scale. ([#2818](https://github.com/EQEmu/Server/pull/2818)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-06
|
||||
|
||||
### Readme
|
||||
|
||||
* Update build badges with Drone ([Akkadius](https://github.com/Akkadius)) 2023-01-29
|
||||
|
||||
### Rules
|
||||
|
||||
* Add rule to ignore name filter on chat channel creation. ([#2820](https://github.com/EQEmu/Server/pull/2820)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
||||
* Added rule to bypass level based haste caps ([#2835](https://github.com/EQEmu/Server/pull/2835)) ([jcr4990](https://github.com/jcr4990)) 2023-02-06
|
||||
* Fix rule updates that affected bot booting checks ([#2841](https://github.com/EQEmu/Server/pull/2841)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
### Tasks
|
||||
|
||||
* Implement alternate currency rewards ([#2827](https://github.com/EQEmu/Server/pull/2827)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
||||
|
||||
## [22.2.0] - 01/27/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add EVENT_UNEQUIP_ITEM_BOT & EVENT_EQUIP_ITEM_BOT ([#2796](https://github.com/EQEmu/Server/pull/2796)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-27
|
||||
* ^create and ^viewcombos popup messages fix. ([#2797](https://github.com/EQEmu/Server/pull/2797)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-26
|
||||
|
||||
### Code Cleanup
|
||||
|
||||
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix crash issue with log formatting during character creation ([#2798](https://github.com/EQEmu/Server/pull/2798)) ([Akkadius](https://github.com/Akkadius)) 2023-01-27
|
||||
|
||||
### Feature
|
||||
|
||||
* ResetItemCooldown added to lua/perl and fix item re-cast times to show properly ([#2793](https://github.com/EQEmu/Server/pull/2793)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-26
|
||||
|
||||
### Git
|
||||
|
||||
* Add CMake Files to .gitignore ([#2792](https://github.com/EQEmu/Server/pull/2792)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-25
|
||||
|
||||
## [22.1.2] - 01/24/2023
|
||||
|
||||
### CI/CD
|
||||
|
||||
* Build / Release Pipeline Changes ([#2788](https://github.com/EQEmu/Server/pull/2788)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
|
||||
|
||||
### Code Cleanup
|
||||
|
||||
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix rarer world crash issue where scheduler database was not available ([#2789](https://github.com/EQEmu/Server/pull/2789)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix nullptr spell in BCSpells::Load() ([#2790](https://github.com/EQEmu/Server/pull/2790)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||
* Remove duplicate logic in GetActSpellHealing reducing HOT criticals ([#2786](https://github.com/EQEmu/Server/pull/2786)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
||||
|
||||
## [22.1.1] - 01/23/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||
|
||||
## [22.1.0] - 01/22/2023
|
||||
|
||||
This is a first release using the new build system. Changelog entry representative of last year. Subsequent releases will consist of incremental changes since the last release.
|
||||
|
||||
### AA
|
||||
|
||||
* Fix AA tables dump ([#2769](https://github.com/EQEmu/Server/pull/2769)) ([Akkadius](https://github.com/Akkadius)) 2023-01-22
|
||||
|
||||
### Appveyor
|
||||
|
||||
* Remove bots preprocessor ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
|
||||
### Bot/Merc
|
||||
|
||||
* Cleanup methods, and virtual overrides. ([#2734](https://github.com/EQEmu/Server/pull/2734)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
||||
|
||||
### Bots
|
||||
|
||||
* Add Bot Command Reloading ([#2773](https://github.com/EQEmu/Server/pull/2773)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||
* Add Bot-specific Spell Settings. ([#2553](https://github.com/EQEmu/Server/pull/2553)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Add Buff support for Bards under AI_IdleCastChecks ([#2590](https://github.com/EQEmu/Server/pull/2590)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-28
|
||||
* Add Data Bucket support to Bot Spell Entries. ([#2505](https://github.com/EQEmu/Server/pull/2505)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
|
||||
* Add EVENT_TRADE Support to Bots. ([#2560](https://github.com/EQEmu/Server/pull/2560)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
||||
* Add Event_Trade Support for ^inventorygive Command ([#2628](https://github.com/EQEmu/Server/pull/2628)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-11
|
||||
* Add Expansion Bitmask Quest APIs. ([#2523](https://github.com/EQEmu/Server/pull/2523)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||
* Add GetBotOwnerByBotID Method ([#2715](https://github.com/EQEmu/Server/pull/2715)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
|
||||
* Add Melee Support for Casting, Cleanup Bot Casting Logic ([#2571](https://github.com/EQEmu/Server/pull/2571)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
||||
* Add Quest API Methods ([#2631](https://github.com/EQEmu/Server/pull/2631)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-12
|
||||
* Add Quest API Support for Limits. ([#2522](https://github.com/EQEmu/Server/pull/2522)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||
* Add Rule Allowing Bots to Equip Any Race Items ([#2578](https://github.com/EQEmu/Server/pull/2578)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-26
|
||||
* Add Support for AA bonuses that were missing. ([#2764](https://github.com/EQEmu/Server/pull/2764)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
||||
* Add Support for Bots to receive Auras, and other AoE Buffs. ([#2586](https://github.com/EQEmu/Server/pull/2586)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
||||
* Add Virtual Override for Bot::Attack ([#2771](https://github.com/EQEmu/Server/pull/2771)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
||||
* Add give/remove saylinks to ^itemuse. ([#2503](https://github.com/EQEmu/Server/pull/2503)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||
* Add support for Bot scripting. ([#2515](https://github.com/EQEmu/Server/pull/2515)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||
* Apply Spells:IgnoreSpellDmgLvlRestriction to bots ([#2024](https://github.com/EQEmu/Server/pull/2024)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
||||
* Bot::PerformTradeWithClient Cleanup. ([#2084](https://github.com/EQEmu/Server/pull/2084)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
|
||||
* Cleanup Bot Spell Functions, reduce reliance on NPC Functions/Attributes ([#2495](https://github.com/EQEmu/Server/pull/2495)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-29
|
||||
* Cleanup Fast Rest Regen ([#2626](https://github.com/EQEmu/Server/pull/2626)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-07
|
||||
* Cleanup Say Event Parse. ([#2557](https://github.com/EQEmu/Server/pull/2557)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
||||
* Cleanup Spell Settings Commands ([#2607](https://github.com/EQEmu/Server/pull/2607)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||
* Cleanup ^inventoryremove, ^inventorylist, and ^list Commands and bot groups. ([#2273](https://github.com/EQEmu/Server/pull/2273)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-03
|
||||
* Cleanup and remove preprocessors. ([#2757](https://github.com/EQEmu/Server/pull/2757)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-20
|
||||
* Cleanup various Bot Spell Focus methods ([#2649](https://github.com/EQEmu/Server/pull/2649)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-16
|
||||
* Convert Load, Save, SaveNew, and Delete to Repositories. ([#2614](https://github.com/EQEmu/Server/pull/2614)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||
* Expanded Bot Spell Settings List. ([#2606](https://github.com/EQEmu/Server/pull/2606)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-03
|
||||
* Fix Bot Spell Type "In Combat Buffs" ([#2711](https://github.com/EQEmu/Server/pull/2711)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-08
|
||||
* Fix Gender not saving as GetBaseGender on BotSave ([#2639](https://github.com/EQEmu/Server/pull/2639)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
|
||||
* Fix Slow Query in QueryNameAvailablity ([#2781](https://github.com/EQEmu/Server/pull/2781)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
|
||||
* Fix ^dyearmor command math. ([#2081](https://github.com/EQEmu/Server/pull/2081)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
||||
* Fix bot spawn when bot id = char_id ([#1984](https://github.com/EQEmu/Server/pull/1984)) ([neckkola](https://github.com/neckkola)) 2022-03-07
|
||||
* Hotfix for possible crash. ([#2539](https://github.com/EQEmu/Server/pull/2539)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Melee Bot Support for Spell Settings Commands ([#2599](https://github.com/EQEmu/Server/pull/2599)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
|
||||
* Move Bot Spell Loading process to constructor from calcbotstats() ([#2583](https://github.com/EQEmu/Server/pull/2583)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
||||
* Optimize inventory loading. ([#2588](https://github.com/EQEmu/Server/pull/2588)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-28
|
||||
* Post pre-processor fixes ([#2770](https://github.com/EQEmu/Server/pull/2770)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
* Resolve incorrect values on Bot Creation ([#2644](https://github.com/EQEmu/Server/pull/2644)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-14
|
||||
* Restrict Bot Groups from spawning while Feigned. ([#2761](https://github.com/EQEmu/Server/pull/2761)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
|
||||
* Save Bot Toggle Archer Setting between Loads. ([#2612](https://github.com/EQEmu/Server/pull/2612)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||
* Update Bot Heal & Damage methods to more closely match Clients + Bugfixes ([#2045](https://github.com/EQEmu/Server/pull/2045)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-11
|
||||
* Update Bot Logic to ignore ST_TargetsTarget when buffing ([#2584](https://github.com/EQEmu/Server/pull/2584)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
||||
|
||||
### C++20
|
||||
|
||||
* Arithmetic on different enums is deprecated ([#2752](https://github.com/EQEmu/Server/pull/2752)) ([mackal](https://github.com/mackal)) 2023-01-17
|
||||
* Enable C++20 + Fixes + FMT 9.1 ([#2664](https://github.com/EQEmu/Server/pull/2664)) ([Akkadius](https://github.com/Akkadius)) 2022-12-21
|
||||
|
||||
### Code
|
||||
|
||||
* Removed vscode setting ([#2753](https://github.com/EQEmu/Server/pull/2753)) ([xackery](https://github.com/xackery)) 2023-01-17
|
||||
|
||||
### Code Cleanup
|
||||
|
||||
* Add Validation to varchar number item fields. ([#2241](https://github.com/EQEmu/Server/pull/2241)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||
* Cleanup #kick message. ([#2164](https://github.com/EQEmu/Server/pull/2164)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
||||
* Cleanup Haste references and Lua API calls for unsigned to signed. ([#2240](https://github.com/EQEmu/Server/pull/2240)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||
* Cleanup code smells and compiler warnings in common/shareddb ([#2270](https://github.com/EQEmu/Server/pull/2270)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||
* Cleanup magic numbers ([#2662](https://github.com/EQEmu/Server/pull/2662)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-20
|
||||
* Cleanup spell and max level bucket logic. ([#2181](https://github.com/EQEmu/Server/pull/2181)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
||||
* Extra Space in NPC::AISpellsList(). ([#2555](https://github.com/EQEmu/Server/pull/2555)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
||||
* Fix unintended copies in zone/zonedb.cpp by changing auto to auto& ([#2271](https://github.com/EQEmu/Server/pull/2271)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||
* Make use of std::abs where possible. ([#2739](https://github.com/EQEmu/Server/pull/2739)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||
* Merge Client::Attack and Bot::Attack into Mob::Attack ([#2756](https://github.com/EQEmu/Server/pull/2756)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
||||
* Move Client::Undye() to client.cpp from #path Command. ([#2188](https://github.com/EQEmu/Server/pull/2188)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-21
|
||||
* Possible issues with variable/parameter name equality. ([#2161](https://github.com/EQEmu/Server/pull/2161)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
||||
* Quest API push methods using invalid types. ([#2172](https://github.com/EQEmu/Server/pull/2172)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-16
|
||||
* Remove Unused EQEMU_DEPOP_INVALIDATES_CACHE ([#2292](https://github.com/EQEmu/Server/pull/2292)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
||||
* Remove this-> in code where its implied ([#2088](https://github.com/EQEmu/Server/pull/2088)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
|
||||
* Remove unused basic_functions.h ([#2729](https://github.com/EQEmu/Server/pull/2729)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
||||
* Remove unused maxskill.h. ([#2728](https://github.com/EQEmu/Server/pull/2728)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
||||
* Remove unused methods. ([#2171](https://github.com/EQEmu/Server/pull/2171)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
|
||||
* Remove unusued Max Item ID Constant ([#2528](https://github.com/EQEmu/Server/pull/2528)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-08
|
||||
* Remove use of bzero since it is deprecated for memset ([#2295](https://github.com/EQEmu/Server/pull/2295)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
||||
* Resharper Warnings ([#2235](https://github.com/EQEmu/Server/pull/2235)) ([Quintinon](https://github.com/Quintinon)) 2022-06-01
|
||||
* Resolve some warnings in loginserver/world_server.cpp ([#2347](https://github.com/EQEmu/Server/pull/2347)) ([mackal](https://github.com/mackal)) 2022-07-31
|
||||
* Rework Lua QuestReward to not use try/catch blocks ([#2417](https://github.com/EQEmu/Server/pull/2417)) ([mackal](https://github.com/mackal)) 2022-09-03
|
||||
* Send eqstr message in AddAAPoints ([#2507](https://github.com/EQEmu/Server/pull/2507)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||
* Update to EQEmu #2253 to clean up message strings ([#2279](https://github.com/EQEmu/Server/pull/2279)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
||||
* Zone Data Loading Refactor ([#2388](https://github.com/EQEmu/Server/pull/2388)) ([Akkadius](https://github.com/Akkadius)) 2022-09-01
|
||||
|
||||
### Commands
|
||||
|
||||
* #bind Typo. ([#2196](https://github.com/EQEmu/Server/pull/2196)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
* #ginfo Cleanup. ([#1955](https://github.com/EQEmu/Server/pull/1955)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
|
||||
* #reload Command Overhaul. ([#2162](https://github.com/EQEmu/Server/pull/2162)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
||||
* #reload level_mods could cause Non-Booted zones to crash. ([#2670](https://github.com/EQEmu/Server/pull/2670)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-24
|
||||
* Add #bugs Command. ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Add #feature Command. ([#2142](https://github.com/EQEmu/Server/pull/2142)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Add #findcharacter Command. ([#2692](https://github.com/EQEmu/Server/pull/2692)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
||||
* Add #findrecipe and #viewrecipe Commands. ([#2401](https://github.com/EQEmu/Server/pull/2401)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-31
|
||||
* Add #setanon Command ([#2690](https://github.com/EQEmu/Server/pull/2690)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
||||
* Add #suspendmulti Command. ([#2619](https://github.com/EQEmu/Server/pull/2619)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||
* Add BestZ and Region Data to #loc ([#2245](https://github.com/EQEmu/Server/pull/2245)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-05
|
||||
* Add additional #peqzone functionality. ([#2085](https://github.com/EQEmu/Server/pull/2085)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
|
||||
* Add max_hp back to #modifynpcstat command. ([#2638](https://github.com/EQEmu/Server/pull/2638)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
|
||||
* Adding movespeed to #showstats output ([#2596](https://github.com/EQEmu/Server/pull/2596)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
|
||||
* Bug fix for #logs command. ([#2008](https://github.com/EQEmu/Server/pull/2008)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
|
||||
* Cleanup #ai Command. ([#1980](https://github.com/EQEmu/Server/pull/1980)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
|
||||
* Cleanup #appearanceeffects Command. ([#2777](https://github.com/EQEmu/Server/pull/2777)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||
* Cleanup #attack Command. ([#2103](https://github.com/EQEmu/Server/pull/2103)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||
* Cleanup #ban, #ipban, #flag, #kick, #setlsinfo, and #setpass Commands. ([#2104](https://github.com/EQEmu/Server/pull/2104)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||
* Cleanup #chat Command. ([#2581](https://github.com/EQEmu/Server/pull/2581)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Cleanup #corpsefix Command. ([#2197](https://github.com/EQEmu/Server/pull/2197)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Cleanup #cvs Command. ([#2153](https://github.com/EQEmu/Server/pull/2153)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||
* Cleanup #date Command. ([#2228](https://github.com/EQEmu/Server/pull/2228)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
||||
* Cleanup #dbspawn2 Command. ([#2493](https://github.com/EQEmu/Server/pull/2493)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||
* Cleanup #delacct Command. ([#2567](https://github.com/EQEmu/Server/pull/2567)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Cleanup #depop Command. ([#2536](https://github.com/EQEmu/Server/pull/2536)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Cleanup #depopzone Command. ([#2537](https://github.com/EQEmu/Server/pull/2537)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Cleanup #devtools Command. ([#2538](https://github.com/EQEmu/Server/pull/2538)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Cleanup #doanim Command. ([#2540](https://github.com/EQEmu/Server/pull/2540)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Cleanup #emote Command. ([#2535](https://github.com/EQEmu/Server/pull/2535)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Cleanup #emotesearch and #emoteview Command. ([#2494](https://github.com/EQEmu/Server/pull/2494)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||
* Cleanup #emptyinventory Command. ([#2219](https://github.com/EQEmu/Server/pull/2219)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
|
||||
* Cleanup #findaliases and #help Commands. ([#2204](https://github.com/EQEmu/Server/pull/2204)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Cleanup #findclass and #findrace Commands. ([#2211](https://github.com/EQEmu/Server/pull/2211)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Cleanup #flagedit Command. ([#1968](https://github.com/EQEmu/Server/pull/1968)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #freeze and #unfreeze Commands. ([#2102](https://github.com/EQEmu/Server/pull/2102)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||
* Cleanup #gassign Command. ([#2101](https://github.com/EQEmu/Server/pull/2101)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #gearup Command. ([#2589](https://github.com/EQEmu/Server/pull/2589)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Cleanup #getvariable Command. ([#2100](https://github.com/EQEmu/Server/pull/2100)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||
* Cleanup #guild Command ([#2693](https://github.com/EQEmu/Server/pull/2693)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-04
|
||||
* Cleanup #hatelist Command. ([#1976](https://github.com/EQEmu/Server/pull/1976)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #heromodel Command. ([#2566](https://github.com/EQEmu/Server/pull/2566)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Cleanup #kill Command. ([#2195](https://github.com/EQEmu/Server/pull/2195)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
* Cleanup #level Command. ([#2203](https://github.com/EQEmu/Server/pull/2203)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Cleanup #logs Command. ([#1969](https://github.com/EQEmu/Server/pull/1969)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #makepet Command. ([#2105](https://github.com/EQEmu/Server/pull/2105)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #modifynpcstat Command. ([#2499](https://github.com/EQEmu/Server/pull/2499)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
||||
* Cleanup #motd Command. ([#2190](https://github.com/EQEmu/Server/pull/2190)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
* Cleanup #name Command. ([#1977](https://github.com/EQEmu/Server/pull/1977)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #netstats Command. ([#1970](https://github.com/EQEmu/Server/pull/1970)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #npcedit Command. ([#2582](https://github.com/EQEmu/Server/pull/2582)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Cleanup #npcedit, #lastname, #title, and #titlesuffix Commands. ([#2215](https://github.com/EQEmu/Server/pull/2215)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
||||
* Cleanup #npceditmass command. ([#1957](https://github.com/EQEmu/Server/pull/1957)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
|
||||
* Cleanup #npcemote Command. ([#2106](https://github.com/EQEmu/Server/pull/2106)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #npcloot Command. ([#1974](https://github.com/EQEmu/Server/pull/1974)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
|
||||
* Cleanup #npcsay and #npcshout Commands. ([#2107](https://github.com/EQEmu/Server/pull/2107)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #npcspecialattk Command. ([#2108](https://github.com/EQEmu/Server/pull/2108)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #npctype_cache Command. ([#2109](https://github.com/EQEmu/Server/pull/2109)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #npctypespawn Command. ([#2110](https://github.com/EQEmu/Server/pull/2110)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #nudge Command. ([#2220](https://github.com/EQEmu/Server/pull/2220)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
|
||||
* Cleanup #oocmute Command. ([#2191](https://github.com/EQEmu/Server/pull/2191)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Cleanup #opcode Command. ([#2547](https://github.com/EQEmu/Server/pull/2547)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||
* Cleanup #profanity Command. ([#2113](https://github.com/EQEmu/Server/pull/2113)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #push Command. ([#2114](https://github.com/EQEmu/Server/pull/2114)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #qglobal Command. ([#2115](https://github.com/EQEmu/Server/pull/2115)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #randomizefeatures Command. ([#2118](https://github.com/EQEmu/Server/pull/2118)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #refreshgroup Command. ([#2119](https://github.com/EQEmu/Server/pull/2119)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadaa Command. ([#2120](https://github.com/EQEmu/Server/pull/2120)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadallrules Command. ([#2121](https://github.com/EQEmu/Server/pull/2121)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadlevelmods Command. ([#2122](https://github.com/EQEmu/Server/pull/2122)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadmerchants Command. ([#2123](https://github.com/EQEmu/Server/pull/2123)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadperlexportsettings Command. ([#2124](https://github.com/EQEmu/Server/pull/2124)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadrulesworld Command. ([#2128](https://github.com/EQEmu/Server/pull/2128)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadstatic Command. ([#2130](https://github.com/EQEmu/Server/pull/2130)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadtitles Command. ([#2125](https://github.com/EQEmu/Server/pull/2125)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadtraps Command. ([#2126](https://github.com/EQEmu/Server/pull/2126)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadworld and #repop Command. ([#2127](https://github.com/EQEmu/Server/pull/2127)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #reloadzps Command. ([#2129](https://github.com/EQEmu/Server/pull/2129)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #resetaa Command. ([#2132](https://github.com/EQEmu/Server/pull/2132)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #resetaa_timer Command. ([#2131](https://github.com/EQEmu/Server/pull/2131)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #resetdisc_timer Command. ([#2133](https://github.com/EQEmu/Server/pull/2133)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #revoke Command. ([#2134](https://github.com/EQEmu/Server/pull/2134)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #roambox Command. ([#2135](https://github.com/EQEmu/Server/pull/2135)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #rules Command. ([#2593](https://github.com/EQEmu/Server/pull/2593)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
|
||||
* Cleanup #save Command. ([#2136](https://github.com/EQEmu/Server/pull/2136)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #scale Command. ([#2591](https://github.com/EQEmu/Server/pull/2591)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
|
||||
* Cleanup #scribespell and #scribespells Commands. ([#2534](https://github.com/EQEmu/Server/pull/2534)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Cleanup #sensetrap Command. ([#2137](https://github.com/EQEmu/Server/pull/2137)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #serverinfo Command. ([#2568](https://github.com/EQEmu/Server/pull/2568)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Cleanup #serverrules Command. ([#2139](https://github.com/EQEmu/Server/pull/2139)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #setlanguage Command. ([#2464](https://github.com/EQEmu/Server/pull/2464)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-13
|
||||
* Cleanup #setskillall Command. ([#1992](https://github.com/EQEmu/Server/pull/1992)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
|
||||
* Cleanup #shownpcgloballoot and #showzonegloballoot Command. ([#2141](https://github.com/EQEmu/Server/pull/2141)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #showskills Command. ([#1994](https://github.com/EQEmu/Server/pull/1994)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
|
||||
* Cleanup #spawneditmass Command. ([#2229](https://github.com/EQEmu/Server/pull/2229)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||
* Cleanup #spawnfix Command. ([#2143](https://github.com/EQEmu/Server/pull/2143)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #spawnstatus Command. ([#2144](https://github.com/EQEmu/Server/pull/2144)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #summon Command. ([#2145](https://github.com/EQEmu/Server/pull/2145)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
||||
* Cleanup #summonburiedplayercorpse Command. ([#2146](https://github.com/EQEmu/Server/pull/2146)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #suspend Command. ([#2564](https://github.com/EQEmu/Server/pull/2564)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Cleanup #task Command. ([#2071](https://github.com/EQEmu/Server/pull/2071)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-14
|
||||
* Cleanup #time and #timezone Command. ([#2147](https://github.com/EQEmu/Server/pull/2147)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #timers Command. ([#2562](https://github.com/EQEmu/Server/pull/2562)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Cleanup #trapinfo Command. ([#2148](https://github.com/EQEmu/Server/pull/2148)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #ucs Command. ([#2149](https://github.com/EQEmu/Server/pull/2149)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Cleanup #undye and #undyeme Commands. ([#1966](https://github.com/EQEmu/Server/pull/1966)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #unscribespell Command. ([#1998](https://github.com/EQEmu/Server/pull/1998)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
|
||||
* Cleanup #untraindisc Command. ([#1996](https://github.com/EQEmu/Server/pull/1996)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
|
||||
* Cleanup #version Command. ([#1967](https://github.com/EQEmu/Server/pull/1967)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Cleanup #worldwide command. ([#2021](https://github.com/EQEmu/Server/pull/2021)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
|
||||
* Cleanup #xtargets Command. ([#2545](https://github.com/EQEmu/Server/pull/2545)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||
* Cleanup #zone and #zoneinstance Commands. ([#2202](https://github.com/EQEmu/Server/pull/2202)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Command Status Reload and Helper Method ([#2377](https://github.com/EQEmu/Server/pull/2377)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
||||
* Consolidate #lock and #unlock Commands into #serverlock. ([#2193](https://github.com/EQEmu/Server/pull/2193)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
* Fix #copycharacter command crash ([#2446](https://github.com/EQEmu/Server/pull/2446)) ([Akkadius](https://github.com/Akkadius)) 2022-09-25
|
||||
* Fix #killallnpcs from crashing ([#2037](https://github.com/EQEmu/Server/pull/2037)) ([Akkadius](https://github.com/Akkadius)) 2022-03-07
|
||||
* Fix Flymode Command Help Prompt ([#2669](https://github.com/EQEmu/Server/pull/2669)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-23
|
||||
* Fix typos in #ban and #ipban Commands. ([#2209](https://github.com/EQEmu/Server/pull/2209)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
|
||||
* Make #damage require a target ([#2426](https://github.com/EQEmu/Server/pull/2426)) ([hgtw](https://github.com/hgtw)) 2022-09-05
|
||||
* Nested Command Aliases ([#2636](https://github.com/EQEmu/Server/pull/2636)) ([Akkadius](https://github.com/Akkadius)) 2022-12-15
|
||||
* Remove #guildapprove, #guildcreate, and #guildlist Commands ([#2775](https://github.com/EQEmu/Server/pull/2775)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||
* Remove #iteminfo Command. ([#2565](https://github.com/EQEmu/Server/pull/2565)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Remove #profiledump and #profilereset Commands. ([#2546](https://github.com/EQEmu/Server/pull/2546)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||
* Remove #undyeme Command. ([#2776](https://github.com/EQEmu/Server/pull/2776)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||
* Remove unused #bestz and #pf Commands. ([#2112](https://github.com/EQEmu/Server/pull/2112)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Remove unused/broken #deletegraveyard and #setgraveyard Commands. ([#2198](https://github.com/EQEmu/Server/pull/2198)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
|
||||
### Diawind
|
||||
|
||||
* Plus sign markdown fix ([#2727](https://github.com/EQEmu/Server/pull/2727)) ([Akkadius](https://github.com/Akkadius)) 2023-01-12
|
||||
|
||||
### Feature
|
||||
|
||||
* AA Cap Limit ([#2423](https://github.com/EQEmu/Server/pull/2423)) ([fryguy503](https://github.com/fryguy503)) 2022-10-13
|
||||
* Add "Keeps Sold Items" Flag to NPCs ([#2671](https://github.com/EQEmu/Server/pull/2671)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
||||
* Add Experience Gain Toggle. ([#2676](https://github.com/EQEmu/Server/pull/2676)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-30
|
||||
* Add Guild Chat to Console. ([#2387](https://github.com/EQEmu/Server/pull/2387)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
||||
* Add Hate Override for Heals ([#2485](https://github.com/EQEmu/Server/pull/2485)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-14
|
||||
* Add Rule to Disable Group EXP Modifier. ([#2741](https://github.com/EQEmu/Server/pull/2741)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||
* Add Support for "Show Mine Only" Filters ([#2484](https://github.com/EQEmu/Server/pull/2484)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||
* Add Type 49545 to Spell Resistrictions ([#2436](https://github.com/EQEmu/Server/pull/2436)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
|
||||
* Add humanoid and non-wielded restrictions to pick pocket ([#2276](https://github.com/EQEmu/Server/pull/2276)) ([noudess](https://github.com/noudess)) 2022-07-03
|
||||
* Add player /inspect quest event ([#2508](https://github.com/EQEmu/Server/pull/2508)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||
* Add special ability to block /open ([#2506](https://github.com/EQEmu/Server/pull/2506)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||
* Allow Focus Effects to be Filtered out. ([#2447](https://github.com/EQEmu/Server/pull/2447)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
|
||||
* Allow pets to zone with permanent (buffdurationformula 50) buffs to maintain them through zone transitions ([#2035](https://github.com/EQEmu/Server/pull/2035)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
||||
* Bind Wound and Forage while mounted. ([#2257](https://github.com/EQEmu/Server/pull/2257)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
||||
* Change #scribespells to be aware of spellgroups & ranks ([#2501](https://github.com/EQEmu/Server/pull/2501)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
|
||||
* Change GetSkillDmgAmt to int32 ([#2364](https://github.com/EQEmu/Server/pull/2364)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-10
|
||||
* Change Lifetap Emotes to be filterable. ([#2454](https://github.com/EQEmu/Server/pull/2454)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-29
|
||||
* Change Mana Costs to use Signed Int ([#2384](https://github.com/EQEmu/Server/pull/2384)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-21
|
||||
* Change mana_used to int32 ([#2321](https://github.com/EQEmu/Server/pull/2321)) ([Aeadoin](https://github.com/Aeadoin)) 2022-07-30
|
||||
* Client Checksum Verification (Resubmit old 1678) ([#1922](https://github.com/EQEmu/Server/pull/1922)) ([noudess](https://github.com/noudess)) 2022-03-07
|
||||
* EQ2-style implied targeting for spells. ([#2032](https://github.com/EQEmu/Server/pull/2032)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
||||
* Faction Association ([#2408](https://github.com/EQEmu/Server/pull/2408)) ([mackal](https://github.com/mackal)) 2022-09-03
|
||||
* GM State Change Persistance ([#2328](https://github.com/EQEmu/Server/pull/2328)) ([fryguy503](https://github.com/fryguy503)) 2022-07-31
|
||||
* Implement Heroic Strikethrough to NPCs ([#2395](https://github.com/EQEmu/Server/pull/2395)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-31
|
||||
* Implement OP_CashReward ([#2307](https://github.com/EQEmu/Server/pull/2307)) ([mackal](https://github.com/mackal)) 2022-07-15
|
||||
* Instance Version Specific Experience Modifiers ([#2376](https://github.com/EQEmu/Server/pull/2376)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
||||
* NPCs with bows and arrows do ranged attacks ([#2322](https://github.com/EQEmu/Server/pull/2322)) ([mackal](https://github.com/mackal)) 2022-07-30
|
||||
* Soft Delete Bots on Character Soft Delete ([#2467](https://github.com/EQEmu/Server/pull/2467)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||
* Spell Ranks will now work with AllowSpellMemorizeFromItem Rule ([#2475](https://github.com/EQEmu/Server/pull/2475)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||
* Update HateMod used by SPA 114 to Int32. ([#2428](https://github.com/EQEmu/Server/pull/2428)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-08
|
||||
|
||||
### Fixes
|
||||
|
||||
* #npcstats command displaying incorrect faction ([#2710](https://github.com/EQEmu/Server/pull/2710)) ([noudess](https://github.com/noudess)) 2023-01-08
|
||||
* #peqzone no longer bypass Handle_OP_ZoneChange ([#2063](https://github.com/EQEmu/Server/pull/2063)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-19
|
||||
* #scribespells triggered error on mysql keyword rank ([#2779](https://github.com/EQEmu/Server/pull/2779)) ([noudess](https://github.com/noudess)) 2023-01-21
|
||||
* #tune command various fixes ([#2046](https://github.com/EQEmu/Server/pull/2046)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-11
|
||||
* Add Complete Heal Spell back to IsCompleteHealSpell Method ([#2722](https://github.com/EQEmu/Server/pull/2722)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
|
||||
* Add SE_MakeDrunk to avoid error message. ([#2601](https://github.com/EQEmu/Server/pull/2601)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||
* Add omitted function call in UCS ([#2768](https://github.com/EQEmu/Server/pull/2768)) ([Valorith](https://github.com/Valorith)) 2023-01-20
|
||||
* Add required distance to CoTH before aggro wipe ([#2253](https://github.com/EQEmu/Server/pull/2253)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
||||
* Adjustment for nullptr crash ([#2232](https://github.com/EQEmu/Server/pull/2232)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
|
||||
* Alleviate some lag with crosszone/worldwide spell casting. ([#2016](https://github.com/EQEmu/Server/pull/2016)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-21
|
||||
* Allow High Level Spells to be Unmemorized. ([#2641](https://github.com/EQEmu/Server/pull/2641)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
||||
* Allow Songs to be scribed from scrolls ([#2460](https://github.com/EQEmu/Server/pull/2460)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-12
|
||||
* AltCurrencySelectItemReply_Struct was not handled correctly. ([#2702](https://github.com/EQEmu/Server/pull/2702)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-04
|
||||
* Any use of TempName left old clean_name. ([#1946](https://github.com/EQEmu/Server/pull/1946)) ([noudess](https://github.com/noudess)) 2022-01-26
|
||||
* Avoid erase in discord queue range loop ([#2411](https://github.com/EQEmu/Server/pull/2411)) ([hgtw](https://github.com/hgtw)) 2022-09-03
|
||||
* Bandolier didn't recognize source weapon on cursor ([#2026](https://github.com/EQEmu/Server/pull/2026)) ([noudess](https://github.com/noudess)) 2022-03-07
|
||||
* Bard Invisible causing display issues. ([#2067](https://github.com/EQEmu/Server/pull/2067)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-01
|
||||
* Bard update fixes 1 ([#1982](https://github.com/EQEmu/Server/pull/1982)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-09
|
||||
* Bazaar Search MYSQL Error ([#2252](https://github.com/EQEmu/Server/pull/2252)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
|
||||
* Blocked spells max spell id increased ([#2207](https://github.com/EQEmu/Server/pull/2207)) ([Isaaru](https://github.com/Isaaru)) 2022-05-25
|
||||
* Boats should never get FixZ'd ([#2246](https://github.com/EQEmu/Server/pull/2246)) ([noudess](https://github.com/noudess)) 2022-07-02
|
||||
* Clamp Item Ldon Sell Back Rates. ([#2592](https://github.com/EQEmu/Server/pull/2592)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-30
|
||||
* Clear title/suffix bug fix. ([#2068](https://github.com/EQEmu/Server/pull/2068)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
|
||||
* Correct (probably) unintended bitwise AND instead of logical AND ([#2239](https://github.com/EQEmu/Server/pull/2239)) ([Quintinon](https://github.com/Quintinon)) 2022-06-02
|
||||
* Correct type signed/unsigned int when reading item from database in shareddb ([#2269](https://github.com/EQEmu/Server/pull/2269)) ([Quintinon](https://github.com/Quintinon)) 2022-06-15
|
||||
* Data Bucket Permanent Duration String ([#2624](https://github.com/EQEmu/Server/pull/2624)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||
* Delete NpcType Struct returned by Bot::CreateDefaultNPCTypeStructForBot() when unused ([#2267](https://github.com/EQEmu/Server/pull/2267)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
|
||||
* Do not allow /open to be used on traps or auras, causes crash ([#1951](https://github.com/EQEmu/Server/pull/1951)) ([KayenEQ](https://github.com/KayenEQ)) 2022-01-30
|
||||
* Doors::GetSize() Perl Croak Typo. ([#2027](https://github.com/EQEmu/Server/pull/2027)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
|
||||
* EVENT_ENTER_AREA/EVENT_LEAVE_AREA. ([#2698](https://github.com/EQEmu/Server/pull/2698)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
||||
* Edge case AA reset timer issue fixes ([#1995](https://github.com/EQEmu/Server/pull/1995)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-14
|
||||
* Fix #door Save ([#2699](https://github.com/EQEmu/Server/pull/2699)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
||||
* Fix #findaa and GetAAName(). ([#2774](https://github.com/EQEmu/Server/pull/2774)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||
* Fix #zone 0. ([#2691](https://github.com/EQEmu/Server/pull/2691)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Fix Aug Clicks where item has no click effect. ([#2725](https://github.com/EQEmu/Server/pull/2725)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-12
|
||||
* Fix Bot "Failed to Load" Messages. ([#2719](https://github.com/EQEmu/Server/pull/2719)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
|
||||
* Fix Bot Group Loading ([#2780](https://github.com/EQEmu/Server/pull/2780)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
|
||||
* Fix Bot ^spellsettingsadd command ([#2603](https://github.com/EQEmu/Server/pull/2603)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
|
||||
* Fix Duplicate Silent Saylink Messages ([#2386](https://github.com/EQEmu/Server/pull/2386)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
||||
* Fix EntityList::GetBotListByCharacterID() ([#2569](https://github.com/EQEmu/Server/pull/2569)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Fix Flag Updating with SetGMStatus() in Lua. ([#2554](https://github.com/EQEmu/Server/pull/2554)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
||||
* Fix Group XP not working. ([#2748](https://github.com/EQEmu/Server/pull/2748)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
|
||||
* Fix HP Regen Per Second. ([#2206](https://github.com/EQEmu/Server/pull/2206)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-25
|
||||
* Fix IDFile Crash with spaces or invalid data. ([#2597](https://github.com/EQEmu/Server/pull/2597)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||
* Fix IP Exemptions. ([#2189](https://github.com/EQEmu/Server/pull/2189)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
||||
* Fix Instance Repository ([#2598](https://github.com/EQEmu/Server/pull/2598)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||
* Fix Legacy Combat Lua Script ([#2226](https://github.com/EQEmu/Server/pull/2226)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
|
||||
* Fix MovePC in #zone and #zoneinstance Commands. ([#2236](https://github.com/EQEmu/Server/pull/2236)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
||||
* Fix NPC Reference in EVENT_SPAWN ([#2712](https://github.com/EQEmu/Server/pull/2712)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-08
|
||||
* Fix ST_TargetsTarget Spells with Restrictions ([#2746](https://github.com/EQEmu/Server/pull/2746)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
||||
* Fix Silent Saylinks Sending Message to Others. ([#2389](https://github.com/EQEmu/Server/pull/2389)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
||||
* Fix Spell Bucket and Spell Global Logic Checks. ([#2285](https://github.com/EQEmu/Server/pull/2285)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
||||
* Fix Spellinfo Command to work with SpellIDs above int16 ([#2437](https://github.com/EQEmu/Server/pull/2437)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
|
||||
* Fix Strings::Money Missing Conditions. ([#2383](https://github.com/EQEmu/Server/pull/2383)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-21
|
||||
* Fix Swarm Pet Flurry/Rampages Messages ([#2444](https://github.com/EQEmu/Server/pull/2444)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
|
||||
* Fix bot compile locking client on server enter. ([#2210](https://github.com/EQEmu/Server/pull/2210)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
|
||||
* Fix bot guild removal. ([#2194](https://github.com/EQEmu/Server/pull/2194)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||
* Fix bots equipping augments. ([#2772](https://github.com/EQEmu/Server/pull/2772)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
||||
* Fix case-sensitivity in #suspend Command. ([#2613](https://github.com/EQEmu/Server/pull/2613)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
|
||||
* Fix duplicate and missing messages due to innate in spells ([#2170](https://github.com/EQEmu/Server/pull/2170)) ([noudess](https://github.com/noudess)) 2022-05-20
|
||||
* Fix empty spawned merchants ([#2275](https://github.com/EQEmu/Server/pull/2275)) ([hgtw](https://github.com/hgtw)) 2022-06-28
|
||||
* Fix for Bot command casting ([#1990](https://github.com/EQEmu/Server/pull/1990)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-12
|
||||
* Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs ([#1986](https://github.com/EQEmu/Server/pull/1986)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
|
||||
* Fix for being able to skill up on corspe. ([#2058](https://github.com/EQEmu/Server/pull/2058)) ([noudess](https://github.com/noudess)) 2022-03-19
|
||||
* Fix for castspell command ([#2010](https://github.com/EQEmu/Server/pull/2010)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-18
|
||||
* Fix issue where #advnpcspawn addspawn does not add spawn sometimes. ([#2247](https://github.com/EQEmu/Server/pull/2247)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
|
||||
* Fix issue where you can set your title to titles you don't have. ([#1917](https://github.com/EQEmu/Server/pull/1917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-30
|
||||
* Fix issue with Bot::LoadAndSpawnAllZonedBots. ([#2733](https://github.com/EQEmu/Server/pull/2733)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||
* Fix issue with mobs summoning PCs into ceilings ([#1921](https://github.com/EQEmu/Server/pull/1921)) ([noudess](https://github.com/noudess)) 2022-01-30
|
||||
* Fix loading world shared task state ([#2398](https://github.com/EQEmu/Server/pull/2398)) ([hgtw](https://github.com/hgtw)) 2022-08-28
|
||||
* Fix luamod GetExperienceForKill return value ([Cole-SoD](https://github.com/Cole-SoD)) 2023-01-12
|
||||
* Fix memory leak in ucs ([#2409](https://github.com/EQEmu/Server/pull/2409)) ([hgtw](https://github.com/hgtw)) 2022-09-03
|
||||
* Fix miscellaneous memory leaks related to EQApplicationPacket and it's pBuffer ([#2262](https://github.com/EQEmu/Server/pull/2262)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||
* Fix null pointer crash on zones that have not booted a zone yet with #reload commands or anything that calls GetZoneDescription ([#2231](https://github.com/EQEmu/Server/pull/2231)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
|
||||
* Fix possible crash in ProcessSpecialAbilities. ([#2630](https://github.com/EQEmu/Server/pull/2630)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||
* Fix possible crash with zone name methods. ([#2055](https://github.com/EQEmu/Server/pull/2055)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
|
||||
* Fix possible issue where variables have the same name. ([#2156](https://github.com/EQEmu/Server/pull/2156)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||
* Fix quest::updatespawntimer() Perl croak. ([#1947](https://github.com/EQEmu/Server/pull/1947)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-26
|
||||
* Fix recipient sound (vtell) on non-player races ([#2066](https://github.com/EQEmu/Server/pull/2066)) ([noudess](https://github.com/noudess)) 2022-04-02
|
||||
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
||||
* Fix stack leaks in Lua events #2254 ([hgtw](https://github.com/hgtw)) 2022-06-09
|
||||
* Fix trading with bots when in an illusion. ([#2645](https://github.com/EQEmu/Server/pull/2645)) ([nytmyr](https://github.com/nytmyr)) 2022-12-15
|
||||
* Fix two invalid data accesses in zone/client.cpp ([#2238](https://github.com/EQEmu/Server/pull/2238)) ([Quintinon](https://github.com/Quintinon)) 2022-06-07
|
||||
* Fixed Spell Logic for Bot Nukes ([#2481](https://github.com/EQEmu/Server/pull/2481)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
||||
* Fixed message on promote/demote permissions check. ([#2700](https://github.com/EQEmu/Server/pull/2700)) ([Valorith](https://github.com/Valorith)) 2023-01-02
|
||||
* Fixed several instances of incorrect comparision - & executes after == ([#2025](https://github.com/EQEmu/Server/pull/2025)) ([noudess](https://github.com/noudess)) 2022-03-07
|
||||
* Force NPCs to respect special ability 24 and 50 when set on player pets ([#2059](https://github.com/EQEmu/Server/pull/2059)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-16
|
||||
* Free return value of ZoneDatabase::LoadTraderItemWithCharges() ([#2264](https://github.com/EQEmu/Server/pull/2264)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
|
||||
* Hacker_Str was causing sql errors - Non Escaped ([#2251](https://github.com/EQEmu/Server/pull/2251)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
|
||||
* Handle memory leaks from return value of Client::GetTraderItems() ([#2266](https://github.com/EQEmu/Server/pull/2266)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
||||
* Handle_OP_AugmentItem could cause Zone crash ([#2750](https://github.com/EQEmu/Server/pull/2750)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
|
||||
* HasPet() Zone Crashes ([#2744](https://github.com/EQEmu/Server/pull/2744)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
||||
* Illusions will now properly display armor to other clients when they zone in. ([#1958](https://github.com/EQEmu/Server/pull/1958)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-04
|
||||
* Instrument Mods should not affect spells that change model size. ([#2072](https://github.com/EQEmu/Server/pull/2072)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-13
|
||||
* Invisible will display as dropped now on air pets when they attack. ([#2042](https://github.com/EQEmu/Server/pull/2042)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
|
||||
* IsDamage test for lifetap was not complete. ([#2213](https://github.com/EQEmu/Server/pull/2213)) ([noudess](https://github.com/noudess)) 2022-05-27
|
||||
* Limit merchant temp item list to zone and instance ([#2346](https://github.com/EQEmu/Server/pull/2346)) ([mackal](https://github.com/mackal)) 2022-07-31
|
||||
* Lua GetBlockNextSpell() no return. ([#2151](https://github.com/EQEmu/Server/pull/2151)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Make Perl TakeMoneyFromPP int64 ([#2158](https://github.com/EQEmu/Server/pull/2158)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
||||
* Missing break ([#2031](https://github.com/EQEmu/Server/pull/2031)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-04
|
||||
* Move EVENT_SPAWN for adding NPCs back to original spot, also add NPCs… ([#2749](https://github.com/EQEmu/Server/pull/2749)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-17
|
||||
* NPC Constructor was passing hp_regen_per_second out of order to Mob(). ([#2681](https://github.com/EQEmu/Server/pull/2681)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-29
|
||||
* NPC::CountItem and Corpse::CountItem 0 Charge Item Fix. ([#1959](https://github.com/EQEmu/Server/pull/1959)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-04
|
||||
* NPC::GetNPCStat has no default return. ([#2150](https://github.com/EQEmu/Server/pull/2150)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* NPCs were getting weapon proc added twice ([#2277](https://github.com/EQEmu/Server/pull/2277)) ([noudess](https://github.com/noudess)) 2022-07-07
|
||||
* Objects::GetTiltX() and Objects::GetTiltY() Perl Croak Typos. ([#2028](https://github.com/EQEmu/Server/pull/2028)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
|
||||
* PR 1982 ([#1985](https://github.com/EQEmu/Server/pull/1985)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
|
||||
* PR 2032 would lock client on casting fail as written ([#2038](https://github.com/EQEmu/Server/pull/2038)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
|
||||
* Remove StringUtilTest::EscapeStringMemoryTest ([#2310](https://github.com/EQEmu/Server/pull/2310)) ([mackal](https://github.com/mackal)) 2022-07-15
|
||||
* Remove Unnecessary Attack Log ([#2643](https://github.com/EQEmu/Server/pull/2643)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
||||
* Remove unnecessary log messages. ([#2642](https://github.com/EQEmu/Server/pull/2642)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
||||
* Removed Lua Event Argument Dispatch. ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
|
||||
* Resolve Warning due to Virtual Mob Method GetInv() ([#2650](https://github.com/EQEmu/Server/pull/2650)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-19
|
||||
* Resolve XP Calculation Bug introduced w/ recent Rule addition ([#2703](https://github.com/EQEmu/Server/pull/2703)) ([Valorith](https://github.com/Valorith)) 2023-01-07
|
||||
* Resolve logic error in Raid::QueueClients ([#2404](https://github.com/EQEmu/Server/pull/2404)) ([mackal](https://github.com/mackal)) 2022-09-01
|
||||
* Resolve subroutine redefinition due to bot methods. ([#2117](https://github.com/EQEmu/Server/pull/2117)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Restore missing messages for lifetap and dmg spells. ([#2057](https://github.com/EQEmu/Server/pull/2057)) ([noudess](https://github.com/noudess)) 2022-04-14
|
||||
* Shared Memory Faction Association Typo ([#2419](https://github.com/EQEmu/Server/pull/2419)) ([mackal](https://github.com/mackal)) 2022-09-03
|
||||
* Spell Buckets/Globals SQL Escape. ([#2019](https://github.com/EQEmu/Server/pull/2019)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-26
|
||||
* Spell Buckets/Globals did not allow string-based values. ([#2043](https://github.com/EQEmu/Server/pull/2043)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-09
|
||||
* Stop skill ups on Charmed NPCs. ([#2249](https://github.com/EQEmu/Server/pull/2249)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-10
|
||||
* Summon Companion causing pets to warps away. ([#1972](https://github.com/EQEmu/Server/pull/1972)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-08
|
||||
* Touch Of Vinitras was ignoring pet DT rule ([#2469](https://github.com/EQEmu/Server/pull/2469)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-03
|
||||
* Tradeskill Autocombine MinSkill ([#2260](https://github.com/EQEmu/Server/pull/2260)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
||||
* Tradeskill Item 0 Error ([#2256](https://github.com/EQEmu/Server/pull/2256)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
||||
* Zone Flags Regression ([#2760](https://github.com/EQEmu/Server/pull/2760)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
|
||||
* checking casting_spell_slot before its defined is bad ([#2013](https://github.com/EQEmu/Server/pull/2013)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-20
|
||||
* manifest for db version 9176 had incorrect field name ([#2062](https://github.com/EQEmu/Server/pull/2062)) ([noudess](https://github.com/noudess)) 2022-03-19
|
||||
* quest::MovePCInstance() Arguments Fix. ([#2020](https://github.com/EQEmu/Server/pull/2020)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-27
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Add Bazaar portal discs to SQL ([Akkadius](https://github.com/Akkadius)) 2022-09-05
|
||||
* Add discord_webhooks to server tables ([Akkadius](https://github.com/Akkadius)) 2022-07-03
|
||||
* Blocks are nested too deeply. ([#2689](https://github.com/EQEmu/Server/pull/2689)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Cleanup #questerrors Command. ([#2116](https://github.com/EQEmu/Server/pull/2116)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
||||
* Compiling fails on FMT 9.1 with Bots ([#2665](https://github.com/EQEmu/Server/pull/2665)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-21
|
||||
* Correct database call to point to the content_db connection ([Akkadius](https://github.com/Akkadius)) 2022-06-12
|
||||
* Corrected misnamed Database Query file for Experience Toggle ([#2683](https://github.com/EQEmu/Server/pull/2683)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-31
|
||||
* Faction associations file naming / lock consistency ([Akkadius](https://github.com/Akkadius)) 2022-09-05
|
||||
* Fix DB version merge ([Akkadius](https://github.com/Akkadius)) 2022-05-08
|
||||
* Fix door click crash issue if destination zone doesn't exist ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
* Fix issue with Bot Loading with 0 Health causing buffs to be lost. ([#2552](https://github.com/EQEmu/Server/pull/2552)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-18
|
||||
* Fix lua mod load path ([Akkadius](https://github.com/Akkadius)) 2022-09-29
|
||||
* Fix merge issue ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
||||
* Fix path load ordering for CLI commands ([Akkadius](https://github.com/Akkadius)) 2022-10-16
|
||||
* Fix potential race for crash dumps (Linux) ([Akkadius](https://github.com/Akkadius)) 2022-07-31
|
||||
* Fix regression caused by #2129 ([Akkadius](https://github.com/Akkadius)) 2022-05-09
|
||||
* Flipped positive / negative values for legacy_combat.lua ([Akkadius](https://github.com/Akkadius)) 2022-06-09
|
||||
* Force collation on conversion script ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
||||
* Instances Repository Fix ([#2576](https://github.com/EQEmu/Server/pull/2576)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||
* Login Server failing to compile on Windows. ([#2758](https://github.com/EQEmu/Server/pull/2758)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
|
||||
* Lua Parser Needs Lua_ItemInst ([#2696](https://github.com/EQEmu/Server/pull/2696)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Make sure we have a proper split size before assuming we can split it ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
* Move discord_webhooks to state tables because we don't want webhooks being exported ([Akkadius](https://github.com/Akkadius)) 2022-07-03
|
||||
* Possible windows compile fix ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||
* Possible windows compile fix take 2 ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||
* Remove appveyor fetch bots ([Akkadius](https://github.com/Akkadius)) 2023-01-21
|
||||
* Remove expansion field from account for those who have it ([#2357](https://github.com/EQEmu/Server/pull/2357)) ([Akkadius](https://github.com/Akkadius)) 2022-08-01
|
||||
* Resolve Zone Crashing when grouped with Bots. ([#2747](https://github.com/EQEmu/Server/pull/2747)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-16
|
||||
* Resolve issue with Bot Casting after zoning. ([#2617](https://github.com/EQEmu/Server/pull/2617)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||
* Return weather_type_map ([Akkadius](https://github.com/Akkadius)) 2022-10-14
|
||||
* SQL Update ([Akkadius](https://github.com/Akkadius)) 2022-07-31
|
||||
* Shared Memory Protection Fixes ([Akkadius](https://github.com/Akkadius)) 2022-07-27
|
||||
* Windows compile fix take 3 (final) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||
* fix manifest ([Akkadius](https://github.com/Akkadius)) 2022-07-16
|
||||
|
||||
### Logging
|
||||
|
||||
* Add stack trace in code paths that shouldn't occur ([#2453](https://github.com/EQEmu/Server/pull/2453)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
||||
* Cleanup AI Logging Events ([#2615](https://github.com/EQEmu/Server/pull/2615)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
||||
* Fix log messages to final damage values ([#2056](https://github.com/EQEmu/Server/pull/2056)) ([noudess](https://github.com/noudess)) 2022-03-14
|
||||
* Fix zoning log typo ([#2478](https://github.com/EQEmu/Server/pull/2478)) ([Akkadius](https://github.com/Akkadius)) 2022-10-11
|
||||
* Force crash logs to always be on regardless of setting ([#2762](https://github.com/EQEmu/Server/pull/2762)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
* Improvements to GM Say Logging ([#2765](https://github.com/EQEmu/Server/pull/2765)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
* Logging Improvements ([#2755](https://github.com/EQEmu/Server/pull/2755)) ([Akkadius](https://github.com/Akkadius)) 2023-01-18
|
||||
* More AI Logging Cleanup ([#2616](https://github.com/EQEmu/Server/pull/2616)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-10
|
||||
* Netcode Logging Unify ([#2443](https://github.com/EQEmu/Server/pull/2443)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
||||
* Remove function prefixes ([#2766](https://github.com/EQEmu/Server/pull/2766)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
||||
* Remove loginserver unhandled error ([#2458](https://github.com/EQEmu/Server/pull/2458)) ([Akkadius](https://github.com/Akkadius)) 2022-09-29
|
||||
* Reset stream so we don't bold the whole line ([Akkadius](https://github.com/Akkadius)) 2023-01-18
|
||||
* Table Injection - Member Variable Cleanup ([#2281](https://github.com/EQEmu/Server/pull/2281)) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
||||
* Update BUILD_LOGGING=false Blank Aliases ([#2083](https://github.com/EQEmu/Server/pull/2083)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
|
||||
|
||||
### Luamod
|
||||
|
||||
* Add CalcSpellEffectValue_formula to luamods ([#2721](https://github.com/EQEmu/Server/pull/2721)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-11
|
||||
|
||||
### Mercs
|
||||
|
||||
* Add Mercenary Support ([#2745](https://github.com/EQEmu/Server/pull/2745)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-17
|
||||
|
||||
### Optimization
|
||||
|
||||
* Handle channel name filter checks in memory ([#2767](https://github.com/EQEmu/Server/pull/2767)) ([Valorith](https://github.com/Valorith)) 2023-01-20
|
||||
|
||||
### QS
|
||||
|
||||
* Database class name change ([#2743](https://github.com/EQEmu/Server/pull/2743)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add AddAISpellEffect(spell_effect_id, base_value, limit_value, max_value) and RemoveAISpellEffect(spell_effect_id) to Lua. ([#1981](https://github.com/EQEmu/Server/pull/1981)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-09
|
||||
* Add AddItem() to Perl/Lua. ([#2054](https://github.com/EQEmu/Server/pull/2054)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
|
||||
* Add AddPlatinum(), GetCarriedPlatinum() and TakePlatinum() to Perl/Lua. ([#2079](https://github.com/EQEmu/Server/pull/2079)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
||||
* Add Area Damage Methods to Perl/Lua. ([#2549](https://github.com/EQEmu/Server/pull/2549)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
||||
* Add Augment Slot Type/Visible to GetItemStat ([#2686](https://github.com/EQEmu/Server/pull/2686)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Add Bot Methods to Lua. ([#2731](https://github.com/EQEmu/Server/pull/2731)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
|
||||
* Add Bot::Camp() to Perl/Lua. ([#2718](https://github.com/EQEmu/Server/pull/2718)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
|
||||
* Add BuffCount() Overloads to Perl/Lua. ([#2679](https://github.com/EQEmu/Server/pull/2679)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-29
|
||||
* Add CampAllBots() to Perl/Lua. ([#2732](https://github.com/EQEmu/Server/pull/2732)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
|
||||
* Add Charges/Augment/Attuned Support to Varlink. ([#2685](https://github.com/EQEmu/Server/pull/2685)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Add CheckNameFilter to Perl/Lua. ([#2175](https://github.com/EQEmu/Server/pull/2175)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-20
|
||||
* Add Client Augment Events to Perl/Lua. ([#2735](https://github.com/EQEmu/Server/pull/2735)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||
* Add Client Spell Methods to Perl/Lua. ([#2550](https://github.com/EQEmu/Server/pull/2550)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Add CloneAppearance() to Perl/Lua. ([#2531](https://github.com/EQEmu/Server/pull/2531)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add CopyHateList() to Perl/Lua. ([#2623](https://github.com/EQEmu/Server/pull/2623)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||
* Add Corpse::AddItem overloads for Lua ([#2509](https://github.com/EQEmu/Server/pull/2509)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||
* Add Despawn Events to Perl/Lua. ([#2707](https://github.com/EQEmu/Server/pull/2707)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-07
|
||||
* Add DoAnim Overloads to Perl/Lua. ([#2627](https://github.com/EQEmu/Server/pull/2627)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
|
||||
* Add DoAugmentSlotsMatch() to Perl/Lua. ([#2687](https://github.com/EQEmu/Server/pull/2687)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Add DoesAugmentFit() to Perl/Lua. ([#2688](https://github.com/EQEmu/Server/pull/2688)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
||||
* Add Door Methods to Perl/Lua. ([#2724](https://github.com/EQEmu/Server/pull/2724)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-12
|
||||
* Add EVENT_AA_BUY and EVENT_AA_GAIN to Perl/Lua. ([#2504](https://github.com/EQEmu/Server/pull/2504)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||
* Add EVENT_BOT_CREATE to Perl/Lua ([#2713](https://github.com/EQEmu/Server/pull/2713)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-09
|
||||
* Add EVENT_CAST_ON exports to EVENT_CAST and EVENT_CAST_BEGIN. ([#2051](https://github.com/EQEmu/Server/pull/2051)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
||||
* Add EVENT_EQUIP_ITEM_CLIENT and EVENT_UNEQUIP_ITEM_CLIENT to Perl/Lua. ([#2015](https://github.com/EQEmu/Server/pull/2015)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-23
|
||||
* Add EVENT_GM_COMMAND to Perl/Lua. ([#2634](https://github.com/EQEmu/Server/pull/2634)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||
* Add EVENT_LEVEL_DOWN to Perl/Lua. ([#2620](https://github.com/EQEmu/Server/pull/2620)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||
* Add EVENT_PAYLOAD to Perl/Lua. ([#2611](https://github.com/EQEmu/Server/pull/2611)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||
* Add EVENT_SKILL_UP & EVENT_LANGUAGE_SKILL_UP to Perl/Lua ([#2076](https://github.com/EQEmu/Server/pull/2076)) ([nytmyr](https://github.com/nytmyr)) 2022-04-25
|
||||
* Add Entity Variable Methods to Perl/Lua. ([#2609](https://github.com/EQEmu/Server/pull/2609)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||
* Add Fling Overloads to Perl/Lua. ([#2622](https://github.com/EQEmu/Server/pull/2622)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||
* Add GetAugmentIDsBySlotID() to Perl/Lua. ([#2673](https://github.com/EQEmu/Server/pull/2673)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
||||
* Add GetAverageLevel() to Perl/Lua. ([#2524](https://github.com/EQEmu/Server/pull/2524)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add GetBotItem() and GetBotItemIDBySlot() to Perl/Lua. ([#2350](https://github.com/EQEmu/Server/pull/2350)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-31
|
||||
* Add GetBotListByCharacterID() to Perl/Lua. ([#2069](https://github.com/EQEmu/Server/pull/2069)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
|
||||
* Add GetBotListByClientName() Class Overload to Perl/Lua. ([#2577](https://github.com/EQEmu/Server/pull/2577)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||
* Add GetBotListByClientName(client_name) to Perl/Lua. ([#2064](https://github.com/EQEmu/Server/pull/2064)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-23
|
||||
* Add GetEnvironmentalDamageName() to Perl/Lua. ([#1964](https://github.com/EQEmu/Server/pull/1964)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
||||
* Add GetGMStatus() to Perl/Lua. ([#2448](https://github.com/EQEmu/Server/pull/2448)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
|
||||
* Add GetGuildPublicNote() to Perl/Lua. ([#2608](https://github.com/EQEmu/Server/pull/2608)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||
* Add GetHealAmount() and GetSpellDamage() to Perl/Lua. ([#2165](https://github.com/EQEmu/Server/pull/2165)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-11
|
||||
* Add GetLeader() and GetLeaderName() to Perl/Lua. ([#2701](https://github.com/EQEmu/Server/pull/2701)) ([Valorith](https://github.com/Valorith)) 2023-01-04
|
||||
* Add GetLowestLevel() to Perl. ([#2517](https://github.com/EQEmu/Server/pull/2517)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||
* Add GetRandomBot() to Perl/Lua ([#2543](https://github.com/EQEmu/Server/pull/2543)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||
* Add GetRandomClient(), GetRandomMob() and GetRandomNPC() overloads to Perl/Lua. ([#2541](https://github.com/EQEmu/Server/pull/2541)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add GetRandomMob() and GetRandomNPC() to Perl/Lua. ([#2006](https://github.com/EQEmu/Server/pull/2006)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
|
||||
* Add GetSkillDmgAmt() to Perl. ([#2365](https://github.com/EQEmu/Server/pull/2365)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-10
|
||||
* Add GetUltimateOwner() to Perl/Lua. ([#2516](https://github.com/EQEmu/Server/pull/2516)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||
* Add Goto Player Teleport Methods. ([#2379](https://github.com/EQEmu/Server/pull/2379)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
||||
* Add Group/Raid Overloads to Perl/Lua. ([#2587](https://github.com/EQEmu/Server/pull/2587)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Add Group/Raid overloads to Perl/Lua. ([#2526](https://github.com/EQEmu/Server/pull/2526)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add HasBotSpellEntry() to Perl/Lua. ([#2563](https://github.com/EQEmu/Server/pull/2563)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
||||
* Add Hotzone Methods to Perl/Lua. ([#2558](https://github.com/EQEmu/Server/pull/2558)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Add Instance ID/Version exports to EVENT_ZONE. ([#2502](https://github.com/EQEmu/Server/pull/2502)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
||||
* Add Instance Methods to Perl/Lua. ([#2573](https://github.com/EQEmu/Server/pull/2573)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||
* Add IsAttackAllowed() to Perl/Lua. ([#2672](https://github.com/EQEmu/Server/pull/2672)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
||||
* Add IsRaining() and IsSnowing() to Perl/Lua. ([#2477](https://github.com/EQEmu/Server/pull/2477)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-14
|
||||
* Add IsRareSpawn() to Perl/Lua. ([#2338](https://github.com/EQEmu/Server/pull/2338)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-30
|
||||
* Add Lua handlers for zone controller events ([#2514](https://github.com/EQEmu/Server/pull/2514)) ([hgtw](https://github.com/hgtw)) 2022-11-05
|
||||
* Add Marquee methods to Perl/Lua. ([#2544](https://github.com/EQEmu/Server/pull/2544)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||
* Add MaxSkills() to Perl/Lua. ([#2621](https://github.com/EQEmu/Server/pull/2621)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
||||
* Add Merchant Events to Perl/Lua. ([#2452](https://github.com/EQEmu/Server/pull/2452)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
|
||||
* Add Mob Hate Methods to Perl/Lua. ([#2548](https://github.com/EQEmu/Server/pull/2548)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
||||
* Add Overloads to MoveZone Methods in Perl/Lua. ([#2551](https://github.com/EQEmu/Server/pull/2551)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
||||
* Add Owner methods to Perl/Lua. ([#2542](https://github.com/EQEmu/Server/pull/2542)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add Popup methods to Perl/Lua. ([#2533](https://github.com/EQEmu/Server/pull/2533)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add Proximity Range Methods to Perl/Lua. ([#2572](https://github.com/EQEmu/Server/pull/2572)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||
* Add RandomizeFeature() overloads to Perl/Lua. ([#2532](https://github.com/EQEmu/Server/pull/2532)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add Recipe Methods ([#2393](https://github.com/EQEmu/Server/pull/2393)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-23
|
||||
* Add ResetAlternateAdvancementRank() to Perl/Lua. ([#2510](https://github.com/EQEmu/Server/pull/2510)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
||||
* Add ResetDecayTimer() to Perl/Lua. ([#2520](https://github.com/EQEmu/Server/pull/2520)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||
* Add SendGMCommand() to Perl/Lua. ([#2527](https://github.com/EQEmu/Server/pull/2527)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add SendPath() to Perl/Lua. ([#2740](https://github.com/EQEmu/Server/pull/2740)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
||||
* Add SignalAllBotsByOwnerName() to Perl/Lua. ([#2730](https://github.com/EQEmu/Server/pull/2730)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
||||
* Add SplitMoney() with Client splitter to Perl. ([#2525](https://github.com/EQEmu/Server/pull/2525)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
||||
* Add TaskSelector to Perl/Lua. ([#2177](https://github.com/EQEmu/Server/pull/2177)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
|
||||
* Add Time String to Seconds Method to Perl/Lua. ([#2580](https://github.com/EQEmu/Server/pull/2580)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Add TrackNPC to Perl/Lua. ([#2272](https://github.com/EQEmu/Server/pull/2272)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-29
|
||||
* Add WearChange Overloads to Perl/Lua. ([#2600](https://github.com/EQEmu/Server/pull/2600)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
||||
* Add Zone Flag Methods to Perl/Lua. ([#2574](https://github.com/EQEmu/Server/pull/2574)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
||||
* Add apis to end shared tasks ([#2521](https://github.com/EQEmu/Server/pull/2521)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||
* Add caster_id and caster_level export to EVENT_CAST_ON in Perl/Lua. ([#2049](https://github.com/EQEmu/Server/pull/2049)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-11
|
||||
* Add commify to Perl/Lua. ([#2099](https://github.com/EQEmu/Server/pull/2099)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-03
|
||||
* Add inventory->CountItemEquippedByID(item_id) and inventory->HasItemEquippedByID(item_id) to Perl/Lua. ([#1963](https://github.com/EQEmu/Server/pull/1963)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-06
|
||||
* Add missing methods/package.adds to Perl API. ([#2287](https://github.com/EQEmu/Server/pull/2287)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
||||
* Add multiple inventory method short hands to client. ([#2078](https://github.com/EQEmu/Server/pull/2078)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
||||
* Add option to Ignore Mods to CalcEXP ([#2704](https://github.com/EQEmu/Server/pull/2704)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-06
|
||||
* Adjustment to depop_all function. ([#2595](https://github.com/EQEmu/Server/pull/2595)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
|
||||
* Allow CreateInstance to be used without a Client initiator. ([#2399](https://github.com/EQEmu/Server/pull/2399)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-28
|
||||
* Allow EVENT_ZONE to be parsed as non-zero to prevent zoning. ([#2052](https://github.com/EQEmu/Server/pull/2052)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
||||
* Allow scripts to prevent door click ([#2327](https://github.com/EQEmu/Server/pull/2327)) ([hgtw](https://github.com/hgtw)) 2022-07-27
|
||||
* Cleanup Proximity Events ([#2697](https://github.com/EQEmu/Server/pull/2697)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
||||
* Cleanup Signal Methods in Perl/Lua. ([#2604](https://github.com/EQEmu/Server/pull/2604)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
||||
* Expand Bot quest API functionality. ([#2096](https://github.com/EQEmu/Server/pull/2096)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||
* Expand SaveGuardSpot ([#2258](https://github.com/EQEmu/Server/pull/2258)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
||||
* Export corpse in EVENT_DEATH_COMPLETE ([#2519](https://github.com/EQEmu/Server/pull/2519)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||
* Export killed XYZH to EVENT_DEATH_ZONE in Perl. ([#2050](https://github.com/EQEmu/Server/pull/2050)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
||||
* Fix Lua Door/Object Create Methods. ([#2633](https://github.com/EQEmu/Server/pull/2633)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
||||
* Fix Perl EVENT_HP double parsing in Spire. ([#2585](https://github.com/EQEmu/Server/pull/2585)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
||||
* Fix lua task selector count when over max ([#2353](https://github.com/EQEmu/Server/pull/2353)) ([hgtw](https://github.com/hgtw)) 2022-07-31
|
||||
* Fix missing arg in perl set_proximity ([#2291](https://github.com/EQEmu/Server/pull/2291)) ([hgtw](https://github.com/hgtw)) 2022-07-09
|
||||
* Fix parameters in some Perl worldwide methods. ([#2224](https://github.com/EQEmu/Server/pull/2224)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
|
||||
* Let HasQuestSub check encounters ([#2435](https://github.com/EQEmu/Server/pull/2435)) ([hgtw](https://github.com/hgtw)) 2022-09-20
|
||||
* Perl Doors Fix. ([#2288](https://github.com/EQEmu/Server/pull/2288)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
||||
* Perl Money Fixes. ([#2098](https://github.com/EQEmu/Server/pull/2098)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
||||
* Send delivered task items in trade events ([#2518](https://github.com/EQEmu/Server/pull/2518)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
||||
* Use Floating Point for CameraEffect Intensity ([#2337](https://github.com/EQEmu/Server/pull/2337)) ([hgtw](https://github.com/hgtw)) 2022-07-31
|
||||
* Use binding library for perl apis ([#2216](https://github.com/EQEmu/Server/pull/2216)) ([hgtw](https://github.com/hgtw)) 2022-07-04
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Backstab Rules ([#2666](https://github.com/EQEmu/Server/pull/2666)) ([Valorith](https://github.com/Valorith)) 2022-12-21
|
||||
* Add Frontal Stun Immunity Rules. ([#2217](https://github.com/EQEmu/Server/pull/2217)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
|
||||
* Add Keep Level on Death ([#2319](https://github.com/EQEmu/Server/pull/2319)) ([trentdm](https://github.com/trentdm)) 2022-07-30
|
||||
* Add LDoN Loot Count Modifier Rule ([#2694](https://github.com/EQEmu/Server/pull/2694)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
||||
* Add ManaOnDeath and EndurOnDeath ([#2661](https://github.com/EQEmu/Server/pull/2661)) ([fryguy503](https://github.com/fryguy503)) 2022-12-20
|
||||
* Add Rule to Disable NPC Last Names. ([#2227](https://github.com/EQEmu/Server/pull/2227)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
||||
* Add Rule to Enable Tells with #hideme ([#2358](https://github.com/EQEmu/Server/pull/2358)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-04
|
||||
* Add Rule to allow Assassinate on non-Humanoid body types. ([#2331](https://github.com/EQEmu/Server/pull/2331)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
|
||||
* Add Rule to allow Headshots on non-Humanoid body types. ([#2329](https://github.com/EQEmu/Server/pull/2329)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
|
||||
* Add Rules to disable various item functionalities and cleanup data types. ([#2225](https://github.com/EQEmu/Server/pull/2225)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
||||
* Add Spells:BuffsFadeOnDeath. ([#2200](https://github.com/EQEmu/Server/pull/2200)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Add Spells:IllusionsAlwaysPersist. ([#2199](https://github.com/EQEmu/Server/pull/2199)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
||||
* Add Toggle for Warrior Shielding ([#2496](https://github.com/EQEmu/Server/pull/2496)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-22
|
||||
* Add adjustment for zone forage. ([#2330](https://github.com/EQEmu/Server/pull/2330)) ([fryguy503](https://github.com/fryguy503)) 2022-07-30
|
||||
* Add rule for NPC Level Based Buff Restrictions. ([#2708](https://github.com/EQEmu/Server/pull/2708)) ([noudess](https://github.com/noudess)) 2023-01-15
|
||||
* Add rule to allow players to permanently save chat channels to database, up to a limit. ([#2706](https://github.com/EQEmu/Server/pull/2706)) ([Valorith](https://github.com/Valorith)) 2023-01-19
|
||||
* Change TradeskillUp Rules to be Floats ([#2674](https://github.com/EQEmu/Server/pull/2674)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-25
|
||||
* Cleanup all unused rules. ([#2184](https://github.com/EQEmu/Server/pull/2184)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
||||
* Rule Gate Pet Zoning ([#2625](https://github.com/EQEmu/Server/pull/2625)) ([fryguy503](https://github.com/fryguy503)) 2022-12-07
|
||||
* Rule to allow cap on % XP gain per kill ([#2667](https://github.com/EQEmu/Server/pull/2667)) ([Valorith](https://github.com/Valorith)) 2022-12-25
|
||||
* Update logic checks everywhere for FVNoDropFlag. ([#2179](https://github.com/EQEmu/Server/pull/2179)) ([Quintinon](https://github.com/Quintinon)) 2022-07-30
|
||||
|
||||
### SQL
|
||||
|
||||
* Bugs Table Migration (#2602) ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([joligario](https://github.com/joligario)) 2022-12-01
|
||||
* Update 2023_01_15_merc_data.sql ([#2763](https://github.com/EQEmu/Server/pull/2763)) ([joligario](https://github.com/joligario)) 2023-01-20
|
||||
|
||||
### UCS
|
||||
|
||||
* Auto Client Reconnection ([#2154](https://github.com/EQEmu/Server/pull/2154)) ([Akkadius](https://github.com/Akkadius)) 2022-05-08
|
||||
|
||||
### Websocket
|
||||
|
||||
* Fix cpp20/gcc11 compile failure ([#2737](https://github.com/EQEmu/Server/pull/2737)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
|
||||
|
||||
### Zone Flags
|
||||
|
||||
* Use database connection, not content connection ([#2759](https://github.com/EQEmu/Server/pull/2759)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
|
||||
+364
-347
@@ -1,30 +1,207 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
#EQEmu CMake
|
||||
#Variables used:
|
||||
#EQEMU_DISABLE_CRT_SECURE_WARNINGS
|
||||
#EQEMU_FAST_FLOATINGPOINT
|
||||
#EQEMU_ENABLE_CRASH_LOGGING
|
||||
#EQEMU_DISABLE_SAFESEH
|
||||
#EQEMU_BUILD_MSVC_MP
|
||||
#EQEMU_DEBUG_LEVEL
|
||||
#EQEMU_LOG_LEVEL_STATUS
|
||||
#EQEMU_LOG_LEVEL_NORMAL
|
||||
#EQEMU_LOG_LEVEL_ERROR
|
||||
#EQEMU_LOG_LEVEL_DEBUG
|
||||
#EQEMU_LOG_LEVEL_QUEST
|
||||
#EQEMU_LOG_LEVEL_COMMANDS
|
||||
#EQEMU_LOG_LEVEL_CRASH
|
||||
#EQEMU_DEPOP_INVALIDATES_CACHE
|
||||
#EQEMU_ENABLE_BOTS
|
||||
#EQEMU_DISABLE_LOGSYS
|
||||
#EQEMU_COMMANDS_LOGGING
|
||||
#EQEMU_BUILD_SERVER
|
||||
#EQEMU_BUILD_LOGIN
|
||||
#EQEMU_BUILD_TESTS
|
||||
#EQEMU_BUILD_PERL
|
||||
#EQEMU_BUILD_LUA
|
||||
#EQEMU_SANITIZE_LUA_LIBS
|
||||
#EQEMU_BUILD_CLIENT_FILES
|
||||
#EQEMU_USE_MAP_MMFS
|
||||
#EQEMU_MAP_DIR
|
||||
|
||||
#We set a fairly new version (as of 2013) because I found finding perl was a bit... buggy on older ones
|
||||
#Can change this if you really want but you should upgrade!
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
|
||||
|
||||
#FindMySQL is located here so lets make it so CMake can find it
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||
|
||||
IF(POLICY CMP0074)
|
||||
CMAKE_POLICY(SET CMP0074 NEW)
|
||||
ENDIF()
|
||||
|
||||
#Our project name is EQEmu
|
||||
PROJECT(EQEmu)
|
||||
|
||||
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
SET(CMAKE_CXX_STANDARD 20)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||
#Add our various windows definitions
|
||||
IF(MSVC OR MINGW)
|
||||
ADD_DEFINITIONS(-D_WINDOWS)
|
||||
IF(CMAKE_CL_64)
|
||||
ADD_DEFINITIONS(-DWIN64)
|
||||
ELSE(CMAKE_CL_64)
|
||||
ADD_DEFINITIONS(-DWIN32)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ENDIF(MSVC OR MINGW)
|
||||
|
||||
# include dirs are universal
|
||||
SET(NATS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/nats")
|
||||
|
||||
#Try to find protobuf automatically
|
||||
FIND_PACKAGE(Protobuf QUIET)
|
||||
#IF(NOT PROTOBUF_FOUND)
|
||||
SET(Protobuf_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/protobuf" CACHE PATH "Root protobuf directory" FORCE)
|
||||
SET(PROTOBUF_FOUND TRUE CACHE BOOL "" FORCE)
|
||||
IF(MSVC)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/windows/x64/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/windows/x64/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/windows/x64/bin/protoc.exe" CACHE PATH "Executable path" FORCE)
|
||||
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/windows/x64/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
|
||||
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/windows/x64/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/windows/x86/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/windows/x86/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/windows/x86/bin/protoc.exe" CACHE PATH "Executable path" FORCE)
|
||||
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/windows/x86/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
|
||||
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/windows/x86/lib/libprotobufd.lib" CACHE PATH "Root protobuf directory" FORCE)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ELSE(MSVC)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/linux/x86/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/linux/x86/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/linux/x86/bin/protoc" CACHE PATH "Executable path" FORCE)
|
||||
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/linux/x86/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
|
||||
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/linux/x86/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(Protobuf_INCLUDE_DIR "${Protobuf_DIR}/linux/x64/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_SRC_ROOT_FOLDER "${Protobuf_DIR}/linux/x64/include" CACHE PATH "Include dir" FORCE)
|
||||
SET(Protobuf_PROTOC_EXECUTABLE "${Protobuf_DIR}/linux/x64/bin/protoc" CACHE PATH "Executable path" FORCE)
|
||||
SET(Protobuf_LIBRARY_DEBUG "${Protobuf_DIR}/linux/x64/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
|
||||
SET(Protobuf_LIBRARY_RELEASE "${Protobuf_DIR}/linux/x64/lib/libprotobuf.so.16" CACHE PATH "Root protobuf directory" FORCE)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ENDIF()
|
||||
IF(NOT Protobuf_LIBRARY_DEBUG)
|
||||
MESSAGE(ERROR "Protobuf library was not found in ${Protobuf_LIBRARY_DEBUG}. Please download the depenencies and extract them as noted.")
|
||||
ENDIF()
|
||||
FILE(COPY ${Protobuf_LIBRARY_DEBUG} DESTINATION ${CMAKE_HOME_DIRECTORY}/bin)
|
||||
#ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${Protobuf_INCLUDE_DIR}")
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
IF(CMAKE_CL_64)
|
||||
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/windows/x64/include")
|
||||
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/windows/x64/lib/nats.lib")
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/windows/x86/include")
|
||||
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/windows/x86/lib/nats.lib")
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ELSE(MSVC)
|
||||
IF(CMAKE_CL_64)
|
||||
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/linux/x86/include")
|
||||
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/linux/x86/lib/libnats.so")
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(NATS_INCLUDE_DIR "${NATS_ROOT}/linux/x64/include")
|
||||
SET(NATS_LIBRARY_DEBUG "${NATS_ROOT}/linux/x64/lib/libnats.so")
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ENDIF()
|
||||
IF(${NATS_LIBRARY_DEBUG})
|
||||
MESSAGE(ERROR " NATS library was not found in ${NATS_LIBRARY_DEBUG}/libnats.so. Please download the depenencies and extract them as noted.")
|
||||
ENDIF()
|
||||
FILE(COPY ${NATS_LIBRARY_DEBUG} DESTINATION ${CMAKE_HOME_DIRECTORY}/bin)
|
||||
|
||||
IF(MSVC)
|
||||
#Set our default locations for zlib/mysql based on x86/x64
|
||||
IF(CMAKE_CL_64)
|
||||
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x64")
|
||||
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x64")
|
||||
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x64")
|
||||
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x64")
|
||||
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
|
||||
IF(MSVC_VERSION GREATER 1800)
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v140/dynamic")
|
||||
ELSEIF(MSVC_VERSION EQUAL 1800)
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v120/dynamic")
|
||||
ELSE()
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v110/dynamic")
|
||||
ENDIF()
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x86")
|
||||
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x86")
|
||||
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x86")
|
||||
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
|
||||
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x86")
|
||||
SET(NATS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/nats_x86")
|
||||
IF(MSVC_VERSION GREATER 1800)
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v140/dynamic")
|
||||
ELSEIF(MSVC_VERSION EQUAL 1800)
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v120/dynamic")
|
||||
ELSE()
|
||||
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v110/dynamic")
|
||||
ENDIF()
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
#disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere
|
||||
OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON)
|
||||
IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ENDIF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
|
||||
|
||||
#fast FP if you'd like it
|
||||
OPTION(EQEMU_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
|
||||
IF(EQEMU_FAST_FLOATINGPOINT)
|
||||
ADD_DEFINITIONS(/fp:fast)
|
||||
ENDIF(EQEMU_FAST_FLOATINGPOINT)
|
||||
|
||||
#crash logging currently only works on windows x86/x64
|
||||
OPTION(EQEMU_ENABLE_CRASH_LOGGING "Enable crash logging" ON)
|
||||
IF(EQEMU_ENABLE_CRASH_LOGGING)
|
||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||
ENDIF(EQEMU_ENABLE_CRASH_LOGGING)
|
||||
|
||||
#Disable safe SEH or not?
|
||||
OPTION(EQEMU_DISABLE_SAFESEH "Disable Safe SEH (Needed for Strawberry Perl)" OFF)
|
||||
IF(EQEMU_DISABLE_SAFESEH)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /SAFESEH:NO")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /SAFESEH:NO")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
|
||||
SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
|
||||
SET(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL} /SAFESEH:NO")
|
||||
SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /SAFESEH:NO")
|
||||
SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} /SAFESEH:NO")
|
||||
ENDIF(EQEMU_DISABLE_SAFESEH)
|
||||
|
||||
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON)
|
||||
IF(EQEMU_BUILD_MSVC_MP)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
ENDIF(EQEMU_BUILD_MSVC_MP)
|
||||
|
||||
#We want to compile /MT not /MD so we change that
|
||||
FOREACH(flag_var CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
IF(${flag_var} MATCHES "/MD")
|
||||
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
ENDIF(${flag_var} MATCHES "/MD")
|
||||
ENDFOREACH(flag_var)
|
||||
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
ELSE(MSVC)
|
||||
|
||||
|
||||
#Normally set by perl but we don't use the perl flags anymore so we set it.
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
|
||||
@@ -41,336 +218,176 @@ IF(UNIX)
|
||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
ENDIF(UNIX)
|
||||
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
||||
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
||||
#debug level, 5 is default. Most people wont ever change this but it's there if you want to
|
||||
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
|
||||
0 - Quiet mode Errors to file Status and Normal ignored
|
||||
1 - Status and Normal to console, Errors to logfile
|
||||
2 - Status, Normal, and Error to console and logfile
|
||||
3 - Light debug release errors and status
|
||||
4 - Moderate debug release errors and status
|
||||
5 - Maximum debug release errors and status
|
||||
10 - More errors than you ever wanted to see"
|
||||
)
|
||||
|
||||
#MSVC can fetch dependencies automatically.
|
||||
IF(MSVC)
|
||||
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
|
||||
ENDIF()
|
||||
SET(EQEMU_LOG_LEVEL_STATUS 2 CACHE STRING "EQEmu logging level for [Status]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
#Find everything we need
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
FIND_PACKAGE(MySQL)
|
||||
FIND_PACKAGE(MariaDB)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
FIND_PACKAGE(Lua51)
|
||||
FIND_PACKAGE(LuaJit)
|
||||
FIND_PACKAGE(PerlLibs)
|
||||
FIND_PACKAGE(Sodium)
|
||||
FIND_PACKAGE(mbedTLS)
|
||||
SET(EQEMU_LOG_LEVEL_NORMAL 3 CACHE STRING "EQEmu logging level for [Normal]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Library Detection *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
SET(EQEMU_LOG_LEVEL_ERROR 2 CACHE STRING "EQEmu logging level for [Error]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
IF(MYSQL_FOUND)
|
||||
MESSAGE(STATUS "* MySQL: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* MySQL: MISSING *")
|
||||
ENDIF()
|
||||
SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
IF(MARIADB_FOUND)
|
||||
MESSAGE(STATUS "* MariaDB: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* MariaDB: MISSING *")
|
||||
ENDIF()
|
||||
SET(EQEMU_LOG_LEVEL_QUEST 2 CACHE STRING "EQEmu logging level for [Quest]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
IF(ZLIB_FOUND)
|
||||
MESSAGE(STATUS "* ZLIB: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* ZLIB: MISSING *")
|
||||
ENDIF()
|
||||
SET(EQEMU_LOG_LEVEL_COMMANDS 1 CACHE STRING "EQEmu logging level for [Commands]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
IF(Lua51_FOUND)
|
||||
MESSAGE(STATUS "* Lua: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* Lua: MISSING *")
|
||||
ENDIF()
|
||||
SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]:
|
||||
0 - Disabled
|
||||
1 - Ouput to File Enabled
|
||||
2 - Output to stdout Enabled
|
||||
3 - Output to File and stdout Enabled
|
||||
8 - Output to stderr Enabled
|
||||
9 - Output to File and stderr Enabled
|
||||
11 - Output to File, stdout and stderr Enabled"
|
||||
)
|
||||
|
||||
IF(LuaJit_FOUND)
|
||||
MESSAGE(STATUS "* LuaJIT: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* LuaJIT: MISSING *")
|
||||
ENDIF()
|
||||
MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_STATUS EQEMU_LOG_LEVEL_NORMAL EQEMU_LOG_LEVEL_ERROR EQEMU_LOG_LEVEL_DEBUG EQEMU_LOG_LEVEL_QUEST EQEMU_LOG_LEVEL_COMMANDS EQEMU_LOG_LEVEL_CRASH)
|
||||
|
||||
IF(PerlLibs_FOUND)
|
||||
MESSAGE(STATUS "* Perl: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* Perl: MISSING *")
|
||||
ENDIF()
|
||||
#NPC Types Cache Behavior
|
||||
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
|
||||
|
||||
IF(SODIUM_FOUND)
|
||||
MESSAGE(STATUS "* libsodium: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* libsodium: MISSING *")
|
||||
ENDIF()
|
||||
#Bots are a compile time option so on/off
|
||||
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
|
||||
|
||||
IF(OpenSSL_FOUND)
|
||||
MESSAGE(STATUS "* OpenSSL: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* OpenSSL: MISSING *")
|
||||
ENDIF()
|
||||
#Disable entire _mlog system (excludes trade/command logs)
|
||||
OPTION(EQEMU_DISABLE_LOGSYS "Disable Logging INI System" ON)
|
||||
|
||||
IF(MBEDTLS_FOUND)
|
||||
MESSAGE(STATUS "* mbedTLS: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#options
|
||||
#Enable GM Command log system
|
||||
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
|
||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
||||
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||
OPTION(EQEMU_PREFER_LUA "Build with normal Lua even if LuaJIT is found." OFF)
|
||||
|
||||
#PRNG options
|
||||
OPTION(EQEMU_ADDITIVE_LFIB_PRNG "Use Additive LFib for PRNG." OFF)
|
||||
MARK_AS_ADVANCED(EQEMU_ADDITIVE_LFIB_PRNG)
|
||||
OPTION(EQEMU_BIASED_INT_DIST "Use biased int dist instead of uniform." OFF)
|
||||
MARK_AS_ADVANCED(EQEMU_BIASED_INT_DIST)
|
||||
SET(EQEMU_CUSTOM_PRNG_ENGINE "" CACHE STRING "Custom random engine. (ex. std::default_random_engine)")
|
||||
MARK_AS_ADVANCED(EQEMU_CUSTOM_PRNG_ENGINE)
|
||||
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
OPTION(EQEMU_SFMT19937 "Use GCC's extention for SIMD Fast MT19937." OFF)
|
||||
MARK_AS_ADVANCED(EQEMU_SFMT19937)
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_ADDITIVE_LFIB_PRNG)
|
||||
ADD_DEFINITIONS(-DUSE_ADDITIVE_LFIB_PRNG)
|
||||
IF(EQEMU_SFMT19937)
|
||||
MESSAGE(STATUS "SFMT19937 and ADDITITVE_LFIB_PRNG both set, SFMT19937 ignored.")
|
||||
SET(EQEMU_SFMT19937 OFF)
|
||||
ENDIF()
|
||||
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
|
||||
MESSAGE(STATUS "CUSTOM_PRNG_ENGINE and ADDITITVE_LFIB_PRNG both set, CUSTOM_PRNG_ENGINE ignored.")
|
||||
SET(EQEMU_CUSTOM_PRNG_ENGINE "")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_SFMT19937)
|
||||
ADD_DEFINITIONS(-DUSE_SFMT19937)
|
||||
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
|
||||
MESSAGE(STATUS "CUSTOM_PRNG_ENGINE and SFMT19937 both set, CUSTOM_PRNG_ENGINE ignored.")
|
||||
SET(EQEMU_CUSTOM_PRNG_ENGINE "")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
|
||||
ADD_DEFINITIONS(-DUSE_CUSTOM_PRNG_ENGINE=${EQEMU_CUSTOM_PRNG_ENGINE})
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_BIASED_INT_DIST)
|
||||
ADD_DEFINITIONS(-DBIASED_INT_DIST)
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_COMMANDS_LOGGING)
|
||||
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
||||
ENDIF(EQEMU_COMMANDS_LOGGING)
|
||||
|
||||
#database
|
||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
||||
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
|
||||
MySQL
|
||||
MariaDB"
|
||||
)
|
||||
IF(EQEMU_DISABLE_LOGSYS)
|
||||
ADD_DEFINITIONS(-DDISABLE_LOGSYS)
|
||||
ENDIF(EQEMU_DISABLE_LOGSYS)
|
||||
|
||||
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
|
||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
||||
ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB")
|
||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB")
|
||||
IF(EQEMU_ENABLE_BOTS)
|
||||
ADD_DEFINITIONS(-DBOTS)
|
||||
ENDIF(EQEMU_ENABLE_BOTS)
|
||||
|
||||
#What to build
|
||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
|
||||
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||
|
||||
#C++11 stuff
|
||||
IF(NOT MSVC)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
|
||||
ENDIF()
|
||||
ELSEIF(MariaDB_FOUND)
|
||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
||||
ELSEIF(MySQL_FOUND)
|
||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.")
|
||||
ENDIF()
|
||||
ENDIF(NOT MSVC)
|
||||
|
||||
#security
|
||||
#prefer openssl to mbedtls (arbitrary)
|
||||
IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
|
||||
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
|
||||
OpenSSL
|
||||
mbedTLS"
|
||||
)
|
||||
#Various definitions
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
ENDIF(EQEMU_BUILD_PERL)
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
|
||||
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
|
||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
||||
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
|
||||
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
ENDIF()
|
||||
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
|
||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS")
|
||||
ENDIF()
|
||||
ELSEIF(OpenSSL_FOUND)
|
||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
||||
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
|
||||
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
ENDIF()
|
||||
ELSEIF(MBEDTLS_FOUND)
|
||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
||||
SET(TLS_LIBRARY_ENABLED ON)
|
||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
||||
ELSE()
|
||||
SET(TLS_LIBRARY_TYPE "Disabled")
|
||||
SET(TLS_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
|
||||
IF(EQEMU_USE_MAP_MMFS)
|
||||
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
|
||||
ENDIF(EQEMU_USE_MAP_MMFS)
|
||||
|
||||
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
|
||||
|
||||
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
||||
ADD_DEFINITIONS(-DINVERSEXY)
|
||||
ADD_DEFINITIONS(-DFIELD_ITEMS)
|
||||
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_STATUS=${EQEMU_LOG_LEVEL_STATUS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_NORMAL=${EQEMU_LOG_LEVEL_NORMAL})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_ERROR=${EQEMU_LOG_LEVEL_ERROR})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
|
||||
#Find everything we need
|
||||
FIND_PACKAGE(ZLIB REQUIRED)
|
||||
FIND_PACKAGE(MySQL REQUIRED)
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
FIND_PACKAGE(PerlLibs REQUIRED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}")
|
||||
ENDIF(EQEMU_BUILD_PERL)
|
||||
|
||||
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt ${NATS_LIBRARY_DEBUG} ${PROTOBUF_LIBRARY_DEBUG})
|
||||
|
||||
FIND_PACKAGE(Sodium REQUIRED)
|
||||
IF(SODIUM_FOUND)
|
||||
SET(SODIUM_LIBRARY_TYPE "Libsodium")
|
||||
SET(SODIUM_LIBRARY_ENABLED ON)
|
||||
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
|
||||
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
|
||||
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
||||
ELSE()
|
||||
SET(SODIUM_LIBRARY_TYPE " Disabled")
|
||||
SET(SODIUM_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(LUAJIT_FOUND AND NOT (EQEMU_PREFER_LUA AND Lua51_FOUND))
|
||||
SET(LUA_LIBRARY_TYPE " LuaJIT")
|
||||
SET(LUA_LIBRARY_ENABLED ON)
|
||||
SET(LUA_LIBRARY_LIBS ${LUAJIT_LIBRARY} luabind)
|
||||
SET(LUA_LIBRARY_INCLUDE ${LUAJIT_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
||||
ELSEIF(Lua51_FOUND )
|
||||
SET(LUA_LIBRARY_TYPE " Lua 5.1")
|
||||
SET(LUA_LIBRARY_ENABLED ON)
|
||||
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
|
||||
SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
||||
ELSE()
|
||||
SET(LUA_LIBRARY_TYPE "Disabled")
|
||||
SET(LUA_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(PerlLibs_FOUND)
|
||||
SET(PERL_LIBRARY_TYPE " Perl")
|
||||
SET(PERL_LIBRARY_ENABLED ON)
|
||||
SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY})
|
||||
SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH})
|
||||
ELSE()
|
||||
SET(PERL_LIBRARY_TYPE "Disabled")
|
||||
SET(PERL_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
#use zlib if exists
|
||||
IF(ZLIB_FOUND)
|
||||
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON)
|
||||
IF(EQEMU_BUILD_ZLIB)
|
||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng")
|
||||
ELSE()
|
||||
SET(ZLIB_LIBRARY_TYPE " zlib")
|
||||
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
|
||||
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Library Usage *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#setup server libs and headers
|
||||
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
||||
|
||||
# silence obnoxious deprecation message
|
||||
ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
|
||||
|
||||
IF(TLS_LIBRARY_ENABLED)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
|
||||
ENDIF()
|
||||
|
||||
IF(SODIUM_LIBRARY_ENABLED)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
|
||||
ENDIF()
|
||||
|
||||
IF(LUA_LIBRARY_ENABLED)
|
||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||
SET(ZONE_LIBS ${LUA_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
|
||||
|
||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(PERL_LIBRARY_ENABLED)
|
||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON)
|
||||
IF(EQEMU_ENABLE_SECURITY)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}")
|
||||
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
@@ -383,40 +400,41 @@ IF(UNIX)
|
||||
IF(NOT DARWIN)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} "rt")
|
||||
ENDIF()
|
||||
# Freebsd provides uuids in the C library
|
||||
IF(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
||||
ENDIF()
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
||||
ENDIF()
|
||||
|
||||
SET(ZONE_LIBS ${ZONE_LIBS} ${SERVER_LIBS})
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
FIND_PACKAGE(EQLua51 REQUIRED)
|
||||
SET(Boost_USE_STATIC_LIBS OFF)
|
||||
SET(Boost_USE_MULTITHREADED ON)
|
||||
SET(Boost_USE_STATIC_RUNTIME OFF)
|
||||
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
|
||||
|
||||
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
|
||||
ENDIF()
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/luabind")
|
||||
|
||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
||||
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
|
||||
ENDIF(EQEMU_BUILD_LUA)
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${NATS_INCLUDE_DIR}")
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/cereal")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/include" )
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/src")
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/format")
|
||||
|
||||
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||
ADD_SUBDIRECTORY(common)
|
||||
ADD_SUBDIRECTORY(libs)
|
||||
ADD_SUBDIRECTORY(submodules/fmt)
|
||||
ADD_SUBDIRECTORY(submodules/libuv)
|
||||
|
||||
IF(EQEMU_BUILD_ZLIB)
|
||||
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
|
||||
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
|
||||
ADD_SUBDIRECTORY(libs/zlibng)
|
||||
ENDIF()
|
||||
|
||||
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
|
||||
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
|
||||
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
|
||||
ADD_SUBDIRECTORY(submodules/recastnavigation)
|
||||
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||
|
||||
IF(EQEMU_BUILD_SERVER)
|
||||
ADD_SUBDIRECTORY(shared_memory)
|
||||
ADD_SUBDIRECTORY(world)
|
||||
@@ -425,7 +443,6 @@ IF(EQEMU_BUILD_SERVER)
|
||||
ADD_SUBDIRECTORY(queryserv)
|
||||
ADD_SUBDIRECTORY(eqlaunch)
|
||||
ENDIF(EQEMU_BUILD_SERVER)
|
||||
|
||||
IF(EQEMU_BUILD_LOGIN)
|
||||
ADD_SUBDIRECTORY(loginserver)
|
||||
ENDIF(EQEMU_BUILD_LOGIN)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
We expect contributors and community members to act professionally and respectfully, and we expect our forums and Discord channels to be dignified environments that expand the community and enhance the learning experience for new members.
|
||||
|
||||
Specifically:
|
||||
|
||||
* Respect people, their ideas, and their work.
|
||||
* Be kind. Be courteous. Be welcoming.
|
||||
* Listen. Consider and acknowledge people's points before responding.
|
||||
* Be respectful of differing viewpoints and experience levels.
|
||||
* Accept constructive criticism and work together toward decisions.
|
||||
* Focus on what is best for the community and users.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of violent threats, trolling, insulting/derogatory comments, abusive or discriminatory language, or personal attacks.
|
||||
* Public or private harassment.
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission.
|
||||
* Conduct which could reasonably be considered inappropriate in a professional setting.
|
||||
* Advocating for or encouraging any of the above behaviors.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, forum posts, Discord messages, and other contributions that are not aligned with this code of conduct.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project.
|
||||
@@ -1,674 +1,165 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# EQEmulator Core Server
|
||||
| Drone (Linux x64) | Drone (Windows x64) |
|
||||
|:---:|:---:|
|
||||
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
||||
|Travis CI (Linux)|Appveyor (Windows) |
|
||||
|:---:|:---:|
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server/branch/master) |
|
||||
|
||||
***
|
||||
|
||||
@@ -17,17 +17,13 @@
|
||||
|:---:|:---:|:---:|
|
||||
|**Install Count**|||
|
||||
### > Windows
|
||||
|
||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
|
||||
* [Install](https://github.com/EQEmu/Server/wiki/Windows-Server)
|
||||
|
||||
### > Debian/Ubuntu/CentOS/Fedora
|
||||
|
||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
|
||||
|
||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
||||
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
||||
|
||||
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
|
||||
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
|
||||
|
||||
## Supported Clients
|
||||
|
||||
@@ -56,7 +52,7 @@ forum, although pull requests will be much quicker and easier on all parties.
|
||||
|
||||
## Resources
|
||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
||||
- [EQEmulator Wiki](https://docs.eqemu.io/)
|
||||
- [EQEmulator Wiki](https://github.com/EQEmu/Server/wiki)
|
||||
|
||||
## Related Repositories
|
||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
||||
@@ -74,10 +70,3 @@ forum, although pull requests will be much quicker and easier on all parties.
|
||||
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
|
||||
* CPPUnit - GLP StringUtilities - Apache
|
||||
* LUA - MIT
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/EQEmu/server/graphs/contributors">
|
||||
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Security Policy - Reporting Vulnerabilities
|
||||
|
||||
When reporting active hacks, exploits and other vulnerabilities, please describe how to reproduce said report and if you can provide context into a possible solution
|
||||
+492
-990
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
add_subdirectory(import)
|
||||
add_subdirectory(export)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(export_sources
|
||||
main.cpp
|
||||
|
||||
+93
-170
@@ -25,101 +25,44 @@
|
||||
#include "../../common/platform.h"
|
||||
#include "../../common/crash.h"
|
||||
#include "../../common/rulesys.h"
|
||||
#include "../../common/strings.h"
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
#include "../../common/string_util.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ExportSpells(SharedDatabase *db);
|
||||
void ExportSkillCaps(SharedDatabase *db);
|
||||
void ExportBaseData(SharedDatabase *db);
|
||||
void ExportDBStrings(SharedDatabase *db);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
RegisterExecutablePlatform(ExePlatformClientExport);
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
LogInfo("Client Files Export Utility");
|
||||
if (!EQEmuConfig::LoadConfig()) {
|
||||
LogError("Unable to load configuration file");
|
||||
Log(Logs::General, Logs::Status, "Client Files Export Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
Log(Logs::General, Logs::Error, "Unable to load configuration file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
|
||||
SharedDatabase database;
|
||||
SharedDatabase content_db;
|
||||
|
||||
LogInfo("Connecting to database");
|
||||
if (!database.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(),
|
||||
Config->DatabaseDB.c_str(),
|
||||
Config->DatabasePort
|
||||
)) {
|
||||
LogError("Unable to connect to the database, cannot continue without a database connection");
|
||||
Log(Logs::General, Logs::Status, "Connecting to database...");
|
||||
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
||||
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-tenancy: Content database
|
||||
*/
|
||||
if (!Config->ContentDbHost.empty()) {
|
||||
if (!content_db.Connect(
|
||||
Config->ContentDbHost.c_str() ,
|
||||
Config->ContentDbUsername.c_str(),
|
||||
Config->ContentDbPassword.c_str(),
|
||||
Config->ContentDbName.c_str(),
|
||||
Config->ContentDbPort
|
||||
)) {
|
||||
LogError("Cannot continue without a content database connection");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
content_db.SetMysql(database.getMySQL());
|
||||
}
|
||||
/* Register Log System and Settings */
|
||||
database.LoadLogSettings(LogSys.log_settings);
|
||||
LogSys.StartFileLogs();
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
std::string arg_1;
|
||||
|
||||
if (argv[1]) {
|
||||
arg_1 = argv[1];
|
||||
}
|
||||
|
||||
if (arg_1 == "spells") {
|
||||
ExportSpells(&content_db);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "skills") {
|
||||
ExportSkillCaps(&content_db);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "basedata") {
|
||||
ExportBaseData(&content_db);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "dbstring") {
|
||||
ExportDBStrings(&database);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExportSpells(&content_db);
|
||||
ExportSkillCaps(&content_db);
|
||||
ExportBaseData(&content_db);
|
||||
ExportSpells(&database);
|
||||
ExportSkillCaps(&database);
|
||||
ExportBaseData(&database);
|
||||
ExportDBStrings(&database);
|
||||
|
||||
LogSys.CloseFileLogs();
|
||||
@@ -127,107 +70,93 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExportSpells(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Spells");
|
||||
void ExportSpells(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting Spells...");
|
||||
|
||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||
FILE *f = fopen("export/spells_us.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string query = "SELECT * FROM spells_new ORDER BY id";
|
||||
auto results = db->QueryDatabase(query);
|
||||
const std::string query = "SELECT * FROM spells_new ORDER BY id";
|
||||
auto results = db->QueryDatabase(query);
|
||||
|
||||
if (results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for (unsigned int i = 0; i < fields; ++i) {
|
||||
if (i != 0) {
|
||||
if(results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for(unsigned int i = 0; i < fields; ++i) {
|
||||
if(i != 0) {
|
||||
line.push_back('^');
|
||||
}
|
||||
|
||||
if (row[i] != nullptr) {
|
||||
if(row[i] != nullptr) {
|
||||
line += row[i];
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
||||
{
|
||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id) {
|
||||
|
||||
bool res = false;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
|
||||
class_id, skill_id
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
std::string query = StringFormat("SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
|
||||
class_id, skill_id);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (results.RowCount() == 0)
|
||||
return false;
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0] && atoi(row[0]) > 0) {
|
||||
return true;
|
||||
}
|
||||
auto row = results.begin();
|
||||
if(row[0] && atoi(row[0]) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
||||
{
|
||||
int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
|
||||
class_id, skill_id, level
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
std::string query = StringFormat("SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
|
||||
class_id, skill_id, level);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Skill Caps");
|
||||
void ExportSkillCaps(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting Skill Caps...");
|
||||
|
||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int cl = 1; cl <= 16; ++cl) {
|
||||
for (int skill = 0; skill <= 77; ++skill) {
|
||||
if (SkillUsable(db, skill, cl)) {
|
||||
int previous_cap = 0;
|
||||
for (int level = 1; level <= 100; ++level) {
|
||||
for(int cl = 1; cl <= 16; ++cl) {
|
||||
for(int skill = 0; skill <= 77; ++skill) {
|
||||
if(SkillUsable(db, skill, cl)) {
|
||||
int previous_cap = 0;
|
||||
for(int level = 1; level <= 100; ++level) {
|
||||
int cap = GetSkill(db, skill, cl, level);
|
||||
if (cap < previous_cap) {
|
||||
if(cap < previous_cap) {
|
||||
cap = previous_cap;
|
||||
}
|
||||
|
||||
@@ -241,29 +170,26 @@ void ExportSkillCaps(SharedDatabase *db)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ExportBaseData(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Base Data");
|
||||
void ExportBaseData(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting Base Data...");
|
||||
|
||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||
FILE *f = fopen("export/BaseData.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string query = "SELECT * FROM base_data ORDER BY level, class";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for (unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||
if (rowIndex != 0) {
|
||||
const std::string query = "SELECT * FROM base_data ORDER BY level, class";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if(results.Success()) {
|
||||
for (auto row = results.begin();row != results.end();++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||
if(rowIndex != 0)
|
||||
line.push_back('^');
|
||||
}
|
||||
|
||||
if (row[rowIndex] != nullptr) {
|
||||
if(row[rowIndex] != nullptr) {
|
||||
line += row[rowIndex];
|
||||
}
|
||||
}
|
||||
@@ -275,30 +201,27 @@ void ExportBaseData(SharedDatabase *db)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ExportDBStrings(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting DB Strings");
|
||||
void ExportDBStrings(SharedDatabase *db) {
|
||||
Log(Logs::General, Logs::Status, "Exporting DB Strings...");
|
||||
|
||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||
if(!f) {
|
||||
Log(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(f, "Major^Minor^String(New)\n");
|
||||
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for (unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||
if (rowIndex != 0) {
|
||||
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if(results.Success()) {
|
||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||
if(rowIndex != 0)
|
||||
line.push_back('^');
|
||||
}
|
||||
|
||||
if (row[rowIndex] != nullptr) {
|
||||
if(row[rowIndex] != nullptr) {
|
||||
line += row[rowIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(import_sources
|
||||
main.cpp
|
||||
|
||||
@@ -23,15 +23,9 @@
|
||||
#include "../../common/platform.h"
|
||||
#include "../../common/crash.h"
|
||||
#include "../../common/rulesys.h"
|
||||
#include "../../common/strings.h"
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
#include "../../common/string_util.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ImportSpells(SharedDatabase *db);
|
||||
void ImportSkillCaps(SharedDatabase *db);
|
||||
@@ -43,61 +37,33 @@ int main(int argc, char **argv) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
set_exception_handler();
|
||||
|
||||
path.LoadPaths();
|
||||
|
||||
LogInfo("Client Files Import Utility");
|
||||
Log(Logs::General, Logs::Status, "Client Files Import Utility");
|
||||
if(!EQEmuConfig::LoadConfig()) {
|
||||
LogError("Unable to load configuration file.");
|
||||
Log(Logs::General, Logs::Error, "Unable to load configuration file.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto Config = EQEmuConfig::get();
|
||||
|
||||
SharedDatabase database;
|
||||
SharedDatabase content_db;
|
||||
|
||||
LogInfo("Connecting to database");
|
||||
if (!database.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(),
|
||||
Config->DatabaseDB.c_str(),
|
||||
Config->DatabasePort
|
||||
)) {
|
||||
LogError("Unable to connect to the database, cannot continue without a database connection");
|
||||
Log(Logs::General, Logs::Status, "Connecting to database...");
|
||||
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
||||
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
|
||||
"database connection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-tenancy: Content database
|
||||
*/
|
||||
if (!Config->ContentDbHost.empty()) {
|
||||
if (!content_db.Connect(
|
||||
Config->ContentDbHost.c_str() ,
|
||||
Config->ContentDbUsername.c_str(),
|
||||
Config->ContentDbPassword.c_str(),
|
||||
Config->ContentDbName.c_str(),
|
||||
Config->ContentDbPort
|
||||
)) {
|
||||
LogError("Cannot continue without a content database connection");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
content_db.SetMysql(database.getMySQL());
|
||||
}
|
||||
database.LoadLogSettings(LogSys.log_settings);
|
||||
LogSys.StartFileLogs();
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
ImportSpells(&content_db);
|
||||
ImportSkillCaps(&content_db);
|
||||
ImportBaseData(&content_db);
|
||||
ImportSpells(&database);
|
||||
ImportSkillCaps(&database);
|
||||
ImportBaseData(&database);
|
||||
ImportDBStrings(&database);
|
||||
|
||||
LogSys.CloseFileLogs();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -131,11 +97,10 @@ bool IsStringField(int i) {
|
||||
}
|
||||
|
||||
void ImportSpells(SharedDatabase *db) {
|
||||
LogInfo("Importing Spells");
|
||||
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
Log(Logs::General, Logs::Status, "Importing Spells...");
|
||||
FILE *f = fopen("import/spells_us.txt", "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -154,8 +119,8 @@ void ImportSpells(SharedDatabase *db) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string escaped = ::Strings::Escape(buffer);
|
||||
auto split = Strings::Split(escaped, '^');
|
||||
std::string escaped = ::EscapeString(buffer);
|
||||
auto split = SplitString(escaped, '^');
|
||||
int line_columns = (int)split.size();
|
||||
|
||||
std::string sql;
|
||||
@@ -208,24 +173,23 @@ void ImportSpells(SharedDatabase *db) {
|
||||
|
||||
spells_imported++;
|
||||
if(spells_imported % 1000 == 0) {
|
||||
LogInfo("[{}] spells imported", spells_imported);
|
||||
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
|
||||
}
|
||||
}
|
||||
|
||||
if(spells_imported % 1000 != 0) {
|
||||
LogInfo("[{}] spells imported", spells_imported);
|
||||
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ImportSkillCaps(SharedDatabase *db) {
|
||||
LogInfo("Importing Skill Caps");
|
||||
Log(Logs::General, Logs::Status, "Importing Skill Caps...");
|
||||
|
||||
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -234,7 +198,7 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
|
||||
char buffer[2048];
|
||||
while(fgets(buffer, 2048, f)) {
|
||||
auto split = Strings::Split(buffer, '^');
|
||||
auto split = SplitString(buffer, '^');
|
||||
|
||||
if(split.size() < 4) {
|
||||
continue;
|
||||
@@ -256,12 +220,11 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ImportBaseData(SharedDatabase *db) {
|
||||
LogInfo("Importing Base Data");
|
||||
Log(Logs::General, Logs::Status, "Importing Base Data...");
|
||||
|
||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
FILE *f = fopen("import/BaseData.txt", "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -270,7 +233,7 @@ void ImportBaseData(SharedDatabase *db) {
|
||||
|
||||
char buffer[2048];
|
||||
while(fgets(buffer, 2048, f)) {
|
||||
auto split = Strings::Split(buffer, '^');
|
||||
auto split = SplitString(buffer, '^');
|
||||
|
||||
if(split.size() < 10) {
|
||||
continue;
|
||||
@@ -302,12 +265,11 @@ void ImportBaseData(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
void ImportDBStrings(SharedDatabase *db) {
|
||||
LogInfo("Importing DB Strings");
|
||||
Log(Logs::General, Logs::Status, "Importing DB Strings...");
|
||||
|
||||
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
Log(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -329,7 +291,7 @@ void ImportDBStrings(SharedDatabase *db) {
|
||||
}
|
||||
}
|
||||
|
||||
auto split = Strings::Split(buffer, '^');
|
||||
auto split = SplitString(buffer, '^');
|
||||
|
||||
if(split.size() < 2) {
|
||||
continue;
|
||||
@@ -338,12 +300,12 @@ void ImportDBStrings(SharedDatabase *db) {
|
||||
std::string sql;
|
||||
int id, type;
|
||||
std::string value;
|
||||
|
||||
|
||||
id = atoi(split[0].c_str());
|
||||
type = atoi(split[1].c_str());
|
||||
|
||||
|
||||
if(split.size() >= 3) {
|
||||
value = ::Strings::Escape(split[2]);
|
||||
value = ::EscapeString(split[2]);
|
||||
}
|
||||
|
||||
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON)
|
||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON)
|
||||
|
||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
||||
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-x86")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-x64")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86")
|
||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64")
|
||||
|
||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64})
|
||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64})
|
||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP})
|
||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR})
|
||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP})
|
||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR})
|
||||
ELSE()
|
||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86})
|
||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86})
|
||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP})
|
||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR})
|
||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP})
|
||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR})
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
||||
MESSAGE(STATUS "Resolving vcpkg dependencies...")
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
|
||||
|
||||
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
|
||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
||||
#Try to find perl first, (so you can use your active install first)
|
||||
FIND_PACKAGE(PerlLibs)
|
||||
|
||||
IF(NOT PerlLibs_FOUND)
|
||||
MESSAGE(STATUS "Resolving perl dependencies...")
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
|
||||
|
||||
MESSAGE(STATUS "Downloading portable perl...")
|
||||
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
|
||||
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
|
||||
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -0,0 +1,124 @@
|
||||
#CMake - Cross Platform Makefile Generator
|
||||
#Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
|
||||
#All rights reserved.
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions
|
||||
#are met:
|
||||
#
|
||||
#* Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
#* Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||
# nor the names of their contributors may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# This module defines
|
||||
# LUA51_FOUND, if false, do not try to link to Lua
|
||||
# LUA_LIBRARIES
|
||||
# LUA_INCLUDE_DIR, where to find lua.h
|
||||
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
|
||||
IF(LUA_ROOT)
|
||||
FIND_PATH(LUA_INCLUDE_DIR
|
||||
NAMES lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
${LUA_ROOT}
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include src
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUA_LIBRARY
|
||||
NAMES lua51 lua5.1 lua-5.1 lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
${LUA_ROOT}
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES lib bin
|
||||
)
|
||||
ELSE(LUA_ROOT)
|
||||
FIND_PATH(LUA_INCLUDE_DIR
|
||||
NAMES lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUA_LIBRARY
|
||||
NAMES lua51 lua5.1 lua-5.1 lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
PATH_SUFFIXES lib bin
|
||||
)
|
||||
ENDIF(LUA_ROOT)
|
||||
|
||||
IF(LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
IF(UNIX AND NOT APPLE)
|
||||
FIND_LIBRARY(LUA_MATH_LIBRARY m)
|
||||
SET(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
ELSE()
|
||||
SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||
|
||||
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||
UNSET(lua_version_str)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
# Modified from the FindLua51 that comes with CMake
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindLua51
|
||||
---------
|
||||
|
||||
|
||||
|
||||
Locate Lua51 library This module defines
|
||||
|
||||
::
|
||||
|
||||
LUA51_FOUND, if false, do not try to link to Lua
|
||||
LUA_LIBRARIES
|
||||
LUA_INCLUDE_DIR, where to find lua.h
|
||||
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
|
||||
|
||||
|
||||
Note that the expected include convention is
|
||||
|
||||
::
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
and not
|
||||
|
||||
::
|
||||
|
||||
#include <lua/lua.h>
|
||||
|
||||
This is because, the lua location is not standardized and may exist in
|
||||
locations other than lua/
|
||||
#]=======================================================================]
|
||||
|
||||
find_path(LUA_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
find_library(LUA_LIBRARY
|
||||
NAMES lua51 lua5.1 lua-5.1 lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
if(LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
|
||||
find_library(LUA_MATH_LIBRARY m)
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
else()
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||
|
||||
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||
unset(lua_version_str)
|
||||
endif()
|
||||
|
||||
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
# Modified from the FindLua51 that comes with CMake
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindLuaJit
|
||||
---------
|
||||
|
||||
|
||||
|
||||
Locate LuaJit library This module defines
|
||||
|
||||
::
|
||||
|
||||
LUAJIT_FOUND, if false, do not try to link to Lua
|
||||
LUAJIT_LIBRARIES
|
||||
LUAJIT_INCLUDE_DIR, where to find lua.h
|
||||
LUAJIT_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
|
||||
|
||||
|
||||
Note that the expected include convention is
|
||||
|
||||
::
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
and not
|
||||
|
||||
::
|
||||
|
||||
#include <lua/lua.h>
|
||||
|
||||
This is because, the lua location is not standardized and may exist in
|
||||
locations other than lua/
|
||||
#]=======================================================================]
|
||||
|
||||
find_path(LUAJIT_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES include/luajit include/luajit-2.0 include/luajit-2.1 include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
find_library(LUAJIT_LIBRARY
|
||||
NAMES luajit51 luajit5.1 luajit-5.1 luajit lua51
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
if(LUAJIT_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
|
||||
find_library(LUAJIT_MATH_LIBRARY m)
|
||||
set( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY};${LUAJIT_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
else()
|
||||
set( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LUAJIT_INCLUDE_DIR AND EXISTS "${LUAJIT_INCLUDE_DIR}/lua.h")
|
||||
file(STRINGS "${LUAJIT_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||
|
||||
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUAJIT_VERSION_STRING "${lua_version_str}")
|
||||
unset(lua_version_str)
|
||||
endif()
|
||||
|
||||
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJit
|
||||
REQUIRED_VARS LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR
|
||||
VERSION_VAR LUAJIT_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
# - Find mariadbclient
|
||||
#
|
||||
# -*- cmake -*-
|
||||
#
|
||||
# Find the native MariaDB includes and library
|
||||
#
|
||||
# MariaDB_INCLUDE_DIR - where to find mysql.h, etc.
|
||||
# MariaDB_LIBRARIES - List of libraries when using MariaDB.
|
||||
# MariaDB_FOUND - True if MariaDB found.
|
||||
# The following can be used as a hint as to where to search:
|
||||
# MARIADB_ROOT
|
||||
|
||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
||||
# Already in cache, be silent
|
||||
SET(MariaDB_FIND_QUIETLY TRUE)
|
||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
||||
|
||||
# Include dir
|
||||
IF(MARIADB_ROOT)
|
||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
||||
NAMES mariadb_version.h
|
||||
PATHS ${MARIADB_ROOT}/include
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
NO_DEFAULT_PATH
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
||||
NAMES mariadb_version.h
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ELSE(MARIADB_ROOT)
|
||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
||||
NAMES mariadb_version.h
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ENDIF(MARIADB_ROOT)
|
||||
|
||||
# Library
|
||||
SET(MariaDB_NAMES libmariadb)
|
||||
IF(MARIADB_ROOT)
|
||||
FIND_LIBRARY(MariaDB_LIBRARY
|
||||
NAMES ${MariaDB_NAMES}
|
||||
PATHS ${MARIADB_ROOT}/lib
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
NO_DEFAULT_PATH
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
|
||||
FIND_LIBRARY(MariaDB_LIBRARY
|
||||
NAMES ${MariaDB_NAMES}
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ELSE(MARIADB_ROOT)
|
||||
FIND_LIBRARY(MariaDB_LIBRARY
|
||||
NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient
|
||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
||||
PATH_SUFFIXES mysql mariadb
|
||||
)
|
||||
ENDIF(MARIADB_ROOT)
|
||||
|
||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
||||
SET(MariaDB_FOUND TRUE)
|
||||
SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY})
|
||||
ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
||||
SET(MariaDB_FOUND FALSE)
|
||||
SET(MariaDB_LIBRARIES)
|
||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
||||
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR)
|
||||
|
||||
IF(MariaDB_FOUND)
|
||||
SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} )
|
||||
SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} )
|
||||
SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} )
|
||||
ELSE(MariaDB_FOUND)
|
||||
SET( MariaDB_LIBRARIES )
|
||||
ENDIF(MariaDB_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
MariaDB_LIBRARY_DEBUG
|
||||
MariaDB_LIBRARY_RELEASE
|
||||
MariaDB_INCLUDE_DIR
|
||||
)
|
||||
@@ -0,0 +1,386 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindPackageHandleStandardArgs
|
||||
-----------------------------
|
||||
|
||||
This module provides a function intended to be used in :ref:`Find Modules`
|
||||
implementing :command:`find_package(<PackageName>)` calls. It handles the
|
||||
``REQUIRED``, ``QUIET`` and version-related arguments of ``find_package``.
|
||||
It also sets the ``<PackageName>_FOUND`` variable. The package is
|
||||
considered found if all variables listed contain valid results, e.g.
|
||||
valid filepaths.
|
||||
|
||||
.. command:: find_package_handle_standard_args
|
||||
|
||||
There are two signatures::
|
||||
|
||||
find_package_handle_standard_args(<PackageName>
|
||||
(DEFAULT_MSG|<custom-failure-message>)
|
||||
<required-var>...
|
||||
)
|
||||
|
||||
find_package_handle_standard_args(<PackageName>
|
||||
[FOUND_VAR <result-var>]
|
||||
[REQUIRED_VARS <required-var>...]
|
||||
[VERSION_VAR <version-var>]
|
||||
[HANDLE_COMPONENTS]
|
||||
[CONFIG_MODE]
|
||||
[FAIL_MESSAGE <custom-failure-message>]
|
||||
)
|
||||
|
||||
The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
|
||||
the variables ``<required-var>...`` are valid and any optional
|
||||
constraints are satisfied, and ``FALSE`` otherwise. A success or
|
||||
failure message may be displayed based on the results and on
|
||||
whether the ``REQUIRED`` and/or ``QUIET`` option was given to
|
||||
the :command:`find_package` call.
|
||||
|
||||
The options are:
|
||||
|
||||
``(DEFAULT_MSG|<custom-failure-message>)``
|
||||
In the simple signature this specifies the failure message.
|
||||
Use ``DEFAULT_MSG`` to ask for a default message to be computed
|
||||
(recommended). Not valid in the full signature.
|
||||
|
||||
``FOUND_VAR <result-var>``
|
||||
Obsolete. Specifies either ``<PackageName>_FOUND`` or
|
||||
``<PACKAGENAME>_FOUND`` as the result variable. This exists only
|
||||
for compatibility with older versions of CMake and is now ignored.
|
||||
Result variables of both names are always set for compatibility.
|
||||
|
||||
``REQUIRED_VARS <required-var>...``
|
||||
Specify the variables which are required for this package.
|
||||
These may be named in the generated failure message asking the
|
||||
user to set the missing variable values. Therefore these should
|
||||
typically be cache entries such as ``FOO_LIBRARY`` and not output
|
||||
variables like ``FOO_LIBRARIES``.
|
||||
|
||||
``VERSION_VAR <version-var>``
|
||||
Specify the name of a variable that holds the version of the package
|
||||
that has been found. This version will be checked against the
|
||||
(potentially) specified required version given to the
|
||||
:command:`find_package` call, including its ``EXACT`` option.
|
||||
The default messages include information about the required
|
||||
version and the version which has been actually found, both
|
||||
if the version is ok or not.
|
||||
|
||||
``HANDLE_COMPONENTS``
|
||||
Enable handling of package components. In this case, the command
|
||||
will report which components have been found and which are missing,
|
||||
and the ``<PackageName>_FOUND`` variable will be set to ``FALSE``
|
||||
if any of the required components (i.e. not the ones listed after
|
||||
the ``OPTIONAL_COMPONENTS`` option of :command:`find_package`) are
|
||||
missing.
|
||||
|
||||
``CONFIG_MODE``
|
||||
Specify that the calling find module is a wrapper around a
|
||||
call to ``find_package(<PackageName> NO_MODULE)``. This implies
|
||||
a ``VERSION_VAR`` value of ``<PackageName>_VERSION``. The command
|
||||
will automatically check whether the package configuration file
|
||||
was found.
|
||||
|
||||
``FAIL_MESSAGE <custom-failure-message>``
|
||||
Specify a custom failure message instead of using the default
|
||||
generated message. Not recommended.
|
||||
|
||||
Example for the simple signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_handle_standard_args(LibXml2 DEFAULT_MSG
|
||||
LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
|
||||
|
||||
The ``LibXml2`` package is considered to be found if both
|
||||
``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
|
||||
Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found
|
||||
and ``REQUIRED`` was used, it fails with a
|
||||
:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
|
||||
used or not. If it is found, success will be reported, including
|
||||
the content of the first ``<required-var>``. On repeated CMake runs,
|
||||
the same message will not be printed again.
|
||||
|
||||
Example for the full signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package_handle_standard_args(LibArchive
|
||||
REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
|
||||
VERSION_VAR LibArchive_VERSION)
|
||||
|
||||
In this case, the ``LibArchive`` package is considered to be found if
|
||||
both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
|
||||
Also the version of ``LibArchive`` will be checked by using the version
|
||||
contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given,
|
||||
the default messages will be printed.
|
||||
|
||||
Another example for the full signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
|
||||
find_package_handle_standard_args(Automoc4 CONFIG_MODE)
|
||||
|
||||
In this case, a ``FindAutmoc4.cmake`` module wraps a call to
|
||||
``find_package(Automoc4 NO_MODULE)`` and adds an additional search
|
||||
directory for ``automoc4``. Then the call to
|
||||
``find_package_handle_standard_args`` produces a proper success/failure
|
||||
message.
|
||||
#]=======================================================================]
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
|
||||
|
||||
# internal helper macro
|
||||
macro(_FPHSA_FAILURE_MESSAGE _msg)
|
||||
if (${_NAME}_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "${_msg}")
|
||||
else ()
|
||||
if (NOT ${_NAME}_FIND_QUIETLY)
|
||||
message(STATUS "${_msg}")
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro()
|
||||
|
||||
|
||||
# internal helper macro to generate the failure message when used in CONFIG_MODE:
|
||||
macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE)
|
||||
# <name>_CONFIG is set, but FOUND is false, this means that some other of the REQUIRED_VARS was not found:
|
||||
if(${_NAME}_CONFIG)
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: missing:${MISSING_VARS} (found ${${_NAME}_CONFIG} ${VERSION_MSG})")
|
||||
else()
|
||||
# If _CONSIDERED_CONFIGS is set, the config-file has been found, but no suitable version.
|
||||
# List them all in the error message:
|
||||
if(${_NAME}_CONSIDERED_CONFIGS)
|
||||
set(configsText "")
|
||||
list(LENGTH ${_NAME}_CONSIDERED_CONFIGS configsCount)
|
||||
math(EXPR configsCount "${configsCount} - 1")
|
||||
foreach(currentConfigIndex RANGE ${configsCount})
|
||||
list(GET ${_NAME}_CONSIDERED_CONFIGS ${currentConfigIndex} filename)
|
||||
list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version)
|
||||
string(APPEND configsText " ${filename} (version ${version})\n")
|
||||
endforeach()
|
||||
if (${_NAME}_NOT_FOUND_MESSAGE)
|
||||
string(APPEND configsText " Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n")
|
||||
endif()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}")
|
||||
|
||||
else()
|
||||
# Simple case: No Config-file was found at all:
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: found neither ${_NAME}Config.cmake nor ${_NAME_LOWER}-config.cmake ${VERSION_MSG}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
|
||||
|
||||
# Set up the arguments for `cmake_parse_arguments`.
|
||||
set(options CONFIG_MODE HANDLE_COMPONENTS)
|
||||
set(oneValueArgs FAIL_MESSAGE VERSION_VAR FOUND_VAR)
|
||||
set(multiValueArgs REQUIRED_VARS)
|
||||
|
||||
# Check whether we are in 'simple' or 'extended' mode:
|
||||
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
|
||||
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
|
||||
|
||||
if(${INDEX} EQUAL -1)
|
||||
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
|
||||
set(FPHSA_REQUIRED_VARS ${ARGN})
|
||||
set(FPHSA_VERSION_VAR)
|
||||
else()
|
||||
cmake_parse_arguments(FPHSA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN})
|
||||
|
||||
if(FPHSA_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unknown keywords given to FIND_PACKAGE_HANDLE_STANDARD_ARGS(): \"${FPHSA_UNPARSED_ARGUMENTS}\"")
|
||||
endif()
|
||||
|
||||
if(NOT FPHSA_FAIL_MESSAGE)
|
||||
set(FPHSA_FAIL_MESSAGE "DEFAULT_MSG")
|
||||
endif()
|
||||
|
||||
# In config-mode, we rely on the variable <package>_CONFIG, which is set by find_package()
|
||||
# when it successfully found the config-file, including version checking:
|
||||
if(FPHSA_CONFIG_MODE)
|
||||
list(INSERT FPHSA_REQUIRED_VARS 0 ${_NAME}_CONFIG)
|
||||
list(REMOVE_DUPLICATES FPHSA_REQUIRED_VARS)
|
||||
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
|
||||
endif()
|
||||
|
||||
if(NOT FPHSA_REQUIRED_VARS)
|
||||
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# now that we collected all arguments, process them
|
||||
|
||||
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
|
||||
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
|
||||
endif()
|
||||
|
||||
list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
|
||||
|
||||
string(TOUPPER ${_NAME} _NAME_UPPER)
|
||||
string(TOLOWER ${_NAME} _NAME_LOWER)
|
||||
|
||||
if(FPHSA_FOUND_VAR)
|
||||
if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
|
||||
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
|
||||
else()
|
||||
message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
|
||||
endif()
|
||||
else()
|
||||
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
|
||||
endif()
|
||||
|
||||
# collect all variables which were not found, so they can be printed, so the
|
||||
# user knows better what went wrong (#6375)
|
||||
set(MISSING_VARS "")
|
||||
set(DETAILS "")
|
||||
# check if all passed variables are valid
|
||||
set(FPHSA_FOUND_${_NAME} TRUE)
|
||||
foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS})
|
||||
if(NOT ${_CURRENT_VAR})
|
||||
set(FPHSA_FOUND_${_NAME} FALSE)
|
||||
string(APPEND MISSING_VARS " ${_CURRENT_VAR}")
|
||||
else()
|
||||
string(APPEND DETAILS "[${${_CURRENT_VAR}}]")
|
||||
endif()
|
||||
endforeach()
|
||||
if(FPHSA_FOUND_${_NAME})
|
||||
set(${_NAME}_FOUND TRUE)
|
||||
set(${_NAME_UPPER}_FOUND TRUE)
|
||||
else()
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
set(${_NAME_UPPER}_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
# component handling
|
||||
unset(FOUND_COMPONENTS_MSG)
|
||||
unset(MISSING_COMPONENTS_MSG)
|
||||
|
||||
if(FPHSA_HANDLE_COMPONENTS)
|
||||
foreach(comp ${${_NAME}_FIND_COMPONENTS})
|
||||
if(${_NAME}_${comp}_FOUND)
|
||||
|
||||
if(NOT DEFINED FOUND_COMPONENTS_MSG)
|
||||
set(FOUND_COMPONENTS_MSG "found components: ")
|
||||
endif()
|
||||
string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
|
||||
|
||||
else()
|
||||
|
||||
if(NOT DEFINED MISSING_COMPONENTS_MSG)
|
||||
set(MISSING_COMPONENTS_MSG "missing components: ")
|
||||
endif()
|
||||
string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
|
||||
|
||||
if(${_NAME}_FIND_REQUIRED_${comp})
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
string(APPEND MISSING_VARS " ${comp}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endforeach()
|
||||
set(COMPONENT_MSG "${FOUND_COMPONENTS_MSG} ${MISSING_COMPONENTS_MSG}")
|
||||
string(APPEND DETAILS "[c${COMPONENT_MSG}]")
|
||||
endif()
|
||||
|
||||
# version handling:
|
||||
set(VERSION_MSG "")
|
||||
set(VERSION_OK TRUE)
|
||||
|
||||
# check with DEFINED here as the requested or found version may be "0"
|
||||
if (DEFINED ${_NAME}_FIND_VERSION)
|
||||
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||
set(_FOUND_VERSION ${${FPHSA_VERSION_VAR}})
|
||||
|
||||
if(${_NAME}_FIND_VERSION_EXACT) # exact version required
|
||||
# count the dots in the version string
|
||||
string(REGEX REPLACE "[^.]" "" _VERSION_DOTS "${_FOUND_VERSION}")
|
||||
# add one dot because there is one dot more than there are components
|
||||
string(LENGTH "${_VERSION_DOTS}." _VERSION_DOTS)
|
||||
if (_VERSION_DOTS GREATER ${_NAME}_FIND_VERSION_COUNT)
|
||||
# Because of the C++ implementation of find_package() ${_NAME}_FIND_VERSION_COUNT
|
||||
# is at most 4 here. Therefore a simple lookup table is used.
|
||||
if (${_NAME}_FIND_VERSION_COUNT EQUAL 1)
|
||||
set(_VERSION_REGEX "[^.]*")
|
||||
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 2)
|
||||
set(_VERSION_REGEX "[^.]*\\.[^.]*")
|
||||
elseif (${_NAME}_FIND_VERSION_COUNT EQUAL 3)
|
||||
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*")
|
||||
else ()
|
||||
set(_VERSION_REGEX "[^.]*\\.[^.]*\\.[^.]*\\.[^.]*")
|
||||
endif ()
|
||||
string(REGEX REPLACE "^(${_VERSION_REGEX})\\..*" "\\1" _VERSION_HEAD "${_FOUND_VERSION}")
|
||||
unset(_VERSION_REGEX)
|
||||
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _VERSION_HEAD)
|
||||
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||
set(VERSION_OK FALSE)
|
||||
else ()
|
||||
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
|
||||
endif ()
|
||||
unset(_VERSION_HEAD)
|
||||
else ()
|
||||
if (NOT ${_NAME}_FIND_VERSION VERSION_EQUAL _FOUND_VERSION)
|
||||
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is exact version \"${${_NAME}_FIND_VERSION}\"")
|
||||
set(VERSION_OK FALSE)
|
||||
else ()
|
||||
set(VERSION_MSG "(found suitable exact version \"${_FOUND_VERSION}\")")
|
||||
endif ()
|
||||
endif ()
|
||||
unset(_VERSION_DOTS)
|
||||
|
||||
else() # minimum version specified:
|
||||
if (${_NAME}_FIND_VERSION VERSION_GREATER _FOUND_VERSION)
|
||||
set(VERSION_MSG "Found unsuitable version \"${_FOUND_VERSION}\", but required is at least \"${${_NAME}_FIND_VERSION}\"")
|
||||
set(VERSION_OK FALSE)
|
||||
else ()
|
||||
set(VERSION_MSG "(found suitable version \"${_FOUND_VERSION}\", minimum required is \"${${_NAME}_FIND_VERSION}\")")
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
# if the package was not found, but a version was given, add that to the output:
|
||||
if(${_NAME}_FIND_VERSION_EXACT)
|
||||
set(VERSION_MSG "(Required is exact version \"${${_NAME}_FIND_VERSION}\")")
|
||||
else()
|
||||
set(VERSION_MSG "(Required is at least version \"${${_NAME}_FIND_VERSION}\")")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
else ()
|
||||
# Check with DEFINED as the found version may be 0.
|
||||
if(DEFINED ${FPHSA_VERSION_VAR})
|
||||
set(VERSION_MSG "(found version \"${${FPHSA_VERSION_VAR}}\")")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if(VERSION_OK)
|
||||
string(APPEND DETAILS "[v${${FPHSA_VERSION_VAR}}(${${_NAME}_FIND_VERSION})]")
|
||||
else()
|
||||
set(${_NAME}_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
# print the result:
|
||||
if (${_NAME}_FOUND)
|
||||
FIND_PACKAGE_MESSAGE(${_NAME} "Found ${_NAME}: ${${_FIRST_REQUIRED_VAR}} ${VERSION_MSG} ${COMPONENT_MSG}" "${DETAILS}")
|
||||
else ()
|
||||
|
||||
if(FPHSA_CONFIG_MODE)
|
||||
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
|
||||
else()
|
||||
if(NOT VERSION_OK)
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
|
||||
else()
|
||||
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif ()
|
||||
|
||||
set(${_NAME}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
|
||||
set(${_NAME_UPPER}_FOUND ${${_NAME}_FOUND} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,47 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# FindPackageMessage
|
||||
# ------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
|
||||
#
|
||||
# This macro is intended to be used in FindXXX.cmake modules files. It
|
||||
# will print a message once for each unique find result. This is useful
|
||||
# for telling the user where a package was found. The first argument
|
||||
# specifies the name (XXX) of the package. The second argument
|
||||
# specifies the message to display. The third argument lists details
|
||||
# about the find result so that if they change the message will be
|
||||
# displayed again. The macro also obeys the QUIET argument to the
|
||||
# find_package command.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# if(X11_FOUND)
|
||||
# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
|
||||
# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
|
||||
# else()
|
||||
# ...
|
||||
# endif()
|
||||
|
||||
function(FIND_PACKAGE_MESSAGE pkg msg details)
|
||||
# Avoid printing a message repeatedly for the same find result.
|
||||
if(NOT ${pkg}_FIND_QUIETLY)
|
||||
string(REPLACE "\n" "" details "${details}")
|
||||
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
|
||||
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
|
||||
# The message has not yet been printed.
|
||||
message(STATUS "${msg}")
|
||||
|
||||
# Save the find details in the cache to avoid printing the same
|
||||
# message again.
|
||||
set("${DETAILS_VAR}" "${details}"
|
||||
CACHE INTERNAL "Details about finding ${pkg}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,579 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# FindProtobuf
|
||||
# ------------
|
||||
#
|
||||
# Locate and configure the Google Protocol Buffers library.
|
||||
#
|
||||
# The following variables can be set and are optional:
|
||||
#
|
||||
# ``Protobuf_SRC_ROOT_FOLDER``
|
||||
# When compiling with MSVC, if this cache variable is set
|
||||
# the protobuf-default VS project build locations
|
||||
# (vsprojects/Debug and vsprojects/Release
|
||||
# or vsprojects/x64/Debug and vsprojects/x64/Release)
|
||||
# will be searched for libraries and binaries.
|
||||
# ``Protobuf_IMPORT_DIRS``
|
||||
# List of additional directories to be searched for
|
||||
# imported .proto files.
|
||||
# ``Protobuf_DEBUG``
|
||||
# Show debug messages.
|
||||
# ``Protobuf_USE_STATIC_LIBS``
|
||||
# Set to ON to force the use of the static libraries.
|
||||
# Default is OFF.
|
||||
#
|
||||
# Defines the following variables:
|
||||
#
|
||||
# ``Protobuf_FOUND``
|
||||
# Found the Google Protocol Buffers library
|
||||
# (libprotobuf & header files)
|
||||
# ``Protobuf_VERSION``
|
||||
# Version of package found.
|
||||
# ``Protobuf_INCLUDE_DIRS``
|
||||
# Include directories for Google Protocol Buffers
|
||||
# ``Protobuf_LIBRARIES``
|
||||
# The protobuf libraries
|
||||
# ``Protobuf_PROTOC_LIBRARIES``
|
||||
# The protoc libraries
|
||||
# ``Protobuf_LITE_LIBRARIES``
|
||||
# The protobuf-lite libraries
|
||||
#
|
||||
# The following :prop_tgt:`IMPORTED` targets are also defined:
|
||||
#
|
||||
# ``protobuf::libprotobuf``
|
||||
# The protobuf library.
|
||||
# ``protobuf::libprotobuf-lite``
|
||||
# The protobuf lite library.
|
||||
# ``protobuf::libprotoc``
|
||||
# The protoc library.
|
||||
# ``protobuf::protoc``
|
||||
# The protoc compiler.
|
||||
#
|
||||
# The following cache variables are also available to set or use:
|
||||
#
|
||||
# ``Protobuf_LIBRARY``
|
||||
# The protobuf library
|
||||
# ``Protobuf_PROTOC_LIBRARY``
|
||||
# The protoc library
|
||||
# ``Protobuf_INCLUDE_DIR``
|
||||
# The include directory for protocol buffers
|
||||
# ``Protobuf_PROTOC_EXECUTABLE``
|
||||
# The protoc compiler
|
||||
# ``Protobuf_LIBRARY_DEBUG``
|
||||
# The protobuf library (debug)
|
||||
# ``Protobuf_PROTOC_LIBRARY_DEBUG``
|
||||
# The protoc library (debug)
|
||||
# ``Protobuf_LITE_LIBRARY``
|
||||
# The protobuf lite library
|
||||
# ``Protobuf_LITE_LIBRARY_DEBUG``
|
||||
# The protobuf lite library (debug)
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# .. code-block:: cmake
|
||||
#
|
||||
# find_package(Protobuf REQUIRED)
|
||||
# include_directories(${Protobuf_INCLUDE_DIRS})
|
||||
# include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
|
||||
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
|
||||
# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS foo.proto)
|
||||
# protobuf_generate_python(PROTO_PY foo.proto)
|
||||
# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
|
||||
# target_link_libraries(bar ${Protobuf_LIBRARIES})
|
||||
#
|
||||
# .. note::
|
||||
# The ``protobuf_generate_cpp`` and ``protobuf_generate_python``
|
||||
# functions and :command:`add_executable` or :command:`add_library`
|
||||
# calls only work properly within the same directory.
|
||||
#
|
||||
# .. command:: protobuf_generate_cpp
|
||||
#
|
||||
# Add custom commands to process ``.proto`` files to C++::
|
||||
#
|
||||
# protobuf_generate_cpp (<SRCS> <HDRS>
|
||||
# [DESCRIPTORS <DESC>] [EXPORT_MACRO <MACRO>] [<ARGN>...])
|
||||
#
|
||||
# ``SRCS``
|
||||
# Variable to define with autogenerated source files
|
||||
# ``HDRS``
|
||||
# Variable to define with autogenerated header files
|
||||
# ``DESCRIPTORS``
|
||||
# Variable to define with autogenerated descriptor files, if requested.
|
||||
# ``EXPORT_MACRO``
|
||||
# is a macro which should expand to ``__declspec(dllexport)`` or
|
||||
# ``__declspec(dllimport)`` depending on what is being compiled.
|
||||
# ``ARGN``
|
||||
# ``.proto`` files
|
||||
#
|
||||
# .. command:: protobuf_generate_python
|
||||
#
|
||||
# Add custom commands to process ``.proto`` files to Python::
|
||||
#
|
||||
# protobuf_generate_python (<PY> [<ARGN>...])
|
||||
#
|
||||
# ``PY``
|
||||
# Variable to define with autogenerated Python files
|
||||
# ``ARGN``
|
||||
# ``.proto`` filess
|
||||
|
||||
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
|
||||
cmake_parse_arguments(protobuf "" "EXPORT_MACRO;DESCRIPTORS" "" ${ARGN})
|
||||
|
||||
set(PROTO_FILES "${protobuf_UNPARSED_ARGUMENTS}")
|
||||
if(NOT PROTO_FILES)
|
||||
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(protobuf_EXPORT_MACRO)
|
||||
set(DLL_EXPORT_DECL "dllexport_decl=${protobuf_EXPORT_MACRO}:")
|
||||
endif()
|
||||
|
||||
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||
# Create an include path for each file specified
|
||||
foreach(FIL ${PROTO_FILES})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(DEFINED PROTOBUF_IMPORT_DIRS AND NOT DEFINED Protobuf_IMPORT_DIRS)
|
||||
set(Protobuf_IMPORT_DIRS "${PROTOBUF_IMPORT_DIRS}")
|
||||
endif()
|
||||
|
||||
if(DEFINED Protobuf_IMPORT_DIRS)
|
||||
foreach(DIR ${Protobuf_IMPORT_DIRS})
|
||||
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(${SRCS})
|
||||
set(${HDRS})
|
||||
if (protobuf_DESCRIPTORS)
|
||||
set(${protobuf_DESCRIPTORS})
|
||||
endif()
|
||||
|
||||
foreach(FIL ${PROTO_FILES})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
||||
if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||
get_filename_component(FIL_DIR ${FIL} DIRECTORY)
|
||||
if(FIL_DIR)
|
||||
set(FIL_WE "${FIL_DIR}/${FIL_WE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(_protobuf_protoc_src "${CMAKE_CURRENT_SOURCE_DIR}/${FIL_WE}.pb.cc")
|
||||
set(_protobuf_protoc_hdr "${CMAKE_CURRENT_SOURCE_DIR}/${FIL_WE}.pb.h")
|
||||
list(APPEND ${SRCS} "${_protobuf_protoc_src}")
|
||||
list(APPEND ${HDRS} "${_protobuf_protoc_hdr}")
|
||||
|
||||
if(protobuf_DESCRIPTORS)
|
||||
set(_protobuf_protoc_desc "${CMAKE_CURRENT_SOURCE_DIR}/${FIL_WE}.desc")
|
||||
set(_protobuf_protoc_flags "--descriptor_set_out=${_protobuf_protoc_desc}")
|
||||
list(APPEND ${protobuf_DESCRIPTORS} "${_protobuf_protoc_desc}")
|
||||
else()
|
||||
set(_protobuf_protoc_desc "")
|
||||
set(_protobuf_protoc_flags "")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${_protobuf_protoc_src}"
|
||||
"${_protobuf_protoc_hdr}"
|
||||
${_protobuf_protoc_desc}
|
||||
COMMAND protobuf::protoc
|
||||
"--cpp_out=${DLL_EXPORT_DECL}${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${_protobuf_protoc_flags}
|
||||
${_protobuf_include_path} ${ABS_FIL}
|
||||
DEPENDS ${ABS_FIL} protobuf::protoc
|
||||
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
|
||||
VERBATIM )
|
||||
endforeach()
|
||||
|
||||
set(${SRCS} "${${SRCS}}" PARENT_SCOPE)
|
||||
set(${HDRS} "${${HDRS}}" PARENT_SCOPE)
|
||||
if(protobuf_DESCRIPTORS)
|
||||
set(${protobuf_DESCRIPTORS} "${${protobuf_DESCRIPTORS}}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
function(PROTOBUF_GENERATE_PYTHON SRCS)
|
||||
if(NOT ARGN)
|
||||
message(SEND_ERROR "Error: PROTOBUF_GENERATE_PYTHON() called without any proto files")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||
# Create an include path for each file specified
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(DEFINED PROTOBUF_IMPORT_DIRS AND NOT DEFINED Protobuf_IMPORT_DIRS)
|
||||
set(Protobuf_IMPORT_DIRS "${PROTOBUF_IMPORT_DIRS}")
|
||||
endif()
|
||||
|
||||
if(DEFINED Protobuf_IMPORT_DIRS)
|
||||
foreach(DIR ${Protobuf_IMPORT_DIRS})
|
||||
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(${SRCS})
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
||||
if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||
get_filename_component(FIL_DIR ${FIL} DIRECTORY)
|
||||
if(FIL_DIR)
|
||||
set(FIL_WE "${FIL_DIR}/${FIL_WE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py")
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}_pb2.py"
|
||||
COMMAND protobuf::protoc --python_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
|
||||
DEPENDS ${ABS_FIL} protobuf::protoc
|
||||
COMMENT "Running Python protocol buffer compiler on ${FIL}"
|
||||
VERBATIM )
|
||||
endforeach()
|
||||
|
||||
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
if(Protobuf_DEBUG)
|
||||
# Output some of their choices
|
||||
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
|
||||
"Protobuf_USE_STATIC_LIBS = ${Protobuf_USE_STATIC_LIBS}")
|
||||
endif()
|
||||
|
||||
|
||||
# Backwards compatibility
|
||||
# Define camel case versions of input variables
|
||||
foreach(UPPER
|
||||
PROTOBUF_SRC_ROOT_FOLDER
|
||||
PROTOBUF_IMPORT_DIRS
|
||||
PROTOBUF_DEBUG
|
||||
PROTOBUF_LIBRARY
|
||||
PROTOBUF_PROTOC_LIBRARY
|
||||
PROTOBUF_INCLUDE_DIR
|
||||
PROTOBUF_PROTOC_EXECUTABLE
|
||||
PROTOBUF_LIBRARY_DEBUG
|
||||
PROTOBUF_PROTOC_LIBRARY_DEBUG
|
||||
PROTOBUF_LITE_LIBRARY
|
||||
PROTOBUF_LITE_LIBRARY_DEBUG
|
||||
)
|
||||
if (DEFINED ${UPPER})
|
||||
string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
|
||||
if (NOT DEFINED ${Camel})
|
||||
set(${Camel} ${${UPPER}})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_PROTOBUF_ARCH_DIR x64/)
|
||||
endif()
|
||||
|
||||
|
||||
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
|
||||
if( Protobuf_USE_STATIC_LIBS )
|
||||
set( _protobuf_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
if(WIN32)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
else()
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
|
||||
|
||||
# Internal function: search for normal library as well as a debug one
|
||||
# if the debug one is specified also include debug/optimized keywords
|
||||
# in *_LIBRARIES variable
|
||||
function(_protobuf_find_libraries name filename)
|
||||
if(${name}_LIBRARIES)
|
||||
# Use result recorded by a previous call.
|
||||
return()
|
||||
elseif(${name}_LIBRARY)
|
||||
# Honor cache entry used by CMake 3.5 and lower.
|
||||
set(${name}_LIBRARIES "${${name}_LIBRARY}" PARENT_SCOPE)
|
||||
else()
|
||||
find_library(${name}_LIBRARY_RELEASE
|
||||
NAMES ${filename}
|
||||
PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release)
|
||||
mark_as_advanced(${name}_LIBRARY_RELEASE)
|
||||
|
||||
find_library(${name}_LIBRARY_DEBUG
|
||||
NAMES ${filename}d ${filename}
|
||||
PATHS ${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug)
|
||||
mark_as_advanced(${name}_LIBRARY_DEBUG)
|
||||
|
||||
select_library_configurations(${name})
|
||||
set(${name}_LIBRARY "${${name}_LIBRARY}" PARENT_SCOPE)
|
||||
set(${name}_LIBRARIES "${${name}_LIBRARIES}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Internal function: find threads library
|
||||
function(_protobuf_find_threads)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
find_package(Threads)
|
||||
if(Threads_FOUND)
|
||||
list(APPEND Protobuf_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
set(Protobuf_LIBRARIES "${Protobuf_LIBRARIES}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# Main.
|
||||
#
|
||||
|
||||
# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc
|
||||
# for each directory where a proto file is referenced.
|
||||
if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH)
|
||||
set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
# Google's provided vcproj files generate libraries with a "lib"
|
||||
# prefix on Windows
|
||||
if(MSVC)
|
||||
set(Protobuf_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}")
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
|
||||
|
||||
find_path(Protobuf_SRC_ROOT_FOLDER protobuf.pc.in)
|
||||
endif()
|
||||
|
||||
# The Protobuf library
|
||||
_protobuf_find_libraries(Protobuf protobuf)
|
||||
#DOC "The Google Protocol Buffers RELEASE Library"
|
||||
|
||||
_protobuf_find_libraries(Protobuf_LITE protobuf-lite)
|
||||
|
||||
# The Protobuf Protoc Library
|
||||
_protobuf_find_libraries(Protobuf_PROTOC protoc)
|
||||
|
||||
# Restore original find library prefixes
|
||||
if(MSVC)
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES "${Protobuf_ORIG_FIND_LIBRARY_PREFIXES}")
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
_protobuf_find_threads()
|
||||
endif()
|
||||
|
||||
# Find the include directory
|
||||
find_path(Protobuf_INCLUDE_DIR
|
||||
google/protobuf/service.h
|
||||
PATHS ${Protobuf_SRC_ROOT_FOLDER}/src
|
||||
)
|
||||
mark_as_advanced(Protobuf_INCLUDE_DIR)
|
||||
|
||||
# Find the protoc Executable
|
||||
find_program(Protobuf_PROTOC_EXECUTABLE
|
||||
NAMES protoc
|
||||
DOC "The Google Protocol Buffers Compiler"
|
||||
PATHS /usr/bin
|
||||
${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Release
|
||||
${Protobuf_SRC_ROOT_FOLDER}/vsprojects/${_PROTOBUF_ARCH_DIR}Debug
|
||||
)
|
||||
mark_as_advanced(Protobuf_PROTOC_EXECUTABLE)
|
||||
|
||||
if(Protobuf_DEBUG)
|
||||
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
|
||||
"requested version of Google Protobuf is ${Protobuf_FIND_VERSION}")
|
||||
endif()
|
||||
|
||||
if(Protobuf_INCLUDE_DIR)
|
||||
set(_PROTOBUF_COMMON_HEADER ${Protobuf_INCLUDE_DIR}/google/protobuf/stubs/common.h)
|
||||
|
||||
if(Protobuf_DEBUG)
|
||||
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
|
||||
"location of common.h: ${_PROTOBUF_COMMON_HEADER}")
|
||||
endif()
|
||||
|
||||
set(Protobuf_VERSION "")
|
||||
set(Protobuf_LIB_VERSION "")
|
||||
file(STRINGS ${_PROTOBUF_COMMON_HEADER} _PROTOBUF_COMMON_H_CONTENTS REGEX "#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+")
|
||||
if(_PROTOBUF_COMMON_H_CONTENTS MATCHES "#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+([0-9]+)")
|
||||
set(Protobuf_LIB_VERSION "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
unset(_PROTOBUF_COMMON_H_CONTENTS)
|
||||
|
||||
math(EXPR _PROTOBUF_MAJOR_VERSION "${Protobuf_LIB_VERSION} / 1000000")
|
||||
math(EXPR _PROTOBUF_MINOR_VERSION "${Protobuf_LIB_VERSION} / 1000 % 1000")
|
||||
math(EXPR _PROTOBUF_SUBMINOR_VERSION "${Protobuf_LIB_VERSION} % 1000")
|
||||
set(Protobuf_VERSION "${_PROTOBUF_MAJOR_VERSION}.${_PROTOBUF_MINOR_VERSION}.${_PROTOBUF_SUBMINOR_VERSION}")
|
||||
|
||||
if(Protobuf_DEBUG)
|
||||
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
|
||||
"${_PROTOBUF_COMMON_HEADER} reveals protobuf ${Protobuf_VERSION}")
|
||||
endif()
|
||||
|
||||
# Check Protobuf compiler version to be aligned with libraries version
|
||||
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} --version
|
||||
OUTPUT_VARIABLE _PROTOBUF_PROTOC_EXECUTABLE_VERSION)
|
||||
|
||||
if("${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" MATCHES "libprotoc ([0-9.]+)")
|
||||
set(_PROTOBUF_PROTOC_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
|
||||
if(Protobuf_DEBUG)
|
||||
message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
|
||||
"${Protobuf_PROTOC_EXECUTABLE} reveals version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}")
|
||||
endif()
|
||||
|
||||
if(NOT "${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" VERSION_EQUAL "${Protobuf_VERSION}")
|
||||
message(WARNING "Protobuf compiler version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}"
|
||||
" doesn't match library version ${Protobuf_VERSION}")
|
||||
endif()
|
||||
|
||||
if(Protobuf_LIBRARY)
|
||||
if(NOT TARGET protobuf::libprotobuf)
|
||||
add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
|
||||
set_target_properties(protobuf::libprotobuf PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
|
||||
if(EXISTS "${Protobuf_LIBRARY}")
|
||||
set_target_properties(protobuf::libprotobuf PROPERTIES
|
||||
IMPORTED_LOCATION "${Protobuf_LIBRARY}")
|
||||
endif()
|
||||
if(EXISTS "${Protobuf_LIBRARY_RELEASE}")
|
||||
set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(protobuf::libprotobuf PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "${Protobuf_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
if(EXISTS "${Protobuf_LIBRARY_DEBUG}")
|
||||
set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(protobuf::libprotobuf PROPERTIES
|
||||
IMPORTED_LOCATION_DEBUG "${Protobuf_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Protobuf_LITE_LIBRARY)
|
||||
if(NOT TARGET protobuf::libprotobuf-lite)
|
||||
add_library(protobuf::libprotobuf-lite UNKNOWN IMPORTED)
|
||||
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
|
||||
if(EXISTS "${Protobuf_LITE_LIBRARY}")
|
||||
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
|
||||
IMPORTED_LOCATION "${Protobuf_LITE_LIBRARY}")
|
||||
endif()
|
||||
if(EXISTS "${Protobuf_LITE_LIBRARY_RELEASE}")
|
||||
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "${Protobuf_LITE_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
if(EXISTS "${Protobuf_LITE_LIBRARY_DEBUG}")
|
||||
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
|
||||
IMPORTED_LOCATION_DEBUG "${Protobuf_LITE_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Protobuf_PROTOC_LIBRARY)
|
||||
if(NOT TARGET protobuf::libprotoc)
|
||||
add_library(protobuf::libprotoc UNKNOWN IMPORTED)
|
||||
set_target_properties(protobuf::libprotoc PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}")
|
||||
if(EXISTS "${Protobuf_PROTOC_LIBRARY}")
|
||||
set_target_properties(protobuf::libprotoc PROPERTIES
|
||||
IMPORTED_LOCATION "${Protobuf_PROTOC_LIBRARY}")
|
||||
endif()
|
||||
if(EXISTS "${Protobuf_PROTOC_LIBRARY_RELEASE}")
|
||||
set_property(TARGET protobuf::libprotoc APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS RELEASE)
|
||||
set_target_properties(protobuf::libprotoc PROPERTIES
|
||||
IMPORTED_LOCATION_RELEASE "${Protobuf_PROTOC_LIBRARY_RELEASE}")
|
||||
endif()
|
||||
if(EXISTS "${Protobuf_PROTOC_LIBRARY_DEBUG}")
|
||||
set_property(TARGET protobuf::libprotoc APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS DEBUG)
|
||||
set_target_properties(protobuf::libprotoc PROPERTIES
|
||||
IMPORTED_LOCATION_DEBUG "${Protobuf_PROTOC_LIBRARY_DEBUG}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Protobuf_PROTOC_EXECUTABLE)
|
||||
if(NOT TARGET protobuf::protoc)
|
||||
add_executable(protobuf::protoc IMPORTED)
|
||||
if(EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
set_target_properties(protobuf::protoc PROPERTIES
|
||||
IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Protobuf
|
||||
REQUIRED_VARS Protobuf_LIBRARIES Protobuf_INCLUDE_DIR
|
||||
VERSION_VAR Protobuf_VERSION
|
||||
)
|
||||
|
||||
if(Protobuf_FOUND)
|
||||
set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
# Restore the original find library ordering
|
||||
if( Protobuf_USE_STATIC_LIBS )
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_protobuf_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
endif()
|
||||
|
||||
# Backwards compatibility
|
||||
# Define upper case versions of output variables
|
||||
foreach(Camel
|
||||
Protobuf_SRC_ROOT_FOLDER
|
||||
Protobuf_IMPORT_DIRS
|
||||
Protobuf_DEBUG
|
||||
Protobuf_INCLUDE_DIRS
|
||||
Protobuf_LIBRARIES
|
||||
Protobuf_PROTOC_LIBRARIES
|
||||
Protobuf_LITE_LIBRARIES
|
||||
Protobuf_LIBRARY
|
||||
Protobuf_PROTOC_LIBRARY
|
||||
Protobuf_INCLUDE_DIR
|
||||
Protobuf_PROTOC_EXECUTABLE
|
||||
Protobuf_LIBRARY_DEBUG
|
||||
Protobuf_PROTOC_LIBRARY_DEBUG
|
||||
Protobuf_LITE_LIBRARY
|
||||
Protobuf_LITE_LIBRARY_DEBUG
|
||||
)
|
||||
string(TOUPPER ${Camel} UPPER)
|
||||
set(${UPPER} ${${Camel}})
|
||||
endforeach()
|
||||
@@ -1,93 +0,0 @@
|
||||
# - Try to find mbedTLS
|
||||
# Once done this will define
|
||||
#
|
||||
# Read-Only variables
|
||||
# MBEDTLS_FOUND - system has mbedTLS
|
||||
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
|
||||
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
|
||||
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
|
||||
# MBEDTLS_LIBRARY - path to mbedTLS library
|
||||
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
|
||||
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
|
||||
#
|
||||
# Hint
|
||||
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.
|
||||
|
||||
SET(_MBEDTLS_ROOT_HINTS
|
||||
${MBEDTLS_ROOT_DIR}
|
||||
ENV MBEDTLS_ROOT_DIR
|
||||
)
|
||||
|
||||
SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
||||
PATHS ${_MBEDTLS_ROOT_PATHS}
|
||||
)
|
||||
|
||||
FIND_PATH(MBEDTLS_INCLUDE_DIR
|
||||
NAMES mbedtls/version.h
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
|
||||
# Already in cache, be silent
|
||||
SET(MBEDTLS_FIND_QUIETLY TRUE)
|
||||
ENDIF()
|
||||
|
||||
FIND_LIBRARY(MBEDTLS_LIBRARY
|
||||
NAMES mbedtls libmbedtls
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES library
|
||||
)
|
||||
FIND_LIBRARY(MBEDX509_LIBRARY
|
||||
NAMES mbedx509 libmbedx509
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES library
|
||||
)
|
||||
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
|
||||
NAMES mbedcrypto libmbedcrypto
|
||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
||||
PATH_SUFFIXES library
|
||||
)
|
||||
|
||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
|
||||
SET(MBEDTLS_FOUND TRUE)
|
||||
ENDIF()
|
||||
|
||||
IF(MBEDTLS_FOUND)
|
||||
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
|
||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
|
||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
|
||||
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
|
||||
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
|
||||
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
|
||||
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
|
||||
|
||||
IF(NOT MBEDTLS_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found mbedTLS:")
|
||||
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
|
||||
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
|
||||
IF (MBEDTLSMATCH)
|
||||
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
|
||||
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
|
||||
ENDIF(MBEDTLSMATCH)
|
||||
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
|
||||
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
|
||||
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
|
||||
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
|
||||
ELSE(MBEDTLS_FOUND)
|
||||
IF(MBEDTLS_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
|
||||
ENDIF(MBEDTLS_FIND_REQUIRED)
|
||||
ENDIF(MBEDTLS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
MBEDTLS_INCLUDE_DIR
|
||||
MBEDTLS_LIBRARY_DIR
|
||||
MBEDTLS_LIBRARIES
|
||||
MBEDTLS_LIBRARY
|
||||
MBEDX509_LIBRARY
|
||||
MBEDCRYPTO_LIBRARY
|
||||
)
|
||||
@@ -0,0 +1,71 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# SelectLibraryConfigurations
|
||||
# ---------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
# select_library_configurations( basename )
|
||||
#
|
||||
# This macro takes a library base name as an argument, and will choose
|
||||
# good values for basename_LIBRARY, basename_LIBRARIES,
|
||||
# basename_LIBRARY_DEBUG, and basename_LIBRARY_RELEASE depending on what
|
||||
# has been found and set. If only basename_LIBRARY_RELEASE is defined,
|
||||
# basename_LIBRARY will be set to the release value, and
|
||||
# basename_LIBRARY_DEBUG will be set to basename_LIBRARY_DEBUG-NOTFOUND.
|
||||
# If only basename_LIBRARY_DEBUG is defined, then basename_LIBRARY will
|
||||
# take the debug value, and basename_LIBRARY_RELEASE will be set to
|
||||
# basename_LIBRARY_RELEASE-NOTFOUND.
|
||||
#
|
||||
# If the generator supports configuration types, then basename_LIBRARY
|
||||
# and basename_LIBRARIES will be set with debug and optimized flags
|
||||
# specifying the library to be used for the given configuration. If no
|
||||
# build type has been set or the generator in use does not support
|
||||
# configuration types, then basename_LIBRARY and basename_LIBRARIES will
|
||||
# take only the release value, or the debug value if the release one is
|
||||
# not set.
|
||||
|
||||
# This macro was adapted from the FindQt4 CMake module and is maintained by Will
|
||||
# Dicharry <wdicharry@stellarscience.com>.
|
||||
|
||||
macro( select_library_configurations basename )
|
||||
if(NOT ${basename}_LIBRARY_RELEASE)
|
||||
set(${basename}_LIBRARY_RELEASE "${basename}_LIBRARY_RELEASE-NOTFOUND" CACHE FILEPATH "Path to a library.")
|
||||
endif()
|
||||
if(NOT ${basename}_LIBRARY_DEBUG)
|
||||
set(${basename}_LIBRARY_DEBUG "${basename}_LIBRARY_DEBUG-NOTFOUND" CACHE FILEPATH "Path to a library.")
|
||||
endif()
|
||||
|
||||
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE AND
|
||||
NOT ${basename}_LIBRARY_DEBUG STREQUAL ${basename}_LIBRARY_RELEASE AND
|
||||
( _isMultiConfig OR CMAKE_BUILD_TYPE ) )
|
||||
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
|
||||
# single-config generators, set optimized and debug libraries
|
||||
set( ${basename}_LIBRARY "" )
|
||||
foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE )
|
||||
list( APPEND ${basename}_LIBRARY optimized "${_libname}" )
|
||||
endforeach()
|
||||
foreach( _libname IN LISTS ${basename}_LIBRARY_DEBUG )
|
||||
list( APPEND ${basename}_LIBRARY debug "${_libname}" )
|
||||
endforeach()
|
||||
elseif( ${basename}_LIBRARY_RELEASE )
|
||||
set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
|
||||
elseif( ${basename}_LIBRARY_DEBUG )
|
||||
set( ${basename}_LIBRARY ${${basename}_LIBRARY_DEBUG} )
|
||||
else()
|
||||
set( ${basename}_LIBRARY "${basename}_LIBRARY-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set( ${basename}_LIBRARIES "${${basename}_LIBRARY}" )
|
||||
|
||||
if( ${basename}_LIBRARY )
|
||||
set( ${basename}_FOUND TRUE )
|
||||
endif()
|
||||
|
||||
mark_as_advanced( ${basename}_LIBRARY_RELEASE
|
||||
${basename}_LIBRARY_DEBUG
|
||||
)
|
||||
endmacro()
|
||||
+370
-766
File diff suppressed because it is too large
Load Diff
@@ -1,147 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2021 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
/*
|
||||
* This is an additive lagged fibonacci generator as seen in The Art of Computer Programming, Vol. 2
|
||||
* This should roughly match the implementation that EQ's client uses and be compatible with our Random class
|
||||
*
|
||||
* EQ's rand looks like it was from an example implementation that as posted on pscode.com
|
||||
*
|
||||
* You might also want to consider defining BIASED_INT_DIST as well to more closely match EQ
|
||||
*/
|
||||
|
||||
namespace EQ {
|
||||
template<typename UIntType, size_t w, size_t j, size_t k>
|
||||
class additive_lagged_fibonacci_engine {
|
||||
static_assert(std::is_unsigned<UIntType>::value, "result_type must be an unsigned integral type");
|
||||
static_assert(0u < j && j < k, "0 < j < k");
|
||||
static_assert(0u < w && w <= std::numeric_limits<UIntType>::digits,
|
||||
"template argument substituting w out of bounds");
|
||||
|
||||
public:
|
||||
using result_type = UIntType;
|
||||
static constexpr size_t word_size = w;
|
||||
static constexpr size_t short_lag = j;
|
||||
static constexpr size_t long_lag = k;
|
||||
static constexpr result_type default_seed = 19780503u; // default for subtract_with_carry_engine
|
||||
|
||||
additive_lagged_fibonacci_engine() : additive_lagged_fibonacci_engine(default_seed) {}
|
||||
|
||||
explicit additive_lagged_fibonacci_engine(result_type sd) { seed(sd); }
|
||||
|
||||
void seed(result_type seed = default_seed)
|
||||
{
|
||||
state1 = long_lag - long_lag;
|
||||
state2 = long_lag - short_lag;
|
||||
state[0] = static_cast<int>(seed) & ((1u << word_size) - 1);
|
||||
state[1] = 1;
|
||||
for (int i = 2; i < long_lag; ++i)
|
||||
state[i] = (state[i - 1] + state[i - 2]) & ((1u << word_size) - 1);
|
||||
return;
|
||||
}
|
||||
// TODO: seed via seed_seq
|
||||
|
||||
static constexpr result_type min() { return 0; }
|
||||
static constexpr result_type max() { return ((1u << word_size) - 1) >> 6; }
|
||||
|
||||
void discard(unsigned long long z) {
|
||||
for (; z != 0ULL; --z)
|
||||
(*this)();
|
||||
}
|
||||
|
||||
result_type operator()() {
|
||||
result_type rand = (state[state1] + state[state2]) & ((1u << word_size) - 1);
|
||||
state[state1] = rand;
|
||||
if (++state1 == long_lag)
|
||||
state1 = 0;
|
||||
if (++state2 == long_lag)
|
||||
state2 = 0;
|
||||
|
||||
return rand >> 6;
|
||||
}
|
||||
|
||||
private:
|
||||
result_type state1;
|
||||
result_type state2;
|
||||
result_type state[long_lag];
|
||||
|
||||
public:
|
||||
template<typename UInt, size_t W, size_t J, size_t K>
|
||||
friend bool operator==(const additive_lagged_fibonacci_engine<UInt, W, J, K> &x,
|
||||
const additive_lagged_fibonacci_engine<UInt, W, J, K> &y)
|
||||
{
|
||||
return std::equal(x.state, x.state + long_lag, y.state) && x.state1 == y.state1 &&
|
||||
x.state2 == y.state2;
|
||||
}
|
||||
|
||||
template<typename UInt, size_t W, size_t J, size_t K>
|
||||
friend bool operator!=(const additive_lagged_fibonacci_engine<UInt, W, J, K> &x,
|
||||
const additive_lagged_fibonacci_engine<UInt, W, J, K> &y)
|
||||
{ return !(x == y); }
|
||||
|
||||
template<typename UInt, size_t W, size_t J, size_t K, typename CharT, typename Traits>
|
||||
friend std::basic_ostream<CharT, Traits> &
|
||||
operator<<(std::basic_istream<CharT, Traits> &os, additive_lagged_fibonacci_engine<UInt, W, J, K> &x)
|
||||
{
|
||||
using ios_base = typename std::basic_istream<CharT, Traits>::ios_base;
|
||||
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
for (size_t i = 0; i < long_lag; ++i)
|
||||
os << x.state[i] << space;
|
||||
os << x.state1 << space << x.state2;
|
||||
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename UInt, size_t W, size_t J, size_t K, typename CharT, typename Traits>
|
||||
friend std::basic_istream<CharT, Traits> &
|
||||
operator>>(std::basic_istream<CharT, Traits> &is, additive_lagged_fibonacci_engine<UInt, W, J, K> &x)
|
||||
{
|
||||
using ios_base = typename std::basic_istream<CharT, Traits>::ios_base;
|
||||
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
is.flags(ios_base::dec | ios_base::skipws);
|
||||
|
||||
for (size_t i = 0; i < long_lag; ++i)
|
||||
is >> x.state[i];
|
||||
is >> x.state1;
|
||||
is >> x.state2;
|
||||
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
};
|
||||
|
||||
using EQRand = additive_lagged_fibonacci_engine<uint32_t, 30, 24, 55>;
|
||||
};
|
||||
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person or organization
|
||||
* obtaining a copy of the software and accompanying documentation covered by
|
||||
* this license (the "Software") to use, reproduce, display, distribute,
|
||||
* execute, and transmit the Software, and to prepare derivative works of the
|
||||
* Software, and to permit third-parties to whom the Software is furnished to
|
||||
* do so, all subject to the following:
|
||||
*
|
||||
* The copyright notices in the Software and this entire statement, including
|
||||
* the above license grant, this restriction and the following disclaimer,
|
||||
* must be included in all copies of the Software, in whole or in part, and
|
||||
* all derivative works of the Software, unless such copies or derivative
|
||||
* works are solely in the form of machine-executable object code generated by
|
||||
* a source language processor.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing.
|
||||
|
||||
#ifndef EQEMU_COMMON_ANY_H
|
||||
#define EQEMU_COMMON_ANY_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
class Any
|
||||
{
|
||||
public:
|
||||
Any()
|
||||
: content(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
Any(const ValueType &value)
|
||||
: content(new Holder<ValueType>(value))
|
||||
{
|
||||
}
|
||||
|
||||
Any(const Any &other)
|
||||
: content(other.content ? other.content->clone() : 0)
|
||||
{
|
||||
}
|
||||
|
||||
~Any()
|
||||
{
|
||||
if(content)
|
||||
delete content;
|
||||
}
|
||||
|
||||
Any& swap(Any &rhs)
|
||||
{
|
||||
std::swap(content, rhs.content);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
Any& operator=(const ValueType &rhs)
|
||||
{
|
||||
Any(rhs).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Any& operator=(Any rhs)
|
||||
{
|
||||
rhs.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return !content;
|
||||
}
|
||||
|
||||
const std::type_info& type() const
|
||||
{
|
||||
return content ? content->type() : typeid(void);
|
||||
}
|
||||
|
||||
class Placeholder
|
||||
{
|
||||
public:
|
||||
virtual ~Placeholder()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const std::type_info& type() const = 0;
|
||||
virtual Placeholder* clone() const = 0;
|
||||
};
|
||||
|
||||
|
||||
template<typename ValueType>
|
||||
class Holder : public Placeholder
|
||||
{
|
||||
public:
|
||||
Holder(const ValueType &value)
|
||||
: held(value)
|
||||
{
|
||||
}
|
||||
|
||||
virtual const std::type_info& type() const
|
||||
{
|
||||
return typeid(ValueType);
|
||||
}
|
||||
|
||||
virtual Placeholder* clone() const
|
||||
{
|
||||
return new Holder(held);
|
||||
}
|
||||
|
||||
ValueType held;
|
||||
|
||||
private:
|
||||
Holder& operator=(const Holder&);
|
||||
};
|
||||
|
||||
private:
|
||||
template<typename ValueType>
|
||||
friend ValueType* any_cast(Any*);
|
||||
|
||||
template<typename ValueType>
|
||||
friend ValueType* unsafe_any_cast(Any*);
|
||||
|
||||
Placeholder* content;
|
||||
};
|
||||
|
||||
class bad_any_cast : public std::bad_cast
|
||||
{
|
||||
public:
|
||||
virtual const char * what() const throw()
|
||||
{
|
||||
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
ValueType* any_cast(Any* operand)
|
||||
{
|
||||
return operand &&
|
||||
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
inline const ValueType* any_cast(const Any* operand)
|
||||
{
|
||||
return any_cast<ValueType>(const_cast<Any*>(operand));
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
ValueType any_cast(Any& operand)
|
||||
{
|
||||
typedef typename std::remove_reference<ValueType>::type nonref;
|
||||
nonref* result = any_cast<nonref>(&operand);
|
||||
if(!result)
|
||||
throw bad_any_cast();
|
||||
return *result;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
inline ValueType any_cast(const Any& operand)
|
||||
{
|
||||
typedef typename std::remove_reference<ValueType>::type nonref;
|
||||
return any_cast<const nonref&>(const_cast<Any&>(operand));
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
inline ValueType* unsafe_any_cast(Any* operand)
|
||||
{
|
||||
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
inline const ValueType* unsafe_any_cast(const Any* operand)
|
||||
{
|
||||
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+8
-20
@@ -23,34 +23,22 @@
|
||||
|
||||
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
|
||||
{
|
||||
pBuffer=nullptr;
|
||||
size=0;
|
||||
_wpos = 0;
|
||||
_rpos = 0;
|
||||
timestamp.tv_sec = 0;
|
||||
this->pBuffer=nullptr;
|
||||
this->size=0;
|
||||
this->_wpos = 0;
|
||||
this->_rpos = 0;
|
||||
this->timestamp.tv_sec = 0;
|
||||
if (len>0) {
|
||||
size=len;
|
||||
this->size=len;
|
||||
pBuffer= new unsigned char[len];
|
||||
if (buf) {
|
||||
memcpy(pBuffer,buf,len);
|
||||
memcpy(this->pBuffer,buf,len);
|
||||
} else {
|
||||
memset(pBuffer,0,len);
|
||||
memset(this->pBuffer,0,len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BasePacket::BasePacket(SerializeBuffer &buf)
|
||||
{
|
||||
pBuffer = buf.m_buffer;
|
||||
buf.m_buffer = nullptr;
|
||||
size = buf.m_pos;
|
||||
buf.m_pos = 0;
|
||||
buf.m_capacity = 0;
|
||||
_wpos = 0;
|
||||
_rpos = 0;
|
||||
timestamp.tv_sec = 0;
|
||||
}
|
||||
|
||||
BasePacket::~BasePacket()
|
||||
{
|
||||
if (pBuffer)
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#define BASEPACKET_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "serialize_buffer.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -64,8 +63,6 @@ public:
|
||||
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
|
||||
void WriteDouble(double value) { *(double *)(pBuffer + _wpos) = value; _wpos += sizeof(double); }
|
||||
void WriteString(const char * str) { uint32 len = static_cast<uint32>(strlen(str)) + 1; memcpy(pBuffer + _wpos, str, len); _wpos += len; }
|
||||
// this is used in task system a lot, it is NOT null-termed
|
||||
void WriteLengthString(uint32 len, const char *str) { *(uint32 *)(pBuffer + _wpos) = len; _wpos += sizeof(uint32); memcpy(pBuffer + _wpos, str, len); _wpos += len; }
|
||||
void WriteData(const void *ptr, size_t n) { memcpy(pBuffer + _wpos, ptr, n); _wpos += n; }
|
||||
|
||||
uint8 ReadUInt8() { uint8 value = *(uint8 *)(pBuffer + _rpos); _rpos += sizeof(uint8); return value; }
|
||||
@@ -75,7 +72,6 @@ public:
|
||||
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
|
||||
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; }
|
||||
void ReadString(char *str) { uint32 len = static_cast<uint32>(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; }
|
||||
void ReadString(std::string &str) { str = reinterpret_cast<char *>(pBuffer + _rpos); _rpos += str.length() + 1; }
|
||||
void ReadString(char *str, uint32 Offset, uint32 MaxLength) const;
|
||||
|
||||
uint32 GetWritePosition() { return _wpos; }
|
||||
@@ -87,7 +83,6 @@ protected:
|
||||
virtual ~BasePacket();
|
||||
BasePacket() { pBuffer=nullptr; size=0; _wpos = 0; _rpos = 0; }
|
||||
BasePacket(const unsigned char *buf, const uint32 len);
|
||||
BasePacket(SerializeBuffer &buf);
|
||||
};
|
||||
|
||||
extern void DumpPacketHex(const BasePacket* app);
|
||||
|
||||
+8
-10
@@ -27,17 +27,16 @@ typedef enum {
|
||||
BT_Extraplanar = 6,
|
||||
BT_Magical = 7, //this name might be a bit off,
|
||||
BT_SummonedUndead = 8,
|
||||
BT_RaidGiant = 9, //Velious era Raid Giant
|
||||
BT_RaidColdain = 10, //Velious era Raid Coldain
|
||||
BT_RaidGiant = 9,
|
||||
// ...
|
||||
BT_NoTarget = 11, //no name, can't target this bodytype
|
||||
BT_Vampire = 12,
|
||||
BT_Atenha_Ra = 13,
|
||||
BT_Greater_Akheva = 14,
|
||||
BT_Khati_Sha = 15,
|
||||
BT_Seru = 16,
|
||||
BT_Grieg_Veneficus = 17,
|
||||
BT_Seru = 16, //not confirmed....
|
||||
BT_Draz_Nurakk = 18,
|
||||
BT_Zek = 19, //"creatures from the Plane of War."
|
||||
BT_Zek = 19,
|
||||
BT_Luggald = 20,
|
||||
BT_Animal = 21,
|
||||
BT_Insect = 22,
|
||||
@@ -47,18 +46,17 @@ typedef enum {
|
||||
BT_Dragon = 26,
|
||||
BT_Summoned2 = 27,
|
||||
BT_Summoned3 = 28,
|
||||
BT_Dragon2 = 29, //database data indicates this is a dragon type (kunark and DoN?)
|
||||
//29
|
||||
BT_VeliousDragon = 30, //might not be a tight set
|
||||
BT_Familiar = 31,
|
||||
// ...
|
||||
BT_Dragon3 = 32,
|
||||
BT_Boxes = 33,
|
||||
BT_Muramite = 34, //tribal dudes
|
||||
// ...
|
||||
BT_NoTarget2 = 60,
|
||||
// ...
|
||||
BT_SwarmPet = 63, //Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
|
||||
BT_MonsterSummon = 64,
|
||||
// 65, trap or effect related?
|
||||
BT_SwarmPet = 63, //is this valid, or made up?
|
||||
// ...
|
||||
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
|
||||
BT_Special = 67
|
||||
} bodyType;
|
||||
|
||||
+471
-601
File diff suppressed because it is too large
Load Diff
+5
-7
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
#define NO_CLASS 0
|
||||
#define WARRIOR 1
|
||||
#define CLERIC 2
|
||||
#define PALADIN 3
|
||||
@@ -56,17 +55,17 @@
|
||||
#define BANKER 40
|
||||
#define MERCHANT 41
|
||||
#define DISCORD_MERCHANT 59
|
||||
#define ADVENTURE_RECRUITER 60
|
||||
#define ADVENTURE_MERCHANT 61
|
||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
|
||||
#define ADVENTURERECRUITER 60
|
||||
#define ADVENTUREMERCHANT 61
|
||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs
|
||||
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
|
||||
#define TRIBUTE_MASTER 63
|
||||
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
||||
#define GUILD_BANKER 66
|
||||
#define NORRATHS_KEEPERS_MERCHANT 67
|
||||
#define DARK_REIGN_MERCHANT 68
|
||||
#define FELLOWSHIP_MASTER 69
|
||||
#define ALT_CURRENCY_MERCHANT 70
|
||||
#define MERCENARY_MASTER 71
|
||||
#define MERCERNARY_MASTER 71
|
||||
|
||||
|
||||
// player class values
|
||||
@@ -136,7 +135,6 @@ uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
||||
bool IsFighterClass(uint8 class_id);
|
||||
bool IsSpellFighterClass(uint8 class_id);
|
||||
bool IsNonSpellFighterClass(uint8 class_id);
|
||||
bool IsHybridClass(uint8 class_id);
|
||||
bool IsCasterClass(uint8 class_id);
|
||||
bool IsINTCasterClass(uint8 class_id);
|
||||
bool IsWISCasterClass(uint8 class_id);
|
||||
|
||||
@@ -1,434 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
namespace argh
|
||||
{
|
||||
// Terminology:
|
||||
// A command line is composed of 2 types of args:
|
||||
// 1. Positional args, i.e. free standing values
|
||||
// 2. Options: args beginning with '-'. We identify two kinds:
|
||||
// 2.1: Flags: boolean options => (exist ? true : false)
|
||||
// 2.2: Parameters: a name followed by a non-option value
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ >= 5)
|
||||
using string_stream = std::istringstream;
|
||||
#else
|
||||
// Until GCC 5, istringstream did not have a move constructor.
|
||||
// stringstream_proxy is used instead, as a workaround.
|
||||
class stringstream_proxy
|
||||
{
|
||||
public:
|
||||
stringstream_proxy() = default;
|
||||
|
||||
// Construct with a value.
|
||||
stringstream_proxy(std::string const& value) :
|
||||
stream_(value)
|
||||
{}
|
||||
|
||||
// Copy constructor.
|
||||
stringstream_proxy(const stringstream_proxy& other) :
|
||||
stream_(other.stream_.str())
|
||||
{
|
||||
stream_.setstate(other.stream_.rdstate());
|
||||
}
|
||||
|
||||
void setstate(std::ios_base::iostate state) { stream_.setstate(state); }
|
||||
|
||||
// Stream out the value of the parameter.
|
||||
// If the conversion was not possible, the stream will enter the fail state,
|
||||
// and operator bool will return false.
|
||||
template<typename T>
|
||||
stringstream_proxy& operator >> (T& thing)
|
||||
{
|
||||
stream_ >> thing;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Get the string value.
|
||||
std::string str() const { return stream_.str(); }
|
||||
|
||||
std::stringbuf* rdbuf() const { return stream_.rdbuf(); }
|
||||
|
||||
// Check the state of the stream.
|
||||
// False when the most recent stream operation failed
|
||||
operator bool() const { return !!stream_; }
|
||||
|
||||
~stringstream_proxy() = default;
|
||||
private:
|
||||
std::istringstream stream_;
|
||||
};
|
||||
using string_stream = stringstream_proxy;
|
||||
#endif
|
||||
|
||||
class parser
|
||||
{
|
||||
public:
|
||||
enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0,
|
||||
PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1,
|
||||
NO_SPLIT_ON_EQUALSIGN = 1 << 2,
|
||||
SINGLE_DASH_IS_MULTIFLAG = 1 << 3,
|
||||
};
|
||||
|
||||
parser() = default;
|
||||
|
||||
parser(std::initializer_list<char const* const> pre_reg_names)
|
||||
{ add_params(pre_reg_names); }
|
||||
|
||||
parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
|
||||
{ parse(argv, mode); }
|
||||
|
||||
parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
|
||||
{ parse(argc, argv, mode); }
|
||||
|
||||
void add_param(std::string const& name);
|
||||
void add_params(std::initializer_list<char const* const> init_list);
|
||||
|
||||
void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
|
||||
void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
|
||||
|
||||
std::multiset<std::string> const& flags() const { return flags_; }
|
||||
std::map<std::string, std::string> const& params() const { return params_; }
|
||||
std::vector<std::string> const& pos_args() const { return pos_args_; }
|
||||
|
||||
// begin() and end() for using range-for over positional args.
|
||||
std::vector<std::string>::const_iterator begin() const { return pos_args_.cbegin(); }
|
||||
std::vector<std::string>::const_iterator end() const { return pos_args_.cend(); }
|
||||
size_t size() const { return pos_args_.size(); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Accessors
|
||||
|
||||
// flag (boolean) accessors: return true if the flag appeared, otherwise false.
|
||||
bool operator[](std::string const& name) const;
|
||||
|
||||
// multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false.
|
||||
bool operator[](std::initializer_list<char const* const> init_list) const;
|
||||
|
||||
// returns positional arg string by order. Like argv[] but without the options
|
||||
std::string const& operator[](size_t ind) const;
|
||||
|
||||
// returns a std::istream that can be used to convert a positional arg to a typed value.
|
||||
string_stream operator()(size_t ind) const;
|
||||
|
||||
// same as above, but with a default value in case the arg is missing (index out of range).
|
||||
template<typename T>
|
||||
string_stream operator()(size_t ind, T&& def_val) const;
|
||||
|
||||
// parameter accessors, give a name get an std::istream that can be used to convert to a typed value.
|
||||
// call .str() on result to get as string
|
||||
string_stream operator()(std::string const& name) const;
|
||||
|
||||
// accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value.
|
||||
// call .str() on result to get as string
|
||||
// returns the first value in the list to be found.
|
||||
string_stream operator()(std::initializer_list<char const* const> init_list) const;
|
||||
|
||||
// same as above, but with a default value in case the param was missing.
|
||||
// Non-string def_val types must have an operator<<() (output stream operator)
|
||||
// If T only has an input stream operator, pass the string version of the type as in "3" instead of 3.
|
||||
template<typename T>
|
||||
string_stream operator()(std::string const& name, T&& def_val) const;
|
||||
|
||||
// same as above but for a list of names. returns the first value to be found.
|
||||
template<typename T>
|
||||
string_stream operator()(std::initializer_list<char const* const> init_list, T&& def_val) const;
|
||||
|
||||
private:
|
||||
string_stream bad_stream() const;
|
||||
std::string trim_leading_dashes(std::string const& name) const;
|
||||
bool is_number(std::string const& arg) const;
|
||||
bool is_option(std::string const& arg) const;
|
||||
bool got_flag(std::string const& name) const;
|
||||
bool is_param(std::string const& name) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> args_;
|
||||
std::map<std::string, std::string> params_;
|
||||
std::vector<std::string> pos_args_;
|
||||
std::multiset<std::string> flags_;
|
||||
std::set<std::string> registeredParams_;
|
||||
std::string empty_;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::parse(const char * const argv[], int mode)
|
||||
{
|
||||
int argc = 0;
|
||||
for (auto argvp = argv; *argvp; ++argc, ++argvp);
|
||||
parse(argc, argv, mode);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/)
|
||||
{
|
||||
// convert to strings
|
||||
args_.resize(argc);
|
||||
std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; });
|
||||
|
||||
// parse line
|
||||
for (auto i = 0u; i < args_.size(); ++i)
|
||||
{
|
||||
if (!is_option(args_[i]))
|
||||
{
|
||||
pos_args_.emplace_back(args_[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto name = trim_leading_dashes(args_[i]);
|
||||
|
||||
if (!(mode & NO_SPLIT_ON_EQUALSIGN))
|
||||
{
|
||||
auto equalPos = name.find('=');
|
||||
if (equalPos != std::string::npos)
|
||||
{
|
||||
params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if the option is unregistered and should be a multi-flag
|
||||
if (1 == (args_[i].size() - name.size()) && // single dash
|
||||
argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode
|
||||
!is_param(name)) // unregistered
|
||||
{
|
||||
std::string keep_param;
|
||||
|
||||
if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param
|
||||
{
|
||||
keep_param += name.back();
|
||||
name.resize(name.size() - 1);
|
||||
}
|
||||
|
||||
for (auto const& c : name)
|
||||
{
|
||||
flags_.emplace(std::string{ c });
|
||||
}
|
||||
|
||||
if (!keep_param.empty())
|
||||
{
|
||||
name = keep_param;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue; // do not consider other options for this arg
|
||||
}
|
||||
}
|
||||
|
||||
// any potential option will get as its value the next arg, unless that arg is an option too
|
||||
// in that case it will be determined a flag.
|
||||
if (i == args_.size() - 1 || is_option(args_[i + 1]))
|
||||
{
|
||||
flags_.emplace(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped
|
||||
// otherwise we have 2 modes:
|
||||
// PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag.
|
||||
// The following value (the next arg) will be a free parameter.
|
||||
//
|
||||
// PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg
|
||||
// will be the value of that option.
|
||||
|
||||
assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION)
|
||||
|| !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION));
|
||||
|
||||
bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION;
|
||||
|
||||
if (is_param(name) || preferParam)
|
||||
{
|
||||
params_.insert({ name, args_[i + 1] });
|
||||
++i; // skip next value, it is not a free parameter
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags_.emplace(name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::bad_stream() const
|
||||
{
|
||||
string_stream bad;
|
||||
bad.setstate(std::ios_base::failbit);
|
||||
return bad;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::is_number(std::string const& arg) const
|
||||
{
|
||||
// inefficient but simple way to determine if a string is a number (which can start with a '-')
|
||||
std::istringstream istr(arg);
|
||||
double number;
|
||||
istr >> number;
|
||||
return !(istr.fail() || istr.bad());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::is_option(std::string const& arg) const
|
||||
{
|
||||
assert(0 != arg.size());
|
||||
if (is_number(arg))
|
||||
return false;
|
||||
return '-' == arg[0];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::string parser::trim_leading_dashes(std::string const& name) const
|
||||
{
|
||||
auto pos = name.find_first_not_of('-');
|
||||
return std::string::npos != pos ? name.substr(pos) : name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool argh::parser::got_flag(std::string const& name) const
|
||||
{
|
||||
return flags_.end() != flags_.find(trim_leading_dashes(name));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool argh::parser::is_param(std::string const& name) const
|
||||
{
|
||||
return registeredParams_.count(name);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::operator[](std::string const& name) const
|
||||
{
|
||||
return got_flag(name);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool parser::operator[](std::initializer_list<char const* const> init_list) const
|
||||
{
|
||||
return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); });
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::string const& parser::operator[](size_t ind) const
|
||||
{
|
||||
if (ind < pos_args_.size())
|
||||
return pos_args_[ind];
|
||||
return empty_;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::operator()(std::string const& name) const
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
return bad_stream();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::operator()(std::initializer_list<char const* const> init_list) const
|
||||
{
|
||||
for (auto& name : init_list)
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
}
|
||||
return bad_stream();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
string_stream parser::operator()(std::string const& name, T&& def_val) const
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
|
||||
std::ostringstream ostr;
|
||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
||||
ostr << def_val;
|
||||
return string_stream(ostr.str()); // use default
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// same as above but for a list of names. returns the first value to be found.
|
||||
template<typename T>
|
||||
string_stream parser::operator()(std::initializer_list<char const* const> init_list, T&& def_val) const
|
||||
{
|
||||
for (auto& name : init_list)
|
||||
{
|
||||
auto optIt = params_.find(trim_leading_dashes(name));
|
||||
if (params_.end() != optIt)
|
||||
return string_stream(optIt->second);
|
||||
}
|
||||
std::ostringstream ostr;
|
||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
||||
ostr << def_val;
|
||||
return string_stream(ostr.str()); // use default
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline string_stream parser::operator()(size_t ind) const
|
||||
{
|
||||
if (pos_args_.size() <= ind)
|
||||
return bad_stream();
|
||||
|
||||
return string_stream(pos_args_[ind]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T>
|
||||
string_stream parser::operator()(size_t ind, T&& def_val) const
|
||||
{
|
||||
if (pos_args_.size() <= ind)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
||||
ostr << def_val;
|
||||
return string_stream(ostr.str());
|
||||
}
|
||||
|
||||
return string_stream(pos_args_[ind]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::add_param(std::string const& name)
|
||||
{
|
||||
registeredParams_.insert(trim_leading_dashes(name));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void parser::add_params(std::initializer_list<char const* const> init_list)
|
||||
{
|
||||
for (auto& name : init_list)
|
||||
registeredParams_.insert(trim_leading_dashes(name));
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "eqemu_command_handler.h"
|
||||
#include "terminal_color.hpp"
|
||||
#include "../platform.h"
|
||||
|
||||
namespace EQEmuCommand {
|
||||
|
||||
std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> function_map;
|
||||
|
||||
/**
|
||||
* @param cmd
|
||||
*/
|
||||
void DisplayDebug(argh::parser &cmd)
|
||||
{
|
||||
if (cmd[{"-d", "--debug"}]) {
|
||||
std::cout << "Positional args:\n";
|
||||
for (auto &pos_arg : cmd.pos_args())
|
||||
std::cout << '\t' << pos_arg << std::endl;
|
||||
|
||||
std::cout << "\nFlags:\n";
|
||||
for (auto &flag : cmd.flags())
|
||||
std::cout << '\t' << flag << std::endl;
|
||||
|
||||
std::cout << "\nParameters:\n";
|
||||
for (auto ¶m : cmd.params())
|
||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param arguments
|
||||
* @param options
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void ValidateCmdInput(
|
||||
std::vector<std::string> &arguments,
|
||||
std::vector<std::string> &options,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
bool arguments_filled = true;
|
||||
|
||||
int index = 2;
|
||||
for (auto &arg : arguments) {
|
||||
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
||||
arguments_filled = false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
|
||||
std::string arguments_string;
|
||||
for (auto &arg : arguments) {
|
||||
arguments_string += " " + arg;
|
||||
}
|
||||
|
||||
std::string options_string;
|
||||
for (auto &opt : options) {
|
||||
options_string += " " + opt + "\n";
|
||||
}
|
||||
|
||||
std::stringstream command_string;
|
||||
|
||||
command_string <<
|
||||
termcolor::colorize <<
|
||||
termcolor::yellow <<
|
||||
"\nCommand" <<
|
||||
termcolor::reset << "\n\n" <<
|
||||
termcolor::green << argv[1] << arguments_string << termcolor::reset << "\n" <<
|
||||
termcolor::yellow << (!options_string.empty() ? "\nOptions\n\n" : "") <<
|
||||
termcolor::reset << termcolor::cyan << options_string << termcolor::reset;
|
||||
|
||||
std::cout << command_string.str() << std::endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in_function_map
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void HandleMenu(
|
||||
std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> &in_function_map,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
std::string description;
|
||||
bool ran_command = false;
|
||||
for (auto &it: in_function_map) {
|
||||
if (it.first == argv[1]) {
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
ran_command = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd[{"-h", "--help"}]) {
|
||||
std::cout << std::endl;
|
||||
std::cout <<
|
||||
"> " <<
|
||||
termcolor::yellow <<
|
||||
"EQEmulator [" + GetPlatformName() + "] CLI Menu" <<
|
||||
termcolor::reset
|
||||
<< std::endl
|
||||
<< std::endl;
|
||||
|
||||
/**
|
||||
* Get max command length for padding length
|
||||
*/
|
||||
int max_command_length = 0;
|
||||
|
||||
for (auto &it: in_function_map) {
|
||||
std::stringstream command;
|
||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||
if (command.str().length() > max_command_length) {
|
||||
max_command_length = command.str().length() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display command menu
|
||||
*/
|
||||
std::string command_section;
|
||||
for (auto &it: in_function_map) {
|
||||
description = "";
|
||||
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
|
||||
/**
|
||||
* Print section header
|
||||
*/
|
||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
||||
|
||||
if (command_prefix.find("test") != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (command_section != command_prefix) {
|
||||
command_section = command_prefix;
|
||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print commands
|
||||
*/
|
||||
std::stringstream command;
|
||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
if (ran_command) {
|
||||
std::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_EQEMU_COMMAND_HANDLER_H
|
||||
#define EQEMU_EQEMU_COMMAND_HANDLER_H
|
||||
|
||||
#include "argh.h"
|
||||
|
||||
namespace EQEmuCommand {
|
||||
|
||||
extern std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> function_map;
|
||||
|
||||
/**
|
||||
* @param arguments
|
||||
* @param options
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void ValidateCmdInput(
|
||||
std::vector<std::string> &arguments,
|
||||
std::vector<std::string> &options,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
);
|
||||
|
||||
/**
|
||||
* @param cmd
|
||||
*/
|
||||
void DisplayDebug(argh::parser &cmd);
|
||||
|
||||
/**
|
||||
* @param in_function_map
|
||||
* @param cmd
|
||||
* @param argc
|
||||
* @param argv
|
||||
*/
|
||||
void HandleMenu(
|
||||
std::map<std::string, void (*)(
|
||||
int argc,
|
||||
char **argv,
|
||||
argh::parser &cmd,
|
||||
std::string &description
|
||||
)> &in_function_map,
|
||||
argh::parser &cmd,
|
||||
int argc,
|
||||
char **argv
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_EQEMU_COMMAND_HANDLER_H
|
||||
@@ -1,557 +0,0 @@
|
||||
//!
|
||||
//! termcolor
|
||||
//! ~~~~~~~~~
|
||||
//!
|
||||
//! termcolor is a header-only c++ library for printing colored messages
|
||||
//! to the terminal. Written just for fun with a help of the Force.
|
||||
//!
|
||||
//! :copyright: (c) 2013 by Ihor Kalnytskyi
|
||||
//! :license: BSD, see LICENSE for details
|
||||
//!
|
||||
|
||||
#ifndef TERMCOLOR_HPP_
|
||||
#define TERMCOLOR_HPP_
|
||||
|
||||
// the following snippet of code detects the current OS and
|
||||
// defines the appropriate macro that is used to wrap some
|
||||
// platform specific things
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define TERMCOLOR_OS_WINDOWS
|
||||
#elif defined(__APPLE__)
|
||||
# define TERMCOLOR_OS_MACOS
|
||||
#elif defined(__unix__) || defined(__unix)
|
||||
# define TERMCOLOR_OS_LINUX
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
|
||||
|
||||
// This headers provides the `isatty()`/`fileno()` functions,
|
||||
// which are used for testing whether a standart stream refers
|
||||
// to the terminal. As for Windows, we also need WinApi funcs
|
||||
// for changing colors attributes of the terminal.
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
# include <unistd.h>
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
|
||||
namespace termcolor
|
||||
{
|
||||
// Forward declaration of the `_internal` namespace.
|
||||
// All comments are below.
|
||||
namespace _internal
|
||||
{
|
||||
// An index to be used to access a private storage of I/O streams. See
|
||||
// colorize / nocolorize I/O manipulators for details.
|
||||
static int colorize_index = std::ios_base::xalloc();
|
||||
|
||||
inline FILE* get_standard_stream(const std::ostream& stream);
|
||||
inline bool is_colorized(std::ostream& stream);
|
||||
inline bool is_atty(const std::ostream& stream);
|
||||
|
||||
#if defined(TERMCOLOR_OS_WINDOWS)
|
||||
inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& colorize(std::ostream& stream)
|
||||
{
|
||||
stream.iword(_internal::colorize_index) = 1L;
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& nocolorize(std::ostream& stream)
|
||||
{
|
||||
stream.iword(_internal::colorize_index) = 0L;
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& reset(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;00m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1, -1);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& bold(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;1m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& dark(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;2m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& underline(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;4m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& blink(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;5m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& reverse(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;7m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& concealed(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;8m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& grey(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;30m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
0 // grey (black)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& red(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;31m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& green(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;32m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_GREEN
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& yellow(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;33m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_GREEN | FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& blue(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;34m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& magenta(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;35m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE | FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& cyan(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;36m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE | FOREGROUND_GREEN
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& white(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;37m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream,
|
||||
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& on_grey(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;40m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
0 // grey (black)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_red(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;41m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_green(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;42m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_yellow(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;43m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN | BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_blue(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;44m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_BLUE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_magenta(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;45m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_BLUE | BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_cyan(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;46m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN | BACKGROUND_BLUE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline
|
||||
std::ostream& on_white(std::ostream& stream)
|
||||
{
|
||||
if (_internal::is_colorized(stream))
|
||||
{
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
stream << "\e[1;47m";
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
_internal::win_change_attributes(stream, -1,
|
||||
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Since C++ hasn't a way to hide something in the header from
|
||||
//! the outer access, I have to introduce this namespace which
|
||||
//! is used for internal purpose and should't be access from
|
||||
//! the user code.
|
||||
namespace _internal
|
||||
{
|
||||
//! Since C++ hasn't a true way to extract stream handler
|
||||
//! from the a given `std::ostream` object, I have to write
|
||||
//! this kind of hack.
|
||||
inline
|
||||
FILE* get_standard_stream(const std::ostream& stream)
|
||||
{
|
||||
if (&stream == &std::cout)
|
||||
return stdout;
|
||||
else if ((&stream == &std::cerr) || (&stream == &std::clog))
|
||||
return stderr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Say whether a given stream should be colorized or not. It's always
|
||||
// true for ATTY streams and may be true for streams marked with
|
||||
// colorize flag.
|
||||
inline
|
||||
bool is_colorized(std::ostream& stream)
|
||||
{
|
||||
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index));
|
||||
}
|
||||
|
||||
//! Test whether a given `std::ostream` object refers to
|
||||
//! a terminal.
|
||||
inline
|
||||
bool is_atty(const std::ostream& stream)
|
||||
{
|
||||
FILE* std_stream = get_standard_stream(stream);
|
||||
|
||||
// Unfortunately, fileno() ends with segmentation fault
|
||||
// if invalid file descriptor is passed. So we need to
|
||||
// handle this case gracefully and assume it's not a tty
|
||||
// if standard stream is not detected, and 0 is returned.
|
||||
if (!std_stream)
|
||||
return false;
|
||||
|
||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
||||
return ::isatty(fileno(std_stream));
|
||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||
return ::_isatty(_fileno(std_stream));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(TERMCOLOR_OS_WINDOWS)
|
||||
//! Change Windows Terminal colors attribute. If some
|
||||
//! parameter is `-1` then attribute won't changed.
|
||||
inline void win_change_attributes(std::ostream& stream, int foreground, int background)
|
||||
{
|
||||
// yeah, i know.. it's ugly, it's windows.
|
||||
static WORD defaultAttributes = 0;
|
||||
|
||||
// Windows doesn't have ANSI escape sequences and so we use special
|
||||
// API to change Terminal output color. That means we can't
|
||||
// manipulate colors by means of "std::stringstream" and hence
|
||||
// should do nothing in this case.
|
||||
if (!_internal::is_atty(stream))
|
||||
return;
|
||||
|
||||
// get terminal handle
|
||||
HANDLE hTerminal = INVALID_HANDLE_VALUE;
|
||||
if (&stream == &std::cout)
|
||||
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
else if (&stream == &std::cerr)
|
||||
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
||||
// save default terminal attributes if it unsaved
|
||||
if (!defaultAttributes)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
||||
return;
|
||||
defaultAttributes = info.wAttributes;
|
||||
}
|
||||
|
||||
// restore all default settings
|
||||
if (foreground == -1 && background == -1)
|
||||
{
|
||||
SetConsoleTextAttribute(hTerminal, defaultAttributes);
|
||||
return;
|
||||
}
|
||||
|
||||
// get current settings
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
||||
return;
|
||||
|
||||
if (foreground != -1)
|
||||
{
|
||||
info.wAttributes &= ~(info.wAttributes & 0x0F);
|
||||
info.wAttributes |= static_cast<WORD>(foreground);
|
||||
}
|
||||
|
||||
if (background != -1)
|
||||
{
|
||||
info.wAttributes &= ~(info.wAttributes & 0xF0);
|
||||
info.wAttributes |= static_cast<WORD>(background);
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hTerminal, info.wAttributes);
|
||||
}
|
||||
#endif // TERMCOLOR_OS_WINDOWS
|
||||
|
||||
} // namespace _internal
|
||||
|
||||
} // namespace termcolor
|
||||
|
||||
|
||||
#undef TERMCOLOR_OS_WINDOWS
|
||||
#undef TERMCOLOR_OS_MACOS
|
||||
#undef TERMCOLOR_OS_LINUX
|
||||
|
||||
#endif // TERMCOLOR_HPP_
|
||||
@@ -1,82 +0,0 @@
|
||||
#include "global_define.h"
|
||||
#include "types.h"
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
uint32 EstimateDeflateBuffer(uint32 len) {
|
||||
z_stream zstream;
|
||||
memset(&zstream, 0, sizeof(zstream));
|
||||
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.opaque = Z_NULL;
|
||||
if (deflateInit(&zstream, Z_FINISH) != Z_OK)
|
||||
return 0;
|
||||
|
||||
return deflateBound(&zstream, len);
|
||||
}
|
||||
|
||||
uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max) {
|
||||
z_stream zstream;
|
||||
memset(&zstream, 0, sizeof(zstream));
|
||||
int zerror;
|
||||
|
||||
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
|
||||
zstream.avail_in = len;
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.opaque = Z_NULL;
|
||||
deflateInit(&zstream, Z_FINISH);
|
||||
|
||||
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);
|
||||
zstream.avail_out = out_len_max;
|
||||
zerror = deflate(&zstream, Z_FINISH);
|
||||
|
||||
if (zerror == Z_STREAM_END)
|
||||
{
|
||||
deflateEnd(&zstream);
|
||||
return (uint32)zstream.total_out;
|
||||
}
|
||||
else
|
||||
{
|
||||
zerror = deflateEnd(&zstream);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max) {
|
||||
z_stream zstream;
|
||||
int zerror = 0;
|
||||
int i;
|
||||
|
||||
zstream.next_in = const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(buffer));
|
||||
zstream.avail_in = len;
|
||||
zstream.next_out = reinterpret_cast<unsigned char*>(out_buffer);;
|
||||
zstream.avail_out = out_len_max;
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.opaque = Z_NULL;
|
||||
|
||||
i = inflateInit2(&zstream, 15);
|
||||
if (i != Z_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
zerror = inflate(&zstream, Z_FINISH);
|
||||
if (zerror == Z_STREAM_END) {
|
||||
inflateEnd(&zstream);
|
||||
return zstream.total_out;
|
||||
}
|
||||
else {
|
||||
if (zerror == -4 && zstream.msg == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
zerror = inflateEnd(&zstream);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
uint32 EstimateDeflateBuffer(uint32 len);
|
||||
uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max);
|
||||
uint32 InflateData(const char* buffer, uint32 len, char* out_buffer, uint32 out_len_max);
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "world_content_service.h"
|
||||
#include "../database.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../loottable.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
|
||||
|
||||
WorldContentService::WorldContentService()
|
||||
{
|
||||
SetCurrentExpansion(Expansion::EXPANSION_ALL);
|
||||
}
|
||||
|
||||
int WorldContentService::GetCurrentExpansion() const
|
||||
{
|
||||
return current_expansion;
|
||||
}
|
||||
|
||||
WorldContentService *WorldContentService::SetExpansionContext()
|
||||
{
|
||||
// do a rule manager reload until where we store expansion is changed to somewhere else
|
||||
RuleManager::Instance()->LoadRules(GetDatabase(), "default", true);
|
||||
|
||||
// pull expansion from rules
|
||||
int expansion = RuleI(Expansion, CurrentExpansion);
|
||||
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
||||
content_service.SetCurrentExpansion(expansion);
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"Current expansion is [{}] ({})",
|
||||
GetCurrentExpansion(),
|
||||
GetCurrentExpansionName()
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
std::string WorldContentService::GetCurrentExpansionName()
|
||||
{
|
||||
if (content_service.GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
|
||||
return "All Expansions";
|
||||
}
|
||||
|
||||
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
|
||||
return Expansion::ExpansionName[content_service.GetCurrentExpansion()];
|
||||
}
|
||||
|
||||
return "Unknown Expansion";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param current_expansion
|
||||
*/
|
||||
void WorldContentService::SetCurrentExpansion(int current_expansion)
|
||||
{
|
||||
WorldContentService::current_expansion = current_expansion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
const std::vector<ContentFlagsRepository::ContentFlags> &WorldContentService::GetContentFlags() const
|
||||
{
|
||||
return content_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::vector<std::string> WorldContentService::GetContentFlagsEnabled()
|
||||
{
|
||||
std::vector<std::string> enabled_flags;
|
||||
|
||||
for (auto &f: GetContentFlags()) {
|
||||
if (f.enabled) {
|
||||
enabled_flags.emplace_back(f.flag_name);
|
||||
}
|
||||
}
|
||||
|
||||
return enabled_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
||||
{
|
||||
std::vector<std::string> disabled_flags;
|
||||
|
||||
for (auto &f: GetContentFlags()) {
|
||||
if (!f.enabled) {
|
||||
disabled_flags.emplace_back(f.flag_name);
|
||||
}
|
||||
}
|
||||
|
||||
return disabled_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content_flags
|
||||
*/
|
||||
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
|
||||
{
|
||||
WorldContentService::content_flags = content_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content_flag
|
||||
* @return
|
||||
*/
|
||||
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
||||
{
|
||||
for (auto &f: GetContentFlags()) {
|
||||
if (f.flag_name == content_flag && f.enabled == true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param content_flag
|
||||
* @return
|
||||
*/
|
||||
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
|
||||
{
|
||||
for (auto &f: GetContentFlags()) {
|
||||
if (f.flag_name == content_flag && f.enabled == false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
|
||||
{
|
||||
// if we're not set to (-1 All) then fail when we aren't within minimum expansion
|
||||
if (f.min_expansion > Expansion::EXPANSION_ALL && current_expansion < f.min_expansion && current_expansion != -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we're not set to (-1 All) then fail when we aren't within max expansion
|
||||
if (f.max_expansion > Expansion::EXPANSION_ALL && current_expansion > f.max_expansion && current_expansion != -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we don't have any enabled flag in enabled flags, we fail
|
||||
for (const auto& flag: Strings::Split(f.content_flags)) {
|
||||
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have any disabled flag in disabled flags, we fail
|
||||
for (const auto& flag: Strings::Split(f.content_flags_disabled)) {
|
||||
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldContentService::ReloadContentFlags()
|
||||
{
|
||||
std::vector<ContentFlagsRepository::ContentFlags> set_content_flags;
|
||||
auto flags = ContentFlagsRepository::All(*GetDatabase());
|
||||
|
||||
set_content_flags.reserve(flags.size());
|
||||
for (auto &f: flags) {
|
||||
set_content_flags.push_back(f);
|
||||
|
||||
LogInfo(
|
||||
"Loaded content flag [{}] [{}]",
|
||||
f.flag_name,
|
||||
(f.enabled ? "Enabled" : "Disabled")
|
||||
);
|
||||
}
|
||||
|
||||
SetContentFlags(set_content_flags);
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetDatabase() const
|
||||
{
|
||||
return m_database;
|
||||
}
|
||||
|
||||
WorldContentService *WorldContentService::SetDatabase(Database *database)
|
||||
{
|
||||
WorldContentService::m_database = database;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
|
||||
{
|
||||
auto flags = ContentFlagsRepository::GetWhere(
|
||||
*GetDatabase(),
|
||||
fmt::format("flag_name = '{}'", content_flag_name)
|
||||
);
|
||||
|
||||
auto f = ContentFlagsRepository::NewEntity();
|
||||
if (!flags.empty()) {
|
||||
f = flags.front();
|
||||
}
|
||||
|
||||
f.enabled = enabled ? 1 : 0;
|
||||
f.flag_name = content_flag_name;
|
||||
|
||||
if (!flags.empty()) {
|
||||
ContentFlagsRepository::UpdateOne(*GetDatabase(), f);
|
||||
}
|
||||
else {
|
||||
ContentFlagsRepository::InsertOne(*GetDatabase(), f);
|
||||
}
|
||||
|
||||
ReloadContentFlags();
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../loottable.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
|
||||
class Database;
|
||||
|
||||
namespace Expansion {
|
||||
static const int EXPANSION_ALL = -1;
|
||||
static const int EXPANSION_FILTER_MAX = 99;
|
||||
|
||||
enum ExpansionNumber {
|
||||
Classic = 0,
|
||||
TheRuinsOfKunark,
|
||||
TheScarsOfVelious,
|
||||
TheShadowsOfLuclin,
|
||||
ThePlanesOfPower,
|
||||
TheLegacyOfYkesha,
|
||||
LostDungeonsOfNorrath,
|
||||
GatesOfDiscord,
|
||||
OmensOfWar,
|
||||
DragonsOfNorrath,
|
||||
DepthsOfDarkhollow,
|
||||
ProphecyOfRo,
|
||||
TheSerpentsSpine,
|
||||
TheBuriedSea,
|
||||
SecretsOfFaydwer,
|
||||
SeedsOfDestruction,
|
||||
Underfoot,
|
||||
HouseOfThule,
|
||||
VeilOfAlaris,
|
||||
RainOfFear,
|
||||
CallOfTheForsaken,
|
||||
TheDarkenedSea,
|
||||
TheBrokenMirror,
|
||||
EmpiresOfKunark,
|
||||
RingOfScale,
|
||||
TheBurningLands,
|
||||
TormentOfVelious,
|
||||
MaxId
|
||||
};
|
||||
|
||||
/**
|
||||
* If you add to this, make sure you update LogCategory
|
||||
*/
|
||||
static const char *ExpansionName[ExpansionNumber::MaxId] = {
|
||||
"Classic",
|
||||
"The Ruins of Kunark",
|
||||
"The Scars of Velious",
|
||||
"The Shadows of Luclin",
|
||||
"The Planes of Power",
|
||||
"The Legacy of Ykesha",
|
||||
"Lost Dungeons of Norrath",
|
||||
"Gates of Discord",
|
||||
"Omens of War",
|
||||
"Dragons of Norrath",
|
||||
"Depths of Darkhollow",
|
||||
"Prophecy of Ro",
|
||||
"The Serpent's Spine",
|
||||
"The Buried Sea",
|
||||
"Secrets of Faydwer",
|
||||
"Seeds of Destruction",
|
||||
"Underfoot",
|
||||
"House of Thule",
|
||||
"Veil of Alaris",
|
||||
"Rain of Fear",
|
||||
"Call of the Forsaken",
|
||||
"The Darkened Sea",
|
||||
"The Broken Mirror",
|
||||
"Empires of Kunark",
|
||||
"Ring of Scale",
|
||||
"The Burning Lands",
|
||||
"Torment of Velious",
|
||||
};
|
||||
}
|
||||
|
||||
class WorldContentService {
|
||||
public:
|
||||
|
||||
WorldContentService();
|
||||
|
||||
std::string GetCurrentExpansionName();
|
||||
int GetCurrentExpansion() const;
|
||||
void SetCurrentExpansion(int current_expansion);
|
||||
|
||||
bool IsClassicEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::Classic || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheRuinsOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheRuinsOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheScarsOfVeliousEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheScarsOfVelious || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheShadowsOfLuclinEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheShadowsOfLuclin || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsThePlanesOfPowerEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::ThePlanesOfPower || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheLegacyOfYkeshaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheLegacyOfYkesha || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsLostDungeonsOfNorrathEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::LostDungeonsOfNorrath || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsGatesOfDiscordEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::GatesOfDiscord || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsOmensOfWarEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::OmensOfWar || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsDragonsOfNorrathEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::DragonsOfNorrath || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsDepthsOfDarkhollowEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::DepthsOfDarkhollow || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsProphecyOfRoEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::ProphecyOfRo || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheSerpentsSpineEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheSerpentsSpine || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheBuriedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBuriedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsSecretsOfFaydwerEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::SecretsOfFaydwer || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsSeedsOfDestructionEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::SeedsOfDestruction || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsUnderfootEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::Underfoot || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsHouseOfThuleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::HouseOfThule || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheDarkenedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkenedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTheBurningLandsEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBurningLands || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
bool IsTormentOfVeliousEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TormentOfVelious || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||
|
||||
bool IsCurrentExpansionClassic() { return current_expansion == Expansion::ExpansionNumber::Classic; }
|
||||
bool IsCurrentExpansionTheRuinsOfKunark() { return current_expansion == Expansion::ExpansionNumber::TheRuinsOfKunark; }
|
||||
bool IsCurrentExpansionTheScarsOfVelious() { return current_expansion == Expansion::ExpansionNumber::TheScarsOfVelious; }
|
||||
bool IsCurrentExpansionTheShadowsOfLuclin() { return current_expansion == Expansion::ExpansionNumber::TheShadowsOfLuclin; }
|
||||
bool IsCurrentExpansionThePlanesOfPower() { return current_expansion == Expansion::ExpansionNumber::ThePlanesOfPower; }
|
||||
bool IsCurrentExpansionTheLegacyOfYkesha() { return current_expansion == Expansion::ExpansionNumber::TheLegacyOfYkesha; }
|
||||
bool IsCurrentExpansionLostDungeonsOfNorrath() { return current_expansion == Expansion::ExpansionNumber::LostDungeonsOfNorrath; }
|
||||
bool IsCurrentExpansionGatesOfDiscord() { return current_expansion == Expansion::ExpansionNumber::GatesOfDiscord; }
|
||||
bool IsCurrentExpansionOmensOfWar() { return current_expansion == Expansion::ExpansionNumber::OmensOfWar; }
|
||||
bool IsCurrentExpansionDragonsOfNorrath() { return current_expansion == Expansion::ExpansionNumber::DragonsOfNorrath; }
|
||||
bool IsCurrentExpansionDepthsOfDarkhollow() { return current_expansion == Expansion::ExpansionNumber::DepthsOfDarkhollow; }
|
||||
bool IsCurrentExpansionProphecyOfRo() { return current_expansion == Expansion::ExpansionNumber::ProphecyOfRo; }
|
||||
bool IsCurrentExpansionTheSerpentsSpine() { return current_expansion == Expansion::ExpansionNumber::TheSerpentsSpine; }
|
||||
bool IsCurrentExpansionTheBuriedSea() { return current_expansion == Expansion::ExpansionNumber::TheBuriedSea; }
|
||||
bool IsCurrentExpansionSecretsOfFaydwer() { return current_expansion == Expansion::ExpansionNumber::SecretsOfFaydwer; }
|
||||
bool IsCurrentExpansionSeedsOfDestruction() { return current_expansion == Expansion::ExpansionNumber::SeedsOfDestruction; }
|
||||
bool IsCurrentExpansionUnderfoot() { return current_expansion == Expansion::ExpansionNumber::Underfoot; }
|
||||
bool IsCurrentExpansionHouseOfThule() { return current_expansion == Expansion::ExpansionNumber::HouseOfThule; }
|
||||
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
|
||||
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
|
||||
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
|
||||
bool IsCurrentExpansionTheDarkenedSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkenedSea; }
|
||||
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
|
||||
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
|
||||
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
|
||||
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
|
||||
bool IsCurrentExpansionTormentOfVelious() { return current_expansion == Expansion::ExpansionNumber::TormentOfVelious; }
|
||||
|
||||
const std::vector<ContentFlagsRepository::ContentFlags> &GetContentFlags() const;
|
||||
std::vector<std::string> GetContentFlagsEnabled();
|
||||
std::vector<std::string> GetContentFlagsDisabled();
|
||||
bool IsContentFlagEnabled(const std::string& content_flag);
|
||||
bool IsContentFlagDisabled(const std::string& content_flag);
|
||||
void SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags);
|
||||
void ReloadContentFlags();
|
||||
WorldContentService * SetExpansionContext();
|
||||
|
||||
bool DoesPassContentFiltering(const ContentFlags& f);
|
||||
|
||||
WorldContentService * SetDatabase(Database *database);
|
||||
Database *GetDatabase() const;
|
||||
|
||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
||||
|
||||
private:
|
||||
int current_expansion{};
|
||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||
|
||||
// reference to database
|
||||
Database *m_database;
|
||||
};
|
||||
|
||||
extern WorldContentService content_service;
|
||||
|
||||
#endif //EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
+6
-200
@@ -1,98 +1,6 @@
|
||||
#include "global_define.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "crash.h"
|
||||
#include "strings.h"
|
||||
#include "process/process.h"
|
||||
#include "http/httplib.h"
|
||||
#include "http/uri.h"
|
||||
#include "json/json.h"
|
||||
#include "version.h"
|
||||
#include "eqemu_config.h"
|
||||
#include "serverinfo.h"
|
||||
#include "rulesys.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#if WINDOWS
|
||||
#define popen _popen
|
||||
#endif
|
||||
|
||||
void SendCrashReport(const std::string &crash_report)
|
||||
{
|
||||
// can configure multiple endpoints if need be
|
||||
std::vector<std::string> endpoints = {
|
||||
"http://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||
};
|
||||
|
||||
auto config = EQEmuConfig::get();
|
||||
for (auto &e: endpoints) {
|
||||
uri u(e);
|
||||
|
||||
std::string base_url = fmt::format("{}://{}", u.get_scheme(), u.get_host());
|
||||
if (u.get_port()) {
|
||||
base_url += fmt::format(":{}", u.get_port());
|
||||
}
|
||||
|
||||
// client
|
||||
httplib::Client r(base_url);
|
||||
r.set_connection_timeout(1, 0);
|
||||
r.set_read_timeout(1, 0);
|
||||
r.set_write_timeout(1, 0);
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// os info
|
||||
auto os = EQ::GetOS();
|
||||
auto cpus = EQ::GetCPUs();
|
||||
auto process_id = EQ::GetPID();
|
||||
auto rss = EQ::GetRSS() / 1048576.0;
|
||||
auto uptime = static_cast<uint32>(EQ::GetUptime());
|
||||
|
||||
// payload
|
||||
Json::Value p;
|
||||
p["platform_name"] = GetPlatformName();
|
||||
p["crash_report"] = crash_report;
|
||||
p["server_version"] = CURRENT_VERSION;
|
||||
p["compile_date"] = COMPILE_DATE;
|
||||
p["compile_time"] = COMPILE_TIME;
|
||||
p["server_name"] = config->LongName;
|
||||
p["server_short_name"] = config->ShortName;
|
||||
p["uptime"] = uptime;
|
||||
p["os_machine"] = os.machine;
|
||||
p["os_release"] = os.release;
|
||||
p["os_version"] = os.version;
|
||||
p["os_sysname"] = os.sysname;
|
||||
p["process_id"] = process_id;
|
||||
p["rss_memory"] = rss;
|
||||
p["cpus"] = cpus.size();
|
||||
p["origination_info"] = "";
|
||||
|
||||
if (!LogSys.origination_info.zone_short_name.empty()) {
|
||||
p["origination_info"] = fmt::format(
|
||||
"{} ({}) instance_id [{}]",
|
||||
LogSys.origination_info.zone_short_name,
|
||||
LogSys.origination_info.zone_long_name,
|
||||
LogSys.origination_info.instance_id
|
||||
);
|
||||
}
|
||||
|
||||
std::stringstream payload;
|
||||
payload << p;
|
||||
|
||||
if (auto res = r.Post(e, payload.str(), "application/json")) {
|
||||
if (res->status == 200) {
|
||||
LogInfo("Sent crash report");
|
||||
}
|
||||
else {
|
||||
LogError("Failed to send crash report to [{}]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
||||
#include "StackWalker.h"
|
||||
@@ -104,30 +12,22 @@ public:
|
||||
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
||||
virtual void OnOutput(LPCSTR szText) {
|
||||
char buffer[4096];
|
||||
for (int i = 0; i < 4096; ++i) {
|
||||
if (szText[i] == 0) {
|
||||
for(int i = 0; i < 4096; ++i) {
|
||||
if(szText[i] == 0) {
|
||||
buffer[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if (szText[i] == '\n' || szText[i] == '\r') {
|
||||
if(szText[i] == '\n' || szText[i] == '\r') {
|
||||
buffer[i] = ' ';
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
buffer[i] = szText[i];
|
||||
}
|
||||
}
|
||||
|
||||
std::string line = buffer;
|
||||
_lines.push_back(line);
|
||||
|
||||
Log(Logs::General, Logs::Crash, buffer);
|
||||
StackWalker::OnOutput(szText);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& const GetLines() { return _lines; }
|
||||
private:
|
||||
std::vector<std::string> _lines;
|
||||
};
|
||||
|
||||
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
@@ -201,20 +101,7 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
|
||||
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
EQEmuStackWalker sw;
|
||||
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||
|
||||
if (RuleB(Analytics, CrashReporting)) {
|
||||
std::string crash_report;
|
||||
auto& lines = sw.GetLines();
|
||||
|
||||
for (auto& line : lines) {
|
||||
crash_report += line;
|
||||
crash_report += "\n";
|
||||
}
|
||||
|
||||
SendCrashReport(crash_report);
|
||||
}
|
||||
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||
}
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
@@ -224,88 +111,7 @@ void set_exception_handler() {
|
||||
SetUnhandledExceptionFilter(windows_exception_handler);
|
||||
}
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
void print_trace()
|
||||
{
|
||||
bool does_gdb_exist = Strings::Contains(Process::execute("gdb -v"), "GNU");
|
||||
if (!does_gdb_exist) {
|
||||
LogCrash(
|
||||
"[Error] GDB is not installed, if you want crash dumps on Linux to work properly you will need GDB installed"
|
||||
);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
auto uid = geteuid();
|
||||
std::string temp_output_file = fmt::format("/tmp/dump-output-{}", Strings::Random(10));
|
||||
|
||||
// check for passwordless sudo if not root
|
||||
if (uid != 0) {
|
||||
bool sudo_password_required = Strings::Contains(Process::execute("sudo -n true"), "a password is required");
|
||||
if (sudo_password_required) {
|
||||
LogCrash(
|
||||
"[Error] Current user does not have passwordless sudo installed. It is required to automatically process crash dumps with GDB as non-root."
|
||||
);
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
char pid_buf[30];
|
||||
sprintf(pid_buf, "%d", getpid());
|
||||
char name_buf[512];
|
||||
name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
|
||||
int child_pid = fork();
|
||||
if (!child_pid) {
|
||||
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
dup2(fd, 1); // redirect output to stderr
|
||||
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
||||
if (uid == 0) {
|
||||
execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
|
||||
}
|
||||
else {
|
||||
execlp("sudo", "gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
abort(); /* If gdb failed to start */
|
||||
}
|
||||
else {
|
||||
waitpid(child_pid, nullptr, 0);
|
||||
}
|
||||
|
||||
std::ifstream input(temp_output_file);
|
||||
std::string crash_report;
|
||||
for (std::string line; getline(input, line);) {
|
||||
LogCrash("{}", line);
|
||||
crash_report += fmt::format("{}\n", line);
|
||||
}
|
||||
|
||||
std::remove(temp_output_file.c_str());
|
||||
|
||||
if (RuleB(Analytics, CrashReporting)) {
|
||||
SendCrashReport(crash_report);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// crash is off or an unhandled platform
|
||||
void set_exception_handler()
|
||||
{
|
||||
signal(SIGABRT, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
signal(SIGSEGV, reinterpret_cast<void (*)(int)>(print_trace));
|
||||
void set_exception_handler() {
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,876 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <bitset>
|
||||
#include <cctype>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
#if __cplusplus > 201402L
|
||||
#include <string_view>
|
||||
#define CRONCPP_IS_CPP17
|
||||
#endif
|
||||
|
||||
namespace cron
|
||||
{
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
#define HAS_STRING_VIEW
|
||||
#define STRING_VIEW std::string_view
|
||||
#define STRING_VIEW_NPOS std::string_view::npos
|
||||
#define CONSTEXPTR constexpr
|
||||
#else
|
||||
#define STRING_VIEW std::string const &
|
||||
#define STRING_VIEW_NPOS std::string::npos
|
||||
#define CONSTEXPTR
|
||||
#endif
|
||||
|
||||
using cron_int = uint8_t;
|
||||
|
||||
constexpr std::time_t INVALID_TIME = static_cast<std::time_t>(-1);
|
||||
|
||||
constexpr size_t INVALID_CRON_INDEX = static_cast<size_t>(-1);
|
||||
|
||||
class cronexpr;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
enum class cron_field
|
||||
{
|
||||
second,
|
||||
minute,
|
||||
hour_of_day,
|
||||
day_of_week,
|
||||
day_of_month,
|
||||
month,
|
||||
year
|
||||
};
|
||||
|
||||
template <typename Traits>
|
||||
static bool find_next(cronexpr const & cex,
|
||||
std::tm& date,
|
||||
size_t const dot);
|
||||
}
|
||||
|
||||
struct bad_cronexpr : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit bad_cronexpr(STRING_VIEW message) :
|
||||
std::runtime_error(message.data())
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
struct cron_standard_traits
|
||||
{
|
||||
static const cron_int CRON_MIN_SECONDS = 0;
|
||||
static const cron_int CRON_MAX_SECONDS = 59;
|
||||
|
||||
static const cron_int CRON_MIN_MINUTES = 0;
|
||||
static const cron_int CRON_MAX_MINUTES = 59;
|
||||
|
||||
static const cron_int CRON_MIN_HOURS = 0;
|
||||
static const cron_int CRON_MAX_HOURS = 23;
|
||||
|
||||
static const cron_int CRON_MIN_DAYS_OF_WEEK = 0;
|
||||
static const cron_int CRON_MAX_DAYS_OF_WEEK = 6;
|
||||
|
||||
static const cron_int CRON_MIN_DAYS_OF_MONTH = 1;
|
||||
static const cron_int CRON_MAX_DAYS_OF_MONTH = 31;
|
||||
|
||||
static const cron_int CRON_MIN_MONTHS = 1;
|
||||
static const cron_int CRON_MAX_MONTHS = 12;
|
||||
|
||||
static const cron_int CRON_MAX_YEARS_DIFF = 4;
|
||||
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
static const inline std::vector<std::string> DAYS = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
|
||||
static const inline std::vector<std::string> MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||||
#else
|
||||
static std::vector<std::string>& DAYS()
|
||||
{
|
||||
static std::vector<std::string> days = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
|
||||
return days;
|
||||
}
|
||||
|
||||
static std::vector<std::string>& MONTHS()
|
||||
{
|
||||
static std::vector<std::string> months = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||||
return months;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cron_oracle_traits
|
||||
{
|
||||
static const cron_int CRON_MIN_SECONDS = 0;
|
||||
static const cron_int CRON_MAX_SECONDS = 59;
|
||||
|
||||
static const cron_int CRON_MIN_MINUTES = 0;
|
||||
static const cron_int CRON_MAX_MINUTES = 59;
|
||||
|
||||
static const cron_int CRON_MIN_HOURS = 0;
|
||||
static const cron_int CRON_MAX_HOURS = 23;
|
||||
|
||||
static const cron_int CRON_MIN_DAYS_OF_WEEK = 1;
|
||||
static const cron_int CRON_MAX_DAYS_OF_WEEK = 7;
|
||||
|
||||
static const cron_int CRON_MIN_DAYS_OF_MONTH = 1;
|
||||
static const cron_int CRON_MAX_DAYS_OF_MONTH = 31;
|
||||
|
||||
static const cron_int CRON_MIN_MONTHS = 0;
|
||||
static const cron_int CRON_MAX_MONTHS = 11;
|
||||
|
||||
static const cron_int CRON_MAX_YEARS_DIFF = 4;
|
||||
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
static const inline std::vector<std::string> DAYS = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
|
||||
static const inline std::vector<std::string> MONTHS = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||||
#else
|
||||
|
||||
static std::vector<std::string>& DAYS()
|
||||
{
|
||||
static std::vector<std::string> days = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
|
||||
return days;
|
||||
}
|
||||
|
||||
static std::vector<std::string>& MONTHS()
|
||||
{
|
||||
static std::vector<std::string> months = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||||
return months;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cron_quartz_traits
|
||||
{
|
||||
static const cron_int CRON_MIN_SECONDS = 0;
|
||||
static const cron_int CRON_MAX_SECONDS = 59;
|
||||
|
||||
static const cron_int CRON_MIN_MINUTES = 0;
|
||||
static const cron_int CRON_MAX_MINUTES = 59;
|
||||
|
||||
static const cron_int CRON_MIN_HOURS = 0;
|
||||
static const cron_int CRON_MAX_HOURS = 23;
|
||||
|
||||
static const cron_int CRON_MIN_DAYS_OF_WEEK = 1;
|
||||
static const cron_int CRON_MAX_DAYS_OF_WEEK = 7;
|
||||
|
||||
static const cron_int CRON_MIN_DAYS_OF_MONTH = 1;
|
||||
static const cron_int CRON_MAX_DAYS_OF_MONTH = 31;
|
||||
|
||||
static const cron_int CRON_MIN_MONTHS = 1;
|
||||
static const cron_int CRON_MAX_MONTHS = 12;
|
||||
|
||||
static const cron_int CRON_MAX_YEARS_DIFF = 4;
|
||||
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
static const inline std::vector<std::string> DAYS = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
|
||||
static const inline std::vector<std::string> MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||||
#else
|
||||
static std::vector<std::string>& DAYS()
|
||||
{
|
||||
static std::vector<std::string> days = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
|
||||
return days;
|
||||
}
|
||||
|
||||
static std::vector<std::string>& MONTHS()
|
||||
{
|
||||
static std::vector<std::string> months = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||||
return months;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class cronexpr;
|
||||
|
||||
template <typename Traits = cron_standard_traits>
|
||||
static cronexpr make_cron(STRING_VIEW expr);
|
||||
|
||||
class cronexpr
|
||||
{
|
||||
std::bitset<60> seconds;
|
||||
std::bitset<60> minutes;
|
||||
std::bitset<24> hours;
|
||||
std::bitset<7> days_of_week;
|
||||
std::bitset<31> days_of_month;
|
||||
std::bitset<12> months;
|
||||
|
||||
friend bool operator==(cronexpr const & e1, cronexpr const & e2);
|
||||
friend bool operator!=(cronexpr const & e1, cronexpr const & e2);
|
||||
|
||||
template <typename Traits>
|
||||
friend bool detail::find_next(cronexpr const & cex,
|
||||
std::tm& date,
|
||||
size_t const dot);
|
||||
|
||||
friend std::string to_string(cronexpr const & cex);
|
||||
|
||||
template <typename Traits>
|
||||
friend cronexpr make_cron(STRING_VIEW expr);
|
||||
};
|
||||
|
||||
inline bool operator==(cronexpr const & e1, cronexpr const & e2)
|
||||
{
|
||||
return
|
||||
e1.seconds == e2.seconds &&
|
||||
e1.minutes == e2.minutes &&
|
||||
e1.hours == e2.hours &&
|
||||
e1.days_of_week == e2.days_of_week &&
|
||||
e1.days_of_month == e2.days_of_month &&
|
||||
e1.months == e2.months;
|
||||
}
|
||||
|
||||
inline bool operator!=(cronexpr const & e1, cronexpr const & e2)
|
||||
{
|
||||
return !(e1 == e2);
|
||||
}
|
||||
|
||||
inline std::string to_string(cronexpr const & cex)
|
||||
{
|
||||
return
|
||||
cex.seconds.to_string() + " " +
|
||||
cex.minutes.to_string() + " " +
|
||||
cex.hours.to_string() + " " +
|
||||
cex.days_of_month.to_string() + " " +
|
||||
cex.months.to_string() + " " +
|
||||
cex.days_of_week.to_string();
|
||||
}
|
||||
|
||||
namespace utils
|
||||
{
|
||||
inline std::time_t tm_to_time(std::tm& date)
|
||||
{
|
||||
return std::mktime(&date);
|
||||
}
|
||||
|
||||
inline std::tm* time_to_tm(std::time_t const * date, std::tm* const out)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
errno_t err = localtime_s(out, date);
|
||||
return 0 == err ? out : nullptr;
|
||||
#else
|
||||
return localtime_r(date, out);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::tm to_tm(STRING_VIEW time)
|
||||
{
|
||||
std::istringstream str(time.data());
|
||||
str.imbue(std::locale(setlocale(LC_ALL, nullptr)));
|
||||
|
||||
std::tm result;
|
||||
str >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
|
||||
if (str.fail()) throw std::runtime_error("Parsing date failed!");
|
||||
|
||||
result.tm_isdst = -1; // DST info not available
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string to_string(std::tm const & tm)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str.imbue(std::locale(setlocale(LC_ALL, nullptr)));
|
||||
str << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||
if (str.fail()) throw std::runtime_error("Writing date failed!");
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
inline std::string to_upper(std::string text)
|
||||
{
|
||||
std::transform(std::begin(text), std::end(text),
|
||||
std::begin(text), static_cast<int(*)(int)>(std::toupper));
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static std::vector<std::string> split(STRING_VIEW text, char const delimiter)
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
std::string token;
|
||||
std::istringstream tokenStream(text.data());
|
||||
while (std::getline(tokenStream, token, delimiter))
|
||||
{
|
||||
tokens.push_back(token);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
CONSTEXPTR inline bool contains(STRING_VIEW text, char const ch) noexcept
|
||||
{
|
||||
return STRING_VIEW_NPOS != text.find_first_of(ch);
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline cron_int to_cron_int(STRING_VIEW text)
|
||||
{
|
||||
try
|
||||
{
|
||||
return static_cast<cron_int>(std::stoul(text.data()));
|
||||
}
|
||||
catch (std::exception const & ex)
|
||||
{
|
||||
throw bad_cronexpr(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
static std::string replace_ordinals(
|
||||
std::string text,
|
||||
std::vector<std::string> const & replacement)
|
||||
{
|
||||
for (size_t i = 0; i < replacement.size(); ++i)
|
||||
{
|
||||
auto pos = text.find(replacement[i]);
|
||||
if (std::string::npos != pos)
|
||||
text.replace(pos, 3 ,std::to_string(i));
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static std::pair<cron_int, cron_int> make_range(
|
||||
STRING_VIEW field,
|
||||
cron_int const minval,
|
||||
cron_int const maxval)
|
||||
{
|
||||
cron_int first = 0;
|
||||
cron_int last = 0;
|
||||
if (field.size() == 1 && field[0] == '*')
|
||||
{
|
||||
first = minval;
|
||||
last = maxval;
|
||||
}
|
||||
else if (!utils::contains(field, '-'))
|
||||
{
|
||||
first = to_cron_int(field);
|
||||
last = first;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto parts = utils::split(field, '-');
|
||||
if (parts.size() != 2)
|
||||
throw bad_cronexpr("Specified range requires two fields");
|
||||
|
||||
first = to_cron_int(parts[0]);
|
||||
last = to_cron_int(parts[1]);
|
||||
}
|
||||
|
||||
if (first > maxval || last > maxval)
|
||||
{
|
||||
throw bad_cronexpr("Specified range exceeds maximum");
|
||||
}
|
||||
if (first < minval || last < minval)
|
||||
{
|
||||
throw bad_cronexpr("Specified range is less than minimum");
|
||||
}
|
||||
if (first > last)
|
||||
{
|
||||
throw bad_cronexpr("Specified range start exceeds range end");
|
||||
}
|
||||
|
||||
return { first, last };
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static void set_cron_field(
|
||||
STRING_VIEW value,
|
||||
std::bitset<N>& target,
|
||||
cron_int const minval,
|
||||
cron_int const maxval)
|
||||
{
|
||||
if(value.length() > 0 && value[value.length()-1] == ',')
|
||||
throw bad_cronexpr("Value cannot end with comma");
|
||||
|
||||
auto fields = utils::split(value, ',');
|
||||
if (fields.empty())
|
||||
throw bad_cronexpr("Expression parsing error");
|
||||
|
||||
for (auto const & field : fields)
|
||||
{
|
||||
if (!utils::contains(field, '/'))
|
||||
{
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
auto[first, last] = detail::make_range(field, minval, maxval);
|
||||
#else
|
||||
auto range = detail::make_range(field, minval, maxval);
|
||||
auto first = range.first;
|
||||
auto last = range.second;
|
||||
#endif
|
||||
for (cron_int i = first - minval; i <= last - minval; ++i)
|
||||
{
|
||||
target.set(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto parts = utils::split(field, '/');
|
||||
if (parts.size() != 2)
|
||||
throw bad_cronexpr("Incrementer must have two fields");
|
||||
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
auto[first, last] = detail::make_range(parts[0], minval, maxval);
|
||||
#else
|
||||
auto range = detail::make_range(parts[0], minval, maxval);
|
||||
auto first = range.first;
|
||||
auto last = range.second;
|
||||
#endif
|
||||
|
||||
if (!utils::contains(parts[0], '-'))
|
||||
{
|
||||
last = maxval;
|
||||
}
|
||||
|
||||
auto delta = detail::to_cron_int(parts[1]);
|
||||
if(delta <= 0)
|
||||
throw bad_cronexpr("Incrementer must be a positive value");
|
||||
|
||||
for (cron_int i = first - minval; i <= last - minval; i += delta)
|
||||
{
|
||||
target.set(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
static void set_cron_days_of_week(
|
||||
std::string value,
|
||||
std::bitset<7>& target)
|
||||
{
|
||||
auto days = utils::to_upper(value);
|
||||
auto days_replaced = detail::replace_ordinals(
|
||||
days,
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
Traits::DAYS
|
||||
#else
|
||||
Traits::DAYS()
|
||||
#endif
|
||||
);
|
||||
|
||||
if (days_replaced.size() == 1 && days_replaced[0] == '?')
|
||||
days_replaced[0] = '*';
|
||||
|
||||
set_cron_field(
|
||||
days_replaced,
|
||||
target,
|
||||
Traits::CRON_MIN_DAYS_OF_WEEK,
|
||||
Traits::CRON_MAX_DAYS_OF_WEEK);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
static void set_cron_days_of_month(
|
||||
std::string value,
|
||||
std::bitset<31>& target)
|
||||
{
|
||||
if (value.size() == 1 && value[0] == '?')
|
||||
value[0] = '*';
|
||||
|
||||
set_cron_field(
|
||||
value,
|
||||
target,
|
||||
Traits::CRON_MIN_DAYS_OF_MONTH,
|
||||
Traits::CRON_MAX_DAYS_OF_MONTH);
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
static void set_cron_month(
|
||||
std::string value,
|
||||
std::bitset<12>& target)
|
||||
{
|
||||
auto month = utils::to_upper(value);
|
||||
auto month_replaced = replace_ordinals(
|
||||
month,
|
||||
#ifdef CRONCPP_IS_CPP17
|
||||
Traits::MONTHS
|
||||
#else
|
||||
Traits::MONTHS()
|
||||
#endif
|
||||
);
|
||||
|
||||
set_cron_field(
|
||||
month_replaced,
|
||||
target,
|
||||
Traits::CRON_MIN_MONTHS,
|
||||
Traits::CRON_MAX_MONTHS);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
inline size_t next_set_bit(
|
||||
std::bitset<N> const & target,
|
||||
size_t /*minimum*/,
|
||||
size_t /*maximum*/,
|
||||
size_t offset)
|
||||
{
|
||||
for (auto i = offset; i < N; ++i)
|
||||
{
|
||||
if (target.test(i)) return i;
|
||||
}
|
||||
|
||||
return INVALID_CRON_INDEX;
|
||||
}
|
||||
|
||||
inline void add_to_field(
|
||||
std::tm& date,
|
||||
cron_field const field,
|
||||
int const val)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case cron_field::second:
|
||||
date.tm_sec += val;
|
||||
break;
|
||||
case cron_field::minute:
|
||||
date.tm_min += val;
|
||||
break;
|
||||
case cron_field::hour_of_day:
|
||||
date.tm_hour += val;
|
||||
break;
|
||||
case cron_field::day_of_week:
|
||||
case cron_field::day_of_month:
|
||||
date.tm_mday += val;
|
||||
break;
|
||||
case cron_field::month:
|
||||
date.tm_mon += val;
|
||||
break;
|
||||
case cron_field::year:
|
||||
date.tm_year += val;
|
||||
break;
|
||||
}
|
||||
|
||||
if (INVALID_TIME == utils::tm_to_time(date))
|
||||
throw bad_cronexpr("Invalid time expression");
|
||||
}
|
||||
|
||||
inline void set_field(
|
||||
std::tm& date,
|
||||
cron_field const field,
|
||||
int const val)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case cron_field::second:
|
||||
date.tm_sec = val;
|
||||
break;
|
||||
case cron_field::minute:
|
||||
date.tm_min = val;
|
||||
break;
|
||||
case cron_field::hour_of_day:
|
||||
date.tm_hour = val;
|
||||
break;
|
||||
case cron_field::day_of_week:
|
||||
date.tm_wday = val;
|
||||
break;
|
||||
case cron_field::day_of_month:
|
||||
date.tm_mday = val;
|
||||
break;
|
||||
case cron_field::month:
|
||||
date.tm_mon = val;
|
||||
break;
|
||||
case cron_field::year:
|
||||
date.tm_year = val;
|
||||
break;
|
||||
}
|
||||
|
||||
if (INVALID_TIME == utils::tm_to_time(date))
|
||||
throw bad_cronexpr("Invalid time expression");
|
||||
}
|
||||
|
||||
inline void reset_field(
|
||||
std::tm& date,
|
||||
cron_field const field)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case cron_field::second:
|
||||
date.tm_sec = 0;
|
||||
break;
|
||||
case cron_field::minute:
|
||||
date.tm_min = 0;
|
||||
break;
|
||||
case cron_field::hour_of_day:
|
||||
date.tm_hour = 0;
|
||||
break;
|
||||
case cron_field::day_of_week:
|
||||
date.tm_wday = 0;
|
||||
break;
|
||||
case cron_field::day_of_month:
|
||||
date.tm_mday = 1;
|
||||
break;
|
||||
case cron_field::month:
|
||||
date.tm_mon = 0;
|
||||
break;
|
||||
case cron_field::year:
|
||||
date.tm_year = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (INVALID_TIME == utils::tm_to_time(date))
|
||||
throw bad_cronexpr("Invalid time expression");
|
||||
}
|
||||
|
||||
inline void reset_all_fields(
|
||||
std::tm& date,
|
||||
std::bitset<7> const & marked_fields)
|
||||
{
|
||||
for (size_t i = 0; i < marked_fields.size(); ++i)
|
||||
{
|
||||
if (marked_fields.test(i))
|
||||
reset_field(date, static_cast<cron_field>(i));
|
||||
}
|
||||
}
|
||||
|
||||
inline void mark_field(
|
||||
std::bitset<7> & orders,
|
||||
cron_field const field)
|
||||
{
|
||||
if (!orders.test(static_cast<size_t>(field)))
|
||||
orders.set(static_cast<size_t>(field));
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static size_t find_next(
|
||||
std::bitset<N> const & target,
|
||||
std::tm& date,
|
||||
unsigned int const minimum,
|
||||
unsigned int const maximum,
|
||||
unsigned int const value,
|
||||
cron_field const field,
|
||||
cron_field const next_field,
|
||||
std::bitset<7> const & marked_fields)
|
||||
{
|
||||
auto next_value = next_set_bit(target, minimum, maximum, value);
|
||||
if (INVALID_CRON_INDEX == next_value)
|
||||
{
|
||||
add_to_field(date, next_field, 1);
|
||||
reset_field(date, field);
|
||||
next_value = next_set_bit(target, minimum, maximum, 0);
|
||||
}
|
||||
|
||||
if (INVALID_CRON_INDEX == next_value || next_value != value)
|
||||
{
|
||||
set_field(date, field, static_cast<int>(next_value));
|
||||
reset_all_fields(date, marked_fields);
|
||||
}
|
||||
|
||||
return next_value;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
static size_t find_next_day(
|
||||
std::tm& date,
|
||||
std::bitset<31> const & days_of_month,
|
||||
size_t day_of_month,
|
||||
std::bitset<7> const & days_of_week,
|
||||
size_t day_of_week,
|
||||
std::bitset<7> const & marked_fields)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
unsigned int maximum = 366;
|
||||
while (
|
||||
(!days_of_month.test(day_of_month - Traits::CRON_MIN_DAYS_OF_MONTH) ||
|
||||
!days_of_week.test(day_of_week - Traits::CRON_MIN_DAYS_OF_WEEK))
|
||||
&& count++ < maximum)
|
||||
{
|
||||
add_to_field(date, cron_field::day_of_month, 1);
|
||||
|
||||
day_of_month = date.tm_mday;
|
||||
day_of_week = date.tm_wday;
|
||||
|
||||
reset_all_fields(date, marked_fields);
|
||||
}
|
||||
|
||||
return day_of_month;
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
static bool find_next(cronexpr const & cex,
|
||||
std::tm& date,
|
||||
size_t const dot)
|
||||
{
|
||||
bool res = true;
|
||||
|
||||
std::bitset<7> marked_fields{ 0 };
|
||||
std::bitset<7> empty_list{ 0 };
|
||||
|
||||
unsigned int second = date.tm_sec;
|
||||
auto updated_second = find_next(
|
||||
cex.seconds,
|
||||
date,
|
||||
Traits::CRON_MIN_SECONDS,
|
||||
Traits::CRON_MAX_SECONDS,
|
||||
second,
|
||||
cron_field::second,
|
||||
cron_field::minute,
|
||||
empty_list);
|
||||
|
||||
if (second == updated_second)
|
||||
{
|
||||
mark_field(marked_fields, cron_field::second);
|
||||
}
|
||||
|
||||
unsigned int minute = date.tm_min;
|
||||
auto update_minute = find_next(
|
||||
cex.minutes,
|
||||
date,
|
||||
Traits::CRON_MIN_MINUTES,
|
||||
Traits::CRON_MAX_MINUTES,
|
||||
minute,
|
||||
cron_field::minute,
|
||||
cron_field::hour_of_day,
|
||||
marked_fields);
|
||||
if (minute == update_minute)
|
||||
{
|
||||
mark_field(marked_fields, cron_field::minute);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = find_next<Traits>(cex, date, dot);
|
||||
if (!res) return res;
|
||||
}
|
||||
|
||||
unsigned int hour = date.tm_hour;
|
||||
auto updated_hour = find_next(
|
||||
cex.hours,
|
||||
date,
|
||||
Traits::CRON_MIN_HOURS,
|
||||
Traits::CRON_MAX_HOURS,
|
||||
hour,
|
||||
cron_field::hour_of_day,
|
||||
cron_field::day_of_week,
|
||||
marked_fields);
|
||||
if (hour == updated_hour)
|
||||
{
|
||||
mark_field(marked_fields, cron_field::hour_of_day);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = find_next<Traits>(cex, date, dot);
|
||||
if (!res) return res;
|
||||
}
|
||||
|
||||
unsigned int day_of_week = date.tm_wday;
|
||||
unsigned int day_of_month = date.tm_mday;
|
||||
auto updated_day_of_month = find_next_day<Traits>(
|
||||
date,
|
||||
cex.days_of_month,
|
||||
day_of_month,
|
||||
cex.days_of_week,
|
||||
day_of_week,
|
||||
marked_fields);
|
||||
if (day_of_month == updated_day_of_month)
|
||||
{
|
||||
mark_field(marked_fields, cron_field::day_of_month);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = find_next<Traits>(cex, date, dot);
|
||||
if (!res) return res;
|
||||
}
|
||||
|
||||
unsigned int month = date.tm_mon;
|
||||
auto updated_month = find_next(
|
||||
cex.months,
|
||||
date,
|
||||
Traits::CRON_MIN_MONTHS,
|
||||
Traits::CRON_MAX_MONTHS,
|
||||
month,
|
||||
cron_field::month,
|
||||
cron_field::year,
|
||||
marked_fields);
|
||||
if (month != updated_month)
|
||||
{
|
||||
if (date.tm_year - dot > Traits::CRON_MAX_YEARS_DIFF)
|
||||
return false;
|
||||
|
||||
res = find_next<Traits>(cex, date, dot);
|
||||
if (!res) return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
static cronexpr make_cron(STRING_VIEW expr)
|
||||
{
|
||||
cronexpr cex;
|
||||
|
||||
if (expr.empty())
|
||||
throw bad_cronexpr("Invalid empty cron expression");
|
||||
|
||||
auto fields = utils::split(expr, ' ');
|
||||
fields.erase(
|
||||
std::remove_if(std::begin(fields), std::end(fields),
|
||||
[](STRING_VIEW s) {return s.empty(); }),
|
||||
std::end(fields));
|
||||
if (fields.size() != 6)
|
||||
throw bad_cronexpr("cron expression must have six fields");
|
||||
|
||||
detail::set_cron_field(fields[0], cex.seconds, Traits::CRON_MIN_SECONDS, Traits::CRON_MAX_SECONDS);
|
||||
detail::set_cron_field(fields[1], cex.minutes, Traits::CRON_MIN_MINUTES, Traits::CRON_MAX_MINUTES);
|
||||
detail::set_cron_field(fields[2], cex.hours, Traits::CRON_MIN_HOURS, Traits::CRON_MAX_HOURS);
|
||||
|
||||
detail::set_cron_days_of_week<Traits>(fields[5], cex.days_of_week);
|
||||
|
||||
detail::set_cron_days_of_month<Traits>(fields[3], cex.days_of_month);
|
||||
|
||||
detail::set_cron_month<Traits>(fields[4], cex.months);
|
||||
|
||||
return cex;
|
||||
}
|
||||
|
||||
template <typename Traits = cron_standard_traits>
|
||||
static std::tm cron_next(cronexpr const & cex, std::tm date)
|
||||
{
|
||||
time_t original = utils::tm_to_time(date);
|
||||
if (INVALID_TIME == original) return {};
|
||||
|
||||
if (!detail::find_next<Traits>(cex, date, date.tm_year))
|
||||
return {};
|
||||
|
||||
time_t calculated = utils::tm_to_time(date);
|
||||
if (INVALID_TIME == calculated) return {};
|
||||
|
||||
if (calculated == original)
|
||||
{
|
||||
add_to_field(date, detail::cron_field::second, 1);
|
||||
if (!detail::find_next<Traits>(cex, date, date.tm_year))
|
||||
return {};
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
template <typename Traits = cron_standard_traits>
|
||||
static std::time_t cron_next(cronexpr const & cex, std::time_t const & date)
|
||||
{
|
||||
std::tm val;
|
||||
std::tm* dt = utils::time_to_tm(&date, &val);
|
||||
if (dt == nullptr) return INVALID_TIME;
|
||||
|
||||
time_t original = utils::tm_to_time(*dt);
|
||||
if (INVALID_TIME == original) return INVALID_TIME;
|
||||
|
||||
if(!detail::find_next<Traits>(cex, *dt, dt->tm_year))
|
||||
return INVALID_TIME;
|
||||
|
||||
time_t calculated = utils::tm_to_time(*dt);
|
||||
if (INVALID_TIME == calculated) return calculated;
|
||||
|
||||
if (calculated == original)
|
||||
{
|
||||
add_to_field(*dt, detail::cron_field::second, 1);
|
||||
if(!detail::find_next<Traits>(cex, *dt, dt->tm_year))
|
||||
return INVALID_TIME;
|
||||
}
|
||||
|
||||
return utils::tm_to_time(*dt);
|
||||
}
|
||||
}
|
||||
+36
-38
@@ -1,57 +1,55 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
#pragma once
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_DATA_VERIFICATION_H
|
||||
#define COMMON_DATA_VERIFICATION_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace EQ {
|
||||
template<typename T>
|
||||
T Clamp(const T &value, const T &lower, const T &upper)
|
||||
{
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
template <typename T>
|
||||
T Clamp(const T& value, const T& lower, const T& upper) {
|
||||
return std::max(lower, std::min(value, upper));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ClampLower(const T &value, const T &lower)
|
||||
{
|
||||
template <typename T>
|
||||
T ClampLower(const T& value, const T& lower) {
|
||||
return std::max(lower, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ClampUpper(const T &value, const T &upper)
|
||||
{
|
||||
template <typename T>
|
||||
T ClampUpper(const T& value, const T& upper) {
|
||||
return std::min(value, upper);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ValueWithin(const T &value, const T &lower, const T &upper)
|
||||
{
|
||||
template <typename T>
|
||||
bool ValueWithin(const T& value, const T& lower, const T& upper) {
|
||||
return value >= lower && value <= upper;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
bool ValueWithin(const T1 &value, const T2 &lower, const T3 &upper)
|
||||
{
|
||||
return value >= (T1) lower && value <= (T1) upper;
|
||||
template <typename T1, typename T2, typename T3>
|
||||
bool ValueWithin(const T1& value, const T2& lower, const T3& upper) {
|
||||
return value >= (T1)lower && value <= (T1)upper;
|
||||
}
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_DATA_VERIFICATION_H*/
|
||||
|
||||
+716
-932
File diff suppressed because it is too large
Load Diff
+81
-80
@@ -40,11 +40,29 @@
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
class InventoryProfile;
|
||||
}
|
||||
|
||||
struct EventLogDetails_Struct {
|
||||
uint32 id;
|
||||
char accountname[64];
|
||||
uint32 account_id;
|
||||
int16 status;
|
||||
char charactername[64];
|
||||
char targetname[64];
|
||||
char timestamp[64];
|
||||
char descriptiontype[64];
|
||||
char details[128];
|
||||
};
|
||||
|
||||
struct CharacterEventLog_Struct {
|
||||
uint32 count;
|
||||
uint8 eventid;
|
||||
EventLogDetails_Struct eld[255];
|
||||
};
|
||||
|
||||
struct npcDecayTimes_Struct {
|
||||
uint16 minlvl;
|
||||
uint16 maxlvl;
|
||||
@@ -76,138 +94,115 @@ class PTimerList;
|
||||
# define _ISNAN_(a) std::isnan(a)
|
||||
#endif
|
||||
|
||||
#define SQL(...) #__VA_ARGS__
|
||||
|
||||
class LogSettings;
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port, std::string connection_label = "default");
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
|
||||
~Database();
|
||||
|
||||
/* Character Creation */
|
||||
|
||||
bool CreateCharacter(
|
||||
uint32 account_id,
|
||||
char *name,
|
||||
uint16 gender,
|
||||
uint16 race,
|
||||
uint16 class_,
|
||||
uint8 str,
|
||||
uint8 sta,
|
||||
uint8 cha,
|
||||
uint8 dex,
|
||||
uint8 int_,
|
||||
uint8 agi,
|
||||
uint8 wis,
|
||||
uint8 face
|
||||
);
|
||||
bool DeleteCharacter(char *character_name);
|
||||
bool MoveCharacterToZone(const char *charname, uint32 zone_id);
|
||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||
bool ReserveName(uint32 account_id, char *name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||
bool UpdateName(const char *oldname, const char *newname);
|
||||
bool CopyCharacter(
|
||||
const std::string& source_character_name,
|
||||
const std::string& destination_character_name,
|
||||
const std::string& destination_account_name
|
||||
);
|
||||
bool AddToNameFilter(const char* name);
|
||||
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
|
||||
bool DeleteCharacter(char* name);
|
||||
bool MoveCharacterToZone(const char* charname, const char* zonename);
|
||||
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
|
||||
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
|
||||
bool ReserveName(uint32 account_id, char* name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
|
||||
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
|
||||
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv);
|
||||
bool UpdateName(const char* oldname, const char* newname);
|
||||
|
||||
/* General Information Queries */
|
||||
|
||||
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(std::string name);
|
||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(std::string name, bool surname = false);
|
||||
bool CheckUsedName(std::string name);
|
||||
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the Banned_IPs table.
|
||||
bool AddGMIP(char* ip_address, char* name);
|
||||
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||
bool CheckNameFilter(const char* name, bool surname = false);
|
||||
bool CheckUsedName(const char* name);
|
||||
|
||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||
uint32 GetAccountIDByChar(uint32 char_id);
|
||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const char *name);
|
||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
||||
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
std::string GetCharNameByID(uint32 char_id);
|
||||
std::string GetNPCNameByID(uint32 npc_id);
|
||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, std::string login_ip);
|
||||
void LoginIP(uint32 AccountID, const char* LoginIP);
|
||||
|
||||
/* Instancing */
|
||||
|
||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
||||
bool AddClientToInstance(uint16 instance_id, uint32 char_id);
|
||||
bool CharacterInInstanceGroup(uint16 instance_id, uint32 char_id);
|
||||
bool CheckInstanceExists(uint16 instance_id);
|
||||
bool CheckInstanceExpired(uint16 instance_id);
|
||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
||||
bool GetUnusedInstanceID(uint16 &instance_id);
|
||||
bool IsGlobalInstance(uint16 instance_id);
|
||||
bool GlobalInstance(uint16 instance_id);
|
||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||
bool RemoveClientsFromInstance(uint16 instance_id);
|
||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 char_id);
|
||||
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||
|
||||
uint16 GetInstanceID(const char* zone, uint32 charid, int16 version);
|
||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
||||
uint8_t GetInstanceVersion(uint16 instance_id);
|
||||
uint16 GetInstanceVersion(uint16 instance_id);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
||||
uint32 GetInstanceZoneID(uint16 instance_id);
|
||||
uint32 VersionFromInstanceID(uint16 instance_id);
|
||||
uint32 ZoneIDFromInstanceID(uint16 instance_id);
|
||||
|
||||
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
||||
void BuryCorpsesInInstance(uint16 instance_id);
|
||||
void DeleteInstance(uint16 instance_id);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
||||
void FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid);
|
||||
void FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list);
|
||||
void PurgeExpiredInstances();
|
||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||
|
||||
/* Adventure related. */
|
||||
|
||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win = false, bool remove = false);
|
||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win);
|
||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
||||
|
||||
/* Account Related */
|
||||
|
||||
bool DeleteAccount(const char *name, const char* loginserver);
|
||||
bool DeleteAccount(const char* name);
|
||||
bool GetLiveChar(uint32 account_id, char* cname);
|
||||
bool SetAccountStatus(const char* name, int16 status);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 accid, const char* password);
|
||||
bool UpdateLiveChar(char* charname, uint32 account_id);
|
||||
bool UpdateLiveChar(char* charname, uint32 lsaccount_id);
|
||||
|
||||
int16 CheckStatus(uint32 account_id);
|
||||
|
||||
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
|
||||
|
||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||
uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0);
|
||||
uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0);
|
||||
uint32 GetMiniLoginAccount(char* ip);
|
||||
uint8 GetAgreementFlag(uint32 acctid);
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 acctid);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
|
||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
|
||||
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
uint32 GetGroupID(const char* name);
|
||||
|
||||
|
||||
void ClearGroup(uint32 gid = 0);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
||||
@@ -226,8 +221,6 @@ public:
|
||||
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
|
||||
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
|
||||
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
|
||||
/* Database Conversions 'database_conversions.cpp' */
|
||||
|
||||
bool CheckDatabaseConversions();
|
||||
@@ -242,11 +235,19 @@ public:
|
||||
|
||||
/* General Queries */
|
||||
|
||||
bool GetSafePoints(const char* short_name, uint32 version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr);
|
||||
bool GetSafePoints(uint32 zoneID, uint32 version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr) { return GetSafePoints(GetZoneName(zoneID), version, safe_x, safe_y, safe_z, minstatus, minlevel, flag_needed); }
|
||||
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
|
||||
bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0);
|
||||
bool LoadPTimers(uint32 charid, PTimerList &into);
|
||||
bool LoadZoneNames();
|
||||
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
|
||||
const char* GetZoneName(uint32 zoneID, bool ErrorUnknown = false);
|
||||
|
||||
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
|
||||
uint32 GetZoneID(const char* zonename);
|
||||
|
||||
uint8 GetPEQZone(uint32 zoneID, uint32 version);
|
||||
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
||||
uint8 GetServerType();
|
||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||
@@ -261,13 +262,13 @@ public:
|
||||
void SetLFP(uint32 CharID, bool LFP);
|
||||
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
|
||||
|
||||
int CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
void ClearInvSnapshots(bool use_rule = true);
|
||||
|
||||
/* EQEmuLogSys */
|
||||
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
|
||||
|
||||
private:
|
||||
std::map<uint32,std::string> zonename_array;
|
||||
|
||||
Mutex Mvarcache;
|
||||
VarCache_Struct varcache;
|
||||
|
||||
@@ -1,537 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <iterator>
|
||||
#include "database_dump_service.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../strings.h"
|
||||
#include "../eqemu_config.h"
|
||||
#include "../database_schema.h"
|
||||
#include "../file.h"
|
||||
#include "../process/process.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#endif
|
||||
|
||||
#define DATABASE_DUMP_PATH "backups/"
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
bool DatabaseDumpService::IsMySQLInstalled()
|
||||
{
|
||||
std::string version_output = GetMySQLVersion();
|
||||
|
||||
return version_output.find("mysql") != std::string::npos && version_output.find("Ver") != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Linux
|
||||
* @return bool
|
||||
*/
|
||||
bool DatabaseDumpService::IsTarAvailable()
|
||||
{
|
||||
std::string version_output = Process::execute("tar --version");
|
||||
|
||||
return version_output.find("GNU tar") != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Windows
|
||||
* @return bool
|
||||
*/
|
||||
bool DatabaseDumpService::Is7ZipAvailable()
|
||||
{
|
||||
std::string version_output = Process::execute("7z --help");
|
||||
|
||||
return version_output.find("7-Zip") != std::string::npos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
bool DatabaseDumpService::HasCompressionBinary()
|
||||
{
|
||||
return IsTarAvailable() || Is7ZipAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetMySQLVersion()
|
||||
{
|
||||
std::string version_output = Process::execute("mysql --version");
|
||||
|
||||
return Strings::Trim(version_output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
||||
{
|
||||
auto config = EQEmuConfig::get();
|
||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||
return fmt::format(
|
||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||
config->ContentDbUsername,
|
||||
config->ContentDbPassword,
|
||||
config->ContentDbHost,
|
||||
config->ContentDbPort,
|
||||
config->ContentDbName
|
||||
);
|
||||
};
|
||||
|
||||
return fmt::format(
|
||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||
config->DatabaseUsername,
|
||||
config->DatabasePassword,
|
||||
config->DatabaseHost,
|
||||
config->DatabasePort,
|
||||
config->DatabaseDB
|
||||
);
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetPlayerTablesList()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetPlayerTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetBotTablesList()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetBotTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetMercTablesList()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetMercTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetLoginTableList()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetQueryServTables()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetSystemTablesList()
|
||||
{
|
||||
auto system_tables = DatabaseSchema::GetServerTables();
|
||||
auto version_tables = DatabaseSchema::GetVersionTables();
|
||||
|
||||
system_tables.insert(
|
||||
std::end(system_tables),
|
||||
std::begin(version_tables),
|
||||
std::end(version_tables)
|
||||
);
|
||||
|
||||
return Strings::Join(system_tables, " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetStateTablesList()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetStateTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetContentTablesList()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetContentTables(), " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string GetDumpDate()
|
||||
{
|
||||
|
||||
time_t now = time(nullptr);
|
||||
struct tm time_struct{};
|
||||
char buf[80];
|
||||
time_struct = *localtime(&now);
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d", &time_struct);
|
||||
|
||||
std::string time = buf;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetSetDumpPath()
|
||||
{
|
||||
return !GetDumpPath().empty() ? GetDumpPath() : DATABASE_DUMP_PATH;
|
||||
}
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetDumpFileNameWithPath()
|
||||
{
|
||||
return GetSetDumpPath() + GetDumpFileName();
|
||||
}
|
||||
|
||||
void DatabaseDumpService::Dump()
|
||||
{
|
||||
if (!IsMySQLInstalled()) {
|
||||
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsDumpDropTableSyntaxOnly()) {
|
||||
SetDumpOutputToConsole(true);
|
||||
}
|
||||
|
||||
if (IsDumpOutputToConsole()) {
|
||||
LogSys.SilenceConsoleLogging();
|
||||
}
|
||||
|
||||
LogInfo("MySQL installed [{}]", GetMySQLVersion());
|
||||
|
||||
SetDumpFileName(EQEmuConfig::get()->DatabaseDB + '-' + GetDumpDate());
|
||||
|
||||
auto config = EQEmuConfig::get();
|
||||
|
||||
LogInfo(
|
||||
"Database [{}] Host [{}] Username [{}]",
|
||||
config->DatabaseDB,
|
||||
config->DatabaseHost,
|
||||
config->DatabaseUsername
|
||||
);
|
||||
|
||||
std::string options = "--allow-keywords --extended-insert --max-allowed-packet=1G --net-buffer-length=32704";
|
||||
if (IsDumpWithNoData()) {
|
||||
options += " --no-data";
|
||||
}
|
||||
|
||||
if (!IsDumpTableLock()) {
|
||||
options += " --skip-lock-tables";
|
||||
}
|
||||
|
||||
std::string tables_to_dump;
|
||||
std::string dump_descriptor;
|
||||
|
||||
if (!IsDumpAllTables()) {
|
||||
if (IsDumpPlayerTables()) {
|
||||
tables_to_dump += GetPlayerTablesList() + " ";
|
||||
dump_descriptor += "-player";
|
||||
}
|
||||
|
||||
if (IsDumpBotTables()) {
|
||||
tables_to_dump += GetBotTablesList() + " ";
|
||||
dump_descriptor += "-bots";
|
||||
}
|
||||
|
||||
if (IsDumpMercTables()) {
|
||||
tables_to_dump += GetMercTablesList() + " ";
|
||||
dump_descriptor += "-mercs";
|
||||
}
|
||||
|
||||
if (IsDumpSystemTables()) {
|
||||
tables_to_dump += GetSystemTablesList() + " ";
|
||||
dump_descriptor += "-system";
|
||||
}
|
||||
|
||||
if (IsDumpStateTables()) {
|
||||
tables_to_dump += GetStateTablesList() + " ";
|
||||
dump_descriptor += "-state";
|
||||
}
|
||||
|
||||
if (IsDumpContentTables()) {
|
||||
tables_to_dump += GetContentTablesList() + " ";
|
||||
dump_descriptor += "-content";
|
||||
}
|
||||
|
||||
if (IsDumpLoginServerTables()) {
|
||||
tables_to_dump += GetLoginTableList() + " ";
|
||||
dump_descriptor += "-login";
|
||||
}
|
||||
|
||||
if (IsDumpQueryServerTables()) {
|
||||
tables_to_dump += GetQueryServTables();
|
||||
dump_descriptor += "-queryserv";
|
||||
}
|
||||
}
|
||||
|
||||
if (!dump_descriptor.empty()) {
|
||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* If we are dumping to stdout then we don't generate a file
|
||||
*/
|
||||
std::string pipe_file;
|
||||
if (!IsDumpOutputToConsole()) {
|
||||
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
||||
}
|
||||
|
||||
std::string execute_command = fmt::format(
|
||||
"{} {} {} {}",
|
||||
GetBaseMySQLDumpCommand(),
|
||||
options,
|
||||
tables_to_dump,
|
||||
pipe_file
|
||||
);
|
||||
|
||||
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||
File::Makedir(GetSetDumpPath());
|
||||
}
|
||||
|
||||
if (IsDumpDropTableSyntaxOnly()) {
|
||||
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
|
||||
|
||||
for (auto &table : tables) {
|
||||
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
|
||||
}
|
||||
|
||||
if (tables_to_dump.empty()) {
|
||||
std::cerr << "No tables were specified" << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string execution_result = Process::execute(execute_command);
|
||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||
std::cout << execution_result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tables_to_dump.empty()) {
|
||||
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
|
||||
}
|
||||
|
||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
||||
if (HasCompressionBinary()) {
|
||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsTarAvailable()) {
|
||||
Process::execute(
|
||||
fmt::format(
|
||||
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
||||
GetDumpFileNameWithPath(),
|
||||
GetSetDumpPath(),
|
||||
GetDumpFileName()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
||||
}
|
||||
else if (Is7ZipAvailable()) {
|
||||
Process::execute(
|
||||
fmt::format(
|
||||
"7z a -t7z {}.zip {}.sql",
|
||||
GetDumpFileNameWithPath(),
|
||||
GetDumpFileNameWithPath()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
||||
}
|
||||
else {
|
||||
LogInfo("Compression requested, but no available compression binary was found");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogWarning("Compression requested but binary not found... Skipping...");
|
||||
}
|
||||
}
|
||||
|
||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||
// LogDebug("[{}] query-serv", (IsDumpQueryServerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
|
||||
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
|
||||
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] bot", (IsDumpBotTables() ? "true" : "false"));
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpSystemTables() const
|
||||
{
|
||||
return dump_system_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpSystemTables(bool dump_system_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_system_tables = dump_system_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpContentTables() const
|
||||
{
|
||||
return dump_content_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpContentTables(bool dump_content_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_content_tables = dump_content_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpPlayerTables() const
|
||||
{
|
||||
return dump_player_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpPlayerTables(bool dump_player_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_player_tables = dump_player_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpLoginServerTables() const
|
||||
{
|
||||
return dump_login_server_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpLoginServerTables(bool dump_login_server_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_login_server_tables = dump_login_server_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpWithNoData() const
|
||||
{
|
||||
return dump_with_no_data;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpWithNoData(bool dump_with_no_data)
|
||||
{
|
||||
DatabaseDumpService::dump_with_no_data = dump_with_no_data;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpAllTables() const
|
||||
{
|
||||
return dump_all_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpAllTables(bool dump_all_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_all_tables = dump_all_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpTableLock() const
|
||||
{
|
||||
return dump_table_lock;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpTableLock(bool dump_table_lock)
|
||||
{
|
||||
DatabaseDumpService::dump_table_lock = dump_table_lock;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpWithCompression() const
|
||||
{
|
||||
return dump_with_compression;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpWithCompression(bool dump_with_compression)
|
||||
{
|
||||
DatabaseDumpService::dump_with_compression = dump_with_compression;
|
||||
}
|
||||
|
||||
const std::string &DatabaseDumpService::GetDumpPath() const
|
||||
{
|
||||
return dump_path;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpPath(const std::string &dump_path)
|
||||
{
|
||||
DatabaseDumpService::dump_path = dump_path;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpFileName(const std::string &dump_file_name)
|
||||
{
|
||||
DatabaseDumpService::dump_file_name = dump_file_name;
|
||||
}
|
||||
|
||||
const std::string &DatabaseDumpService::GetDumpFileName() const
|
||||
{
|
||||
return dump_file_name;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpQueryServerTables() const
|
||||
{
|
||||
return dump_query_server_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpQueryServerTables(bool dump_query_server_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_query_server_tables = dump_query_server_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpOutputToConsole() const
|
||||
{
|
||||
return dump_output_to_console;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpOutputToConsole(bool dump_output_to_console)
|
||||
{
|
||||
DatabaseDumpService::dump_output_to_console = dump_output_to_console;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpDropTableSyntaxOnly() const
|
||||
{
|
||||
return dump_drop_table_syntax_only;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only)
|
||||
{
|
||||
DatabaseDumpService::dump_drop_table_syntax_only = dump_drop_table_syntax_only;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpStateTables() const
|
||||
{
|
||||
return dump_state_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_state_tables = dump_state_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpBotTables() const
|
||||
{
|
||||
return dump_bot_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpBotTables(bool dump_bot_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_bot_tables = dump_bot_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpMercTables() const
|
||||
{
|
||||
return dump_merc_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_DATABASE_DUMP_SERVICE_H
|
||||
#define EQEMU_DATABASE_DUMP_SERVICE_H
|
||||
|
||||
|
||||
class DatabaseDumpService {
|
||||
public:
|
||||
void Dump();
|
||||
bool IsDumpAllTables() const;
|
||||
void SetDumpAllTables(bool dump_all_tables);
|
||||
bool IsDumpWithNoData() const;
|
||||
void SetDumpWithNoData(bool dump_with_no_data);
|
||||
bool IsDumpSystemTables() const;
|
||||
void SetDumpSystemTables(bool dump_system_tables);
|
||||
bool IsDumpContentTables() const;
|
||||
void SetDumpContentTables(bool dump_content_tables);
|
||||
bool IsDumpPlayerTables() const;
|
||||
void SetDumpPlayerTables(bool dump_player_tables);
|
||||
bool IsDumpLoginServerTables() const;
|
||||
void SetDumpLoginServerTables(bool dump_login_server_tables);
|
||||
bool IsDumpTableLock() const;
|
||||
void SetDumpTableLock(bool dump_table_lock);
|
||||
bool IsDumpWithCompression() const;
|
||||
void SetDumpWithCompression(bool dump_with_compression);
|
||||
const std::string &GetDumpPath() const;
|
||||
void SetDumpPath(const std::string &dump_path);
|
||||
const std::string &GetDumpFileName() const;
|
||||
void SetDumpFileName(const std::string &dump_file_name);
|
||||
bool IsDumpQueryServerTables() const;
|
||||
void SetDumpQueryServerTables(bool dump_query_server_tables);
|
||||
bool IsDumpOutputToConsole() const;
|
||||
void SetDumpOutputToConsole(bool dump_output_to_console);
|
||||
bool IsDumpDropTableSyntaxOnly() const;
|
||||
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
||||
bool IsDumpStateTables() const;
|
||||
void SetDumpStateTables(bool dump_state_tables);
|
||||
bool IsDumpBotTables() const;
|
||||
void SetDumpBotTables(bool dump_bot_tables);
|
||||
bool IsDumpMercTables() const;
|
||||
void SetDumpMercTables(bool dump_bot_tables);
|
||||
|
||||
private:
|
||||
bool dump_all_tables = false;
|
||||
bool dump_state_tables = false;
|
||||
bool dump_system_tables = false;
|
||||
bool dump_content_tables = false;
|
||||
bool dump_player_tables = false;
|
||||
bool dump_query_server_tables = false;
|
||||
bool dump_login_server_tables = false;
|
||||
bool dump_with_no_data = false;
|
||||
bool dump_table_lock = false;
|
||||
bool dump_with_compression = false;
|
||||
bool dump_output_to_console = false;
|
||||
bool dump_drop_table_syntax_only = false;
|
||||
bool dump_bot_tables = false;
|
||||
bool dump_merc_tables = false;
|
||||
std::string dump_path;
|
||||
std::string dump_file_name;
|
||||
|
||||
bool IsMySQLInstalled();
|
||||
std::string GetMySQLVersion();
|
||||
std::string GetBaseMySQLDumpCommand();
|
||||
std::string GetPlayerTablesList();
|
||||
std::string GetBotTablesList();
|
||||
std::string GetMercTablesList();
|
||||
std::string GetSystemTablesList();
|
||||
std::string GetStateTablesList();
|
||||
std::string GetContentTablesList();
|
||||
std::string GetLoginTableList();
|
||||
bool IsTarAvailable();
|
||||
bool Is7ZipAvailable();
|
||||
bool HasCompressionBinary();
|
||||
std::string GetDumpFileNameWithPath();
|
||||
std::string GetSetDumpPath();
|
||||
std::string GetQueryServTables();
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_DATABASE_DUMP_SERVICE_H
|
||||
+113
-126
@@ -18,12 +18,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/strings.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/timer.h"
|
||||
|
||||
#include "database.h"
|
||||
#include "extprofile.h"
|
||||
#include "path_manager.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
@@ -42,14 +41,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// all const/macro reference values should really be converted to a magic number for this
|
||||
// process to ensure that the struct sizes and offsets match up to the corresponding blob
|
||||
|
||||
/* Conversion Structs */
|
||||
|
||||
namespace Convert {
|
||||
struct BindStruct {
|
||||
/*000*/ uint32 zone_id;
|
||||
/*000*/ uint32 zoneId;
|
||||
/*004*/ float x;
|
||||
/*008*/ float y;
|
||||
/*012*/ float z;
|
||||
@@ -190,7 +186,7 @@ namespace Convert {
|
||||
/*002*/ uint32 HP;
|
||||
/*006*/ uint32 Mana;
|
||||
/*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT];
|
||||
/*510*/ uint32 Items[EQ::textures::materialCount];
|
||||
/*510*/ uint32 Items[EQEmu::textures::materialCount];
|
||||
/*546*/ char Name[64];
|
||||
/*610*/
|
||||
};
|
||||
@@ -218,7 +214,7 @@ namespace Convert {
|
||||
/*0245*/ uint8 guildbanker;
|
||||
/*0246*/ uint8 unknown0246[6]; //
|
||||
/*0252*/ uint32 intoxication;
|
||||
/*0256*/ uint32 spellSlotRefresh[9]; //in ms
|
||||
/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms
|
||||
/*0292*/ uint32 abilitySlotRefresh;
|
||||
/*0296*/ uint8 haircolor; // Player hair color
|
||||
/*0297*/ uint8 beardcolor; // Player beard color
|
||||
@@ -231,9 +227,9 @@ namespace Convert {
|
||||
/*0304*/ uint8 ability_time_minutes;
|
||||
/*0305*/ uint8 ability_time_hours; //place holder
|
||||
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
|
||||
/*0312*/ uint32 item_material[EQ::textures::materialCount]; // Item texture/material of worn/held items
|
||||
/*0312*/ uint32 item_material[EQEmu::textures::materialCount]; // Item texture/material of worn/held items
|
||||
/*0348*/ uint8 unknown0348[44];
|
||||
/*0392*/ Convert::Color_Struct item_tint[EQ::textures::materialCount];
|
||||
/*0392*/ Convert::Color_Struct item_tint[EQEmu::textures::materialCount];
|
||||
/*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY];
|
||||
/*2348*/ float unknown2384; //seen ~128, ~47
|
||||
/*2352*/ char servername[32]; // length probably not right
|
||||
@@ -257,9 +253,9 @@ namespace Convert {
|
||||
/*2505*/ uint8 unknown2541[47]; // ?
|
||||
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
|
||||
/*2580*/ uint8 unknown2616[4];
|
||||
/*2584*/ uint32 spell_book[480];
|
||||
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
|
||||
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
|
||||
/*4632*/ uint32 mem_spells[9];
|
||||
/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL];
|
||||
/*4668*/ uint8 unknown4704[32]; //
|
||||
/*4700*/ float y; // Player y position
|
||||
/*4704*/ float x; // Player x position
|
||||
@@ -334,7 +330,7 @@ namespace Convert {
|
||||
/*7212*/ uint32 tribute_points;
|
||||
/*7216*/ uint32 unknown7252;
|
||||
/*7220*/ uint32 tribute_active; //1=active
|
||||
/*7224*/ Convert::Tribute_Struct tributes[5];
|
||||
/*7224*/ Convert::Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE];
|
||||
/*7264*/ Convert::Disciplines_Struct disciplines;
|
||||
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
|
||||
/*7744*/ char unknown7780[160];
|
||||
@@ -476,17 +472,8 @@ bool Database::CheckDatabaseConversions() {
|
||||
CheckDatabaseConvertPPDeblob();
|
||||
CheckDatabaseConvertCorpseDeblob();
|
||||
|
||||
auto *r = RuleManager::Instance();
|
||||
r->LoadRules(this, "default", false);
|
||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
||||
r->SetRule("Bots:Enabled", "true", this, true, true);
|
||||
}
|
||||
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
|
||||
const std::string file = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
|
||||
system(fmt::format("perl {} ran_from_world", file).c_str());
|
||||
system("perl eqemu_server.pl ran_from_world");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -971,7 +958,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)"
|
||||
"VALUES (%u, '%s')",
|
||||
character_id,
|
||||
Strings::Escape(inspectmessage).c_str()
|
||||
EscapeString(inspectmessage).c_str()
|
||||
);
|
||||
auto results = QueryDatabase(rquery);
|
||||
}
|
||||
@@ -1107,95 +1094,95 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
"e_expended_aa_spent"
|
||||
")"
|
||||
"VALUES ("
|
||||
"%u," // id
|
||||
"%u," // account_id
|
||||
"'%s'," // `name`
|
||||
"'%s'," // last_name
|
||||
"%u," // gender
|
||||
"%u," // race
|
||||
"%u," // class
|
||||
"%u," // `level`
|
||||
"%u," // deity
|
||||
"%u," // birthday
|
||||
"%u," // last_login
|
||||
"%u," // time_played
|
||||
"%u," // pvp_status
|
||||
"%u," // level2
|
||||
"%u," // anon
|
||||
"%u," // gm
|
||||
"%u," // intoxication
|
||||
"%u," // hair_color
|
||||
"%u," // beard_color
|
||||
"%u," // eye_color_1
|
||||
"%u," // eye_color_2
|
||||
"%u," // hair_style
|
||||
"%u," // beard
|
||||
"%u," // ability_time_seconds
|
||||
"%u," // ability_number
|
||||
"%u," // ability_time_minutes
|
||||
"%u," // ability_time_hours
|
||||
"'%s'," // title
|
||||
"'%s'," // suffix
|
||||
"%u," // exp
|
||||
"%u," // points
|
||||
"%u," // mana
|
||||
"%u," // cur_hp
|
||||
"%u," // str
|
||||
"%u," // sta
|
||||
"%u," // cha
|
||||
"%u," // dex
|
||||
"%u," // `int`
|
||||
"%u," // agi
|
||||
"%u," // wis
|
||||
"%u," // face
|
||||
"%f," // y
|
||||
"%f," // x
|
||||
"%f," // z
|
||||
"%f," // heading
|
||||
"%u," // pvp2
|
||||
"%u," // pvp_type
|
||||
"%u," // autosplit_enabled
|
||||
"%u," // zone_change_count
|
||||
"%u," // drakkin_heritage
|
||||
"%u," // drakkin_tattoo
|
||||
"%u," // drakkin_details
|
||||
"%i," // toxicity
|
||||
"%u," // hunger_level
|
||||
"%u," // thirst_level
|
||||
"%u," // ability_up
|
||||
"%u," // zone_id
|
||||
"%u," // zone_instance
|
||||
"%u," // leadership_exp_on
|
||||
"%u," // ldon_points_guk
|
||||
"%u," // ldon_points_mir
|
||||
"%u," // ldon_points_mmc
|
||||
"%u," // ldon_points_ruj
|
||||
"%u," // ldon_points_tak
|
||||
"%u," // ldon_points_available
|
||||
"%u," // tribute_time_remaining
|
||||
"%u," // show_helm
|
||||
"%u," // career_tribute_points
|
||||
"%u," // tribute_points
|
||||
"%u," // tribute_active
|
||||
"%u," // endurance
|
||||
"%u," // group_leadership_exp
|
||||
"%u," // raid_leadership_exp
|
||||
"%u," // group_leadership_points
|
||||
"%u," // raid_leadership_points
|
||||
"%u," // air_remaining
|
||||
"%u," // pvp_kills
|
||||
"%u," // pvp_deaths
|
||||
"%u," // pvp_current_points
|
||||
"%u," // pvp_career_points
|
||||
"%u," // pvp_best_kill_streak
|
||||
"%u," // pvp_worst_death_streak
|
||||
"%u," // pvp_current_kill_streak
|
||||
"%u," // aa_points_spent
|
||||
"%u," // aa_exp
|
||||
"%u," // aa_points
|
||||
"%u," // group_auto_consent
|
||||
"%u," // raid_auto_consent
|
||||
"%u," // guild_auto_consent
|
||||
"%u," // id
|
||||
"%u," // account_id
|
||||
"'%s'," // `name`
|
||||
"'%s'," // last_name
|
||||
"%u," // gender
|
||||
"%u," // race
|
||||
"%u," // class
|
||||
"%u," // `level`
|
||||
"%u," // deity
|
||||
"%u," // birthday
|
||||
"%u," // last_login
|
||||
"%u," // time_played
|
||||
"%u," // pvp_status
|
||||
"%u," // level2
|
||||
"%u," // anon
|
||||
"%u," // gm
|
||||
"%u," // intoxication
|
||||
"%u," // hair_color
|
||||
"%u," // beard_color
|
||||
"%u," // eye_color_1
|
||||
"%u," // eye_color_2
|
||||
"%u," // hair_style
|
||||
"%u," // beard
|
||||
"%u," // ability_time_seconds
|
||||
"%u," // ability_number
|
||||
"%u," // ability_time_minutes
|
||||
"%u," // ability_time_hours
|
||||
"'%s'," // title
|
||||
"'%s'," // suffix
|
||||
"%u," // exp
|
||||
"%u," // points
|
||||
"%u," // mana
|
||||
"%u," // cur_hp
|
||||
"%u," // str
|
||||
"%u," // sta
|
||||
"%u," // cha
|
||||
"%u," // dex
|
||||
"%u," // `int`
|
||||
"%u," // agi
|
||||
"%u," // wis
|
||||
"%u," // face
|
||||
"%f," // y
|
||||
"%f," // x
|
||||
"%f," // z
|
||||
"%f," // heading
|
||||
"%u," // pvp2
|
||||
"%u," // pvp_type
|
||||
"%u," // autosplit_enabled
|
||||
"%u," // zone_change_count
|
||||
"%u," // drakkin_heritage
|
||||
"%u," // drakkin_tattoo
|
||||
"%u," // drakkin_details
|
||||
"%i," // toxicity
|
||||
"%u," // hunger_level
|
||||
"%u," // thirst_level
|
||||
"%u," // ability_up
|
||||
"%u," // zone_id
|
||||
"%u," // zone_instance
|
||||
"%u," // leadership_exp_on
|
||||
"%u," // ldon_points_guk
|
||||
"%u," // ldon_points_mir
|
||||
"%u," // ldon_points_mmc
|
||||
"%u," // ldon_points_ruj
|
||||
"%u," // ldon_points_tak
|
||||
"%u," // ldon_points_available
|
||||
"%u," // tribute_time_remaining
|
||||
"%u," // show_helm
|
||||
"%u," // career_tribute_points
|
||||
"%u," // tribute_points
|
||||
"%u," // tribute_active
|
||||
"%u," // endurance
|
||||
"%u," // group_leadership_exp
|
||||
"%u," // raid_leadership_exp
|
||||
"%u," // group_leadership_points
|
||||
"%u," // raid_leadership_points
|
||||
"%u," // air_remaining
|
||||
"%u," // pvp_kills
|
||||
"%u," // pvp_deaths
|
||||
"%u," // pvp_current_points
|
||||
"%u," // pvp_career_points
|
||||
"%u," // pvp_best_kill_streak
|
||||
"%u," // pvp_worst_death_streak
|
||||
"%u," // pvp_current_kill_streak
|
||||
"%u," // aa_points_spent
|
||||
"%u," // aa_exp
|
||||
"%u," // aa_points
|
||||
"%u," // group_auto_consent
|
||||
"%u," // raid_auto_consent
|
||||
"%u," // guild_auto_consent
|
||||
"%u," // RestTimer
|
||||
"%u," // First Logon - References online status for EVENT_CONNECT/EVENT_DISCONNECt
|
||||
"%u," // Looking for Group
|
||||
@@ -1208,8 +1195,8 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
")",
|
||||
character_id,
|
||||
account_id,
|
||||
Strings::Escape(pp->name).c_str(),
|
||||
Strings::Escape(pp->last_name).c_str(),
|
||||
EscapeString(pp->name).c_str(),
|
||||
EscapeString(pp->last_name).c_str(),
|
||||
pp->gender,
|
||||
pp->race,
|
||||
pp->class_,
|
||||
@@ -1233,8 +1220,8 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
pp->ability_number,
|
||||
pp->ability_time_minutes,
|
||||
pp->ability_time_hours,
|
||||
Strings::Escape(pp->title).c_str(),
|
||||
Strings::Escape(pp->suffix).c_str(),
|
||||
EscapeString(pp->title).c_str(),
|
||||
EscapeString(pp->suffix).c_str(),
|
||||
pp->exp,
|
||||
pp->points,
|
||||
pp->mana,
|
||||
@@ -1330,18 +1317,18 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
|
||||
/* Run Bind Home Convert */
|
||||
if (pp->binds[4].zone_id < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) {
|
||||
if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) {
|
||||
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, 1)",
|
||||
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading);
|
||||
character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading);
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
}
|
||||
|
||||
/* Run Bind Convert */
|
||||
if (pp->binds[0].zone_id < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) {
|
||||
if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) {
|
||||
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, 0)",
|
||||
character_id, pp->binds[0].zone_id, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading);
|
||||
character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading);
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
}
|
||||
/* Run Language Convert */
|
||||
@@ -1370,7 +1357,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Spell Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = 0; i < 480; i++){
|
||||
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){
|
||||
if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]);
|
||||
@@ -1382,7 +1369,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Max Memmed Spell Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = 0; i < 9; i++){
|
||||
for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){
|
||||
if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]);
|
||||
@@ -1406,7 +1393,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Material Color Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = EQ::textures::textureBegin; i < EQ::textures::materialCount; i++){
|
||||
for (i = EQEmu::textures::textureBegin; i < EQEmu::textures::materialCount; i++){
|
||||
if (pp->item_tint[i].color > 0){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color);
|
||||
@@ -1418,7 +1405,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
/* Run Tribute Convert */
|
||||
first_entry = 0; rquery = "";
|
||||
for (i = 0; i < 5; i++){
|
||||
for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++){
|
||||
if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
|
||||
@@ -1462,7 +1449,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){
|
||||
if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){
|
||||
if (first_entry != 1){
|
||||
rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
||||
rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
||||
first_entry = 1;
|
||||
}
|
||||
rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
||||
|
||||
+341
-317
@@ -18,18 +18,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/strings.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/repositories/character_corpses_repository.h"
|
||||
#include "../common/repositories/dynamic_zone_members_repository.h"
|
||||
#include "../common/repositories/dynamic_zones_repository.h"
|
||||
#include "../common/repositories/group_id_repository.h"
|
||||
#include "../common/repositories/instance_list_repository.h"
|
||||
#include "../common/repositories/instance_list_player_repository.h"
|
||||
#include "../common/repositories/raid_members_repository.h"
|
||||
#include "../common/repositories/respawn_times_repository.h"
|
||||
#include "../common/repositories/spawn_condition_values_repository.h"
|
||||
|
||||
|
||||
#include "database.h"
|
||||
|
||||
@@ -44,213 +34,219 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include "unix.h"
|
||||
#include "../zone/zonedb.h"
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id)
|
||||
{
|
||||
auto e = InstanceListPlayerRepository::NewEntity();
|
||||
|
||||
e.id = instance_id;
|
||||
e.charid = character_id;
|
||||
|
||||
return InstanceListPlayerRepository::ReplaceOne(*this, e);
|
||||
std::string query = StringFormat(
|
||||
"REPLACE INTO `instance_list_player` (id, charid) "
|
||||
"VALUES "
|
||||
"(%lu, %lu)",
|
||||
(unsigned long)instance_id,
|
||||
(unsigned long)char_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
return results.Success();
|
||||
}
|
||||
|
||||
bool Database::CheckInstanceByCharID(uint16 instance_id, uint32 character_id)
|
||||
bool Database::CharacterInInstanceGroup(uint16 instance_id, uint32 char_id)
|
||||
{
|
||||
if (!instance_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto l = InstanceListPlayerRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"id = {} AND charid = {}",
|
||||
instance_id,
|
||||
character_id
|
||||
)
|
||||
);
|
||||
if (l.empty()) {
|
||||
std::string query = StringFormat("SELECT charid FROM instance_list_player where id=%u AND charid=%u", instance_id, char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
if (results.RowCount() != 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::CheckInstanceExists(uint16 instance_id)
|
||||
{
|
||||
if (!instance_id) {
|
||||
return false;
|
||||
}
|
||||
bool Database::CheckInstanceExists(uint16 instance_id) {
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"`id` "
|
||||
"FROM "
|
||||
"`instance_list` "
|
||||
"WHERE "
|
||||
"`id` = %u",
|
||||
instance_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::CheckInstanceExpired(uint16 instance_id)
|
||||
{
|
||||
if (!instance_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
return true;
|
||||
}
|
||||
int32 start_time = 0;
|
||||
int32 duration = 0;
|
||||
uint32 never_expires = 0;
|
||||
|
||||
if (i.never_expires) {
|
||||
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return true;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return true;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
start_time = atoi(row[0]);
|
||||
duration = atoi(row[1]);
|
||||
never_expires = atoi(row[2]);
|
||||
|
||||
if (never_expires == 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
timeval tv{};
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
|
||||
return (i.start_time + i.duration) <= tv.tv_sec;
|
||||
if ((start_time + duration) <= tv.tv_sec)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
||||
{
|
||||
auto e = InstanceListRepository::NewEntity();
|
||||
std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||
" values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)",
|
||||
(unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
e.id = instance_id;
|
||||
e.zone = zone_id;
|
||||
e.version = version;
|
||||
e.start_time = std::time(nullptr);
|
||||
e.duration = duration;
|
||||
|
||||
return InstanceListRepository::InsertOne(*this, e).id;
|
||||
return results.Success();
|
||||
}
|
||||
|
||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
{
|
||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||
uint32 max = 32000;
|
||||
|
||||
auto query = fmt::format(
|
||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||
max_reserved_instance_id,
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
query = (
|
||||
SQL(
|
||||
SELECT i.id + 1 AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
||||
WHERE i2.id IS NULL
|
||||
ORDER BY i.id
|
||||
LIMIT 0, 1;
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
uint32 count = RuleI(Zone, ReservedInstances);
|
||||
uint32 max = 65535;
|
||||
|
||||
std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
if (!results.Success())
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (atoi(row[0]) <= max) {
|
||||
if (atoi(row[0]) <= max)
|
||||
{
|
||||
instance_id = atoi(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (instance_id < max_reserved_instance_id) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
||||
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
if (!results.Success())
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
|
||||
for (auto row : results) {
|
||||
if (max_reserved_instance_id < std::stoul(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
count++;
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
if (count < atoi(row[0]))
|
||||
{
|
||||
instance_id = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (max_reserved_instance_id > max) {
|
||||
if (count > max)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
count++;
|
||||
}
|
||||
|
||||
instance_id = max_reserved_instance_id;
|
||||
|
||||
instance_id = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
||||
bool Database::GlobalInstance(uint16 instance_id)
|
||||
{
|
||||
if (!instance_id) {
|
||||
return false;
|
||||
}
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"is_global "
|
||||
"FROM "
|
||||
"instance_list "
|
||||
"WHERE "
|
||||
"id = %u "
|
||||
"LIMIT 1 ",
|
||||
instance_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
if (!results.Success())
|
||||
return false;
|
||||
}
|
||||
|
||||
return i.is_global;
|
||||
if (results.RowCount() == 0)
|
||||
return false;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return (atoi(row[0]) == 1) ? true : false;
|
||||
}
|
||||
|
||||
bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id)
|
||||
{
|
||||
return InstanceListPlayerRepository::DeleteWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"id = {} AND charid = {}",
|
||||
instance_id,
|
||||
char_id
|
||||
)
|
||||
);
|
||||
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu",
|
||||
(unsigned long)instance_id, (unsigned long)char_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return results.Success();
|
||||
}
|
||||
|
||||
|
||||
bool Database::RemoveClientsFromInstance(uint16 instance_id)
|
||||
{
|
||||
return InstanceListPlayerRepository::DeleteOne(*this, instance_id);
|
||||
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu", (unsigned long)instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return results.Success();
|
||||
}
|
||||
|
||||
bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
|
||||
bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 char_id)
|
||||
{
|
||||
//we are not saved to this instance so set our instance to 0
|
||||
if (!IsGlobalInstance(instance_id) && !CheckInstanceByCharID(instance_id, character_id)) {
|
||||
if (!GlobalInstance(instance_id) && !CharacterInInstanceGroup(instance_id, char_id))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CheckInstanceExpired(instance_id)) {
|
||||
if (CheckInstanceExpired(instance_id))
|
||||
{
|
||||
DeleteInstance(instance_id);
|
||||
return false;
|
||||
}
|
||||
@@ -260,102 +256,129 @@ bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
|
||||
|
||||
bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id)
|
||||
{
|
||||
auto l = InstanceListRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"id = {} AND zone = {}",
|
||||
instance_id,
|
||||
zone_id
|
||||
)
|
||||
);
|
||||
if (l.empty()) {
|
||||
|
||||
std::string query = StringFormat("SELECT id FROM instance_list where id=%u AND zone=%u", instance_id, zone_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 version)
|
||||
uint16 Database::GetInstanceID(const char* zone, uint32 character_id, int16 version) {
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"instance_list.id "
|
||||
"FROM "
|
||||
"instance_list, "
|
||||
"instance_list_player "
|
||||
"WHERE "
|
||||
"instance_list.zone = %u "
|
||||
"AND instance_list.version = %u "
|
||||
"AND instance_list.id = instance_list_player.id "
|
||||
"AND instance_list_player.charid = %u "
|
||||
"LIMIT 1 ",
|
||||
GetZoneID(zone),
|
||||
version,
|
||||
character_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
uint16 Database::GetInstanceID(uint32 zone, uint32 character_id, int16 version)
|
||||
{
|
||||
if (!zone_id) {
|
||||
if (!zone)
|
||||
return 0;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT "
|
||||
"instance_list.id "
|
||||
"FROM "
|
||||
"instance_list, "
|
||||
"instance_list_player "
|
||||
"WHERE "
|
||||
"instance_list.zone = %u "
|
||||
"AND instance_list.version = %u "
|
||||
"AND instance_list.id = instance_list_player.id "
|
||||
"AND instance_list_player.charid = %u "
|
||||
"LIMIT 1; ",
|
||||
zone,
|
||||
version,
|
||||
character_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
uint16 Database::GetInstanceVersion(uint16 instance_id) {
|
||||
if (instance_id == 0)
|
||||
return 0;
|
||||
|
||||
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
||||
{
|
||||
uint32 start_time = 0;
|
||||
uint32 duration = 0;
|
||||
uint32 never_expires = 0;
|
||||
|
||||
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
is_perma = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto query = fmt::format(
|
||||
"SELECT instance_list.id FROM "
|
||||
"instance_list, instance_list_player WHERE "
|
||||
"instance_list.zone = {} AND "
|
||||
"instance_list.version = {} AND "
|
||||
"instance_list.id = instance_list_player.id AND "
|
||||
"instance_list_player.charid = {} "
|
||||
"LIMIT 1;",
|
||||
zone_id,
|
||||
version,
|
||||
character_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
is_perma = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return static_cast<uint16>(std::stoul(row[0]));
|
||||
}
|
||||
start_time = atoi(row[0]);
|
||||
duration = atoi(row[1]);
|
||||
never_expires = atoi(row[2]);
|
||||
|
||||
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
|
||||
{
|
||||
std::vector<uint16> l;
|
||||
|
||||
if (!zone_id) {
|
||||
return l;
|
||||
}
|
||||
|
||||
const auto query = fmt::format(
|
||||
"SELECT instance_list.id FROM "
|
||||
"instance_list, instance_list_player WHERE "
|
||||
"instance_list.zone = {} AND "
|
||||
"instance_list.id = instance_list_player.id AND "
|
||||
"instance_list_player.charid = {}",
|
||||
zone_id,
|
||||
character_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return l;
|
||||
}
|
||||
|
||||
for (auto row : results) {
|
||||
l.push_back(static_cast<uint16>(std::stoul(row[0])));
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
uint8_t Database::GetInstanceVersion(uint16 instance_id) {
|
||||
if (!instance_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return i.version;
|
||||
}
|
||||
|
||||
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
||||
{
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
is_perma = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (i.never_expires) {
|
||||
if (never_expires == 1)
|
||||
{
|
||||
is_perma = true;
|
||||
return 0;
|
||||
}
|
||||
@@ -364,175 +387,176 @@ uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
||||
|
||||
timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return ((i.start_time + i.duration) - tv.tv_sec);
|
||||
return ((start_time + duration) - tv.tv_sec);
|
||||
}
|
||||
|
||||
uint32 Database::GetInstanceZoneID(uint16 instance_id)
|
||||
uint32 Database::VersionFromInstanceID(uint16 instance_id)
|
||||
{
|
||||
if (!instance_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
return 0;
|
||||
}
|
||||
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return i.zone;
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
uint32 Database::ZoneIDFromInstanceID(uint16 instance_id)
|
||||
{
|
||||
|
||||
std::string query = StringFormat("SELECT zone FROM instance_list where id=%u", instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return 0;
|
||||
|
||||
if (results.RowCount() == 0)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
}
|
||||
|
||||
void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
||||
{
|
||||
auto zone_id = GetInstanceZoneID(instance_id);
|
||||
auto version = GetInstanceVersion(instance_id);
|
||||
|
||||
auto l = GroupIdRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"groupid = {}",
|
||||
group_id
|
||||
)
|
||||
);
|
||||
if (l.empty()) {
|
||||
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
|
||||
uint16 version = VersionFromInstanceID(instance_id);
|
||||
|
||||
std::string query = StringFormat("SELECT `charid` FROM `group_id` WHERE `groupid` = %u", group_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
||||
AddClientToInstance(instance_id, e.charid);
|
||||
}
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
uint32 charid = atoi(row[0]);
|
||||
if (GetInstanceID(zone_id, charid, version) == 0)
|
||||
AddClientToInstance(instance_id, charid);
|
||||
}
|
||||
}
|
||||
|
||||
void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
||||
{
|
||||
auto zone_id = GetInstanceZoneID(instance_id);
|
||||
auto version = GetInstanceVersion(instance_id);
|
||||
|
||||
auto l = RaidMembersRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"raidid = {}",
|
||||
raid_id
|
||||
)
|
||||
);
|
||||
if (l.empty()) {
|
||||
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
|
||||
uint16 version = VersionFromInstanceID(instance_id);
|
||||
|
||||
std::string query = StringFormat("SELECT `charid` FROM `raid_members` WHERE `raidid` = %u", raid_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
||||
AddClientToInstance(instance_id, e.charid);
|
||||
}
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
uint32 charid = atoi(row[0]);
|
||||
if (GetInstanceID(zone_id, charid, version) == 0)
|
||||
AddClientToInstance(instance_id, charid);
|
||||
}
|
||||
}
|
||||
|
||||
void Database::BuryCorpsesInInstance(uint16 instance_id) {
|
||||
std::string query = StringFormat(
|
||||
"UPDATE `character_corpses` "
|
||||
"SET `is_buried` = 1, "
|
||||
"`instance_id` = 0 "
|
||||
"WHERE "
|
||||
"`instance_id` = %u ",
|
||||
instance_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
}
|
||||
|
||||
void Database::DeleteInstance(uint16 instance_id)
|
||||
{
|
||||
std::string query;
|
||||
|
||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
||||
std::string query = StringFormat("DELETE FROM instance_list WHERE id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
query = StringFormat("DELETE FROM respawn_times WHERE instance_id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
|
||||
BuryCorpsesInInstance(instance_id);
|
||||
}
|
||||
|
||||
void Database::FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id)
|
||||
void Database::FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid)
|
||||
{
|
||||
auto instance_id = GetInstanceID(zone_id, character_id, version);
|
||||
if (instance_id) {
|
||||
uint16 id = GetInstanceID(zone, charid, version);
|
||||
if (id != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
char ln[128];
|
||||
memset(ln, 0, 128);
|
||||
GetGroupLeadershipInfo(group_id, ln);
|
||||
strcpy(ln, GetGroupLeadershipInfo(gid, ln));
|
||||
uint32 l_charid = GetCharacterID((const char*)ln);
|
||||
uint16 l_id = GetInstanceID(zone, l_charid, version);
|
||||
|
||||
auto group_leader_id = GetCharacterID((const char*)ln);
|
||||
auto group_leader_instance_id = GetInstanceID(zone_id, group_leader_id, version);
|
||||
|
||||
if (!group_leader_instance_id) {
|
||||
if (l_id == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
AddClientToInstance(group_leader_instance_id, character_id);
|
||||
AddClientToInstance(l_id, charid);
|
||||
}
|
||||
|
||||
void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id)
|
||||
void Database::FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid)
|
||||
{
|
||||
uint16 instance_id = GetInstanceID(zone_id, character_id, version);
|
||||
if (instance_id) {
|
||||
uint16 id = GetInstanceID(zone, charid, version);
|
||||
if (id != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
||||
uint32 l_charid = GetCharacterID(GetRaidLeaderName(rid));
|
||||
uint16 l_id = GetInstanceID(zone, l_charid, version);
|
||||
|
||||
if (!raid_leader_instance_id) {
|
||||
if (l_id == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
AddClientToInstance(raid_leader_instance_id, character_id);
|
||||
AddClientToInstance(l_id, charid);
|
||||
}
|
||||
|
||||
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids)
|
||||
{
|
||||
auto l = InstanceListPlayerRepository::GetWhere(*this, fmt::format("id = {}", instance_id));
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list) {
|
||||
|
||||
for (const auto& e : l) {
|
||||
character_ids.push_back(e.charid);
|
||||
}
|
||||
std::string query = StringFormat("SELECT `charid` FROM `instance_list_player` WHERE `id` = %u", instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
charid_list.push_back(atoi(row[0]));
|
||||
}
|
||||
|
||||
void Database::PurgeExpiredInstances()
|
||||
{
|
||||
/**
|
||||
* Delay purging by a day so that we can continue using adjacent free instance id's
|
||||
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
||||
* has not been fully de-allocated
|
||||
*/
|
||||
auto l = InstanceListRepository::GetWhere(
|
||||
*this,
|
||||
"(start_time + duration) <= (UNIX_TIMESTAMP() - 86400) AND never_expires = 0"
|
||||
);
|
||||
if (l.empty()) {
|
||||
std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0");
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> instance_ids;
|
||||
for (const auto& e : l) {
|
||||
instance_ids.emplace_back(std::to_string(e.id));
|
||||
}
|
||||
if (results.RowCount() == 0)
|
||||
return;
|
||||
|
||||
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
|
||||
|
||||
InstanceListRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
DeleteInstance(atoi(row[0]));
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
{
|
||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
||||
if (!i.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
i.start_time = std::time(nullptr);
|
||||
i.duration = new_duration;
|
||||
|
||||
InstanceListRepository::UpdateOne(*this, i);
|
||||
}
|
||||
std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), "
|
||||
"duration=%u WHERE id=%u", new_duration, instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
}
|
||||
@@ -1,438 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_DATABASE_SCHEMA_H
|
||||
#define EQEMU_DATABASE_SCHEMA_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace DatabaseSchema {
|
||||
|
||||
/**
|
||||
* Character-specific tables
|
||||
*
|
||||
* Does not included related meta-data tables such as 'guilds', 'accounts'
|
||||
* @return
|
||||
*/
|
||||
static std::map<std::string, std::string> GetCharacterTables()
|
||||
{
|
||||
return {
|
||||
{"adventure_stats", "player_id"},
|
||||
{"buyer", "charid"},
|
||||
{"char_recipe_list", "char_id"},
|
||||
{"character_activities", "charid"},
|
||||
{"character_alt_currency", "char_id"},
|
||||
{"character_alternate_abilities", "id"},
|
||||
{"character_auras", "id"},
|
||||
{"character_bandolier", "id"},
|
||||
{"character_bind", "id"},
|
||||
{"character_buffs", "character_id"},
|
||||
{"character_corpses", "id"},
|
||||
{"character_currency", "id"},
|
||||
{"character_data", "id"},
|
||||
{"character_disciplines", "id"},
|
||||
{"character_enabledtasks", "charid"},
|
||||
{"character_expedition_lockouts", "character_id"},
|
||||
{"character_exp_modifiers", "character_id"},
|
||||
{"character_inspect_messages", "id"},
|
||||
{"character_instance_safereturns", "character_id"},
|
||||
{"character_item_recast", "id"},
|
||||
{"character_languages", "id"},
|
||||
{"character_leadership_abilities", "id"},
|
||||
{"character_material", "id"},
|
||||
{"character_memmed_spells", "id"},
|
||||
{"character_pet_buffs", "char_id"},
|
||||
{"character_pet_info", "char_id"},
|
||||
{"character_pet_inventory", "char_id"},
|
||||
{"character_peqzone_flags", "id"},
|
||||
{"character_potionbelt", "id"},
|
||||
{"character_skills", "id"},
|
||||
{"character_spells", "id"},
|
||||
{"character_task_timers", "character_id"},
|
||||
{"character_tasks", "charid"},
|
||||
{"character_tribute", "id"},
|
||||
{"completed_tasks", "charid"},
|
||||
{"data_buckets", "id"},
|
||||
{"faction_values", "char_id"},
|
||||
{"friends", "charid"},
|
||||
{"guild_members", "char_id"},
|
||||
{"guilds", "id"},
|
||||
{"instance_list_player", "id"},
|
||||
{"inventory", "charid"},
|
||||
{"inventory_snapshots", "charid"},
|
||||
{"keyring", "char_id"},
|
||||
{"mail", "charid"},
|
||||
{"player_titlesets", "char_id"},
|
||||
{"quest_globals", "charid"},
|
||||
{"timers", "char_id"},
|
||||
{"trader", "char_id"},
|
||||
{"zone_flags", "charID"}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Gets all player and meta-data tables
|
||||
* @note These tables have no content in the PEQ daily dump
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetPlayerTables()
|
||||
{
|
||||
return {
|
||||
"account",
|
||||
"account_ip",
|
||||
"account_flags",
|
||||
"account_rewards",
|
||||
"adventure_details",
|
||||
"adventure_stats",
|
||||
"buyer",
|
||||
"char_recipe_list",
|
||||
"character_activities",
|
||||
"character_alt_currency",
|
||||
"character_alternate_abilities",
|
||||
"character_auras",
|
||||
"character_bandolier",
|
||||
"character_bind",
|
||||
"character_buffs",
|
||||
"character_corpse_items",
|
||||
"character_corpses",
|
||||
"character_currency",
|
||||
"character_data",
|
||||
"character_disciplines",
|
||||
"character_enabledtasks",
|
||||
"character_expedition_lockouts",
|
||||
"character_exp_modifiers",
|
||||
"character_inspect_messages",
|
||||
"character_instance_safereturns",
|
||||
"character_item_recast",
|
||||
"character_languages",
|
||||
"character_leadership_abilities",
|
||||
"character_material",
|
||||
"character_memmed_spells",
|
||||
"character_pet_buffs",
|
||||
"character_pet_info",
|
||||
"character_pet_inventory",
|
||||
"character_peqzone_flags",
|
||||
"character_potionbelt",
|
||||
"character_skills",
|
||||
"character_spells",
|
||||
"character_task_timers",
|
||||
"character_tasks",
|
||||
"character_tribute",
|
||||
"completed_tasks",
|
||||
"data_buckets",
|
||||
"discovered_items",
|
||||
"faction_values",
|
||||
"friends",
|
||||
"guild_bank",
|
||||
"guild_members",
|
||||
"guild_ranks",
|
||||
"guild_relations",
|
||||
"guilds",
|
||||
"instance_list_player",
|
||||
"inventory",
|
||||
"inventory_snapshots",
|
||||
"keyring",
|
||||
"mail",
|
||||
"petitions",
|
||||
"player_titlesets",
|
||||
"quest_globals",
|
||||
"sharedbank",
|
||||
"spell_buckets",
|
||||
"spell_globals",
|
||||
"timers",
|
||||
"trader",
|
||||
"trader_audit",
|
||||
"zone_flags"
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets content tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetContentTables()
|
||||
{
|
||||
return {
|
||||
"aa_ability",
|
||||
"aa_rank_effects",
|
||||
"aa_rank_prereqs",
|
||||
"aa_ranks",
|
||||
"adventure_template",
|
||||
"adventure_template_entry",
|
||||
"adventure_template_entry_flavor",
|
||||
"alternate_currency",
|
||||
"auras",
|
||||
"base_data",
|
||||
"blocked_spells",
|
||||
"books",
|
||||
"char_create_combinations",
|
||||
"char_create_point_allocations",
|
||||
"damageshieldtypes",
|
||||
"doors",
|
||||
"dynamic_zone_templates",
|
||||
"faction_association",
|
||||
"faction_base_data",
|
||||
"faction_list",
|
||||
"faction_list_mod",
|
||||
"fishing",
|
||||
"forage",
|
||||
"global_loot",
|
||||
"graveyard",
|
||||
"grid",
|
||||
"grid_entries",
|
||||
"ground_spawns",
|
||||
"horses",
|
||||
"items",
|
||||
"ldon_trap_entries",
|
||||
"ldon_trap_templates",
|
||||
"lootdrop",
|
||||
"lootdrop_entries",
|
||||
"loottable",
|
||||
"loottable_entries",
|
||||
"merchantlist",
|
||||
"npc_emotes",
|
||||
"npc_faction",
|
||||
"npc_faction_entries",
|
||||
"npc_scale_global_base",
|
||||
"npc_spells",
|
||||
"npc_spells_effects",
|
||||
"npc_spells_effects_entries",
|
||||
"npc_spells_entries",
|
||||
"npc_types",
|
||||
"npc_types_tint",
|
||||
"object",
|
||||
"pets",
|
||||
"pets_beastlord_data",
|
||||
"pets_equipmentset",
|
||||
"pets_equipmentset_entries",
|
||||
"skill_caps",
|
||||
"spawn2",
|
||||
"spawn_conditions",
|
||||
"spawnentry",
|
||||
"spawngroup",
|
||||
"spells_new",
|
||||
"start_zones",
|
||||
"starting_items",
|
||||
"task_activities",
|
||||
"tasks",
|
||||
"tasksets",
|
||||
"tradeskill_recipe",
|
||||
"tradeskill_recipe_entries",
|
||||
"traps",
|
||||
"tribute_levels",
|
||||
"tributes",
|
||||
"veteran_reward_templates",
|
||||
"zone",
|
||||
"zone_points",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetServerTables()
|
||||
{
|
||||
return {
|
||||
"chatchannels",
|
||||
"command_settings",
|
||||
"content_flags",
|
||||
"db_str",
|
||||
"eqtime",
|
||||
"launcher",
|
||||
"launcher_zones",
|
||||
"spawn_condition_values",
|
||||
"spawn_events",
|
||||
"level_exp_mods",
|
||||
"logsys_categories",
|
||||
"name_filter",
|
||||
"perl_event_export_settings",
|
||||
"profanity_list",
|
||||
"rule_sets",
|
||||
"titles",
|
||||
"rule_values",
|
||||
"variables",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets QueryServer tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetQueryServerTables()
|
||||
{
|
||||
return {
|
||||
"qs_merchant_transaction_record",
|
||||
"qs_merchant_transaction_record_entries",
|
||||
"qs_player_aa_rate_hourly",
|
||||
"qs_player_delete_record",
|
||||
"qs_player_delete_record_entries",
|
||||
"qs_player_events",
|
||||
"qs_player_handin_record",
|
||||
"qs_player_handin_record_entries",
|
||||
"qs_player_move_record",
|
||||
"qs_player_move_record_entries",
|
||||
"qs_player_npc_kill_record",
|
||||
"qs_player_npc_kill_record_entries",
|
||||
"qs_player_speech",
|
||||
"qs_player_trade_record",
|
||||
"qs_player_trade_record_entries",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets state tables
|
||||
* Tables that keep track of server state
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetStateTables()
|
||||
{
|
||||
return {
|
||||
"adventure_members",
|
||||
"banned_ips",
|
||||
"bug_reports",
|
||||
"bugs",
|
||||
"completed_shared_task_activity_state",
|
||||
"completed_shared_task_members",
|
||||
"completed_shared_tasks",
|
||||
"discord_webhooks",
|
||||
"dynamic_zone_members",
|
||||
"dynamic_zones",
|
||||
"expedition_lockouts",
|
||||
"expeditions",
|
||||
"gm_ips",
|
||||
"group_id",
|
||||
"group_leaders",
|
||||
"instance_list",
|
||||
"ip_exemptions",
|
||||
"item_tick",
|
||||
"lfguild",
|
||||
"merc_buffs",
|
||||
"merchantlist_temp",
|
||||
"mercs",
|
||||
"object_contents",
|
||||
"raid_details",
|
||||
"raid_leaders",
|
||||
"raid_members",
|
||||
"reports",
|
||||
"respawn_times",
|
||||
"saylink",
|
||||
"server_scheduled_events",
|
||||
"player_event_log_settings",
|
||||
"player_event_logs",
|
||||
"shared_task_activity_state",
|
||||
"shared_task_dynamic_zones",
|
||||
"shared_task_members",
|
||||
"shared_tasks",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets login tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetLoginTables()
|
||||
{
|
||||
return {
|
||||
"login_accounts",
|
||||
"login_api_tokens",
|
||||
"login_server_admins",
|
||||
"login_server_list_types",
|
||||
"login_world_servers",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets login tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetVersionTables()
|
||||
{
|
||||
return {
|
||||
"db_version",
|
||||
"inventory_versions",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Gets all player bot tables
|
||||
* @note These tables have no content in the PEQ daily dump
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetBotTables()
|
||||
{
|
||||
return {
|
||||
"bot_buffs",
|
||||
"bot_command_settings",
|
||||
"bot_create_combinations",
|
||||
"bot_data",
|
||||
"bot_group_members",
|
||||
"bot_groups",
|
||||
"bot_guild_members",
|
||||
"bot_heal_rotation_members",
|
||||
"bot_heal_rotation_targets",
|
||||
"bot_heal_rotations",
|
||||
"bot_inspect_messages",
|
||||
"bot_inventories",
|
||||
"bot_owner_options",
|
||||
"bot_pet_buffs",
|
||||
"bot_pet_inventories",
|
||||
"bot_pets",
|
||||
"bot_spell_casting_chances",
|
||||
"bot_spell_settings",
|
||||
"bot_spells_entries",
|
||||
"bot_stances",
|
||||
"bot_timers"
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> GetMercTables()
|
||||
{
|
||||
return {
|
||||
"merc_armorinfo",
|
||||
"merc_inventory",
|
||||
"merc_merchant_entries",
|
||||
"merc_merchant_template_entries",
|
||||
"merc_merchant_templates",
|
||||
"merc_name_types",
|
||||
"merc_npc_types",
|
||||
"merc_spell_list_entries",
|
||||
"merc_spell_lists",
|
||||
"merc_stance_entries",
|
||||
"merc_stats",
|
||||
"merc_subtypes",
|
||||
"merc_templates",
|
||||
"merc_types",
|
||||
"merc_weaponinfo"
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //EQEMU_DATABASE_SCHEMA_H
|
||||
+75
-159
@@ -2,9 +2,8 @@
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "misc_functions.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "timer.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
|
||||
#include "dbcore.h"
|
||||
|
||||
@@ -15,51 +14,33 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#include <process.h>
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#include <process.h>
|
||||
#else
|
||||
|
||||
#include "unix.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include "unix.h"
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef _EQDEBUG
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#else
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#define DEBUG_MYSQL_QUERIES 0
|
||||
#endif
|
||||
|
||||
DBcore::DBcore()
|
||||
{
|
||||
DBcore::DBcore() {
|
||||
mysql_init(&mysql);
|
||||
pHost = nullptr;
|
||||
pUser = nullptr;
|
||||
pPassword = nullptr;
|
||||
pDatabase = nullptr;
|
||||
pCompress = false;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
pHost = 0;
|
||||
pUser = 0;
|
||||
pPassword = 0;
|
||||
pDatabase = 0;
|
||||
pCompress = false;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
}
|
||||
|
||||
DBcore::~DBcore()
|
||||
{
|
||||
/**
|
||||
* This prevents us from doing a double free in multi-tenancy setups where we
|
||||
* are re-using the default database connection pointer when we dont have an
|
||||
* external configuration setup ex: (content_database)
|
||||
*/
|
||||
std::string mysql_connection_host;
|
||||
if (mysql.host) {
|
||||
mysql_connection_host = mysql.host;
|
||||
}
|
||||
|
||||
if (GetOriginHost() != mysql_connection_host) {
|
||||
return;
|
||||
}
|
||||
|
||||
DBcore::~DBcore() {
|
||||
mysql_close(&mysql);
|
||||
safe_delete_array(pHost);
|
||||
safe_delete_array(pUser);
|
||||
@@ -68,8 +49,7 @@ DBcore::~DBcore()
|
||||
}
|
||||
|
||||
// Sends the MySQL server a keepalive
|
||||
void DBcore::ping()
|
||||
{
|
||||
void DBcore::ping() {
|
||||
if (!MDatabase.trylock()) {
|
||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||
return;
|
||||
@@ -83,44 +63,34 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO
|
||||
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||
}
|
||||
|
||||
bool DBcore::DoesTableExist(std::string table_name)
|
||||
MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce)
|
||||
{
|
||||
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
|
||||
|
||||
return results.RowCount() > 0;
|
||||
}
|
||||
|
||||
MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce)
|
||||
{
|
||||
BenchTimer timer;
|
||||
timer.reset();
|
||||
|
||||
LockMutex lock(&MDatabase);
|
||||
|
||||
// Reconnect if we are not connected before hand.
|
||||
if (pStatus != Connected) {
|
||||
if (pStatus != Connected)
|
||||
Open();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// request query. != 0 indicates some kind of error.
|
||||
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
||||
if (mysql_real_query(&mysql, query, querylen) != 0)
|
||||
{
|
||||
unsigned int errorNumber = mysql_errno(&mysql);
|
||||
|
||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
||||
if (errorNumber == CR_SERVER_GONE_ERROR)
|
||||
pStatus = Error;
|
||||
}
|
||||
|
||||
// error appears to be a disconnect error, may need to try again.
|
||||
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) {
|
||||
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR)
|
||||
{
|
||||
|
||||
if (retryOnFailureOnce) {
|
||||
LogInfo("Database Error: Lost connection, attempting to recover");
|
||||
if (retryOnFailureOnce)
|
||||
{
|
||||
std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl;
|
||||
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
|
||||
|
||||
if (requestResult.Success()) {
|
||||
LogInfo("Reconnection to database successful");
|
||||
if (requestResult.Success())
|
||||
{
|
||||
std::cout << "Reconnection to database successful." << std::endl;
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
@@ -132,170 +102,116 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
|
||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer);
|
||||
}
|
||||
|
||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
|
||||
/**
|
||||
* Error logging
|
||||
*/
|
||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(&mysql), mysql_error(&mysql), query);
|
||||
/* Implement Logging at the Root */
|
||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0){
|
||||
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)
|
||||
Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query);
|
||||
}
|
||||
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer);
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer);
|
||||
|
||||
}
|
||||
|
||||
// successful query. get results.
|
||||
MYSQL_RES *res = mysql_store_result(&mysql);
|
||||
uint32 rowCount = 0;
|
||||
MYSQL_RES* res = mysql_store_result(&mysql);
|
||||
uint32 rowCount = 0;
|
||||
|
||||
if (res != nullptr) {
|
||||
rowCount = (uint32) mysql_num_rows(res);
|
||||
}
|
||||
if (res != nullptr)
|
||||
rowCount = (uint32)mysql_num_rows(res);
|
||||
|
||||
MySQLRequestResult requestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(&mysql),
|
||||
rowCount,
|
||||
(uint32) mysql_field_count(&mysql),
|
||||
(uint32) mysql_insert_id(&mysql)
|
||||
);
|
||||
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
|
||||
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)
|
||||
{
|
||||
if ((strncasecmp(query, "select", 6) == 0)) {
|
||||
LogMySQLQuery(
|
||||
"{0} -- ({1} row{2} returned) ({3}s)",
|
||||
query,
|
||||
requestResult.RowCount(),
|
||||
requestResult.RowCount() == 1 ? "" : "s",
|
||||
std::to_string(timer.elapsed())
|
||||
);
|
||||
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s");
|
||||
}
|
||||
else {
|
||||
LogMySQLQuery(
|
||||
"{0} -- ({1} row{2} affected) ({3}s)",
|
||||
query,
|
||||
requestResult.RowsAffected(),
|
||||
requestResult.RowsAffected() == 1 ? "" : "s",
|
||||
std::to_string(timer.elapsed())
|
||||
);
|
||||
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s");
|
||||
}
|
||||
}
|
||||
|
||||
return requestResult;
|
||||
}
|
||||
|
||||
void DBcore::TransactionBegin()
|
||||
{
|
||||
void DBcore::TransactionBegin() {
|
||||
QueryDatabase("START TRANSACTION");
|
||||
}
|
||||
|
||||
void DBcore::TransactionCommit()
|
||||
{
|
||||
void DBcore::TransactionCommit() {
|
||||
QueryDatabase("COMMIT");
|
||||
}
|
||||
|
||||
void DBcore::TransactionRollback()
|
||||
{
|
||||
void DBcore::TransactionRollback() {
|
||||
QueryDatabase("ROLLBACK");
|
||||
}
|
||||
|
||||
uint32 DBcore::DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen)
|
||||
{
|
||||
uint32 DBcore::DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen) {
|
||||
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
||||
// LockMutex lock(&MDatabase);
|
||||
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
||||
}
|
||||
|
||||
bool DBcore::Open(
|
||||
const char *iHost,
|
||||
const char *iUser,
|
||||
const char *iPassword,
|
||||
const char *iDatabase,
|
||||
uint32 iPort,
|
||||
uint32 *errnum,
|
||||
char *errbuf,
|
||||
bool iCompress,
|
||||
bool iSSL
|
||||
)
|
||||
{
|
||||
bool DBcore::Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase,uint32 iPort, uint32* errnum, char* errbuf, bool iCompress, bool iSSL) {
|
||||
LockMutex lock(&MDatabase);
|
||||
safe_delete_array(pHost);
|
||||
safe_delete_array(pUser);
|
||||
safe_delete_array(pPassword);
|
||||
safe_delete_array(pDatabase);
|
||||
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
|
||||
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
|
||||
safe_delete(pHost);
|
||||
safe_delete(pUser);
|
||||
safe_delete(pPassword);
|
||||
safe_delete(pDatabase);
|
||||
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
|
||||
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
|
||||
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
|
||||
pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase);
|
||||
pCompress = iCompress;
|
||||
pPort = iPort;
|
||||
pSSL = iSSL;
|
||||
pPort = iPort;
|
||||
pSSL = iSSL;
|
||||
return Open(errnum, errbuf);
|
||||
}
|
||||
|
||||
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||
{
|
||||
if (errbuf) {
|
||||
bool DBcore::Open(uint32* errnum, char* errbuf) {
|
||||
if (errbuf)
|
||||
errbuf[0] = 0;
|
||||
}
|
||||
LockMutex lock(&MDatabase);
|
||||
if (GetStatus() == Connected) {
|
||||
if (GetStatus() == Connected)
|
||||
return true;
|
||||
}
|
||||
if (GetStatus() == Error) {
|
||||
mysql_close(&mysql);
|
||||
mysql_init(&mysql); // Initialize structure again
|
||||
mysql_init(&mysql); // Initialize structure again
|
||||
}
|
||||
if (!pHost) {
|
||||
if (!pHost)
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
Added CLIENT_FOUND_ROWS flag to the connect
|
||||
otherwise DB update calls would say 0 rows affected when the value already equalled
|
||||
what the function was tring to set it to, therefore the function would think it failed
|
||||
*/
|
||||
uint32 flags = CLIENT_FOUND_ROWS;
|
||||
if (pCompress) {
|
||||
if (pCompress)
|
||||
flags |= CLIENT_COMPRESS;
|
||||
}
|
||||
if (pSSL) {
|
||||
if (pSSL)
|
||||
flags |= CLIENT_SSL;
|
||||
}
|
||||
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
||||
pStatus = Connected;
|
||||
|
||||
std::string connected_origin_host = pHost;
|
||||
SetOriginHost(connected_origin_host);
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (errnum) {
|
||||
if (errnum)
|
||||
*errnum = mysql_errno(&mysql);
|
||||
}
|
||||
if (errbuf) {
|
||||
if (errbuf)
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
}
|
||||
pStatus = Error;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DBcore::SetMysql(MYSQL *mysql)
|
||||
{
|
||||
DBcore::mysql = *mysql;
|
||||
}
|
||||
|
||||
const std::string &DBcore::GetOriginHost() const
|
||||
{
|
||||
return origin_host;
|
||||
}
|
||||
|
||||
void DBcore::SetOriginHost(const std::string &origin_host)
|
||||
{
|
||||
DBcore::origin_host = origin_host;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+20
-41
@@ -2,8 +2,8 @@
|
||||
#define DBCORE_H
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "../common/mutex.h"
|
||||
@@ -15,57 +15,36 @@
|
||||
|
||||
class DBcore {
|
||||
public:
|
||||
enum eStatus {
|
||||
Closed, Connected, Error
|
||||
};
|
||||
enum eStatus { Closed, Connected, Error };
|
||||
|
||||
DBcore();
|
||||
~DBcore();
|
||||
eStatus GetStatus() { return pStatus; }
|
||||
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
||||
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
|
||||
eStatus GetStatus() { return pStatus; }
|
||||
MySQLRequestResult QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce = true);
|
||||
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
|
||||
void TransactionBegin();
|
||||
void TransactionCommit();
|
||||
void TransactionRollback();
|
||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||
void ping();
|
||||
MYSQL *getMySQL() { return &mysql; }
|
||||
void SetMysql(MYSQL *mysql);
|
||||
|
||||
const std::string &GetOriginHost() const;
|
||||
void SetOriginHost(const std::string &origin_host);
|
||||
|
||||
bool DoesTableExist(std::string table_name);
|
||||
uint32 DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen);
|
||||
void ping();
|
||||
MYSQL* getMySQL(){ return &mysql; }
|
||||
|
||||
protected:
|
||||
bool Open(
|
||||
const char *iHost,
|
||||
const char *iUser,
|
||||
const char *iPassword,
|
||||
const char *iDatabase,
|
||||
uint32 iPort,
|
||||
uint32 *errnum = 0,
|
||||
char *errbuf = 0,
|
||||
bool iCompress = false,
|
||||
bool iSSL = false
|
||||
);
|
||||
|
||||
bool Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase, uint32 iPort, uint32* errnum = 0, char* errbuf = 0, bool iCompress = false, bool iSSL = false);
|
||||
private:
|
||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||
bool Open(uint32* errnum = 0, char* errbuf = 0);
|
||||
|
||||
MYSQL mysql;
|
||||
Mutex MDatabase;
|
||||
MYSQL mysql;
|
||||
Mutex MDatabase;
|
||||
eStatus pStatus;
|
||||
|
||||
std::string origin_host;
|
||||
|
||||
char *pHost;
|
||||
char *pUser;
|
||||
char *pPassword;
|
||||
char *pDatabase;
|
||||
bool pCompress;
|
||||
uint32 pPort;
|
||||
bool pSSL;
|
||||
char* pHost;
|
||||
char* pUser;
|
||||
char* pPassword;
|
||||
char* pDatabase;
|
||||
bool pCompress;
|
||||
uint32 pPort;
|
||||
bool pSSL;
|
||||
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@
|
||||
#include "deity.h"
|
||||
|
||||
|
||||
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
||||
EQEmu::deity::DeityTypeBit EQEmu::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
@@ -63,7 +63,7 @@ EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deit
|
||||
};
|
||||
}
|
||||
|
||||
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
||||
EQEmu::deity::DeityType EQEmu::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
||||
{
|
||||
switch (deity_type_bit) {
|
||||
case bit_DeityAgnostic:
|
||||
@@ -105,7 +105,7 @@ EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deit
|
||||
};
|
||||
}
|
||||
|
||||
const char* EQ::deity::DeityName(DeityType deity_type)
|
||||
const char* EQEmu::deity::DeityName(DeityType deity_type)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
#include "types.h"
|
||||
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
namespace deity {
|
||||
enum DeityType {
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <cereal/archives/binary.hpp>
|
||||
#include "discord.h"
|
||||
#include "../http/httplib.h"
|
||||
#include "../json/json.h"
|
||||
#include "../strings.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../events/player_event_logs.h"
|
||||
|
||||
constexpr int MAX_RETRIES = 10;
|
||||
|
||||
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
||||
{
|
||||
if (!ValidateWebhookUrl(webhook_url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// split
|
||||
auto s = Strings::Split(webhook_url, '/');
|
||||
|
||||
// url
|
||||
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
|
||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||
|
||||
// client
|
||||
httplib::Client cli(base_url);
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// payload
|
||||
Json::Value p;
|
||||
p["content"] = message;
|
||||
std::stringstream payload;
|
||||
payload << p;
|
||||
|
||||
bool retry = true;
|
||||
int retries = 0;
|
||||
int retry_timer = 1000;
|
||||
while (retry) {
|
||||
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
|
||||
if (res->status != 200 && res->status != 204) {
|
||||
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
|
||||
}
|
||||
if (res->status == 429) {
|
||||
if (!res->body.empty()) {
|
||||
std::stringstream ss(res->body);
|
||||
Json::Value response;
|
||||
|
||||
try {
|
||||
ss >> response;
|
||||
}
|
||||
catch (std::exception const &ex) {
|
||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||
}
|
||||
|
||||
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
||||
}
|
||||
|
||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
|
||||
}
|
||||
if (res->status == 204) {
|
||||
retry = false;
|
||||
}
|
||||
if (retries > MAX_RETRIES) {
|
||||
LogDiscord("Retries exceeded for message [{}]", message);
|
||||
retry = false;
|
||||
}
|
||||
|
||||
retries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Discord::SendPlayerEventMessage(
|
||||
const PlayerEvent::PlayerEventContainer &e,
|
||||
const std::string &webhook_url
|
||||
)
|
||||
{
|
||||
if (!ValidateWebhookUrl(webhook_url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto s = Strings::Split(webhook_url, '/');
|
||||
|
||||
// url
|
||||
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
|
||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||
|
||||
// client
|
||||
httplib::Client cli(base_url);
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
|
||||
if (payload.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool retry = true;
|
||||
int retries = 0;
|
||||
int retry_timer = 1000;
|
||||
while (retry) {
|
||||
if (auto res = cli.Post(endpoint, payload, "application/json")) {
|
||||
if (res->status != 200 && res->status != 204) {
|
||||
LogError("Code [{}] Error [{}]", res->status, res->body);
|
||||
}
|
||||
if (res->status == 429) {
|
||||
if (!res->body.empty()) {
|
||||
std::stringstream ss(res->body);
|
||||
Json::Value response;
|
||||
|
||||
try {
|
||||
ss >> response;
|
||||
}
|
||||
catch (std::exception const &ex) {
|
||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||
}
|
||||
|
||||
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
||||
}
|
||||
|
||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
|
||||
}
|
||||
if (res->status == 204) {
|
||||
retry = false;
|
||||
}
|
||||
if (retries > MAX_RETRIES) {
|
||||
LogDiscord("Retries exceeded for player event message");
|
||||
retry = false;
|
||||
}
|
||||
|
||||
retries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
|
||||
{
|
||||
if (category_id == Logs::LogCategory::MySQLQuery) {
|
||||
return fmt::format("```sql\n{}\n```", message);
|
||||
}
|
||||
|
||||
return message + "\n";
|
||||
}
|
||||
|
||||
bool Discord::ValidateWebhookUrl(const std::string &webhook_url)
|
||||
{
|
||||
// validate
|
||||
if (webhook_url.empty()) {
|
||||
LogDiscord("[webhook_url] is empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate
|
||||
if (!Strings::Contains(webhook_url, "http://") && !Strings::Contains(webhook_url, "https://")) {
|
||||
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef EQEMU_DISCORD_H
|
||||
#define EQEMU_DISCORD_H
|
||||
|
||||
|
||||
#include <string>
|
||||
#include "../types.h"
|
||||
#include "../http/httplib.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../events/player_events.h"
|
||||
|
||||
class Discord {
|
||||
public:
|
||||
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
||||
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
|
||||
static void SendPlayerEventMessage(const PlayerEvent::PlayerEventContainer& e, const std::string &webhook_url);
|
||||
static bool ValidateWebhookUrl(const std::string &webhook_url);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_DISCORD_H
|
||||
@@ -1,75 +0,0 @@
|
||||
#include "discord_manager.h"
|
||||
#include "../../common/discord/discord.h"
|
||||
#include "../events/player_event_logs.h"
|
||||
|
||||
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
||||
{
|
||||
webhook_queue_lock.lock();
|
||||
webhook_message_queue[webhook_id].emplace_back(message);
|
||||
webhook_queue_lock.unlock();
|
||||
}
|
||||
|
||||
constexpr int MAX_MESSAGE_LENGTH = 1900;
|
||||
|
||||
void DiscordManager::ProcessMessageQueue()
|
||||
{
|
||||
if (webhook_message_queue.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
webhook_queue_lock.lock();
|
||||
for (auto &q: webhook_message_queue) {
|
||||
LogDiscord("Processing [{}] messages in queue for webhook ID [{}]...", q.second.size(), q.first);
|
||||
|
||||
if (q.first >= MAX_DISCORD_WEBHOOK_ID) {
|
||||
LogDiscord("Out of bounds webhook ID [{}] max [{}]", q.first, MAX_DISCORD_WEBHOOK_ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto webhook = LogSys.GetDiscordWebhooks()[q.first];
|
||||
std::string message;
|
||||
|
||||
for (auto &m: q.second) {
|
||||
// next message would become too large
|
||||
bool next_message_too_large = ((int) m.length() + (int) message.length()) > MAX_MESSAGE_LENGTH;
|
||||
if (next_message_too_large) {
|
||||
Discord::SendWebhookMessage(
|
||||
message,
|
||||
webhook.webhook_url
|
||||
);
|
||||
message = "";
|
||||
}
|
||||
|
||||
message += m;
|
||||
|
||||
// one single message was too large
|
||||
// this should rarely happen but the message will need to be split
|
||||
if ((int) message.length() > MAX_MESSAGE_LENGTH) {
|
||||
for (unsigned mi = 0; mi < message.length(); mi += MAX_MESSAGE_LENGTH) {
|
||||
Discord::SendWebhookMessage(
|
||||
message.substr(mi, MAX_MESSAGE_LENGTH),
|
||||
webhook.webhook_url
|
||||
);
|
||||
}
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
// final flush
|
||||
if (!message.empty()) {
|
||||
Discord::SendWebhookMessage(
|
||||
message,
|
||||
webhook.webhook_url
|
||||
);
|
||||
}
|
||||
}
|
||||
webhook_message_queue.clear();
|
||||
webhook_queue_lock.unlock();
|
||||
}
|
||||
|
||||
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
|
||||
{
|
||||
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
|
||||
if (!w.empty()) {
|
||||
Discord::SendPlayerEventMessage(e, w);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef EQEMU_DISCORD_MANAGER_H
|
||||
#define EQEMU_DISCORD_MANAGER_H
|
||||
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "../../common/types.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../events/player_events.h"
|
||||
|
||||
class DiscordManager {
|
||||
public:
|
||||
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
||||
void ProcessMessageQueue();
|
||||
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
||||
private:
|
||||
std::mutex webhook_queue_lock{};
|
||||
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,649 +0,0 @@
|
||||
#include "dynamic_zone_base.h"
|
||||
#include "database.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "repositories/instance_list_repository.h"
|
||||
#include "repositories/instance_list_player_repository.h"
|
||||
#include "rulesys.h"
|
||||
#include "servertalk.h"
|
||||
#include "util/uuid.h"
|
||||
|
||||
DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry)
|
||||
{
|
||||
LoadRepositoryResult(std::move(entry));
|
||||
}
|
||||
|
||||
uint32_t DynamicZoneBase::Create()
|
||||
{
|
||||
if (GetInstanceID() == 0)
|
||||
{
|
||||
CreateInstance();
|
||||
}
|
||||
|
||||
m_uuid = EQ::Util::UUID::Generate().ToString();
|
||||
m_id = SaveToDatabase();
|
||||
|
||||
return m_id;
|
||||
}
|
||||
|
||||
uint32_t DynamicZoneBase::CreateInstance()
|
||||
{
|
||||
if (m_instance_id)
|
||||
{
|
||||
LogDynamicZones("CreateInstance failed, instance id [{}] already created", m_instance_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_zone_id)
|
||||
{
|
||||
LogDynamicZones("CreateInstance failed, invalid zone id [{}]", m_zone_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t unused_instance_id = 0;
|
||||
if (!GetDatabase().GetUnusedInstanceID(unused_instance_id)) // todo: doesn't this race with insert?
|
||||
{
|
||||
LogDynamicZones("Failed to find unused instance id");
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_start_time = std::chrono::system_clock::now();
|
||||
m_expire_time = m_start_time + m_duration;
|
||||
|
||||
auto insert_instance = InstanceListRepository::NewEntity();
|
||||
insert_instance.id = unused_instance_id;
|
||||
insert_instance.zone = m_zone_id;
|
||||
insert_instance.version = m_zone_version;
|
||||
insert_instance.start_time = static_cast<int>(std::chrono::system_clock::to_time_t(m_start_time));
|
||||
insert_instance.duration = static_cast<int>(m_duration.count());
|
||||
insert_instance.never_expires = m_never_expires;
|
||||
|
||||
auto instance = InstanceListRepository::InsertOne(GetDatabase(), insert_instance);
|
||||
if (instance.id == 0)
|
||||
{
|
||||
LogDynamicZones("Failed to create instance [{}] for zone [{}]", unused_instance_id, m_zone_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_instance_id = instance.id;
|
||||
|
||||
return m_instance_id;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry)
|
||||
{
|
||||
m_id = dz_entry.id;
|
||||
m_uuid = std::move(dz_entry.uuid);
|
||||
m_name = std::move(dz_entry.name);
|
||||
m_leader.id = dz_entry.leader_id;
|
||||
m_min_players = dz_entry.min_players;
|
||||
m_max_players = dz_entry.max_players;
|
||||
m_instance_id = dz_entry.instance_id;
|
||||
m_type = static_cast<DynamicZoneType>(dz_entry.type);
|
||||
m_dz_switch_id = dz_entry.dz_switch_id;
|
||||
m_compass.zone_id = dz_entry.compass_zone_id;
|
||||
m_compass.x = dz_entry.compass_x;
|
||||
m_compass.y = dz_entry.compass_y;
|
||||
m_compass.z = dz_entry.compass_z;
|
||||
m_safereturn.zone_id = dz_entry.safe_return_zone_id;
|
||||
m_safereturn.x = dz_entry.safe_return_x;
|
||||
m_safereturn.y = dz_entry.safe_return_y;
|
||||
m_safereturn.z = dz_entry.safe_return_z;
|
||||
m_safereturn.heading = dz_entry.safe_return_heading;
|
||||
m_zonein.x = dz_entry.zone_in_x;
|
||||
m_zonein.y = dz_entry.zone_in_y;
|
||||
m_zonein.z = dz_entry.zone_in_z;
|
||||
m_zonein.heading = dz_entry.zone_in_heading;
|
||||
m_has_zonein = (dz_entry.has_zone_in != 0);
|
||||
// instance_list portion
|
||||
m_zone_id = dz_entry.zone;
|
||||
m_zone_version = dz_entry.version;
|
||||
m_start_time = std::chrono::system_clock::from_time_t(dz_entry.start_time);
|
||||
m_duration = std::chrono::seconds(dz_entry.duration);
|
||||
m_never_expires = (dz_entry.never_expires != 0);
|
||||
m_expire_time = m_start_time + m_duration;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::AddMemberFromRepositoryResult(
|
||||
DynamicZoneMembersRepository::MemberWithName&& entry)
|
||||
{
|
||||
auto status = DynamicZoneMemberStatus::Unknown;
|
||||
|
||||
if (m_leader.id == entry.character_id)
|
||||
{
|
||||
m_leader.name = entry.character_name;
|
||||
}
|
||||
|
||||
AddInternalMember({ entry.character_id, std::move(entry.character_name), status });
|
||||
}
|
||||
|
||||
uint32_t DynamicZoneBase::SaveToDatabase()
|
||||
{
|
||||
LogDynamicZonesDetail("Saving dz instance [{}] to database", m_instance_id);
|
||||
|
||||
if (m_instance_id != 0)
|
||||
{
|
||||
auto insert_dz = DynamicZonesRepository::NewEntity();
|
||||
insert_dz.uuid = m_uuid;
|
||||
insert_dz.name = m_name;
|
||||
insert_dz.leader_id = m_leader.id;
|
||||
insert_dz.min_players = m_min_players;
|
||||
insert_dz.max_players = m_max_players;
|
||||
insert_dz.instance_id = m_instance_id,
|
||||
insert_dz.type = static_cast<int>(m_type);
|
||||
insert_dz.dz_switch_id = m_dz_switch_id;
|
||||
insert_dz.compass_zone_id = m_compass.zone_id;
|
||||
insert_dz.compass_x = m_compass.x;
|
||||
insert_dz.compass_y = m_compass.y;
|
||||
insert_dz.compass_z = m_compass.z;
|
||||
insert_dz.safe_return_zone_id = m_safereturn.zone_id;
|
||||
insert_dz.safe_return_x = m_safereturn.x;
|
||||
insert_dz.safe_return_y = m_safereturn.y;
|
||||
insert_dz.safe_return_z = m_safereturn.z;
|
||||
insert_dz.safe_return_heading = m_safereturn.heading;
|
||||
insert_dz.zone_in_x = m_zonein.x;
|
||||
insert_dz.zone_in_y = m_zonein.y;
|
||||
insert_dz.zone_in_z = m_zonein.z;
|
||||
insert_dz.zone_in_heading = m_zonein.heading;
|
||||
insert_dz.has_zone_in = m_has_zonein;
|
||||
|
||||
auto inserted_dz = DynamicZonesRepository::InsertOne(GetDatabase(), insert_dz);
|
||||
return inserted_dz.id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::AddMember(const DynamicZoneMember& add_member)
|
||||
{
|
||||
if (HasMember(add_member.id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DynamicZoneMembersRepository::AddMember(GetDatabase(), m_id, add_member.id);
|
||||
GetDatabase().AddClientToInstance(m_instance_id, add_member.id);
|
||||
|
||||
ProcessMemberAddRemove(add_member, false);
|
||||
SendServerPacket(CreateServerMemberAddRemovePacket(add_member, false).get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::RemoveMember(uint32_t character_id)
|
||||
{
|
||||
auto remove_member = GetMemberData(character_id);
|
||||
return RemoveMember(remove_member);
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::RemoveMember(const std::string& character_name)
|
||||
{
|
||||
auto remove_member = GetMemberData(character_name);
|
||||
return RemoveMember(remove_member);
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::RemoveMember(const DynamicZoneMember& remove_member)
|
||||
{
|
||||
if (remove_member.id == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DynamicZoneMembersRepository::RemoveMember(GetDatabase(), m_id, remove_member.id);
|
||||
GetDatabase().RemoveClientFromInstance(m_instance_id, remove_member.id);
|
||||
|
||||
ProcessMemberAddRemove(remove_member, true);
|
||||
SendServerPacket(CreateServerMemberAddRemovePacket(remove_member, true).get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::SwapMember(
|
||||
const DynamicZoneMember& add_member, const std::string& remove_char_name)
|
||||
{
|
||||
auto remove_member = GetMemberData(remove_char_name);
|
||||
if (!add_member.IsValid() || !remove_member.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// make remove and add atomic to avoid racing with separate world messages
|
||||
DynamicZoneMembersRepository::RemoveMember(GetDatabase(), m_id, remove_member.id);
|
||||
GetDatabase().RemoveClientFromInstance(m_instance_id, remove_member.id);
|
||||
|
||||
DynamicZoneMembersRepository::AddMember(GetDatabase(), m_id, add_member.id);
|
||||
GetDatabase().AddClientToInstance(m_instance_id, add_member.id);
|
||||
|
||||
ProcessMemberAddRemove(remove_member, true);
|
||||
ProcessMemberAddRemove(add_member, false);
|
||||
SendServerPacket(CreateServerMemberSwapPacket(remove_member, add_member).get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::RemoveAllMembers()
|
||||
{
|
||||
DynamicZoneMembersRepository::RemoveAllMembers(GetDatabase(), m_id);
|
||||
GetDatabase().RemoveClientsFromInstance(GetInstanceID());
|
||||
|
||||
ProcessRemoveAllMembers();
|
||||
SendServerPacket(CreateServerRemoveAllMembersPacket().get());
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
|
||||
{
|
||||
LogDynamicZonesDetail("Saving [{}] member(s) for dz [{}]", members.size(), m_id);
|
||||
|
||||
m_members = members;
|
||||
|
||||
// the lower level instance_list_players needs to be kept updated as well
|
||||
std::vector<DynamicZoneMembersRepository::DynamicZoneMembers> insert_members;
|
||||
std::vector<InstanceListPlayerRepository::InstanceListPlayer> insert_players;
|
||||
for (const auto& member : m_members)
|
||||
{
|
||||
DynamicZoneMembersRepository::DynamicZoneMembers member_entry{};
|
||||
member_entry.dynamic_zone_id = m_id;
|
||||
member_entry.character_id = member.id;
|
||||
insert_members.emplace_back(member_entry);
|
||||
|
||||
InstanceListPlayerRepository::InstanceListPlayer player_entry;
|
||||
player_entry.id = static_cast<int>(m_instance_id);
|
||||
player_entry.charid = static_cast<int>(member.id);
|
||||
insert_players.emplace_back(player_entry);
|
||||
}
|
||||
|
||||
DynamicZoneMembersRepository::InsertOrUpdateMany(GetDatabase(), insert_members);
|
||||
InstanceListPlayerRepository::InsertOrUpdateMany(GetDatabase(), insert_players);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetCompass(const DynamicZoneLocation& location, bool update_db)
|
||||
{
|
||||
ProcessCompassChange(location);
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
LogDynamicZonesDetail("Saving [{}] compass zone: [{}] xyz: ([{}], [{}], [{}])",
|
||||
m_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z);
|
||||
|
||||
DynamicZonesRepository::UpdateCompass(GetDatabase(),
|
||||
m_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z);
|
||||
|
||||
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetCompass, location).get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db)
|
||||
{
|
||||
SetCompass({ zone_id, x, y, z, 0.0f }, update_db);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetSafeReturn(const DynamicZoneLocation& location, bool update_db)
|
||||
{
|
||||
m_safereturn = location;
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
LogDynamicZonesDetail("Saving [{}] safereturn zone: [{}] xyzh: ([{}], [{}], [{}], [{}])",
|
||||
m_id, m_safereturn.zone_id, m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading);
|
||||
|
||||
DynamicZonesRepository::UpdateSafeReturn(GetDatabase(), m_id, m_safereturn.zone_id,
|
||||
m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading);
|
||||
|
||||
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetSafeReturn, location).get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db)
|
||||
{
|
||||
SetSafeReturn({ zone_id, x, y, z, heading }, update_db);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetZoneInLocation(const DynamicZoneLocation& location, bool update_db)
|
||||
{
|
||||
m_zonein = location;
|
||||
m_has_zonein = true;
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
LogDynamicZonesDetail("Saving [{}] zonein zone: [{}] xyzh: ([{}], [{}], [{}], [{}])",
|
||||
m_id, m_zone_id, m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading);
|
||||
|
||||
DynamicZonesRepository::UpdateZoneIn(GetDatabase(), m_id, m_zone_id,
|
||||
m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading, m_has_zonein);
|
||||
|
||||
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetZoneIn, location).get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetZoneInLocation(float x, float y, float z, float heading, bool update_db)
|
||||
{
|
||||
SetZoneInLocation({ 0, x, y, z, heading }, update_db);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetSwitchID(int dz_switch_id, bool update_db)
|
||||
{
|
||||
m_dz_switch_id = dz_switch_id;
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
DynamicZonesRepository::UpdateSwitchID(GetDatabase(), m_id, dz_switch_id);
|
||||
SendServerPacket(CreateServerDzSwitchIDPacket().get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update_db)
|
||||
{
|
||||
m_leader = new_leader;
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
DynamicZonesRepository::UpdateLeaderID(GetDatabase(), m_id, new_leader.id);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DynamicZoneBase::GetSecondsRemaining() const
|
||||
{
|
||||
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(GetDurationRemaining()).count();
|
||||
return std::max(0, static_cast<int>(remaining));
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberAddRemovePacket(
|
||||
const DynamicZoneMember& member, bool removed)
|
||||
{
|
||||
constexpr uint32_t pack_size = sizeof(ServerDzMember_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzAddRemoveMember, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzMember_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->dz_zone_id = GetZoneID();
|
||||
buf->dz_instance_id = GetInstanceID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->removed = removed;
|
||||
buf->character_id = member.id;
|
||||
buf->character_status = static_cast<uint8_t>(member.status);
|
||||
strn0cpy(buf->character_name, member.name.c_str(), sizeof(buf->character_name));
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberSwapPacket(
|
||||
const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member)
|
||||
{
|
||||
constexpr uint32_t pack_size = sizeof(ServerDzMemberSwap_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSwapMembers, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzMemberSwap_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->dz_zone_id = GetZoneID();
|
||||
buf->dz_instance_id = GetInstanceID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->add_character_status = static_cast<uint8_t>(add_member.status);
|
||||
buf->add_character_id = add_member.id;
|
||||
buf->remove_character_id = remove_member.id;
|
||||
strn0cpy(buf->add_character_name, add_member.name.c_str(), sizeof(buf->add_character_name));
|
||||
strn0cpy(buf->remove_character_name, remove_member.name.c_str(), sizeof(buf->remove_character_name));
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerRemoveAllMembersPacket()
|
||||
{
|
||||
constexpr uint32_t pack_size = sizeof(ServerDzID_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzRemoveAllMembers, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzID_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->dz_zone_id = GetZoneID();
|
||||
buf->dz_instance_id = GetInstanceID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzLocationPacket(
|
||||
uint16_t server_opcode, const DynamicZoneLocation& location)
|
||||
{
|
||||
constexpr uint32_t pack_size = sizeof(ServerDzLocation_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(server_opcode, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzLocation_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->zone_id = location.zone_id;
|
||||
buf->x = location.x;
|
||||
buf->y = location.y;
|
||||
buf->z = location.z;
|
||||
buf->heading = location.heading;
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzSwitchIDPacket()
|
||||
{
|
||||
constexpr uint32_t pack_size = sizeof(ServerDzSwitchID_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSetSwitchID, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzSwitchID_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->dz_switch_id = GetSwitchID();
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberStatusPacket(
|
||||
uint32_t character_id, DynamicZoneMemberStatus status)
|
||||
{
|
||||
constexpr uint32_t pack_size = sizeof(ServerDzMemberStatus_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzUpdateMemberStatus, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzMemberStatus_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->status = static_cast<uint8_t>(status);
|
||||
buf->character_id = character_id;
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
uint32_t DynamicZoneBase::GetDatabaseMemberCount()
|
||||
{
|
||||
return DynamicZoneMembersRepository::GetCountWhere(GetDatabase(),
|
||||
fmt::format("dynamic_zone_id = {}", m_id));
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::HasDatabaseMember(uint32_t character_id)
|
||||
{
|
||||
if (character_id == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto entries = DynamicZoneMembersRepository::GetWhere(GetDatabase(), fmt::format(
|
||||
"dynamic_zone_id = {} AND character_id = {}",
|
||||
m_id, character_id
|
||||
));
|
||||
|
||||
return entries.size() != 0;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::AddInternalMember(const DynamicZoneMember& member)
|
||||
{
|
||||
if (!HasMember(member.id))
|
||||
{
|
||||
m_members.emplace_back(member);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::RemoveInternalMember(uint32_t character_id)
|
||||
{
|
||||
m_members.erase(std::remove_if(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) { return member.id == character_id; }
|
||||
), m_members.end());
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::HasMember(uint32_t character_id)
|
||||
{
|
||||
return std::any_of(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) { return member.id == character_id; });
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::HasMember(const std::string& character_name)
|
||||
{
|
||||
return std::any_of(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) {
|
||||
return strcasecmp(member.name.c_str(), character_name.c_str()) == 0;
|
||||
});
|
||||
}
|
||||
|
||||
DynamicZoneMember DynamicZoneBase::GetMemberData(uint32_t character_id)
|
||||
{
|
||||
auto it = std::find_if(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) { return member.id == character_id; });
|
||||
|
||||
DynamicZoneMember member_data;
|
||||
if (it != m_members.end())
|
||||
{
|
||||
member_data = *it;
|
||||
}
|
||||
return member_data;
|
||||
}
|
||||
|
||||
DynamicZoneMember DynamicZoneBase::GetMemberData(const std::string& character_name)
|
||||
{
|
||||
auto it = std::find_if(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) {
|
||||
return strcasecmp(member.name.c_str(), character_name.c_str()) == 0;
|
||||
});
|
||||
|
||||
DynamicZoneMember member_data;
|
||||
if (it != m_members.end())
|
||||
{
|
||||
member_data = *it;
|
||||
}
|
||||
return member_data;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status)
|
||||
{
|
||||
if (status == DynamicZoneMemberStatus::InDynamicZone && !RuleB(DynamicZone, EnableInDynamicZoneStatus))
|
||||
{
|
||||
status = DynamicZoneMemberStatus::Online;
|
||||
}
|
||||
|
||||
if (character_id == m_leader.id)
|
||||
{
|
||||
m_leader.status = status;
|
||||
}
|
||||
|
||||
auto it = std::find_if(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) { return member.id == character_id; });
|
||||
|
||||
if (it != m_members.end() && it->status != status)
|
||||
{
|
||||
it->status = status;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status)
|
||||
{
|
||||
auto update_member = GetMemberData(character_id);
|
||||
if (update_member.IsValid())
|
||||
{
|
||||
ProcessMemberStatusChange(character_id, status);
|
||||
SendServerPacket(CreateServerMemberStatusPacket(character_id, status).get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed)
|
||||
{
|
||||
if (!removed)
|
||||
{
|
||||
AddInternalMember(member);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveInternalMember(member.id);
|
||||
}
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::ProcessMemberStatusChange(uint32_t character_id, DynamicZoneMemberStatus status)
|
||||
{
|
||||
return SetInternalMemberStatus(character_id, status);
|
||||
}
|
||||
|
||||
std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
|
||||
{
|
||||
switch (dz_type)
|
||||
{
|
||||
case DynamicZoneType::Expedition:
|
||||
return "Expedition";
|
||||
case DynamicZoneType::Tutorial:
|
||||
return "Tutorial";
|
||||
case DynamicZoneType::Task:
|
||||
return "Task";
|
||||
case DynamicZoneType::Mission:
|
||||
return "Mission";
|
||||
case DynamicZoneType::Quest:
|
||||
return "Quest";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
|
||||
{
|
||||
EQ::Net::DynamicPacket dyn_pack;
|
||||
dyn_pack.PutSerialize(0, *this);
|
||||
|
||||
LogDynamicZonesDetail("Serialized server dz size [{}]", dyn_pack.Length());
|
||||
return dyn_pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzCreatePacket(
|
||||
uint16_t origin_zone_id, uint16_t origin_instance_id)
|
||||
{
|
||||
EQ::Net::DynamicPacket dyn_pack = GetSerializedDzPacket();
|
||||
|
||||
auto pack_size = sizeof(ServerDzCreateSerialized_Struct) + dyn_pack.Length();
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzCreated, static_cast<uint32_t>(pack_size));
|
||||
auto buf = reinterpret_cast<ServerDzCreateSerialized_Struct*>(pack->pBuffer);
|
||||
buf->origin_zone_id = origin_zone_id;
|
||||
buf->origin_instance_id = origin_instance_id;
|
||||
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
|
||||
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size)
|
||||
{
|
||||
LogDynamicZonesDetail("Deserializing server dz size [{}]", cereal_size);
|
||||
EQ::Util::MemoryStreamReader ss(cereal_data, cereal_size);
|
||||
cereal::BinaryInputArchive archive(ss);
|
||||
archive(*this);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template)
|
||||
{
|
||||
m_zone_id = dz_template.zone_id;
|
||||
m_zone_version = dz_template.zone_version;
|
||||
m_name = dz_template.name;
|
||||
m_min_players = dz_template.min_players;
|
||||
m_max_players = dz_template.max_players;
|
||||
m_duration = std::chrono::seconds(dz_template.duration_seconds);
|
||||
m_dz_switch_id = dz_template.dz_switch_id;
|
||||
m_compass.zone_id = dz_template.compass_zone_id;
|
||||
m_compass.x = dz_template.compass_x;
|
||||
m_compass.y = dz_template.compass_y;
|
||||
m_compass.z = dz_template.compass_z;
|
||||
m_safereturn.zone_id = dz_template.return_zone_id;
|
||||
m_safereturn.x = dz_template.return_x;
|
||||
m_safereturn.y = dz_template.return_y;
|
||||
m_safereturn.z = dz_template.return_z;
|
||||
m_safereturn.heading = dz_template.return_h;
|
||||
m_has_zonein = dz_template.override_zone_in;
|
||||
m_zonein.x = dz_template.zone_in_x;
|
||||
m_zonein.y = dz_template.zone_in_y;
|
||||
m_zonein.z = dz_template.zone_in_z;
|
||||
m_zonein.heading = dz_template.zone_in_h;
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
#ifndef COMMON_DYNAMIC_ZONE_BASE_H
|
||||
#define COMMON_DYNAMIC_ZONE_BASE_H
|
||||
|
||||
#include "eq_constants.h"
|
||||
#include "net/packet.h"
|
||||
#include "repositories/dynamic_zones_repository.h"
|
||||
#include "repositories/dynamic_zone_members_repository.h"
|
||||
#include "repositories/dynamic_zone_templates_repository.h"
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Database;
|
||||
class ServerPacket;
|
||||
|
||||
struct DynamicZoneMember
|
||||
{
|
||||
uint32_t id = 0;
|
||||
std::string name;
|
||||
DynamicZoneMemberStatus status = DynamicZoneMemberStatus::Unknown;
|
||||
|
||||
DynamicZoneMember() = default;
|
||||
DynamicZoneMember(uint32_t id, std::string name_)
|
||||
: id(id), name{std::move(name_)} {}
|
||||
DynamicZoneMember(uint32_t id, std::string name_, DynamicZoneMemberStatus status_)
|
||||
: id(id), name{std::move(name_)}, status(status_) {}
|
||||
|
||||
bool IsOnline() const { return status == DynamicZoneMemberStatus::Online ||
|
||||
status == DynamicZoneMemberStatus::InDynamicZone; }
|
||||
bool IsValid() const { return id != 0 && !name.empty(); }
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& archive)
|
||||
{
|
||||
archive(id, name, status);
|
||||
}
|
||||
};
|
||||
|
||||
struct DynamicZoneLocation
|
||||
{
|
||||
uint32_t zone_id = 0;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
float heading = 0.0f;
|
||||
|
||||
DynamicZoneLocation() = default;
|
||||
DynamicZoneLocation(uint32_t zone_id_, float x_, float y_, float z_, float heading_)
|
||||
: zone_id(zone_id_), x(x_), y(y_), z(z_), heading(heading_) {}
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& archive)
|
||||
{
|
||||
archive(zone_id, x, y, z, heading);
|
||||
}
|
||||
};
|
||||
|
||||
class DynamicZoneBase
|
||||
{
|
||||
public:
|
||||
virtual ~DynamicZoneBase() = default;
|
||||
DynamicZoneBase(const DynamicZoneBase&) = default;
|
||||
DynamicZoneBase(DynamicZoneBase&&) = default;
|
||||
DynamicZoneBase& operator=(const DynamicZoneBase&) = default;
|
||||
DynamicZoneBase& operator=(DynamicZoneBase&&) = default;
|
||||
DynamicZoneBase() = default;
|
||||
DynamicZoneBase(uint32_t dz_id) : m_id(dz_id) {}
|
||||
DynamicZoneBase(DynamicZoneType type) : m_type(type) {}
|
||||
DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry);
|
||||
|
||||
static std::string GetDynamicZoneTypeName(DynamicZoneType dz_type);
|
||||
|
||||
virtual void SetSecondsRemaining(uint32_t seconds_remaining) = 0;
|
||||
|
||||
int GetDuration() const { return static_cast<int>(m_duration.count()); }
|
||||
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
||||
uint32_t GetID() const { return m_id; }
|
||||
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); }
|
||||
uint32_t GetLeaderID() const { return m_leader.id; }
|
||||
uint32_t GetMaxPlayers() const { return m_max_players; }
|
||||
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
|
||||
uint32_t GetMinPlayers() const { return m_min_players; }
|
||||
uint32_t GetSecondsRemaining() const;
|
||||
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
|
||||
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
|
||||
uint32_t GetZoneVersion() const { return m_zone_version; }
|
||||
int GetSwitchID() const { return m_dz_switch_id; }
|
||||
DynamicZoneType GetType() const { return m_type; }
|
||||
const std::string& GetLeaderName() const { return m_leader.name; }
|
||||
const std::string& GetName() const { return m_name; }
|
||||
const std::string& GetUUID() const { return m_uuid; }
|
||||
const DynamicZoneMember& GetLeader() const { return m_leader; }
|
||||
const std::vector<DynamicZoneMember>& GetMembers() const { return m_members; }
|
||||
const DynamicZoneLocation& GetCompassLocation() const { return m_compass; }
|
||||
const DynamicZoneLocation& GetSafeReturnLocation() const { return m_safereturn; }
|
||||
const DynamicZoneLocation& GetZoneInLocation() const { return m_zonein; }
|
||||
std::chrono::system_clock::duration GetDurationRemaining() const { return m_expire_time - std::chrono::system_clock::now(); }
|
||||
|
||||
bool AddMember(const DynamicZoneMember& add_member);
|
||||
void AddMemberFromRepositoryResult(DynamicZoneMembersRepository::MemberWithName&& entry);
|
||||
uint32_t GetDatabaseMemberCount();
|
||||
DynamicZoneMember GetMemberData(uint32_t character_id);
|
||||
DynamicZoneMember GetMemberData(const std::string& character_name);
|
||||
EQ::Net::DynamicPacket GetSerializedDzPacket();
|
||||
bool HasDatabaseMember(uint32_t character_id);
|
||||
bool HasMember(uint32_t character_id);
|
||||
bool HasMember(const std::string& character_name);
|
||||
bool HasMembers() const { return !m_members.empty(); }
|
||||
bool HasZoneInLocation() const { return m_has_zonein; }
|
||||
bool IsExpired() const { return m_expire_time < std::chrono::system_clock::now(); }
|
||||
bool IsInstanceID(uint32_t instance_id) const { return (m_instance_id != 0 && m_instance_id == instance_id); }
|
||||
bool IsValid() const { return m_instance_id != 0; }
|
||||
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const { return zone_id == m_zone_id && instance_id == m_instance_id; }
|
||||
void LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size);
|
||||
void LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template);
|
||||
void RemoveAllMembers();
|
||||
bool RemoveMember(uint32_t character_id);
|
||||
bool RemoveMember(const std::string& character_name);
|
||||
bool RemoveMember(const DynamicZoneMember& remove_member);
|
||||
void SaveMembers(const std::vector<DynamicZoneMember>& members);
|
||||
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db = false);
|
||||
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
|
||||
void SetLeader(const DynamicZoneMember& leader, bool update_db = false);
|
||||
void SetMaxPlayers(uint32_t max_players) { m_max_players = max_players; }
|
||||
void SetMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||
void SetMinPlayers(uint32_t min_players) { m_min_players = min_players; }
|
||||
void SetName(const std::string& name) { m_name = name; }
|
||||
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
|
||||
void SetSwitchID(int dz_switch_id, bool update_db = false);
|
||||
void SetType(DynamicZoneType type) { m_type = type; }
|
||||
void SetUUID(std::string uuid) { m_uuid = std::move(uuid); }
|
||||
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetZoneInLocation(float x, float y, float z, float heading, bool update_db = false);
|
||||
bool SwapMember(const DynamicZoneMember& add_member, const std::string& remove_char_name);
|
||||
|
||||
protected:
|
||||
virtual uint16_t GetCurrentInstanceID() { return 0; }
|
||||
virtual uint16_t GetCurrentZoneID() { return 0; }
|
||||
virtual Database& GetDatabase() = 0;
|
||||
virtual void ProcessCompassChange(const DynamicZoneLocation& location) { m_compass = location; }
|
||||
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
|
||||
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
|
||||
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
|
||||
virtual void ProcessSetSwitchID(int dz_switch_id) { m_dz_switch_id = dz_switch_id; }
|
||||
virtual bool SendServerPacket(ServerPacket* packet) = 0;
|
||||
|
||||
void AddInternalMember(const DynamicZoneMember& member);
|
||||
uint32_t Create();
|
||||
uint32_t CreateInstance();
|
||||
void LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry);
|
||||
void RemoveInternalMember(uint32_t character_id);
|
||||
uint32_t SaveToDatabase();
|
||||
bool SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||
|
||||
std::unique_ptr<ServerPacket> CreateServerDzCreatePacket(uint16_t origin_zone_id, uint16_t origin_instance_id);
|
||||
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
|
||||
std::unique_ptr<ServerPacket> CreateServerDzSwitchIDPacket();
|
||||
std::unique_ptr<ServerPacket> CreateServerMemberAddRemovePacket(const DynamicZoneMember& member, bool removed);
|
||||
std::unique_ptr<ServerPacket> CreateServerMemberStatusPacket(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||
std::unique_ptr<ServerPacket> CreateServerMemberSwapPacket(const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member);
|
||||
std::unique_ptr<ServerPacket> CreateServerRemoveAllMembersPacket();
|
||||
|
||||
uint32_t m_id = 0;
|
||||
uint32_t m_zone_id = 0;
|
||||
uint32_t m_instance_id = 0;
|
||||
uint32_t m_zone_version = 0;
|
||||
uint32_t m_min_players = 0;
|
||||
uint32_t m_max_players = 0;
|
||||
int m_dz_switch_id = 0;
|
||||
bool m_never_expires = false;
|
||||
bool m_has_zonein = false;
|
||||
bool m_has_member_statuses = false;
|
||||
std::string m_name;
|
||||
std::string m_uuid;
|
||||
DynamicZoneMember m_leader;
|
||||
DynamicZoneType m_type{ DynamicZoneType::None };
|
||||
DynamicZoneLocation m_compass;
|
||||
DynamicZoneLocation m_safereturn;
|
||||
DynamicZoneLocation m_zonein;
|
||||
std::chrono::seconds m_duration;
|
||||
std::chrono::time_point<std::chrono::system_clock> m_start_time;
|
||||
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
|
||||
std::vector<DynamicZoneMember> m_members;
|
||||
|
||||
public:
|
||||
template<class Archive>
|
||||
void serialize(Archive& archive)
|
||||
{
|
||||
archive(
|
||||
m_id,
|
||||
m_zone_id,
|
||||
m_instance_id,
|
||||
m_zone_version,
|
||||
m_min_players,
|
||||
m_max_players,
|
||||
m_dz_switch_id,
|
||||
m_never_expires,
|
||||
m_has_zonein,
|
||||
m_has_member_statuses,
|
||||
m_name,
|
||||
m_uuid,
|
||||
m_leader,
|
||||
m_type,
|
||||
m_compass,
|
||||
m_safereturn,
|
||||
m_zonein,
|
||||
m_duration,
|
||||
m_start_time,
|
||||
m_expire_time,
|
||||
m_members
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
+4
-500
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -18,49 +18,9 @@
|
||||
*/
|
||||
|
||||
#include "emu_constants.h"
|
||||
#include "bodytypes.h"
|
||||
#include "data_verification.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
#include "languages.h"
|
||||
#include "rulesys.h"
|
||||
|
||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
static const int16 local_array[] = {
|
||||
POSSESSIONS_SIZE,
|
||||
BANK_SIZE,
|
||||
SHARED_BANK_SIZE,
|
||||
TRADE_SIZE,
|
||||
WORLD_SIZE,
|
||||
LIMBO_SIZE,
|
||||
TRIBUTE_SIZE,
|
||||
TROPHY_TRIBUTE_SIZE,
|
||||
GUILD_TRIBUTE_SIZE,
|
||||
MERCHANT_SIZE,
|
||||
DELETED_SIZE,
|
||||
CORPSE_SIZE,
|
||||
BAZAAR_SIZE,
|
||||
INSPECT_SIZE,
|
||||
REAL_ESTATE_SIZE,
|
||||
VIEW_MOD_PC_SIZE,
|
||||
VIEW_MOD_BANK_SIZE,
|
||||
VIEW_MOD_SHARED_BANK_SIZE,
|
||||
VIEW_MOD_LIMBO_SIZE,
|
||||
ALT_STORAGE_SIZE,
|
||||
ARCHIVED_SIZE,
|
||||
MAIL_SIZE,
|
||||
GUILD_TROPHY_TRIBUTE_SIZE,
|
||||
KRONO_SIZE,
|
||||
OTHER_SIZE,
|
||||
};
|
||||
|
||||
if (inv_type < TYPE_BEGIN || inv_type > TYPE_END)
|
||||
return INULL;
|
||||
|
||||
return local_array[inv_type];
|
||||
}
|
||||
|
||||
const char* EQ::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||
const char* EQEmu::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||
switch (category_id) {
|
||||
case catVideo:
|
||||
return "Video";
|
||||
@@ -92,7 +52,7 @@ const char* EQ::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||
}
|
||||
}
|
||||
|
||||
EQ::bug::CategoryID EQ::bug::CategoryNameToCategoryID(const char* category_name) {
|
||||
EQEmu::bug::CategoryID EQEmu::bug::CategoryNameToCategoryID(const char* category_name) {
|
||||
if (!category_name)
|
||||
return catOther;
|
||||
|
||||
@@ -120,462 +80,6 @@ EQ::bug::CategoryID EQ::bug::CategoryNameToCategoryID(const char* category_name)
|
||||
return catLoNTCG;
|
||||
if (!strcmp(category_name, "Mercenaries"))
|
||||
return catMercenaries;
|
||||
|
||||
|
||||
return catOther;
|
||||
}
|
||||
|
||||
const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
||||
switch (stance_type) {
|
||||
case stanceUnknown:
|
||||
return "Unknown";
|
||||
case stancePassive:
|
||||
return "Passive";
|
||||
case stanceBalanced:
|
||||
return "Balanced";
|
||||
case stanceEfficient:
|
||||
return "Efficient";
|
||||
case stanceReactive:
|
||||
return "Reactive";
|
||||
case stanceAggressive:
|
||||
return "Aggressive";
|
||||
case stanceAssist:
|
||||
return "Assist";
|
||||
case stanceBurn:
|
||||
return "Burn";
|
||||
case stanceEfficient2:
|
||||
return "Efficient2";
|
||||
case stanceBurnAE:
|
||||
return "BurnAE";
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
||||
return (stance_type - EQ::constants::stancePassive);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
||||
{
|
||||
static const std::map<int, std::string> language_map = {
|
||||
{ LANG_COMMON_TONGUE, "Common Tongue" },
|
||||
{ LANG_BARBARIAN, "Barbarian" },
|
||||
{ LANG_ERUDIAN, "Erudian" },
|
||||
{ LANG_ELVISH, "Elvish" },
|
||||
{ LANG_DARK_ELVISH, "Dark Elvish" },
|
||||
{ LANG_DWARVISH, "Dwarvish" },
|
||||
{ LANG_TROLL, "Troll" },
|
||||
{ LANG_OGRE, "Ogre" },
|
||||
{ LANG_GNOMISH, "Gnomish" },
|
||||
{ LANG_HALFLING, "Halfling" },
|
||||
{ LANG_THIEVES_CANT, "Thieves Cant" },
|
||||
{ LANG_OLD_ERUDIAN, "Old Erudian" },
|
||||
{ LANG_ELDER_ELVISH, "Elder Elvish" },
|
||||
{ LANG_FROGLOK, "Froglok" },
|
||||
{ LANG_GOBLIN, "Goblin" },
|
||||
{ LANG_GNOLL, "Gnoll" },
|
||||
{ LANG_COMBINE_TONGUE, "Combine Tongue" },
|
||||
{ LANG_ELDER_TEIRDAL, "Elder Teirdal" },
|
||||
{ LANG_LIZARDMAN, "Lizardman" },
|
||||
{ LANG_ORCISH, "Orcish" },
|
||||
{ LANG_FAERIE, "Faerie" },
|
||||
{ LANG_DRAGON, "Dragon" },
|
||||
{ LANG_ELDER_DRAGON, "Elder Dragon" },
|
||||
{ LANG_DARK_SPEECH, "Dark Speech" },
|
||||
{ LANG_VAH_SHIR, "Vah Shir" },
|
||||
{ LANG_ALARAN, "Alaran" },
|
||||
{ LANG_HADAL, "Hadal" },
|
||||
{ LANG_UNKNOWN, "Unknown" }
|
||||
};
|
||||
|
||||
return language_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetLanguageName(int language_id)
|
||||
{
|
||||
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
|
||||
{
|
||||
static const std::map<uint32, std::string> ldon_theme_map = {
|
||||
{ LDoNThemes::Unused, "Unused" },
|
||||
{ LDoNThemes::GUK, "Deepest Guk" },
|
||||
{ LDoNThemes::MIR, "Miragul's Menagerie" },
|
||||
{ LDoNThemes::MMC, "Mistmoore Catacombs" },
|
||||
{ LDoNThemes::RUJ, "Rujarkian Hills" },
|
||||
{ LDoNThemes::TAK, "Takish-Hiz" },
|
||||
};
|
||||
|
||||
return ldon_theme_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
|
||||
{
|
||||
if (EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
|
||||
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
||||
{
|
||||
static const std::map<int8, std::string> flymode_map = {
|
||||
{ GravityBehavior::Ground, "Ground" },
|
||||
{ GravityBehavior::Flying, "Flying" },
|
||||
{ GravityBehavior::Levitating, "Levitating" },
|
||||
{ GravityBehavior::Water, "Water" },
|
||||
{ GravityBehavior::Floating, "Floating" },
|
||||
{ GravityBehavior::LevitateWhileRunning, "Levitating While Running" },
|
||||
};
|
||||
|
||||
return flymode_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
||||
{
|
||||
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
|
||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
|
||||
{
|
||||
static const std::map<bodyType, std::string> bodytype_map = {
|
||||
{ BT_Humanoid, "Humanoid" },
|
||||
{ BT_Lycanthrope, "Lycanthrope" },
|
||||
{ BT_Undead, "Undead" },
|
||||
{ BT_Giant, "Giant" },
|
||||
{ BT_Construct, "Construct" },
|
||||
{ BT_Extraplanar, "Extraplanar" },
|
||||
{ BT_Magical, "Magical" },
|
||||
{ BT_SummonedUndead, "Summoned Undead" },
|
||||
{ BT_RaidGiant, "Raid Giant" },
|
||||
{ BT_RaidColdain, "Raid Coldain" },
|
||||
{ BT_NoTarget, "Untargetable" },
|
||||
{ BT_Vampire, "Vampire" },
|
||||
{ BT_Atenha_Ra, "Aten Ha Ra" },
|
||||
{ BT_Greater_Akheva, "Greater Akheva" },
|
||||
{ BT_Khati_Sha, "Khati Sha" },
|
||||
{ BT_Seru, "Seru" },
|
||||
{ BT_Grieg_Veneficus, "Grieg Veneficus" },
|
||||
{ BT_Draz_Nurakk, "Draz Nurakk" },
|
||||
{ BT_Zek, "Zek" },
|
||||
{ BT_Luggald, "Luggald" },
|
||||
{ BT_Animal, "Animal" },
|
||||
{ BT_Insect, "Insect" },
|
||||
{ BT_Monster, "Monster" },
|
||||
{ BT_Summoned, "Summoned" },
|
||||
{ BT_Plant, "Plant" },
|
||||
{ BT_Dragon, "Dragon" },
|
||||
{ BT_Summoned2, "Summoned 2" },
|
||||
{ BT_Summoned3, "Summoned 3" },
|
||||
{ BT_Dragon2, "Dragon 2" },
|
||||
{ BT_VeliousDragon, "Velious Dragon" },
|
||||
{ BT_Familiar, "Familiar" },
|
||||
{ BT_Dragon3, "Dragon 3" },
|
||||
{ BT_Boxes, "Boxes" },
|
||||
{ BT_Muramite, "Muramite" },
|
||||
{ BT_NoTarget2, "Untargetable 2" },
|
||||
{ BT_SwarmPet, "Swarm Pet" },
|
||||
{ BT_MonsterSummon, "Monster Summon" },
|
||||
{ BT_InvisMan, "Invisible Man" },
|
||||
{ BT_Special, "Special" },
|
||||
};
|
||||
|
||||
return bodytype_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
|
||||
{
|
||||
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
|
||||
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> account_status_map = {
|
||||
{ AccountStatus::Player, "Player" },
|
||||
{ AccountStatus::Steward, "Steward" },
|
||||
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
|
||||
{ AccountStatus::Guide, "Guide" },
|
||||
{ AccountStatus::QuestTroupe, "Quest Troupe" },
|
||||
{ AccountStatus::SeniorGuide, "Senior Guide" },
|
||||
{ AccountStatus::GMTester, "GM Tester" },
|
||||
{ AccountStatus::EQSupport, "EQ Support" },
|
||||
{ AccountStatus::GMStaff, "GM Staff" },
|
||||
{ AccountStatus::GMAdmin, "GM Admin" },
|
||||
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
|
||||
{ AccountStatus::QuestMaster, "Quest Master" },
|
||||
{ AccountStatus::GMAreas, "GM Areas" },
|
||||
{ AccountStatus::GMCoder, "GM Coder" },
|
||||
{ AccountStatus::GMMgmt, "GM Mgmt" },
|
||||
{ AccountStatus::GMImpossible, "GM Impossible" },
|
||||
{ AccountStatus::Max, "GM Max" }
|
||||
};
|
||||
|
||||
return account_status_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
|
||||
{
|
||||
for (
|
||||
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
|
||||
status_level != EQ::constants::GetAccountStatusMap().rend();
|
||||
++status_level
|
||||
) {
|
||||
if (account_status >= status_level->first) {
|
||||
return status_level->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> consider_level_map = {
|
||||
{ ConsiderLevel::Ally, "Ally" },
|
||||
{ ConsiderLevel::Warmly, "Warmly" },
|
||||
{ ConsiderLevel::Kindly, "Kindly" },
|
||||
{ ConsiderLevel::Amiably, "Amiably" },
|
||||
{ ConsiderLevel::Indifferently, "Indifferently" },
|
||||
{ ConsiderLevel::Apprehensively, "Apprehensively" },
|
||||
{ ConsiderLevel::Dubiously, "Dubiously" },
|
||||
{ ConsiderLevel::Threateningly, "Threateningly" },
|
||||
{ ConsiderLevel::Scowls, "Scowls" }
|
||||
};
|
||||
|
||||
return consider_level_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
|
||||
{
|
||||
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
|
||||
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> damage_type_map = {
|
||||
{ EnvironmentalDamage::Lava, "Lava" },
|
||||
{ EnvironmentalDamage::Drowning, "Drowning" },
|
||||
{ EnvironmentalDamage::Falling, "Falling" },
|
||||
{ EnvironmentalDamage::Trap, "Trap" }
|
||||
};
|
||||
|
||||
return damage_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
|
||||
{
|
||||
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
|
||||
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> stuck_behavior_map = {
|
||||
{ StuckBehavior::RunToTarget, "Run To Target" },
|
||||
{ StuckBehavior::WarpToTarget, "Warp To Target" },
|
||||
{ StuckBehavior::TakeNoAction, "Take No Action" },
|
||||
{ StuckBehavior::EvadeCombat, "Evade Combat" }
|
||||
};
|
||||
|
||||
return stuck_behavior_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
|
||||
{
|
||||
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
|
||||
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> spawn_animation_map = {
|
||||
{ SpawnAnimations::Standing, "Standing" },
|
||||
{ SpawnAnimations::Sitting, "Sitting" },
|
||||
{ SpawnAnimations::Crouching, "Crouching" },
|
||||
{ SpawnAnimations::Laying, "Laying" },
|
||||
{ SpawnAnimations::Looting, "Looting" }
|
||||
};
|
||||
|
||||
return spawn_animation_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
||||
{
|
||||
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
|
||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
||||
{
|
||||
static const std::map<int, std::string> object_type_map = {
|
||||
{ ObjectTypes::SmallBag, "Small Bag" },
|
||||
{ ObjectTypes::LargeBag, "Large Bag" },
|
||||
{ ObjectTypes::Quiver, "Quiver" },
|
||||
{ ObjectTypes::BeltPouch, "Belt Pouch" },
|
||||
{ ObjectTypes::WristPouch, "Wrist Pouch" },
|
||||
{ ObjectTypes::Backpack, "Backpack" },
|
||||
{ ObjectTypes::SmallChest, "Small Chest" },
|
||||
{ ObjectTypes::LargeChest, "Large Chest" },
|
||||
{ ObjectTypes::Bandolier, "Bandolier" },
|
||||
{ ObjectTypes::Medicine, "Medicine" },
|
||||
{ ObjectTypes::Tinkering, "Tinkering" },
|
||||
{ ObjectTypes::Lexicon, "Lexicon" },
|
||||
{ ObjectTypes::PoisonMaking, "Mortar and Pestle" },
|
||||
{ ObjectTypes::Quest, "Quest" },
|
||||
{ ObjectTypes::MixingBowl, "Mixing Bowl" },
|
||||
{ ObjectTypes::Baking, "Baking" },
|
||||
{ ObjectTypes::Tailoring, "Tailoring" },
|
||||
{ ObjectTypes::Blacksmithing, "Blacksmithing" },
|
||||
{ ObjectTypes::Fletching, "Fletching" },
|
||||
{ ObjectTypes::Brewing, "Brewing" },
|
||||
{ ObjectTypes::JewelryMaking, "Jewelry Making" },
|
||||
{ ObjectTypes::Pottery, "Pottery" },
|
||||
{ ObjectTypes::Kiln, "Kiln" },
|
||||
{ ObjectTypes::KeyMaker, "Key Maker" },
|
||||
{ ObjectTypes::ResearchWIZ, "Lexicon" },
|
||||
{ ObjectTypes::ResearchMAG, "Lexicon" },
|
||||
{ ObjectTypes::ResearchNEC, "Lexicon" },
|
||||
{ ObjectTypes::ResearchENC, "Lexicon" },
|
||||
{ ObjectTypes::Unknown, "Unknown" },
|
||||
{ ObjectTypes::ResearchPractice, "Lexicon" },
|
||||
{ ObjectTypes::Alchemy, "Alchemy" },
|
||||
{ ObjectTypes::HighElfForge, "High Elf Forge" },
|
||||
{ ObjectTypes::DarkElfForge, "Dark Elf Forge" },
|
||||
{ ObjectTypes::OgreForge, "Ogre Forge" },
|
||||
{ ObjectTypes::DwarfForge, "Dwarf Forge" },
|
||||
{ ObjectTypes::GnomeForge, "Gnome Forge" },
|
||||
{ ObjectTypes::BarbarianForge, "Barbarian Forge" },
|
||||
{ ObjectTypes::IksarForge, "Iksar Forge" },
|
||||
{ ObjectTypes::HumanForgeOne, "Human Forge" },
|
||||
{ ObjectTypes::HumanForgeTwo, "Human Forge" },
|
||||
{ ObjectTypes::HalflingTailoringOne, "Halfling Tailoring" },
|
||||
{ ObjectTypes::HalflingTailoringTwo, "Halfling Tailoring" },
|
||||
{ ObjectTypes::EruditeTailoring, "Erudite Tailoring" },
|
||||
{ ObjectTypes::WoodElfTailoring, "Wood Elf Tailoring" },
|
||||
{ ObjectTypes::WoodElfFletching, "Wood Elf Fletching" },
|
||||
{ ObjectTypes::IksarPottery, "Iksar Pottery" },
|
||||
{ ObjectTypes::Fishing, "Fishing" },
|
||||
{ ObjectTypes::TrollForge, "Troll Forge" },
|
||||
{ ObjectTypes::WoodElfForge, "Wood Elf Forge" },
|
||||
{ ObjectTypes::HalflingForge, "Halfling Forge" },
|
||||
{ ObjectTypes::EruditeForge, "Erudite Forge" },
|
||||
{ ObjectTypes::Merchant, "Merchant" },
|
||||
{ ObjectTypes::FroglokForge, "Froglok Forge" },
|
||||
{ ObjectTypes::Augmenter, "Augmenter" },
|
||||
{ ObjectTypes::Churn, "Churn" },
|
||||
{ ObjectTypes::TransformationMold, "Transformation Mold" },
|
||||
{ ObjectTypes::DetransformationMold, "Detransformation Mold" },
|
||||
{ ObjectTypes::Unattuner, "Unattuner" },
|
||||
{ ObjectTypes::TradeskillBag, "Tradeskill Bag" },
|
||||
{ ObjectTypes::CollectibleBag, "Collectible Bag" },
|
||||
{ ObjectTypes::NoDeposit, "No Deposit" }
|
||||
};
|
||||
|
||||
return object_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetObjectTypeName(int object_type)
|
||||
{
|
||||
if (EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> weather_type_map = {
|
||||
{WeatherTypes::None, "None"},
|
||||
{WeatherTypes::Raining, "Raining"},
|
||||
{WeatherTypes::Snowing, "Snowing"}
|
||||
};
|
||||
|
||||
return weather_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
|
||||
{
|
||||
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> emote_event_type_map = {
|
||||
{ EmoteEventTypes::LeaveCombat, "Leave Combat" },
|
||||
{ EmoteEventTypes::EnterCombat, "Enter Combat" },
|
||||
{ EmoteEventTypes::OnDeath, "On Death" },
|
||||
{ EmoteEventTypes::AfterDeath, "After Death" },
|
||||
{ EmoteEventTypes::Hailed, "Hailed" },
|
||||
{ EmoteEventTypes::KilledPC, "Killed PC" },
|
||||
{ EmoteEventTypes::KilledNPC, "Killed NPC" },
|
||||
{ EmoteEventTypes::OnSpawn, "On Spawn" },
|
||||
{ EmoteEventTypes::OnDespawn, "On Despawn" }
|
||||
};
|
||||
|
||||
return emote_event_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
||||
{
|
||||
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> emote_type_map = {
|
||||
{ EmoteTypes::Emote, "Emote" },
|
||||
{ EmoteTypes::Shout, "Shout" },
|
||||
{ EmoteTypes::Proximity, "Proximity" }
|
||||
};
|
||||
|
||||
return emote_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
||||
{
|
||||
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
+116
-519
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,439 +21,115 @@
|
||||
#define COMMON_EMU_CONSTANTS_H
|
||||
|
||||
#include "eq_limits.h"
|
||||
#include "emu_legacy.h"
|
||||
#include "emu_versions.h"
|
||||
#include "bodytypes.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// local definitions are the result of using hybrid-client or server-only values and methods
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
using RoF2::IINVALID;
|
||||
using RoF2::INULL;
|
||||
namespace inventory {
|
||||
//using namespace RoF2::invtype;
|
||||
//using namespace RoF2::invslot;
|
||||
//using namespace RoF2::invbag;
|
||||
//using namespace RoF2::invaug;
|
||||
|
||||
namespace invtype {
|
||||
using namespace RoF2::invtype::enum_;
|
||||
enum : int16 { typeInvalid = -1, slotInvalid = -1, containerInvalid = -1, socketInvalid = -1 }; // temporary
|
||||
enum : int16 { typeBegin = 0, slotBegin = 0, containerBegin = 0, socketBegin = 0 }; // temporary
|
||||
|
||||
using RoF2::invtype::POSSESSIONS_SIZE;
|
||||
using RoF2::invtype::BANK_SIZE;
|
||||
using RoF2::invtype::SHARED_BANK_SIZE;
|
||||
using RoF2::invtype::TRADE_SIZE;
|
||||
using RoF2::invtype::WORLD_SIZE;
|
||||
using RoF2::invtype::LIMBO_SIZE;
|
||||
using RoF2::invtype::TRIBUTE_SIZE;
|
||||
using RoF2::invtype::TROPHY_TRIBUTE_SIZE;
|
||||
using RoF2::invtype::GUILD_TRIBUTE_SIZE;
|
||||
using RoF2::invtype::MERCHANT_SIZE;
|
||||
using RoF2::invtype::DELETED_SIZE;
|
||||
using RoF2::invtype::CORPSE_SIZE;
|
||||
using RoF2::invtype::BAZAAR_SIZE;
|
||||
using RoF2::invtype::INSPECT_SIZE;
|
||||
using RoF2::invtype::REAL_ESTATE_SIZE;
|
||||
using RoF2::invtype::VIEW_MOD_PC_SIZE;
|
||||
using RoF2::invtype::VIEW_MOD_BANK_SIZE;
|
||||
using RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE;
|
||||
using RoF2::invtype::VIEW_MOD_LIMBO_SIZE;
|
||||
using RoF2::invtype::ALT_STORAGE_SIZE;
|
||||
using RoF2::invtype::ARCHIVED_SIZE;
|
||||
using RoF2::invtype::MAIL_SIZE;
|
||||
using RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE;
|
||||
using RoF2::invtype::KRONO_SIZE;
|
||||
using RoF2::invtype::OTHER_SIZE;
|
||||
enum PossessionsSlots : int16 { // temporary
|
||||
slotCharm = 0,
|
||||
slotEar1,
|
||||
slotHead,
|
||||
slotFace,
|
||||
slotEar2,
|
||||
slotNeck, // 5
|
||||
slotShoulders,
|
||||
slotArms,
|
||||
slotBack,
|
||||
slotWrist1,
|
||||
slotWrist2, // 10
|
||||
slotRange,
|
||||
slotHands,
|
||||
slotPrimary,
|
||||
slotSecondary,
|
||||
slotFinger1, // 15
|
||||
slotFinger2,
|
||||
slotChest,
|
||||
slotLegs,
|
||||
slotFeet,
|
||||
slotWaist, // 20
|
||||
slotPowerSource = 9999,
|
||||
slotAmmo = 21,
|
||||
slotGeneral1,
|
||||
slotGeneral2,
|
||||
slotGeneral3,
|
||||
slotGeneral4, // 25
|
||||
slotGeneral5,
|
||||
slotGeneral6,
|
||||
slotGeneral7,
|
||||
slotGeneral8,
|
||||
slotCursor, // 30
|
||||
slotCount
|
||||
};
|
||||
|
||||
using Titanium::invtype::TRADE_NPC_SIZE;
|
||||
enum InventoryTypes : int16 { // temporary
|
||||
typePossessions = 0,
|
||||
typeBank,
|
||||
typeSharedBank,
|
||||
typeTrade,
|
||||
typeWorld,
|
||||
typeLimbo, // 5
|
||||
typeTribute,
|
||||
typeTrophyTribute,
|
||||
typeGuildTribute,
|
||||
typeMerchant,
|
||||
typeDeleted, // 10
|
||||
typeCorpse,
|
||||
typeBazaar,
|
||||
typeInspect,
|
||||
typeRealEstate,
|
||||
typeViewMODPC, // 15
|
||||
typeViewMODBank,
|
||||
typeViewMODSharedBank,
|
||||
typeViewMODLimbo,
|
||||
typeAltStorage,
|
||||
typeArchived, // 20
|
||||
typeMail,
|
||||
typeGuildTrophyTribute,
|
||||
typeKrono,
|
||||
typeOther,
|
||||
typeCount
|
||||
};
|
||||
|
||||
using RoF2::invtype::TYPE_INVALID;
|
||||
using RoF2::invtype::TYPE_BEGIN;
|
||||
using RoF2::invtype::TYPE_END;
|
||||
using RoF2::invtype::TYPE_COUNT;
|
||||
static int16 SlotCount(int16 type_index) { return 0; } // temporary
|
||||
|
||||
int16 GetInvTypeSize(int16 inv_type);
|
||||
using RoF2::invtype::GetInvTypeName;
|
||||
const int16 ContainerCount = 10; // temporary
|
||||
const int16 SocketCount = 6; // temporary
|
||||
|
||||
} // namespace invtype
|
||||
|
||||
namespace DevTools {
|
||||
const int32 GM_ACCOUNT_STATUS_LEVEL = 150;
|
||||
}
|
||||
|
||||
namespace popupresponse {
|
||||
const int32 SERVER_INTERNAL_USE_BASE = 2000000000;
|
||||
const int32 MOB_INFO_DISMISS = 2000000001;
|
||||
}
|
||||
|
||||
namespace invslot {
|
||||
using namespace RoF2::invslot::enum_;
|
||||
|
||||
using RoF2::invslot::SLOT_INVALID;
|
||||
using RoF2::invslot::SLOT_BEGIN;
|
||||
|
||||
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
|
||||
|
||||
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
|
||||
|
||||
using RoF2::invslot::POSSESSIONS_BEGIN;
|
||||
using RoF2::invslot::POSSESSIONS_END;
|
||||
using RoF2::invslot::POSSESSIONS_COUNT;
|
||||
|
||||
using RoF2::invslot::EQUIPMENT_BEGIN;
|
||||
using RoF2::invslot::EQUIPMENT_END;
|
||||
using RoF2::invslot::EQUIPMENT_COUNT;
|
||||
|
||||
using RoF2::invslot::GENERAL_BEGIN;
|
||||
using RoF2::invslot::GENERAL_END;
|
||||
using RoF2::invslot::GENERAL_COUNT;
|
||||
|
||||
using RoF2::invslot::BONUS_BEGIN;
|
||||
using RoF2::invslot::BONUS_STAT_END;
|
||||
using RoF2::invslot::BONUS_SKILL_END;
|
||||
|
||||
using Titanium::invslot::BANK_BEGIN;
|
||||
using SoF::invslot::BANK_END;
|
||||
|
||||
using Titanium::invslot::SHARED_BANK_BEGIN;
|
||||
using Titanium::invslot::SHARED_BANK_END;
|
||||
|
||||
using Titanium::invslot::TRADE_BEGIN;
|
||||
using Titanium::invslot::TRADE_END;
|
||||
|
||||
using Titanium::invslot::TRADE_NPC_END;
|
||||
|
||||
using Titanium::invslot::WORLD_BEGIN;
|
||||
using Titanium::invslot::WORLD_END;
|
||||
|
||||
using Titanium::invslot::TRIBUTE_BEGIN;
|
||||
using Titanium::invslot::TRIBUTE_END;
|
||||
|
||||
using Titanium::invslot::GUILD_TRIBUTE_BEGIN;
|
||||
using Titanium::invslot::GUILD_TRIBUTE_END;
|
||||
|
||||
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
|
||||
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
|
||||
|
||||
using RoF2::invslot::EQUIPMENT_BITMASK;
|
||||
using RoF2::invslot::GENERAL_BITMASK;
|
||||
using RoF2::invslot::CURSOR_BITMASK;
|
||||
using RoF2::invslot::POSSESSIONS_BITMASK;
|
||||
using RoF2::invslot::CORPSE_BITMASK;
|
||||
|
||||
using RoF2::invslot::GetInvPossessionsSlotName;
|
||||
using RoF2::invslot::GetInvSlotName;
|
||||
|
||||
} // namespace invslot
|
||||
|
||||
namespace invbag {
|
||||
using Titanium::invbag::SLOT_INVALID;
|
||||
using Titanium::invbag::SLOT_BEGIN;
|
||||
using Titanium::invbag::SLOT_END;
|
||||
using Titanium::invbag::SLOT_COUNT;
|
||||
|
||||
using Titanium::invbag::GENERAL_BAGS_BEGIN;
|
||||
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
|
||||
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
|
||||
|
||||
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
|
||||
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
|
||||
|
||||
const int16 CURSOR_BAG_BEGIN = 351;
|
||||
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
|
||||
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::BANK_BAGS_BEGIN;
|
||||
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
|
||||
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
|
||||
|
||||
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
|
||||
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::SHARED_BANK_BAGS_BEGIN;
|
||||
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
|
||||
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::TRADE_BAGS_BEGIN;
|
||||
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
|
||||
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
|
||||
|
||||
using Titanium::invbag::GetInvBagIndexName;
|
||||
|
||||
} // namespace invbag
|
||||
|
||||
namespace invaug {
|
||||
using RoF2::invaug::SOCKET_INVALID;
|
||||
using RoF2::invaug::SOCKET_BEGIN;
|
||||
using RoF2::invaug::SOCKET_END;
|
||||
using RoF2::invaug::SOCKET_COUNT;
|
||||
|
||||
using RoF2::invaug::GetInvAugIndexName;
|
||||
|
||||
} // namespace invaug
|
||||
} /*inventory*/
|
||||
|
||||
namespace constants {
|
||||
const EQ::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQ::versions::ClientVersion::Titanium;
|
||||
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
|
||||
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
|
||||
|
||||
using RoF2::constants::EXPANSION;
|
||||
using RoF2::constants::EXPANSION_BIT;
|
||||
using RoF2::constants::EXPANSIONS_MASK;
|
||||
const size_t SayLinkOpenerSize = 1;
|
||||
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
|
||||
const size_t SayLinkTextSize = 256; // this may be varied until it breaks something (tested:374) - the others are constant
|
||||
const size_t SayLinkCloserSize = 1;
|
||||
const size_t SayLinkMaximumSize = (SayLinkOpenerSize + SayLinkBodySize + SayLinkTextSize + SayLinkCloserSize);
|
||||
|
||||
using RoF2::constants::CHARACTER_CREATION_LIMIT;
|
||||
|
||||
const size_t SAY_LINK_OPENER_SIZE = 1;
|
||||
using RoF2::constants::SAY_LINK_BODY_SIZE;
|
||||
const size_t SAY_LINK_TEXT_SIZE = 256; // this may be varied until it breaks something (tested:374) - the others are constant
|
||||
const size_t SAY_LINK_CLOSER_SIZE = 1;
|
||||
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
|
||||
|
||||
enum StanceType : int {
|
||||
stanceUnknown = 0,
|
||||
stancePassive,
|
||||
stanceBalanced,
|
||||
stanceEfficient,
|
||||
stanceReactive,
|
||||
stanceAggressive,
|
||||
stanceAssist,
|
||||
stanceBurn,
|
||||
stanceEfficient2,
|
||||
stanceBurnAE
|
||||
};
|
||||
|
||||
enum BotSpellIDs : int {
|
||||
Warrior = 3001,
|
||||
Cleric,
|
||||
Paladin,
|
||||
Ranger,
|
||||
Shadowknight,
|
||||
Druid,
|
||||
Monk,
|
||||
Bard,
|
||||
Rogue,
|
||||
Shaman,
|
||||
Necromancer,
|
||||
Wizard,
|
||||
Magician,
|
||||
Enchanter,
|
||||
Beastlord,
|
||||
Berserker
|
||||
};
|
||||
|
||||
enum GravityBehavior : int8 {
|
||||
Ground,
|
||||
Flying,
|
||||
Levitating,
|
||||
Water,
|
||||
Floating,
|
||||
LevitateWhileRunning
|
||||
};
|
||||
|
||||
enum EnvironmentalDamage : uint8 {
|
||||
Lava = 250,
|
||||
Drowning,
|
||||
Falling,
|
||||
Trap
|
||||
};
|
||||
|
||||
enum StuckBehavior : uint8 {
|
||||
RunToTarget,
|
||||
WarpToTarget,
|
||||
TakeNoAction,
|
||||
EvadeCombat
|
||||
};
|
||||
|
||||
enum SpawnAnimations : uint8 {
|
||||
Standing,
|
||||
Sitting,
|
||||
Crouching,
|
||||
Laying,
|
||||
Looting
|
||||
};
|
||||
|
||||
enum ObjectTypes : int {
|
||||
SmallBag,
|
||||
LargeBag,
|
||||
Quiver,
|
||||
BeltPouch,
|
||||
WristPouch,
|
||||
Backpack,
|
||||
SmallChest,
|
||||
LargeChest,
|
||||
Bandolier,
|
||||
Medicine,
|
||||
Tinkering,
|
||||
Lexicon,
|
||||
PoisonMaking,
|
||||
Quest,
|
||||
MixingBowl,
|
||||
Baking,
|
||||
Tailoring,
|
||||
Blacksmithing,
|
||||
Fletching,
|
||||
Brewing,
|
||||
JewelryMaking,
|
||||
Pottery,
|
||||
Kiln,
|
||||
KeyMaker,
|
||||
ResearchWIZ,
|
||||
ResearchMAG,
|
||||
ResearchNEC,
|
||||
ResearchENC,
|
||||
Unknown,
|
||||
ResearchPractice,
|
||||
Alchemy,
|
||||
HighElfForge,
|
||||
DarkElfForge,
|
||||
OgreForge,
|
||||
DwarfForge,
|
||||
GnomeForge,
|
||||
BarbarianForge,
|
||||
IksarForge,
|
||||
HumanForgeOne,
|
||||
HumanForgeTwo,
|
||||
HalflingTailoringOne,
|
||||
HalflingTailoringTwo,
|
||||
EruditeTailoring,
|
||||
WoodElfTailoring,
|
||||
WoodElfFletching,
|
||||
IksarPottery,
|
||||
Fishing,
|
||||
TrollForge,
|
||||
WoodElfForge,
|
||||
HalflingForge,
|
||||
EruditeForge,
|
||||
Merchant,
|
||||
FroglokForge,
|
||||
Augmenter,
|
||||
Churn,
|
||||
TransformationMold,
|
||||
DetransformationMold,
|
||||
Unattuner,
|
||||
TradeskillBag,
|
||||
CollectibleBag,
|
||||
NoDeposit
|
||||
};
|
||||
|
||||
enum WeatherTypes : uint8 {
|
||||
None,
|
||||
Raining,
|
||||
Snowing
|
||||
};
|
||||
|
||||
enum EmoteEventTypes : uint8 {
|
||||
LeaveCombat,
|
||||
EnterCombat,
|
||||
OnDeath,
|
||||
AfterDeath,
|
||||
Hailed,
|
||||
KilledPC,
|
||||
KilledNPC,
|
||||
OnSpawn,
|
||||
OnDespawn
|
||||
};
|
||||
|
||||
enum EmoteTypes : uint8 {
|
||||
Emote,
|
||||
Shout,
|
||||
Proximity
|
||||
};
|
||||
|
||||
const char *GetStanceName(StanceType stance_type);
|
||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||
|
||||
extern const std::map<int, std::string>& GetLanguageMap();
|
||||
std::string GetLanguageName(int language_id);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
||||
std::string GetLDoNThemeName(uint32 theme_id);
|
||||
|
||||
extern const std::map<int8, std::string>& GetFlyModeMap();
|
||||
std::string GetFlyModeName(int8 flymode_id);
|
||||
|
||||
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
|
||||
std::string GetBodyTypeName(bodyType bodytype_id);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetAccountStatusMap();
|
||||
std::string GetAccountStatusName(uint8 account_status);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
||||
std::string GetConsiderLevelName(uint8 consider_level);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetEnvironmentalDamageMap();
|
||||
std::string GetEnvironmentalDamageName(uint8 damage_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetStuckBehaviorMap();
|
||||
std::string GetStuckBehaviorName(uint8 behavior_id);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
|
||||
std::string GetSpawnAnimationName(uint8 animation_id);
|
||||
|
||||
extern const std::map<int, std::string>& GetObjectTypeMap();
|
||||
std::string GetObjectTypeName(int object_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
|
||||
std::string GetWeatherTypeName(uint8 weather_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetEmoteEventTypeMap();
|
||||
std::string GetEmoteEventTypeName(uint8 emote_event_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
||||
std::string GetEmoteTypeName(uint8 emote_type);
|
||||
|
||||
const int STANCE_TYPE_FIRST = stancePassive;
|
||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||
const int LongBuffs = RoF2::constants::LongBuffs;
|
||||
const int ShortBuffs = RoF2::constants::ShortBuffs;
|
||||
const int DiscBuffs = RoF2::constants::DiscBuffs;
|
||||
const int TotalBuffs = RoF2::constants::TotalBuffs;
|
||||
const int NPCBuffs = RoF2::constants::NPCBuffs;
|
||||
const int PetBuffs = RoF2::constants::PetBuffs;
|
||||
const int MercBuffs = RoF2::constants::MercBuffs;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace profile {
|
||||
using RoF2::profile::BANDOLIERS_SIZE;
|
||||
using RoF2::profile::BANDOLIER_ITEM_COUNT;
|
||||
|
||||
using RoF2::profile::POTION_BELT_SIZE;
|
||||
|
||||
using RoF2::profile::SKILL_ARRAY_SIZE;
|
||||
|
||||
} // namespace profile
|
||||
|
||||
namespace behavior {
|
||||
using RoF2::behavior::CoinHasWeight;
|
||||
|
||||
} // namespace behavior
|
||||
|
||||
namespace spells {
|
||||
enum class CastingSlot : uint32 { // hybrid declaration
|
||||
Gem1 = 0,
|
||||
Gem2 = 1,
|
||||
Gem3 = 2,
|
||||
Gem4 = 3,
|
||||
Gem5 = 4,
|
||||
Gem6 = 5,
|
||||
Gem7 = 6,
|
||||
Gem8 = 7,
|
||||
Gem9 = 8,
|
||||
Gem10 = 9,
|
||||
Gem11 = 10,
|
||||
Gem12 = 11,
|
||||
MaxGems = 12,
|
||||
Ability = 20, // HT/LoH for Tit
|
||||
PotionBelt = 21, // Tit uses a different slot for PB
|
||||
Item = 22,
|
||||
Discipline = 23,
|
||||
AltAbility = 0xFF
|
||||
};
|
||||
|
||||
using RoF2::spells::SPELL_ID_MAX;
|
||||
using RoF2::spells::SPELLBOOK_SIZE;
|
||||
using UF::spells::SPELL_GEM_COUNT; // RoF+ clients define more than UF client..but, they are not valid beyond UF
|
||||
|
||||
using RoF2::spells::LONG_BUFFS;
|
||||
using RoF2::spells::SHORT_BUFFS;
|
||||
using RoF2::spells::DISC_BUFFS;
|
||||
using RoF2::spells::TOTAL_BUFFS;
|
||||
using RoF2::spells::NPC_BUFFS;
|
||||
using RoF2::spells::PET_BUFFS;
|
||||
using RoF2::spells::MERC_BUFFS;
|
||||
|
||||
} // namespace spells
|
||||
|
||||
namespace bug {
|
||||
enum CategoryID : uint32 {
|
||||
catOther = 0,
|
||||
@@ -485,112 +161,33 @@ namespace EQ
|
||||
|
||||
} // namespace bug
|
||||
|
||||
enum WaypointStatus : int {
|
||||
RoamBoxPauseInProgress = -3,
|
||||
QuestControlNoGrid = -2,
|
||||
QuestControlGrid = -1
|
||||
enum class CastingSlot : uint32 {
|
||||
Gem1 = 0,
|
||||
Gem2 = 1,
|
||||
Gem3 = 2,
|
||||
Gem4 = 3,
|
||||
Gem5 = 4,
|
||||
Gem6 = 5,
|
||||
Gem7 = 6,
|
||||
Gem8 = 7,
|
||||
Gem9 = 8,
|
||||
Gem10 = 9,
|
||||
Gem11 = 10,
|
||||
Gem12 = 11,
|
||||
MaxGems = 12,
|
||||
Ability = 20, // HT/LoH for Tit
|
||||
PotionBelt = 21, // Tit uses a different slot for PB
|
||||
Item = 22,
|
||||
Discipline = 23,
|
||||
AltAbility = 0xFF
|
||||
};
|
||||
|
||||
namespace consent {
|
||||
enum eConsentType : uint8 {
|
||||
Normal = 0,
|
||||
Group,
|
||||
Raid,
|
||||
Guild
|
||||
};
|
||||
}; // namespace consent
|
||||
} /*EQEmu*/
|
||||
|
||||
enum ServerLockType : int {
|
||||
List,
|
||||
Lock,
|
||||
Unlock
|
||||
};
|
||||
|
||||
enum AccountStatus : uint8 {
|
||||
Player = 0,
|
||||
Steward = 10,
|
||||
ApprenticeGuide = 20,
|
||||
Guide = 50,
|
||||
QuestTroupe = 80,
|
||||
SeniorGuide = 81,
|
||||
GMTester = 85,
|
||||
EQSupport = 90,
|
||||
GMStaff = 95,
|
||||
GMAdmin = 100,
|
||||
GMLeadAdmin = 150,
|
||||
QuestMaster = 160,
|
||||
GMAreas = 170,
|
||||
GMCoder = 180,
|
||||
GMMgmt = 200,
|
||||
GMImpossible = 250,
|
||||
Max = 255
|
||||
};
|
||||
|
||||
enum Invisibility : uint8 {
|
||||
Visible,
|
||||
Invisible,
|
||||
Special = 255
|
||||
};
|
||||
|
||||
enum AugmentActions : int {
|
||||
Insert,
|
||||
Remove,
|
||||
Swap,
|
||||
Destroy
|
||||
};
|
||||
|
||||
enum ConsiderLevel : uint8 {
|
||||
Ally = 1,
|
||||
Warmly,
|
||||
Kindly,
|
||||
Amiably,
|
||||
Indifferently,
|
||||
Apprehensively,
|
||||
Dubiously,
|
||||
Threateningly,
|
||||
Scowls
|
||||
};
|
||||
|
||||
enum TargetDescriptionType : uint8 {
|
||||
LCSelf,
|
||||
UCSelf,
|
||||
LCYou,
|
||||
UCYou,
|
||||
LCYour,
|
||||
UCYour
|
||||
};
|
||||
|
||||
enum ReloadWorld : uint8 {
|
||||
NoRepop = 0,
|
||||
Repop,
|
||||
ForceRepop
|
||||
};
|
||||
|
||||
enum BucketComparison : uint8 {
|
||||
BucketEqualTo = 0,
|
||||
BucketNotEqualTo,
|
||||
BucketGreaterThanOrEqualTo,
|
||||
BucketLesserThanOrEqualTo,
|
||||
BucketGreaterThan,
|
||||
BucketLesserThan,
|
||||
BucketIsAny,
|
||||
BucketIsNotAny,
|
||||
BucketIsBetween,
|
||||
BucketIsNotBetween
|
||||
};
|
||||
|
||||
enum class EntityFilterType {
|
||||
All,
|
||||
Bots,
|
||||
Clients,
|
||||
NPCs
|
||||
};
|
||||
|
||||
enum class ApplySpellType {
|
||||
Solo,
|
||||
Group,
|
||||
Raid
|
||||
};
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
/* hack list to prevent circular references
|
||||
|
||||
eq_limits.h:EQEmu::inventory::LookupEntry::InventoryTypeSize[n];
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "emu_legacy.h"
|
||||
@@ -0,0 +1,182 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_EMU_LEGACY_H
|
||||
#define COMMON_EMU_LEGACY_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
// this is for perl and other legacy systems
|
||||
namespace legacy {
|
||||
enum InventorySlot {
|
||||
SLOT_CHARM = 0,
|
||||
SLOT_EAR01 = 1,
|
||||
SLOT_HEAD = 2,
|
||||
SLOT_FACE = 3,
|
||||
SLOT_EAR02 = 4,
|
||||
SLOT_NECK = 5,
|
||||
SLOT_SHOULDER = 6,
|
||||
SLOT_ARMS = 7,
|
||||
SLOT_BACK = 8,
|
||||
SLOT_BRACER01 = 9,
|
||||
SLOT_BRACER02 = 10,
|
||||
SLOT_RANGE = 11,
|
||||
SLOT_HANDS = 12,
|
||||
SLOT_PRIMARY = 13,
|
||||
SLOT_SECONDARY = 14,
|
||||
SLOT_RING01 = 15,
|
||||
SLOT_RING02 = 16,
|
||||
SLOT_CHEST = 17,
|
||||
SLOT_LEGS = 18,
|
||||
SLOT_FEET = 19,
|
||||
SLOT_WAIST = 20,
|
||||
SLOT_POWER_SOURCE = 9999,
|
||||
SLOT_AMMO = 21,
|
||||
SLOT_GENERAL_1 = 22,
|
||||
SLOT_GENERAL_2 = 23,
|
||||
SLOT_GENERAL_3 = 24,
|
||||
SLOT_GENERAL_4 = 25,
|
||||
SLOT_GENERAL_5 = 26,
|
||||
SLOT_GENERAL_6 = 27,
|
||||
SLOT_GENERAL_7 = 28,
|
||||
SLOT_GENERAL_8 = 29,
|
||||
SLOT_CURSOR = 30,
|
||||
SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this...
|
||||
SLOT_TRADESKILL = 1000,
|
||||
SLOT_AUGMENT = 1001,
|
||||
SLOT_INVALID = (int16)0xFFFF,
|
||||
SLOT_POSSESSIONS_BEGIN = 0,
|
||||
SLOT_POSSESSIONS_END = 30,
|
||||
SLOT_EQUIPMENT_BEGIN = 0,
|
||||
SLOT_EQUIPMENT_END = 21,
|
||||
SLOT_PERSONAL_BEGIN = 22,
|
||||
SLOT_PERSONAL_END = 29,
|
||||
SLOT_PERSONAL_BAGS_BEGIN = 251,
|
||||
SLOT_PERSONAL_BAGS_END = 330,
|
||||
SLOT_CURSOR_BAG_BEGIN = 331,
|
||||
SLOT_CURSOR_BAG_END = 340,
|
||||
SLOT_TRIBUTE_BEGIN = 400,
|
||||
SLOT_TRIBUTE_END = 404,
|
||||
SLOT_GUILD_TRIBUTE_BEGIN = 450,
|
||||
SLOT_GUILD_TRIBUTE_END = 451,
|
||||
SLOT_BANK_BEGIN = 2000,
|
||||
SLOT_BANK_END = 2023,
|
||||
SLOT_BANK_BAGS_BEGIN = 2031,
|
||||
SLOT_BANK_BAGS_END = 2270,
|
||||
SLOT_SHARED_BANK_BEGIN = 2500,
|
||||
SLOT_SHARED_BANK_END = 2501,
|
||||
SLOT_SHARED_BANK_BAGS_BEGIN = 2531,
|
||||
SLOT_SHARED_BANK_BAGS_END = 2550,
|
||||
SLOT_TRADE_BEGIN = 3000,
|
||||
SLOT_TRADE_END = 3007,
|
||||
SLOT_TRADE_BAGS_BEGIN = 3031,
|
||||
SLOT_TRADE_BAGS_END = 3110,
|
||||
SLOT_WORLD_BEGIN = 4000,
|
||||
SLOT_WORLD_END = 4009
|
||||
};
|
||||
|
||||
// these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready
|
||||
static const uint16 TYPE_POSSESSIONS_SIZE = 31;
|
||||
static const uint16 TYPE_BANK_SIZE = 24;
|
||||
static const uint16 TYPE_SHARED_BANK_SIZE = 2;
|
||||
static const uint16 TYPE_TRADE_SIZE = 8;
|
||||
static const uint16 TYPE_WORLD_SIZE = 10;
|
||||
static const uint16 TYPE_LIMBO_SIZE = 36;
|
||||
static const uint16 TYPE_TRIBUTE_SIZE = 5; // (need client values)
|
||||
static const uint16 TYPE_TROPHY_TRIBUTE_SIZE = 0;
|
||||
static const uint16 TYPE_GUILD_TRIBUTE_SIZE = 0;
|
||||
static const uint16 TYPE_MERCHANT_SIZE = 0;
|
||||
static const uint16 TYPE_DELETED_SIZE = 0;
|
||||
static const uint16 TYPE_CORPSE_SIZE = 31; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
|
||||
static const uint16 TYPE_BAZAAR_SIZE = 80;
|
||||
static const uint16 TYPE_INSPECT_SIZE = 22;
|
||||
static const uint16 TYPE_REAL_ESTATE_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_PC_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_BANK_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_SHARED_BANK_SIZE = 0;
|
||||
static const uint16 TYPE_VIEW_MOD_LIMBO_SIZE = 0;
|
||||
static const uint16 TYPE_ALT_STORAGE_SIZE = 0;
|
||||
static const uint16 TYPE_ARCHIVED_SIZE = 0;
|
||||
static const uint16 TYPE_MAIL_SIZE = 0;
|
||||
static const uint16 TYPE_GUILD_TROPHY_TRIBUTE_SIZE = 0;
|
||||
static const uint16 TYPE_KRONO_SIZE = 0;
|
||||
static const uint16 TYPE_OTHER_SIZE = 0;
|
||||
|
||||
// most of these definitions will go away with the structure-based system..this maintains compatibility for now
|
||||
// (these are mainly to assign specific values to constants used in conversions and to identify per-client ranges/offsets)
|
||||
static const int16 EQUIPMENT_BEGIN = 0;
|
||||
static const int16 EQUIPMENT_END = 21;
|
||||
static const uint16 EQUIPMENT_SIZE = 22; // does not account for 'Power Source' - used mainly for npc equipment arrays
|
||||
|
||||
static const int16 GENERAL_BEGIN = 22;
|
||||
static const int16 GENERAL_END = 29;
|
||||
static const uint16 GENERAL_SIZE = 8;
|
||||
static const int16 GENERAL_BAGS_BEGIN = 251;
|
||||
static const int16 GENERAL_BAGS_END_OFFSET = 79;
|
||||
static const int16 GENERAL_BAGS_END = GENERAL_BAGS_BEGIN + GENERAL_BAGS_END_OFFSET;
|
||||
|
||||
static const int16 CURSOR_BAG_BEGIN = 331;
|
||||
static const int16 CURSOR_BAG_END_OFFSET = 9;
|
||||
static const int16 CURSOR_BAG_END = CURSOR_BAG_BEGIN + CURSOR_BAG_END_OFFSET;
|
||||
|
||||
static const int16 BANK_BEGIN = 2000;
|
||||
static const int16 BANK_END = 2023;
|
||||
static const int16 BANK_BAGS_BEGIN = 2031;
|
||||
static const int16 BANK_BAGS_END_OFFSET = 239;
|
||||
static const int16 BANK_BAGS_END = BANK_BAGS_BEGIN + BANK_BAGS_END_OFFSET;
|
||||
|
||||
static const int16 SHARED_BANK_BEGIN = 2500;
|
||||
static const int16 SHARED_BANK_END = 2501;
|
||||
static const int16 SHARED_BANK_BAGS_BEGIN = 2531;
|
||||
static const int16 SHARED_BANK_BAGS_END_OFFSET = 19;
|
||||
static const int16 SHARED_BANK_BAGS_END = SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_END_OFFSET;
|
||||
|
||||
static const int16 TRADE_BEGIN = 3000;
|
||||
static const int16 TRADE_END = 3007;
|
||||
static const int16 TRADE_NPC_END = 3003;
|
||||
static const int16 TRADE_BAGS_BEGIN = 3031;
|
||||
static const int16 TRADE_BAGS_END_OFFSET = 79;
|
||||
static const int16 TRADE_BAGS_END = TRADE_BAGS_BEGIN + TRADE_BAGS_END_OFFSET;
|
||||
|
||||
static const int16 WORLD_BEGIN = 4000;
|
||||
static const int16 WORLD_END = 4009;
|
||||
static const int16 WORLD_SIZE = TYPE_WORLD_SIZE;
|
||||
|
||||
static const int16 TRIBUTE_BEGIN = 400;
|
||||
static const int16 TRIBUTE_END = 404;
|
||||
static const int16 TRIBUTE_SIZE = TYPE_TRIBUTE_SIZE;
|
||||
|
||||
static const int16 CORPSE_BEGIN = 22;
|
||||
|
||||
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* COMMON_EMU_LEGACY_H */
|
||||
+24
-48
@@ -28,98 +28,74 @@
|
||||
namespace EntityLimits
|
||||
{
|
||||
namespace NPC {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*NPC*/
|
||||
|
||||
namespace NPCMerchant {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*NPCMerchant*/
|
||||
|
||||
namespace Merc {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*Merc*/
|
||||
|
||||
namespace Bot {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 8;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
|
||||
namespace invslot {
|
||||
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
|
||||
const uint64 GENERAL_BITMASK = 0x0000000000000000;
|
||||
const uint64 CURSOR_BITMASK = 0x0000000000000000;
|
||||
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 34-slot count (RoF+)
|
||||
|
||||
} // namespace invslot
|
||||
const size_t InvTypeTradeSize = 8;
|
||||
|
||||
} /*Bot*/
|
||||
|
||||
namespace ClientPet {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*Pet*/
|
||||
|
||||
namespace NPCPet {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*Pet*/
|
||||
|
||||
namespace MercPet {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*Pet*/
|
||||
|
||||
namespace BotPet {
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace invtype {
|
||||
const int16 TRADE_SIZE = 4;
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} // namespace invtype
|
||||
const size_t InvTypeTradeSize = 4;
|
||||
|
||||
} /*Pet*/
|
||||
|
||||
|
||||
+10
-31
@@ -35,7 +35,7 @@ N(OP_AltCurrencyMerchantRequest),
|
||||
N(OP_AltCurrencyPurchase),
|
||||
N(OP_AltCurrencyReclaim),
|
||||
N(OP_AltCurrencySell),
|
||||
N(OP_AltCurrencySellSelection), // Used by eqstr_us.txt 8066, 8068, 8069
|
||||
N(OP_AltCurrencySellSelection),
|
||||
N(OP_Animation),
|
||||
N(OP_AnnoyingZoneUnknown),
|
||||
N(OP_ApplyPoison),
|
||||
@@ -71,7 +71,6 @@ N(OP_Camp),
|
||||
N(OP_CancelSneakHide),
|
||||
N(OP_CancelTask),
|
||||
N(OP_CancelTrade),
|
||||
N(OP_CashReward),
|
||||
N(OP_CastSpell),
|
||||
N(OP_ChangeSize),
|
||||
N(OP_ChannelMessage),
|
||||
@@ -130,29 +129,27 @@ N(OP_DisciplineTimer),
|
||||
N(OP_DisciplineUpdate),
|
||||
N(OP_DiscordMerchantInventory),
|
||||
N(OP_DoGroupLeadershipAbility),
|
||||
N(OP_DuelDecline),
|
||||
N(OP_DuelAccept),
|
||||
N(OP_DuelResponse),
|
||||
N(OP_DuelResponse2),
|
||||
N(OP_DumpName),
|
||||
N(OP_Dye),
|
||||
N(OP_DynamicWall),
|
||||
N(OP_DzAddPlayer),
|
||||
N(OP_DzChooseZone),
|
||||
N(OP_DzChooseZoneReply),
|
||||
N(OP_DzCompass),
|
||||
N(OP_DzExpeditionEndsWarning),
|
||||
N(OP_DzExpeditionInfo),
|
||||
N(OP_DzExpeditionInvite),
|
||||
N(OP_DzExpeditionInviteResponse),
|
||||
N(OP_DzExpeditionLockoutTimers),
|
||||
N(OP_DzExpeditionList),
|
||||
N(OP_DzJoinExpeditionConfirm),
|
||||
N(OP_DzJoinExpeditionReply),
|
||||
N(OP_DzLeaderStatus),
|
||||
N(OP_DzListTimers),
|
||||
N(OP_DzMakeLeader),
|
||||
N(OP_DzMemberList),
|
||||
N(OP_DzMemberListName),
|
||||
N(OP_DzMemberListStatus),
|
||||
N(OP_DzMemberStatus),
|
||||
N(OP_DzPlayerList),
|
||||
N(OP_DzQuit),
|
||||
N(OP_DzRemovePlayer),
|
||||
N(OP_DzSetLeaderName),
|
||||
N(OP_DzSwapPlayer),
|
||||
N(OP_Emote),
|
||||
N(OP_EndLootRequest),
|
||||
@@ -274,7 +271,6 @@ N(OP_ItemVerifyRequest),
|
||||
N(OP_ItemViewUnknown),
|
||||
N(OP_Jump),
|
||||
N(OP_KeyRing),
|
||||
N(OP_KickPlayers),
|
||||
N(OP_KnowledgeBase),
|
||||
N(OP_LDoNButton),
|
||||
N(OP_LDoNDisarmTraps),
|
||||
@@ -304,7 +300,6 @@ N(OP_LockoutTimerInfo),
|
||||
N(OP_Login),
|
||||
N(OP_LoginAccepted),
|
||||
N(OP_LoginComplete),
|
||||
N(OP_LoginExpansionPacketData), //added for Rof2 client to send expansion data packet. Requires login_opcodes_sod.conf to be updated.
|
||||
N(OP_LoginUnknown1),
|
||||
N(OP_LoginUnknown2),
|
||||
N(OP_Logout),
|
||||
@@ -357,6 +352,7 @@ N(OP_OpenContainer),
|
||||
N(OP_OpenDiscordMerchant),
|
||||
N(OP_OpenGuildTributeMaster),
|
||||
N(OP_OpenInventory),
|
||||
N(OP_OpenNewTasksWindow),
|
||||
N(OP_OpenTributeMaster),
|
||||
N(OP_PDeletePetition),
|
||||
N(OP_PetBuffWindow),
|
||||
@@ -457,7 +453,6 @@ N(OP_ServerListResponse),
|
||||
N(OP_SessionReady),
|
||||
N(OP_SetChatServer),
|
||||
N(OP_SetChatServer2),
|
||||
N(OP_SetFace),
|
||||
N(OP_SetGroupTarget),
|
||||
N(OP_SetGuildMOTD),
|
||||
N(OP_SetGuildRank),
|
||||
@@ -466,19 +461,6 @@ N(OP_SetServerFilter),
|
||||
N(OP_SetStartCity),
|
||||
N(OP_SetTitle),
|
||||
N(OP_SetTitleReply),
|
||||
N(OP_SharedTaskMemberList),
|
||||
N(OP_SharedTaskAddPlayer),
|
||||
N(OP_SharedTaskRemovePlayer),
|
||||
N(OP_SharedTaskMakeLeader),
|
||||
N(OP_SharedTaskMemberInvite),
|
||||
N(OP_SharedTaskInvite),
|
||||
N(OP_SharedTaskInviteResponse),
|
||||
N(OP_SharedTaskAcceptNew),
|
||||
N(OP_SharedTaskMemberChange),
|
||||
N(OP_SharedTaskPlayerList),
|
||||
N(OP_SharedTaskSelectWindow),
|
||||
N(OP_SharedTaskQuit),
|
||||
N(OP_TaskTimers),
|
||||
N(OP_Shielding),
|
||||
N(OP_ShopDelItem),
|
||||
N(OP_ShopEnd),
|
||||
@@ -514,8 +496,7 @@ N(OP_TaskActivityComplete),
|
||||
N(OP_TaskDescription),
|
||||
N(OP_TaskHistoryReply),
|
||||
N(OP_TaskHistoryRequest),
|
||||
N(OP_TaskRequestTimer),
|
||||
N(OP_TaskSelectWindow),
|
||||
N(OP_TaskMemberList),
|
||||
N(OP_Taunt),
|
||||
N(OP_TestBuff),
|
||||
N(OP_TGB),
|
||||
@@ -561,7 +542,6 @@ N(OP_WhoAllRequest),
|
||||
N(OP_WhoAllResponse),
|
||||
N(OP_World_Client_CRC1),
|
||||
N(OP_World_Client_CRC2),
|
||||
N(OP_World_Client_CRC3),
|
||||
N(OP_WorldClientReady),
|
||||
N(OP_WorldComplete),
|
||||
N(OP_WorldLogout),
|
||||
@@ -584,5 +564,4 @@ N(OP_ZoneServerReady),
|
||||
N(OP_ZoneSpawns),
|
||||
N(OP_ZoneUnavail),
|
||||
N(OP_ResetAA),
|
||||
N(OP_UnderWorld),
|
||||
// mail and chat opcodes located in ../mail_oplist.h
|
||||
|
||||
+54
-242
@@ -18,10 +18,9 @@
|
||||
*/
|
||||
|
||||
#include "emu_versions.h"
|
||||
#include "emu_constants.h"
|
||||
|
||||
|
||||
bool EQ::versions::IsValidClientVersion(ClientVersion client_version)
|
||||
bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version)
|
||||
{
|
||||
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
|
||||
return false;
|
||||
@@ -29,7 +28,7 @@ bool EQ::versions::IsValidClientVersion(ClientVersion client_version)
|
||||
return true;
|
||||
}
|
||||
|
||||
EQ::versions::ClientVersion EQ::versions::ValidateClientVersion(ClientVersion client_version)
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ValidateClientVersion(ClientVersion client_version)
|
||||
{
|
||||
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
|
||||
return ClientVersion::Unknown;
|
||||
@@ -37,7 +36,7 @@ EQ::versions::ClientVersion EQ::versions::ValidateClientVersion(ClientVersion cl
|
||||
return client_version;
|
||||
}
|
||||
|
||||
const char* EQ::versions::ClientVersionName(ClientVersion client_version)
|
||||
const char* EQEmu::versions::ClientVersionName(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Unknown:
|
||||
@@ -61,29 +60,35 @@ const char* EQ::versions::ClientVersionName(ClientVersion client_version)
|
||||
};
|
||||
}
|
||||
|
||||
uint32 EQ::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
|
||||
uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Unknown:
|
||||
case ClientVersion::Client62:
|
||||
return bit_Unknown;
|
||||
case ClientVersion::Titanium:
|
||||
return bitTitanium;
|
||||
return bit_Titanium;
|
||||
case ClientVersion::SoF:
|
||||
return bitSoF;
|
||||
return bit_SoF;
|
||||
case ClientVersion::SoD:
|
||||
return bitSoD;
|
||||
return bit_SoD;
|
||||
case ClientVersion::UF:
|
||||
return bitUF;
|
||||
return bit_UF;
|
||||
case ClientVersion::RoF:
|
||||
return bitRoF;
|
||||
return bit_RoF;
|
||||
case ClientVersion::RoF2:
|
||||
return bitRoF2;
|
||||
return bit_RoF2;
|
||||
default:
|
||||
return bitUnknown;
|
||||
return bit_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
|
||||
{
|
||||
switch (client_version_bit) {
|
||||
case (uint32)static_cast<unsigned int>(ClientVersion::Unknown) :
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Client62) - 1)) :
|
||||
return ClientVersion::Unknown;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
|
||||
return ClientVersion::Titanium;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SoF) - 1)) :
|
||||
@@ -101,7 +106,28 @@ EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::versions::IsValidMobVersion(MobVersion mob_version)
|
||||
uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Unknown:
|
||||
case ClientVersion::Client62:
|
||||
case ClientVersion::Titanium:
|
||||
return 0x000007FFU;
|
||||
case ClientVersion::SoF:
|
||||
return 0x00007FFFU;
|
||||
case ClientVersion::SoD:
|
||||
return 0x0000FFFFU;
|
||||
case ClientVersion::UF:
|
||||
return 0x0001FFFFU;
|
||||
case ClientVersion::RoF:
|
||||
case ClientVersion::RoF2:
|
||||
return 0x000FFFFFU;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
|
||||
return false;
|
||||
@@ -109,7 +135,7 @@ bool EQ::versions::IsValidMobVersion(MobVersion mob_version)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQ::versions::IsValidPCMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidPCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
|
||||
return false;
|
||||
@@ -117,7 +143,7 @@ bool EQ::versions::IsValidPCMobVersion(MobVersion mob_version)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQ::versions::IsValidNonPCMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidNonPCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
|
||||
return false;
|
||||
@@ -125,7 +151,7 @@ bool EQ::versions::IsValidNonPCMobVersion(MobVersion mob_version)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EQ::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
|
||||
return false;
|
||||
@@ -133,7 +159,7 @@ bool EQ::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
|
||||
return true;
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ValidateMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidateMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
@@ -141,7 +167,7 @@ EQ::versions::MobVersion EQ::versions::ValidateMobVersion(MobVersion mob_version
|
||||
return mob_version;
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ValidatePCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidatePCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
@@ -149,7 +175,7 @@ EQ::versions::MobVersion EQ::versions::ValidatePCMobVersion(MobVersion mob_versi
|
||||
return mob_version;
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ValidateNonPCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidateNonPCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
@@ -157,7 +183,7 @@ EQ::versions::MobVersion EQ::versions::ValidateNonPCMobVersion(MobVersion mob_ve
|
||||
return mob_version;
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ValidateOfflinePCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ValidateOfflinePCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
|
||||
return MobVersion::Unknown;
|
||||
@@ -165,7 +191,7 @@ EQ::versions::MobVersion EQ::versions::ValidateOfflinePCMobVersion(MobVersion mo
|
||||
return mob_version;
|
||||
}
|
||||
|
||||
const char* EQ::versions::MobVersionName(MobVersion mob_version)
|
||||
const char* EQEmu::versions::MobVersionName(MobVersion mob_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::Unknown:
|
||||
@@ -217,7 +243,7 @@ const char* EQ::versions::MobVersionName(MobVersion mob_version)
|
||||
};
|
||||
}
|
||||
|
||||
EQ::versions::ClientVersion EQ::versions::ConvertMobVersionToClientVersion(MobVersion mob_version)
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertMobVersionToClientVersion(MobVersion mob_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::Unknown:
|
||||
@@ -240,7 +266,7 @@ EQ::versions::ClientVersion EQ::versions::ConvertMobVersionToClientVersion(MobVe
|
||||
}
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ConvertClientVersionToMobVersion(ClientVersion client_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Unknown:
|
||||
@@ -263,7 +289,7 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToMobVersion(ClientVe
|
||||
}
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::Titanium:
|
||||
@@ -283,7 +309,7 @@ EQ::versions::MobVersion EQ::versions::ConvertPCMobVersionToOfflinePCMobVersion(
|
||||
}
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::OfflineTitanium:
|
||||
@@ -303,7 +329,7 @@ EQ::versions::MobVersion EQ::versions::ConvertOfflinePCMobVersionToPCMobVersion(
|
||||
}
|
||||
}
|
||||
|
||||
EQ::versions::ClientVersion EQ::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version)
|
||||
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version)
|
||||
{
|
||||
switch (mob_version) {
|
||||
case MobVersion::OfflineTitanium:
|
||||
@@ -323,7 +349,7 @@ EQ::versions::ClientVersion EQ::versions::ConvertOfflinePCMobVersionToClientVers
|
||||
}
|
||||
}
|
||||
|
||||
EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version)
|
||||
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version)
|
||||
{
|
||||
switch (client_version) {
|
||||
case ClientVersion::Titanium:
|
||||
@@ -342,217 +368,3 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion
|
||||
return MobVersion::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
const char* EQ::expansions::ExpansionName(Expansion expansion)
|
||||
{
|
||||
switch (expansion) {
|
||||
case Expansion::EverQuest:
|
||||
return "EverQuest";
|
||||
case Expansion::RoK:
|
||||
return "The Ruins of Kunark";
|
||||
case Expansion::SoV:
|
||||
return "The Scars of Velious";
|
||||
case Expansion::SoL:
|
||||
return "The Shadows of Luclin";
|
||||
case Expansion::PoP:
|
||||
return "The Planes of Power";
|
||||
case Expansion::LoY:
|
||||
return "The Legacy of Ykesha";
|
||||
case Expansion::LDoN:
|
||||
return "Lost Dungeons of Norrath";
|
||||
case Expansion::GoD:
|
||||
return "Gates of Discord";
|
||||
case Expansion::OoW:
|
||||
return "Omens of War";
|
||||
case Expansion::DoN:
|
||||
return "Dragons of Norrath";
|
||||
case Expansion::DoD:
|
||||
return "Depths of Darkhollow";
|
||||
case Expansion::PoR:
|
||||
return "Prophecy of Ro";
|
||||
case Expansion::TSS:
|
||||
return "The Serpent's Spine";
|
||||
case Expansion::TBS:
|
||||
return "The Buried Sea";
|
||||
case Expansion::SoF:
|
||||
return "Secrets of Faydwer";
|
||||
case Expansion::SoD:
|
||||
return "Seeds of Destruction";
|
||||
case Expansion::UF:
|
||||
return "Underfoot";
|
||||
case Expansion::HoT:
|
||||
return "House of Thule";
|
||||
case Expansion::VoA:
|
||||
return "Veil of Alaris";
|
||||
case Expansion::RoF:
|
||||
return "Rain of Fear";
|
||||
case Expansion::CotF:
|
||||
return "Call of the Forsaken";
|
||||
default:
|
||||
return "Invalid Expansion";
|
||||
}
|
||||
}
|
||||
|
||||
const char* EQ::expansions::ExpansionName(uint32 expansion_bit)
|
||||
{
|
||||
return ExpansionName(ConvertExpansionBitToExpansion(expansion_bit));
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
|
||||
{
|
||||
switch (expansion) {
|
||||
case Expansion::RoK:
|
||||
return bitRoK;
|
||||
case Expansion::SoV:
|
||||
return bitSoV;
|
||||
case Expansion::SoL:
|
||||
return bitSoL;
|
||||
case Expansion::PoP:
|
||||
return bitPoP;
|
||||
case Expansion::LoY:
|
||||
return bitLoY;
|
||||
case Expansion::LDoN:
|
||||
return bitLDoN;
|
||||
case Expansion::GoD:
|
||||
return bitGoD;
|
||||
case Expansion::OoW:
|
||||
return bitOoW;
|
||||
case Expansion::DoN:
|
||||
return bitDoN;
|
||||
case Expansion::DoD:
|
||||
return bitDoD;
|
||||
case Expansion::PoR:
|
||||
return bitPoR;
|
||||
case Expansion::TSS:
|
||||
return bitTSS;
|
||||
case Expansion::TBS:
|
||||
return bitTBS;
|
||||
case Expansion::SoF:
|
||||
return bitSoF;
|
||||
case Expansion::SoD:
|
||||
return bitSoD;
|
||||
case Expansion::UF:
|
||||
return bitUF;
|
||||
case Expansion::HoT:
|
||||
return bitHoT;
|
||||
case Expansion::VoA:
|
||||
return bitVoA;
|
||||
case Expansion::RoF:
|
||||
return bitRoF;
|
||||
case Expansion::CotF:
|
||||
return bitCotF;
|
||||
default:
|
||||
return bitEverQuest;
|
||||
}
|
||||
}
|
||||
|
||||
EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
|
||||
{
|
||||
switch (expansion_bit) {
|
||||
case bitRoK:
|
||||
return Expansion::RoK;
|
||||
case bitSoV:
|
||||
return Expansion::SoV;
|
||||
case bitSoL:
|
||||
return Expansion::SoL;
|
||||
case bitPoP:
|
||||
return Expansion::PoP;
|
||||
case bitLoY:
|
||||
return Expansion::LoY;
|
||||
case bitLDoN:
|
||||
return Expansion::LDoN;
|
||||
case bitGoD:
|
||||
return Expansion::GoD;
|
||||
case bitOoW:
|
||||
return Expansion::OoW;
|
||||
case bitDoN:
|
||||
return Expansion::DoN;
|
||||
case bitDoD:
|
||||
return Expansion::DoD;
|
||||
case bitPoR:
|
||||
return Expansion::PoR;
|
||||
case bitTSS:
|
||||
return Expansion::TSS;
|
||||
case bitTBS:
|
||||
return Expansion::TBS;
|
||||
case bitSoF:
|
||||
return Expansion::SoF;
|
||||
case bitSoD:
|
||||
return Expansion::SoD;
|
||||
case bitUF:
|
||||
return Expansion::UF;
|
||||
case bitHoT:
|
||||
return Expansion::HoT;
|
||||
case bitVoA:
|
||||
return Expansion::VoA;
|
||||
case bitRoF:
|
||||
return Expansion::RoF;
|
||||
case bitCotF:
|
||||
return Expansion::CotF;
|
||||
default:
|
||||
return Expansion::EverQuest;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
|
||||
{
|
||||
switch (expansion) {
|
||||
case Expansion::RoK:
|
||||
return maskRoK;
|
||||
case Expansion::SoV:
|
||||
return maskSoV;
|
||||
case Expansion::SoL:
|
||||
return maskSoL;
|
||||
case Expansion::PoP:
|
||||
return maskPoP;
|
||||
case Expansion::LoY:
|
||||
return maskLoY;
|
||||
case Expansion::LDoN:
|
||||
return maskLDoN;
|
||||
case Expansion::GoD:
|
||||
return maskGoD;
|
||||
case Expansion::OoW:
|
||||
return maskOoW;
|
||||
case Expansion::DoN:
|
||||
return maskDoN;
|
||||
case Expansion::DoD:
|
||||
return maskDoD;
|
||||
case Expansion::PoR:
|
||||
return maskPoR;
|
||||
case Expansion::TSS:
|
||||
return maskTSS;
|
||||
case Expansion::TBS:
|
||||
return maskTBS;
|
||||
case Expansion::SoF:
|
||||
return maskSoF;
|
||||
case Expansion::SoD:
|
||||
return maskSoD;
|
||||
case Expansion::UF:
|
||||
return maskUF;
|
||||
case Expansion::HoT:
|
||||
return maskHoT;
|
||||
case Expansion::VoA:
|
||||
return maskVoA;
|
||||
case Expansion::RoF:
|
||||
return maskRoF;
|
||||
case Expansion::CotF:
|
||||
return maskCotF;
|
||||
default:
|
||||
return maskEverQuest;
|
||||
}
|
||||
}
|
||||
|
||||
EQ::expansions::Expansion EQ::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
|
||||
{
|
||||
return EQ::constants::StaticLookup(client_version)->Expansion;
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
|
||||
{
|
||||
return EQ::constants::StaticLookup(client_version)->ExpansionBit;
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
|
||||
{
|
||||
return EQ::constants::StaticLookup(client_version)->ExpansionsMask;
|
||||
}
|
||||
|
||||
+24
-104
@@ -25,7 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
namespace versions {
|
||||
enum class ClientVersion : uint32 {
|
||||
@@ -39,27 +39,26 @@ namespace EQ
|
||||
RoF2 // Build: 'May 10 2013 23:30:08'
|
||||
};
|
||||
|
||||
enum ClientVersionBitmask : uint32 {
|
||||
bitUnknown = 0x00000000,
|
||||
bitClient62 = 0x00000001, // unsupported (placeholder for scripts)
|
||||
bitTitanium = 0x00000002,
|
||||
bitSoF = 0x00000004,
|
||||
bitSoD = 0x00000008,
|
||||
bitUF = 0x00000010,
|
||||
bitRoF = 0x00000020,
|
||||
bitRoF2 = 0x00000040,
|
||||
maskUnknown = 0x00000000,
|
||||
maskTitaniumAndEarlier = 0x00000003,
|
||||
maskSoFAndEarlier = 0x00000007,
|
||||
maskSoDAndEarlier = 0x0000000F,
|
||||
maskUFAndEarlier = 0x0000001F,
|
||||
maskRoFAndEarlier = 0x0000003F,
|
||||
maskSoFAndLater = 0xFFFFFFFC,
|
||||
maskSoDAndLater = 0xFFFFFFF8,
|
||||
maskUFAndLater = 0xFFFFFFF0,
|
||||
maskRoFAndLater = 0xFFFFFFE0,
|
||||
maskRoF2AndLater = 0xFFFFFFC0,
|
||||
maskAllClients = 0xFFFFFFFF
|
||||
enum ClientVersionBit : uint32 {
|
||||
bit_Unknown = 0,
|
||||
bit_Client62 = 0x00000001, // unsupported (placeholder for scripts)
|
||||
bit_Titanium = 0x00000002,
|
||||
bit_SoF = 0x00000004,
|
||||
bit_SoD = 0x00000008,
|
||||
bit_UF = 0x00000010,
|
||||
bit_RoF = 0x00000020,
|
||||
bit_RoF2 = 0x00000040,
|
||||
bit_TitaniumAndEarlier = 0x00000003,
|
||||
bit_SoFAndEarlier = 0x00000007,
|
||||
bit_SoDAndEarlier = 0x0000000F,
|
||||
bit_UFAndEarlier = 0x0000001F,
|
||||
bit_RoFAndEarlier = 0x0000003F,
|
||||
bit_SoFAndLater = 0xFFFFFFFC,
|
||||
bit_SoDAndLater = 0xFFFFFFF8,
|
||||
bit_UFAndLater = 0xFFFFFFF0,
|
||||
bit_RoFAndLater = 0xFFFFFFE0,
|
||||
bit_RoF2AndLater = 0xFFFFFFC0,
|
||||
bit_AllClients = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
const ClientVersion LastClientVersion = ClientVersion::RoF2;
|
||||
@@ -70,7 +69,9 @@ namespace EQ
|
||||
const char* ClientVersionName(ClientVersion client_version);
|
||||
uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
|
||||
ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
|
||||
|
||||
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
||||
|
||||
|
||||
enum class MobVersion : uint32 {
|
||||
Unknown = 0,
|
||||
Client62,
|
||||
@@ -136,87 +137,6 @@ namespace EQ
|
||||
|
||||
} /*versions*/
|
||||
|
||||
namespace expansions {
|
||||
enum class Expansion : uint32 {
|
||||
EverQuest = 0,
|
||||
RoK,
|
||||
SoV,
|
||||
SoL,
|
||||
PoP,
|
||||
LoY,
|
||||
LDoN,
|
||||
GoD,
|
||||
OoW,
|
||||
DoN,
|
||||
DoD,
|
||||
PoR,
|
||||
TSS,
|
||||
TBS,
|
||||
SoF,
|
||||
SoD,
|
||||
UF,
|
||||
HoT,
|
||||
VoA,
|
||||
RoF,
|
||||
CotF
|
||||
};
|
||||
|
||||
enum ExpansionBitmask : uint32 {
|
||||
bitEverQuest = 0x00000000,
|
||||
bitRoK = 0x00000001,
|
||||
bitSoV = 0x00000002,
|
||||
bitSoL = 0x00000004,
|
||||
bitPoP = 0x00000008,
|
||||
bitLoY = 0x00000010,
|
||||
bitLDoN = 0x00000020,
|
||||
bitGoD = 0x00000040,
|
||||
bitOoW = 0x00000080,
|
||||
bitDoN = 0x00000100,
|
||||
bitDoD = 0x00000200,
|
||||
bitPoR = 0x00000400,
|
||||
bitTSS = 0x00000800,
|
||||
bitTBS = 0x00001000,
|
||||
bitSoF = 0x00002000,
|
||||
bitSoD = 0x00004000,
|
||||
bitUF = 0x00008000,
|
||||
bitHoT = 0x00010000,
|
||||
bitVoA = 0x00020000,
|
||||
bitRoF = 0x00040000,
|
||||
bitCotF = 0x00080000,
|
||||
maskEverQuest = 0x00000000,
|
||||
maskRoK = 0x00000001,
|
||||
maskSoV = 0x00000003,
|
||||
maskSoL = 0x00000007,
|
||||
maskPoP = 0x0000000F,
|
||||
maskLoY = 0x0000001F,
|
||||
maskLDoN = 0x0000003F,
|
||||
maskGoD = 0x0000007F,
|
||||
maskOoW = 0x000000FF,
|
||||
maskDoN = 0x000001FF,
|
||||
maskDoD = 0x000003FF,
|
||||
maskPoR = 0x000007FF,
|
||||
maskTSS = 0x00000FFF,
|
||||
maskTBS = 0x00001FFF,
|
||||
maskSoF = 0x00003FFF,
|
||||
maskSoD = 0x00007FFF,
|
||||
maskUF = 0x0000FFFF,
|
||||
maskHoT = 0x0001FFFF,
|
||||
maskVoA = 0x0003FFFF,
|
||||
maskRoF = 0x0007FFFF,
|
||||
maskCotF = 0x000FFFFF
|
||||
};
|
||||
|
||||
const char* ExpansionName(Expansion expansion);
|
||||
const char* ExpansionName(uint32 expansion_bit);
|
||||
uint32 ConvertExpansionToExpansionBit(Expansion expansion);
|
||||
Expansion ConvertExpansionBitToExpansion(uint32 expansion_bit);
|
||||
uint32 ConvertExpansionToExpansionsMask(Expansion expansion);
|
||||
Expansion ConvertClientVersionToExpansion(versions::ClientVersion client_version);
|
||||
uint32 ConvertClientVersionToExpansionBit(versions::ClientVersion client_version);
|
||||
uint32 ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version);
|
||||
|
||||
} /*expansions*/
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_EMU_VERSIONS_H*/
|
||||
|
||||
+202
-724
@@ -65,22 +65,19 @@
|
||||
#define AT_FindBits 46 // set FindBits, whatever those are!
|
||||
#define AT_TextureType 48 // TextureType
|
||||
#define AT_FacePick 49 // Turns off face pick window? maybe ...
|
||||
#define AT_AntiCheat 51 // sent by the client randomly telling the server how long since last action has occured
|
||||
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
|
||||
#define AT_Offline 53 // Offline mode
|
||||
|
||||
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
||||
|
||||
// animations for AT_Anim
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_STAND 0x64
|
||||
#define ANIM_SIT 0x6e
|
||||
#define ANIM_CROUCH 0x6f
|
||||
#define ANIM_DEATH 0x73
|
||||
#define ANIM_LOOT 0x69
|
||||
|
||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||
|
||||
typedef enum {
|
||||
eaStanding = 0,
|
||||
eaSitting, //1
|
||||
@@ -90,601 +87,208 @@ typedef enum {
|
||||
_eaMaxAppearance
|
||||
} EmuAppearance;
|
||||
|
||||
namespace Chat {
|
||||
const uint16 White = 0;
|
||||
const uint16 DimGray = 1;
|
||||
const uint16 Default = 1;
|
||||
const uint16 Green = 2;
|
||||
const uint16 BrightBlue = 3;
|
||||
const uint16 LightBlue = 4;
|
||||
const uint16 Magenta = 5;
|
||||
const uint16 Gray = 6;
|
||||
const uint16 LightGray = 7;
|
||||
const uint16 NPCQuestSay = 10;
|
||||
const uint16 DarkGray = 12;
|
||||
const uint16 Red = 13;
|
||||
const uint16 Lime = 14;
|
||||
const uint16 Yellow = 15;
|
||||
const uint16 Blue = 16;
|
||||
const uint16 LightNavy = 17;
|
||||
const uint16 Cyan = 18;
|
||||
const uint16 Black = 20;
|
||||
// msg_type's for custom usercolors
|
||||
#define MT_Say 256
|
||||
#define MT_Tell 257
|
||||
#define MT_Group 258
|
||||
#define MT_Guild 259
|
||||
#define MT_OOC 260
|
||||
#define MT_Auction 261
|
||||
#define MT_Shout 262
|
||||
#define MT_Emote 263
|
||||
#define MT_Spells 264
|
||||
#define MT_YouHitOther 265
|
||||
#define MT_OtherHitsYou 266
|
||||
#define MT_YouMissOther 267
|
||||
#define MT_OtherMissesYou 268
|
||||
#define MT_Broadcasts 269
|
||||
#define MT_Skills 270
|
||||
#define MT_Disciplines 271
|
||||
#define MT_Unused1 272
|
||||
#define MT_DefaultText 273
|
||||
#define MT_Unused2 274
|
||||
#define MT_MerchantOffer 275
|
||||
#define MT_MerchantBuySell 276
|
||||
#define MT_YourDeath 277
|
||||
#define MT_OtherDeath 278
|
||||
#define MT_OtherHits 279
|
||||
#define MT_OtherMisses 280
|
||||
#define MT_Who 281
|
||||
#define MT_YellForHelp 282
|
||||
#define MT_NonMelee 283
|
||||
#define MT_WornOff 284
|
||||
#define MT_MoneySplit 285
|
||||
#define MT_LootMessages 286
|
||||
#define MT_DiceRoll 287
|
||||
#define MT_OtherSpells 288
|
||||
#define MT_SpellFailure 289
|
||||
#define MT_Chat 290
|
||||
#define MT_Channel1 291
|
||||
#define MT_Channel2 292
|
||||
#define MT_Channel3 293
|
||||
#define MT_Channel4 294
|
||||
#define MT_Channel5 295
|
||||
#define MT_Channel6 296
|
||||
#define MT_Channel7 297
|
||||
#define MT_Channel8 298
|
||||
#define MT_Channel9 299
|
||||
#define MT_Channel10 300
|
||||
#define MT_CritMelee 301
|
||||
#define MT_SpellCrits 302
|
||||
#define MT_TooFarAway 303
|
||||
#define MT_NPCRampage 304
|
||||
#define MT_NPCFlurry 305
|
||||
#define MT_NPCEnrage 306
|
||||
#define MT_SayEcho 307
|
||||
#define MT_TellEcho 308
|
||||
#define MT_GroupEcho 309
|
||||
#define MT_GuildEcho 310
|
||||
#define MT_OOCEcho 311
|
||||
#define MT_AuctionEcho 312
|
||||
#define MT_ShoutECho 313
|
||||
#define MT_EmoteEcho 314
|
||||
#define MT_Chat1Echo 315
|
||||
#define MT_Chat2Echo 316
|
||||
#define MT_Chat3Echo 317
|
||||
#define MT_Chat4Echo 318
|
||||
#define MT_Chat5Echo 319
|
||||
#define MT_Chat6Echo 320
|
||||
#define MT_Chat7Echo 321
|
||||
#define MT_Chat8Echo 322
|
||||
#define MT_Chat9Echo 323
|
||||
#define MT_Chat10Echo 324
|
||||
#define MT_DoTDamage 325
|
||||
#define MT_ItemLink 326
|
||||
#define MT_RaidSay 327
|
||||
#define MT_MyPet 328
|
||||
#define MT_DS 329
|
||||
#define MT_Leadership 330
|
||||
#define MT_PetFlurry 331
|
||||
#define MT_PetCrit 332
|
||||
#define MT_FocusEffect 333
|
||||
#define MT_Experience 334
|
||||
#define MT_System 335
|
||||
#define MT_PetSpell 336
|
||||
#define MT_PetResponse 337
|
||||
#define MT_ItemSpeech 338
|
||||
#define MT_StrikeThrough 339
|
||||
#define MT_Stun 340
|
||||
|
||||
/**
|
||||
* User colors
|
||||
*/
|
||||
const uint16 Say = 256;
|
||||
const uint16 Tell = 257;
|
||||
const uint16 Group = 258;
|
||||
const uint16 Guild = 259;
|
||||
const uint16 OOC = 260;
|
||||
const uint16 Auction = 261;
|
||||
const uint16 Shout = 262;
|
||||
const uint16 Emote = 263;
|
||||
const uint16 Spells = 264;
|
||||
const uint16 YouHitOther = 265;
|
||||
const uint16 OtherHitYou = 266;
|
||||
const uint16 YouMissOther = 267;
|
||||
const uint16 OtherMissYou = 268;
|
||||
const uint16 Broadcasts = 269;
|
||||
const uint16 Skills = 270;
|
||||
const uint16 Disciplines = 271;
|
||||
const uint16 Unused1 = 272;
|
||||
const uint16 DefaultText = 273;
|
||||
const uint16 Unused2 = 274;
|
||||
const uint16 MerchantOffer = 275;
|
||||
const uint16 MerchantExchange = 276;
|
||||
const uint16 YourDeath = 277;
|
||||
const uint16 OtherDeath = 278;
|
||||
const uint16 OtherHitOther = 279;
|
||||
const uint16 OtherMissOther = 280;
|
||||
const uint16 Who = 281;
|
||||
const uint16 YellForHelp = 282;
|
||||
const uint16 NonMelee = 283;
|
||||
const uint16 SpellWornOff = 284;
|
||||
const uint16 MoneySplit = 285;
|
||||
const uint16 Loot = 286;
|
||||
const uint16 DiceRoll = 287;
|
||||
const uint16 OtherSpells = 288;
|
||||
const uint16 SpellFailure = 289;
|
||||
const uint16 ChatChannel = 290;
|
||||
const uint16 Chat1 = 291;
|
||||
const uint16 Chat2 = 292;
|
||||
const uint16 Chat3 = 293;
|
||||
const uint16 Chat4 = 294;
|
||||
const uint16 Chat5 = 295;
|
||||
const uint16 Chat6 = 296;
|
||||
const uint16 Chat7 = 297;
|
||||
const uint16 Chat8 = 298;
|
||||
const uint16 Chat9 = 299;
|
||||
const uint16 Chat10 = 300;
|
||||
const uint16 MeleeCrit = 301;
|
||||
const uint16 SpellCrit = 302;
|
||||
const uint16 TooFarAway = 303;
|
||||
const uint16 NPCRampage = 304;
|
||||
const uint16 NPCFlurry = 305;
|
||||
const uint16 NPCEnrage = 306;
|
||||
const uint16 EchoSay = 307;
|
||||
const uint16 EchoTell = 308;
|
||||
const uint16 EchoGroup = 309;
|
||||
const uint16 EchoGuild = 310;
|
||||
const uint16 EchoOOC = 311;
|
||||
const uint16 EchoAuction = 312;
|
||||
const uint16 EchoShout = 313;
|
||||
const uint16 EchoEmote = 314;
|
||||
const uint16 EchoChat1 = 315;
|
||||
const uint16 EchoChat2 = 316;
|
||||
const uint16 EchoChat3 = 317;
|
||||
const uint16 EchoChat4 = 318;
|
||||
const uint16 EchoChat5 = 319;
|
||||
const uint16 EchoChat6 = 320;
|
||||
const uint16 EchoChat7 = 321;
|
||||
const uint16 EchoChat8 = 322;
|
||||
const uint16 EchoChat9 = 323;
|
||||
const uint16 EchoChat10 = 324;
|
||||
const uint16 DotDamage = 325;
|
||||
const uint16 ItemLink = 326;
|
||||
const uint16 RaidSay = 327;
|
||||
const uint16 MyPet = 328;
|
||||
const uint16 DamageShield = 329;
|
||||
const uint16 LeaderShip = 330;
|
||||
const uint16 PetFlurry = 331;
|
||||
const uint16 PetCritical = 332;
|
||||
const uint16 FocusEffect = 333;
|
||||
const uint16 Experience = 334;
|
||||
const uint16 System = 335;
|
||||
const uint16 PetSpell = 336;
|
||||
const uint16 PetResponse = 337;
|
||||
const uint16 ItemSpeech = 338;
|
||||
const uint16 StrikeThrough = 339;
|
||||
const uint16 Stun = 340;
|
||||
// TODO: Really should combine above and below into one
|
||||
|
||||
//from showeq
|
||||
enum ChatColor
|
||||
{
|
||||
/*
|
||||
CC_Default = 0,
|
||||
CC_DarkGrey = 1,
|
||||
CC_DarkGreen = 2,
|
||||
CC_DarkBlue = 3,
|
||||
CC_Purple = 5,
|
||||
CC_LightGrey = 6,
|
||||
*/
|
||||
|
||||
CC_WhiteSmoke = 0, // FF|F0F0F0
|
||||
CC_Green = 2, // FF|008000
|
||||
CC_BrightBlue = 3, // FF|0040FF
|
||||
CC_Magenta = 5, // FF|F000F0
|
||||
CC_Gray = 6, // FF|808080
|
||||
CC_LightGray = 7, // FF|E0E0E0
|
||||
//CC_WhiteSmoke2 = 10, // FF|F0F0F0
|
||||
CC_DarkGray = 12, // FF|A0A0A0
|
||||
CC_Red = 13, // FF|F00000
|
||||
CC_Lime = 14, // FF|00F000
|
||||
CC_Yellow = 15, // FF|F0F000
|
||||
CC_Blue = 16, // FF|0000F0
|
||||
CC_LightNavy = 17, // FF|0000AF
|
||||
CC_Cyan = 18, // FF|00F0F0
|
||||
CC_Black = 20, // FF|000000
|
||||
|
||||
// any index <= 255 that is not defined above
|
||||
CC_DimGray = 1, // FF|606060
|
||||
CC_Default = 1,
|
||||
|
||||
CC_User_Say = 256,
|
||||
CC_User_Tell = 257,
|
||||
CC_User_Group = 258,
|
||||
CC_User_Guild = 259,
|
||||
CC_User_OOC = 260,
|
||||
CC_User_Auction = 261,
|
||||
CC_User_Shout = 262,
|
||||
CC_User_Emote = 263,
|
||||
CC_User_Spells = 264,
|
||||
CC_User_YouHitOther = 265,
|
||||
CC_User_OtherHitYou = 266,
|
||||
CC_User_YouMissOther = 267,
|
||||
CC_User_OtherMissYou = 268,
|
||||
CC_User_Duels = 269,
|
||||
CC_User_Skills = 270,
|
||||
CC_User_Disciplines = 271,
|
||||
CC_User_Default = 273,
|
||||
CC_User_MerchantOffer = 275,
|
||||
CC_User_MerchantExchange = 276,
|
||||
CC_User_YourDeath = 277,
|
||||
CC_User_OtherDeath = 278,
|
||||
CC_User_OtherHitOther = 279,
|
||||
CC_User_OtherMissOther = 280,
|
||||
CC_User_Who = 281,
|
||||
CC_User_Yell = 282,
|
||||
CC_User_NonMelee = 283,
|
||||
CC_User_SpellWornOff = 284,
|
||||
CC_User_MoneySplit = 285,
|
||||
CC_User_Loot = 286,
|
||||
CC_User_Random = 287,
|
||||
CC_User_OtherSpells = 288,
|
||||
CC_User_SpellFailure = 289,
|
||||
CC_User_ChatChannel = 290,
|
||||
CC_User_Chat1 = 291,
|
||||
CC_User_Chat2 = 292,
|
||||
CC_User_Chat3 = 293,
|
||||
CC_User_Chat4 = 294,
|
||||
CC_User_Chat5 = 295,
|
||||
CC_User_Chat6 = 296,
|
||||
CC_User_Chat7 = 297,
|
||||
CC_User_Chat8 = 298,
|
||||
CC_User_Chat9 = 299,
|
||||
CC_User_Chat10 = 300,
|
||||
CC_User_MeleeCrit = 301,
|
||||
CC_User_SpellCrit = 302,
|
||||
CC_User_TooFarAway = 303,
|
||||
CC_User_NPCRampage = 304,
|
||||
CC_User_NPCFurry = 305,
|
||||
CC_User_NPCEnrage = 306,
|
||||
CC_User_EchoSay = 307,
|
||||
CC_User_EchoTell = 308,
|
||||
CC_User_EchoGroup = 309,
|
||||
CC_User_EchoGuild = 310,
|
||||
CC_User_EchoOOC = 311,
|
||||
CC_User_EchoAuction = 312,
|
||||
CC_User_EchoShout = 313,
|
||||
CC_User_EchoEmote = 314,
|
||||
CC_User_EchoChat1 = 315,
|
||||
CC_User_EchoChat2 = 316,
|
||||
CC_User_EchoChat3 = 317,
|
||||
CC_User_EchoChat4 = 318,
|
||||
CC_User_EchoChat5 = 319,
|
||||
CC_User_EchoChat6 = 320,
|
||||
CC_User_EchoChat7 = 321,
|
||||
CC_User_EchoChat8 = 322,
|
||||
CC_User_EchoChat9 = 323,
|
||||
CC_User_EchoChat10 = 324,
|
||||
CC_User_UnusedAtThisTime = 325,
|
||||
CC_User_ItemTags = 326,
|
||||
CC_User_RaidSay = 327,
|
||||
CC_User_MyPet = 328,
|
||||
CC_User_DamageShield = 329,
|
||||
};
|
||||
|
||||
// generation SQL:
|
||||
// SELECT CONCAT(' constexpr uint16 ', UPPER(short_name), ' = ' , zoneidnumber, '; // ', long_name) from zone group by zoneidnumber ORDER BY zoneidnumber;
|
||||
namespace Zones {
|
||||
constexpr uint16 QEYNOS = 1; // South Qeynos
|
||||
constexpr uint16 QEYNOS2 = 2; // North Qeynos
|
||||
constexpr uint16 QRG = 3; // The Surefall Glade
|
||||
constexpr uint16 QEYTOQRG = 4; // The Qeynos Hills
|
||||
constexpr uint16 HIGHPASS = 5; // Highpass Hold
|
||||
constexpr uint16 HIGHKEEP = 6; // High Keep
|
||||
constexpr uint16 FREPORTN = 8; // North Freeport
|
||||
constexpr uint16 FREPORTW = 9; // West Freeport
|
||||
constexpr uint16 FREPORTE = 10; // East Freeport
|
||||
constexpr uint16 RUNNYEYE = 11; // The Liberated Citadel of Runnyeye
|
||||
constexpr uint16 QEY2HH1 = 12; // The Western Plains of Karana
|
||||
constexpr uint16 NORTHKARANA = 13; // The Northern Plains of Karana
|
||||
constexpr uint16 SOUTHKARANA = 14; // The Southern Plains of Karana
|
||||
constexpr uint16 EASTKARANA = 15; // Eastern Plains of Karana
|
||||
constexpr uint16 BEHOLDER = 16; // Gorge of King Xorbb
|
||||
constexpr uint16 BLACKBURROW = 17; // Blackburrow
|
||||
constexpr uint16 PAW = 18; // The Lair of the Splitpaw
|
||||
constexpr uint16 RIVERVALE = 19; // Rivervale
|
||||
constexpr uint16 KITHICOR = 20; // Kithicor Forest
|
||||
constexpr uint16 COMMONS = 21; // West Commonlands
|
||||
constexpr uint16 ECOMMONS = 22; // East Commonlands
|
||||
constexpr uint16 ERUDNINT = 23; // The Erudin Palace
|
||||
constexpr uint16 ERUDNEXT = 24; // Erudin
|
||||
constexpr uint16 NEKTULOS = 25; // The Nektulos Forest
|
||||
constexpr uint16 CSHOME = 26; // Sunset Home
|
||||
constexpr uint16 LAVASTORM = 27; // The Lavastorm Mountains
|
||||
constexpr uint16 NEKTROPOS = 28; // Nektropos
|
||||
constexpr uint16 HALAS = 29; // Halas
|
||||
constexpr uint16 EVERFROST = 30; // Everfrost Peaks
|
||||
constexpr uint16 SOLDUNGA = 31; // Solusek's Eye
|
||||
constexpr uint16 SOLDUNGB = 32; // Nagafen's Lair
|
||||
constexpr uint16 MISTY = 33; // Misty Thicket
|
||||
constexpr uint16 NRO = 34; // Northern Desert of Ro
|
||||
constexpr uint16 SRO = 35; // Southern Desert of Ro
|
||||
constexpr uint16 BEFALLEN = 36; // Befallen
|
||||
constexpr uint16 OASIS = 37; // Oasis of Marr
|
||||
constexpr uint16 TOX = 38; // Toxxulia Forest
|
||||
constexpr uint16 HOLE = 39; // The Hole
|
||||
constexpr uint16 NERIAKA = 40; // Neriak - Foreign Quarter
|
||||
constexpr uint16 NERIAKB = 41; // Neriak - Commons
|
||||
constexpr uint16 NERIAKC = 42; // Neriak - 3rd Gate
|
||||
constexpr uint16 NERIAKD = 43; // Neriak Palace
|
||||
constexpr uint16 NAJENA = 44; // Najena
|
||||
constexpr uint16 QCAT = 45; // The Qeynos Aqueduct System
|
||||
constexpr uint16 INNOTHULE = 46; // Innothule Swamp
|
||||
constexpr uint16 FEERROTT = 47; // The Feerrott
|
||||
constexpr uint16 CAZICTHULE = 48; // Accursed Temple of CazicThule
|
||||
constexpr uint16 OGGOK = 49; // Oggok
|
||||
constexpr uint16 RATHEMTN = 50; // The Rathe Mountains
|
||||
constexpr uint16 LAKERATHE = 51; // Lake Rathetear
|
||||
constexpr uint16 GROBB = 52; // Grobb
|
||||
constexpr uint16 AVIAK = 53; // Aviak Village
|
||||
constexpr uint16 GFAYDARK = 54; // The Greater Faydark
|
||||
constexpr uint16 AKANON = 55; // Ak'Anon
|
||||
constexpr uint16 STEAMFONT = 56; // Steamfont Mountains
|
||||
constexpr uint16 LFAYDARK = 57; // The Lesser Faydark
|
||||
constexpr uint16 CRUSHBONE = 58; // Crushbone
|
||||
constexpr uint16 MISTMOORE = 59; // The Castle of Mistmoore
|
||||
constexpr uint16 KALADIMA = 60; // South Kaladim
|
||||
constexpr uint16 FELWITHEA = 61; // Northern Felwithe
|
||||
constexpr uint16 FELWITHEB = 62; // Southern Felwithe
|
||||
constexpr uint16 UNREST = 63; // The Estate of Unrest
|
||||
constexpr uint16 KEDGE = 64; // Kedge Keep
|
||||
constexpr uint16 GUKTOP = 65; // The City of Guk
|
||||
constexpr uint16 GUKBOTTOM = 66; // The Ruins of Old Guk
|
||||
constexpr uint16 KALADIMB = 67; // North Kaladim
|
||||
constexpr uint16 BUTCHER = 68; // Butcherblock Mountains
|
||||
constexpr uint16 OOT = 69; // Ocean of Tears
|
||||
constexpr uint16 CAULDRON = 70; // Dagnor's Cauldron
|
||||
constexpr uint16 AIRPLANE = 71; // The Plane of Sky
|
||||
constexpr uint16 FEARPLANE = 72; // The Plane of Fear
|
||||
constexpr uint16 PERMAFROST = 73; // The Permafrost Caverns
|
||||
constexpr uint16 KERRARIDGE = 74; // Kerra Isle
|
||||
constexpr uint16 PAINEEL = 75; // Paineel
|
||||
constexpr uint16 HATEPLANE = 76; // Plane of Hate
|
||||
constexpr uint16 ARENA = 77; // The Arena
|
||||
constexpr uint16 FIELDOFBONE = 78; // The Field of Bone
|
||||
constexpr uint16 WARSLIKSWOOD = 79; // The Warsliks Woods
|
||||
constexpr uint16 SOLTEMPLE = 80; // The Temple of Solusek Ro
|
||||
constexpr uint16 DROGA = 81; // The Temple of Droga
|
||||
constexpr uint16 CABWEST = 82; // Cabilis West
|
||||
constexpr uint16 SWAMPOFNOHOPE = 83; // The Swamp of No Hope
|
||||
constexpr uint16 FIRIONA = 84; // Firiona Vie
|
||||
constexpr uint16 LAKEOFILLOMEN = 85; // Lake of Ill Omen
|
||||
constexpr uint16 DREADLANDS = 86; // The Dreadlands
|
||||
constexpr uint16 BURNINGWOOD = 87; // The Burning Wood
|
||||
constexpr uint16 KAESORA = 88; // Kaesora
|
||||
constexpr uint16 SEBILIS = 89; // The Ruins of Sebilis
|
||||
constexpr uint16 CITYMIST = 90; // The City of Mist
|
||||
constexpr uint16 SKYFIRE = 91; // The Skyfire Mountains
|
||||
constexpr uint16 FRONTIERMTNS = 92; // Frontier Mountains
|
||||
constexpr uint16 OVERTHERE = 93; // The Overthere
|
||||
constexpr uint16 EMERALDJUNGLE = 94; // The Emerald Jungle
|
||||
constexpr uint16 TRAKANON = 95; // Trakanon's Teeth
|
||||
constexpr uint16 TIMOROUS = 96; // Timorous Deep
|
||||
constexpr uint16 KURN = 97; // Kurn's Tower
|
||||
constexpr uint16 ERUDSXING = 98; // Erud's Crossing
|
||||
constexpr uint16 STONEBRUNT = 100; // The Stonebrunt Mountains
|
||||
constexpr uint16 WARRENS = 101; // The Warrens
|
||||
constexpr uint16 KARNOR = 102; // Karnor's Castle
|
||||
constexpr uint16 CHARDOK = 103; // Chardok
|
||||
constexpr uint16 DALNIR = 104; // The Crypt of Dalnir
|
||||
constexpr uint16 CHARASIS = 105; // The Howling Stones
|
||||
constexpr uint16 CABEAST = 106; // Cabilis East
|
||||
constexpr uint16 NURGA = 107; // The Mines of Nurga
|
||||
constexpr uint16 VEESHAN = 108; // Veeshan's Peak
|
||||
constexpr uint16 VEKSAR = 109; // Veksar
|
||||
constexpr uint16 ICECLAD = 110; // The Iceclad Ocean
|
||||
constexpr uint16 FROZENSHADOW = 111; // The Tower of Frozen Shadow
|
||||
constexpr uint16 VELKETOR = 112; // Velketor's Labyrinth
|
||||
constexpr uint16 KAEL = 113; // Kael Drakkel
|
||||
constexpr uint16 SKYSHRINE = 114; // Skyshrine
|
||||
constexpr uint16 THURGADINA = 115; // The City of Thurgadin
|
||||
constexpr uint16 EASTWASTES = 116; // Eastern Wastes
|
||||
constexpr uint16 COBALTSCAR = 117; // Cobaltscar
|
||||
constexpr uint16 GREATDIVIDE = 118; // The Great Divide
|
||||
constexpr uint16 WAKENING = 119; // The Wakening Land
|
||||
constexpr uint16 WESTWASTES = 120; // The Western Wastes
|
||||
constexpr uint16 CRYSTAL = 121; // The Crystal Caverns
|
||||
constexpr uint16 NECROPOLIS = 123; // Dragon Necropolis
|
||||
constexpr uint16 TEMPLEVEESHAN = 124; // The Temple of Veeshan
|
||||
constexpr uint16 SIRENS = 125; // Siren's Grotto
|
||||
constexpr uint16 MISCHIEFPLANE = 126; // The Plane of Mischief
|
||||
constexpr uint16 GROWTHPLANE = 127; // The Plane of Growth
|
||||
constexpr uint16 SLEEPER = 128; // The Sleeper's Tomb
|
||||
constexpr uint16 THURGADINB = 129; // Icewell Keep
|
||||
constexpr uint16 ERUDSXING2 = 130; // Marauders Mire
|
||||
constexpr uint16 SHADOWHAVEN = 150; // Shadow Haven
|
||||
constexpr uint16 BAZAAR = 151; // The Bazaar
|
||||
constexpr uint16 NEXUS = 152; // Nexus
|
||||
constexpr uint16 ECHO_ = 153; // The Echo Caverns
|
||||
constexpr uint16 ACRYLIA = 154; // The Acrylia Caverns
|
||||
constexpr uint16 SHARVAHL = 155; // The City of Shar Vahl
|
||||
constexpr uint16 PALUDAL = 156; // The Paludal Caverns
|
||||
constexpr uint16 FUNGUSGROVE = 157; // The Fungus Grove
|
||||
constexpr uint16 VEXTHAL = 158; // Vex Thal
|
||||
constexpr uint16 SSERU = 159; // Sanctus Seru
|
||||
constexpr uint16 KATTA = 160; // Katta Castellum
|
||||
constexpr uint16 NETHERBIAN = 161; // Netherbian Lair
|
||||
constexpr uint16 SSRATEMPLE = 162; // Ssraeshza Temple
|
||||
constexpr uint16 GRIEGSEND = 163; // Grieg's End
|
||||
constexpr uint16 THEDEEP = 164; // The Deep
|
||||
constexpr uint16 SHADEWEAVER = 165; // Shadeweaver's Thicket
|
||||
constexpr uint16 HOLLOWSHADE = 166; // Hollowshade Moor
|
||||
constexpr uint16 GRIMLING = 167; // Grimling Forest
|
||||
constexpr uint16 MSERU = 168; // Marus Seru
|
||||
constexpr uint16 LETALIS = 169; // Mons Letalis
|
||||
constexpr uint16 TWILIGHT = 170; // The Twilight Sea
|
||||
constexpr uint16 THEGREY = 171; // The Grey
|
||||
constexpr uint16 TENEBROUS = 172; // The Tenebrous Mountains
|
||||
constexpr uint16 MAIDEN = 173; // The Maiden's Eye
|
||||
constexpr uint16 DAWNSHROUD = 174; // The Dawnshroud Peaks
|
||||
constexpr uint16 SCARLET = 175; // The Scarlet Desert
|
||||
constexpr uint16 UMBRAL = 176; // The Umbral Plains
|
||||
constexpr uint16 AKHEVA = 179; // The Akheva Ruins
|
||||
constexpr uint16 ARENA2 = 180; // The Arena Two
|
||||
constexpr uint16 JAGGEDPINE = 181; // The Jaggedpine Forest
|
||||
constexpr uint16 NEDARIA = 182; // Nedaria's Landing
|
||||
constexpr uint16 TUTORIAL = 183; // EverQuest Tutorial
|
||||
constexpr uint16 LOAD = 184; // Loading Zone
|
||||
constexpr uint16 LOAD2 = 185; // New Loading Zone
|
||||
constexpr uint16 HATEPLANEB = 186; // The Plane of Hate
|
||||
constexpr uint16 SHADOWREST = 187; // Shadowrest
|
||||
constexpr uint16 TUTORIALA = 188; // The Mines of Gloomingdeep
|
||||
constexpr uint16 TUTORIALB = 189; // The Mines of Gloomingdeep
|
||||
constexpr uint16 CLZ = 190; // Loading
|
||||
constexpr uint16 CODECAY = 200; // The Crypt of Decay
|
||||
constexpr uint16 POJUSTICE = 201; // The Plane of Justice
|
||||
constexpr uint16 POKNOWLEDGE = 202; // The Plane of Knowledge
|
||||
constexpr uint16 POTRANQUILITY = 203; // The Plane of Tranquility
|
||||
constexpr uint16 PONIGHTMARE = 204; // The Plane of Nightmares
|
||||
constexpr uint16 PODISEASE = 205; // The Plane of Disease
|
||||
constexpr uint16 POINNOVATION = 206; // The Plane of Innovation
|
||||
constexpr uint16 POTORMENT = 207; // Torment, the Plane of Pain
|
||||
constexpr uint16 POVALOR = 208; // The Plane of Valor
|
||||
constexpr uint16 BOTHUNDER = 209; // Bastion of Thunder
|
||||
constexpr uint16 POSTORMS = 210; // The Plane of Storms
|
||||
constexpr uint16 HOHONORA = 211; // The Halls of Honor
|
||||
constexpr uint16 SOLROTOWER = 212; // The Tower of Solusek Ro
|
||||
constexpr uint16 POWAR = 213; // Plane of War
|
||||
constexpr uint16 POTACTICS = 214; // Drunder, the Fortress of Zek
|
||||
constexpr uint16 POAIR = 215; // The Plane of Air
|
||||
constexpr uint16 POWATER = 216; // The Plane of Water
|
||||
constexpr uint16 POFIRE = 217; // The Plane of Fire
|
||||
constexpr uint16 POEARTHA = 218; // The Plane of Earth
|
||||
constexpr uint16 POTIMEA = 219; // The Plane of Time
|
||||
constexpr uint16 HOHONORB = 220; // The Temple of Marr
|
||||
constexpr uint16 NIGHTMAREB = 221; // The Lair of Terris Thule
|
||||
constexpr uint16 POEARTHB = 222; // The Plane of Earth
|
||||
constexpr uint16 POTIMEB = 223; // The Plane of Time
|
||||
constexpr uint16 GUNTHAK = 224; // The Gulf of Gunthak
|
||||
constexpr uint16 DULAK = 225; // Dulak's Harbor
|
||||
constexpr uint16 TORGIRAN = 226; // The Torgiran Mines
|
||||
constexpr uint16 NADOX = 227; // The Crypt of Nadox
|
||||
constexpr uint16 HATESFURY = 228; // Hate's Fury
|
||||
constexpr uint16 GUKA = 229; // Deepest Guk: Cauldron of Lost Souls
|
||||
constexpr uint16 RUJA = 230; // The Rujarkian Hills: Bloodied Quarries
|
||||
constexpr uint16 TAKA = 231; // Takish-Hiz: Sunken Library
|
||||
constexpr uint16 MIRA = 232; // Miragul's Menagerie: Silent Gallery
|
||||
constexpr uint16 MMCA = 233; // Mistmoore's Catacombs: Forlorn Caverns
|
||||
constexpr uint16 GUKB = 234; // The Drowning Crypt
|
||||
constexpr uint16 RUJB = 235; // The Rujarkian Hills: Halls of War
|
||||
constexpr uint16 TAKB = 236; // Takish-Hiz: Shifting Tower
|
||||
constexpr uint16 MIRB = 237; // Miragul's Menagerie: Frozen Nightmare
|
||||
constexpr uint16 MMCB = 238; // Mistmoore's Catacombs: Dreary Grotto
|
||||
constexpr uint16 GUKC = 239; // Deepest Guk: Ancient Aqueducts
|
||||
constexpr uint16 RUJC = 240; // The Rujarkian Hills: Wind Bridges
|
||||
constexpr uint16 TAKC = 241; // Takish-Hiz: Within the Compact
|
||||
constexpr uint16 MIRC = 242; // The Spider Den
|
||||
constexpr uint16 MMCC = 243; // Mistmoore's Catacombs: Struggles within the Progeny
|
||||
constexpr uint16 GUKD = 244; // The Mushroom Grove
|
||||
constexpr uint16 RUJD = 245; // The Rujarkian Hills: Prison Break
|
||||
constexpr uint16 TAKD = 246; // Takish-Hiz: Royal Observatory
|
||||
constexpr uint16 MIRD = 247; // Miragul's Menagerie: Hushed Banquet
|
||||
constexpr uint16 MMCD = 248; // Mistmoore's Catacombs: Chambers of Eternal Affliction
|
||||
constexpr uint16 GUKE = 249; // Deepest Guk: The Curse Reborn
|
||||
constexpr uint16 RUJE = 250; // The Rujarkian Hills: Drudge Hollows
|
||||
constexpr uint16 TAKE = 251; // Takish-Hiz: River of Recollection
|
||||
constexpr uint16 MIRE = 252; // The Frosted Halls
|
||||
constexpr uint16 MMCE = 253; // Mistmoore's Catacombs: Sepulcher of the Damned
|
||||
constexpr uint16 GUKF = 254; // Deepest Guk: Chapel of the Witnesses
|
||||
constexpr uint16 RUJF = 255; // The Rujarkian Hills: Fortified Lair of the Taskmasters
|
||||
constexpr uint16 TAKF = 256; // Takish-Hiz: Sandfall Corridors
|
||||
constexpr uint16 MIRF = 257; // The Forgotten Wastes
|
||||
constexpr uint16 MMCF = 258; // Mistmoore's Catacombs: Scion Lair of Fury
|
||||
constexpr uint16 GUKG = 259; // The Root Garden
|
||||
constexpr uint16 RUJG = 260; // The Rujarkian Hills: Hidden Vale of Deceit
|
||||
constexpr uint16 TAKG = 261; // Takish-Hiz: Balancing Chamber
|
||||
constexpr uint16 MIRG = 262; // Miragul's Menagerie: Heart of the Menagerie
|
||||
constexpr uint16 MMCG = 263; // Mistmoore's Catacombs: Cesspits of Putrescence
|
||||
constexpr uint16 GUKH = 264; // Deepest Guk: Accursed Sanctuary
|
||||
constexpr uint16 RUJH = 265; // The Rujarkian Hills: Blazing Forge
|
||||
constexpr uint16 TAKH = 266; // Takish-Hiz: Sweeping Tides
|
||||
constexpr uint16 MIRH = 267; // The Morbid Laboratory
|
||||
constexpr uint16 MMCH = 268; // Mistmoore's Catacombs: Aisles of Blood
|
||||
constexpr uint16 RUJI = 269; // The Rujarkian Hills: Arena of Chance
|
||||
constexpr uint16 TAKI = 270; // Takish-Hiz: Antiquated Palace
|
||||
constexpr uint16 MIRI = 271; // The Theater of Imprisoned Horror
|
||||
constexpr uint16 MMCI = 272; // Mistmoore's Catacombs: Halls of Sanguinary Rites
|
||||
constexpr uint16 RUJJ = 273; // The Rujarkian Hills: Barracks of War
|
||||
constexpr uint16 TAKJ = 274; // Takish-Hiz: Prismatic Corridors
|
||||
constexpr uint16 MIRJ = 275; // Miragul's Menagerie: Grand Library
|
||||
constexpr uint16 MMCJ = 276; // Mistmoore's Catacombs: Infernal Sanctuary
|
||||
constexpr uint16 CHARDOKB = 277; // Chardok: The Halls of Betrayal
|
||||
constexpr uint16 SOLDUNGC = 278; // The Caverns of Exile
|
||||
constexpr uint16 ABYSMAL = 279; // The Abysmal Sea
|
||||
constexpr uint16 NATIMBI = 280; // Natimbi, the Broken Shores
|
||||
constexpr uint16 QINIMI = 281; // Qinimi, Court of Nihilia
|
||||
constexpr uint16 RIWWI = 282; // Riwwi, Coliseum of Games
|
||||
constexpr uint16 BARINDU = 283; // Barindu, Hanging Gardens
|
||||
constexpr uint16 FERUBI = 284; // Ferubi, Forgotten Temple of Taelosia
|
||||
constexpr uint16 SNPOOL = 285; // Sewers of Nihilia, Pool of Sludg
|
||||
constexpr uint16 SNLAIR = 286; // Sewers of Nihilia, Lair of Trapp
|
||||
constexpr uint16 SNPLANT = 287; // Sewers of Nihilia, Purifying Pla
|
||||
constexpr uint16 SNCREMATORY = 288; // Sewers of Nihilia, Emanating Cre
|
||||
constexpr uint16 TIPT = 289; // Tipt, Treacherous Crags
|
||||
constexpr uint16 VXED = 290; // Vxed, the Crumbling Caverns
|
||||
constexpr uint16 YXTTA = 291; // Yxtta, Pulpit of Exiles
|
||||
constexpr uint16 UQUA = 292; // Uqua, the Ocean God Chantry
|
||||
constexpr uint16 KODTAZ = 293; // Kod'Taz, Broken Trial Grounds
|
||||
constexpr uint16 IKKINZ = 294; // Ikkinz, Chambers of Transcendence
|
||||
constexpr uint16 QVIC = 295; // Qvic, Prayer Grounds of Calling
|
||||
constexpr uint16 INKTUTA = 296; // Inktu'Ta, the Unmasked Chapel
|
||||
constexpr uint16 TXEVU = 297; // Txevu, Lair of the Elite
|
||||
constexpr uint16 TACVI = 298; // Tacvi, The Broken Temple
|
||||
constexpr uint16 QVICB = 299; // Qvic, the Hidden Vault
|
||||
constexpr uint16 WALLOFSLAUGHTER = 300; // Wall of Slaughter
|
||||
constexpr uint16 BLOODFIELDS = 301; // The Bloodfields
|
||||
constexpr uint16 DRANIKSSCAR = 302; // Dranik's Scar
|
||||
constexpr uint16 CAUSEWAY = 303; // Nobles' Causeway
|
||||
constexpr uint16 CHAMBERSA = 304; // Muramite Proving Grounds
|
||||
constexpr uint16 CHAMBERSB = 305; // Muramite Proving Grounds
|
||||
constexpr uint16 CHAMBERSC = 306; // Muramite Proving Grounds
|
||||
constexpr uint16 CHAMBERSD = 307; // Muramite Proving Grounds
|
||||
constexpr uint16 CHAMBERSE = 308; // Muramite Proving Grounds
|
||||
constexpr uint16 CHAMBERSF = 309; // Muramite Proving Grounds
|
||||
constexpr uint16 PROVINGGROUNDS = 316; // Muramite Proving Grounds
|
||||
constexpr uint16 ANGUISH = 317; // Anguish, the Fallen Palace
|
||||
constexpr uint16 DRANIKHOLLOWSA = 318; // Dranik's Hollows
|
||||
constexpr uint16 DRANIKHOLLOWSB = 319; // Dranik's Hollows
|
||||
constexpr uint16 DRANIKHOLLOWSC = 320; // Dranik's Hollows
|
||||
constexpr uint16 DRANIKCATACOMBSA = 328; // Catacombs of Dranik
|
||||
constexpr uint16 DRANIKCATACOMBSB = 329; // Catacombs of Dranik
|
||||
constexpr uint16 DRANIKCATACOMBSC = 330; // Catacombs of Dranik
|
||||
constexpr uint16 DRANIKSEWERSA = 331; // Sewers of Dranik
|
||||
constexpr uint16 DRANIKSEWERSB = 332; // Sewers of Dranik
|
||||
constexpr uint16 DRANIKSEWERSC = 333; // Sewers of Dranik
|
||||
constexpr uint16 RIFTSEEKERS = 334; // Riftseekers' Sanctum
|
||||
constexpr uint16 HARBINGERS = 335; // Harbinger's Spire
|
||||
constexpr uint16 DRANIK = 336; // The Ruined City of Dranik
|
||||
constexpr uint16 BROODLANDS = 337; // The Broodlands
|
||||
constexpr uint16 STILLMOONA = 338; // Stillmoon Temple
|
||||
constexpr uint16 STILLMOONB = 339; // The Ascent
|
||||
constexpr uint16 THUNDERCREST = 340; // Thundercrest Isles
|
||||
constexpr uint16 DELVEA = 341; // Lavaspinner's Lair
|
||||
constexpr uint16 DELVEB = 342; // Tirranun's Delve
|
||||
constexpr uint16 THENEST = 343; // The Nest
|
||||
constexpr uint16 GUILDLOBBY = 344; // Guild Lobby
|
||||
constexpr uint16 GUILDHALL = 345; // Guild Hall
|
||||
constexpr uint16 BARTER = 346; // The Barter Hall
|
||||
constexpr uint16 ILLSALIN = 347; // Ruins of Illsalin
|
||||
constexpr uint16 ILLSALINA = 348; // Illsalin Marketplace
|
||||
constexpr uint16 ILLSALINB = 349; // Temple of Korlach
|
||||
constexpr uint16 ILLSALINC = 350; // The Nargil Pits
|
||||
constexpr uint16 DREADSPIRE = 351; // Dreadspire Keep
|
||||
constexpr uint16 DRACHNIDHIVE = 354; // The Hive
|
||||
constexpr uint16 DRACHNIDHIVEA = 355; // The Hatchery
|
||||
constexpr uint16 DRACHNIDHIVEB = 356; // The Cocoons
|
||||
constexpr uint16 DRACHNIDHIVEC = 357; // Queen Sendaii`s Lair
|
||||
constexpr uint16 WESTKORLACH = 358; // Stoneroot Falls
|
||||
constexpr uint16 WESTKORLACHA = 359; // Prince's Manor
|
||||
constexpr uint16 WESTKORLACHB = 360; // Caverns of the Lost
|
||||
constexpr uint16 WESTKORLACHC = 361; // Lair of the Korlach
|
||||
constexpr uint16 EASTKORLACH = 362; // The Undershore
|
||||
constexpr uint16 EASTKORLACHA = 363; // Snarlstone Dens
|
||||
constexpr uint16 SHADOWSPINE = 364; // Shadow Spine
|
||||
constexpr uint16 CORATHUS = 365; // Corathus Creep
|
||||
constexpr uint16 CORATHUSA = 366; // Sporali Caverns
|
||||
constexpr uint16 CORATHUSB = 367; // The Corathus Mines
|
||||
constexpr uint16 NEKTULOSA = 368; // Shadowed Grove
|
||||
constexpr uint16 ARCSTONE = 369; // Arcstone, Isle of Spirits
|
||||
constexpr uint16 RELIC = 370; // Relic, the Artifact City
|
||||
constexpr uint16 SKYLANCE = 371; // Skylance
|
||||
constexpr uint16 DEVASTATION = 372; // The Devastation
|
||||
constexpr uint16 DEVASTATIONA = 373; // The Seething Wall
|
||||
constexpr uint16 RAGE = 374; // Sverag, Stronghold of Rage
|
||||
constexpr uint16 RAGEA = 375; // Razorthorn, Tower of Sullon Zek
|
||||
constexpr uint16 TAKISHRUINS = 376; // Ruins of Takish-Hiz
|
||||
constexpr uint16 TAKISHRUINSA = 377; // The Root of Ro
|
||||
constexpr uint16 ELDDAR = 378; // The Elddar Forest
|
||||
constexpr uint16 ELDDARA = 379; // Tunare's Shrine
|
||||
constexpr uint16 THEATER = 380; // Theater of Blood
|
||||
constexpr uint16 THEATERA = 381; // Deathknell, Tower of Dissonance
|
||||
constexpr uint16 FREEPORTEAST = 382; // East Freeport
|
||||
constexpr uint16 FREEPORTWEST = 383; // West Freeport
|
||||
constexpr uint16 FREEPORTSEWERS = 384; // Freeport Sewers
|
||||
constexpr uint16 FREEPORTACADEMY = 385; // Academy of Arcane Sciences
|
||||
constexpr uint16 FREEPORTTEMPLE = 386; // Temple of Marr
|
||||
constexpr uint16 FREEPORTMILITIA = 387; // Freeport Militia House: My Precious
|
||||
constexpr uint16 FREEPORTARENA = 388; // Arena
|
||||
constexpr uint16 FREEPORTCITYHALL = 389; // City Hall
|
||||
constexpr uint16 FREEPORTTHEATER = 390; // Theater of the Tranquil
|
||||
constexpr uint16 FREEPORTHALL = 391; // Hall of Truth: Bounty
|
||||
constexpr uint16 NORTHRO = 392; // North Desert of Ro
|
||||
constexpr uint16 SOUTHRO = 393; // South Desert of Ro
|
||||
constexpr uint16 CRESCENT = 394; // Crescent Reach
|
||||
constexpr uint16 MOORS = 395; // Blightfire Moors
|
||||
constexpr uint16 STONEHIVE = 396; // Stone Hive
|
||||
constexpr uint16 MESA = 397; // Goru`kar Mesa
|
||||
constexpr uint16 ROOST = 398; // Blackfeather Roost
|
||||
constexpr uint16 STEPPES = 399; // The Steppes
|
||||
constexpr uint16 ICEFALL = 400; // Icefall Glacier
|
||||
constexpr uint16 VALDEHOLM = 401; // Valdeholm
|
||||
constexpr uint16 FROSTCRYPT = 402; // Frostcrypt, Throne of the Shade King
|
||||
constexpr uint16 SUNDEROCK = 403; // Sunderock Springs
|
||||
constexpr uint16 VERGALID = 404; // Vergalid Mines
|
||||
constexpr uint16 DIREWIND = 405; // Direwind Cliffs
|
||||
constexpr uint16 ASHENGATE = 406; // Ashengate, Reliquary of the Scale
|
||||
constexpr uint16 HIGHPASSHOLD = 407; // Highpass Hold
|
||||
constexpr uint16 COMMONLANDS = 408; // The Commonlands
|
||||
constexpr uint16 OCEANOFTEARS = 409; // The Ocean of Tears
|
||||
constexpr uint16 KITHFOREST = 410; // Kithicor Forest
|
||||
constexpr uint16 BEFALLENB = 411; // Befallen
|
||||
constexpr uint16 HIGHPASSKEEP = 412; // HighKeep
|
||||
constexpr uint16 INNOTHULEB = 413; // The Innothule Swamp
|
||||
constexpr uint16 TOXXULIA = 414; // Toxxulia Forest
|
||||
constexpr uint16 MISTYTHICKET = 415; // The Misty Thicket
|
||||
constexpr uint16 KATTACASTRUM = 416; // Katta Castrum
|
||||
constexpr uint16 THALASSIUS = 417; // Thalassius, the Coral Keep
|
||||
constexpr uint16 ATIIKI = 418; // Jewel of Atiiki
|
||||
constexpr uint16 ZHISZA = 419; // Zhisza, the Shissar Sanctuary
|
||||
constexpr uint16 SILYSSAR = 420; // Silyssar, New Chelsith
|
||||
constexpr uint16 SOLTERIS = 421; // Solteris, the Throne of Ro
|
||||
constexpr uint16 BARREN = 422; // Barren Coast
|
||||
constexpr uint16 BURIEDSEA = 423; // The Buried Sea
|
||||
constexpr uint16 JARDELSHOOK = 424; // Jardel's Hook
|
||||
constexpr uint16 MONKEYROCK = 425; // Monkey Rock
|
||||
constexpr uint16 SUNCREST = 426; // Suncrest Isle
|
||||
constexpr uint16 DEADBONE = 427; // Deadbone Reef
|
||||
constexpr uint16 BLACKSAIL = 428; // Blacksail Folly
|
||||
constexpr uint16 MAIDENSGRAVE = 429; // Maiden's Grave
|
||||
constexpr uint16 REDFEATHER = 430; // Redfeather Isle
|
||||
constexpr uint16 SHIPMVP = 431; // The Open Sea
|
||||
constexpr uint16 SHIPMVU = 432; // The Open Sea
|
||||
constexpr uint16 SHIPPVU = 433; // The Open Sea
|
||||
constexpr uint16 SHIPUVU = 434; // The Open Sea
|
||||
constexpr uint16 SHIPMVM = 435; // The Open Sea
|
||||
constexpr uint16 MECHANOTUS = 436; // Fortress Mechanotus
|
||||
constexpr uint16 MANSION = 437; // Meldrath's Majestic Mansion
|
||||
constexpr uint16 STEAMFACTORY = 438; // The Steam Factory
|
||||
constexpr uint16 SHIPWORKSHOP = 439; // S.H.I.P. Workshop
|
||||
constexpr uint16 GYROSPIREB = 440; // Gyrospire Beza
|
||||
constexpr uint16 GYROSPIREZ = 441; // Gyrospire Zeka
|
||||
constexpr uint16 DRAGONSCALE = 442; // Dragonscale Hills
|
||||
constexpr uint16 LOPINGPLAINS = 443; // Loping Plains
|
||||
constexpr uint16 HILLSOFSHADE = 444; // Hills of Shade
|
||||
constexpr uint16 BLOODMOON = 445; // Bloodmoon Keep
|
||||
constexpr uint16 CRYSTALLOS = 446; // Crystallos, Lair of the Awakened
|
||||
constexpr uint16 GUARDIAN = 447; // The Mechamatic Guardian
|
||||
constexpr uint16 STEAMFONTMTS = 448; // The Steamfont Mountains
|
||||
constexpr uint16 CRYPTOFSHADE = 449; // Crypt of Shade
|
||||
constexpr uint16 DRAGONSCALEB = 451; // Deepscar's Den
|
||||
constexpr uint16 OLDFIELDOFBONE = 452; // Field of Scale
|
||||
constexpr uint16 OLDKAESORAA = 453; // Kaesora Library
|
||||
constexpr uint16 OLDKAESORAB = 454; // Kaesora Hatchery
|
||||
constexpr uint16 OLDKURN = 455; // Kurn's Tower
|
||||
constexpr uint16 OLDKITHICOR = 456; // Bloody Kithicor
|
||||
constexpr uint16 OLDCOMMONS = 457; // Old Commonlands
|
||||
constexpr uint16 OLDHIGHPASS = 458; // Highpass Hold
|
||||
constexpr uint16 THEVOIDA = 459; // The Void
|
||||
constexpr uint16 THEVOIDB = 460; // The Void
|
||||
constexpr uint16 THEVOIDC = 461; // The Void
|
||||
constexpr uint16 THEVOIDD = 462; // The Void
|
||||
constexpr uint16 THEVOIDE = 463; // The Void
|
||||
constexpr uint16 THEVOIDF = 464; // The Void
|
||||
constexpr uint16 THEVOIDG = 465; // The Void
|
||||
constexpr uint16 OCEANGREENHILLS = 466; // Oceangreen Hills
|
||||
constexpr uint16 OCEANGREENVILLAGE = 467; // Oceangreen Village
|
||||
constexpr uint16 OLDBLACKBURROW = 468; // BlackBurrow
|
||||
constexpr uint16 BERTOXTEMPLE = 469; // Temple of Bertoxxulous
|
||||
constexpr uint16 DISCORD = 470; // Korafax, Home of the Riders
|
||||
constexpr uint16 DISCORDTOWER = 471; // Citadel of the Worldslayer
|
||||
constexpr uint16 OLDBLOODFIELD = 472; // Old Bloodfields
|
||||
constexpr uint16 PRECIPICEOFWAR = 473; // The Precipice of War
|
||||
constexpr uint16 OLDDRANIK = 474; // City of Dranik
|
||||
constexpr uint16 TOSKIRAKK = 475; // Toskirakk
|
||||
constexpr uint16 KORASCIAN = 476; // Korascian Warrens
|
||||
constexpr uint16 RATHECHAMBER = 477; // Rathe Council Chamber
|
||||
constexpr uint16 BRELLSREST = 480; // Brell's Rest
|
||||
constexpr uint16 FUNGALFOREST = 481; // Fungal Forest
|
||||
constexpr uint16 UNDERQUARRY = 482; // The Underquarry
|
||||
constexpr uint16 COOLINGCHAMBER = 483; // The Cooling Chamber
|
||||
constexpr uint16 SHININGCITY = 484; // Kernagir, the Shining City
|
||||
constexpr uint16 ARTHICREX = 485; // Arthicrex
|
||||
constexpr uint16 FOUNDATION = 486; // The Foundation
|
||||
constexpr uint16 LICHENCREEP = 487; // Lichen Creep
|
||||
constexpr uint16 PELLUCID = 488; // Pellucid Grotto
|
||||
constexpr uint16 STONESNAKE = 489; // Volska's Husk
|
||||
constexpr uint16 BRELLSTEMPLE = 490; // Brell's Temple
|
||||
constexpr uint16 CONVORTEUM = 491; // The Convorteum
|
||||
constexpr uint16 BRELLSARENA = 492; // Brell's Arena
|
||||
constexpr uint16 WEDDINGCHAPEL = 493; // Wedding Chapel
|
||||
constexpr uint16 WEDDINGCHAPELDARK = 494; // Wedding Chapel
|
||||
constexpr uint16 DRAGONCRYPT = 495; // Lair of the Risen
|
||||
constexpr uint16 FEERROTT2 = 700; // The Feerrott
|
||||
constexpr uint16 THULEHOUSE1 = 701; // House of Thule
|
||||
constexpr uint16 THULEHOUSE2 = 702; // House of Thule, Upper Floors
|
||||
constexpr uint16 HOUSEGARDEN = 703; // The Grounds
|
||||
constexpr uint16 THULELIBRARY = 704; // The Library
|
||||
constexpr uint16 WELL = 705; // The Well
|
||||
constexpr uint16 FALLEN = 706; // Erudin Burning
|
||||
constexpr uint16 MORELLCASTLE = 707; // Morell's Castle
|
||||
constexpr uint16 SOMNIUM = 708; // Sanctum Somnium
|
||||
constexpr uint16 ALKABORMARE = 709; // Al'Kabor's Nightmare
|
||||
constexpr uint16 MIRAGULMARE = 710; // Miragul's Nightmare
|
||||
constexpr uint16 THULEDREAM = 711; // Fear Itself
|
||||
constexpr uint16 NEIGHBORHOOD = 712; // Sunrise Hills
|
||||
constexpr uint16 ARGATH = 724; // Argath, Bastion of Illdaera
|
||||
constexpr uint16 ARELIS = 725; // Valley of Lunanyn
|
||||
constexpr uint16 SARITHCITY = 726; // Sarith, City of Tides
|
||||
constexpr uint16 RUBAK = 727; // Rubak Oseka, Temple of the Sea
|
||||
constexpr uint16 BEASTDOMAIN = 728; // Beasts' Domain
|
||||
constexpr uint16 RESPLENDENT = 729; // The Resplendent Temple
|
||||
constexpr uint16 PILLARSALRA = 730; // Pillars of Alra
|
||||
constexpr uint16 WINDSONG = 731; // Windsong Sanctuary
|
||||
constexpr uint16 CITYOFBRONZE = 732; // Erillion, City of Bronze
|
||||
constexpr uint16 SEPULCHER = 733; // Sepulcher of Order
|
||||
constexpr uint16 EASTSEPULCHER = 734; // Sepulcher East
|
||||
constexpr uint16 WESTSEPULCHER = 735; // Sepulcher West
|
||||
constexpr uint16 SHARDSLANDING = 752; // Shard's Landing
|
||||
constexpr uint16 XORBB = 753; // Valley of King Xorbb
|
||||
constexpr uint16 KAELSHARD = 754; // Kael Drakkel: The King's Madness
|
||||
constexpr uint16 EASTWASTESSHARD = 755; // East Wastes: Zeixshi-Kar's Awakening
|
||||
constexpr uint16 CRYSTALSHARD = 756; // The Crystal Caverns: Fragment of Fear
|
||||
constexpr uint16 BREEDINGGROUNDS = 757; // The Breeding Grounds
|
||||
constexpr uint16 EVILTREE = 758; // Evantil, the Vile Oak
|
||||
constexpr uint16 GRELLETH = 759; // Grelleth's Palace, the Chateau of Filth
|
||||
constexpr uint16 CHAPTERHOUSE = 760; // Chapterhouse of the Fallen
|
||||
constexpr uint16 ARTTEST = 996; // Art Testing Domain
|
||||
constexpr uint16 FHALLS = 998; // The Forgotten Halls
|
||||
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
||||
}
|
||||
//ZoneChange_Struct->success values
|
||||
#define ZONE_ERROR_NOMSG 0
|
||||
#define ZONE_ERROR_NOTREADY -1
|
||||
#define ZONE_ERROR_VALIDPC -2
|
||||
#define ZONE_ERROR_STORYZONE -3
|
||||
#define ZONE_ERROR_NOEXPANSION -6
|
||||
#define ZONE_ERROR_NOEXPERIENCE -7
|
||||
|
||||
|
||||
typedef enum {
|
||||
@@ -712,7 +316,7 @@ typedef enum {
|
||||
FilterPetMisses = 21, //0=show, 1=hide
|
||||
FilterFocusEffects = 22, //0=show, 1=hide
|
||||
FilterPetSpells = 23, //0=show, 1=hide
|
||||
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
||||
FilterHealOverTime = 24, //0=show, 1=hide
|
||||
FilterUnknown25 = 25,
|
||||
FilterUnknown26 = 26,
|
||||
FilterUnknown27 = 27,
|
||||
@@ -799,7 +403,7 @@ static const uint8 DamageTypeUnknown = 0xFF;
|
||||
**
|
||||
** (indexed by 'Skill' of SkillUseTypes)
|
||||
*/
|
||||
static const uint8 SkillDamageTypes[EQ::skills::HIGHEST_SKILL + 1] = // change to _SkillServerArraySize once activated
|
||||
static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // change to _SkillServerArraySize once activated
|
||||
{
|
||||
/*1HBlunt*/ 0,
|
||||
/*1HSlashing*/ 1,
|
||||
@@ -919,130 +523,4 @@ static const uint8 SkillDamageTypes[EQ::skills::HIGHEST_SKILL + 1] = // change t
|
||||
|
||||
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
|
||||
|
||||
static const uint32 DB_FACTION_GEM_CHOPPERS = 255;
|
||||
static const uint32 DB_FACTION_HERETICS = 265;
|
||||
static const uint32 DB_FACTION_KING_AKANON = 333;
|
||||
|
||||
enum ChatChannelNames : uint16
|
||||
{
|
||||
ChatChannel_Guild = 0,
|
||||
ChatChannel_Group = 2,
|
||||
ChatChannel_Shout = 3,
|
||||
ChatChannel_Auction = 4,
|
||||
ChatChannel_OOC = 5,
|
||||
ChatChannel_Broadcast = 6,
|
||||
ChatChannel_Tell = 7,
|
||||
ChatChannel_Say = 8,
|
||||
ChatChannel_Petition = 10,
|
||||
ChatChannel_GMSAY = 11,
|
||||
ChatChannel_TellEcho = 14,
|
||||
ChatChannel_Raid = 15,
|
||||
|
||||
ChatChannel_UNKNOWN_Guild = 17,
|
||||
ChatChannel_UNKNOWN_GMSAY = 18,
|
||||
ChatChannel_UCSRelay = 20,
|
||||
ChatChannel_Emotes = 22
|
||||
};
|
||||
|
||||
namespace ZoneBlockedSpellTypes {
|
||||
const uint8 ZoneWide = 1;
|
||||
const uint8 Region = 2;
|
||||
};
|
||||
|
||||
enum class DynamicZoneType
|
||||
{
|
||||
None = 0,
|
||||
Expedition,
|
||||
Tutorial,
|
||||
Task,
|
||||
Mission, // Shared Task
|
||||
Quest
|
||||
};
|
||||
|
||||
enum class DynamicZoneMemberStatus : uint8_t
|
||||
{
|
||||
Unknown = 0,
|
||||
Online,
|
||||
Offline,
|
||||
InDynamicZone,
|
||||
LinkDead
|
||||
};
|
||||
|
||||
enum LDoNThemes {
|
||||
Unused = 0,
|
||||
GUK,
|
||||
MIR,
|
||||
MMC,
|
||||
RUJ,
|
||||
TAK
|
||||
};
|
||||
|
||||
enum LDoNThemeBits {
|
||||
UnusedBit = 0,
|
||||
GUKBit = 1,
|
||||
MIRBit = 2,
|
||||
MMCBit = 4,
|
||||
RUJBit = 8,
|
||||
TAKBit = 16
|
||||
};
|
||||
|
||||
enum StartZoneIndex {
|
||||
Odus = 0,
|
||||
Qeynos,
|
||||
Halas,
|
||||
Rivervale,
|
||||
Freeport,
|
||||
Neriak,
|
||||
Grobb,
|
||||
Oggok,
|
||||
Kaladim,
|
||||
GreaterFaydark,
|
||||
Felwithe,
|
||||
Akanon,
|
||||
Cabilis,
|
||||
SharVahl
|
||||
};
|
||||
|
||||
enum FVNoDropFlagRule
|
||||
{
|
||||
Disabled = 0,
|
||||
Enabled = 1,
|
||||
AdminOnly = 2
|
||||
};
|
||||
|
||||
enum Anonymity : uint8
|
||||
{
|
||||
NotAnonymous,
|
||||
Anonymous,
|
||||
Roleplaying
|
||||
};
|
||||
|
||||
enum ZoningMessage : int8 {
|
||||
ZoneNoMessage = 0,
|
||||
ZoneSuccess = 1,
|
||||
ZoneNotReady = -1,
|
||||
ZoneValidPC = -2,
|
||||
ZoneStoryZone = -3,
|
||||
ZoneNoExpansion = -6,
|
||||
ZoneNoExperience = -7
|
||||
};
|
||||
|
||||
enum class RecipeCountType : uint8
|
||||
{
|
||||
Component,
|
||||
Container,
|
||||
Fail,
|
||||
Salvage,
|
||||
Success
|
||||
};
|
||||
|
||||
#define ALT_CURRENCY_ID_RADIANT 4
|
||||
#define ALT_CURRENCY_ID_EBON 5
|
||||
|
||||
enum ResurrectionActions
|
||||
{
|
||||
Decline,
|
||||
Accept
|
||||
};
|
||||
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
+882
-1148
File diff suppressed because it is too large
Load Diff
+41
-209
@@ -20,6 +20,7 @@
|
||||
#ifndef COMMON_EQ_LIMITS_H
|
||||
#define COMMON_EQ_LIMITS_H
|
||||
|
||||
#include "emu_legacy.h"
|
||||
#include "types.h"
|
||||
#include "eq_constants.h"
|
||||
#include "emu_versions.h"
|
||||
@@ -31,168 +32,12 @@
|
||||
#include "../common/patches/rof2_limits.h"
|
||||
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
void InitializeDynamicLookups();
|
||||
|
||||
namespace constants {
|
||||
struct LookupEntry {
|
||||
EQ::expansions::Expansion Expansion;
|
||||
uint32 ExpansionBit;
|
||||
uint32 ExpansionsMask;
|
||||
int16 CharacterCreationLimit;
|
||||
size_t SayLinkBodySize;
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
EQ::expansions::Expansion Expansion,
|
||||
uint32 ExpansionBit,
|
||||
uint32 ExpansionsMask,
|
||||
int16 CharacterCreationLimit,
|
||||
size_t SayLinkBodySize
|
||||
) :
|
||||
Expansion(Expansion),
|
||||
ExpansionBit(ExpansionBit),
|
||||
ExpansionsMask(ExpansionsMask),
|
||||
CharacterCreationLimit(CharacterCreationLimit),
|
||||
SayLinkBodySize(SayLinkBodySize)
|
||||
{ }
|
||||
};
|
||||
|
||||
void InitializeDynamicLookups();
|
||||
|
||||
const LookupEntry* DynamicLookup(versions::ClientVersion client_version, bool gm_flag);
|
||||
const LookupEntry* DynamicNonGMLookup(versions::ClientVersion client_version);
|
||||
const LookupEntry* DynamicGMLookup(versions::ClientVersion client_version);
|
||||
const LookupEntry* StaticLookup(versions::ClientVersion client_version);
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace inventory {
|
||||
struct LookupEntry {
|
||||
// note: 'PossessionsBitmask' needs to be attuned to the client version with the highest number
|
||||
// of possessions slots and 'InventoryTypeSize[typePossessions]' should reflect the same count
|
||||
// with translators adjusting for valid slot indices. Server-side validations will be performed
|
||||
// against 'PossessionsBitmask' (note: the same applies to CorpseBitmask..size is not dependent)
|
||||
|
||||
struct InventoryTypeSize_Struct { // should reflect count and naming conventions referenced in emu_constants.h
|
||||
int16 Possessions, Bank, SharedBank;
|
||||
int16 Trade, World, Limbo;
|
||||
int16 Tribute, TrophyTribute, GuildTribute;
|
||||
int16 Merchant, Deleted, Corpse;
|
||||
int16 Bazaar, Inspect, RealEstate;
|
||||
int16 ViewMODPC, ViewMODBank, ViewMODSharedBank;
|
||||
int16 ViewMODLimbo, AltStorage, Archived;
|
||||
int16 Mail, GuildTrophyTribute, Krono;
|
||||
int16 Other;
|
||||
|
||||
InventoryTypeSize_Struct(
|
||||
int16 Possessions, int16 Bank, int16 SharedBank,
|
||||
int16 Trade, int16 World, int16 Limbo,
|
||||
int16 Tribute, int16 TrophyTribute, int16 GuildTribute,
|
||||
int16 Merchant, int16 Deleted, int16 Corpse,
|
||||
int16 Bazaar, int16 Inspect, int16 RealEstate,
|
||||
int16 ViewMODPC, int16 ViewMODBank, int16 ViewMODSharedBank,
|
||||
int16 ViewMODLimbo, int16 AltStorage, int16 Archived,
|
||||
int16 Mail, int16 GuildTrophyTribute, int16 Krono,
|
||||
int16 Other
|
||||
) :
|
||||
Possessions(Possessions), Bank(Bank), SharedBank(SharedBank),
|
||||
Trade(Trade), World(World), Limbo(Limbo),
|
||||
Tribute(Tribute), TrophyTribute(TrophyTribute), GuildTribute(GuildTribute),
|
||||
Merchant(Merchant), Deleted(Deleted), Corpse(Corpse),
|
||||
Bazaar(Bazaar), Inspect(Inspect), RealEstate(RealEstate),
|
||||
ViewMODPC(ViewMODPC), ViewMODBank(ViewMODBank), ViewMODSharedBank(ViewMODSharedBank),
|
||||
ViewMODLimbo(ViewMODLimbo), AltStorage(AltStorage), Archived(Archived),
|
||||
Mail(Mail), GuildTrophyTribute(GuildTrophyTribute), Krono(Krono),
|
||||
Other(Other)
|
||||
{ }
|
||||
};
|
||||
|
||||
union {
|
||||
InventoryTypeSize_Struct InventoryTypeSize;
|
||||
int16 InventoryTypeSizeArray[25]; // should reflect EQ::invtype::TYPE_COUNT referenced in emu_constants.h
|
||||
};
|
||||
|
||||
uint64 EquipmentBitmask;
|
||||
uint64 GeneralBitmask;
|
||||
uint64 CursorBitmask;
|
||||
uint64 PossessionsBitmask;
|
||||
uint64 CorpseBitmask;
|
||||
int16 BagSlotCount;
|
||||
int16 AugSocketCount;
|
||||
|
||||
bool AllowEmptyBagInBag;
|
||||
bool AllowClickCastFromBag;
|
||||
bool ConcatenateInvTypeLimbo;
|
||||
bool AllowOverLevelEquipment;
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
InventoryTypeSize_Struct InventoryTypeSize,
|
||||
uint64 EquipmentBitmask,
|
||||
uint64 GeneralBitmask,
|
||||
uint64 CursorBitmask,
|
||||
uint64 PossessionsBitmask,
|
||||
uint64 CorpseBitmask,
|
||||
int16 BagSlotCount,
|
||||
int16 AugSocketCount,
|
||||
bool AllowEmptyBagInBag,
|
||||
bool AllowClickCastFromBag,
|
||||
bool ConcatenateInvTypeLimbo,
|
||||
bool AllowOverLevelEquipment
|
||||
) :
|
||||
InventoryTypeSize(InventoryTypeSize),
|
||||
EquipmentBitmask(EquipmentBitmask),
|
||||
GeneralBitmask(GeneralBitmask),
|
||||
CursorBitmask(CursorBitmask),
|
||||
PossessionsBitmask(PossessionsBitmask),
|
||||
CorpseBitmask(CorpseBitmask),
|
||||
BagSlotCount(BagSlotCount),
|
||||
AugSocketCount(AugSocketCount),
|
||||
AllowEmptyBagInBag(AllowEmptyBagInBag),
|
||||
AllowClickCastFromBag(AllowClickCastFromBag),
|
||||
ConcatenateInvTypeLimbo(ConcatenateInvTypeLimbo),
|
||||
AllowOverLevelEquipment(AllowOverLevelEquipment)
|
||||
{ }
|
||||
};
|
||||
|
||||
void InitializeDynamicLookups();
|
||||
|
||||
const LookupEntry* DynamicLookup(versions::MobVersion mob_version, bool gm_flag);
|
||||
const LookupEntry* DynamicNonGMLookup(versions::MobVersion mob_version);
|
||||
const LookupEntry* DynamicGMLookup(versions::MobVersion mob_version);
|
||||
const LookupEntry* StaticLookup(versions::MobVersion mob_version);
|
||||
|
||||
} /*inventory*/
|
||||
|
||||
namespace behavior {
|
||||
struct LookupEntry {
|
||||
bool CoinHasWeight;
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
bool CoinHasWeight
|
||||
) :
|
||||
CoinHasWeight(CoinHasWeight)
|
||||
{ }
|
||||
};
|
||||
|
||||
void InitializeDynamicLookups();
|
||||
|
||||
const LookupEntry* DynamicLookup(versions::MobVersion mob_version, bool gm_flag);
|
||||
const LookupEntry* DynamicNonGMLookup(versions::MobVersion mob_version);
|
||||
const LookupEntry* DynamicGMLookup(versions::MobVersion mob_version);
|
||||
const LookupEntry* StaticLookup(versions::MobVersion mob_version);
|
||||
|
||||
} /*behavior*/
|
||||
|
||||
namespace spells {
|
||||
struct LookupEntry {
|
||||
int SpellIdMax;
|
||||
int SpellbookSize;
|
||||
int SpellGemCount;
|
||||
|
||||
class LookupEntry {
|
||||
public:
|
||||
size_t CharacterCreationLimit;
|
||||
int LongBuffs;
|
||||
int ShortBuffs;
|
||||
int DiscBuffs;
|
||||
@@ -200,69 +45,56 @@ namespace EQ
|
||||
int NPCBuffs;
|
||||
int PetBuffs;
|
||||
int MercBuffs;
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
int SpellIdMax,
|
||||
int SpellbookSize,
|
||||
int SpellGemCount,
|
||||
int LongBuffs,
|
||||
int ShortBuffs,
|
||||
int DiscBuffs,
|
||||
int TotalBuffs,
|
||||
int NPCBuffs,
|
||||
int PetBuffs,
|
||||
int MercBuffs
|
||||
) :
|
||||
SpellIdMax(SpellIdMax),
|
||||
SpellbookSize(SpellbookSize),
|
||||
SpellGemCount(SpellGemCount),
|
||||
LongBuffs(LongBuffs),
|
||||
ShortBuffs(ShortBuffs),
|
||||
DiscBuffs(DiscBuffs),
|
||||
TotalBuffs(TotalBuffs),
|
||||
NPCBuffs(NPCBuffs),
|
||||
PetBuffs(PetBuffs),
|
||||
MercBuffs(MercBuffs)
|
||||
{ }
|
||||
};
|
||||
|
||||
void InitializeDynamicLookups();
|
||||
|
||||
const LookupEntry* DynamicLookup(versions::ClientVersion client_version, bool gm_flag);
|
||||
const LookupEntry* DynamicNonGMLookup(versions::ClientVersion client_version);
|
||||
const LookupEntry* DynamicGMLookup(versions::ClientVersion client_version);
|
||||
const LookupEntry* StaticLookup(versions::ClientVersion client_version);
|
||||
|
||||
} /*spells*/
|
||||
const LookupEntry* Lookup(versions::ClientVersion client_version);
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace inventory {
|
||||
class LookupEntry {
|
||||
public:
|
||||
size_t InventoryTypeSize[25]; // should reflect EQEmu::inventory::typeCount referenced in emu_constants.h
|
||||
|
||||
uint64 PossessionsBitmask;
|
||||
size_t ItemBagSize;
|
||||
size_t ItemAugSize;
|
||||
|
||||
bool AllowEmptyBagInBag;
|
||||
bool AllowClickCastFromBag;
|
||||
bool ConcatenateInvTypeLimbo;
|
||||
bool AllowOverLevelEquipment;
|
||||
};
|
||||
|
||||
const LookupEntry* Lookup(versions::MobVersion mob_version);
|
||||
|
||||
} /*inventory*/
|
||||
|
||||
namespace behavior {
|
||||
class LookupEntry {
|
||||
public:
|
||||
bool CoinHasWeight;
|
||||
};
|
||||
|
||||
const LookupEntry* Lookup(versions::MobVersion mob_version);
|
||||
|
||||
} /*behavior*/
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
namespace ClientUnknown
|
||||
{
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace constants {
|
||||
const EQ::expansions::Expansion EXPANSION = EQ::expansions::Expansion::EverQuest;
|
||||
const uint32 EXPANSION_BIT = EQ::expansions::bitEverQuest;
|
||||
const uint32 EXPANSIONS_MASK = EQ::expansions::maskEverQuest;
|
||||
|
||||
} // namespace constants
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} /*ClientUnknown*/
|
||||
|
||||
namespace Client62
|
||||
{
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
enum : int { Invalid = -1, Null, Safety };
|
||||
|
||||
namespace constants {
|
||||
const EQ::expansions::Expansion EXPANSION = EQ::expansions::Expansion::EverQuest;
|
||||
const uint32 EXPANSION_BIT = EQ::expansions::bitEverQuest;
|
||||
const uint32 EXPANSIONS_MASK = EQ::expansions::maskEverQuest;
|
||||
|
||||
} // namespace constants
|
||||
enum : bool { False = false, True = true };
|
||||
|
||||
} /*Client62*/
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ protected:
|
||||
EmuOpcode emu_opcode;
|
||||
|
||||
EQPacket(EmuOpcode opcode, const unsigned char *buf, const uint32 len);
|
||||
EQPacket(EmuOpcode opcode, SerializeBuffer &buf) : BasePacket(buf), emu_opcode(opcode) { };
|
||||
// EQPacket(const EQPacket &p) { }
|
||||
EQPacket() { emu_opcode=OP_Unknown; pBuffer=nullptr; size=0; }
|
||||
|
||||
@@ -105,8 +104,6 @@ public:
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op, SerializeBuffer &buf) : EQPacket(op, buf), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
bool combine(const EQApplicationPacket *rhs);
|
||||
uint32 serialize (uint16 opcode, unsigned char *dest) const;
|
||||
uint32 Size() const { return size+app_opcode_size; }
|
||||
|
||||
+193
-429
@@ -29,14 +29,12 @@
|
||||
#include "textures.h"
|
||||
|
||||
|
||||
static const uint32 BUFF_COUNT = 42;
|
||||
static const uint32 BUFF_COUNT = 25;
|
||||
static const uint32 PET_BUFF_COUNT = 30;
|
||||
static const uint32 MAX_MERC = 100;
|
||||
static const uint32 MAX_MERC_GRADES = 10;
|
||||
static const uint32 MAX_MERC_STANCES = 10;
|
||||
static const uint32 BLOCKED_BUFF_COUNT = 20;
|
||||
static const uint32 QUESTREWARD_COUNT = 8;
|
||||
static const uint32 ADVANCED_LORE_LENGTH = 8192;
|
||||
|
||||
|
||||
/*
|
||||
@@ -129,7 +127,7 @@ struct LDoNTrapTemplate
|
||||
|
||||
// All clients translate the character select information to some degree
|
||||
|
||||
struct CharSelectEquip : EQ::textures::Texture_Struct, EQ::textures::Tint_Struct {};
|
||||
struct CharSelectEquip : EQEmu::textures::Texture_Struct, EQEmu::textures::Tint_Struct {};
|
||||
|
||||
// RoF2-based hybrid struct
|
||||
struct CharacterSelectEntry_Struct
|
||||
@@ -144,7 +142,7 @@ struct CharacterSelectEntry_Struct
|
||||
uint16 Instance;
|
||||
uint8 Gender;
|
||||
uint8 Face;
|
||||
CharSelectEquip Equip[EQ::textures::materialCount];
|
||||
CharSelectEquip Equip[EQEmu::textures::materialCount];
|
||||
uint8 Unknown15; // Seen FF
|
||||
uint8 Unknown19; // Seen FF
|
||||
uint32 DrakkinTattoo;
|
||||
@@ -253,7 +251,7 @@ struct Spawn_Struct {
|
||||
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
|
||||
/*0193*/ uint8 guildrank; // 0=normal, 1=officer, 2=leader
|
||||
/*0194*/ uint8 unknown0194[3];
|
||||
/*0197*/ EQ::TextureProfile equipment;
|
||||
/*0197*/ EQEmu::TextureProfile equipment;
|
||||
/*0233*/ float runspeed; // Speed when running
|
||||
/*0036*/ uint8 afk; // 0=no, 1=afk
|
||||
/*0238*/ uint32 guildID; // Current guild
|
||||
@@ -284,7 +282,7 @@ union
|
||||
/*0340*/ uint32 spawnId; // Spawn Id
|
||||
/*0344*/ float bounding_radius; // used in melee, overrides calc
|
||||
/*0347*/ uint8 IsMercenary;
|
||||
/*0348*/ EQ::TintProfile equipment_tint;
|
||||
/*0348*/ EQEmu::TintProfile equipment_tint;
|
||||
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
||||
/*0385*/
|
||||
|
||||
@@ -308,6 +306,7 @@ union
|
||||
uint32 DestructibleUnk9;
|
||||
bool targetable_with_hotkey;
|
||||
bool show_name;
|
||||
|
||||
};
|
||||
|
||||
struct PlayerState_Struct {
|
||||
@@ -374,19 +373,10 @@ struct NewZone_Struct {
|
||||
/*0684*/ uint16 zone_id;
|
||||
/*0686*/ uint16 zone_instance;
|
||||
/*0688*/ uint32 unknown688;
|
||||
/*0692*/ uint8 unknown692[8];
|
||||
// Titanium doesn't have a translator, but we can still safely add stuff under here without issues since client memcpy's only what it knows
|
||||
// Just wastes some bandwidth sending to tit clients /shrug
|
||||
/*0700*/ float fog_density;
|
||||
/*0704*/ uint32 suspend_buffs;
|
||||
/*0708*/ uint32 fast_regen_hp;
|
||||
/*0712*/ uint32 fast_regen_mana;
|
||||
/*0716*/ uint32 fast_regen_endurance;
|
||||
/*0720*/ uint32 npc_aggro_max_dist;
|
||||
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
|
||||
/*0728*/ uint32 lava_damage; // Seen 50
|
||||
/*0732*/ uint32 min_lava_damage; // Seen 10
|
||||
/*0736*/
|
||||
/*0692*/ uint8 unknown692[8];
|
||||
/*0700*/ float fog_density;
|
||||
/*0704*/ uint32 SuspendBuffs;
|
||||
/*0704*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -448,7 +438,6 @@ struct ManaChange_Struct
|
||||
/*08*/ uint32 spell_id;
|
||||
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
|
||||
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
|
||||
/*16*/ int32 slot; // -1 normal, otherwise clear ETA and GCD
|
||||
};
|
||||
|
||||
struct SwapSpell_Struct
|
||||
@@ -742,7 +731,7 @@ struct BandolierItem_Struct
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[EQ::profile::BANDOLIER_ITEM_COUNT];
|
||||
BandolierItem_Struct Items[EQEmu::legacy::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
@@ -756,7 +745,7 @@ struct PotionBeltItem_Struct
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[EQ::profile::POTION_BELT_SIZE];
|
||||
PotionBeltItem_Struct Items[EQEmu::legacy::POTION_BELT_ITEM_COUNT];
|
||||
};
|
||||
|
||||
struct MovePotionToBelt_Struct
|
||||
@@ -832,7 +821,7 @@ struct LeadershipAA_Struct {
|
||||
* Size: 20 Octets
|
||||
*/
|
||||
struct BindStruct {
|
||||
/*000*/ uint32 zone_id;
|
||||
/*000*/ uint32 zoneId;
|
||||
/*004*/ float x;
|
||||
/*008*/ float y;
|
||||
/*012*/ float z;
|
||||
@@ -847,7 +836,7 @@ struct SuspendedMinion_Struct
|
||||
/*002*/ uint32 HP;
|
||||
/*006*/ uint32 Mana;
|
||||
/*010*/ SpellBuff_Struct Buffs[BUFF_COUNT];
|
||||
/*510*/ EQ::TextureMaterialProfile Items;
|
||||
/*510*/ EQEmu::TextureMaterialProfile Items;
|
||||
/*546*/ char Name[64];
|
||||
/*610*/
|
||||
};
|
||||
@@ -860,6 +849,10 @@ struct SuspendedMinion_Struct
|
||||
** OpCode: 0x006a
|
||||
*/
|
||||
static const uint32 MAX_PP_LANGUAGE = 28;
|
||||
static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions
|
||||
static const uint32 MAX_PP_MEMSPELL = static_cast<uint32>(EQEmu::CastingSlot::MaxGems); // Set to latest client so functions can work right -- 12
|
||||
static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain
|
||||
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
|
||||
|
||||
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_INNATE_SKILL = 25;
|
||||
@@ -917,7 +910,7 @@ sed -e 's/_t//g' -e 's/MAX_AA/MAX_PP_AA_ARRAY/g' \
|
||||
|
||||
struct PlayerProfile_Struct
|
||||
{
|
||||
// /*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum
|
||||
/*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum
|
||||
/*0004*/ char name[64]; // Name of player sizes not right
|
||||
/*0068*/ char last_name[32]; // Last name of player sizes not right
|
||||
/*0100*/ uint32 gender; // Player Gender - 0 Male, 1 Female
|
||||
@@ -939,7 +932,7 @@ struct PlayerProfile_Struct
|
||||
/*0245*/ uint8 guildbanker;
|
||||
/*0246*/ uint8 unknown0246[6]; //
|
||||
/*0252*/ uint32 intoxication;
|
||||
/*0256*/ uint32 spellSlotRefresh[EQ::spells::SPELL_GEM_COUNT]; //in ms
|
||||
/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms
|
||||
/*0292*/ uint32 abilitySlotRefresh;
|
||||
/*0296*/ uint8 haircolor; // Player hair color
|
||||
/*0297*/ uint8 beardcolor; // Player beard color
|
||||
@@ -952,9 +945,9 @@ struct PlayerProfile_Struct
|
||||
/*0304*/ uint8 ability_time_minutes;
|
||||
/*0305*/ uint8 ability_time_hours; //place holder
|
||||
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
|
||||
/*0312*/ EQ::TextureMaterialProfile item_material; // Item texture/material of worn/held items
|
||||
/*0312*/ EQEmu::TextureMaterialProfile item_material; // Item texture/material of worn/held items
|
||||
/*0348*/ uint8 unknown0348[44];
|
||||
/*0392*/ EQ::TintProfile item_tint;
|
||||
/*0392*/ EQEmu::TintProfile item_tint;
|
||||
/*0428*/ AA_Array aa_array[MAX_PP_AA_ARRAY];
|
||||
/*2348*/ float unknown2384; //seen ~128, ~47
|
||||
/*2352*/ char servername[32]; // length probably not right
|
||||
@@ -978,9 +971,9 @@ struct PlayerProfile_Struct
|
||||
/*2505*/ uint8 unknown2541[47]; // ?
|
||||
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
|
||||
/*2580*/ uint8 unknown2616[4];
|
||||
/*2584*/ uint32 spell_book[EQ::spells::SPELLBOOK_SIZE];
|
||||
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
|
||||
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
|
||||
/*4632*/ uint32 mem_spells[EQ::spells::SPELL_GEM_COUNT];
|
||||
/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL];
|
||||
/*4668*/ uint8 unknown4704[32]; //
|
||||
/*4700*/ float y; // Player y position
|
||||
/*4704*/ float x; // Player x position
|
||||
@@ -1056,7 +1049,7 @@ struct PlayerProfile_Struct
|
||||
/*7212*/ uint32 tribute_points;
|
||||
/*7216*/ uint32 unknown7252;
|
||||
/*7220*/ uint32 tribute_active; //1=active
|
||||
/*7224*/ Tribute_Struct tributes[EQ::invtype::TRIBUTE_SIZE];
|
||||
/*7224*/ Tribute_Struct tributes[EQEmu::legacy::TRIBUTE_SIZE];
|
||||
/*7264*/ Disciplines_Struct disciplines;
|
||||
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
|
||||
/*7744*/ char unknown7780[160];
|
||||
@@ -1083,7 +1076,7 @@ struct PlayerProfile_Struct
|
||||
/*12800*/ uint32 expAA;
|
||||
/*12804*/ uint32 aapoints; //avaliable, unspent
|
||||
/*12808*/ uint8 unknown12844[36];
|
||||
/*12844*/ Bandolier_Struct bandoliers[EQ::profile::BANDOLIERS_SIZE];
|
||||
/*12844*/ Bandolier_Struct bandoliers[EQEmu::legacy::BANDOLIERS_SIZE];
|
||||
/*14124*/ uint8 unknown14160[4506];
|
||||
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
|
||||
/*19240*/ uint32 timeentitledonaccount;
|
||||
@@ -1099,18 +1092,6 @@ struct PlayerProfile_Struct
|
||||
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
|
||||
/*19564*/ uint32 RestTimer;
|
||||
/*19568*/
|
||||
|
||||
// All player profile packets are translated and this overhead is ignored in out-bound packets
|
||||
PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { }
|
||||
|
||||
EQ::versions::MobVersion PlayerProfileVersion() { return m_player_profile_version; }
|
||||
void SetPlayerProfileVersion(EQ::versions::MobVersion mob_version) { m_player_profile_version = EQ::versions::ValidateMobVersion(mob_version); }
|
||||
void SetPlayerProfileVersion(EQ::versions::ClientVersion client_version) { SetPlayerProfileVersion(EQ::versions::ConvertClientVersionToMobVersion(client_version)); }
|
||||
|
||||
private:
|
||||
// No need for gm flag since pp already has one
|
||||
// No need for lookup pointer since this struct is not tied to any one system
|
||||
EQ::versions::MobVersion m_player_profile_version;
|
||||
};
|
||||
|
||||
|
||||
@@ -1196,33 +1177,19 @@ struct SpecialMesg_Struct
|
||||
/*24*/ char message[1]; // What is being said?
|
||||
};
|
||||
|
||||
struct SpecialMesgHeader_Struct
|
||||
{
|
||||
/*00*/ char SpeakMode; // 2 shouts, 4 %1 %2, 3 %2, 5 tells group, 0 copy, default says
|
||||
/*01*/ char JournalMode; // 1 and 2 go to journal
|
||||
/*02*/ char language;
|
||||
/*03*/ uint32 msg_type; // Color of text (see MT_*** below)
|
||||
/*07*/ uint32 target_spawn_id; // Who is it being said to?
|
||||
/*11*/ // speaker's name
|
||||
/*xx*/ // unknown, location, client doesn't care
|
||||
/*xx*/ // unknown
|
||||
/*xx*/ // unknown
|
||||
/*xx*/ // message
|
||||
};
|
||||
|
||||
/*
|
||||
** When somebody changes what they're wearing or give a pet a weapon (model changes)
|
||||
** Length: 19 Bytes
|
||||
*/
|
||||
struct WearChange_Struct {
|
||||
/*000*/ uint16 spawn_id;
|
||||
/*002*/ uint32 material;
|
||||
/*006*/ uint32 unknown06;
|
||||
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
|
||||
/*014*/ uint32 hero_forge_model; // New to VoA
|
||||
/*018*/ uint32 unknown18; // New to RoF
|
||||
/*022*/ EQ::textures::Tint_Struct color;
|
||||
/*026*/ uint8 wear_slot_id;
|
||||
struct WearChange_Struct{
|
||||
/*000*/ uint16 spawn_id;
|
||||
/*002*/ uint32 material;
|
||||
/*006*/ uint32 unknown06;
|
||||
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
|
||||
/*014*/ uint32 hero_forge_model; // New to VoA
|
||||
/*018*/ uint32 unknown18; // New to RoF
|
||||
/*022*/ EQEmu::textures::Tint_Struct color;
|
||||
/*026*/ uint8 wear_slot_id;
|
||||
/*027*/
|
||||
};
|
||||
|
||||
@@ -1366,24 +1333,21 @@ struct BecomeCorpse_Struct {
|
||||
*/
|
||||
struct PlayerPositionUpdateServer_Struct
|
||||
{
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 vehicle_id;
|
||||
/*0004*/ signed padding0004 : 12;
|
||||
signed y_pos : 19; // y coord
|
||||
unsigned padding : 1;
|
||||
/*0008*/ signed delta_z : 13; // change in z
|
||||
signed delta_x : 13; // change in x
|
||||
signed padding0008 : 6;
|
||||
/*0012*/ signed x_pos : 19; // x coord
|
||||
unsigned heading : 12; // heading
|
||||
signed padding0016 : 1;
|
||||
/*0016*/ signed delta_heading : 10; // change in heading
|
||||
signed z_pos : 19; // z coord
|
||||
signed padding0020 : 3;
|
||||
/*0020*/ signed animation : 10; // animation
|
||||
signed delta_y : 13; // change in y
|
||||
signed padding0024 : 9;
|
||||
/*0024*/
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ int32 delta_heading:10, // change in heading
|
||||
x_pos:19, // x coord
|
||||
padding0002:3; // ***Placeholder
|
||||
/*0006*/ int32 y_pos:19, // y coord
|
||||
animation:10, // animation
|
||||
padding0006:3; // ***Placeholder
|
||||
/*0010*/ int32 z_pos:19, // z coord
|
||||
delta_y:13; // change in y
|
||||
/*0014*/ int32 delta_x:13, // change in x
|
||||
heading:12, // heading
|
||||
padding0014:7; // ***Placeholder
|
||||
/*0018*/ int32 delta_z:13, // change in z
|
||||
padding0018:19; // ***Placeholder
|
||||
/*0022*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1394,23 +1358,21 @@ struct PlayerPositionUpdateServer_Struct
|
||||
*/
|
||||
struct PlayerPositionUpdateClient_Struct
|
||||
{
|
||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
||||
/*0010*/ float delta_x; // Change in x
|
||||
/*0014*/ unsigned heading : 12; // Directional heading
|
||||
unsigned padding0040 : 20; // ***Placeholder
|
||||
/*0018*/ float x_pos; // x coord (2nd loc value)
|
||||
/*0022*/ float delta_z; // Change in z
|
||||
/*0026*/ float z_pos; // z coord (3rd loc value)
|
||||
/*0030*/ float y_pos; // y coord (1st loc value)
|
||||
/*0034*/ unsigned animation : 10; // ***Placeholder
|
||||
unsigned padding0024 : 22; // animation
|
||||
/*0038*/ float delta_y; // Change in y
|
||||
/*0042*/ signed delta_heading : 10; // change in heading
|
||||
unsigned padding0041 : 22; // ***Placeholder
|
||||
/*0046*/
|
||||
/*0000*/ uint16 spawn_id;
|
||||
/*0002*/ uint16 sequence; //increments one each packet
|
||||
/*0004*/ float y_pos; // y coord
|
||||
/*0008*/ float delta_z; // Change in z
|
||||
/*0012*/ float delta_x; // Change in x
|
||||
/*0016*/ float delta_y; // Change in y
|
||||
/*0020*/ int32 animation:10, // animation
|
||||
delta_heading:10, // change in heading
|
||||
padding0020:12; // ***Placeholder (mostly 1)
|
||||
/*0024*/ float x_pos; // x coord
|
||||
/*0028*/ float z_pos; // z coord
|
||||
/*0032*/ uint16 heading:12, // Directional heading
|
||||
padding0004:4; // ***Placeholder
|
||||
/*0034*/ uint8 unknown0006[2]; // ***Placeholder
|
||||
/*0036*/
|
||||
};
|
||||
|
||||
struct SpawnPositionUpdate_Struct
|
||||
@@ -1775,7 +1737,7 @@ struct GMZoneRequest_Struct {
|
||||
/*0068*/ float x;
|
||||
/*0072*/ float y;
|
||||
/*0076*/ float z;
|
||||
/*0080*/ float heading;
|
||||
/*0080*/ char unknown0080[4];
|
||||
/*0084*/ uint32 success; // 0 if command failed, 1 if succeeded?
|
||||
/*0088*/
|
||||
// /*072*/ int8 success; // =0 client->server, =1 server->client, -X=specific error
|
||||
@@ -1821,15 +1783,6 @@ struct CombatAbility_Struct {
|
||||
uint32 m_skill;
|
||||
};
|
||||
|
||||
// Disarm Struct incoming from Client [Size: 16]
|
||||
struct Disarm_Struct
|
||||
{
|
||||
uint32 source;
|
||||
uint32 target;
|
||||
uint32 skill;
|
||||
uint32 unknown;
|
||||
};
|
||||
|
||||
//Instill Doubt
|
||||
struct Instill_Doubt_Struct {
|
||||
uint8 i_id;
|
||||
@@ -2129,36 +2082,36 @@ struct AdventureLeaderboard_Struct
|
||||
/*struct Item_Shop_Struct {
|
||||
uint16 merchantid;
|
||||
uint8 itemtype;
|
||||
EQ::ItemData item;
|
||||
EQEmu::ItemData item;
|
||||
uint8 iss_unknown001[6];
|
||||
};*/
|
||||
|
||||
struct Illusion_Struct { //size: 256 - SoF
|
||||
/*000*/ uint32 spawnid;
|
||||
/*004*/ char charname[64]; //
|
||||
/*068*/ uint16 race; //
|
||||
/*070*/ char unknown006[2];
|
||||
/*072*/ uint8 gender;
|
||||
/*073*/ uint8 texture;
|
||||
/*074*/ uint8 unknown008; //
|
||||
/*075*/ uint8 unknown009; //
|
||||
/*076*/ uint8 helmtexture; //
|
||||
/*077*/ uint8 unknown010; //
|
||||
/*078*/ uint8 unknown011; //
|
||||
/*079*/ uint8 unknown012; //
|
||||
/*080*/ uint32 face; //
|
||||
/*084*/ uint8 hairstyle; //
|
||||
/*085*/ uint8 haircolor; //
|
||||
/*086*/ uint8 beard; //
|
||||
/*087*/ uint8 beardcolor; //
|
||||
/*088*/ float size; //
|
||||
/*092*/ uint32 drakkin_heritage; //
|
||||
/*096*/ uint32 drakkin_tattoo; //
|
||||
/*100*/ uint32 drakkin_details; //
|
||||
/*104*/ EQ::TintProfile armor_tint; //
|
||||
/*140*/ uint8 eyecolor1; // Field Not Identified in any Illusion Struct
|
||||
/*141*/ uint8 eyecolor2; // Field Not Identified in any Illusion Struct
|
||||
/*142*/ uint8 unknown138[114]; //
|
||||
/*000*/ uint32 spawnid;
|
||||
/*004*/ char charname[64]; //
|
||||
/*068*/ uint16 race; //
|
||||
/*070*/ char unknown006[2];
|
||||
/*072*/ uint8 gender;
|
||||
/*073*/ uint8 texture;
|
||||
/*074*/ uint8 unknown008; //
|
||||
/*075*/ uint8 unknown009; //
|
||||
/*076*/ uint8 helmtexture; //
|
||||
/*077*/ uint8 unknown010; //
|
||||
/*078*/ uint8 unknown011; //
|
||||
/*079*/ uint8 unknown012; //
|
||||
/*080*/ uint32 face; //
|
||||
/*084*/ uint8 hairstyle; //
|
||||
/*085*/ uint8 haircolor; //
|
||||
/*086*/ uint8 beard; //
|
||||
/*087*/ uint8 beardcolor; //
|
||||
/*088*/ float size; //
|
||||
/*092*/ uint32 drakkin_heritage; //
|
||||
/*096*/ uint32 drakkin_tattoo; //
|
||||
/*100*/ uint32 drakkin_details; //
|
||||
/*104*/ EQEmu::TintProfile armor_tint; //
|
||||
/*140*/ uint8 eyecolor1; // Field Not Identified in any Illusion Struct
|
||||
/*141*/ uint8 eyecolor2; // Field Not Identified in any Illusion Struct
|
||||
/*142*/ uint8 unknown138[114]; //
|
||||
/*256*/
|
||||
};
|
||||
|
||||
@@ -2188,23 +2141,22 @@ struct QuestReward_Struct
|
||||
/*024*/ uint32 silver; // Gives silver to the client
|
||||
/*028*/ uint32 gold; // Gives gold to the client
|
||||
/*032*/ uint32 platinum; // Gives platinum to the client
|
||||
/*036*/ int32 item_id[QUESTREWARD_COUNT]; // -1 for nothing
|
||||
/*036*/ uint32 item_id;
|
||||
/*040*/ uint32 unknown040;
|
||||
/*044*/ uint32 unknown044;
|
||||
/*048*/ uint32 unknown048;
|
||||
/*052*/ uint32 unknown052;
|
||||
/*056*/ uint32 unknown056;
|
||||
/*060*/ uint32 unknown060;
|
||||
/*064*/ uint32 unknown064;
|
||||
/*068*/
|
||||
};
|
||||
|
||||
struct CashReward_Struct
|
||||
{
|
||||
/*000*/ uint32 copper;
|
||||
/*004*/ uint32 silver;
|
||||
/*008*/ uint32 gold;
|
||||
/*012*/ uint32 platinum;
|
||||
};
|
||||
|
||||
// Size: 8
|
||||
struct Camera_Struct
|
||||
{
|
||||
uint32 duration; // Duration in ms
|
||||
float intensity;
|
||||
uint32 intensity; // Between 1023410176 and 1090519040
|
||||
};
|
||||
|
||||
struct ZonePoint_Entry {
|
||||
@@ -2324,12 +2276,9 @@ struct FaceChange_Struct {
|
||||
/*004*/ uint8 hairstyle;
|
||||
/*005*/ uint8 beard;
|
||||
/*006*/ uint8 face;
|
||||
/*007*/ uint8 unused_padding;
|
||||
/*008*/ uint32 drakkin_heritage;
|
||||
/*012*/ uint32 drakkin_tattoo;
|
||||
/*016*/ uint32 drakkin_details;
|
||||
/*020*/ uint32 entity_id;
|
||||
/*024*/
|
||||
/*007*/ uint32 drakkin_heritage;
|
||||
/*011*/ uint32 drakkin_tattoo;
|
||||
/*015*/ uint32 drakkin_details;
|
||||
//there are only 10 faces for barbs changing woad just
|
||||
//increase the face value by ten so if there were 8 woad
|
||||
//designs then there would be 80 barb faces
|
||||
@@ -2773,7 +2722,7 @@ struct EnvDamage2_Struct {
|
||||
/*0004*/ uint16 unknown4;
|
||||
/*0006*/ uint32 damage;
|
||||
/*0010*/ uint8 unknown10[12];
|
||||
/*0022*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
|
||||
/*0022*/ uint8 dmgtype; //FA = Lava; FC = Falling
|
||||
/*0023*/ uint8 unknown2[4];
|
||||
/*0027*/ uint16 constant; //Always FFFF
|
||||
/*0029*/ uint16 unknown29;
|
||||
@@ -2984,12 +2933,6 @@ struct ItemViewRequest_Struct {
|
||||
/*046*/ char unknown046[2];
|
||||
};
|
||||
|
||||
struct ItemAdvancedLoreText_Struct {
|
||||
int32 item_id;
|
||||
char item_name[64];
|
||||
char advanced_lore[ADVANCED_LORE_LENGTH];
|
||||
};
|
||||
|
||||
struct LDONItemViewRequest_Struct {
|
||||
uint32 item_id;
|
||||
uint8 unknown004[4];
|
||||
@@ -3261,7 +3204,7 @@ struct TraderClick_Struct{
|
||||
};
|
||||
|
||||
struct FormattedMessage_Struct{
|
||||
uint32 unknown0; // 1 means from world server
|
||||
uint32 unknown0;
|
||||
uint32 string_id;
|
||||
uint32 type;
|
||||
char message[0];
|
||||
@@ -3269,7 +3212,7 @@ struct FormattedMessage_Struct{
|
||||
struct SimpleMessage_Struct{
|
||||
uint32 string_id;
|
||||
uint32 color;
|
||||
uint32 unknown8; // 1 means from world server
|
||||
uint32 unknown8;
|
||||
};
|
||||
|
||||
struct GuildMemberUpdate_Struct {
|
||||
@@ -3506,8 +3449,8 @@ struct SelectTributeReply_Struct {
|
||||
|
||||
struct TributeInfo_Struct {
|
||||
uint32 active; //0 == inactive, 1 == active
|
||||
uint32 tributes[EQ::invtype::TRIBUTE_SIZE]; //-1 == NONE
|
||||
uint32 tiers[EQ::invtype::TRIBUTE_SIZE]; //all 00's
|
||||
uint32 tributes[EQEmu::legacy::TRIBUTE_SIZE]; //-1 == NONE
|
||||
uint32 tiers[EQEmu::legacy::TRIBUTE_SIZE]; //all 00's
|
||||
uint32 tribute_master_id;
|
||||
};
|
||||
|
||||
@@ -3632,19 +3575,14 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
|
||||
};
|
||||
|
||||
struct MerchantList {
|
||||
uint32 id;
|
||||
uint32 slot;
|
||||
uint32 item;
|
||||
int16 faction_required;
|
||||
int8 level_required;
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
uint16 alt_currency_cost;
|
||||
uint32 classes_required;
|
||||
uint8 probability;
|
||||
std::string bucket_name;
|
||||
std::string bucket_value;
|
||||
uint8 bucket_comparison;
|
||||
uint32 id;
|
||||
uint32 slot;
|
||||
uint32 item;
|
||||
int16 faction_required;
|
||||
int8 level_required;
|
||||
uint16 alt_currency_cost;
|
||||
uint32 classes_required;
|
||||
uint8 probability;
|
||||
};
|
||||
|
||||
struct TempMerchantList {
|
||||
@@ -3733,66 +3671,17 @@ struct SetTitleReply_Struct {
|
||||
uint32 entity_id;
|
||||
};
|
||||
|
||||
struct SharedTaskMemberList_Struct {
|
||||
/*00*/ uint32 gopher_id;
|
||||
/*04*/ uint32 unknown04;
|
||||
/*08*/ uint32 member_count; //1 less than the number of members
|
||||
///*12*/ char list_pointer[0];
|
||||
char member_name[1]; //null terminated string
|
||||
uint32 monster_mission; // class chosen
|
||||
uint8 task_leader; //boolean flag
|
||||
|
||||
struct TaskMemberList_Struct {
|
||||
/*00*/ uint32 gopher_id;
|
||||
/*04*/ uint32 unknown04;
|
||||
/*08*/ uint32 member_count; //1 less than the number of members
|
||||
/*12*/ char list_pointer[0];
|
||||
/* list is of the form:
|
||||
char member_name[1] //null terminated string
|
||||
uint8 task_leader //boolean flag
|
||||
*/
|
||||
};
|
||||
|
||||
struct SharedTaskQuit_Struct {
|
||||
int32 field1;
|
||||
int32 field2;
|
||||
int32 field3;
|
||||
};
|
||||
|
||||
struct SharedTaskAddPlayer_Struct {
|
||||
int32 field1;
|
||||
int32 field2;
|
||||
char player_name[64];
|
||||
};
|
||||
|
||||
struct SharedTaskMakeLeader_Struct {
|
||||
int32 field1;
|
||||
int32 field2;
|
||||
char player_name[64];
|
||||
};
|
||||
|
||||
struct SharedTaskRemovePlayer_Struct {
|
||||
int32 field1;
|
||||
int32 field2;
|
||||
char player_name[64];
|
||||
};
|
||||
|
||||
struct SharedTaskInvite_Struct {
|
||||
int32_t unknown00; // probably the unique character id sent in some packets
|
||||
int32_t invite_id; // invite id sent back in response
|
||||
char task_name[64];
|
||||
char inviter_name[64];
|
||||
};
|
||||
|
||||
struct SharedTaskInviteResponse_Struct {
|
||||
int32_t unknown00; // 0
|
||||
int32_t invite_id; // same id sent in the invite, probably for server verification
|
||||
int8_t accepted; // 0: declined 1: accepted
|
||||
int8_t padding[3]; // padding garbage probably
|
||||
};
|
||||
|
||||
struct SharedTaskAccept_Struct {
|
||||
int32_t unknown00;
|
||||
int32_t unknown04;
|
||||
uint32_t npc_entity_id; // npc task giver entity id (sent in selection window)
|
||||
uint32_t task_id;
|
||||
float reward_multiplier; // added after titanium (sent in selection window)
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
// Old struct not used by Task System implementation but left for reference
|
||||
@@ -3885,7 +3774,7 @@ struct TaskHistory_Struct {
|
||||
#endif
|
||||
|
||||
struct AcceptNewTask_Struct {
|
||||
uint32 task_type; // type sent in selection window
|
||||
uint32 unknown00;
|
||||
uint32 task_id; //set to 0 for 'decline'
|
||||
uint32 task_master_id; //entity ID
|
||||
};
|
||||
@@ -3893,7 +3782,7 @@ struct AcceptNewTask_Struct {
|
||||
//was all 0's from client, server replied with same op, all 0's
|
||||
struct CancelTask_Struct {
|
||||
uint32 SequenceNumber;
|
||||
uint32 type; // Only seen 0x00000002
|
||||
uint32 unknown4; // Only seen 0x00000002
|
||||
};
|
||||
|
||||
#if 0
|
||||
@@ -3947,28 +3836,28 @@ struct AvailableTaskTrailer_Struct {
|
||||
struct TaskDescriptionHeader_Struct {
|
||||
uint32 SequenceNumber; // The order the tasks appear in the journal. 0 for first task, 1 for second, etc.
|
||||
uint32 TaskID;
|
||||
uint8 open_window;
|
||||
uint32 task_type;
|
||||
uint32 reward_type; // if this != 4 says Ebon Crystals else Radiant Crystals
|
||||
uint32 unknown2;
|
||||
uint32 unknown3;
|
||||
uint8 unknown4;
|
||||
};
|
||||
|
||||
struct TaskDescriptionData1_Struct {
|
||||
uint32 Duration;
|
||||
uint32 dur_code; // if Duration == 0
|
||||
uint32 unknown2;
|
||||
uint32 StartTime;
|
||||
};
|
||||
|
||||
struct TaskDescriptionData2_Struct {
|
||||
uint8 has_rewards;
|
||||
uint32 coin_reward;
|
||||
uint32 xp_reward;
|
||||
uint32 faction_reward;
|
||||
uint32 RewardCount; // ??
|
||||
uint32 unknown1;
|
||||
uint32 unknown2;
|
||||
uint16 unknown3;
|
||||
//uint8 unknown4;
|
||||
};
|
||||
|
||||
struct TaskDescriptionTrailer_Struct {
|
||||
//uint16 unknown1; // 0x0012
|
||||
uint32 Points;
|
||||
uint8 has_reward_selection; // uses newer reward selection window, not in all clients
|
||||
};
|
||||
|
||||
struct TaskActivityHeader_Struct {
|
||||
@@ -4008,11 +3897,11 @@ struct TaskActivityShort_Struct {
|
||||
|
||||
struct TaskActivityComplete_Struct {
|
||||
uint32 TaskIndex;
|
||||
uint32 TaskType; // task, shared task, quest
|
||||
uint32 TaskID; // must match
|
||||
uint32 unknown2; // 0x00000002
|
||||
uint32 unknown3;
|
||||
uint32 ActivityID;
|
||||
uint32 task_completed; // Broadcasts "Task '%1' Completed" it not 0 and "Task '%1' Failed." if 0
|
||||
uint32 stage_complete; // Broadcasts "Task Stage Completed"
|
||||
uint32 unknown4; // 0x00000001
|
||||
uint32 unknown5; // 0x00000001
|
||||
};
|
||||
|
||||
#if 0
|
||||
@@ -4359,8 +4248,8 @@ struct AARankPrereq_Struct
|
||||
struct AARankEffect_Struct
|
||||
{
|
||||
int32 effect_id;
|
||||
int32 base_value;
|
||||
int32 limit_value;
|
||||
int32 base1;
|
||||
int32 base2;
|
||||
int32 slot;
|
||||
};
|
||||
|
||||
@@ -4368,8 +4257,8 @@ struct AARankEffect_Struct
|
||||
|
||||
struct AA_Ability {
|
||||
/*00*/ uint32 skill_id;
|
||||
/*04*/ uint32 base_value;
|
||||
/*08*/ uint32 limit_value;
|
||||
/*04*/ uint32 base1;
|
||||
/*08*/ uint32 base2;
|
||||
/*12*/ uint32 slot;
|
||||
};
|
||||
|
||||
@@ -4472,7 +4361,7 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
};
|
||||
|
||||
struct LoadSpellSet_Struct {
|
||||
uint32 spell[EQ::spells::SPELL_GEM_COUNT]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
|
||||
uint32 spell[MAX_PP_MEMSPELL]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
|
||||
uint32 unknown; //there seems to be an extra field in this packet...
|
||||
};
|
||||
|
||||
@@ -4547,7 +4436,7 @@ struct ItemVerifyReply_Struct {
|
||||
struct ItemRecastDelay_Struct {
|
||||
/*000*/ uint32 recast_delay; // in seconds
|
||||
/*004*/ uint32 recast_type;
|
||||
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
||||
/*008*/ uint32 unknown008;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
@@ -4903,99 +4792,17 @@ struct BuffIcon_Struct
|
||||
BuffIconEntry_Struct entries[0];
|
||||
};
|
||||
|
||||
struct ExpeditionInvite_Struct
|
||||
struct ExpeditionInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id; // unique character id
|
||||
/*004*/ uint32 unknown004; // added after titanium
|
||||
/*008*/ char inviter_name[64];
|
||||
/*072*/ char expedition_name[128];
|
||||
/*200*/ uint8 swapping; // 0: adding 1: swapping
|
||||
/*201*/ char swap_name[64]; // if swapping, swap name being removed
|
||||
/*265*/ uint8 padding[3];
|
||||
/*268*/ uint16 dz_zone_id; // dz_id zone/instance pair, sent back in reply
|
||||
/*270*/ uint16 dz_instance_id;
|
||||
/*000*/ uint32 max_players;
|
||||
/*004*/ char expedition_name[128];
|
||||
/*132*/ char leader_name[64];
|
||||
};
|
||||
|
||||
struct ExpeditionInviteResponse_Struct
|
||||
struct ExpeditionJoinPrompt_Struct
|
||||
{
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint32 unknown004; // added after titanium
|
||||
/*008*/ uint16 dz_zone_id; // dz_id pair sent in invite
|
||||
/*010*/ uint16 dz_instance_id;
|
||||
/*012*/ uint8 accepted; // 0: declined 1: accepted
|
||||
/*013*/ uint8 swapping; // 0: adding 1: swapping (sent in invite)
|
||||
/*014*/ char swap_name[64]; // swap name sent in invite
|
||||
/*078*/ uint8 unknown078; // padding garbage?
|
||||
/*079*/ uint8 unknown079; // padding garbage?
|
||||
};
|
||||
|
||||
struct DynamicZoneInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*004*/ uint32 unknown004; // added after titanium
|
||||
/*008*/ uint32 assigned; // padded bool, 0: clear info, 1: fill window info
|
||||
/*012*/ uint32 max_players;
|
||||
/*016*/ char dz_name[128];
|
||||
/*144*/ char leader_name[64];
|
||||
//*208*/ uint32 dz_type; // only in newer clients, if not 1 (expedition type) window does not auto show when dz info assigned
|
||||
};
|
||||
|
||||
struct DynamicZoneMemberEntry_Struct
|
||||
{
|
||||
/*000*/ char name[64]; // variable length, null terminated, max 0x40 (64)
|
||||
/*064*/ uint8 online_status; // 0: unknown, 1: Online, 2: Offline, 3: In Dynamic Zone, 4: Link Dead
|
||||
};
|
||||
|
||||
struct DynamicZoneMemberList_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*004*/ uint32 member_count;
|
||||
/*008*/ DynamicZoneMemberEntry_Struct members[0]; // variable length
|
||||
};
|
||||
|
||||
struct DynamicZoneMemberListName_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*004*/ uint32 unknown004;
|
||||
/*008*/ uint32 add_name; // padded bool, 0: remove name, 1: add name with unknown status
|
||||
/*012*/ char name[64];
|
||||
};
|
||||
|
||||
struct ExpeditionLockoutTimerEntry_Struct
|
||||
{
|
||||
/*000*/ char expedition_name[128]; // variable length, null terminated, max 0x80 (128)
|
||||
/*000*/ uint32 seconds_remaining;
|
||||
/*000*/ int32 event_type; // seen -1 (0xffffffff) for replay timers and 1 for event timers
|
||||
/*000*/ char event_name[256]; // variable length, null terminated, max 0x100 (256)
|
||||
};
|
||||
|
||||
struct ExpeditionLockoutTimers_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*004*/ uint32 count;
|
||||
/*008*/ ExpeditionLockoutTimerEntry_Struct timers[0];
|
||||
};
|
||||
|
||||
struct DynamicZoneLeaderName_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*004*/ uint32 unknown004;
|
||||
/*008*/ char leader_name[64];
|
||||
};
|
||||
|
||||
struct ExpeditionCommand_Struct
|
||||
{
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint32 unknown004;
|
||||
/*008*/ char name[64];
|
||||
};
|
||||
|
||||
struct ExpeditionCommandSwap_Struct
|
||||
{
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint32 unknown004;
|
||||
/*008*/ char add_player_name[64]; // swap to (player must confirm)
|
||||
/*072*/ char rem_player_name[64]; // swap from
|
||||
/*000*/ char player_name[64];
|
||||
/*064*/ char expedition_name[64];
|
||||
};
|
||||
|
||||
struct ExpeditionExpireWarning
|
||||
@@ -5003,67 +4810,48 @@ struct ExpeditionExpireWarning
|
||||
/*008*/ uint32 minutes_remaining;
|
||||
};
|
||||
|
||||
struct DynamicZoneCompassEntry_Struct
|
||||
struct ExpeditionCompassEntry_Struct
|
||||
{
|
||||
/*000*/ uint16 dz_zone_id; // target dz id pair
|
||||
/*002*/ uint16 dz_instance_id;
|
||||
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
|
||||
/*008*/ uint32 dz_switch_id;
|
||||
/*012*/ float y;
|
||||
/*016*/ float x;
|
||||
/*020*/ float z;
|
||||
/*000*/ uint32 enabled; //guess
|
||||
/*004*/ float y;
|
||||
/*008*/ float x;
|
||||
/*012*/ float z;
|
||||
};
|
||||
|
||||
struct DynamicZoneCompass_Struct
|
||||
struct ExpeditionCompass_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*000*/ uint32 count;
|
||||
/*004*/ DynamicZoneCompassEntry_Struct entries[0];
|
||||
/*004*/ ExpeditionCompassEntry_Struct entries[0];
|
||||
};
|
||||
|
||||
struct DynamicZoneChooseZoneEntry_Struct
|
||||
struct ExpeditionMemberEntry_Struct
|
||||
{
|
||||
/*000*/ uint16 dz_zone_id; // dz_id pair
|
||||
/*002*/ uint16 dz_instance_id;
|
||||
/*004*/ uint32 unknown_id1; // seen 28 00 00 00 (40), sent back in reply
|
||||
/*008*/ uint32 dz_type; // 1: Expedition, 2: Tutorial, 3: Task, 4: Mission, 5: Quest -- sent back in reply
|
||||
/*012*/ uint32 unknown_id2; // possibly an id based on dz type, for expeditions this was same as dz_id (zone|instance) but task dz was different
|
||||
/*016*/ char description[128]; // variable length, null terminated
|
||||
/*144*/ char leader_name[64]; // variable length, null terminated
|
||||
char name[64];
|
||||
char status;
|
||||
};
|
||||
|
||||
struct DynamicZoneChooseZone_Struct
|
||||
struct ExpeditionMemberList_Struct
|
||||
{
|
||||
/*000*/ uint32 client_id;
|
||||
/*004*/ uint32 count;
|
||||
/*008*/ DynamicZoneChooseZoneEntry_Struct choices[0];
|
||||
/*000*/ uint32 count;
|
||||
/*004*/ ExpeditionMemberEntry_Struct entries[0];
|
||||
};
|
||||
|
||||
struct DynamicZoneChooseZoneReply_Struct
|
||||
struct ExpeditionLockoutEntry_Struct
|
||||
{
|
||||
/*000*/ uint32 unknown000; // ff ff ff ff
|
||||
/*004*/ uint32 unknown004; // seen 69 00 00 00
|
||||
/*008*/ uint32 unknown008; // ff ff ff ff
|
||||
/*012*/ uint32 unknown_id1; // from choose zone entry message
|
||||
/*016*/ uint16 dz_zone_id; // dz_id pair
|
||||
/*018*/ uint16 dz_instance_id;
|
||||
/*020*/ uint32 dz_type; // 1: Expedition, 2: Tutorial, 3: Task, 4: Mission, 5: Quest
|
||||
/*024*/ uint32 unknown_id2; // from choose zone entry message
|
||||
/*028*/ uint32 unknown028; // 00 00 00 00
|
||||
/*032*/ uint32 unknown032; // always same as unknown044
|
||||
/*036*/ uint32 unknown036;
|
||||
/*040*/ uint32 unknown040;
|
||||
/*044*/ uint32 unknown044; // always same as unknown032
|
||||
/*048*/ uint32 unknown048; // seen 01 00 00 00 and 02 00 00 00
|
||||
/*000*/ uint32 time_left;
|
||||
/*004*/ char expedition[128];
|
||||
/*132*/ char expedition_event[128];
|
||||
};
|
||||
|
||||
struct KickPlayers_Struct
|
||||
struct ExpeditionLockoutList_Struct
|
||||
{
|
||||
/*000*/ char char_name[64];
|
||||
/*064*/ uint32 unknown064; // always 0
|
||||
/*068*/ uint8 kick_expedition; // true if /kickplayers exp
|
||||
/*069*/ uint8 kick_task; // true if /kickplayers task
|
||||
/*070*/ uint8 padding[2];
|
||||
/*000*/ uint32 count;
|
||||
/*004*/ ExpeditionLockoutEntry_Struct entries[0];
|
||||
};
|
||||
|
||||
struct ExpeditionLeaderSet_Struct
|
||||
{
|
||||
/*000*/ char leader_name[64];
|
||||
};
|
||||
|
||||
struct CorpseDrag_Struct
|
||||
@@ -5165,10 +4953,10 @@ struct AltCurrencySelectItemReply_Struct {
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint8 unknown004; //0xff
|
||||
/*005*/ uint8 unknown005; //0xff
|
||||
/*006*/ uint16 unknown006; //0xffff
|
||||
/*008*/ uint16 unknown008; //0xffff
|
||||
/*010*/ char item_name[64];
|
||||
/*074*/ uint16 unknown074;
|
||||
/*006*/ uint8 unknown006; //0xff
|
||||
/*007*/ uint8 unknown007; //0xff
|
||||
/*008*/ char item_name[64];
|
||||
/*072*/ uint32 unknown074;
|
||||
/*076*/ uint32 cost;
|
||||
/*080*/ uint32 unknown080;
|
||||
/*084*/ uint32 unknown084;
|
||||
@@ -5513,20 +5301,18 @@ struct MercenaryMerchantResponse_Struct {
|
||||
|
||||
struct ServerLootItem_Struct {
|
||||
uint32 item_id; // uint32 item_id;
|
||||
int16 equip_slot; // int16 equip_slot;
|
||||
uint16 charges; // uint8 charges;
|
||||
uint16 lootslot; // uint16 lootslot;
|
||||
uint32 aug_1; // uint32 aug_1;
|
||||
uint32 aug_2; // uint32 aug_2;
|
||||
uint32 aug_3; // uint32 aug_3;
|
||||
uint32 aug_4; // uint32 aug_4;
|
||||
uint32 aug_5; // uint32 aug_5;
|
||||
uint32 aug_6; // uint32 aug_5;
|
||||
uint8 attuned;
|
||||
uint16 trivial_min_level;
|
||||
uint16 trivial_max_level;
|
||||
uint16 npc_min_level;
|
||||
uint16 npc_max_level;
|
||||
int16 equip_slot; // int16 equip_slot;
|
||||
uint16 charges; // uint8 charges;
|
||||
uint16 lootslot; // uint16 lootslot;
|
||||
uint32 aug_1; // uint32 aug_1;
|
||||
uint32 aug_2; // uint32 aug_2;
|
||||
uint32 aug_3; // uint32 aug_3;
|
||||
uint32 aug_4; // uint32 aug_4;
|
||||
uint32 aug_5; // uint32 aug_5;
|
||||
uint32 aug_6; // uint32 aug_5;
|
||||
uint8 attuned;
|
||||
uint8 min_level;
|
||||
uint8 max_level;
|
||||
};
|
||||
|
||||
//Found in client near a ref to the string:
|
||||
@@ -5544,7 +5330,7 @@ struct ClientMarqueeMessage_Struct {
|
||||
uint32 fade_out_time; //The fade out time, in ms
|
||||
uint32 duration; //in ms
|
||||
char msg[1]; //message plus null terminator
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef std::list<ServerLootItem_Struct*> ItemList;
|
||||
@@ -5598,28 +5384,6 @@ struct SayLinkBodyFrame_Struct {
|
||||
/*056*/
|
||||
};
|
||||
|
||||
struct Checksum_Struct {
|
||||
uint64 checksum;
|
||||
uint8 data[2048];
|
||||
};
|
||||
|
||||
struct UpdateMovementEntry {
|
||||
/* 00 */ float Y;
|
||||
/* 04 */ float X;
|
||||
/* 08 */ float Z;
|
||||
/* 12 */ uint8 type;
|
||||
/* 13 */ unsigned int timestamp;
|
||||
/* 17 */
|
||||
};
|
||||
|
||||
struct UnderWorld {
|
||||
/* 00 */ int spawn_id;
|
||||
/* 04 */ float y;
|
||||
/* 08 */ float x;
|
||||
/* 12 */ float z;
|
||||
/* 16 */
|
||||
};
|
||||
|
||||
// Restore structure packing to default
|
||||
#pragma pack()
|
||||
|
||||
|
||||
+111
-111
@@ -23,7 +23,7 @@
|
||||
#include "op_codes.h"
|
||||
#include "crc16.h"
|
||||
#include "platform.h"
|
||||
#include "strings.h"
|
||||
#include "string_util.h"
|
||||
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
@@ -84,14 +84,14 @@ void EQStream::init(bool resetSession) {
|
||||
|
||||
OpMgr = nullptr;
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
LogNetcode(_L "init Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
}
|
||||
|
||||
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
||||
{
|
||||
EQRawApplicationPacket *ap=nullptr;
|
||||
LogNetcode(_L "Creating new application packet, length [{}]" __L, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size);
|
||||
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
|
||||
ap = p->MakeAppPacket();
|
||||
return ap;
|
||||
@@ -100,7 +100,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
||||
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
|
||||
{
|
||||
EQRawApplicationPacket *ap=nullptr;
|
||||
LogNetcode(_L "Creating new application packet, length [{}]" __L, len);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len);
|
||||
ap = new EQRawApplicationPacket(buf, len);
|
||||
return ap;
|
||||
}
|
||||
@@ -130,7 +130,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
}
|
||||
|
||||
if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) {
|
||||
LogNetcode(_L "Session not initialized, packet ignored" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L);
|
||||
// _raw(NET__DEBUG, 0xFFFF, p);
|
||||
return;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
while(processed < p->size) {
|
||||
subpacket_length=*(p->pBuffer+processed);
|
||||
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length);
|
||||
LogNetcode(_L "Extracting combined packet of length [{}]" __L, subpacket_length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length);
|
||||
// _raw(NET__NET_CREATE_HEX, 0xFFFF, subp);
|
||||
subp->copyInfo(p);
|
||||
ProcessPacket(subp);
|
||||
@@ -156,12 +156,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
while(processed<p->size) {
|
||||
EQRawApplicationPacket *ap=nullptr;
|
||||
if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) {
|
||||
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
|
||||
ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length);
|
||||
processed+=subpacket_length+1;
|
||||
} else {
|
||||
subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1));
|
||||
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
|
||||
ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length);
|
||||
processed+=subpacket_length+3;
|
||||
}
|
||||
@@ -176,29 +176,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_Packet: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
LogNetcode(_L "Received OP_Packet that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
SeqOrder check=CompareSequence(NextInSeq,seq);
|
||||
if (check == SeqFuture) {
|
||||
LogNetcode(_L "Future OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
|
||||
PacketQueue[seq]=p->Copy();
|
||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||
|
||||
//SendOutOfOrderAck(seq);
|
||||
|
||||
} else if (check == SeqPast) {
|
||||
LogNetcode(_L "Duplicate OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
SendOutOfOrderAck(seq); //we already got this packet but it was out of order
|
||||
} else {
|
||||
// In case we did queue one before as well.
|
||||
EQProtocolPacket *qp=RemoveQueue(seq);
|
||||
if (qp) {
|
||||
LogNetcode("[NET_TRACE] OP_Packet: Removing older queued packet with sequence [{}]", seq);
|
||||
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq);
|
||||
delete qp;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
// Check for an embedded OP_AppCombinded (protocol level 0x19)
|
||||
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
||||
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2);
|
||||
LogNetcode(_L "seq [{}], Extracting combined packet of length [{}]" __L, seq, subp->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size);
|
||||
// _raw(NET__NET_CREATE_HEX, seq, subp);
|
||||
subp->copyInfo(p);
|
||||
ProcessPacket(subp);
|
||||
@@ -226,29 +226,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_Fragment: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
LogNetcode(_L "Received OP_Fragment that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
SeqOrder check=CompareSequence(NextInSeq,seq);
|
||||
if (check == SeqFuture) {
|
||||
LogNetcode(_L "Future OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
|
||||
PacketQueue[seq]=p->Copy();
|
||||
LogNetcode(_L "OP_Fragment Queue size=[{}]" __L, PacketQueue.size());
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size());
|
||||
|
||||
//SendOutOfOrderAck(seq);
|
||||
|
||||
} else if (check == SeqPast) {
|
||||
LogNetcode(_L "Duplicate OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||
// _raw(NET__DEBUG, seq, p);
|
||||
SendOutOfOrderAck(seq);
|
||||
} else {
|
||||
// In case we did queue one before as well.
|
||||
EQProtocolPacket *qp=RemoveQueue(seq);
|
||||
if (qp) {
|
||||
LogNetcode("[NET_TRACE] OP_Fragment: Removing older queued packet with sequence [{}]", seq);
|
||||
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq);
|
||||
delete qp;
|
||||
}
|
||||
SetNextAckToSend(seq);
|
||||
@@ -256,18 +256,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
if (oversize_buffer) {
|
||||
memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2);
|
||||
oversize_offset+=p->size-2;
|
||||
LogNetcode(_L "Fragment of oversized of length [{}], seq [{}]: now at [{}]/[{}]" __L, p->size-2, seq, oversize_offset, oversize_length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length);
|
||||
if (oversize_offset==oversize_length) {
|
||||
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
||||
EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset);
|
||||
LogNetcode(_L "seq [{}], Extracting combined oversize packet of length [{}]" __L, seq, subp->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size);
|
||||
//// _raw(NET__NET_CREATE_HEX, subp);
|
||||
subp->copyInfo(p);
|
||||
ProcessPacket(subp);
|
||||
delete subp;
|
||||
} else {
|
||||
EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset);
|
||||
LogNetcode(_L "seq [{}], completed combined oversize packet of length [{}]" __L, seq, ap->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size);
|
||||
if (ap) {
|
||||
ap->copyInfo(p);
|
||||
InboundQueuePush(ap);
|
||||
@@ -282,20 +282,20 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
oversize_buffer=new unsigned char[oversize_length];
|
||||
memcpy(oversize_buffer,p->pBuffer+6,p->size-6);
|
||||
oversize_offset=p->size-6;
|
||||
LogNetcode(_L "First fragment of oversized of seq [{}]: now at [{}]/[{}]" __L, seq, oversize_offset, oversize_length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_KeepAlive: {
|
||||
NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size));
|
||||
LogNetcode(_L "Received and queued reply to keep alive" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L);
|
||||
}
|
||||
break;
|
||||
case OP_Ack: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
LogNetcode(_L "Received OP_Ack that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
@@ -309,11 +309,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_SessionRequest: {
|
||||
if(p->Size() < sizeof(SessionRequest))
|
||||
{
|
||||
LogNetcode(_L "Received OP_SessionRequest that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
if (GetState()==ESTABLISHED) {
|
||||
LogNetcode(_L "Received OP_SessionRequest in ESTABLISHED state ([{}]) streamactive ([{}]) attempt ([{}])" __L, GetState(),streamactive,sessionAttempts);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts);
|
||||
|
||||
// client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case
|
||||
// streamactive means we identified the opcode for the stream, we cannot re-establish this connection
|
||||
@@ -331,7 +331,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
SessionRequest *Request=(SessionRequest *)p->pBuffer;
|
||||
Session=ntohl(Request->Session);
|
||||
SetMaxLen(ntohl(Request->MaxLength));
|
||||
LogNetcode(_L "Received OP_SessionRequest: session [{}], maxlen [{}]" __L, (unsigned long)Session, MaxLen);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen);
|
||||
SetState(ESTABLISHED);
|
||||
Key=0x11223344;
|
||||
SendSessionResponse();
|
||||
@@ -340,7 +340,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_SessionResponse: {
|
||||
if(p->Size() < sizeof(SessionResponse))
|
||||
{
|
||||
LogNetcode(_L "Received OP_SessionResponse that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
compressed=(Response->Format&FLAG_COMPRESSED);
|
||||
encoded=(Response->Format&FLAG_ENCODED);
|
||||
|
||||
LogNetcode(_L "Received OP_SessionResponse: session [{}], maxlen [{}], key [{}], compressed? [{}], encoded? [{}]" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
|
||||
|
||||
// Kinda kludgy, but trie for now
|
||||
if (StreamType==UnknownStream) {
|
||||
@@ -379,17 +379,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
EQStreamState state = GetState();
|
||||
if(state == ESTABLISHED) {
|
||||
//client initiated disconnect?
|
||||
LogNetcode(_L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L);
|
||||
_SendDisconnect();
|
||||
SetState(CLOSED);
|
||||
} else if(state == CLOSING) {
|
||||
//we were waiting for this anyways, ignore pending messages, send the reply and be closed.
|
||||
LogNetcode(_L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L);
|
||||
_SendDisconnect();
|
||||
SetState(CLOSED);
|
||||
} else {
|
||||
//we are expecting this (or have already gotten it, but dont care either way)
|
||||
LogNetcode(_L "Received expected OP_SessionDisconnect. Moving to closed state" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L);
|
||||
SetState(CLOSED);
|
||||
}
|
||||
}
|
||||
@@ -397,16 +397,16 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_OutOfOrderAck: {
|
||||
if(!p->pBuffer || (p->Size() < 4))
|
||||
{
|
||||
LogNetcode(_L "Received OP_OutOfOrderAck that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||
MOutboundQueue.lock();
|
||||
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
|
||||
|
||||
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
|
||||
if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L,
|
||||
@@ -414,7 +414,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
|
||||
uint16 sqsize = SequencedQueue.size();
|
||||
uint16 index = seq - SequencedBase;
|
||||
LogNetcode(_L "OP_OutOfOrderAck marking packet acked in queue (queue index = [{}], queue size = [{}])" __L, index, sqsize);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize);
|
||||
if (index < sqsize) {
|
||||
SequencedQueue[index]->acked = true;
|
||||
// flag packets for a resend
|
||||
@@ -423,7 +423,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) {
|
||||
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) {
|
||||
(*sitr)->sent_time = 0;
|
||||
LogNetcode(_L "OP_OutOfOrderAck Flagging packet [{}] for retransmission" __L, SequencedBase + count);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck Flagging packet %d for retransmission" __L, SequencedBase + count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -432,11 +432,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
retransmittimer = Timer::GetCurrentTime();
|
||||
}
|
||||
} else {
|
||||
LogNetcode(_L "Received OP_OutOfOrderAck for out-of-window [{}]. Window ([{}]->[{}])" __L, seq, SequencedBase, NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq);
|
||||
}
|
||||
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
LogNetcode(_L "Post-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
|
||||
MOutboundQueue.unlock();
|
||||
@@ -445,7 +445,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
case OP_SessionStatRequest: {
|
||||
if(p->Size() < sizeof(ClientSessionStats))
|
||||
{
|
||||
LogNetcode(_L "Received OP_SessionStatRequest that was of malformed size" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
|
||||
break;
|
||||
}
|
||||
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
|
||||
@@ -453,7 +453,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
(unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta),
|
||||
(unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta),
|
||||
(unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta));
|
||||
|
||||
|
||||
AdjustRates(ntohl(ClientStats->average_delta));
|
||||
|
||||
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
|
||||
@@ -468,7 +468,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
retransmittimeout += 300;
|
||||
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
|
||||
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
|
||||
LogNetcode(_L "Retransmit timeout recalculated to [{}]ms" __L, retransmittimeout);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,11 +485,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
||||
}
|
||||
break;
|
||||
case OP_SessionStatResponse: {
|
||||
LogNetcode(_L "Received OP_SessionStatResponse. Ignoring" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L);
|
||||
}
|
||||
break;
|
||||
case OP_OutOfSession: {
|
||||
LogNetcode(_L "Received OP_OutOfSession. Ignoring" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -520,7 +520,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
|
||||
return;
|
||||
|
||||
if(OpMgr == nullptr || *OpMgr == nullptr) {
|
||||
LogNetcode(_L "Packet enqueued into a stream with no opcode manager, dropping" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L);
|
||||
delete pack;
|
||||
return;
|
||||
}
|
||||
@@ -559,18 +559,18 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
||||
|
||||
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
|
||||
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
|
||||
LogNetcode(_L "Making oversized packet, len [{}]" __L, p->Size());
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
|
||||
|
||||
auto tmpbuff = new unsigned char[p->size + 3];
|
||||
length=p->serialize(opcode, tmpbuff);
|
||||
if (length != p->Size())
|
||||
LogNetcode(_L "Packet adjustment, len [{}] to [{}]" __L, p->Size(), length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
|
||||
|
||||
auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4);
|
||||
*(uint32 *)(out->pBuffer+2)=htonl(length);
|
||||
used=MaxLen-10;
|
||||
memcpy(out->pBuffer+6,tmpbuff,used);
|
||||
LogNetcode(_L "First fragment: used [{}]/[{}]. Payload size [{}] in the packet" __L, used, length, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
|
||||
SequencedPush(out);
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
||||
out->size=chunksize+2;
|
||||
SequencedPush(out);
|
||||
used+=chunksize;
|
||||
LogNetcode(_L "Subsequent fragment: len [{}], used [{}]/[{}]" __L, chunksize, used, length);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
|
||||
}
|
||||
delete p;
|
||||
delete[] tmpbuff;
|
||||
@@ -623,7 +623,7 @@ void EQStream::SequencedPush(EQProtocolPacket *p)
|
||||
void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
||||
{
|
||||
MOutboundQueue.lock();
|
||||
LogNetcode(_L "Pushing non-sequenced packet of length [{}]" __L, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size);
|
||||
NonSequencedQueue.push(p);
|
||||
MOutboundQueue.unlock();
|
||||
}
|
||||
@@ -631,14 +631,14 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
||||
void EQStream::SendAck(uint16 seq)
|
||||
{
|
||||
uint16 Seq=htons(seq);
|
||||
LogNetcode(_L "Sending ack with sequence [{}]" __L, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq);
|
||||
SetLastAckSent(seq);
|
||||
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
|
||||
}
|
||||
|
||||
void EQStream::SendOutOfOrderAck(uint16 seq)
|
||||
{
|
||||
LogNetcode(_L "Sending out of order ack with sequence [{}]" __L, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq);
|
||||
uint16 Seq=htons(seq);
|
||||
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
|
||||
}
|
||||
@@ -688,24 +688,24 @@ void EQStream::Write(int eq_fd)
|
||||
// If we don't have a packet to try to combine into, use this one as the base
|
||||
// And remove it form the queue
|
||||
p = NonSequencedQueue.front();
|
||||
LogNetcode(_L "Starting combined packet with non-seq packet of len [{}]" __L, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size);
|
||||
NonSequencedQueue.pop();
|
||||
} else if (!p->combine(NonSequencedQueue.front())) {
|
||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||
// So just send the base packet (we'll try this packet again later)
|
||||
LogNetcode(_L "Combined packet full at len [{}], next non-seq packet is len [{}]" __L, p->size, (NonSequencedQueue.front())->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
p=nullptr;
|
||||
|
||||
if (BytesWritten > threshold) {
|
||||
// Sent enough this round, lets stop to be fair
|
||||
LogNetcode(_L "Exceeded write threshold in nonseq ([{}] > [{}])" __L, BytesWritten, threshold);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Combine worked, so just remove this packet and it's spot in the queue
|
||||
LogNetcode(_L "Combined non-seq packet of len [{}], yeilding [{}] combined" __L, (NonSequencedQueue.front())->size, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size);
|
||||
delete NonSequencedQueue.front();
|
||||
NonSequencedQueue.pop();
|
||||
}
|
||||
@@ -718,7 +718,7 @@ void EQStream::Write(int eq_fd)
|
||||
uint16 seq_send = SequencedBase + count; //just for logging...
|
||||
|
||||
if(SequencedQueue.empty()) {
|
||||
LogNetcode(_L "Tried to write a packet with an empty queue ([{}] is past next out [{}])" __L, seq_send, NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq);
|
||||
SeqEmpty=true;
|
||||
continue;
|
||||
}
|
||||
@@ -728,35 +728,35 @@ void EQStream::Write(int eq_fd)
|
||||
++sitr;
|
||||
++count;
|
||||
if (p) {
|
||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten += p->size;
|
||||
p = nullptr;
|
||||
}
|
||||
LogNetcode(_L "Not retransmitting seq packet [{}] because already marked as acked" __L, seq_send);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send);
|
||||
} else if (!p) {
|
||||
// If we don't have a packet to try to combine into, use this one as the base
|
||||
// Copy it first as it will still live until it is acked
|
||||
p=(*sitr)->Copy();
|
||||
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
++sitr;
|
||||
++count;
|
||||
} else if (!p->combine(*sitr)) {
|
||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||
// So just send the base packet (we'll try this packet again later)
|
||||
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send + 1, (*sitr)->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send + 1, (*sitr)->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
p=nullptr;
|
||||
if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) {
|
||||
// Sent enough this round, lets stop to be fair
|
||||
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Combine worked
|
||||
LogNetcode(_L "Combined seq packet [{}] of len [{}], yeilding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size);
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
++sitr;
|
||||
++count;
|
||||
@@ -766,7 +766,7 @@ void EQStream::Write(int eq_fd)
|
||||
++sitr;
|
||||
++count;
|
||||
if (p) {
|
||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten += p->size;
|
||||
p = nullptr;
|
||||
@@ -776,25 +776,25 @@ void EQStream::Write(int eq_fd)
|
||||
// Copy it first as it will still live until it is acked
|
||||
p=(*sitr)->Copy();
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
|
||||
++sitr;
|
||||
++count;
|
||||
} else if (!p->combine(*sitr)) {
|
||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||
// So just send the base packet (we'll try this packet again later)
|
||||
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send, (*sitr)->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
p=nullptr;
|
||||
|
||||
if (BytesWritten > threshold) {
|
||||
// Sent enough this round, lets stop to be fair
|
||||
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Combine worked
|
||||
LogNetcode(_L "Combined seq packet [{}] of len [{}], yielding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yielding %d combined." __L, seq_send, (*sitr)->size, p->size);
|
||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||
++sitr;
|
||||
++count;
|
||||
@@ -802,7 +802,7 @@ void EQStream::Write(int eq_fd)
|
||||
}
|
||||
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
LogNetcode(_L "Post send Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
} else {
|
||||
// No more sequenced packets
|
||||
@@ -814,7 +814,7 @@ void EQStream::Write(int eq_fd)
|
||||
|
||||
// We have a packet still, must have run out of both seq and non-seq, so send it
|
||||
if (p) {
|
||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||
ReadyToSend.push(p);
|
||||
BytesWritten+=p->size;
|
||||
}
|
||||
@@ -831,7 +831,7 @@ void EQStream::Write(int eq_fd)
|
||||
if(SeqEmpty && NonSeqEmpty) {
|
||||
//no more data to send
|
||||
if(CheckState(CLOSING)) {
|
||||
LogNetcode(_L "All outgoing data flushed, closing stream" __L );
|
||||
Log(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L );
|
||||
//we are waiting for the queues to empty, now we can do our disconnect.
|
||||
//this packet will not actually go out until the next call to Write().
|
||||
_SendDisconnect();
|
||||
@@ -910,7 +910,7 @@ void EQStream::SendSessionRequest()
|
||||
Request->Session=htonl(time(nullptr));
|
||||
Request->MaxLength=htonl(512);
|
||||
|
||||
LogNetcode(_L "Sending OP_SessionRequest: session [{}], maxlen=[{}]" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
|
||||
|
||||
NonSequencedPush(out);
|
||||
}
|
||||
@@ -924,7 +924,7 @@ void EQStream::_SendDisconnect()
|
||||
*(uint32 *)out->pBuffer=htonl(Session);
|
||||
NonSequencedPush(out);
|
||||
|
||||
LogNetcode(_L "Sending OP_SessionDisconnect: session [{}]" __L, (unsigned long)Session);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session);
|
||||
}
|
||||
|
||||
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
|
||||
@@ -951,7 +951,7 @@ EQRawApplicationPacket *p=nullptr;
|
||||
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
|
||||
if (emu_op == OP_Unknown) {
|
||||
// Log(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str());
|
||||
}
|
||||
}
|
||||
p->SetOpcode(emu_op);
|
||||
}
|
||||
}
|
||||
@@ -976,7 +976,7 @@ EQRawApplicationPacket *p=nullptr;
|
||||
if(OpMgr != nullptr && *OpMgr != nullptr) {
|
||||
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
|
||||
if(emu_op == OP_Unknown) {
|
||||
LogNetcode("Unable to convert EQ opcode {:#04x} to an Application opcode", p->opcode);
|
||||
Log(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode);
|
||||
}
|
||||
|
||||
p->SetOpcode(emu_op);
|
||||
@@ -1004,7 +1004,7 @@ void EQStream::InboundQueueClear()
|
||||
{
|
||||
EQApplicationPacket *p=nullptr;
|
||||
|
||||
LogNetcode(_L "Clearing inbound queue" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L);
|
||||
|
||||
MInboundQueue.lock();
|
||||
if (!InboundQueue.empty()) {
|
||||
@@ -1047,7 +1047,7 @@ void EQStream::OutboundQueueClear()
|
||||
{
|
||||
EQProtocolPacket *p=nullptr;
|
||||
|
||||
LogNetcode(_L "Clearing outbound queue" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L);
|
||||
|
||||
MOutboundQueue.lock();
|
||||
while(!NonSequencedQueue.empty()) {
|
||||
@@ -1069,7 +1069,7 @@ void EQStream::PacketQueueClear()
|
||||
{
|
||||
EQProtocolPacket *p=nullptr;
|
||||
|
||||
LogNetcode(_L "Clearing future packet queue" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L);
|
||||
|
||||
if(!PacketQueue.empty()) {
|
||||
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
|
||||
@@ -1101,7 +1101,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
|
||||
delete p;
|
||||
ProcessQueue();
|
||||
} else {
|
||||
LogNetcode(_L "Incoming packet failed checksum" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,23 +1132,23 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
||||
SeqOrder ord = CompareSequence(SequencedBase, seq);
|
||||
if(ord == SeqInOrder) {
|
||||
//they are not acking anything new...
|
||||
LogNetcode(_L "Received an ack with no window advancement (seq [{}])" __L, seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq);
|
||||
} else if(ord == SeqPast) {
|
||||
//they are nacking blocks going back before our buffer, wtf?
|
||||
LogNetcode(_L "Received an ack with backward window advancement (they gave [{}], our window starts at [{}]). This is bad" __L, seq, SequencedBase);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase);
|
||||
} else {
|
||||
LogNetcode(_L "Received an ack up through sequence [{}]. Our base is [{}]" __L, seq, SequencedBase);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase);
|
||||
|
||||
|
||||
//this is a good ack, we get to ack some blocks.
|
||||
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
|
||||
while(SequencedBase != seq) {
|
||||
if(SequencedQueue.empty()) {
|
||||
LogNetcode(_L "OUT OF PACKETS acked packet with sequence [{}]. Next send is [{}] before this" __L, (unsigned long)SequencedBase, SequencedQueue.size());
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, SequencedQueue.size());
|
||||
SequencedBase = NextOutSeq;
|
||||
break;
|
||||
}
|
||||
LogNetcode(_L "Removing acked packet with sequence [{}]" __L, (unsigned long)SequencedBase);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu." __L, (unsigned long)SequencedBase);
|
||||
//clean out the acked packet
|
||||
delete SequencedQueue.front();
|
||||
SequencedQueue.pop_front();
|
||||
@@ -1156,7 +1156,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
||||
SequencedBase++;
|
||||
}
|
||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
LogNetcode(_L "Post-Ack on [{}] Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1166,7 +1166,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
||||
void EQStream::SetNextAckToSend(uint32 seq)
|
||||
{
|
||||
MAcks.lock();
|
||||
LogNetcode(_L "Set Next Ack To Send to [{}]" __L, (unsigned long)seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq);
|
||||
NextAckToSend=seq;
|
||||
MAcks.unlock();
|
||||
}
|
||||
@@ -1174,7 +1174,7 @@ void EQStream::SetNextAckToSend(uint32 seq)
|
||||
void EQStream::SetLastAckSent(uint32 seq)
|
||||
{
|
||||
MAcks.lock();
|
||||
LogNetcode(_L "Set Last Ack Sent to [{}]" __L, (unsigned long)seq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq);
|
||||
LastAckSent=seq;
|
||||
MAcks.unlock();
|
||||
}
|
||||
@@ -1187,10 +1187,10 @@ void EQStream::ProcessQueue()
|
||||
|
||||
EQProtocolPacket *qp=nullptr;
|
||||
while((qp=RemoveQueue(NextInSeq))!=nullptr) {
|
||||
LogNetcode(_L "Processing Queued Packet: Seq=[{}]" __L, NextInSeq);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq);
|
||||
ProcessPacket(qp);
|
||||
delete qp;
|
||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1201,21 +1201,21 @@ EQProtocolPacket *qp=nullptr;
|
||||
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
|
||||
qp=itr->second;
|
||||
PacketQueue.erase(itr);
|
||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
||||
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||
}
|
||||
return qp;
|
||||
}
|
||||
|
||||
void EQStream::SetStreamType(EQStreamType type)
|
||||
{
|
||||
LogNetcode(_L "Changing stream type from [{}] to [{}]" __L, StreamTypeString(StreamType), StreamTypeString(type));
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type));
|
||||
StreamType=type;
|
||||
switch (StreamType) {
|
||||
case LoginStream:
|
||||
app_opcode_size=1;
|
||||
compressed=false;
|
||||
encoded=false;
|
||||
LogNetcode(_L "Login stream has app opcode size [{}], is not compressed or encoded" __L, app_opcode_size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size);
|
||||
break;
|
||||
case ChatOrMailStream:
|
||||
case ChatStream:
|
||||
@@ -1223,7 +1223,7 @@ void EQStream::SetStreamType(EQStreamType type)
|
||||
app_opcode_size=1;
|
||||
compressed=false;
|
||||
encoded=true;
|
||||
LogNetcode(_L "Chat/Mail stream has app opcode size [{}], is not compressed, and is encoded" __L, app_opcode_size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size);
|
||||
break;
|
||||
case ZoneStream:
|
||||
case WorldStream:
|
||||
@@ -1231,7 +1231,7 @@ void EQStream::SetStreamType(EQStreamType type)
|
||||
app_opcode_size=2;
|
||||
compressed=true;
|
||||
encoded=false;
|
||||
LogNetcode(_L "World/Zone stream has app opcode size [{}], is compressed, and is not encoded" __L, app_opcode_size);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1281,7 +1281,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
|
||||
|
||||
void EQStream::SetState(EQStreamState state) {
|
||||
MState.lock();
|
||||
LogNetcode(_L "Changing state from [{}] to [{}]" __L, State, state);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state);
|
||||
State=state;
|
||||
MState.unlock();
|
||||
}
|
||||
@@ -1293,29 +1293,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
|
||||
|
||||
EQStreamState orig_state = GetState();
|
||||
if (orig_state == CLOSING && !outgoing_data) {
|
||||
LogNetcode(_L "Out of data in closing state, disconnecting" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L);
|
||||
_SendDisconnect();
|
||||
SetState(DISCONNECTING);
|
||||
} else if (LastPacket && (now-LastPacket) > timeout) {
|
||||
switch(orig_state) {
|
||||
case CLOSING:
|
||||
//if we time out in the closing state, they are not acking us, just give up
|
||||
LogNetcode(_L "Timeout expired in closing state. Moving to closed state" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L);
|
||||
_SendDisconnect();
|
||||
SetState(CLOSED);
|
||||
break;
|
||||
case DISCONNECTING:
|
||||
//we timed out waiting for them to send us the disconnect reply, just give up.
|
||||
LogNetcode(_L "Timeout expired in disconnecting state. Moving to closed state" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L);
|
||||
SetState(CLOSED);
|
||||
break;
|
||||
case CLOSED:
|
||||
LogNetcode(_L "Timeout expired in closed state??" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L);
|
||||
break;
|
||||
case ESTABLISHED:
|
||||
//we timed out during normal operation. Try to be nice about it.
|
||||
//we will almost certainly time out again waiting for the disconnect reply, but oh well.
|
||||
LogNetcode(_L "Timeout expired in established state. Closing connection" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L);
|
||||
_SendDisconnect();
|
||||
SetState(DISCONNECTING);
|
||||
break;
|
||||
@@ -1342,7 +1342,7 @@ void EQStream::Decay()
|
||||
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) {
|
||||
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) {
|
||||
(*sitr)->sent_time = 0;
|
||||
LogNetcode(_L "Timeout exceeded for seq [{}]. Flagging packet for retransmission" __L, SequencedBase + count);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Timeout exceeded for seq %d. Flagging packet for retransmission" __L, SequencedBase + count);
|
||||
}
|
||||
}
|
||||
MOutboundQueue.unlock();
|
||||
@@ -1359,11 +1359,11 @@ void EQStream::AdjustRates(uint32 average_delta)
|
||||
DecayRate=DECAYBASE/average_delta;
|
||||
if (BytesWritten > RateThreshold)
|
||||
BytesWritten = RateThreshold + DecayRate;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
|
||||
RateThreshold, DecayRate, average_delta);
|
||||
MRate.unlock();
|
||||
} else {
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
|
||||
average_delta, AVERAGE_DELTA_MAX);
|
||||
AverageDelta = AVERAGE_DELTA_MAX;
|
||||
}
|
||||
@@ -1374,7 +1374,7 @@ void EQStream::AdjustRates(uint32 average_delta)
|
||||
BytesWritten = 0;
|
||||
RateThreshold=RATEBASE/average_delta;
|
||||
DecayRate=DECAYBASE/average_delta;
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
|
||||
RateThreshold, DecayRate, average_delta);
|
||||
MRate.unlock();
|
||||
}
|
||||
@@ -1384,12 +1384,12 @@ void EQStream::AdjustRates(uint32 average_delta)
|
||||
void EQStream::Close() {
|
||||
if(HasOutgoingData()) {
|
||||
//there is pending data, wait for it to go out.
|
||||
LogNetcode(_L "Stream requested to Close(), but there is pending data, waiting for it" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
|
||||
SetState(CLOSING);
|
||||
} else {
|
||||
//otherwise, we are done, we can drop immediately.
|
||||
_SendDisconnect();
|
||||
LogNetcode(_L "Stream closing immediate due to Close()" __L);
|
||||
Log(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L);
|
||||
SetState(DISCONNECTING);
|
||||
}
|
||||
}
|
||||
@@ -1417,19 +1417,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
|
||||
} else if(p->opcode == sig->first_eq_opcode) {
|
||||
//opcode matches, check length..
|
||||
if(p->size == sig->first_length) {
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length matched [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
res = MatchSuccessful;
|
||||
} else if(sig->first_length == 0) {
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length ([{}]) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||
res = MatchSuccessful;
|
||||
} else {
|
||||
//opcode matched but length did not.
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x}, but length [{}] did not match expected [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
|
||||
res = MatchFailed;
|
||||
}
|
||||
} else {
|
||||
//first opcode did not match..
|
||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode {:#04x} did not match expected {:#04x}", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
|
||||
res = MatchFailed;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-11
@@ -218,13 +218,13 @@ class EQStream : public EQStreamInterface {
|
||||
|
||||
void init(bool resetSession=true);
|
||||
public:
|
||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
|
||||
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
|
||||
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
|
||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
|
||||
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
|
||||
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
|
||||
streamactive = false; }
|
||||
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
|
||||
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
|
||||
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
|
||||
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
|
||||
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
|
||||
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
|
||||
create_time = Timer::GetTimeSeconds(); }
|
||||
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
|
||||
void SetMaxLen(uint32 length) { MaxLen=length; }
|
||||
@@ -243,11 +243,6 @@ class EQStream : public EQStreamInterface {
|
||||
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
||||
|
||||
virtual OpcodeManager* GetOpcodeManager() const
|
||||
{
|
||||
return (*OpMgr);
|
||||
};
|
||||
|
||||
void CheckTimeout(uint32 now, uint32 timeout=30);
|
||||
bool HasOutgoingData();
|
||||
void Process(const unsigned char *data, const uint32 length);
|
||||
|
||||
+11
-11
@@ -46,7 +46,7 @@ void EQStreamIdentifier::Process() {
|
||||
|
||||
//first see if this stream has expired
|
||||
if(r.expire.Check(false)) {
|
||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before timeout", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
r.stream->Close();
|
||||
|
||||
cur = m_streams.erase(cur);
|
||||
@@ -62,23 +62,23 @@ void EQStreamIdentifier::Process() {
|
||||
}
|
||||
if(r.stream->GetState() != ESTABLISHED) {
|
||||
//the stream closed before it was identified.
|
||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before it closed", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
switch(r.stream->GetState())
|
||||
{
|
||||
case ESTABLISHED:
|
||||
LogNetcode("[StreamIdentify] Stream state was Established");
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established");
|
||||
break;
|
||||
case CLOSING:
|
||||
LogNetcode("[StreamIdentify] Stream state was Closing");
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing");
|
||||
break;
|
||||
case DISCONNECTING:
|
||||
LogNetcode("[StreamIdentify] Stream state was Disconnecting");
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting");
|
||||
break;
|
||||
case CLOSED:
|
||||
LogNetcode("[StreamIdentify] Stream state was Closed");
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed");
|
||||
break;
|
||||
default:
|
||||
LogNetcode("[StreamIdentify] Stream state was Unestablished or unknown");
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown");
|
||||
break;
|
||||
}
|
||||
r.stream->ReleaseFromUse();
|
||||
@@ -102,13 +102,13 @@ void EQStreamIdentifier::Process() {
|
||||
switch(res) {
|
||||
case EQStreamInterface::MatchNotReady:
|
||||
//the stream has not received enough packets to compare with this signature
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[StreamIdentify] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
all_ready = false;
|
||||
break;
|
||||
case EQStreamInterface::MatchSuccessful: {
|
||||
//yay, a match.
|
||||
|
||||
LogNetcode("[StreamIdentify] Identified stream [{}:{}] with signature [{}]", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
|
||||
// before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further
|
||||
r.stream->SetActive(true);
|
||||
@@ -122,7 +122,7 @@ void EQStreamIdentifier::Process() {
|
||||
}
|
||||
case EQStreamInterface::MatchFailed:
|
||||
//do nothing...
|
||||
LogNetcode("[StreamIdentify] [{}:{}] Tried patch [{}] and it did not match", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ void EQStreamIdentifier::Process() {
|
||||
//if we checked all patches and did not find a match.
|
||||
if(all_ready && !found_one) {
|
||||
//the stream cannot be identified.
|
||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}], no match found", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||
r.stream->ReleaseFromUse();
|
||||
}
|
||||
|
||||
|
||||
+6
-55
@@ -6,7 +6,6 @@
|
||||
#include <string>
|
||||
#include "emu_versions.h"
|
||||
#include "eq_packet.h"
|
||||
#include "net/daybreak_connection.h"
|
||||
|
||||
typedef enum {
|
||||
ESTABLISHED,
|
||||
@@ -19,47 +18,6 @@ typedef enum {
|
||||
class EQApplicationPacket;
|
||||
class OpcodeManager;
|
||||
|
||||
struct EQStreamManagerInterfaceOptions
|
||||
{
|
||||
EQStreamManagerInterfaceOptions() {
|
||||
opcode_size = 2;
|
||||
}
|
||||
|
||||
EQStreamManagerInterfaceOptions(int port, bool encoded, bool compressed) {
|
||||
opcode_size = 2;
|
||||
|
||||
//World seems to support both compression and xor zone supports one or the others.
|
||||
//Enforce one or the other in the convienence construct
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//but that might be because it was still a bit buggy when i was testing that.
|
||||
if (compressed) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
}
|
||||
else if (encoded) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||
}
|
||||
|
||||
daybreak_options.port = port;
|
||||
}
|
||||
|
||||
int opcode_size;
|
||||
bool track_opcode_stats;
|
||||
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
||||
};
|
||||
|
||||
class EQStreamManagerInterface
|
||||
{
|
||||
public:
|
||||
EQStreamManagerInterface(const EQStreamManagerInterfaceOptions &options) { m_options = options; }
|
||||
virtual ~EQStreamManagerInterface() { };
|
||||
|
||||
EQStreamManagerInterfaceOptions GetOptions() { return m_options; }
|
||||
const EQStreamManagerInterfaceOptions& GetOptions() const { return m_options; }
|
||||
virtual void SetOptions(const EQStreamManagerInterfaceOptions& options) = 0;
|
||||
protected:
|
||||
EQStreamManagerInterfaceOptions m_options;
|
||||
};
|
||||
|
||||
class EQStreamInterface {
|
||||
public:
|
||||
virtual ~EQStreamInterface() {}
|
||||
@@ -71,20 +29,12 @@ public:
|
||||
uint16 first_eq_opcode;
|
||||
uint32 first_length; //0=dont check length
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
MatchNotReady,
|
||||
MatchSuccessful,
|
||||
MatchFailed
|
||||
} MatchState;
|
||||
|
||||
struct Stats
|
||||
{
|
||||
EQ::Net::DaybreakConnectionStats DaybreakStats;
|
||||
int RecvCount[_maxEmuOpcode];
|
||||
int SentCount[_maxEmuOpcode];
|
||||
};
|
||||
|
||||
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req=true) = 0;
|
||||
virtual void FastQueuePacket(EQApplicationPacket **p, bool ack_req=true) = 0;
|
||||
virtual EQApplicationPacket *PopPacket() = 0;
|
||||
@@ -100,11 +50,12 @@ public:
|
||||
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
||||
virtual EQStreamState GetState() = 0;
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
|
||||
virtual OpcodeManager* GetOpcodeManager() const = 0;
|
||||
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
|
||||
virtual Stats GetStats() const = 0;
|
||||
virtual void ResetStats() = 0;
|
||||
virtual EQStreamManagerInterface* GetManager() const = 0;
|
||||
|
||||
virtual const uint32 GetBytesSent() const { return 0; }
|
||||
virtual const uint32 GetBytesRecieved() const { return 0; }
|
||||
virtual const uint32 GetBytesSentPerSecond() const { return 0; }
|
||||
virtual const uint32 GetBytesRecvPerSecond() const { return 0; }
|
||||
virtual const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; }
|
||||
};
|
||||
|
||||
#endif /*EQSTREAMINTF_H_*/
|
||||
|
||||
+26
-22
@@ -22,7 +22,7 @@ std::string EQStreamProxy::Describe() const {
|
||||
return(m_structs->Describe());
|
||||
}
|
||||
|
||||
const EQ::versions::ClientVersion EQStreamProxy::ClientVersion() const
|
||||
const EQEmu::versions::ClientVersion EQStreamProxy::ClientVersion() const
|
||||
{
|
||||
return m_structs->ClientVersion();
|
||||
}
|
||||
@@ -38,8 +38,12 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
|
||||
}
|
||||
|
||||
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||
if (p == nullptr) {
|
||||
if(p == nullptr)
|
||||
return;
|
||||
|
||||
if (p->GetOpcode() != OP_SpecialMesg) {
|
||||
Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||
}
|
||||
|
||||
EQApplicationPacket *newp = p->Copy();
|
||||
@@ -78,6 +82,26 @@ uint16 EQStreamProxy::GetRemotePort() const {
|
||||
return(m_stream->GetRemotePort());
|
||||
}
|
||||
|
||||
const uint32 EQStreamProxy::GetBytesSent() const
|
||||
{
|
||||
return(m_stream->GetBytesSent());
|
||||
}
|
||||
|
||||
const uint32 EQStreamProxy::GetBytesRecieved() const
|
||||
{
|
||||
return(m_stream->GetBytesRecieved());
|
||||
}
|
||||
|
||||
const uint32 EQStreamProxy::GetBytesSentPerSecond() const
|
||||
{
|
||||
return(m_stream->GetBytesSentPerSecond());
|
||||
}
|
||||
|
||||
const uint32 EQStreamProxy::GetBytesRecvPerSecond() const
|
||||
{
|
||||
return(m_stream->GetBytesRecvPerSecond());
|
||||
}
|
||||
|
||||
void EQStreamProxy::ReleaseFromUse() {
|
||||
m_stream->ReleaseFromUse();
|
||||
}
|
||||
@@ -86,21 +110,6 @@ void EQStreamProxy::RemoveData() {
|
||||
m_stream->RemoveData();
|
||||
}
|
||||
|
||||
EQStreamInterface::Stats EQStreamProxy::GetStats() const
|
||||
{
|
||||
return m_stream->GetStats();
|
||||
}
|
||||
|
||||
void EQStreamProxy::ResetStats()
|
||||
{
|
||||
m_stream->ResetStats();
|
||||
}
|
||||
|
||||
EQStreamManagerInterface *EQStreamProxy::GetManager() const
|
||||
{
|
||||
return m_stream->GetManager();
|
||||
}
|
||||
|
||||
bool EQStreamProxy::CheckState(EQStreamState state) {
|
||||
if(m_stream)
|
||||
return(m_stream->CheckState(state));
|
||||
@@ -108,8 +117,3 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
|
||||
{
|
||||
return (*m_opcodes);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,21 +28,21 @@ public:
|
||||
virtual void RemoveData();
|
||||
virtual bool CheckState(EQStreamState state);
|
||||
virtual std::string Describe() const;
|
||||
virtual const EQ::versions::ClientVersion ClientVersion() const;
|
||||
virtual const EQEmu::versions::ClientVersion ClientVersion() const;
|
||||
virtual EQStreamState GetState();
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm);
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
virtual OpcodeManager* GetOpcodeManager() const;
|
||||
|
||||
virtual const uint32 GetBytesSent() const;
|
||||
virtual const uint32 GetBytesRecieved() const;
|
||||
virtual const uint32 GetBytesSentPerSecond() const;
|
||||
virtual const uint32 GetBytesRecvPerSecond() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
||||
const StructStrategy *const m_structs; //we do not own this object.
|
||||
//this is a pointer to a pointer to make it less likely that a packet will
|
||||
//reference an invalid opcode manager when they are being reloaded.
|
||||
OpcodeManager **const m_opcodes;
|
||||
//we do not own this object.
|
||||
OpcodeManager **const m_opcodes; //we do not own this object.
|
||||
};
|
||||
|
||||
#endif /*EQSTREAMPROXY_H_*/
|
||||
|
||||
+48
-108
@@ -26,32 +26,24 @@
|
||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||
|
||||
void EQEmuConfig::parse_config()
|
||||
{
|
||||
|
||||
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||
void EQEmuConfig::parse_config() {
|
||||
|
||||
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||
LoginCount = 0;
|
||||
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||
LoginCount = 0;
|
||||
|
||||
if (_root["server"]["world"]["loginserver"].isObject()) {
|
||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||
LoginLegacy = false;
|
||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") LoginLegacy = true;
|
||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
||||
|
||||
// at least today, this is wrong a majority of the time
|
||||
// remove this if eqemulator ever upgrades its loginserver
|
||||
if (LoginHost.find("login.eqemulator.net") != std::string::npos) {
|
||||
LoginLegacy = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
char str[32];
|
||||
loginlist.Clear();
|
||||
do {
|
||||
@@ -61,122 +53,74 @@ void EQEmuConfig::parse_config()
|
||||
}
|
||||
|
||||
auto loginconfig = new LoginConfig;
|
||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||
|
||||
loginconfig->LoginLegacy = false;
|
||||
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
|
||||
|
||||
// at least today, this is wrong a majority of the time
|
||||
// remove this if eqemulator ever upgrades its loginserver
|
||||
if (loginconfig->LoginHost.find("login.eqemulator.net") != std::string::npos) {
|
||||
loginconfig->LoginLegacy = true;
|
||||
}
|
||||
|
||||
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") loginconfig->LoginLegacy = true;
|
||||
loginlist.Insert(loginconfig);
|
||||
} while (LoginCount < 100);
|
||||
}
|
||||
|
||||
|
||||
//<locked> from xml converts to json as locked: "", so i default to "false".
|
||||
|
||||
|
||||
//<locked> from xml converts to json as locked: "", so i default to "false".
|
||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||
Locked = false;
|
||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") Locked = true;
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||
|
||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||
|
||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||
TelnetEnabled = false;
|
||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") TelnetEnabled = true;
|
||||
|
||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||
WorldHTTPEnabled = false;
|
||||
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||
WorldHTTPEnabled = false;
|
||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") WorldHTTPEnabled = true;
|
||||
|
||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||
WorldHTTPEnabled = true;
|
||||
}
|
||||
|
||||
if (_root["server"].get("disable_config_checks", "false").asString() == "true") {
|
||||
DisableConfigChecks = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* UCS
|
||||
*/
|
||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
/**
|
||||
* Database
|
||||
*/
|
||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||
|
||||
/**
|
||||
* Content Database
|
||||
*/
|
||||
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
||||
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
||||
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
||||
ContentDbPort = atoi(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||
|
||||
/**
|
||||
* QS
|
||||
*/
|
||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||
|
||||
/**
|
||||
* Zones
|
||||
*/
|
||||
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||
|
||||
/**
|
||||
* Files
|
||||
*/
|
||||
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
||||
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
||||
MailOpCodesFile = _root["server"]["files"].get("mail_opcodes", "mail_opcodes.conf").asString();
|
||||
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
||||
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
||||
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
||||
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
||||
|
||||
/**
|
||||
* Directories
|
||||
*/
|
||||
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
||||
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
||||
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||
|
||||
/**
|
||||
* Logs
|
||||
*/
|
||||
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
|
||||
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
|
||||
|
||||
/**
|
||||
* Launcher
|
||||
*/
|
||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||
#ifdef WIN32
|
||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||
@@ -286,9 +230,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
||||
if (var_name == "OpCodesFile") {
|
||||
return (OpCodesFile);
|
||||
}
|
||||
if (var_name == "MailOpCodesFile") {
|
||||
return (MailOpCodesFile);
|
||||
}
|
||||
if (var_name == "PluginPlFile") {
|
||||
return (PluginPlFile);
|
||||
}
|
||||
@@ -371,7 +312,6 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
||||
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
||||
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
||||
std::cout << "MailOpcodesFile = " << MailOpCodesFile << std::endl;
|
||||
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
|
||||
std::cout << "MapDir = " << MapDir << std::endl;
|
||||
std::cout << "QuestDir = " << QuestDir << std::endl;
|
||||
@@ -382,6 +322,6 @@ void EQEmuConfig::Dump() const
|
||||
std::cout << "LogDir = " << LogDir << std::endl;
|
||||
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
|
||||
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
|
||||
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
||||
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
|
||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||
}
|
||||
|
||||
+12
-27
@@ -20,9 +20,7 @@
|
||||
|
||||
#include "json/json.h"
|
||||
#include "linked_list.h"
|
||||
#include "path_manager.h"
|
||||
#include <fstream>
|
||||
#include <fmt/format.h>
|
||||
|
||||
struct LoginConfig {
|
||||
std::string LoginHost;
|
||||
@@ -60,7 +58,6 @@ class EQEmuConfig
|
||||
uint16 WorldHTTPPort;
|
||||
std::string WorldHTTPMimeFile;
|
||||
std::string SharedKey;
|
||||
bool DisableConfigChecks;
|
||||
|
||||
// From <chatserver/>
|
||||
std::string ChatHost;
|
||||
@@ -77,13 +74,6 @@ class EQEmuConfig
|
||||
std::string DatabaseDB;
|
||||
uint16 DatabasePort;
|
||||
|
||||
// From <content_database/>
|
||||
std::string ContentDbHost;
|
||||
std::string ContentDbUsername;
|
||||
std::string ContentDbPassword;
|
||||
std::string ContentDbName;
|
||||
uint16 ContentDbPort;
|
||||
|
||||
// From <qsdatabase> // QueryServ
|
||||
std::string QSDatabaseHost;
|
||||
std::string QSDatabaseUsername;
|
||||
@@ -91,10 +81,13 @@ class EQEmuConfig
|
||||
std::string QSDatabaseDB;
|
||||
uint16 QSDatabasePort;
|
||||
|
||||
// From <nats/>
|
||||
std::string NATSHost;
|
||||
uint16 NATSPort;
|
||||
|
||||
// From <files/>
|
||||
std::string SpellsFile;
|
||||
std::string OpCodesFile;
|
||||
std::string MailOpCodesFile;
|
||||
std::string PluginPlFile;
|
||||
|
||||
// From <directories/>
|
||||
@@ -133,7 +126,7 @@ class EQEmuConfig
|
||||
void parse_config();
|
||||
|
||||
EQEmuConfig()
|
||||
{
|
||||
{
|
||||
|
||||
}
|
||||
virtual ~EQEmuConfig() {}
|
||||
@@ -154,38 +147,30 @@ class EQEmuConfig
|
||||
}
|
||||
|
||||
// Load the config
|
||||
static bool LoadConfig(const std::string& path = "")
|
||||
static bool LoadConfig()
|
||||
{
|
||||
if (_config != nullptr) {
|
||||
return true;
|
||||
}
|
||||
_config = new EQEmuConfig;
|
||||
|
||||
return parseFile(path);
|
||||
return parseFile();
|
||||
}
|
||||
|
||||
// Load config file and parse data
|
||||
static bool parseFile(const std::string& file_path = ".")
|
||||
{
|
||||
static bool parseFile() {
|
||||
if (_config == nullptr) {
|
||||
return LoadConfig(file_path);
|
||||
return LoadConfig();
|
||||
}
|
||||
|
||||
std::string file = fmt::format(
|
||||
"{}/{}",
|
||||
(file_path.empty() ? path.GetServerPath() : file_path),
|
||||
EQEmuConfig::ConfigFile
|
||||
);
|
||||
|
||||
std::ifstream fconfig(file, std::ifstream::binary);
|
||||
|
||||
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
|
||||
try {
|
||||
fconfig >> _config->_root;
|
||||
_config->parse_config();
|
||||
}
|
||||
catch (std::exception &) {
|
||||
catch (std::exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "eqemu_exception.h"
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
Exception::Exception(const char* name, const std::string& description, const char* file, long line)
|
||||
: line_(line),
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <sstream>
|
||||
#include <exception>
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
//! EQEmu Exception Class
|
||||
/*!
|
||||
@@ -104,7 +104,7 @@ namespace EQ
|
||||
} // EQEmu
|
||||
|
||||
#ifndef EQ_EXCEPT
|
||||
#define EQ_EXCEPT(n, d) throw EQ::Exception(n, d, __FILE__, __LINE__)
|
||||
#define EQ_EXCEPT(n, d) throw EQEmu::Exception(n, d, __FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+258
-644
@@ -1,447 +1,313 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "eqemu_logsys.h"
|
||||
#include "rulesys.h"
|
||||
#include "platform.h"
|
||||
#include "strings.h"
|
||||
#include "repositories/discord_webhooks_repository.h"
|
||||
#include "repositories/logsys_categories_repository.h"
|
||||
#include "termcolor/rang.hpp"
|
||||
#include "string_util.h"
|
||||
#include "database.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
std::ofstream process_log;
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <direct.h>
|
||||
#include <conio.h>
|
||||
#include <iostream>
|
||||
#include <dos.h>
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <direct.h>
|
||||
#include <conio.h>
|
||||
#include <iostream>
|
||||
#include <dos.h>
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <thread>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* EQEmuLogSys Constructor
|
||||
*/
|
||||
/* Linux ANSI console color defines */
|
||||
#define LC_RESET "\033[0m"
|
||||
#define LC_BLACK "\033[30m" /* Black */
|
||||
#define LC_RED "\033[31m" /* Red */
|
||||
#define LC_GREEN "\033[32m" /* Green */
|
||||
#define LC_YELLOW "\033[33m" /* Yellow */
|
||||
#define LC_BLUE "\033[34m" /* Blue */
|
||||
#define LC_MAGENTA "\033[35m" /* Magenta */
|
||||
#define LC_CYAN "\033[36m" /* Cyan */
|
||||
#define LC_WHITE "\033[37m" /* White */
|
||||
|
||||
namespace Console {
|
||||
enum Color {
|
||||
Black = 0,
|
||||
Blue = 1,
|
||||
Green = 2,
|
||||
Cyan = 3,
|
||||
Red = 4,
|
||||
Magenta = 5,
|
||||
Brown = 6,
|
||||
LightGray = 7,
|
||||
DarkGray = 8,
|
||||
LightBlue = 9,
|
||||
LightGreen = 10,
|
||||
LightCyan = 11,
|
||||
LightRed = 12,
|
||||
LightMagenta = 13,
|
||||
Yellow = 14,
|
||||
White = 15
|
||||
};
|
||||
}
|
||||
|
||||
EQEmuLogSys::EQEmuLogSys()
|
||||
{
|
||||
m_on_log_gmsay_hook = [](uint16 log_type, const char *func, const std::string &) {};
|
||||
m_on_log_console_hook = [](uint16 log_type, const std::string &) {};
|
||||
on_log_gmsay_hook = [](uint16 log_type, const std::string&) {};
|
||||
bool file_logs_enabled = false;
|
||||
int log_platform = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* EQEmuLogSys Deconstructor
|
||||
*/
|
||||
EQEmuLogSys::~EQEmuLogSys() = default;
|
||||
|
||||
EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
EQEmuLogSys::~EQEmuLogSys()
|
||||
{
|
||||
/**
|
||||
* Get Executable platform currently running this code (Zone/World/etc)
|
||||
*/
|
||||
m_log_platform = GetExecutablePlatformInt();
|
||||
|
||||
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
|
||||
log_settings[log_category_id].log_to_console = 0;
|
||||
log_settings[log_category_id].log_to_file = 0;
|
||||
log_settings[log_category_id].log_to_gmsay = 0;
|
||||
log_settings[log_category_id].log_to_discord = 0;
|
||||
log_settings[log_category_id].is_category_enabled = 0;
|
||||
}
|
||||
|
||||
m_file_logs_enabled = false;
|
||||
|
||||
/**
|
||||
* Set Defaults
|
||||
*/
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Loot].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Scheduler].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::CombatRecord].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* RFC 5424
|
||||
*/
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* Set Category enabled status on defaults
|
||||
*/
|
||||
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
|
||||
const bool log_to_console = log_settings[log_category_id].log_to_console > 0;
|
||||
const bool log_to_file = log_settings[log_category_id].log_to_file > 0;
|
||||
const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0;
|
||||
const bool log_to_discord = log_settings[log_category_id].log_to_discord > 0;
|
||||
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
|
||||
if (is_category_enabled) {
|
||||
log_settings[log_category_id].is_category_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare process file names for log writing=
|
||||
*/
|
||||
if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld) {
|
||||
m_platform_file_name = "world";
|
||||
}
|
||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
|
||||
m_platform_file_name = "query_server";
|
||||
}
|
||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) {
|
||||
m_platform_file_name = "zone";
|
||||
}
|
||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformUCS) {
|
||||
m_platform_file_name = "ucs";
|
||||
}
|
||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLogin) {
|
||||
m_platform_file_name = "login";
|
||||
}
|
||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLaunch) {
|
||||
m_platform_file_name = "launcher";
|
||||
}
|
||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformHC) {
|
||||
m_platform_file_name = "hc";
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void EQEmuLogSys::ProcessLogWrite(
|
||||
uint16 log_category,
|
||||
const std::string &message
|
||||
)
|
||||
void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
{
|
||||
/* Get Executable platform currently running this code (Zone/World/etc) */
|
||||
log_platform = GetExecutablePlatformInt();
|
||||
|
||||
/* Zero out Array */
|
||||
memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID);
|
||||
|
||||
/* Set Defaults */
|
||||
log_settings[Logs::World_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::QS_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::Crash].log_to_console = Logs::General;
|
||||
log_settings[Logs::MySQLError].log_to_console = Logs::General;
|
||||
log_settings[Logs::Login_Server].log_to_console = Logs::General;
|
||||
log_settings[Logs::Headless_Client].log_to_console = Logs::General;
|
||||
log_settings[Logs::NATS].log_to_console = Logs::General;
|
||||
|
||||
/* Set Category enabled status on defaults */
|
||||
log_settings[Logs::World_Server].is_category_enabled = 1;
|
||||
log_settings[Logs::Zone_Server].is_category_enabled = 1;
|
||||
log_settings[Logs::QS_Server].is_category_enabled = 1;
|
||||
log_settings[Logs::UCS_Server].is_category_enabled = 1;
|
||||
log_settings[Logs::Crash].is_category_enabled = 1;
|
||||
log_settings[Logs::MySQLError].is_category_enabled = 1;
|
||||
log_settings[Logs::Login_Server].is_category_enabled = 1;
|
||||
log_settings[Logs::NATS].is_category_enabled = 1;
|
||||
|
||||
/* Declare process file names for log writing
|
||||
If there is no process_file_name declared, no log file will be written, simply
|
||||
*/
|
||||
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld)
|
||||
platform_file_name = "world";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ)
|
||||
platform_file_name = "query_server";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
|
||||
platform_file_name = "zone";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS)
|
||||
platform_file_name = "ucs";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin)
|
||||
platform_file_name = "login";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch)
|
||||
platform_file_name = "launcher";
|
||||
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC)
|
||||
platform_file_name = "hc";
|
||||
}
|
||||
|
||||
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
|
||||
{
|
||||
std::string ret;
|
||||
ret.push_back('[');
|
||||
ret.append(Logs::LogCategoryName[log_category]);
|
||||
ret.push_back(']');
|
||||
ret.push_back(' ');
|
||||
ret.append(in_message);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
{
|
||||
/* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */
|
||||
if (log_category == Logs::LogCategory::Netcode)
|
||||
return;
|
||||
|
||||
/* Check to see if the process that actually ran this is zone */
|
||||
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
|
||||
on_log_gmsay_hook(log_category, message);
|
||||
}
|
||||
|
||||
void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
{
|
||||
if (log_category == Logs::Crash) {
|
||||
char time_stamp[80];
|
||||
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
|
||||
std::ofstream crash_log;
|
||||
EQEmuLogSys::MakeDirectory("logs/crashes");
|
||||
crash_log.open(
|
||||
StringFormat("logs/crashes/crash_%s_%i.log", m_platform_file_name.c_str(), getpid()),
|
||||
std::ios_base::app | std::ios_base::out
|
||||
);
|
||||
crash_log.open(StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
|
||||
crash_log << time_stamp << " " << message << "\n";
|
||||
crash_log.close();
|
||||
}
|
||||
|
||||
if (process_log) {
|
||||
char time_stamp[80];
|
||||
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
|
||||
char time_stamp[80];
|
||||
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
|
||||
|
||||
if (process_log)
|
||||
process_log << time_stamp << " " << message << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_category
|
||||
* @return
|
||||
*/
|
||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
||||
{
|
||||
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) {
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
return Console::Color::Yellow;
|
||||
case Logs::MySQLError:
|
||||
case Logs::QuestErrors:
|
||||
case Logs::Error:
|
||||
return Chat::Red;
|
||||
return Console::Color::LightRed;
|
||||
case Logs::MySQLQuery:
|
||||
case Logs::Debug:
|
||||
return Chat::Lime;
|
||||
return Console::Color::LightGreen;
|
||||
case Logs::Quests:
|
||||
return Chat::Group;
|
||||
return Console::Color::LightCyan;
|
||||
case Logs::Commands:
|
||||
case Logs::Mercenaries:
|
||||
return Chat::Magenta;
|
||||
return Console::Color::LightMagenta;
|
||||
case Logs::Crash:
|
||||
return Chat::Red;
|
||||
return Console::Color::LightRed;
|
||||
default:
|
||||
return Chat::Yellow;
|
||||
return Console::Color::Yellow;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
void EQEmuLogSys::ProcessConsoleMessage(
|
||||
uint16 log_category,
|
||||
const std::string &message,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line
|
||||
)
|
||||
{
|
||||
bool is_error = (
|
||||
log_category == Logs::LogCategory::Error ||
|
||||
log_category == Logs::LogCategory::MySQLError ||
|
||||
log_category == Logs::LogCategory::Crash ||
|
||||
log_category == Logs::LogCategory::QuestErrors
|
||||
);
|
||||
bool is_warning = (
|
||||
log_category == Logs::LogCategory::Warning
|
||||
);
|
||||
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< ""
|
||||
<< rang::fgB::black
|
||||
<< rang::style::bold
|
||||
<< fmt::format("{:>6}", GetPlatformName().substr(0, 6))
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< " | "
|
||||
<< ((is_error || is_warning) ? rang::fgB::red : rang::fgB::gray)
|
||||
<< rang::style::bold
|
||||
<< fmt::format("{:^10}", fmt::format("{}", Logs::LogCategoryName[log_category]).substr(0, 10))
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< " | "
|
||||
<< rang::fgB::gray
|
||||
<< rang::style::bold
|
||||
<< fmt::format("{}", func)
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< " ";
|
||||
|
||||
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< ""
|
||||
<< rang::fgB::green
|
||||
<< rang::style::bold
|
||||
<< fmt::format("{:}", fmt::format("{}:{}:{}", std::filesystem::path(file).filename().string(), func, line))
|
||||
<< rang::style::reset
|
||||
<< " | ";
|
||||
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) {
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
return LC_YELLOW;
|
||||
case Logs::MySQLError:
|
||||
case Logs::Error:
|
||||
return LC_RED;
|
||||
case Logs::MySQLQuery:
|
||||
case Logs::Debug:
|
||||
return LC_GREEN;
|
||||
case Logs::Quests:
|
||||
return LC_CYAN;
|
||||
case Logs::Commands:
|
||||
case Logs::Mercenaries:
|
||||
return LC_MAGENTA;
|
||||
case Logs::Crash:
|
||||
return LC_RED;
|
||||
default:
|
||||
return LC_YELLOW;
|
||||
}
|
||||
|
||||
if (log_category == Logs::LogCategory::MySQLQuery) {
|
||||
auto s = Strings::Split(message, "--");
|
||||
if (s.size() > 1) {
|
||||
std::string query = Strings::Trim(s[0]);
|
||||
std::string meta = Strings::Trim(s[1]);
|
||||
|
||||
std::cout <<
|
||||
rang::fgB::green
|
||||
<<
|
||||
query
|
||||
<<
|
||||
rang::style::reset;
|
||||
|
||||
std::cout <<
|
||||
rang::fgB::black
|
||||
<<
|
||||
" -- "
|
||||
<<
|
||||
meta
|
||||
<<
|
||||
rang::style::reset;
|
||||
}
|
||||
}
|
||||
else if (Strings::Contains(message, "[")) {
|
||||
for (auto &e: Strings::Split(message, " ")) {
|
||||
if (Strings::Contains(e, "[") && Strings::Contains(e, "]")) {
|
||||
e = Strings::Replace(e, "[", "");
|
||||
e = Strings::Replace(e, "]", "");
|
||||
|
||||
bool is_upper = false;
|
||||
|
||||
for (int i = 0; i < strlen(e.c_str()); i++) {
|
||||
if (isupper(e[i])) {
|
||||
is_upper = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_upper) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< rang::fgB::yellow
|
||||
<< e
|
||||
<< rang::fgB::gray
|
||||
<< "] "
|
||||
;
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< (is_error ? rang::fgB::red : rang::fgB::gray)
|
||||
<< e
|
||||
<< " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< (is_error ? rang::fgB::red : rang::fgB::gray)
|
||||
<< message
|
||||
<< " ";
|
||||
}
|
||||
|
||||
if (!origination_info.zone_short_name.empty()) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<<
|
||||
rang::fgB::black
|
||||
<<
|
||||
"-- "
|
||||
<<
|
||||
fmt::format(
|
||||
"[{}] ({}) inst_id [{}]",
|
||||
origination_info.zone_short_name,
|
||||
origination_info.zone_long_name,
|
||||
origination_info.instance_id
|
||||
);
|
||||
}
|
||||
|
||||
(!is_error ? std::cout : std::cerr) << rang::style::reset << std::endl;
|
||||
|
||||
m_on_log_console_hook(log_category, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
constexpr const char *str_end(const char *str)
|
||||
{
|
||||
return *str ? str_end(str + 1) : str;
|
||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
|
||||
switch (log_category) {
|
||||
case Logs::Status:
|
||||
case Logs::Normal:
|
||||
return 15; /* Yellow */
|
||||
case Logs::MySQLError:
|
||||
case Logs::Error:
|
||||
return 13; /* Red */
|
||||
case Logs::MySQLQuery:
|
||||
case Logs::Debug:
|
||||
return 14; /* Light Green */
|
||||
case Logs::Quests:
|
||||
return 258; /* Light Cyan */
|
||||
case Logs::Commands:
|
||||
case Logs::Mercenaries:
|
||||
return 5; /* Light Purple */
|
||||
case Logs::Crash:
|
||||
return 13; /* Red */
|
||||
default:
|
||||
return 15; /* Yellow */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Core logging function
|
||||
*
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
* @param message
|
||||
* @param ...
|
||||
*/
|
||||
void EQEmuLogSys::Out(
|
||||
Logs::DebugLevel debug_level,
|
||||
uint16 log_category,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *message,
|
||||
...
|
||||
)
|
||||
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
{
|
||||
auto l = GetLogsEnabled(debug_level, log_category);
|
||||
|
||||
// bail out if nothing to log
|
||||
if (!l.log_enabled) {
|
||||
#ifdef _WINDOWS
|
||||
HANDLE console_handle;
|
||||
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_FONT_INFOEX info = { 0 };
|
||||
info.cbSize = sizeof(info);
|
||||
info.dwFontSize.Y = 12; // leave X as zero
|
||||
info.FontWeight = FW_NORMAL;
|
||||
wcscpy(info.FaceName, L"Lucida Console");
|
||||
SetCurrentConsoleFontEx(console_handle, NULL, &info);
|
||||
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
|
||||
std::cout << message << "\n";
|
||||
SetConsoleTextAttribute(console_handle, Console::Color::White);
|
||||
#else
|
||||
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
|
||||
{
|
||||
|
||||
bool log_to_console = true;
|
||||
if (log_settings[log_category].log_to_console < debug_level) {
|
||||
log_to_console = false;
|
||||
}
|
||||
|
||||
bool log_to_file = true;
|
||||
if (log_settings[log_category].log_to_file < debug_level) {
|
||||
log_to_file = false;
|
||||
}
|
||||
|
||||
bool log_to_gmsay = true;
|
||||
if (log_settings[log_category].log_to_gmsay < debug_level) {
|
||||
log_to_gmsay = false;
|
||||
}
|
||||
|
||||
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
|
||||
if (nothing_to_log)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prefix;
|
||||
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
||||
prefix = fmt::format("[{0}::{1}:{2}] ", std::filesystem::path(file).filename().string(), func, line);
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
std::string output_message = vStringFormat(message.c_str(), args);
|
||||
va_end(args);
|
||||
|
||||
// remove this when we remove all legacy logs
|
||||
bool ignore_log_legacy_format = (
|
||||
log_category == Logs::Netcode ||
|
||||
log_category == Logs::PacketServerClient ||
|
||||
log_category == Logs::PacketClientServer ||
|
||||
log_category == Logs::PacketServerToServer
|
||||
);
|
||||
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message);
|
||||
|
||||
// remove this when we remove all legacy logs
|
||||
std::string output_message = message;
|
||||
if (!ignore_log_legacy_format) {
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
output_message = vStringFormat(message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
if (l.log_to_console_enabled) {
|
||||
EQEmuLogSys::ProcessConsoleMessage(
|
||||
log_category,
|
||||
output_message,
|
||||
file,
|
||||
func,
|
||||
line
|
||||
);
|
||||
}
|
||||
if (l.log_to_gmsay_enabled) {
|
||||
m_on_log_gmsay_hook(log_category, func, output_message);
|
||||
}
|
||||
if (l.log_to_file_enabled) {
|
||||
EQEmuLogSys::ProcessLogWrite(
|
||||
log_category,
|
||||
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
|
||||
);
|
||||
}
|
||||
if (l.log_to_discord_enabled && m_on_log_discord_hook) {
|
||||
m_on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message);
|
||||
}
|
||||
if (log_to_console) EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
|
||||
if (log_to_gmsay) EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
|
||||
if (log_to_file) EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param time_stamp
|
||||
*/
|
||||
void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
|
||||
void EQEmuLogSys::SetCurrentTimeStamp(char* time_stamp)
|
||||
{
|
||||
time_t raw_time;
|
||||
struct tm *time_info;
|
||||
time_t raw_time;
|
||||
struct tm * time_info;
|
||||
time(&raw_time);
|
||||
time_info = localtime(&raw_time);
|
||||
strftime(time_stamp, 80, "[%m-%d-%Y %H:%M:%S]", time_info);
|
||||
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
@@ -450,10 +316,9 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
|
||||
return;
|
||||
_mkdir(directory_name.c_str());
|
||||
#else
|
||||
struct stat st{};
|
||||
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||
struct stat st;
|
||||
if (stat(directory_name.c_str(), &st) == 0) // exists
|
||||
return;
|
||||
}
|
||||
mkdir(directory_name.c_str(), 0755);
|
||||
#endif
|
||||
}
|
||||
@@ -465,280 +330,29 @@ void EQEmuLogSys::CloseFileLogs()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_name
|
||||
*/
|
||||
void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
{
|
||||
EQEmuLogSys::CloseFileLogs();
|
||||
|
||||
/**
|
||||
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
|
||||
*/
|
||||
if (!m_file_logs_enabled) {
|
||||
/* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one... */
|
||||
if (file_logs_enabled == false)
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Zone
|
||||
*/
|
||||
if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) {
|
||||
if (!log_name.empty()) {
|
||||
m_platform_file_name = log_name;
|
||||
}
|
||||
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
|
||||
if (!log_name.empty())
|
||||
platform_file_name = log_name;
|
||||
|
||||
if (m_platform_file_name.empty()) {
|
||||
if (platform_file_name.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Starting File Log [{}/zone/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
|
||||
|
||||
// Make directory if not exists
|
||||
EQEmuLogSys::MakeDirectory(fmt::format("{}/zone", GetLogPath()));
|
||||
|
||||
// Open file pointer
|
||||
process_log.open(
|
||||
fmt::format("{}/zone/{}_{}.log", GetLogPath(), m_platform_file_name, getpid()),
|
||||
std::ios_base::app | std::ios_base::out
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
// All other processes
|
||||
if (m_platform_file_name.empty()) {
|
||||
EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid());
|
||||
EQEmuLogSys::MakeDirectory("logs/zone");
|
||||
process_log.open(StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
|
||||
} else {
|
||||
if (platform_file_name.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Starting File Log [{}/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
|
||||
|
||||
// Open file pointer
|
||||
process_log.open(
|
||||
fmt::format("{}/{}_{}.log", GetLogPath(), m_platform_file_name.c_str(), getpid()),
|
||||
std::ios_base::app | std::ios_base::out
|
||||
);
|
||||
EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid());
|
||||
process_log.open(StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Silence console logging
|
||||
*/
|
||||
void EQEmuLogSys::SilenceConsoleLogging()
|
||||
{
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = 0;
|
||||
log_settings[log_index].is_category_enabled = 0;
|
||||
}
|
||||
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables console logging
|
||||
*/
|
||||
void EQEmuLogSys::EnableConsoleLogging()
|
||||
{
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = Logs::General;
|
||||
log_settings[log_index].is_category_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
{
|
||||
InjectTablesIfNotExist();
|
||||
|
||||
auto categories = LogsysCategoriesRepository::GetWhere(
|
||||
*m_database,
|
||||
"TRUE ORDER BY log_category_id"
|
||||
);
|
||||
|
||||
// keep track of categories
|
||||
std::vector<int> db_categories{};
|
||||
db_categories.reserve(categories.size());
|
||||
|
||||
// loop through database categories
|
||||
for (auto &c: categories) {
|
||||
if (c.log_category_id <= Logs::None || c.log_category_id >= Logs::MaxCategoryID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
|
||||
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
|
||||
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
|
||||
log_settings[c.log_category_id].log_to_discord = static_cast<uint8>(c.log_to_discord);
|
||||
log_settings[c.log_category_id].discord_webhook_id = c.discord_webhook_id;
|
||||
|
||||
// Determine if any output method is enabled for the category
|
||||
// and set it to 1 so it can used to check if category is enabled
|
||||
const bool log_to_console = log_settings[c.log_category_id].log_to_console > 0;
|
||||
const bool log_to_file = log_settings[c.log_category_id].log_to_file > 0;
|
||||
const bool log_to_gmsay = log_settings[c.log_category_id].log_to_gmsay > 0;
|
||||
const bool log_to_discord = log_settings[c.log_category_id].log_to_discord > 0 &&
|
||||
log_settings[c.log_category_id].discord_webhook_id > 0;
|
||||
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
|
||||
|
||||
if (is_category_enabled) {
|
||||
log_settings[c.log_category_id].is_category_enabled = 1;
|
||||
}
|
||||
|
||||
// This determines whether or not the process needs to actually file log anything.
|
||||
// If we go through this whole loop and nothing is set to any debug level, there
|
||||
// is no point to create a file or keep anything open
|
||||
if (log_settings[c.log_category_id].log_to_file > 0) {
|
||||
LogSys.m_file_logs_enabled = true;
|
||||
}
|
||||
|
||||
db_categories.emplace_back(c.log_category_id);
|
||||
}
|
||||
|
||||
// Auto inject categories that don't exist in the database...
|
||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||
|
||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||
bool is_deprecated_category = Strings::Contains(fmt::format("{}", Logs::LogCategoryName[i]), "Deprecated");
|
||||
if (!is_missing_in_database && is_deprecated_category) {
|
||||
LogInfo(
|
||||
"Logging category [{}] ({}) is now deprecated, deleting from database",
|
||||
Logs::LogCategoryName[i],
|
||||
i
|
||||
);
|
||||
LogsysCategoriesRepository::DeleteOne(*m_database, i);
|
||||
}
|
||||
|
||||
if (is_missing_in_database && !is_deprecated_category) {
|
||||
LogInfo(
|
||||
"Automatically adding new log category [{}] ({})",
|
||||
Logs::LogCategoryName[i],
|
||||
i
|
||||
);
|
||||
|
||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||
new_category.log_category_id = i;
|
||||
new_category.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
|
||||
new_category.log_to_console = log_settings[i].log_to_console;
|
||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
||||
new_category.log_to_file = log_settings[i].log_to_file;
|
||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
||||
|
||||
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Loaded [{}] log categories", categories.size());
|
||||
|
||||
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
||||
if (!webhooks.empty()) {
|
||||
for (auto &w: webhooks) {
|
||||
m_discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url};
|
||||
}
|
||||
LogInfo("Loaded [{}] Discord webhooks", webhooks.size());
|
||||
}
|
||||
|
||||
// force override this setting
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
EQEmuLogSys *EQEmuLogSys::SetDatabase(Database *db)
|
||||
{
|
||||
m_database = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::InjectTablesIfNotExist()
|
||||
{
|
||||
// do not run injections for zone as its unnecessary hits every time a zone boots
|
||||
// other processes less frequently ran can pick up injection
|
||||
if (m_log_platform == EQEmuExePlatform::ExePlatformZone) {
|
||||
return;
|
||||
}
|
||||
|
||||
// inject discord_webhooks
|
||||
if (!m_database->DoesTableExist("discord_webhooks")) {
|
||||
LogInfo("Creating table [discord_webhooks]");
|
||||
m_database->QueryDatabase(
|
||||
SQL(
|
||||
CREATE TABLE discord_webhooks
|
||||
(
|
||||
id INT auto_increment primary key NULL,
|
||||
webhook_name varchar(100) NULL,
|
||||
webhook_url varchar(255) NULL,
|
||||
created_at DATETIME NULL,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_general_ci;
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// inject logsys_categories
|
||||
if (!m_database->DoesTableExist("logsys_categories")) {
|
||||
LogInfo("Creating table [logsys_categories]");
|
||||
m_database->QueryDatabase(
|
||||
SQL(
|
||||
CREATE TABLE `logsys_categories` (
|
||||
`log_category_id` int(11) NOT NULL,
|
||||
`log_category_description` varchar(150) DEFAULT NULL,
|
||||
`log_to_console` smallint(11) DEFAULT 0,
|
||||
`log_to_file` smallint(11) DEFAULT 0,
|
||||
`log_to_gmsay` smallint(11) DEFAULT 0,
|
||||
`log_to_discord` smallint(11) DEFAULT 0,
|
||||
`discord_webhook_id` int(11) DEFAULT 0,
|
||||
PRIMARY KEY (`log_category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const EQEmuLogSys::DiscordWebhooks *EQEmuLogSys::GetDiscordWebhooks() const
|
||||
{
|
||||
return m_discord_webhooks;
|
||||
}
|
||||
|
||||
EQEmuLogSys::LogEnabled EQEmuLogSys::GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
||||
{
|
||||
auto e = LogEnabled{};
|
||||
|
||||
e.log_to_console_enabled = log_settings[log_category].log_to_console > 0 &&
|
||||
log_settings[log_category].log_to_console >= debug_level;
|
||||
e.log_to_file_enabled = log_settings[log_category].log_to_file > 0 &&
|
||||
log_settings[log_category].log_to_file >= debug_level;
|
||||
e.log_to_gmsay_enabled = log_settings[log_category].log_to_gmsay > 0 &&
|
||||
log_settings[log_category].log_to_gmsay >= debug_level &&
|
||||
log_category != Logs::LogCategory::Netcode &&
|
||||
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
|
||||
e.log_to_discord_enabled = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
|
||||
log_settings[log_category].log_to_discord > 0 &&
|
||||
log_settings[log_category].log_to_discord >= debug_level &&
|
||||
log_settings[log_category].discord_webhook_id > 0 &&
|
||||
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
|
||||
e.log_enabled =
|
||||
e.log_to_console_enabled || e.log_to_file_enabled || e.log_to_gmsay_enabled || e.log_to_discord_enabled;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool EQEmuLogSys::IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
||||
{
|
||||
return GetLogsEnabled(debug_level, log_category).log_enabled;
|
||||
}
|
||||
|
||||
const std::string &EQEmuLogSys::GetLogPath() const
|
||||
{
|
||||
return m_log_path;
|
||||
}
|
||||
|
||||
EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
|
||||
{
|
||||
EQEmuLogSys::m_log_path = log_path;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+186
-374
@@ -1,426 +1,238 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_LOGSYS_H
|
||||
#define EQEMU_LOGSYS_H
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <stdio.h>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef utf16_to_utf8
|
||||
#undef utf16_to_utf8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "types.h"
|
||||
|
||||
namespace Logs {
|
||||
enum DebugLevel {
|
||||
General = 1, // 1 - Low-Level general debugging, useful info on single line
|
||||
Detail // 2 - Use this for very chatty logging you want to leave in but don't want on by default
|
||||
General = 1, /* 1 - Low-Level general debugging, useful info on single line */
|
||||
Moderate, /* 2 - Informational based, used in functions, when particular things load */
|
||||
Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */
|
||||
};
|
||||
|
||||
/**
|
||||
* If you add to this, make sure you update LogCategoryName
|
||||
*
|
||||
* NOTE: Only add to the bottom of the enum because that is the type ID assignment
|
||||
*/
|
||||
enum LogCategory {
|
||||
None = 0,
|
||||
AA,
|
||||
AI,
|
||||
Aggro,
|
||||
Attack,
|
||||
DeprecatedCS, // deprecated
|
||||
Combat,
|
||||
Commands,
|
||||
Crash,
|
||||
Debug,
|
||||
Doors,
|
||||
Error,
|
||||
Guilds,
|
||||
Inventory,
|
||||
Launcher,
|
||||
Netcode,
|
||||
Normal, // deprecated
|
||||
Object,
|
||||
Pathing,
|
||||
QSServer, // deprecated
|
||||
Quests,
|
||||
Rules,
|
||||
Skills,
|
||||
Spawns,
|
||||
Spells,
|
||||
Status, // deprecated
|
||||
TCPConnection,
|
||||
Tasks,
|
||||
Tradeskills,
|
||||
Trading,
|
||||
Tribute,
|
||||
UCSServer, // deprecated
|
||||
WebInterfaceServer, // deprecated
|
||||
WorldServer, // deprecated
|
||||
ZoneServer, // deprecated
|
||||
MySQLError,
|
||||
MySQLQuery,
|
||||
Mercenaries,
|
||||
QuestDebug,
|
||||
DeprecatedSC, // deprecated
|
||||
DeprecatedCSU, // deprecated
|
||||
DeprecatedSCD, // deprecated
|
||||
DeprecatedCSD, // deprecated
|
||||
Loginserver, // deprecated
|
||||
ClientLogin,
|
||||
HeadlessClient, // deprecated
|
||||
HPUpdate,
|
||||
FixZ,
|
||||
Food,
|
||||
Traps,
|
||||
NPCRoamBox,
|
||||
NPCScaling,
|
||||
MobAppearance,
|
||||
Info,
|
||||
Warning,
|
||||
Critical, // deprecated
|
||||
Emergency, // deprecated
|
||||
Alert, // deprecated
|
||||
Notice, // deprecated
|
||||
AIScanClose,
|
||||
AIYellForHelp,
|
||||
AICastBeneficialClose,
|
||||
AoeCast,
|
||||
EntityManagement,
|
||||
Flee,
|
||||
Aura,
|
||||
HotReload,
|
||||
Merchants,
|
||||
ZonePoints,
|
||||
Loot,
|
||||
Expeditions,
|
||||
DynamicZones,
|
||||
Scheduler,
|
||||
Cheat,
|
||||
ClientList,
|
||||
DiaWind,
|
||||
HTTP,
|
||||
Saylink,
|
||||
ChecksumVerification,
|
||||
CombatRecord,
|
||||
Hate,
|
||||
Discord,
|
||||
Faction,
|
||||
PacketServerClient,
|
||||
PacketClientServer,
|
||||
PacketServerToServer,
|
||||
Bugs,
|
||||
QuestErrors,
|
||||
PlayerEvents,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
/*
|
||||
If you add to this, make sure you update LogCategoryName
|
||||
NOTE: Only add to the bottom of the enum because that is the type ID assignment
|
||||
*/
|
||||
|
||||
/**
|
||||
* If you add to this, make sure you update LogCategory
|
||||
*/
|
||||
static const char *LogCategoryName[LogCategory::MaxCategoryID] = {
|
||||
"",
|
||||
"AA",
|
||||
"AI",
|
||||
"Aggro",
|
||||
"Attack",
|
||||
"Deprecated",
|
||||
"Combat",
|
||||
"Commands",
|
||||
"Crash",
|
||||
"Debug",
|
||||
"Doors",
|
||||
"Error",
|
||||
"Guilds",
|
||||
"Inventory",
|
||||
"Launcher",
|
||||
"Netcode",
|
||||
"Normal (Deprecated)",
|
||||
"Object",
|
||||
"Pathing",
|
||||
"QS Server (Deprecated)",
|
||||
"Quests",
|
||||
"Rules",
|
||||
"Skills",
|
||||
"Spawns",
|
||||
"Spells",
|
||||
"Status (Deprecated)",
|
||||
"TCP Connection",
|
||||
"Tasks",
|
||||
"Tradeskills",
|
||||
"Trading",
|
||||
"Tribute",
|
||||
"UCS Server (Deprecated)",
|
||||
"Web Interface (Deprecated)",
|
||||
"World Server (Deprecated)",
|
||||
"Zone Server (Deprecated)",
|
||||
"QueryErr",
|
||||
"Query",
|
||||
"Mercenaries",
|
||||
"Quest Debug",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Login Server (Deprecated)",
|
||||
"Client Login",
|
||||
"Headless Client (Deprecated)",
|
||||
"HP Update",
|
||||
"FixZ",
|
||||
"Food",
|
||||
"Traps",
|
||||
"NPC Roam Box",
|
||||
"NPC Scaling",
|
||||
"MobAppearance",
|
||||
"Info",
|
||||
"Warning",
|
||||
"Critical (Deprecated)",
|
||||
"Emergency (Deprecated)",
|
||||
"Alert (Deprecated)",
|
||||
"Notice (Deprecated)",
|
||||
"AI Scan",
|
||||
"AI Yell",
|
||||
"AI CastBeneficial",
|
||||
"AOE Cast",
|
||||
"Entity Management",
|
||||
"Flee",
|
||||
"Aura",
|
||||
"HotReload",
|
||||
"Merchants",
|
||||
"ZonePoints",
|
||||
"Loot",
|
||||
"Expeditions",
|
||||
"DynamicZones",
|
||||
"Scheduler",
|
||||
"Cheat",
|
||||
"ClientList",
|
||||
"DialogueWindow",
|
||||
"HTTP",
|
||||
"Saylink",
|
||||
"ChecksumVer",
|
||||
"CombatRecord",
|
||||
"Hate",
|
||||
"Discord",
|
||||
"Faction",
|
||||
"Packet S->C",
|
||||
"Packet C->S",
|
||||
"Packet S->S",
|
||||
"Bugs",
|
||||
"QuestErrors",
|
||||
"PlayerEvents",
|
||||
};
|
||||
enum LogCategory {
|
||||
None = 0,
|
||||
AA,
|
||||
AI,
|
||||
Aggro,
|
||||
Attack,
|
||||
Client_Server_Packet,
|
||||
Combat,
|
||||
Commands,
|
||||
Crash,
|
||||
Debug,
|
||||
Doors,
|
||||
Error,
|
||||
Guilds,
|
||||
Inventory,
|
||||
Launcher,
|
||||
Netcode,
|
||||
Normal,
|
||||
Object,
|
||||
Pathing,
|
||||
QS_Server,
|
||||
Quests,
|
||||
Rules,
|
||||
Skills,
|
||||
Spawns,
|
||||
Spells,
|
||||
Status,
|
||||
TCP_Connection,
|
||||
Tasks,
|
||||
Tradeskills,
|
||||
Trading,
|
||||
Tribute,
|
||||
UCS_Server,
|
||||
WebInterface_Server,
|
||||
World_Server,
|
||||
Zone_Server,
|
||||
MySQLError,
|
||||
MySQLQuery,
|
||||
Mercenaries,
|
||||
QuestDebug,
|
||||
Server_Client_Packet,
|
||||
Client_Server_Packet_Unhandled,
|
||||
Server_Client_Packet_With_Dump,
|
||||
Client_Server_Packet_With_Dump,
|
||||
Login_Server,
|
||||
Client_Login,
|
||||
Headless_Client,
|
||||
HP_Update,
|
||||
FixZ,
|
||||
Food,
|
||||
Traps,
|
||||
NATS,
|
||||
MaxCategoryID /* Don't Remove this*/
|
||||
};
|
||||
|
||||
/* If you add to this, make sure you update LogCategory */
|
||||
static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
|
||||
"",
|
||||
"AA",
|
||||
"AI",
|
||||
"Aggro",
|
||||
"Attack",
|
||||
"Packet :: Client -> Server",
|
||||
"Combat",
|
||||
"Commands",
|
||||
"Crash",
|
||||
"Debug",
|
||||
"Doors",
|
||||
"Error",
|
||||
"Guilds",
|
||||
"Inventory",
|
||||
"Launcher",
|
||||
"Netcode",
|
||||
"Normal",
|
||||
"Object",
|
||||
"Pathing",
|
||||
"QS Server",
|
||||
"Quests",
|
||||
"Rules",
|
||||
"Skills",
|
||||
"Spawns",
|
||||
"Spells",
|
||||
"Status",
|
||||
"TCP Connection",
|
||||
"Tasks",
|
||||
"Tradeskills",
|
||||
"Trading",
|
||||
"Tribute",
|
||||
"UCS Server",
|
||||
"WebInterface Server",
|
||||
"World Server",
|
||||
"Zone Server",
|
||||
"MySQL Error",
|
||||
"MySQL Query",
|
||||
"Mercenaries",
|
||||
"Quest Debug",
|
||||
"Packet :: Server -> Client",
|
||||
"Packet :: Client -> Server Unhandled",
|
||||
"Packet :: Server -> Client (Dump)",
|
||||
"Packet :: Client -> Server (Dump)",
|
||||
"Login Server",
|
||||
"Client Login",
|
||||
"Headless Client",
|
||||
"HP Update",
|
||||
"FixZ",
|
||||
"Food",
|
||||
"Traps",
|
||||
"NATS"
|
||||
};
|
||||
}
|
||||
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
class Database;
|
||||
|
||||
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
|
||||
#define LogF(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
LogSys.OutF(debug_level, log_category, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
class EQEmuLogSys {
|
||||
public:
|
||||
EQEmuLogSys();
|
||||
~EQEmuLogSys();
|
||||
|
||||
/**
|
||||
* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else.
|
||||
* This should be handled on deconstructor but to be safe we use it anyways.
|
||||
*/
|
||||
void CloseFileLogs();
|
||||
EQEmuLogSys *LoadLogSettingsDefaults();
|
||||
EQEmuLogSys *LoadLogDatabaseSettings();
|
||||
void CloseFileLogs(); /* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else. This should be handled on deconstructor but to be safe we use it anyways. */
|
||||
void LoadLogSettingsDefaults(); /* Initializes log_settings and sets some defaults if DB is not present */
|
||||
void MakeDirectory(const std::string &directory_name); /* Platform independent way of performing a MakeDirectory based on name */
|
||||
/*
|
||||
The one and only Logging function that uses a debug level as a parameter, as well as a log_category
|
||||
log_category - defined in Logs::LogCategory::[]
|
||||
log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id]
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void MakeDirectory(const std::string &directory_name);
|
||||
|
||||
/**
|
||||
* The one and only Logging function that uses a debug level as a parameter, as well as a log_category
|
||||
* log_category - defined in Logs::LogCategory::[]
|
||||
* log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id]
|
||||
*
|
||||
* Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present");
|
||||
* - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
|
||||
* be checked against to see if that piped output is set to actually process it for the category and debug level
|
||||
Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present");
|
||||
- This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
|
||||
be checked against to see if that piped output is set to actually process it for the category and debug level
|
||||
*/
|
||||
void Out(
|
||||
Logs::DebugLevel debug_level,
|
||||
uint16 log_category,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *message,
|
||||
...
|
||||
);
|
||||
void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...);
|
||||
void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */
|
||||
void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */
|
||||
|
||||
/**
|
||||
* Used in file logs to prepend a timestamp entry for logs
|
||||
* @param time_stamp
|
||||
*/
|
||||
void SetCurrentTimeStamp(char *time_stamp);
|
||||
template <typename... Args>
|
||||
void OutF(Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args)
|
||||
{
|
||||
std::string log_str = fmt::format(fmt, args...);
|
||||
Out(debug_level, log_category, log_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_name
|
||||
*/
|
||||
void StartFileLogs(const std::string &log_name = "");
|
||||
/*
|
||||
LogSettings Struct
|
||||
|
||||
/**
|
||||
* LogSettings Struct
|
||||
*
|
||||
* This struct is the master reference for all settings for each category, and for each output
|
||||
*
|
||||
* log_to_file[category_id] = [1-3] - Sets debug level for category to output to file
|
||||
* log_to_console[category_id] = [1-3] - Sets debug level for category to output to console
|
||||
* log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay
|
||||
*
|
||||
This struct is the master reference for all settings for each category, and for each output
|
||||
|
||||
log_to_file[category_id] = [1-3] - Sets debug level for category to output to file
|
||||
log_to_console[category_id] = [1-3] - Sets debug level for category to output to console
|
||||
log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay
|
||||
*/
|
||||
|
||||
struct LogSettings {
|
||||
uint8 log_to_file;
|
||||
uint8 log_to_console;
|
||||
uint8 log_to_gmsay;
|
||||
uint8 log_to_discord;
|
||||
int discord_webhook_id;
|
||||
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
|
||||
};
|
||||
|
||||
struct OriginationInfo {
|
||||
std::string zone_short_name;
|
||||
std::string zone_long_name;
|
||||
int instance_id;
|
||||
};
|
||||
|
||||
OriginationInfo origination_info{};
|
||||
|
||||
/**
|
||||
* Internally used memory reference for all log settings per category
|
||||
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
||||
* Database loaded via LogSys.SetDatabase(&database)->LoadLogDatabaseSettings();
|
||||
/* Internally used memory reference for all log settings per category.
|
||||
These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults.
|
||||
Database loaded via Database::LoadLogSettings(log_settings)
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID];
|
||||
|
||||
struct LogEnabled {
|
||||
bool log_to_file_enabled;
|
||||
bool log_to_console_enabled;
|
||||
bool log_to_gmsay_enabled;
|
||||
bool log_to_discord_enabled;
|
||||
bool log_enabled;
|
||||
};
|
||||
bool file_logs_enabled; /* Set when log settings are loaded to determine if keeping a file open is necessary */
|
||||
|
||||
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
int log_platform; /* Sets Executable platform (Zone/World/UCS) etc. */
|
||||
|
||||
struct DiscordWebhooks {
|
||||
int id;
|
||||
std::string webhook_name;
|
||||
std::string webhook_url;
|
||||
};
|
||||
std::string platform_file_name; /* File name used in writing logs */
|
||||
|
||||
const DiscordWebhooks *GetDiscordWebhooks() const;
|
||||
uint16 GetGMSayColorFromCategory(uint16 log_category); /* GMSay Client Message colors mapped by category */
|
||||
|
||||
// gmsay
|
||||
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
||||
|
||||
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)>& f)
|
||||
{
|
||||
m_on_log_gmsay_hook = f;
|
||||
return this;
|
||||
}
|
||||
|
||||
EQEmuLogSys *SetDiscordHandler(std::function<void(uint16 log_category, int webhook_id, const std::string &)> f)
|
||||
{
|
||||
m_on_log_discord_hook = f;
|
||||
return this;
|
||||
}
|
||||
|
||||
// console
|
||||
void SetConsoleHandler(
|
||||
std::function<void(
|
||||
uint16 log_type,
|
||||
const std::string &
|
||||
)> f
|
||||
) { m_on_log_console_hook = f; }
|
||||
void SilenceConsoleLogging();
|
||||
void EnableConsoleLogging();
|
||||
|
||||
// database
|
||||
EQEmuLogSys *SetDatabase(Database *db);
|
||||
|
||||
[[nodiscard]] const std::string &GetLogPath() const;
|
||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
||||
void OnLogHookCallBackZone(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
|
||||
|
||||
private:
|
||||
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook; /* Callback pointer to zone process for hooking logs to zone using GMSay */
|
||||
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message); /* Formats log messages like '[Category] This is a log message' */
|
||||
std::string GetLinuxConsoleColorFromCategory(uint16 log_category); /* Linux console color messages mapped by category */
|
||||
|
||||
// reference to database
|
||||
Database *m_database;
|
||||
std::function<void(uint16 log_category, const char *func, const std::string &)> m_on_log_gmsay_hook;
|
||||
std::function<void(uint16 log_category, int webhook_id, const std::string &)> m_on_log_discord_hook;
|
||||
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
|
||||
DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
|
||||
bool m_file_logs_enabled = false;
|
||||
int m_log_platform = 0;
|
||||
std::string m_platform_file_name;
|
||||
std::string m_log_path;
|
||||
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category); /* Windows console color messages mapped by category */
|
||||
|
||||
void ProcessConsoleMessage(
|
||||
uint16 log_category,
|
||||
const std::string &message,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line
|
||||
);
|
||||
void ProcessLogWrite(uint16 log_category, const std::string &message);
|
||||
void InjectTablesIfNotExist();
|
||||
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessConsoleMessage called via Log */
|
||||
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessGMSay called via Log */
|
||||
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessLogWrite called via Log */
|
||||
};
|
||||
|
||||
extern EQEmuLogSys LogSys;
|
||||
|
||||
/**
|
||||
template<typename... Args>
|
||||
void OutF(
|
||||
EQEmuLogSys &ls,
|
||||
Logs::DebugLevel debug_level,
|
||||
uint16 log_category,
|
||||
const char *file,
|
||||
const char *func,
|
||||
int line,
|
||||
const char *fmt,
|
||||
const Args &... args
|
||||
)
|
||||
{
|
||||
std::string log_str = fmt::format(fmt, args...);
|
||||
ls.Out(debug_level, log_category, file, func, line, log_str.c_str());
|
||||
}
|
||||
**/
|
||||
|
||||
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
|
||||
do { \
|
||||
ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,808 +0,0 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
|
||||
#define LogAA(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AA))\
|
||||
OutF(LogSys, Logs::General, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAADetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AA))\
|
||||
OutF(LogSys, Logs::Detail, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAI(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AI))\
|
||||
OutF(LogSys, Logs::General, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AI))\
|
||||
OutF(LogSys, Logs::Detail, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAggro(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Aggro))\
|
||||
OutF(LogSys, Logs::General, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAggroDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Aggro))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAttack(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Attack))\
|
||||
OutF(LogSys, Logs::General, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAttackDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Attack))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketClientServer(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::PacketClientServer))\
|
||||
OutF(LogSys, Logs::General, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketClientServerDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer))\
|
||||
OutF(LogSys, Logs::Detail, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCombat(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Combat))\
|
||||
OutF(LogSys, Logs::General, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Combat))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCommands(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Commands))\
|
||||
OutF(LogSys, Logs::General, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCommandsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Commands))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCrash(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Crash))\
|
||||
OutF(LogSys, Logs::General, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCrashDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Crash))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDebug(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Debug))\
|
||||
OutF(LogSys, Logs::General, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDebugDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Debug))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDoors(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Doors))\
|
||||
OutF(LogSys, Logs::General, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDoorsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Doors))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogError(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Error))\
|
||||
OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogErrorDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Error))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogGuilds(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Guilds))\
|
||||
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogGuildsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Guilds))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInventory(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Inventory))\
|
||||
OutF(LogSys, Logs::General, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInventoryDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Inventory))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLauncher(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Launcher))\
|
||||
OutF(LogSys, Logs::General, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLauncherDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Launcher))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNetcode(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Netcode))\
|
||||
OutF(LogSys, Logs::General, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNetcodeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Netcode))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNormal(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Normal))\
|
||||
OutF(LogSys, Logs::General, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNormalDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Normal))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogObject(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Object))\
|
||||
OutF(LogSys, Logs::General, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogObjectDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Object))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPathing(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Pathing))\
|
||||
OutF(LogSys, Logs::General, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPathingDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Pathing))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuests(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Quests))\
|
||||
OutF(LogSys, Logs::General, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Quests))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogRules(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Rules))\
|
||||
OutF(LogSys, Logs::General, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogRulesDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Rules))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSkills(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Skills))\
|
||||
OutF(LogSys, Logs::General, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSkillsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Skills))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpawns(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Spawns))\
|
||||
OutF(LogSys, Logs::General, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpawnsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Spawns))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpells(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Spells))\
|
||||
OutF(LogSys, Logs::General, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSpellsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Spells))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogStatus(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Status))\
|
||||
OutF(LogSys, Logs::General, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogStatusDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Status))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTCPConnection(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::TCPConnection))\
|
||||
OutF(LogSys, Logs::General, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTCPConnectionDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::TCPConnection))\
|
||||
OutF(LogSys, Logs::Detail, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTasks(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Tasks))\
|
||||
OutF(LogSys, Logs::General, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTasksDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Tasks))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTradeskills(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Tradeskills))\
|
||||
OutF(LogSys, Logs::General, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTradeskillsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Tradeskills))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTrading(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Trading))\
|
||||
OutF(LogSys, Logs::General, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTradingDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Trading))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTribute(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Tribute))\
|
||||
OutF(LogSys, Logs::General, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTributeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Tribute))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLError(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::MySQLError))\
|
||||
OutF(LogSys, Logs::General, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLErrorDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::MySQLError))\
|
||||
OutF(LogSys, Logs::Detail, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLQuery(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::MySQLQuery))\
|
||||
OutF(LogSys, Logs::General, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMySQLQueryDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::MySQLQuery))\
|
||||
OutF(LogSys, Logs::Detail, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMercenaries(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Mercenaries))\
|
||||
OutF(LogSys, Logs::General, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMercenariesDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Mercenaries))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestDebug(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::QuestDebug))\
|
||||
OutF(LogSys, Logs::General, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestDebugDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::QuestDebug))\
|
||||
OutF(LogSys, Logs::Detail, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketServerClient(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::PacketServerClient))\
|
||||
OutF(LogSys, Logs::General, Logs::PacketServerClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketServerClientDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient))\
|
||||
OutF(LogSys, Logs::Detail, Logs::PacketServerClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
|
||||
#define LogLoginserver(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Loginserver))\
|
||||
OutF(LogSys, Logs::General, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLoginserverDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Loginserver))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogClientLogin(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::ClientLogin))\
|
||||
OutF(LogSys, Logs::General, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogClientLoginDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::ClientLogin))\
|
||||
OutF(LogSys, Logs::Detail, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHPUpdate(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::HPUpdate))\
|
||||
OutF(LogSys, Logs::General, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHPUpdateDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::HPUpdate))\
|
||||
OutF(LogSys, Logs::Detail, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFixZ(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::FixZ))\
|
||||
OutF(LogSys, Logs::General, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFixZDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::FixZ))\
|
||||
OutF(LogSys, Logs::Detail, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFood(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Food))\
|
||||
OutF(LogSys, Logs::General, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFoodDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Food))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTraps(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Traps))\
|
||||
OutF(LogSys, Logs::General, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogTrapsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Traps))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCRoamBox(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::NPCRoamBox))\
|
||||
OutF(LogSys, Logs::General, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCRoamBoxDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::NPCRoamBox))\
|
||||
OutF(LogSys, Logs::Detail, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCScaling(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::NPCScaling))\
|
||||
OutF(LogSys, Logs::General, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNPCScalingDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::NPCScaling))\
|
||||
OutF(LogSys, Logs::Detail, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMobAppearance(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::MobAppearance))\
|
||||
OutF(LogSys, Logs::General, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMobAppearanceDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::MobAppearance))\
|
||||
OutF(LogSys, Logs::Detail, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInfo(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Info))\
|
||||
OutF(LogSys, Logs::General, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogInfoDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Info))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogWarning(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Warning))\
|
||||
OutF(LogSys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogWarningDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Warning))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCritical(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Critical))\
|
||||
OutF(LogSys, Logs::General, Logs::Critical, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCriticalDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Critical))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Critical, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEmergency(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Emergency))\
|
||||
OutF(LogSys, Logs::General, Logs::Emergency, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEmergencyDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Emergency))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Emergency, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAlert(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Alert))\
|
||||
OutF(LogSys, Logs::General, Logs::Alert, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAlertDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Alert))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Alert, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNotice(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Notice))\
|
||||
OutF(LogSys, Logs::General, Logs::Notice, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNoticeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Notice))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Notice, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIScanClose(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AIScanClose))\
|
||||
OutF(LogSys, Logs::General, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIScanCloseDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AIScanClose))\
|
||||
OutF(LogSys, Logs::Detail, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIYellForHelp(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AIYellForHelp))\
|
||||
OutF(LogSys, Logs::General, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAIYellForHelpDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AIYellForHelp))\
|
||||
OutF(LogSys, Logs::Detail, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAICastBeneficialClose(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AICastBeneficialClose))\
|
||||
OutF(LogSys, Logs::General, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAICastBeneficialCloseDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AICastBeneficialClose))\
|
||||
OutF(LogSys, Logs::Detail, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAoeCast(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AoeCast))\
|
||||
OutF(LogSys, Logs::General, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAoeCastDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::AoeCast))\
|
||||
OutF(LogSys, Logs::Detail, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEntityManagement(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::EntityManagement))\
|
||||
OutF(LogSys, Logs::General, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEntityManagementDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EntityManagement))\
|
||||
OutF(LogSys, Logs::Detail, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFlee(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Flee))\
|
||||
OutF(LogSys, Logs::General, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFleeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Flee))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAura(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Aura))\
|
||||
OutF(LogSys, Logs::General, Logs::Aura, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogAuraDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Aura))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Aura, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHotReload(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::HotReload))\
|
||||
OutF(LogSys, Logs::General, Logs::HotReload, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHotReloadDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::HotReload))\
|
||||
OutF(LogSys, Logs::Detail, Logs::HotReload, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMerchants(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Merchants))\
|
||||
OutF(LogSys, Logs::General, Logs::Merchants, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogMerchantsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Merchants))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Merchants, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZonePoints(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::ZonePoints))\
|
||||
OutF(LogSys, Logs::General, Logs::ZonePoints, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZonePointsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::ZonePoints))\
|
||||
OutF(LogSys, Logs::Detail, Logs::ZonePoints, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLoot(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Loot))\
|
||||
OutF(LogSys, Logs::General, Logs::Loot, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogLootDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Loot))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Loot, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogExpeditions(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Expeditions))\
|
||||
OutF(LogSys, Logs::General, Logs::Expeditions, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogExpeditionsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Expeditions))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Expeditions, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDynamicZones(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::DynamicZones))\
|
||||
OutF(LogSys, Logs::General, Logs::DynamicZones, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDynamicZonesDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DynamicZones))\
|
||||
OutF(LogSys, Logs::Detail, Logs::DynamicZones, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogScheduler(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Scheduler))\
|
||||
OutF(LogSys, Logs::General, Logs::Scheduler, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSchedulerDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Scheduler))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Scheduler, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCheat(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Cheat))\
|
||||
OutF(LogSys, Logs::General, Logs::Cheat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCheatDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Cheat))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Cheat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogClientList(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::ClientList))\
|
||||
OutF(LogSys, Logs::General, Logs::ClientList, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogClientListDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::ClientList))\
|
||||
OutF(LogSys, Logs::Detail, Logs::ClientList, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDiaWind(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::DiaWind))\
|
||||
OutF(LogSys, Logs::General, Logs::DiaWind, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDiaWindDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DiaWind))\
|
||||
OutF(LogSys, Logs::Detail, Logs::DiaWind, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHTTP(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::HTTP))\
|
||||
OutF(LogSys, Logs::General, Logs::HTTP, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHTTPDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::HTTP))\
|
||||
OutF(LogSys, Logs::Detail, Logs::HTTP, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSaylink(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Saylink))\
|
||||
OutF(LogSys, Logs::General, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSaylinkDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Saylink))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogChecksumVerification(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::ChecksumVerification))\
|
||||
OutF(LogSys, Logs::General, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogChecksumVerificationDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::ChecksumVerification))\
|
||||
OutF(LogSys, Logs::Detail, Logs::ChecksumVerification, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatRecord(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::CombatRecord))\
|
||||
OutF(LogSys, Logs::General, Logs::CombatRecord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCombatRecordDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::CombatRecord))\
|
||||
OutF(LogSys, Logs::Detail, Logs::CombatRecord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHate(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Hate))\
|
||||
OutF(LogSys, Logs::General, Logs::Hate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogHateDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Hate))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Hate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDiscord(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Discord))\
|
||||
OutF(LogSys, Logs::General, Logs::Discord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDiscordDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Discord))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Discord, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFaction(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Faction))\
|
||||
OutF(LogSys, Logs::General, Logs::Faction, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogFactionDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Faction))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Faction, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketServerToServer(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::PacketServerToServer))\
|
||||
OutF(LogSys, Logs::General, Logs::PacketServerToServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPacketServerToServerDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer))\
|
||||
OutF(LogSys, Logs::Detail, Logs::PacketServerToServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
// manually created
|
||||
|
||||
#define LogBugs(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Bugs))\
|
||||
OutF(LogSys, Logs::General, Logs::Bugs, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBugsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Bugs))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Bugs, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestErrors(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::QuestErrors))\
|
||||
OutF(LogSys, Logs::General, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogQuestErrorsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::QuestErrors))\
|
||||
OutF(LogSys, Logs::Detail, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPlayerEvents(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::PlayerEvents))\
|
||||
OutF(LogSys, Logs::General, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPlayerEventsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PlayerEvents))\
|
||||
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogF(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include "event_loop.h"
|
||||
|
||||
namespace EQ {
|
||||
class BackgroundTask
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(void)> BackgroundTaskFunction;
|
||||
struct BackgroundTaskBaton
|
||||
{
|
||||
BackgroundTaskFunction fn;
|
||||
BackgroundTaskFunction on_finish;
|
||||
};
|
||||
|
||||
BackgroundTask(BackgroundTaskFunction fn, BackgroundTaskFunction on_finish) {
|
||||
uv_work_t *m_work = new uv_work_t;
|
||||
memset(m_work, 0, sizeof(uv_work_t));
|
||||
BackgroundTaskBaton *baton = new BackgroundTaskBaton();
|
||||
baton->fn = fn;
|
||||
baton->on_finish = on_finish;
|
||||
|
||||
m_work->data = baton;
|
||||
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
||||
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
|
||||
baton->fn();
|
||||
}, [](uv_work_t* req, int status) {
|
||||
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
|
||||
baton->on_finish();
|
||||
delete baton;
|
||||
delete req;
|
||||
});
|
||||
}
|
||||
|
||||
~BackgroundTask() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace EQ
|
||||
{
|
||||
public:
|
||||
static EventLoop &Get() {
|
||||
static thread_local EventLoop inst;
|
||||
static EventLoop inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
@@ -21,14 +21,6 @@ namespace EQ
|
||||
uv_run(&m_loop, UV_RUN_NOWAIT);
|
||||
}
|
||||
|
||||
void Run() {
|
||||
uv_run(&m_loop, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
uv_stop(&m_loop);
|
||||
}
|
||||
|
||||
uv_loop_t* Handle() { return &m_loop; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
#pragma once
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <exception>
|
||||
#include "event_loop.h"
|
||||
|
||||
namespace EQ {
|
||||
class Task
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(const std::any&)> ResolveFn;
|
||||
typedef std::function<void(const std::exception&)> RejectFn;
|
||||
typedef std::function<void()> FinallyFn;
|
||||
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
|
||||
struct TaskBaton
|
||||
{
|
||||
TaskFn fn;
|
||||
ResolveFn on_then;
|
||||
RejectFn on_catch;
|
||||
FinallyFn on_finally;
|
||||
bool has_result;
|
||||
std::any result;
|
||||
bool has_error;
|
||||
std::exception error;
|
||||
};
|
||||
|
||||
Task(TaskFn fn) {
|
||||
m_fn = fn;
|
||||
}
|
||||
|
||||
~Task() {
|
||||
|
||||
}
|
||||
|
||||
Task& Then(ResolveFn fn) {
|
||||
m_then = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Task& Catch(RejectFn fn) {
|
||||
m_catch = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Task& Finally(FinallyFn fn) {
|
||||
m_finally = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Run() {
|
||||
uv_work_t *m_work = new uv_work_t;
|
||||
memset(m_work, 0, sizeof(uv_work_t));
|
||||
TaskBaton *baton = new TaskBaton();
|
||||
baton->fn = m_fn;
|
||||
baton->on_then = m_then;
|
||||
baton->on_catch = m_catch;
|
||||
baton->on_finally = m_finally;
|
||||
baton->has_result = false;
|
||||
baton->has_error = false;
|
||||
|
||||
m_work->data = baton;
|
||||
|
||||
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
||||
TaskBaton *baton = (TaskBaton*)req->data;
|
||||
|
||||
baton->fn([baton](const std::any& result) {
|
||||
baton->has_error = false;
|
||||
baton->has_result = true;
|
||||
baton->result = result;
|
||||
}, [baton](const std::exception &err) {
|
||||
baton->has_error = true;
|
||||
baton->has_result = false;
|
||||
baton->error = err;
|
||||
});
|
||||
}, [](uv_work_t* req, int status) {
|
||||
TaskBaton *baton = (TaskBaton*)req->data;
|
||||
|
||||
if (baton->has_error && baton->on_catch) {
|
||||
baton->on_catch(baton->error);
|
||||
}
|
||||
else if (baton->has_result && baton->on_then) {
|
||||
baton->on_then(baton->result);
|
||||
}
|
||||
|
||||
if (baton->on_finally) {
|
||||
baton->on_finally();
|
||||
}
|
||||
|
||||
delete baton;
|
||||
delete req;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
TaskFn m_fn;
|
||||
ResolveFn m_then;
|
||||
RejectFn m_catch;
|
||||
FinallyFn m_finally;
|
||||
};
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <future>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Event
|
||||
{
|
||||
class TaskScheduler
|
||||
{
|
||||
public:
|
||||
static const int DefaultThreadCount = 4;
|
||||
|
||||
TaskScheduler() : _running(false)
|
||||
{
|
||||
Start(DefaultThreadCount);
|
||||
}
|
||||
|
||||
TaskScheduler(size_t threads) : _running(false)
|
||||
{
|
||||
Start(threads);
|
||||
}
|
||||
|
||||
~TaskScheduler() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
void Start(size_t threads) {
|
||||
if (true == _running) {
|
||||
return;
|
||||
}
|
||||
|
||||
_running = true;
|
||||
|
||||
for (size_t i = 0; i < threads; ++i) {
|
||||
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
||||
}
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
if (false == _running) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
_running = false;
|
||||
}
|
||||
|
||||
_cv.notify_all();
|
||||
|
||||
for (auto &t : _threads) {
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Fn, typename... Args>
|
||||
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::invoke_result<Fn, Args...>::type> {
|
||||
using return_type = typename std::invoke_result<Fn, Args...>::type;
|
||||
|
||||
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
||||
);
|
||||
|
||||
std::future<return_type> res = task->get_future();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
|
||||
if (false == _running) {
|
||||
throw std::runtime_error("Enqueue on stopped scheduler.");
|
||||
}
|
||||
|
||||
_tasks.emplace([task]() { (*task)(); });
|
||||
}
|
||||
|
||||
_cv.notify_one();
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
void ProcessWork() {
|
||||
for (;;) {
|
||||
std::function<void()> work;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_lock);
|
||||
_cv.wait(lock, [this] { return !_running || !_tasks.empty(); });
|
||||
|
||||
if (false == _running) {
|
||||
return;
|
||||
}
|
||||
|
||||
work = std::move(_tasks.front());
|
||||
_tasks.pop();
|
||||
}
|
||||
|
||||
work();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool _running = true;
|
||||
std::vector<std::thread> _threads;
|
||||
std::mutex _lock;
|
||||
std::condition_variable _cv;
|
||||
std::queue<std::function<void()>> _tasks;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace EQ {
|
||||
void Stop() {
|
||||
if (m_timer) {
|
||||
uv_close((uv_handle_t*)m_timer, [](uv_handle_t* handle) {
|
||||
delete (uv_timer_t *)handle;
|
||||
delete handle;
|
||||
});
|
||||
m_timer = nullptr;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "event_sub.h"
|
||||
#include <string.h>
|
||||
|
||||
void EventSubscriptionWatcher::Subscribe(const std::string &event_name)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
class EventSubscriptionWatcher
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,214 +0,0 @@
|
||||
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||
|
||||
#include <string>
|
||||
#include "player_events.h"
|
||||
#include "../repositories/base/base_player_event_logs_repository.h"
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
|
||||
struct DiscordField {
|
||||
std::string name;
|
||||
std::string value;
|
||||
bool is_inline;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(name),
|
||||
CEREAL_NVP(value),
|
||||
cereal::make_nvp("inline", is_inline)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscordAuthor {
|
||||
std::string name;
|
||||
std::string icon_url;
|
||||
std::string url;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(name),
|
||||
CEREAL_NVP(icon_url),
|
||||
CEREAL_NVP(url)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscordEmbed {
|
||||
std::vector<DiscordField> fields;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string timestamp;
|
||||
DiscordAuthor author;
|
||||
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(fields),
|
||||
CEREAL_NVP(title),
|
||||
CEREAL_NVP(description),
|
||||
CEREAL_NVP(timestamp),
|
||||
CEREAL_NVP(author)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscordWebhook {
|
||||
std::vector<DiscordEmbed> embeds;
|
||||
std::string content;
|
||||
std::string avatar_url;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(embeds),
|
||||
CEREAL_NVP(avatar_url),
|
||||
CEREAL_NVP(content)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PlayerEventDiscordFormatter {
|
||||
public:
|
||||
static std::string GetCurrentTimestamp();
|
||||
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
|
||||
static std::string
|
||||
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
|
||||
static void BuildDiscordField(
|
||||
std::vector<DiscordField> *f,
|
||||
const std::string &name,
|
||||
const std::string &value,
|
||||
bool is_inline = true
|
||||
);
|
||||
static void BuildBaseEmbed(
|
||||
std::vector<DiscordEmbed> *e,
|
||||
const std::vector<DiscordField> &f,
|
||||
PlayerEvent::PlayerEventContainer c
|
||||
);
|
||||
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
|
||||
|
||||
static std::string FormatAAGainedEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::AAGainedEvent &e
|
||||
);
|
||||
static std::string FormatAAPurchasedEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::AAPurchasedEvent &e
|
||||
);
|
||||
static std::string FormatDeathEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DeathEvent &e
|
||||
);
|
||||
static std::string FormatFishSuccessEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::FishSuccessEvent &e
|
||||
);
|
||||
static std::string FormatForageSuccessEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::ForageSuccessEvent &e
|
||||
);
|
||||
static std::string FormatDestroyItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DestroyItemEvent &e
|
||||
);
|
||||
static std::string FormatDiscoverItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DiscoverItemEvent &e
|
||||
);
|
||||
static std::string FormatDroppedItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DroppedItemEvent &e
|
||||
);
|
||||
static std::string FormatLevelGainedEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::LevelGainedEvent &e
|
||||
);
|
||||
static std::string FormatLevelLostEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::LevelLostEvent &e
|
||||
);
|
||||
static std::string FormatLootItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::LootItemEvent &e
|
||||
);
|
||||
static std::string FormatGroundSpawnPickupEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::GroundSpawnPickupEvent &e
|
||||
);
|
||||
static std::string FormatMerchantPurchaseEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::MerchantPurchaseEvent &e
|
||||
);
|
||||
static std::string FormatMerchantSellEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::MerchantSellEvent &e
|
||||
);
|
||||
static std::string FormatNPCHandinEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::HandinEvent &e
|
||||
);
|
||||
static std::string FormatSkillUpEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::SkillUpEvent &e
|
||||
);
|
||||
static std::string FormatTaskAcceptEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TaskAcceptEvent &e
|
||||
);
|
||||
static std::string FormatTaskCompleteEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TaskCompleteEvent &e
|
||||
);
|
||||
static std::string FormatTaskUpdateEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TaskUpdateEvent &e
|
||||
);
|
||||
static std::string FormatTradeEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TradeEvent &e
|
||||
);
|
||||
static std::string FormatTraderPurchaseEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TraderPurchaseEvent &e
|
||||
);
|
||||
static std::string FormatTraderSellEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TraderSellEvent &e
|
||||
);
|
||||
static std::string FormatResurrectAcceptEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::ResurrectAcceptEvent &e
|
||||
);
|
||||
static std::string FormatSplitMoneyEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::SplitMoneyEvent &e
|
||||
);
|
||||
static std::string FormatCombineEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::CombineEvent &e
|
||||
);
|
||||
static std::string FormatZoningEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::ZoningEvent &e
|
||||
);
|
||||
static DiscordWebhook BuildDiscordWebhook(
|
||||
const PlayerEvent::PlayerEventContainer &p,
|
||||
std::vector<DiscordEmbed> &embeds
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user