mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 16:28:28 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 307923598b | |||
| 644d9c15c6 | |||
| cf4f628340 | |||
| 8af508d8c5 | |||
| f85644a09c | |||
| 1a6c6cf768 | |||
| c5ffb44edb | |||
| e0637e29f1 | |||
| 40980a9d39 | |||
| d906f79e6f | |||
| 8293225ecc | |||
| e06a845921 | |||
| aa4aced94d | |||
| 0e0027ca20 | |||
| 5c7ab59fd3 | |||
| 120cf6a4b8 | |||
| 3ddfed8bb6 | |||
| 586eb9e5c1 | |||
| 32227d19ce | |||
| c233379894 | |||
| a51a1d7106 | |||
| 6d05903170 | |||
| 4ae0f2a1d7 |
-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:v13
|
||||
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
|
||||
+1
-41
@@ -17,8 +17,6 @@
|
||||
*.out
|
||||
*.app
|
||||
|
||||
.bash_history
|
||||
|
||||
# CMake
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
@@ -29,45 +27,7 @@ install_manifest.txt
|
||||
log/
|
||||
logs/
|
||||
vcpkg/
|
||||
perl/
|
||||
|
||||
.idea/*
|
||||
*cbp
|
||||
|
||||
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/*
|
||||
.editorconfig
|
||||
@@ -16,3 +16,6 @@
|
||||
[submodule "submodules/recastnavigation"]
|
||||
path = submodules/recastnavigation
|
||||
url = https://github.com/EQEmu/recastnavigation.git
|
||||
[submodule "submodules/zlibng"]
|
||||
path = submodules/zlibng
|
||||
url = https://github.com/zlib-ng/zlib-ng.git
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
language: cpp
|
||||
compiler: gcc
|
||||
dist: trusty
|
||||
|
||||
before_install:
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo apt-get update -qq
|
||||
- mkdir $HOME/usr
|
||||
- export PATH="$HOME/usr/bin:$PATH"
|
||||
- wget https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.sh
|
||||
- chmod +x cmake-3.11.2-Linux-x86_64.sh
|
||||
- ./cmake-3.11.2-Linux-x86_64.sh --prefix=$HOME/usr --exclude-subdir --skip-license
|
||||
|
||||
install:
|
||||
- sudo apt-get install -qq g++-7
|
||||
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90
|
||||
- sudo apt-get install libmysqlclient-dev
|
||||
- sudo apt-get install libperl-dev
|
||||
- sudo apt-get install libboost-dev
|
||||
- sudo apt-get install liblua5.1-0-dev
|
||||
- sudo apt-get install zlib1g-dev
|
||||
- sudo apt-get install uuid-dev
|
||||
- sudo apt-get install libssl-dev
|
||||
script:
|
||||
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
||||
- make -j2
|
||||
- ./bin/tests
|
||||
@@ -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
|
||||
-2381
File diff suppressed because it is too large
Load Diff
+68
-212
@@ -1,47 +1,23 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||
|
||||
IF(POLICY CMP0074)
|
||||
CMAKE_POLICY(SET CMP0074 NEW)
|
||||
ENDIF()
|
||||
|
||||
PROJECT(EQEmu)
|
||||
|
||||
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 14)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
||||
|
||||
IF (EQEMU_BUILD_STATIC)
|
||||
SET(BUILD_SHARED_LIBS OFF)
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
||||
MESSAGE(STATUS "Building with static linking")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
||||
IF (UNIX)
|
||||
SET(PERL_LIBRARY "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/libperl.so")
|
||||
SET(PERL_INCLUDE_PATH "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/")
|
||||
SET(PERL_EXECUTABLE "/opt/eqemu-perl/bin/perl")
|
||||
ENDIF ()
|
||||
ENDIF (EQEMU_BUILD_STATIC)
|
||||
|
||||
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")
|
||||
|
||||
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
||||
IF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||
ELSE(MSVC)
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
@@ -63,19 +39,13 @@ ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
||||
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
||||
|
||||
#MSVC can fetch dependencies automatically.
|
||||
IF(MSVC)
|
||||
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
|
||||
ENDIF()
|
||||
|
||||
#Find everything we need
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
FIND_PACKAGE(MySQL)
|
||||
FIND_PACKAGE(MariaDB)
|
||||
FIND_PACKAGE(Boost REQUIRED)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
FIND_PACKAGE(Lua51)
|
||||
FIND_PACKAGE(LuaJit)
|
||||
FIND_PACKAGE(PerlLibs)
|
||||
FIND_PACKAGE(Sodium)
|
||||
FIND_PACKAGE(mbedTLS)
|
||||
@@ -108,12 +78,6 @@ ELSE()
|
||||
MESSAGE(STATUS "* Lua: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
IF(LuaJit_FOUND)
|
||||
MESSAGE(STATUS "* LuaJIT: FOUND *")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "* LuaJIT: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
IF(PerlLibs_FOUND)
|
||||
MESSAGE(STATUS "* Perl: FOUND *")
|
||||
ELSE()
|
||||
@@ -138,87 +102,31 @@ ELSE()
|
||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
|
||||
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
|
||||
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
|
||||
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
|
||||
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
|
||||
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
|
||||
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#options
|
||||
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
|
||||
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
|
||||
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_ENABLE_BOTS)
|
||||
ADD_DEFINITIONS(-DBOTS)
|
||||
ENDIF(EQEMU_ENABLE_BOTS)
|
||||
|
||||
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")
|
||||
ENDIF()
|
||||
#database
|
||||
#prefer mariadb to mysql (arbitrary)
|
||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
||||
ELSEIF(MariaDB_FOUND)
|
||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
||||
@@ -234,47 +142,23 @@ ENDIF()
|
||||
#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"
|
||||
)
|
||||
|
||||
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()
|
||||
SET(SSL_LIBRARY_TYPE " OpenSSL")
|
||||
SET(SSL_LIBRARY_ENABLED ON)
|
||||
SET(SSL_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||
SET(SSL_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||
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()
|
||||
SET(SSL_LIBRARY_TYPE " OpenSSL")
|
||||
SET(SSL_LIBRARY_ENABLED ON)
|
||||
SET(SSL_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||
SET(SSL_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||
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)
|
||||
SET(SSL_LIBRARY_TYPE " mbedTLS")
|
||||
SET(SSL_LIBRARY_ENABLED ON)
|
||||
SET(SSL_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
||||
SET(SSL_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
||||
ELSE()
|
||||
SET(TLS_LIBRARY_TYPE "Disabled")
|
||||
SET(TLS_LIBRARY_ENABLED OFF)
|
||||
SET(SSL_LIBRARY_TYPE "Disabled")
|
||||
SET(SSL_LIBRARY_ENABLED OFF)
|
||||
ENDIF()
|
||||
|
||||
IF(SODIUM_FOUND)
|
||||
@@ -288,64 +172,65 @@ ELSE()
|
||||
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 )
|
||||
IF(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")
|
||||
|
||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||
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()
|
||||
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})
|
||||
|
||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
ENDIF()
|
||||
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)
|
||||
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." OFF)
|
||||
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")
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/submodules/zlibng")
|
||||
ELSE()
|
||||
SET(ZLIB_LIBRARY_TYPE " zlib")
|
||||
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")
|
||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/submodules/zlibng")
|
||||
ENDIF()
|
||||
|
||||
IF (EQEMU_BUILD_STATIC)
|
||||
SET(ZLIB_LIBRARY_LIBS libz.a)
|
||||
ENDIF(EQEMU_BUILD_STATIC)
|
||||
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Library Usage *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "* TLS: ${SSL_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 "* zlib: ${ZLIB_LIBRARY_TYPE} *")
|
||||
MESSAGE(STATUS "**************************************************")
|
||||
|
||||
#setup server libs and headers
|
||||
@@ -365,12 +250,9 @@ INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigat
|
||||
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}")
|
||||
IF(SSL_LIBRARY_ENABLED)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SSL_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${SSL_LIBRARY_INCLUDE}")
|
||||
ENDIF()
|
||||
|
||||
IF(SODIUM_LIBRARY_ENABLED)
|
||||
@@ -378,33 +260,14 @@ IF(SODIUM_LIBRARY_ENABLED)
|
||||
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()
|
||||
IF(EQEMU_BUILD_LUA)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
|
||||
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)
|
||||
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
||||
IF (UNIX AND EQEMU_BUILD_STATIC)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
IF(EQEMU_BUILD_PERL)
|
||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||
ENDIF()
|
||||
|
||||
IF(WIN32)
|
||||
@@ -416,20 +279,11 @@ 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_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
|
||||
IF(EQEMU_BUILD_LOGIN AND NOT SSL_LIBRARY_ENABLED)
|
||||
MESSAGE(FATAL_ERROR "Login server requires a SSL Library to build.")
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||
@@ -437,19 +291,21 @@ IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_H
|
||||
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)
|
||||
ADD_SUBDIRECTORY(submodules/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)
|
||||
|
||||
MESSAGE(STATUS "Libs: ${SERVER_LIBS}")
|
||||
|
||||
IF(EQEMU_BUILD_SERVER)
|
||||
ADD_SUBDIRECTORY(shared_memory)
|
||||
ADD_SUBDIRECTORY(world)
|
||||
|
||||
@@ -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,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 w/ Bots (Windows) |Appveyor w/o Bots (Windows) |
|
||||
|:---:|:---:|:---:|
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[](https://ci.appveyor.com/project/KimLS/server-w0pq2/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)
|
||||
@@ -80,4 +76,3 @@ forum, although pull requests will be much quicker and easier on all parties.
|
||||
<a href="https://github.com/EQEmu/server/graphs/contributors">
|
||||
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
|
||||
</a>
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
image: Visual Studio 2017
|
||||
configuration: RelWithDebInfo
|
||||
clone_folder: c:\projects\eqemu
|
||||
init:
|
||||
- ps: git config --global core.autocrlf input
|
||||
cache: c:\tools\vcpkg\installed\
|
||||
before_build:
|
||||
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||
build:
|
||||
project: C:\projects\eqemu\build\EQEmu.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- cmd: >-
|
||||
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb
|
||||
|
||||
appveyor PushArtifact build_x64-bots.zip
|
||||
@@ -0,0 +1,21 @@
|
||||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
image: Visual Studio 2017
|
||||
configuration: RelWithDebInfo
|
||||
clone_folder: c:\projects\eqemu
|
||||
init:
|
||||
- ps: git config --global core.autocrlf input
|
||||
cache: c:\tools\vcpkg\installed\
|
||||
before_build:
|
||||
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=OFF -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||
build:
|
||||
project: C:\projects\eqemu\build\EQEmu.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- cmd: >-
|
||||
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb
|
||||
|
||||
appveyor PushArtifact build_x64-no-bots.zip
|
||||
+551
-562
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
|
||||
|
||||
add_subdirectory(import)
|
||||
add_subdirectory(export)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
|
||||
|
||||
SET(export_sources
|
||||
main.cpp
|
||||
|
||||
+97
-151
@@ -25,74 +25,40 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
->SetLogPath(path.GetLogPath())
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
/* Register Log System and Settings */
|
||||
database.LoadLogSettings(LogSys.log_settings);
|
||||
LogSys.StartFileLogs();
|
||||
|
||||
std::string arg_1;
|
||||
|
||||
@@ -101,15 +67,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (arg_1 == "spells") {
|
||||
ExportSpells(&content_db);
|
||||
ExportSpells(&database);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "skills") {
|
||||
ExportSkillCaps(&content_db);
|
||||
ExportSkillCaps(&database);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "basedata") {
|
||||
ExportBaseData(&content_db);
|
||||
ExportBaseData(&database);
|
||||
return 0;
|
||||
}
|
||||
if (arg_1 == "dbstring") {
|
||||
@@ -117,9 +83,9 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExportSpells(&content_db);
|
||||
ExportSkillCaps(&content_db);
|
||||
ExportBaseData(&content_db);
|
||||
ExportSpells(&database);
|
||||
ExportSkillCaps(&database);
|
||||
ExportBaseData(&database);
|
||||
ExportDBStrings(&database);
|
||||
|
||||
LogSys.CloseFileLogs();
|
||||
@@ -127,107 +93,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] && Strings::ToInt(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();
|
||||
return Strings::ToInt(row[0]);
|
||||
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 +193,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 +224,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 3.10)
|
||||
|
||||
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);
|
||||
}
|
||||
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,17 +198,17 @@ 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;
|
||||
}
|
||||
|
||||
int class_id, skill_id, level, cap;
|
||||
class_id = Strings::ToInt(split[0].c_str());
|
||||
skill_id = Strings::ToInt(split[1].c_str());
|
||||
level = Strings::ToInt(split[2].c_str());
|
||||
cap = Strings::ToInt(split[3].c_str());
|
||||
class_id = atoi(split[0].c_str());
|
||||
skill_id = atoi(split[1].c_str());
|
||||
level = atoi(split[2].c_str());
|
||||
cap = atoi(split[3].c_str());
|
||||
|
||||
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
||||
class_id, skill_id, level, cap);
|
||||
@@ -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;
|
||||
@@ -280,16 +243,16 @@ void ImportBaseData(SharedDatabase *db) {
|
||||
int level, class_id;
|
||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
||||
|
||||
level = Strings::ToInt(split[0].c_str());
|
||||
class_id = Strings::ToInt(split[1].c_str());
|
||||
hp = Strings::ToFloat(split[2].c_str());
|
||||
mana = Strings::ToFloat(split[3].c_str());
|
||||
end = Strings::ToFloat(split[4].c_str());
|
||||
unk1 = Strings::ToFloat(split[5].c_str());
|
||||
unk2 = Strings::ToFloat(split[6].c_str());
|
||||
hp_fac = Strings::ToFloat(split[7].c_str());
|
||||
mana_fac = Strings::ToFloat(split[8].c_str());
|
||||
end_fac = Strings::ToFloat(split[9].c_str());
|
||||
level = atoi(split[0].c_str());
|
||||
class_id = atoi(split[1].c_str());
|
||||
hp = atof(split[2].c_str());
|
||||
mana = atof(split[3].c_str());
|
||||
end = atof(split[4].c_str());
|
||||
unk1 = atof(split[5].c_str());
|
||||
unk2 = atof(split[6].c_str());
|
||||
hp_fac = atof(split[7].c_str());
|
||||
mana_fac = atof(split[8].c_str());
|
||||
end_fac = atof(split[9].c_str());
|
||||
|
||||
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
||||
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
|
||||
@@ -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 = Strings::ToInt(split[0].c_str());
|
||||
type = Strings::ToInt(split[1].c_str());
|
||||
|
||||
|
||||
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()
|
||||
@@ -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)
|
||||
|
||||
+377
-774
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@
|
||||
* 2005-08-05 v5 - Removed most Lint (http://www.gimpel.com/) errors... thanks to Okko Willeboordse!
|
||||
*
|
||||
**********************************************************************/
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* 2013-01-26 - Modified by KimLS(KLS) for EQEmu's purposes
|
||||
*
|
||||
**********************************************************************/
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _WIN32
|
||||
// #pragma once is supported starting with _MCS_VER 1000,
|
||||
// so we need not to check the version (because we only support _MSC_VER >= 1100)!
|
||||
#pragma once
|
||||
|
||||
@@ -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
|
||||
@@ -23,18 +23,18 @@
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _WIN32
|
||||
#include <time.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
+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;
|
||||
|
||||
+4
-110
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/classes.h"
|
||||
#include "data_verification.h"
|
||||
|
||||
const char *GetClassIDName(uint8 class_id, uint8 level)
|
||||
{
|
||||
@@ -379,30 +378,16 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
|
||||
return "Berserker Guildmaster";
|
||||
case MERCHANT:
|
||||
return "Merchant";
|
||||
case DISCORD_MERCHANT:
|
||||
return "Discord Merchant";
|
||||
case ADVENTURE_RECRUITER:
|
||||
case ADVENTURERECRUITER:
|
||||
return "Adventure Recruiter";
|
||||
case ADVENTURE_MERCHANT:
|
||||
case ADVENTUREMERCHANT:
|
||||
return "Adventure Merchant";
|
||||
case LDON_TREASURE:
|
||||
return "LDoN Treasure";
|
||||
case CORPSE_CLASS:
|
||||
return "Corpse Class";
|
||||
case TRIBUTE_MASTER:
|
||||
return "Tribute Master";
|
||||
case GUILD_TRIBUTE_MASTER:
|
||||
return "Guild Tribute Master";
|
||||
case GUILD_BANKER:
|
||||
return "Guild Banker";
|
||||
case NORRATHS_KEEPERS_MERCHANT:
|
||||
return "Radiant Crystal Merchant";
|
||||
case DARK_REIGN_MERCHANT:
|
||||
return "Ebon Crystal Merchant";
|
||||
case FELLOWSHIP_MASTER:
|
||||
return "Fellowship Master";
|
||||
case ALT_CURRENCY_MERCHANT:
|
||||
return "Alternate Currency Merchant";
|
||||
case MERCENARY_MASTER:
|
||||
return "Mercenary Liaison";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -588,20 +573,6 @@ bool IsNonSpellFighterClass(uint8 class_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHybridClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case PALADIN:
|
||||
case RANGER:
|
||||
case SHADOWKNIGHT:
|
||||
case BARD:
|
||||
case BEASTLORD:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
@@ -631,20 +602,6 @@ bool IsINTCasterClass(uint8 class_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHeroicINTCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case NECROMANCER:
|
||||
case WIZARD:
|
||||
case MAGICIAN:
|
||||
case ENCHANTER:
|
||||
case SHADOWKNIGHT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsWISCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
@@ -657,21 +614,6 @@ bool IsWISCasterClass(uint8 class_id)
|
||||
}
|
||||
}
|
||||
|
||||
bool IsHeroicWISCasterClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
case CLERIC:
|
||||
case DRUID:
|
||||
case SHAMAN:
|
||||
case PALADIN:
|
||||
case BEASTLORD:
|
||||
case RANGER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsPlateClass(uint8 class_id)
|
||||
{
|
||||
switch (class_id) {
|
||||
@@ -751,51 +693,3 @@ uint8 ClassArmorType(uint8 class_id)
|
||||
return ARMOR_TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string GetPlayerClassAbbreviation(uint8 class_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) {
|
||||
return std::string("UNK");
|
||||
}
|
||||
|
||||
switch (class_id) {
|
||||
case WARRIOR:
|
||||
return "WAR";
|
||||
case CLERIC:
|
||||
return "CLR";
|
||||
case PALADIN:
|
||||
return "PAL";
|
||||
case RANGER:
|
||||
return "RNG";
|
||||
case SHADOWKNIGHT:
|
||||
return "SHD";
|
||||
case DRUID:
|
||||
return "DRU";
|
||||
case MONK:
|
||||
return "MNK";
|
||||
case BARD:
|
||||
return "BRD";
|
||||
case ROGUE:
|
||||
return "ROG";
|
||||
case SHAMAN:
|
||||
return "SHM";
|
||||
case NECROMANCER:
|
||||
return "NEC";
|
||||
case WIZARD:
|
||||
return "WIZ";
|
||||
case MAGICIAN:
|
||||
return "MAG";
|
||||
case ENCHANTER:
|
||||
return "ENC";
|
||||
case BEASTLORD:
|
||||
return "BST";
|
||||
case BERSERKER:
|
||||
return "BER";
|
||||
}
|
||||
|
||||
return std::string("UNK");
|
||||
}
|
||||
|
||||
bool IsPlayerClass(uint8 class_id) {
|
||||
return EQ::ValueWithin(class_id, WARRIOR, BERSERKER);
|
||||
}
|
||||
|
||||
+6
-13
@@ -19,9 +19,7 @@
|
||||
#define CLASSES_CH
|
||||
|
||||
#include "../common/types.h"
|
||||
#include <string>
|
||||
|
||||
#define NO_CLASS 0
|
||||
#define WARRIOR 1
|
||||
#define CLERIC 2
|
||||
#define PALADIN 3
|
||||
@@ -57,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
|
||||
@@ -128,9 +126,6 @@
|
||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
||||
|
||||
bool IsPlayerClass(uint8 class_id);
|
||||
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
||||
|
||||
uint32 GetPlayerClassValue(uint8 class_id);
|
||||
uint32 GetPlayerClassBit(uint8 class_id);
|
||||
|
||||
@@ -140,12 +135,10 @@ 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);
|
||||
bool IsHeroicINTCasterClass(uint8 class_id);
|
||||
bool IsHeroicWISCasterClass(uint8 class_id);
|
||||
|
||||
bool IsPlateClass(uint8 class_id);
|
||||
bool IsChainClass(uint8 class_id);
|
||||
bool IsLeatherClass(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,192 +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"}]) || (argc == 3 && 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;
|
||||
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.clear();
|
||||
|
||||
(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);
|
||||
}
|
||||
|
||||
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 (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_
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
uint32 EstimateDeflateBuffer(uint32 len) {
|
||||
z_stream zstream;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
uint32 EstimateDeflateBuffer(uint32 len);
|
||||
uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "condition.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _WIN32
|
||||
|
||||
Condition::Condition()
|
||||
{
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "global_define.h"
|
||||
#include "mutex.h"
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
class Condition {
|
||||
private:
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
enum {
|
||||
SignalEvent = 0,
|
||||
BroadcastEvent,
|
||||
|
||||
@@ -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(const 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(const 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
|
||||
+7
-198
@@ -1,97 +1,8 @@
|
||||
#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);
|
||||
|
||||
// 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)
|
||||
#if defined(_WIN32) && defined(CRASH_LOGGING)
|
||||
#include "StackWalker.h"
|
||||
|
||||
class EQEmuStackWalker : public StackWalker
|
||||
@@ -101,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>& GetLines() { return _lines; }
|
||||
private:
|
||||
std::vector<std::string> _lines;
|
||||
};
|
||||
|
||||
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
@@ -198,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;
|
||||
@@ -221,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>(Strings::ToUnsignedInt(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);
|
||||
}
|
||||
}
|
||||
+32
-36
@@ -1,57 +1,53 @@
|
||||
/**
|
||||
* 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
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#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*/
|
||||
|
||||
|
||||
+916
-1127
File diff suppressed because it is too large
Load Diff
+83
-85
@@ -34,15 +34,35 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//atoi is not uint32 or uint32 safe!!!!
|
||||
#define atoul(str) strtoul(str, nullptr, 10)
|
||||
|
||||
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;
|
||||
@@ -62,150 +82,119 @@ struct VarCache_Struct {
|
||||
};
|
||||
|
||||
class PTimerList;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if _MSC_VER > 1700 // greater than 2012 (2013+)
|
||||
# define _ISNAN_(a) std::isnan(a)
|
||||
#else
|
||||
# include <float.h>
|
||||
# define _ISNAN_(a) _isnan(a)
|
||||
#endif
|
||||
#else
|
||||
# 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);
|
||||
@@ -235,16 +224,24 @@ public:
|
||||
/* Database Variables */
|
||||
|
||||
bool GetVariable(std::string varname, std::string &varvalue);
|
||||
bool SetVariable(const std::string& varname, const std::string &varvalue);
|
||||
bool SetVariable(const std::string varname, const std::string &varvalue);
|
||||
bool LoadVariables();
|
||||
|
||||
/* 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);
|
||||
@@ -262,10 +259,11 @@ public:
|
||||
int CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
void SourceSqlFromUrl(std::string url);
|
||||
/* EQEmuLogSys */
|
||||
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
|
||||
|
||||
private:
|
||||
std::map<uint32,std::string> zonename_array;
|
||||
|
||||
Mutex Mvarcache;
|
||||
VarCache_Struct varcache;
|
||||
|
||||
@@ -1,623 +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 "../termcolor/rang.hpp"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <thread>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
const std::string CREDENTIALS_FILE = "login.my.cnf";
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
||||
{
|
||||
auto config = EQEmuConfig::get();
|
||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||
return fmt::format(
|
||||
"mysqldump --defaults-extra-file={} {}",
|
||||
CREDENTIALS_FILE,
|
||||
config->ContentDbName
|
||||
);
|
||||
};
|
||||
|
||||
return fmt::format(
|
||||
"mysqldump --defaults-extra-file={} {}",
|
||||
CREDENTIALS_FILE,
|
||||
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::DatabaseDump()
|
||||
{
|
||||
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 (IsDumpStaticInstanceData()) {
|
||||
tables_to_dump += "instance_list";
|
||||
options += " --no-create-info --where=\"instance_list.is_global > 0 and instance_list.never_expires > 0\"";
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
const auto execute_command = fmt::format(
|
||||
"{} {} {} {}",
|
||||
GetBaseMySQLDumpCommand(),
|
||||
options,
|
||||
tables_to_dump,
|
||||
pipe_file
|
||||
);
|
||||
|
||||
BuildCredentialsFile();
|
||||
std::string execution_result = Process::execute(execute_command);
|
||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||
std::cout << execution_result;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsDumpOutputToConsole()) {
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
}
|
||||
|
||||
if (!pipe_file.empty()) {
|
||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||
auto r = File::GetContents(file);
|
||||
if (!r.error.empty()) {
|
||||
LogError("{}", r.error);
|
||||
}
|
||||
|
||||
for (auto &line: Strings::Split(r.contents, "\n")) {
|
||||
if (Strings::Contains(line, "mysqldump:")) {
|
||||
LogError("{}", line);
|
||||
LogError("Database dump failed. Correct the error before continuing or trying again");
|
||||
LogError("This is to prevent data loss on behalf of the server operator");
|
||||
RemoveSqlBackup();
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
RemoveSqlBackup();
|
||||
}
|
||||
else if (Is7ZipAvailable()) {
|
||||
Process::execute(
|
||||
fmt::format(
|
||||
"7z a -t7z {}.zip {}.sql",
|
||||
GetDumpFileNameWithPath(),
|
||||
GetDumpFileNameWithPath()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
||||
RemoveSqlBackup();
|
||||
}
|
||||
else {
|
||||
LogInfo("Compression requested, but no available compression binary was found");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogWarning("Compression requested but binary not found... Skipping...");
|
||||
}
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::RemoveSqlBackup()
|
||||
{
|
||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||
if (File::Exists(file)) {
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
}
|
||||
|
||||
void DatabaseDumpService::BuildCredentialsFile()
|
||||
{
|
||||
auto config = EQEmuConfig::get();
|
||||
std::ofstream out(CREDENTIALS_FILE);
|
||||
if (out.is_open()) {
|
||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||
out << "[mysqldump]" << std::endl;
|
||||
out << "user=" << config->ContentDbUsername << std::endl;
|
||||
out << "password=" << config->ContentDbPassword << std::endl;
|
||||
out << "host=" << config->ContentDbHost << std::endl;
|
||||
out << "port=" << config->ContentDbPort << std::endl;
|
||||
out << "default-character-set=utf8" << std::endl;
|
||||
}
|
||||
else {
|
||||
out << "[mysqldump]" << std::endl;
|
||||
out << "user=" << config->DatabaseUsername << std::endl;
|
||||
out << "password=" << config->DatabasePassword << std::endl;
|
||||
out << "host=" << config->DatabaseHost << std::endl;
|
||||
out << "port=" << config->DatabasePort << std::endl;
|
||||
out << "default-character-set=utf8" << std::endl;
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
else {
|
||||
LogError("Failed to open credentials file for writing");
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseDumpService::RemoveCredentialsFile()
|
||||
{
|
||||
if (File::Exists(CREDENTIALS_FILE)) {
|
||||
std::filesystem::remove(CREDENTIALS_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpStaticInstanceData()
|
||||
{
|
||||
return dump_static_instance_data;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpStaticInstanceData(bool b)
|
||||
{
|
||||
dump_static_instance_data = b;
|
||||
}
|
||||
@@ -1,106 +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 DatabaseDump();
|
||||
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);
|
||||
|
||||
void SetDumpStaticInstanceData(bool b);
|
||||
bool IsDumpStaticInstanceData();
|
||||
|
||||
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;
|
||||
bool dump_static_instance_data = 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();
|
||||
void RemoveSqlBackup();
|
||||
void BuildCredentialsFile();
|
||||
void RemoveCredentialsFile();
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_DATABASE_DUMP_SERVICE_H
|
||||
@@ -1,300 +0,0 @@
|
||||
#include <filesystem>
|
||||
#include "database_update.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../http/httplib.h"
|
||||
|
||||
#include "database_update_manifest.cpp"
|
||||
#include "database_update_manifest_bots.cpp"
|
||||
#include "database_dump_service.h"
|
||||
|
||||
constexpr int BREAK_LENGTH = 70;
|
||||
|
||||
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
||||
{
|
||||
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
LogError("Failed to read from [db_version] table!");
|
||||
return DatabaseVersion{};
|
||||
}
|
||||
|
||||
auto r = results.begin();
|
||||
|
||||
return DatabaseVersion{
|
||||
.server_database_version = Strings::ToInt(r[0]),
|
||||
.bots_database_version = Strings::ToInt(r[1]),
|
||||
};
|
||||
}
|
||||
|
||||
DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
|
||||
{
|
||||
return DatabaseVersion{
|
||||
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
|
||||
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
|
||||
};
|
||||
}
|
||||
|
||||
// the amount of versions we look-back to ensure we have all migrations
|
||||
// we may not want to force these, but just warn about the look-backs
|
||||
constexpr int LOOK_BACK_AMOUNT = 10;
|
||||
|
||||
// this check will take action
|
||||
void DatabaseUpdate::CheckDbUpdates()
|
||||
{
|
||||
InjectBotsVersionColumn();
|
||||
auto v = GetDatabaseVersions();
|
||||
auto b = GetBinaryDatabaseVersions();
|
||||
if (CheckVersionsUpToDate(v, b)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
|
||||
LogInfo(
|
||||
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||
b.server_database_version,
|
||||
v.server_database_version
|
||||
);
|
||||
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
|
||||
}
|
||||
|
||||
if (b.bots_database_version > 0) {
|
||||
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
|
||||
LogInfo(
|
||||
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||
b.bots_database_version,
|
||||
v.bots_database_version
|
||||
);
|
||||
m_database->QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `db_version` SET `bots_version` = {}",
|
||||
b.bots_database_version
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string DatabaseUpdate::GetQueryResult(std::string query)
|
||||
{
|
||||
auto results = m_database->QueryDatabase(query);
|
||||
|
||||
std::vector<std::string> result_lines = {};
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::vector<std::string> cols;
|
||||
|
||||
int field_count = results.ColumnCount();
|
||||
cols.reserve(field_count);
|
||||
for (int i = 0; i < field_count; ++i) {
|
||||
if (row[i] != nullptr) {
|
||||
cols.emplace_back(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
result_lines.emplace_back(Strings::Join(cols, " "));
|
||||
}
|
||||
|
||||
return Strings::Join(result_lines, "\n");
|
||||
}
|
||||
|
||||
bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_result)
|
||||
{
|
||||
std::string r = Strings::Trim(query_result);
|
||||
if (e.condition == "contains") {
|
||||
return Strings::Contains(r, e.match);
|
||||
}
|
||||
else if (e.condition == "match") {
|
||||
return r == e.match;
|
||||
}
|
||||
else if (e.condition == "missing") {
|
||||
return !Strings::Contains(r, e.match);
|
||||
}
|
||||
else if (e.condition == "empty") {
|
||||
return r.empty();
|
||||
}
|
||||
else if (e.condition == "not_empty") {
|
||||
return !r.empty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// return true if we ran updates
|
||||
bool DatabaseUpdate::UpdateManifest(
|
||||
std::vector<ManifestEntry> entries,
|
||||
int version_low,
|
||||
int version_high
|
||||
)
|
||||
{
|
||||
std::vector<int> missing_migrations = {};
|
||||
if (version_low != version_high) {
|
||||
|
||||
LogSys.DisableMySQLErrorLogs();
|
||||
for (int version = version_low + 1; version <= version_high; ++version) {
|
||||
for (auto &e: entries) {
|
||||
if (e.version == version) {
|
||||
bool has_migration = true;
|
||||
std::string r = GetQueryResult(e.check);
|
||||
if (ShouldRunMigration(e, r)) {
|
||||
has_migration = false;
|
||||
missing_migrations.emplace_back(e.version);
|
||||
}
|
||||
|
||||
std::string prefix = fmt::format(
|
||||
"[{}]",
|
||||
has_migration ? "ok" : "missing"
|
||||
);
|
||||
|
||||
LogInfo(
|
||||
"[{}] {:>10} | [{}]",
|
||||
e.version,
|
||||
prefix,
|
||||
e.description
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
LogSys.EnableMySQLErrorLogs();
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
if (!missing_migrations.empty()) {
|
||||
LogInfo("Automatically backing up database before applying updates");
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
auto s = DatabaseDumpService();
|
||||
s.SetDumpAllTables(true);
|
||||
s.SetDumpWithCompression(true);
|
||||
s.DatabaseDump();
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
}
|
||||
|
||||
if (!missing_migrations.empty()) {
|
||||
LogInfo("Running database migrations. Please wait...");
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
}
|
||||
|
||||
for (auto &m: missing_migrations) {
|
||||
for (auto &e: entries) {
|
||||
if (e.version == m) {
|
||||
bool errored_migration = false;
|
||||
|
||||
auto r = m_database->QueryDatabaseMulti(e.sql);
|
||||
|
||||
// ignore empty query result "errors"
|
||||
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
||||
LogError("(#{}) [{}]", r.ErrorNumber(), r.ErrorMessage());
|
||||
errored_migration = true;
|
||||
|
||||
LogInfo("Required database update failed. This could be a problem");
|
||||
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
||||
|
||||
// user input
|
||||
std::string input;
|
||||
bool gave_input = false;
|
||||
time_t start_time = time(nullptr);
|
||||
time_t wait_time_seconds = 60;
|
||||
|
||||
// spawn a concurrent thread that waits for input from std::cin
|
||||
std::thread t1(
|
||||
[&]() {
|
||||
std::cin >> input;
|
||||
gave_input = true;
|
||||
}
|
||||
);
|
||||
t1.detach();
|
||||
|
||||
// check the inputReceived flag once every 50ms for 10 seconds
|
||||
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
}
|
||||
|
||||
// prompt for user skip
|
||||
if (Strings::Trim(input) == "y") {
|
||||
errored_migration = false;
|
||||
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo(
|
||||
"[{}] [{}] [{}]",
|
||||
e.version,
|
||||
e.description,
|
||||
(errored_migration ? "error" : "ok")
|
||||
);
|
||||
|
||||
if (errored_migration) {
|
||||
LogError("Fatal | Database migration [{}] failed to run", e.description);
|
||||
LogError("Fatal | Shutting down");
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
|
||||
{
|
||||
m_database = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||
{
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
LogInfo(
|
||||
"{:>8} | database [{}] binary [{}] {}",
|
||||
"Server",
|
||||
v.server_database_version,
|
||||
b.server_database_version,
|
||||
(v.server_database_version == b.server_database_version) ? "up to date" : "checking updates"
|
||||
);
|
||||
|
||||
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
|
||||
LogInfo(
|
||||
"{:>8} | database [{}] binary [{}] {}",
|
||||
"Bots",
|
||||
v.bots_database_version,
|
||||
b.bots_database_version,
|
||||
(v.bots_database_version == b.bots_database_version) ? "up to date" : "checking updates"
|
||||
);
|
||||
}
|
||||
|
||||
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
|
||||
|
||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||
|
||||
// server database version is required
|
||||
bool server_up_to_date = v.server_database_version == b.server_database_version;
|
||||
// bots database version is optional, if not enabled then it is always up-to-date
|
||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
|
||||
|
||||
return server_up_to_date && bots_up_to_date;
|
||||
}
|
||||
|
||||
// checks to see if there are pending updates
|
||||
// used by zone to prevent launch or boot loop until updates are applied
|
||||
bool DatabaseUpdate::HasPendingUpdates()
|
||||
{
|
||||
auto v = GetDatabaseVersions();
|
||||
auto b = GetBinaryDatabaseVersions();
|
||||
|
||||
return !CheckVersionsUpToDate(v, b);
|
||||
}
|
||||
|
||||
void DatabaseUpdate::InjectBotsVersionColumn()
|
||||
{
|
||||
auto r = m_database->QueryDatabase("show columns from db_version where Field like '%bots_version%'");
|
||||
if (r.RowCount() == 0) {
|
||||
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
#ifndef EQEMU_DATABASE_UPDATE_H
|
||||
#define EQEMU_DATABASE_UPDATE_H
|
||||
|
||||
#include "../database.h"
|
||||
|
||||
struct ManifestEntry {
|
||||
int version{}; // database version of the migration
|
||||
std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
||||
std::string check{}; // query that checks against the condition
|
||||
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||
};
|
||||
|
||||
struct DatabaseVersion {
|
||||
int server_database_version;
|
||||
int bots_database_version;
|
||||
};
|
||||
|
||||
class DatabaseUpdate {
|
||||
public:
|
||||
DatabaseVersion GetDatabaseVersions();
|
||||
DatabaseVersion GetBinaryDatabaseVersions();
|
||||
void CheckDbUpdates();
|
||||
std::string GetQueryResult(std::string query);
|
||||
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
|
||||
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
|
||||
|
||||
DatabaseUpdate *SetDatabase(Database *db);
|
||||
bool HasPendingUpdates();
|
||||
private:
|
||||
Database *m_database;
|
||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
||||
void InjectBotsVersionColumn();
|
||||
};
|
||||
|
||||
#endif //EQEMU_DATABASE_UPDATE_H
|
||||
File diff suppressed because one or more lines are too long
@@ -1,107 +0,0 @@
|
||||
#include "database_update.h"
|
||||
|
||||
std::vector<ManifestEntry> bot_manifest_entries = {
|
||||
ManifestEntry{
|
||||
.version = 9035,
|
||||
.description = "2022_12_04_bot_archery.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `archery_setting` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `enforce_spell_settings`;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9036,
|
||||
.description = "2023_01_19_drop_bot_views.sql",
|
||||
.check = "SHOW TABLES LIKE 'vw_groups'",
|
||||
.condition = "not_empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
DROP VIEW vw_bot_groups;
|
||||
DROP VIEW vw_bot_character_mobs;
|
||||
DROP VIEW vw_groups;
|
||||
DROP VIEW vw_guild_members;
|
||||
DROP TABLE bot_guild_members;
|
||||
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9037,
|
||||
.description = "2023_01_22_add_name_index.sql",
|
||||
.check = "show index from bot_data WHERE key_name = 'name`",
|
||||
.condition = "",
|
||||
.match = "empty",
|
||||
.sql = R"(
|
||||
create index `name` on bot_data(`name`);
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9038,
|
||||
.description = "2023_02_16_add_caster_range.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'",
|
||||
.condition = "",
|
||||
.match = "empty",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9039,
|
||||
.description = "2023_03_31_remove_bot_groups.sql",
|
||||
.check = "SHOW TABLES LIKE 'bot_groups'",
|
||||
.condition = "",
|
||||
.match = "not_empty",
|
||||
.sql = R"(
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
DROP TABLE IF EXISTS `bot_groups`;
|
||||
DROP TABLE IF EXISTS `bot_group_members`;
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9040,
|
||||
.description = "2023_11_16_bot_starting_items.sql",
|
||||
.check = "SHOW TABLES LIKE 'bot_starting_items'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `bot_starting_items` (
|
||||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`races` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`classes` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`slot_id` mediumint(9) NOT NULL DEFAULT -1,
|
||||
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
|
||||
`content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
// .version = 9228,
|
||||
// .description = "some_new_migration.sql",
|
||||
// .check = "SHOW COLUMNS FROM `table_name` LIKE 'column_name'",
|
||||
// .condition = "empty",
|
||||
// .match = "",
|
||||
// .sql = R"(
|
||||
//
|
||||
//)"
|
||||
};
|
||||
|
||||
// see struct definitions for what each field does
|
||||
// struct ManifestEntry {
|
||||
// int version{}; // database version of the migration
|
||||
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
||||
// std::string check{}; // query that checks against the condition
|
||||
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||
// };
|
||||
+1796
-14
File diff suppressed because it is too large
Load Diff
+365
-368
@@ -18,19 +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 "repositories/spawn2_disabled_repository.h"
|
||||
|
||||
|
||||
#include "database.h"
|
||||
|
||||
@@ -38,254 +27,233 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <iostream>
|
||||
|
||||
// Disgrace: for windows compile
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#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)
|
||||
/**
|
||||
* @param instance_id
|
||||
* @param char_id
|
||||
* @return
|
||||
*/
|
||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id)
|
||||
{
|
||||
auto e = InstanceListPlayerRepository::NewEntity();
|
||||
std::string query = StringFormat(
|
||||
"REPLACE INTO `instance_list_player` (id, charid) "
|
||||
"VALUES "
|
||||
"(%lu, %lu)",
|
||||
(unsigned long) instance_id,
|
||||
(unsigned long) char_id
|
||||
);
|
||||
|
||||
e.id = instance_id;
|
||||
e.charid = character_id;
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
return InstanceListPlayerRepository::ReplaceOne(*this, e);
|
||||
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_instance_id = 32000;
|
||||
|
||||
// sanity check reserved
|
||||
if (max_reserved_instance_id >= max_instance_id) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// recycle instances
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
|
||||
//query to get first unused id above reserved
|
||||
auto query = fmt::format(
|
||||
SQL(
|
||||
SELECT id
|
||||
FROM instance_list
|
||||
WHERE id = {};
|
||||
),
|
||||
max_reserved_instance_id + 1
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// first id is available
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// now look for next available above reserved
|
||||
query = fmt::format(
|
||||
SQL(
|
||||
SELECT MIN(i.id + 1) AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
||||
WHERE i.id >= {}
|
||||
AND i2.id IS NULL;
|
||||
),
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// did not retrieve any rows - bail out
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
// check that id is within limits
|
||||
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// get max unused id above reserved
|
||||
auto query = fmt::format(
|
||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||
max_reserved_instance_id,
|
||||
max_reserved_instance_id
|
||||
);
|
||||
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);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
if (!results.Success())
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// did not retrieve any rows - bail out
|
||||
if (results.RowCount() == 0) {
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
// no instances currently used
|
||||
if (!row[0]) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
if (atoi(row[0]) <= max)
|
||||
{
|
||||
instance_id = atoi(row[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// check that id is within limits
|
||||
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
return true;
|
||||
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
if (results.RowCount() == 0)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count++;
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
if (count < atoi(row[0]))
|
||||
{
|
||||
instance_id = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (count > max)
|
||||
{
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -295,102 +263,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>(Strings::ToUnsignedInt(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>(Strings::ToUnsignedInt(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;
|
||||
}
|
||||
@@ -399,174 +394,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)
|
||||
{
|
||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
||||
|
||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
std::string query = StringFormat("DELETE FROM instance_list WHERE id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
query = StringFormat("DELETE FROM respawn_times WHERE instance_id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
|
||||
query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
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));
|
||||
Spawn2DisabledRepository::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,440 +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_stats_record", "character_id"},
|
||||
{"character_task_timers", "character_id"},
|
||||
{"character_tasks", "charid"},
|
||||
{"character_tribute", "character_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_stats_record",
|
||||
"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",
|
||||
"chatchannel_reserved_names",
|
||||
"command_settings",
|
||||
"command_subsettings",
|
||||
"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",
|
||||
"spawn2_disabled",
|
||||
"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_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
|
||||
+92
-314
@@ -1,10 +1,9 @@
|
||||
#ifdef _WINDOWS
|
||||
#ifdef _WIN32
|
||||
#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"
|
||||
|
||||
@@ -13,51 +12,36 @@
|
||||
#include <iostream>
|
||||
#include <mysqld_error.h>
|
||||
#include <string.h>
|
||||
#include "strings.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#define snprintf _snprintf
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#include <process.h>
|
||||
#ifdef _WIN32
|
||||
#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()
|
||||
{
|
||||
mysql = mysql_init(nullptr);
|
||||
mysqlOwner = true;
|
||||
pHost = nullptr;
|
||||
pUser = nullptr;
|
||||
pPassword = nullptr;
|
||||
pDatabase = nullptr;
|
||||
pCompress = false;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
m_mutex = new Mutex;
|
||||
DBcore::DBcore() {
|
||||
mysql_init(&mysql);
|
||||
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)
|
||||
*/
|
||||
if (mysqlOwner) {
|
||||
mysql_close(mysql);
|
||||
}
|
||||
|
||||
DBcore::~DBcore() {
|
||||
mysql_close(&mysql);
|
||||
safe_delete_array(pHost);
|
||||
safe_delete_array(pUser);
|
||||
safe_delete_array(pPassword);
|
||||
@@ -65,58 +49,48 @@ DBcore::~DBcore()
|
||||
}
|
||||
|
||||
// Sends the MySQL server a keepalive
|
||||
void DBcore::ping()
|
||||
{
|
||||
if (!m_mutex->trylock()) {
|
||||
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;
|
||||
}
|
||||
mysql_ping(mysql);
|
||||
m_mutex->unlock();
|
||||
mysql_ping(&mysql);
|
||||
MDatabase.unlock();
|
||||
}
|
||||
|
||||
MySQLRequestResult DBcore::QueryDatabase(const std::string& query, bool retryOnFailureOnce)
|
||||
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
||||
{
|
||||
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||
return r;
|
||||
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||
}
|
||||
|
||||
bool DBcore::DoesTableExist(const 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(m_mutex);
|
||||
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) {
|
||||
unsigned int errorNumber = mysql_errno(mysql);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -126,314 +100,118 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
|
||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||
|
||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
||||
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));
|
||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
|
||||
/**
|
||||
* Error logging
|
||||
*/
|
||||
if (mysql_errno(mysql) > 0 && query[0] != '\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);
|
||||
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
|
||||
)
|
||||
{
|
||||
LockMutex lock(m_mutex);
|
||||
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);
|
||||
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(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(m_mutex);
|
||||
if (GetStatus() == Connected) {
|
||||
LockMutex lock(&MDatabase);
|
||||
if (GetStatus() == Connected)
|
||||
return true;
|
||||
}
|
||||
if (GetStatus() == Error) {
|
||||
mysql_close(mysql);
|
||||
mysql_init(mysql); // Initialize structure again
|
||||
mysql_close(&mysql);
|
||||
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)) {
|
||||
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) {
|
||||
*errnum = mysql_errno(mysql);
|
||||
}
|
||||
if (errbuf) {
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
||||
}
|
||||
if (errnum)
|
||||
*errnum = mysql_errno(&mysql);
|
||||
if (errbuf)
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||
pStatus = Error;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &DBcore::GetOriginHost() const
|
||||
{
|
||||
return origin_host;
|
||||
}
|
||||
|
||||
void DBcore::SetOriginHost(const std::string &origin_host)
|
||||
{
|
||||
DBcore::origin_host = origin_host;
|
||||
}
|
||||
|
||||
std::string DBcore::Escape(const std::string& s)
|
||||
{
|
||||
const std::size_t s_len = s.length();
|
||||
std::vector<char> temp((s_len * 2) + 1, '\0');
|
||||
mysql_real_escape_string(mysql, temp.data(), s.c_str(), s_len);
|
||||
|
||||
return temp.data();
|
||||
}
|
||||
|
||||
void DBcore::SetMutex(Mutex *mutex)
|
||||
{
|
||||
safe_delete(m_mutex);
|
||||
|
||||
DBcore::m_mutex = mutex;
|
||||
}
|
||||
|
||||
// executes multiple statements in one query
|
||||
// do not use this in application logic
|
||||
// this was built and maintained for database migrations only
|
||||
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
||||
{
|
||||
SetMultiStatementsOn();
|
||||
|
||||
BenchTimer timer;
|
||||
timer.reset();
|
||||
|
||||
LockMutex lock(m_mutex);
|
||||
|
||||
// Reconnect if we are not connected before hand.
|
||||
if (pStatus != Connected) {
|
||||
Open();
|
||||
}
|
||||
auto r = MySQLRequestResult{};
|
||||
|
||||
int status = mysql_real_query(mysql, query.c_str(), query.length());
|
||||
|
||||
// process single result
|
||||
if (status != 0) {
|
||||
unsigned int error_number = mysql_errno(mysql);
|
||||
|
||||
if (error_number == CR_SERVER_GONE_ERROR) {
|
||||
pStatus = Error;
|
||||
}
|
||||
|
||||
// error logging
|
||||
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
|
||||
std::string error_raw = fmt::format("{}", mysql_error(mysql));
|
||||
std::string mysql_err = Strings::Trim(error_raw);
|
||||
std::string clean_query = Strings::Replace(query, "\n", "");
|
||||
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
|
||||
|
||||
MYSQL_RES *res = mysql_store_result(mysql);
|
||||
|
||||
uint32 row_count = 0;
|
||||
if (res) {
|
||||
row_count = (uint32) mysql_num_rows(res);
|
||||
}
|
||||
|
||||
r = MySQLRequestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(mysql),
|
||||
row_count,
|
||||
(uint32) mysql_field_count(mysql),
|
||||
(uint32) mysql_insert_id(mysql)
|
||||
);
|
||||
|
||||
std::string error_message = mysql_error(mysql);
|
||||
r.SetErrorMessage(error_message);
|
||||
r.SetErrorNumber(mysql_errno(mysql));
|
||||
|
||||
if (res) {
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
SetMultiStatementsOff();
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int index = 0;
|
||||
|
||||
// there could be a query with a semicolon in the actual data, this is best effort for
|
||||
// logging / display purposes
|
||||
// rare that we see this when this is only used in DDL statements
|
||||
auto pieces = Strings::Split(query, ";");
|
||||
|
||||
// process each statement result
|
||||
do {
|
||||
uint32 row_count = 0;
|
||||
MYSQL_RES *res = mysql_store_result(mysql);
|
||||
|
||||
r = MySQLRequestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(mysql),
|
||||
row_count,
|
||||
(uint32) mysql_field_count(mysql),
|
||||
(uint32) mysql_insert_id(mysql)
|
||||
);
|
||||
|
||||
if (pieces.size() >= index) {
|
||||
auto piece = pieces[index];
|
||||
LogMySQLQuery(
|
||||
"{} -- ({} row{} affected) ({}s)",
|
||||
piece,
|
||||
r.RowsAffected(),
|
||||
r.RowsAffected() == 1 ? "" : "s",
|
||||
std::to_string(timer.elapsed())
|
||||
);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
row_count = (uint32) mysql_num_rows(res);
|
||||
}
|
||||
|
||||
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
|
||||
if ((status = mysql_next_result(mysql)) > 0) {
|
||||
if (mysql_errno(mysql) > 0) {
|
||||
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
|
||||
// error logging
|
||||
std::string error_message = mysql_error(mysql);
|
||||
r.SetErrorMessage(error_message);
|
||||
r.SetErrorNumber(mysql_errno(mysql));
|
||||
|
||||
SetMultiStatementsOff();
|
||||
|
||||
// we handle errors elsewhere
|
||||
return r;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
mysql_free_result(res);
|
||||
}
|
||||
|
||||
index++;
|
||||
} while (status == 0);
|
||||
|
||||
SetMultiStatementsOff();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
+22
-66
@@ -1,9 +1,9 @@
|
||||
#ifndef DBCORE_H
|
||||
#define DBCORE_H
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "../common/mutex.h"
|
||||
@@ -12,86 +12,42 @@
|
||||
|
||||
#include <mysql.h>
|
||||
#include <string.h>
|
||||
#include <mutex>
|
||||
|
||||
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(const std::string& query, bool retryOnFailureOnce = true);
|
||||
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
||||
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();
|
||||
std::string Escape(const std::string& s);
|
||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||
void ping();
|
||||
|
||||
const std::string &GetOriginHost() const;
|
||||
void SetOriginHost(const std::string &origin_host);
|
||||
|
||||
bool DoesTableExist(const std::string& table_name);
|
||||
|
||||
void SetMySQL(const DBcore &o)
|
||||
{
|
||||
mysql = o.mysql;
|
||||
mysqlOwner = false;
|
||||
}
|
||||
void SetMutex(Mutex *mutex);
|
||||
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;
|
||||
bool mysqlOwner;
|
||||
Mutex *m_mutex;
|
||||
MYSQL mysql;
|
||||
Mutex MDatabase;
|
||||
eStatus pStatus;
|
||||
|
||||
std::mutex m_query_lock{};
|
||||
char* pHost;
|
||||
char* pUser;
|
||||
char* pPassword;
|
||||
char* pDatabase;
|
||||
bool pCompress;
|
||||
uint32 pPort;
|
||||
bool pSSL;
|
||||
|
||||
std::string origin_host;
|
||||
|
||||
char *pHost;
|
||||
char *pUser;
|
||||
char *pPassword;
|
||||
char *pDatabase;
|
||||
bool pCompress;
|
||||
uint32 pPort;
|
||||
bool pSSL;
|
||||
|
||||
// allows multiple queries to be executed within the same query
|
||||
// do not use this under normal operation
|
||||
// we use this during database migrations only currently
|
||||
void SetMultiStatementsOn()
|
||||
{
|
||||
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
|
||||
}
|
||||
|
||||
// disables multiple statements to be executed in one query
|
||||
void SetMultiStatementsOff()
|
||||
{
|
||||
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+122
-72
@@ -11,7 +11,7 @@
|
||||
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
|
||||
@@ -19,81 +19,131 @@
|
||||
|
||||
#include "deity.h"
|
||||
|
||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
||||
|
||||
EQEmu::deity::DeityTypeBit EQEmu::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
return bit_DeityBertoxxulous;
|
||||
case DeityBrellSirilis:
|
||||
return bit_DeityBrellSirilis;
|
||||
case DeityCazicThule:
|
||||
return bit_DeityCazicThule;
|
||||
case DeityErollisiMarr:
|
||||
return bit_DeityErollisiMarr;
|
||||
case DeityBristlebane:
|
||||
return bit_DeityBristlebane;
|
||||
case DeityInnoruuk:
|
||||
return bit_DeityInnoruuk;
|
||||
case DeityKarana:
|
||||
return bit_DeityKarana;
|
||||
case DeityMithanielMarr:
|
||||
return bit_DeityMithanielMarr;
|
||||
case DeityPrexus:
|
||||
return bit_DeityPrexus;
|
||||
case DeityQuellious:
|
||||
return bit_DeityQuellious;
|
||||
case DeityRallosZek:
|
||||
return bit_DeityRallosZek;
|
||||
case DeityRodcetNife:
|
||||
return bit_DeityRodcetNife;
|
||||
case DeitySolusekRo:
|
||||
return bit_DeitySolusekRo;
|
||||
case DeityTheTribunal:
|
||||
return bit_DeityTheTribunal;
|
||||
case DeityTunare:
|
||||
return bit_DeityTunare;
|
||||
case DeityVeeshan:
|
||||
return bit_DeityVeeshan;
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return bit_DeityAgnostic;
|
||||
default:
|
||||
return bit_DeityAll;
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
|
||||
{
|
||||
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
|
||||
{ DeityAgnostic, "Agnostic" },
|
||||
{ DeityAgnostic_LB, "Agnostic" },
|
||||
{ DeityBertoxxulous, "Bertoxxulous" },
|
||||
{ DeityBrellSirilis, "Brell Serilis" },
|
||||
{ DeityBristlebane, "Bristlebane" },
|
||||
{ DeityCazicThule, "Cazic-Thule" },
|
||||
{ DeityErollisiMarr, "Erollisi Marr" },
|
||||
{ DeityInnoruuk, "Innoruuk" },
|
||||
{ DeityKarana, "Karana" },
|
||||
{ DeityMithanielMarr, "Mithaniel Marr" },
|
||||
{ DeityPrexus, "Prexus" },
|
||||
{ DeityQuellious, "Quellious" },
|
||||
{ DeityRallosZek, "Rallos Zek" },
|
||||
{ DeityRodcetNife, "Rodcet Nife" },
|
||||
{ DeitySolusekRo, "Solusek Ro" },
|
||||
{ DeityTheTribunal, "The Tribunal" },
|
||||
{ DeityTunare, "Tunare" },
|
||||
{ DeityVeeshan, "Veeshan" }
|
||||
case DeityBertoxxulous:
|
||||
return bit_DeityBertoxxulous;
|
||||
case DeityBrellSirilis:
|
||||
return bit_DeityBrellSirilis;
|
||||
case DeityCazicThule:
|
||||
return bit_DeityCazicThule;
|
||||
case DeityErollisiMarr:
|
||||
return bit_DeityErollisiMarr;
|
||||
case DeityBristlebane:
|
||||
return bit_DeityBristlebane;
|
||||
case DeityInnoruuk:
|
||||
return bit_DeityInnoruuk;
|
||||
case DeityKarana:
|
||||
return bit_DeityKarana;
|
||||
case DeityMithanielMarr:
|
||||
return bit_DeityMithanielMarr;
|
||||
case DeityPrexus:
|
||||
return bit_DeityPrexus;
|
||||
case DeityQuellious:
|
||||
return bit_DeityQuellious;
|
||||
case DeityRallosZek:
|
||||
return bit_DeityRallosZek;
|
||||
case DeityRodcetNife:
|
||||
return bit_DeityRodcetNife;
|
||||
case DeitySolusekRo:
|
||||
return bit_DeitySolusekRo;
|
||||
case DeityTheTribunal:
|
||||
return bit_DeityTheTribunal;
|
||||
case DeityTunare:
|
||||
return bit_DeityTunare;
|
||||
case DeityVeeshan:
|
||||
return bit_DeityVeeshan;
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return bit_DeityAgnostic;
|
||||
default:
|
||||
return bit_DeityAll;
|
||||
};
|
||||
|
||||
return deity_map;
|
||||
}
|
||||
|
||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
||||
EQEmu::deity::DeityType EQEmu::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
||||
{
|
||||
|
||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
switch (deity_type_bit) {
|
||||
case bit_DeityAgnostic:
|
||||
return DeityAgnostic;
|
||||
case bit_DeityBertoxxulous:
|
||||
return DeityBertoxxulous;
|
||||
case bit_DeityBrellSirilis:
|
||||
return DeityBrellSirilis;
|
||||
case bit_DeityCazicThule:
|
||||
return DeityCazicThule;
|
||||
case bit_DeityErollisiMarr:
|
||||
return DeityErollisiMarr;
|
||||
case bit_DeityBristlebane:
|
||||
return DeityBristlebane;
|
||||
case bit_DeityInnoruuk:
|
||||
return DeityInnoruuk;
|
||||
case bit_DeityKarana:
|
||||
return DeityKarana;
|
||||
case bit_DeityMithanielMarr:
|
||||
return DeityMithanielMarr;
|
||||
case bit_DeityPrexus:
|
||||
return DeityPrexus;
|
||||
case bit_DeityQuellious:
|
||||
return DeityQuellious;
|
||||
case bit_DeityRallosZek:
|
||||
return DeityRallosZek;
|
||||
case bit_DeityRodcetNife:
|
||||
return DeityRodcetNife;
|
||||
case bit_DeitySolusekRo:
|
||||
return DeitySolusekRo;
|
||||
case bit_DeityTheTribunal:
|
||||
return DeityTheTribunal;
|
||||
case bit_DeityTunare:
|
||||
return DeityTunare;
|
||||
case bit_DeityVeeshan:
|
||||
return DeityVeeshan;
|
||||
default:
|
||||
return DeityUnknown;
|
||||
};
|
||||
}
|
||||
|
||||
const char* EQEmu::deity::DeityName(DeityType deity_type)
|
||||
{
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
return "Bertoxxulous";
|
||||
case DeityBrellSirilis:
|
||||
return "Brell Serilis";
|
||||
case DeityCazicThule:
|
||||
return "Cazic-Thule";
|
||||
case DeityErollisiMarr:
|
||||
return "Erollisi Marr";
|
||||
case DeityBristlebane:
|
||||
return "Bristlebane";
|
||||
case DeityInnoruuk:
|
||||
return "Innoruuk";
|
||||
case DeityKarana:
|
||||
return "Karana";
|
||||
case DeityMithanielMarr:
|
||||
return "Mithaniel Marr";
|
||||
case DeityPrexus:
|
||||
return "Prexus";
|
||||
case DeityQuellious:
|
||||
return "Quellious";
|
||||
case DeityRallosZek:
|
||||
return "Rallos Zek";
|
||||
case DeityRodcetNife:
|
||||
return "Rodcet Nife";
|
||||
case DeitySolusekRo:
|
||||
return "Solusek Ro";
|
||||
case DeityTheTribunal:
|
||||
return "The Tribunal";
|
||||
case DeityTunare:
|
||||
return "Tunare";
|
||||
case DeityVeeshan:
|
||||
return "Veeshan";
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return "Agnostic";
|
||||
default:
|
||||
return "Unknown";
|
||||
};
|
||||
}
|
||||
|
||||
+22
-23
@@ -21,11 +21,9 @@
|
||||
#define COMMON_DEITY_H
|
||||
|
||||
#include "types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
namespace deity {
|
||||
enum DeityType {
|
||||
@@ -51,29 +49,30 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum DeityTypeBit : uint32 {
|
||||
bit_DeityAgnostic = 0x00000001,
|
||||
bit_DeityBertoxxulous = 0x00000002,
|
||||
bit_DeityBrellSirilis = 0x00000004,
|
||||
bit_DeityCazicThule = 0x00000008,
|
||||
bit_DeityErollisiMarr = 0x00000010,
|
||||
bit_DeityBristlebane = 0x00000020,
|
||||
bit_DeityInnoruuk = 0x00000040,
|
||||
bit_DeityKarana = 0x00000080,
|
||||
bit_DeityNone = 0x00000000,
|
||||
bit_DeityAgnostic = 0x00000001,
|
||||
bit_DeityBertoxxulous = 0x00000002,
|
||||
bit_DeityBrellSirilis = 0x00000004,
|
||||
bit_DeityCazicThule = 0x00000008,
|
||||
bit_DeityErollisiMarr = 0x00000010,
|
||||
bit_DeityBristlebane = 0x00000020,
|
||||
bit_DeityInnoruuk = 0x00000040,
|
||||
bit_DeityKarana = 0x00000080,
|
||||
bit_DeityMithanielMarr = 0x00000100,
|
||||
bit_DeityPrexus = 0x00000200,
|
||||
bit_DeityQuellious = 0x00000400,
|
||||
bit_DeityRallosZek = 0x00000800,
|
||||
bit_DeityRodcetNife = 0x00001000,
|
||||
bit_DeitySolusekRo = 0x00002000,
|
||||
bit_DeityTheTribunal = 0x00004000,
|
||||
bit_DeityTunare = 0x00008000,
|
||||
bit_DeityVeeshan = 0x00010000,
|
||||
bit_DeityAll = UINT32_MAX
|
||||
bit_DeityPrexus = 0x00000200,
|
||||
bit_DeityQuellious = 0x00000400,
|
||||
bit_DeityRallosZek = 0x00000800,
|
||||
bit_DeityRodcetNife = 0x00001000,
|
||||
bit_DeitySolusekRo = 0x00002000,
|
||||
bit_DeityTheTribunal = 0x00004000,
|
||||
bit_DeityTunare = 0x00008000,
|
||||
bit_DeityVeeshan = 0x00010000,
|
||||
bit_DeityAll = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
||||
extern std::string GetDeityName(DeityType deity_type);
|
||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
||||
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
|
||||
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
|
||||
extern const char* DeityName(DeityType deity_type);
|
||||
|
||||
} /*deity*/
|
||||
|
||||
|
||||
@@ -1,165 +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
|
||||
|
||||
// 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 = Strings::ToInt(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
|
||||
|
||||
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 = Strings::ToInt(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.clear();
|
||||
}
|
||||
|
||||
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.clear();
|
||||
}
|
||||
}
|
||||
// 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
|
||||
+10
-438
@@ -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,14 +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) {
|
||||
|
||||
int16 EQEmu::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
static const int16 local_array[] = {
|
||||
POSSESSIONS_SIZE,
|
||||
BANK_SIZE,
|
||||
@@ -60,7 +55,7 @@ int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
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 +87,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,11 +115,11 @@ 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) {
|
||||
const char *EQEmu::constants::GetStanceName(StanceType stance_type) {
|
||||
switch (stance_type) {
|
||||
case stanceUnknown:
|
||||
return "Unknown";
|
||||
@@ -151,432 +146,9 @@ const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
||||
}
|
||||
}
|
||||
|
||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
||||
return (stance_type - EQ::constants::stancePassive);
|
||||
}
|
||||
int EQEmu::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||
if (stance_type >= EQEmu::constants::stancePassive && stance_type <= EQEmu::constants::stanceBurnAE)
|
||||
return (stance_type - EQEmu::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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||
}
|
||||
|
||||
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::ValueWithin(faction_consider_level, ConsiderLevel::Ally, ConsiderLevel::Scowls)) {
|
||||
return std::string();;
|
||||
}
|
||||
|
||||
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
|
||||
}
|
||||
|
||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
||||
}
|
||||
|
||||
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 std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
||||
}
|
||||
|
||||
+15
-308
@@ -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
|
||||
@@ -22,16 +22,19 @@
|
||||
|
||||
#include "eq_limits.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 {
|
||||
|
||||
} /*inventory*/
|
||||
|
||||
namespace invtype {
|
||||
using namespace RoF2::invtype::enum_;
|
||||
@@ -190,14 +193,14 @@ namespace EQ
|
||||
} // namespace invaug
|
||||
|
||||
namespace constants {
|
||||
const EQ::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQ::versions::ClientVersion::Titanium;
|
||||
const EQEmu::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQEmu::versions::ClientVersion::Titanium;
|
||||
|
||||
using RoF2::constants::EXPANSION;
|
||||
using RoF2::constants::EXPANSION_BIT;
|
||||
using RoF2::constants::EXPANSIONS_MASK;
|
||||
|
||||
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
|
||||
@@ -217,186 +220,9 @@ namespace EQ
|
||||
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;
|
||||
@@ -406,7 +232,7 @@ namespace EQ
|
||||
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;
|
||||
@@ -491,131 +317,12 @@ namespace EQ
|
||||
QuestControlGrid = -1
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
namespace HeroicBonusBucket
|
||||
{
|
||||
const std::string WisMaxMana = "HWIS-MaxMana";
|
||||
const std::string WisManaRegen = "HWIS-ManaRegen";
|
||||
const std::string WisHealAmt = "HWIS-HealAmt";
|
||||
const std::string IntMaxMana = "HINT-MaxMana";
|
||||
const std::string IntManaRegen = "HINT-ManaRegen";
|
||||
const std::string IntSpellDmg = "HINT-SpellDmg";
|
||||
const std::string StrMeleeDamage = "HSTR-MeleeDamage";
|
||||
const std::string StrShieldAC = "HSTR-ShieldAC";
|
||||
const std::string StrMaxEndurance = "HSTR-MaxEndurance";
|
||||
const std::string StrEnduranceRegen = "HSTR-EnduranceRegen";
|
||||
const std::string StaMaxHP = "HSTA-MaxHP";
|
||||
const std::string StaHPRegen = "HSTA-HPRegen";
|
||||
const std::string StaMaxEndurance = "HSTA-MaxEndurance";
|
||||
const std::string StaEnduranceRegen = "HSTA-EnduranceRegen";
|
||||
const std::string AgiAvoidance = "HAGI-Avoidance";
|
||||
const std::string AgiMaxEndurance = "HAGI-MaxEndurance";
|
||||
const std::string AgiEnduranceRegen = "HAGI-EnduranceRegen";
|
||||
const std::string DexRangedDamage = "HDEX-RangedDamage";
|
||||
const std::string DexMaxEndurance = "HDEX-MaxEndurance";
|
||||
const std::string DexEnduranceRegen = "HDEX-EnduranceRegen";
|
||||
}
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
/* hack list to prevent circular references
|
||||
|
||||
eq_limits.h:EQEmu::inventory::LookupEntry::InventoryTypeSize[n];
|
||||
|
||||
*/
|
||||
|
||||
+10
-35
@@ -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),
|
||||
@@ -62,7 +62,6 @@ N(OP_BeginCast),
|
||||
N(OP_Bind_Wound),
|
||||
N(OP_BlockedBuffs),
|
||||
N(OP_BoardBoat),
|
||||
N(OP_BookButton),
|
||||
N(OP_Buff),
|
||||
N(OP_BuffCreate),
|
||||
N(OP_BuffRemoveRequest),
|
||||
@@ -72,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),
|
||||
@@ -131,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),
|
||||
@@ -275,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),
|
||||
@@ -305,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),
|
||||
@@ -317,7 +311,6 @@ N(OP_LootRequest),
|
||||
N(OP_ManaChange),
|
||||
N(OP_ManaUpdate),
|
||||
N(OP_MarkNPC),
|
||||
N(OP_MarkRaidNPC),
|
||||
N(OP_Marquee),
|
||||
N(OP_MemorizeSpell),
|
||||
N(OP_Mend),
|
||||
@@ -359,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),
|
||||
@@ -400,8 +394,6 @@ N(OP_PVPLeaderBoardRequest),
|
||||
N(OP_PVPStats),
|
||||
N(OP_QueryResponseThing),
|
||||
N(OP_QueryUCSServerStatus),
|
||||
N(OP_RaidDelegateAbility),
|
||||
N(OP_RaidClearNPCMarks),
|
||||
N(OP_RaidInvite),
|
||||
N(OP_RaidJoin),
|
||||
N(OP_RaidUpdate),
|
||||
@@ -461,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),
|
||||
@@ -470,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),
|
||||
@@ -518,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),
|
||||
@@ -565,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),
|
||||
@@ -588,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
|
||||
|
||||
+31
-31
@@ -21,7 +21,7 @@
|
||||
#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 +29,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 +37,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,7 +61,7 @@ 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::Titanium:
|
||||
@@ -81,7 +81,7 @@ uint32 EQ::versions::ConvertClientVersionToClientVersionBit(ClientVersion client
|
||||
}
|
||||
}
|
||||
|
||||
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)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
|
||||
@@ -101,7 +101,7 @@ EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::versions::IsValidMobVersion(MobVersion mob_version)
|
||||
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
|
||||
{
|
||||
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
|
||||
return false;
|
||||
@@ -109,7 +109,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 +117,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 +125,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 +133,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 +141,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 +149,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 +157,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 +165,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 +217,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 +240,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 +263,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 +283,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 +303,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 +323,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:
|
||||
@@ -343,7 +343,7 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion
|
||||
}
|
||||
}
|
||||
|
||||
const char* EQ::expansions::ExpansionName(Expansion expansion)
|
||||
const char* EQEmu::expansions::ExpansionName(Expansion expansion)
|
||||
{
|
||||
switch (expansion) {
|
||||
case Expansion::EverQuest:
|
||||
@@ -393,12 +393,12 @@ const char* EQ::expansions::ExpansionName(Expansion expansion)
|
||||
}
|
||||
}
|
||||
|
||||
const char* EQ::expansions::ExpansionName(uint32 expansion_bit)
|
||||
const char* EQEmu::expansions::ExpansionName(uint32 expansion_bit)
|
||||
{
|
||||
return ExpansionName(ConvertExpansionBitToExpansion(expansion_bit));
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
|
||||
uint32 EQEmu::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
|
||||
{
|
||||
switch (expansion) {
|
||||
case Expansion::RoK:
|
||||
@@ -446,7 +446,7 @@ uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
|
||||
}
|
||||
}
|
||||
|
||||
EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
|
||||
EQEmu::expansions::Expansion EQEmu::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
|
||||
{
|
||||
switch (expansion_bit) {
|
||||
case bitRoK:
|
||||
@@ -494,7 +494,7 @@ EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32
|
||||
}
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
|
||||
uint32 EQEmu::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
|
||||
{
|
||||
switch (expansion) {
|
||||
case Expansion::RoK:
|
||||
@@ -542,17 +542,17 @@ uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
|
||||
}
|
||||
}
|
||||
|
||||
EQ::expansions::Expansion EQ::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
|
||||
EQEmu::expansions::Expansion EQEmu::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
|
||||
{
|
||||
return EQ::constants::StaticLookup(client_version)->Expansion;
|
||||
return EQEmu::constants::StaticLookup(client_version)->Expansion;
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
|
||||
uint32 EQEmu::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
|
||||
{
|
||||
return EQ::constants::StaticLookup(client_version)->ExpansionBit;
|
||||
return EQEmu::constants::StaticLookup(client_version)->ExpansionBit;
|
||||
}
|
||||
|
||||
uint32 EQ::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
|
||||
uint32 EQEmu::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
|
||||
{
|
||||
return EQ::constants::StaticLookup(client_version)->ExpansionsMask;
|
||||
return EQEmu::constants::StaticLookup(client_version)->ExpansionsMask;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
namespace versions {
|
||||
enum class ClientVersion : uint32 {
|
||||
|
||||
+9
-609
@@ -65,7 +65,6 @@
|
||||
#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
|
||||
|
||||
@@ -79,8 +78,6 @@
|
||||
#define ANIM_DEATH 0x73
|
||||
#define ANIM_LOOT 0x69
|
||||
|
||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||
|
||||
typedef enum {
|
||||
eaStanding = 0,
|
||||
eaSitting, //1
|
||||
@@ -200,491 +197,13 @@ namespace Chat {
|
||||
const uint16 Stun = 340;
|
||||
};
|
||||
|
||||
// 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 +231,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 +318,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,10 +438,6 @@ 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,
|
||||
@@ -944,119 +459,4 @@ enum ChatChannelNames : uint16
|
||||
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
|
||||
};
|
||||
|
||||
enum ScribeSpellActions
|
||||
{
|
||||
Scribe,
|
||||
Memorize,
|
||||
Unmemorize
|
||||
};
|
||||
|
||||
enum SpellTimeRestrictions
|
||||
{
|
||||
NoRestriction,
|
||||
Day,
|
||||
Night
|
||||
};
|
||||
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
+186
-186
@@ -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
|
||||
@@ -11,7 +11,7 @@
|
||||
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
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
|
||||
static bool global_dictionary_init = false;
|
||||
void EQ::InitializeDynamicLookups() {
|
||||
if (global_dictionary_init)
|
||||
void EQEmu::InitializeDynamicLookups() {
|
||||
if (global_dictionary_init == true)
|
||||
return;
|
||||
|
||||
constants::InitializeDynamicLookups();
|
||||
@@ -37,12 +37,12 @@ void EQ::InitializeDynamicLookups() {
|
||||
global_dictionary_init = true;
|
||||
}
|
||||
|
||||
static std::unique_ptr<EQ::constants::LookupEntry> constants_dynamic_nongm_lookup_entries[EQ::versions::ClientVersionCount];
|
||||
static std::unique_ptr<EQ::constants::LookupEntry> constants_dynamic_gm_lookup_entries[EQ::versions::ClientVersionCount];
|
||||
static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::versions::ClientVersionCount] =
|
||||
static std::unique_ptr<EQEmu::constants::LookupEntry> constants_dynamic_nongm_lookup_entries[EQEmu::versions::ClientVersionCount];
|
||||
static std::unique_ptr<EQEmu::constants::LookupEntry> constants_dynamic_gm_lookup_entries[EQEmu::versions::ClientVersionCount];
|
||||
static const EQEmu::constants::LookupEntry constants_static_lookup_entries[EQEmu::versions::ClientVersionCount] =
|
||||
{
|
||||
/*[ClientVersion::Unknown] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
ClientUnknown::constants::EXPANSION,
|
||||
ClientUnknown::constants::EXPANSION_BIT,
|
||||
ClientUnknown::constants::EXPANSIONS_MASK,
|
||||
@@ -50,7 +50,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
ClientUnknown::INULL
|
||||
),
|
||||
/*[ClientVersion::Client62] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
Client62::constants::EXPANSION,
|
||||
Client62::constants::EXPANSION_BIT,
|
||||
Client62::constants::EXPANSIONS_MASK,
|
||||
@@ -58,7 +58,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
Client62::INULL
|
||||
),
|
||||
/*[ClientVersion::Titanium] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
Titanium::constants::EXPANSION,
|
||||
Titanium::constants::EXPANSION_BIT,
|
||||
Titanium::constants::EXPANSIONS_MASK,
|
||||
@@ -66,7 +66,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
Titanium::constants::SAY_LINK_BODY_SIZE
|
||||
),
|
||||
/*[ClientVersion::SoF] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
SoF::constants::EXPANSION,
|
||||
SoF::constants::EXPANSION_BIT,
|
||||
SoF::constants::EXPANSIONS_MASK,
|
||||
@@ -74,7 +74,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
SoF::constants::SAY_LINK_BODY_SIZE
|
||||
),
|
||||
/*[ClientVersion::SoD] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
SoD::constants::EXPANSION,
|
||||
SoD::constants::EXPANSION_BIT,
|
||||
SoD::constants::EXPANSIONS_MASK,
|
||||
@@ -82,7 +82,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
SoD::constants::SAY_LINK_BODY_SIZE
|
||||
),
|
||||
/*[ClientVersion::UF] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
UF::constants::EXPANSION,
|
||||
UF::constants::EXPANSION_BIT,
|
||||
UF::constants::EXPANSIONS_MASK,
|
||||
@@ -90,7 +90,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
UF::constants::SAY_LINK_BODY_SIZE
|
||||
),
|
||||
/*[ClientVersion::RoF] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
RoF::constants::EXPANSION,
|
||||
RoF::constants::EXPANSION_BIT,
|
||||
RoF::constants::EXPANSIONS_MASK,
|
||||
@@ -98,7 +98,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
RoF::constants::SAY_LINK_BODY_SIZE
|
||||
),
|
||||
/*[ClientVersion::RoF2] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
EQEmu::constants::LookupEntry(
|
||||
RoF2::constants::EXPANSION,
|
||||
RoF2::constants::EXPANSION_BIT,
|
||||
RoF2::constants::EXPANSIONS_MASK,
|
||||
@@ -108,7 +108,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
};
|
||||
|
||||
static bool constants_dictionary_init = false;
|
||||
void EQ::constants::InitializeDynamicLookups() {
|
||||
void EQEmu::constants::InitializeDynamicLookups() {
|
||||
if (constants_dictionary_init == true)
|
||||
return;
|
||||
constants_dictionary_init = true;
|
||||
@@ -119,7 +119,7 @@ void EQ::constants::InitializeDynamicLookups() {
|
||||
// use static references for now
|
||||
}
|
||||
|
||||
const EQ::constants::LookupEntry* EQ::constants::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
|
||||
const EQEmu::constants::LookupEntry* EQEmu::constants::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
|
||||
{
|
||||
if (gm_flag)
|
||||
return DynamicGMLookup(client_version);
|
||||
@@ -127,7 +127,7 @@ const EQ::constants::LookupEntry* EQ::constants::DynamicLookup(versions::ClientV
|
||||
return DynamicNonGMLookup(client_version);
|
||||
}
|
||||
|
||||
const EQ::constants::LookupEntry* EQ::constants::DynamicNonGMLookup(versions::ClientVersion client_version)
|
||||
const EQEmu::constants::LookupEntry* EQEmu::constants::DynamicNonGMLookup(versions::ClientVersion client_version)
|
||||
{
|
||||
client_version = versions::ValidateClientVersion(client_version);
|
||||
if (constants_dynamic_nongm_lookup_entries[static_cast<int>(client_version)])
|
||||
@@ -136,7 +136,7 @@ const EQ::constants::LookupEntry* EQ::constants::DynamicNonGMLookup(versions::Cl
|
||||
return &constants_static_lookup_entries[static_cast<int>(client_version)];
|
||||
}
|
||||
|
||||
const EQ::constants::LookupEntry* EQ::constants::DynamicGMLookup(versions::ClientVersion client_version)
|
||||
const EQEmu::constants::LookupEntry* EQEmu::constants::DynamicGMLookup(versions::ClientVersion client_version)
|
||||
{
|
||||
client_version = versions::ValidateClientVersion(client_version);
|
||||
if (constants_dynamic_gm_lookup_entries[static_cast<int>(client_version)])
|
||||
@@ -145,18 +145,18 @@ const EQ::constants::LookupEntry* EQ::constants::DynamicGMLookup(versions::Clien
|
||||
return &constants_static_lookup_entries[static_cast<int>(client_version)];
|
||||
}
|
||||
|
||||
const EQ::constants::LookupEntry* EQ::constants::StaticLookup(versions::ClientVersion client_version)
|
||||
const EQEmu::constants::LookupEntry* EQEmu::constants::StaticLookup(versions::ClientVersion client_version)
|
||||
{
|
||||
return &constants_static_lookup_entries[static_cast<int>(versions::ValidateClientVersion(client_version))];
|
||||
}
|
||||
|
||||
static std::unique_ptr<EQ::inventory::LookupEntry> inventory_dynamic_nongm_lookup_entries[EQ::versions::MobVersionCount];
|
||||
static std::unique_ptr<EQ::inventory::LookupEntry> inventory_dynamic_gm_lookup_entries[EQ::versions::MobVersionCount];
|
||||
static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::versions::MobVersionCount] =
|
||||
static std::unique_ptr<EQEmu::inventory::LookupEntry> inventory_dynamic_nongm_lookup_entries[EQEmu::versions::MobVersionCount];
|
||||
static std::unique_ptr<EQEmu::inventory::LookupEntry> inventory_dynamic_gm_lookup_entries[EQEmu::versions::MobVersionCount];
|
||||
static const EQEmu::inventory::LookupEntry inventory_static_lookup_entries[EQEmu::versions::MobVersionCount] =
|
||||
{
|
||||
/*[MobVersion::Unknown] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
|
||||
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
|
||||
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
|
||||
@@ -167,7 +167,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
|
||||
ClientUnknown::INULL
|
||||
),
|
||||
|
||||
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
@@ -175,15 +175,15 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
|
||||
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
),
|
||||
/*[MobVersion::Client62] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
Client62::INULL, Client62::INULL, Client62::INULL,
|
||||
Client62::INULL, Client62::INULL, Client62::INULL,
|
||||
Client62::INULL, Client62::INULL, Client62::INULL,
|
||||
@@ -194,7 +194,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
Client62::INULL, Client62::INULL, Client62::INULL,
|
||||
Client62::INULL
|
||||
),
|
||||
|
||||
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
@@ -202,16 +202,16 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
|
||||
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
),
|
||||
/*[MobVersion::Titanium] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, Titanium::invtype::BANK_SIZE, Titanium::invtype::SHARED_BANK_SIZE,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, Titanium::invtype::BANK_SIZE, Titanium::invtype::SHARED_BANK_SIZE,
|
||||
Titanium::invtype::TRADE_SIZE, Titanium::invtype::WORLD_SIZE, Titanium::invtype::LIMBO_SIZE,
|
||||
Titanium::invtype::TRIBUTE_SIZE, Titanium::INULL, Titanium::invtype::GUILD_TRIBUTE_SIZE,
|
||||
Titanium::invtype::MERCHANT_SIZE, Titanium::INULL, Titanium::invtype::CORPSE_SIZE,
|
||||
@@ -221,7 +221,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
Titanium::INULL, Titanium::INULL, Titanium::INULL,
|
||||
Titanium::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
|
||||
Titanium::invslot::EQUIPMENT_BITMASK,
|
||||
Titanium::invslot::GENERAL_BITMASK,
|
||||
Titanium::invslot::CURSOR_BITMASK,
|
||||
@@ -229,16 +229,16 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
Titanium::invslot::CORPSE_BITMASK,
|
||||
Titanium::invbag::SLOT_COUNT,
|
||||
Titanium::invaug::SOCKET_COUNT,
|
||||
|
||||
|
||||
Titanium::inventory::AllowEmptyBagInBag,
|
||||
Titanium::inventory::AllowClickCastFromBag,
|
||||
Titanium::inventory::ConcatenateInvTypeLimbo,
|
||||
Titanium::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::SoF] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, SoF::invtype::BANK_SIZE, SoF::invtype::SHARED_BANK_SIZE,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, SoF::invtype::BANK_SIZE, SoF::invtype::SHARED_BANK_SIZE,
|
||||
SoF::invtype::TRADE_SIZE, SoF::invtype::WORLD_SIZE, SoF::invtype::LIMBO_SIZE,
|
||||
SoF::invtype::TRIBUTE_SIZE, SoF::INULL, SoF::invtype::GUILD_TRIBUTE_SIZE,
|
||||
SoF::invtype::MERCHANT_SIZE, SoF::INULL, SoF::invtype::CORPSE_SIZE,
|
||||
@@ -248,7 +248,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoF::INULL, SoF::INULL, SoF::INULL,
|
||||
SoF::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
|
||||
SoF::invslot::EQUIPMENT_BITMASK,
|
||||
SoF::invslot::GENERAL_BITMASK,
|
||||
SoF::invslot::CURSOR_BITMASK,
|
||||
@@ -256,16 +256,16 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoF::invslot::CORPSE_BITMASK,
|
||||
SoF::invbag::SLOT_COUNT,
|
||||
SoF::invaug::SOCKET_COUNT,
|
||||
|
||||
|
||||
SoF::inventory::AllowEmptyBagInBag,
|
||||
SoF::inventory::AllowClickCastFromBag,
|
||||
SoF::inventory::ConcatenateInvTypeLimbo,
|
||||
SoF::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::SoD] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, SoD::invtype::BANK_SIZE, SoD::invtype::SHARED_BANK_SIZE,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, SoD::invtype::BANK_SIZE, SoD::invtype::SHARED_BANK_SIZE,
|
||||
SoD::invtype::TRADE_SIZE, SoD::invtype::WORLD_SIZE, SoD::invtype::LIMBO_SIZE,
|
||||
SoD::invtype::TRIBUTE_SIZE, SoD::INULL, SoD::invtype::GUILD_TRIBUTE_SIZE,
|
||||
SoD::invtype::MERCHANT_SIZE, SoD::INULL, SoD::invtype::CORPSE_SIZE,
|
||||
@@ -290,9 +290,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoD::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::UF] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, UF::invtype::BANK_SIZE, UF::invtype::SHARED_BANK_SIZE,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, UF::invtype::BANK_SIZE, UF::invtype::SHARED_BANK_SIZE,
|
||||
UF::invtype::TRADE_SIZE, UF::invtype::WORLD_SIZE, UF::invtype::LIMBO_SIZE,
|
||||
UF::invtype::TRIBUTE_SIZE, UF::INULL, UF::invtype::GUILD_TRIBUTE_SIZE,
|
||||
UF::invtype::MERCHANT_SIZE, UF::INULL, UF::invtype::CORPSE_SIZE,
|
||||
@@ -317,9 +317,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
UF::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::RoF] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, RoF::invtype::BANK_SIZE, RoF::invtype::SHARED_BANK_SIZE,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, RoF::invtype::BANK_SIZE, RoF::invtype::SHARED_BANK_SIZE,
|
||||
RoF::invtype::TRADE_SIZE, RoF::invtype::WORLD_SIZE, RoF::invtype::LIMBO_SIZE,
|
||||
RoF::invtype::TRIBUTE_SIZE, RoF::invtype::TROPHY_TRIBUTE_SIZE, RoF::invtype::GUILD_TRIBUTE_SIZE,
|
||||
RoF::invtype::MERCHANT_SIZE, RoF::invtype::DELETED_SIZE, RoF::invtype::CORPSE_SIZE,
|
||||
@@ -344,9 +344,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::RoF2] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, RoF2::invtype::BANK_SIZE, RoF2::invtype::SHARED_BANK_SIZE,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, RoF2::invtype::BANK_SIZE, RoF2::invtype::SHARED_BANK_SIZE,
|
||||
RoF2::invtype::TRADE_SIZE, RoF2::invtype::WORLD_SIZE, RoF2::invtype::LIMBO_SIZE,
|
||||
RoF2::invtype::TRIBUTE_SIZE, RoF2::invtype::TROPHY_TRIBUTE_SIZE, RoF2::invtype::GUILD_TRIBUTE_SIZE,
|
||||
RoF2::invtype::MERCHANT_SIZE, RoF2::invtype::DELETED_SIZE, RoF2::invtype::CORPSE_SIZE,
|
||||
@@ -371,9 +371,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF2::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::NPC] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::invtype::TRADE_SIZE, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -389,8 +389,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -398,9 +398,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::NPCMerchant] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::invtype::TRADE_SIZE, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -416,8 +416,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -425,9 +425,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::Merc] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::invtype::TRADE_SIZE, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -443,8 +443,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -452,9 +452,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::Bot] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EntityLimits::Bot::invtype::TRADE_SIZE, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -470,8 +470,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::Bot::invslot::CURSOR_BITMASK,
|
||||
EntityLimits::Bot::invslot::POSSESSIONS_BITMASK,
|
||||
EntityLimits::Bot::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
EQ::invaug::SOCKET_COUNT, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
EQEmu::invaug::SOCKET_COUNT, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -479,9 +479,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::ClientPet] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::invtype::TRADE_SIZE, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -497,8 +497,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -506,9 +506,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::NPCPet] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::invtype::TRADE_SIZE, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -524,8 +524,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -533,9 +533,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::MercPet] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::invtype::TRADE_SIZE, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -551,8 +551,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -560,9 +560,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::BotPet] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::invtype::TRADE_SIZE, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, /*InvTypeCorpseSize,*/
|
||||
@@ -578,8 +578,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL,
|
||||
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
|
||||
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
|
||||
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
|
||||
|
||||
false,
|
||||
false,
|
||||
@@ -587,8 +587,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineTitanium] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
Titanium::INULL, Titanium::INULL, Titanium::INULL,
|
||||
Titanium::invtype::TRADE_SIZE, Titanium::INULL, Titanium::INULL,
|
||||
Titanium::INULL, Titanium::INULL, Titanium::INULL,
|
||||
@@ -614,8 +614,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineSoF] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
SoF::INULL, SoF::INULL, SoF::INULL,
|
||||
SoF::invtype::TRADE_SIZE, SoF::INULL, SoF::INULL,
|
||||
SoF::INULL, SoF::INULL, SoF::INULL,
|
||||
@@ -641,8 +641,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineSoD] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
SoD::INULL, SoD::INULL, SoD::INULL,
|
||||
SoD::invtype::TRADE_SIZE, SoD::INULL, SoD::INULL,
|
||||
SoD::INULL, SoD::INULL, SoD::INULL,
|
||||
@@ -668,8 +668,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineUF] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
UF::INULL, UF::INULL, UF::INULL,
|
||||
UF::invtype::TRADE_SIZE, UF::INULL, UF::INULL,
|
||||
UF::INULL, UF::INULL, UF::INULL,
|
||||
@@ -695,8 +695,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineRoF] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
RoF::INULL, RoF::INULL, RoF::INULL,
|
||||
RoF::invtype::TRADE_SIZE, RoF::INULL, RoF::INULL,
|
||||
RoF::INULL, RoF::INULL, RoF::INULL,
|
||||
@@ -722,8 +722,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineRoF2] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQEmu::inventory::LookupEntry(
|
||||
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::invtype::TRADE_SIZE, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL,
|
||||
@@ -751,7 +751,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
};
|
||||
|
||||
static bool inventory_dictionary_init = false;
|
||||
void EQ::inventory::InitializeDynamicLookups() {
|
||||
void EQEmu::inventory::InitializeDynamicLookups() {
|
||||
if (inventory_dictionary_init == true)
|
||||
return;
|
||||
inventory_dictionary_init = true;
|
||||
@@ -763,7 +763,7 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
// Notes:
|
||||
// - Currently, there are only 3 known expansions that affect inventory-related settings in the clients..
|
||||
// -- Expansion::PoR "Prophecy of Ro" - toggles between 24 (set) and 16 (clear) bank slots
|
||||
// -- Expansion::TBS "The Buried Sea" - toggles slotPowerSource activated (set) and deactivated (clear)
|
||||
// -- Expansion::TBS "The Buried Sea" - toggles slotPowerSource activated (set) and deactivated (clear)
|
||||
// -- Expansion::HoT "House of Thule" - toggles slotGeneral9/slotGeneral10 activated (set) and deactivated (clear)
|
||||
// - Corspe size does not appear to reflect loss of active possessions slots
|
||||
// - Inspect size does not appear to reflect loss of active equipment slots
|
||||
@@ -772,11 +772,11 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
// - General9 and General10 slots are activated by GM flag when expansion bit is (clear)
|
||||
// - Obviously, the client must support the expansion to allow any (set) or override condition
|
||||
|
||||
const uint32 dynamic_check_mask =
|
||||
const uint32 dynamic_check_mask =
|
||||
(
|
||||
EQ::expansions::bitPoR |
|
||||
EQ::expansions::bitTBS |
|
||||
EQ::expansions::bitHoT
|
||||
EQEmu::expansions::bitPoR |
|
||||
EQEmu::expansions::bitTBS |
|
||||
EQEmu::expansions::bitHoT
|
||||
);
|
||||
|
||||
// if all of the above expansion bits are present, then static references will suffice
|
||||
@@ -784,7 +784,7 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
return;
|
||||
|
||||
// Dynamic Lookups (promotive methodology) (all mob versions allowed)
|
||||
for (uint32 iter = static_cast<uint32>(EQ::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQ::versions::LastPCMobVersion); ++iter) {
|
||||
for (uint32 iter = static_cast<uint32>(EQEmu::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQEmu::versions::LastPCMobVersion); ++iter) {
|
||||
// no need to dynamic this condition since it is the lowest compatibility standard
|
||||
if ((dynamic_check_mask & ~constants_static_lookup_entries[iter].ExpansionsMask) == dynamic_check_mask)
|
||||
continue;
|
||||
@@ -794,7 +794,7 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
continue;
|
||||
|
||||
// direct manipulation of lookup indices is safe so long as (int)ClientVersion::<mob> == (int)MobVersion::<mob>
|
||||
inventory_dynamic_nongm_lookup_entries[iter] = std::make_unique<LookupEntry>(inventory_static_lookup_entries[iter]);
|
||||
inventory_dynamic_nongm_lookup_entries[iter] = std::unique_ptr<LookupEntry>(new LookupEntry(inventory_static_lookup_entries[iter]));
|
||||
|
||||
// clamp affected fields to the lowest standard
|
||||
inventory_dynamic_nongm_lookup_entries[iter]->InventoryTypeSize.Bank = Titanium::invtype::BANK_SIZE; // bank size
|
||||
@@ -803,21 +803,21 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
inventory_dynamic_nongm_lookup_entries[iter]->PossessionsBitmask = 0; // we'll fix later
|
||||
inventory_dynamic_nongm_lookup_entries[iter]->CorpseBitmask = 0; // we'll fix later
|
||||
|
||||
if (RuleI(World, ExpansionSettings) & EQ::expansions::bitPoR) {
|
||||
if (RuleI(World, ExpansionSettings) & EQEmu::expansions::bitPoR) {
|
||||
// update bank size
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitPoR)
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitPoR)
|
||||
inventory_dynamic_nongm_lookup_entries[iter]->InventoryTypeSize.Bank = SoF::invtype::BANK_SIZE;
|
||||
}
|
||||
|
||||
if (RuleI(World, ExpansionSettings) & EQ::expansions::bitTBS) {
|
||||
if (RuleI(World, ExpansionSettings) & EQEmu::expansions::bitTBS) {
|
||||
// update power source
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitTBS)
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitTBS)
|
||||
inventory_dynamic_nongm_lookup_entries[iter]->EquipmentBitmask = SoF::invslot::EQUIPMENT_BITMASK;
|
||||
}
|
||||
|
||||
if (RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT) {
|
||||
if (RuleI(World, ExpansionSettings) & EQEmu::expansions::bitHoT) {
|
||||
// update general size
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitHoT)
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitHoT)
|
||||
inventory_dynamic_nongm_lookup_entries[iter]->GeneralBitmask = RoF::invslot::GENERAL_BITMASK;
|
||||
}
|
||||
|
||||
@@ -841,7 +841,7 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
}
|
||||
|
||||
// Dynamic GM Lookups (demotive methodology) (client-linked mob versions only)
|
||||
for (uint32 iter = static_cast<uint32>(EQ::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQ::versions::LastPCMobVersion); ++iter) {
|
||||
for (uint32 iter = static_cast<uint32>(EQEmu::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQEmu::versions::LastPCMobVersion); ++iter) {
|
||||
// no need to dynamic this condition since it is the lowest compatibility standard
|
||||
if ((dynamic_check_mask & ~constants_static_lookup_entries[iter].ExpansionsMask) == dynamic_check_mask)
|
||||
continue;
|
||||
@@ -864,18 +864,18 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
}
|
||||
|
||||
// direct manipulation of lookup indices is safe so long as (int)ClientVersion::<client> == (int)MobVersion::<client>
|
||||
inventory_dynamic_gm_lookup_entries[iter] = std::make_unique<LookupEntry>(inventory_static_lookup_entries[iter]);
|
||||
inventory_dynamic_gm_lookup_entries[iter] = std::unique_ptr<LookupEntry>(new LookupEntry(inventory_static_lookup_entries[iter]));
|
||||
|
||||
inventory_dynamic_gm_lookup_entries[iter]->PossessionsBitmask = 0; // we'll fix later
|
||||
inventory_dynamic_gm_lookup_entries[iter]->CorpseBitmask = 0; // we'll fix later
|
||||
|
||||
if (~RuleI(World, ExpansionSettings) & EQ::expansions::bitPoR) {
|
||||
if (~RuleI(World, ExpansionSettings) & EQEmu::expansions::bitPoR) {
|
||||
// update bank size
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitPoR)
|
||||
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitPoR)
|
||||
inventory_dynamic_gm_lookup_entries[iter]->InventoryTypeSize.Bank = Titanium::invtype::BANK_SIZE;
|
||||
}
|
||||
|
||||
if (~RuleI(World, ExpansionSettings) & EQ::expansions::bitTBS) {
|
||||
if (~RuleI(World, ExpansionSettings) & EQEmu::expansions::bitTBS) {
|
||||
// update power source
|
||||
switch (iter) {
|
||||
case versions::bitUF:
|
||||
@@ -890,7 +890,7 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
}
|
||||
}
|
||||
|
||||
if (~RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT) {
|
||||
if (~RuleI(World, ExpansionSettings) & EQEmu::expansions::bitHoT) {
|
||||
// update general size
|
||||
switch (iter) {
|
||||
case versions::bitUF:
|
||||
@@ -927,7 +927,7 @@ void EQ::inventory::InitializeDynamicLookups() {
|
||||
// only client versions that require a change from their static definitions have been given a dynamic (gm) lookup entry
|
||||
}
|
||||
|
||||
const EQ::inventory::LookupEntry* EQ::inventory::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
|
||||
const EQEmu::inventory::LookupEntry* EQEmu::inventory::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
|
||||
{
|
||||
if (gm_flag)
|
||||
return DynamicGMLookup(mob_version);
|
||||
@@ -935,7 +935,7 @@ const EQ::inventory::LookupEntry* EQ::inventory::DynamicLookup(versions::MobVers
|
||||
return DynamicNonGMLookup(mob_version);
|
||||
}
|
||||
|
||||
const EQ::inventory::LookupEntry* EQ::inventory::DynamicNonGMLookup(versions::MobVersion mob_version)
|
||||
const EQEmu::inventory::LookupEntry* EQEmu::inventory::DynamicNonGMLookup(versions::MobVersion mob_version)
|
||||
{
|
||||
mob_version = versions::ValidateMobVersion(mob_version);
|
||||
if (inventory_dynamic_nongm_lookup_entries[static_cast<int>(mob_version)])
|
||||
@@ -944,7 +944,7 @@ const EQ::inventory::LookupEntry* EQ::inventory::DynamicNonGMLookup(versions::Mo
|
||||
return &inventory_static_lookup_entries[static_cast<int>(mob_version)];
|
||||
}
|
||||
|
||||
const EQ::inventory::LookupEntry* EQ::inventory::DynamicGMLookup(versions::MobVersion mob_version)
|
||||
const EQEmu::inventory::LookupEntry* EQEmu::inventory::DynamicGMLookup(versions::MobVersion mob_version)
|
||||
{
|
||||
mob_version = versions::ValidateMobVersion(mob_version);
|
||||
if (inventory_dynamic_gm_lookup_entries[static_cast<int>(mob_version)])
|
||||
@@ -953,107 +953,107 @@ const EQ::inventory::LookupEntry* EQ::inventory::DynamicGMLookup(versions::MobVe
|
||||
return &inventory_static_lookup_entries[static_cast<int>(mob_version)];
|
||||
}
|
||||
|
||||
const EQ::inventory::LookupEntry* EQ::inventory::StaticLookup(versions::MobVersion mob_version)
|
||||
const EQEmu::inventory::LookupEntry* EQEmu::inventory::StaticLookup(versions::MobVersion mob_version)
|
||||
{
|
||||
return &inventory_static_lookup_entries[static_cast<int>(versions::ValidateMobVersion(mob_version))];
|
||||
}
|
||||
|
||||
static std::unique_ptr<EQ::behavior::LookupEntry> behavior_dynamic_nongm_lookup_entries[EQ::versions::MobVersionCount];
|
||||
static std::unique_ptr<EQ::behavior::LookupEntry> behavior_dynamic_gm_lookup_entries[EQ::versions::MobVersionCount];
|
||||
static const EQ::behavior::LookupEntry behavior_static_lookup_entries[EQ::versions::MobVersionCount] =
|
||||
static std::unique_ptr<EQEmu::behavior::LookupEntry> behavior_dynamic_nongm_lookup_entries[EQEmu::versions::MobVersionCount];
|
||||
static std::unique_ptr<EQEmu::behavior::LookupEntry> behavior_dynamic_gm_lookup_entries[EQEmu::versions::MobVersionCount];
|
||||
static const EQEmu::behavior::LookupEntry behavior_static_lookup_entries[EQEmu::versions::MobVersionCount] =
|
||||
{
|
||||
/*[MobVersion::Unknown] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
true
|
||||
),
|
||||
/*[MobVersion::Client62] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
true
|
||||
),
|
||||
/*[MobVersion::Titanium] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
Titanium::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::SoF] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
SoF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::SoD] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
SoD::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::UF] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
UF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::RoF] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
RoF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::RoF2] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
RoF2::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::NPC] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::NPCMerchant] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::Merc] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::Bot] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::ClientPet] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::NPCPet] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::MercPet] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::BotPet] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
EQEmu::behavior::LookupEntry(
|
||||
EQEmu::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineTitanium] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
Titanium::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineSoF] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
SoF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineSoD] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
SoD::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineUF] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
UF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineRoF] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
RoF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineRoF2] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQEmu::behavior::LookupEntry(
|
||||
RoF2::behavior::CoinHasWeight
|
||||
)
|
||||
};
|
||||
|
||||
static bool behavior_dictionary_init = false;
|
||||
void EQ::behavior::InitializeDynamicLookups() {
|
||||
void EQEmu::behavior::InitializeDynamicLookups() {
|
||||
if (behavior_dictionary_init == true)
|
||||
return;
|
||||
behavior_dictionary_init = true;
|
||||
@@ -1064,7 +1064,7 @@ void EQ::behavior::InitializeDynamicLookups() {
|
||||
// use static references for now
|
||||
}
|
||||
|
||||
const EQ::behavior::LookupEntry* EQ::behavior::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
|
||||
const EQEmu::behavior::LookupEntry* EQEmu::behavior::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
|
||||
{
|
||||
if (gm_flag)
|
||||
return DynamicGMLookup(mob_version);
|
||||
@@ -1072,7 +1072,7 @@ const EQ::behavior::LookupEntry* EQ::behavior::DynamicLookup(versions::MobVersio
|
||||
return DynamicNonGMLookup(mob_version);
|
||||
}
|
||||
|
||||
const EQ::behavior::LookupEntry* EQ::behavior::DynamicNonGMLookup(versions::MobVersion mob_version)
|
||||
const EQEmu::behavior::LookupEntry* EQEmu::behavior::DynamicNonGMLookup(versions::MobVersion mob_version)
|
||||
{
|
||||
mob_version = versions::ValidateMobVersion(mob_version);
|
||||
if (behavior_dynamic_nongm_lookup_entries[static_cast<int>(mob_version)])
|
||||
@@ -1081,7 +1081,7 @@ const EQ::behavior::LookupEntry* EQ::behavior::DynamicNonGMLookup(versions::MobV
|
||||
return &behavior_static_lookup_entries[static_cast<int>(mob_version)];
|
||||
}
|
||||
|
||||
const EQ::behavior::LookupEntry* EQ::behavior::DynamicGMLookup(versions::MobVersion mob_version)
|
||||
const EQEmu::behavior::LookupEntry* EQEmu::behavior::DynamicGMLookup(versions::MobVersion mob_version)
|
||||
{
|
||||
mob_version = versions::ValidateMobVersion(mob_version);
|
||||
if (behavior_dynamic_gm_lookup_entries[static_cast<int>(mob_version)])
|
||||
@@ -1090,17 +1090,17 @@ const EQ::behavior::LookupEntry* EQ::behavior::DynamicGMLookup(versions::MobVers
|
||||
return &behavior_static_lookup_entries[static_cast<int>(mob_version)];
|
||||
}
|
||||
|
||||
const EQ::behavior::LookupEntry* EQ::behavior::StaticLookup(versions::MobVersion mob_version)
|
||||
const EQEmu::behavior::LookupEntry* EQEmu::behavior::StaticLookup(versions::MobVersion mob_version)
|
||||
{
|
||||
return &behavior_static_lookup_entries[static_cast<int>(versions::ValidateMobVersion(mob_version))];
|
||||
}
|
||||
|
||||
static std::unique_ptr<EQ::spells::LookupEntry> spells_dynamic_nongm_lookup_entries[EQ::versions::ClientVersionCount];
|
||||
static std::unique_ptr<EQ::spells::LookupEntry> spells_dynamic_gm_lookup_entries[EQ::versions::ClientVersionCount];
|
||||
static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::ClientVersionCount] =
|
||||
static std::unique_ptr<EQEmu::spells::LookupEntry> spells_dynamic_nongm_lookup_entries[EQEmu::versions::ClientVersionCount];
|
||||
static std::unique_ptr<EQEmu::spells::LookupEntry> spells_dynamic_gm_lookup_entries[EQEmu::versions::ClientVersionCount];
|
||||
static const EQEmu::spells::LookupEntry spells_static_lookup_entries[EQEmu::versions::ClientVersionCount] =
|
||||
{
|
||||
/*[ClientVersion::Unknown] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
@@ -1113,7 +1113,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
ClientUnknown::INULL
|
||||
),
|
||||
/*[ClientVersion::Client62] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
@@ -1126,7 +1126,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
Client62::INULL
|
||||
),
|
||||
/*[ClientVersion::Titanium] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
Titanium::spells::SPELL_ID_MAX,
|
||||
Titanium::spells::SPELLBOOK_SIZE,
|
||||
Titanium::spells::SPELL_GEM_COUNT,
|
||||
@@ -1139,7 +1139,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
Titanium::spells::MERC_BUFFS
|
||||
),
|
||||
/*[ClientVersion::SoF] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
SoF::spells::SPELL_ID_MAX,
|
||||
SoF::spells::SPELLBOOK_SIZE,
|
||||
SoF::spells::SPELL_GEM_COUNT,
|
||||
@@ -1152,7 +1152,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
SoF::spells::MERC_BUFFS
|
||||
),
|
||||
/*[ClientVersion::SoD] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
SoD::spells::SPELL_ID_MAX,
|
||||
SoD::spells::SPELLBOOK_SIZE,
|
||||
SoD::spells::SPELL_GEM_COUNT,
|
||||
@@ -1165,7 +1165,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
SoD::spells::MERC_BUFFS
|
||||
),
|
||||
/*[ClientVersion::UF] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
UF::spells::SPELL_ID_MAX,
|
||||
UF::spells::SPELLBOOK_SIZE,
|
||||
UF::spells::SPELL_GEM_COUNT,
|
||||
@@ -1178,7 +1178,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
UF::spells::MERC_BUFFS
|
||||
),
|
||||
/*[ClientVersion::RoF] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
RoF::spells::SPELL_ID_MAX,
|
||||
RoF::spells::SPELLBOOK_SIZE,
|
||||
UF::spells::SPELL_GEM_COUNT, // client translators are setup to allow the max value a client supports..however, the top 4 indices are not valid in this case
|
||||
@@ -1191,7 +1191,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
RoF::spells::MERC_BUFFS
|
||||
),
|
||||
/*[ClientVersion::RoF2] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
EQEmu::spells::LookupEntry(
|
||||
RoF2::spells::SPELL_ID_MAX,
|
||||
RoF2::spells::SPELLBOOK_SIZE,
|
||||
UF::spells::SPELL_GEM_COUNT, // client translators are setup to allow the max value a client supports..however, the top 4 indices are not valid in this case
|
||||
@@ -1206,18 +1206,18 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
};
|
||||
|
||||
static bool spells_dictionary_init = false;
|
||||
void EQ::spells::InitializeDynamicLookups() {
|
||||
void EQEmu::spells::InitializeDynamicLookups() {
|
||||
if (spells_dictionary_init == true)
|
||||
return;
|
||||
spells_dictionary_init = true;
|
||||
|
||||
|
||||
if (RuleB(World, UseClientBasedExpansionSettings))
|
||||
return;
|
||||
|
||||
|
||||
// use static references for now
|
||||
}
|
||||
|
||||
const EQ::spells::LookupEntry* EQ::spells::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
|
||||
const EQEmu::spells::LookupEntry* EQEmu::spells::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
|
||||
{
|
||||
if (gm_flag)
|
||||
return DynamicGMLookup(client_version);
|
||||
@@ -1225,7 +1225,7 @@ const EQ::spells::LookupEntry* EQ::spells::DynamicLookup(versions::ClientVersion
|
||||
return DynamicNonGMLookup(client_version);
|
||||
}
|
||||
|
||||
const EQ::spells::LookupEntry* EQ::spells::DynamicNonGMLookup(versions::ClientVersion client_version)
|
||||
const EQEmu::spells::LookupEntry* EQEmu::spells::DynamicNonGMLookup(versions::ClientVersion client_version)
|
||||
{
|
||||
client_version = versions::ValidateClientVersion(client_version);
|
||||
if (spells_dynamic_nongm_lookup_entries[static_cast<int>(client_version)])
|
||||
@@ -1234,16 +1234,16 @@ const EQ::spells::LookupEntry* EQ::spells::DynamicNonGMLookup(versions::ClientVe
|
||||
return &spells_static_lookup_entries[static_cast<int>(client_version)];
|
||||
}
|
||||
|
||||
const EQ::spells::LookupEntry* EQ::spells::DynamicGMLookup(versions::ClientVersion client_version)
|
||||
const EQEmu::spells::LookupEntry* EQEmu::spells::DynamicGMLookup(versions::ClientVersion client_version)
|
||||
{
|
||||
client_version = versions::ValidateClientVersion(client_version);
|
||||
if (spells_dynamic_gm_lookup_entries[static_cast<int>(client_version)])
|
||||
return spells_dynamic_gm_lookup_entries[static_cast<int>(client_version)].get();
|
||||
|
||||
|
||||
return &spells_static_lookup_entries[static_cast<int>(client_version)];
|
||||
}
|
||||
|
||||
const EQ::spells::LookupEntry* EQ::spells::StaticLookup(versions::ClientVersion client_version)
|
||||
const EQEmu::spells::LookupEntry* EQEmu::spells::StaticLookup(versions::ClientVersion client_version)
|
||||
{
|
||||
return &spells_static_lookup_entries[static_cast<int>(versions::ValidateClientVersion(client_version))];
|
||||
}
|
||||
|
||||
+11
-11
@@ -31,13 +31,13 @@
|
||||
#include "../common/patches/rof2_limits.h"
|
||||
|
||||
|
||||
namespace EQ
|
||||
namespace EQEmu
|
||||
{
|
||||
void InitializeDynamicLookups();
|
||||
|
||||
namespace constants {
|
||||
struct LookupEntry {
|
||||
EQ::expansions::Expansion Expansion;
|
||||
EQEmu::expansions::Expansion Expansion;
|
||||
uint32 ExpansionBit;
|
||||
uint32 ExpansionsMask;
|
||||
int16 CharacterCreationLimit;
|
||||
@@ -45,7 +45,7 @@ namespace EQ
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
EQ::expansions::Expansion Expansion,
|
||||
EQEmu::expansions::Expansion Expansion,
|
||||
uint32 ExpansionBit,
|
||||
uint32 ExpansionsMask,
|
||||
int16 CharacterCreationLimit,
|
||||
@@ -111,7 +111,7 @@ namespace EQ
|
||||
|
||||
union {
|
||||
InventoryTypeSize_Struct InventoryTypeSize;
|
||||
int16 InventoryTypeSizeArray[25]; // should reflect EQ::invtype::TYPE_COUNT referenced in emu_constants.h
|
||||
int16 InventoryTypeSizeArray[25]; // should reflect EQEmu::invtype::TYPE_COUNT referenced in emu_constants.h
|
||||
};
|
||||
|
||||
uint64 EquipmentBitmask;
|
||||
@@ -129,7 +129,7 @@ namespace EQ
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
const InventoryTypeSize_Struct& InventoryTypeSize,
|
||||
InventoryTypeSize_Struct InventoryTypeSize,
|
||||
uint64 EquipmentBitmask,
|
||||
uint64 GeneralBitmask,
|
||||
uint64 CursorBitmask,
|
||||
@@ -244,9 +244,9 @@ namespace ClientUnknown
|
||||
const int16 INULL = 0;
|
||||
|
||||
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;
|
||||
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::EverQuest;
|
||||
const uint32 EXPANSION_BIT = EQEmu::expansions::bitEverQuest;
|
||||
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskEverQuest;
|
||||
|
||||
} // namespace constants
|
||||
|
||||
@@ -258,9 +258,9 @@ namespace Client62
|
||||
const int16 INULL = 0;
|
||||
|
||||
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;
|
||||
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::EverQuest;
|
||||
const uint32 EXPANSION_BIT = EQEmu::expansions::bitEverQuest;
|
||||
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskEverQuest;
|
||||
|
||||
} // namespace constants
|
||||
|
||||
|
||||
+138
-1
@@ -236,6 +236,26 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
|
||||
return size+OpCodeBytes;
|
||||
}
|
||||
|
||||
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
|
||||
: BasePacket(buf, len),
|
||||
opcode(op)
|
||||
{
|
||||
|
||||
uint32 offset;
|
||||
opcode=ntohs(*(const uint16 *)buf);
|
||||
offset=2;
|
||||
|
||||
if (len-offset) {
|
||||
pBuffer= new unsigned char[len-offset];
|
||||
memcpy(pBuffer,buf+offset,len-offset);
|
||||
size=len-offset;
|
||||
} else {
|
||||
pBuffer=nullptr;
|
||||
size=0;
|
||||
}
|
||||
OpMgr=&RawOpcodeManager;
|
||||
}*/
|
||||
|
||||
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
|
||||
{
|
||||
bool result=false;
|
||||
@@ -267,6 +287,74 @@ bool result=false;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
this is the code to do app-layer combining, instead of protocol layer.
|
||||
this was taken out due to complex interactions with the opcode manager,
|
||||
and will require a bit more thinking (likely moving into EQStream) to
|
||||
get running again... but might be a good thing some day.
|
||||
|
||||
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
|
||||
{
|
||||
uint32 newsize=0, offset=0;
|
||||
unsigned char *tmpbuffer=nullptr;
|
||||
|
||||
if (opcode!=OP_AppCombined) {
|
||||
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
|
||||
tmpbuffer=new unsigned char [newsize];
|
||||
offset=0;
|
||||
if (size>254) {
|
||||
tmpbuffer[offset++]=0xff;
|
||||
*(uint16 *)(tmpbuffer+offset)=htons(size);
|
||||
offset+=1;
|
||||
} else {
|
||||
tmpbuffer[offset++]=size;
|
||||
}
|
||||
offset+=serialize(tmpbuffer+offset);
|
||||
} else {
|
||||
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
|
||||
tmpbuffer=new unsigned char [newsize];
|
||||
memcpy(tmpbuffer,pBuffer,size);
|
||||
offset=size;
|
||||
}
|
||||
|
||||
if (rhs->size>254) {
|
||||
tmpbuffer[offset++]=0xff;
|
||||
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
|
||||
offset+=1;
|
||||
} else {
|
||||
tmpbuffer[offset++]=rhs->size;
|
||||
}
|
||||
offset+=rhs->serialize(tmpbuffer+offset);
|
||||
|
||||
size=offset;
|
||||
opcode=OP_AppCombined;
|
||||
|
||||
delete[] pBuffer;
|
||||
pBuffer=tmpbuffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
|
||||
{
|
||||
bool valid=false;
|
||||
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
|
||||
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
|
||||
valid=true;
|
||||
} else {
|
||||
uint16 comp_crc=CRC16(buffer,length-2,Key);
|
||||
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
|
||||
#ifdef EQN_DEBUG
|
||||
if (packet_crc && comp_crc != packet_crc) {
|
||||
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
|
||||
}
|
||||
#endif
|
||||
valid = (!packet_crc || comp_crc == packet_crc);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
|
||||
{
|
||||
uint32 newlen=0;
|
||||
@@ -315,6 +403,55 @@ uint32 flag_offset=1,newlength;
|
||||
return newlength;
|
||||
}
|
||||
|
||||
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
|
||||
{
|
||||
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
|
||||
int Key=DecodeKey;
|
||||
unsigned char *test=(unsigned char *)malloc(size);
|
||||
buffer+=2;
|
||||
size-=2;
|
||||
|
||||
int i;
|
||||
for (i = 0 ; i+4 <= size ; i+=4)
|
||||
{
|
||||
int pt = (*(int*)&buffer[i])^(Key);
|
||||
Key = (*(int*)&buffer[i]);
|
||||
*(int*)&test[i]=pt;
|
||||
}
|
||||
unsigned char KC=Key&0xFF;
|
||||
for ( ; i < size ; i++)
|
||||
{
|
||||
test[i]=buffer[i]^KC;
|
||||
}
|
||||
memcpy(buffer,test,size);
|
||||
free(test);
|
||||
}
|
||||
}
|
||||
|
||||
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
|
||||
{
|
||||
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
|
||||
int Key=EncodeKey;
|
||||
char *test=(char*)malloc(size);
|
||||
int i;
|
||||
buffer+=2;
|
||||
size-=2;
|
||||
for ( i = 0 ; i+4 <= size ; i+=4)
|
||||
{
|
||||
int pt = (*(int*)&buffer[i])^(Key);
|
||||
Key = pt;
|
||||
*(int*)&test[i]=pt;
|
||||
}
|
||||
unsigned char KC=Key&0xFF;
|
||||
for ( ; i < size ; i++)
|
||||
{
|
||||
test[i]=buffer[i]^KC;
|
||||
}
|
||||
memcpy(buffer,test,size);
|
||||
free(test);
|
||||
}
|
||||
}
|
||||
|
||||
EQApplicationPacket *EQApplicationPacket::Copy() const {
|
||||
return(new EQApplicationPacket(*this));
|
||||
}
|
||||
@@ -378,4 +515,4 @@ std::string DumpPacketToString(const EQApplicationPacket* app){
|
||||
std::ostringstream out;
|
||||
out << DumpPacketHexToString(app->pBuffer, app->size);
|
||||
return out.str();
|
||||
}
|
||||
}
|
||||
@@ -80,8 +80,11 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
|
||||
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
|
||||
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
|
||||
|
||||
uint16 GetRawOpcode() const { return(opcode); }
|
||||
|
||||
|
||||
+181
-416
@@ -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*/
|
||||
|
||||
@@ -374,19 +372,14 @@ 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;
|
||||
/*0708*/ uint32 FastRegenHP;
|
||||
/*0712*/ uint32 FastRegenMana;
|
||||
/*0716*/ uint32 FastRegenEndurance;
|
||||
/*0720*/ uint32 NPCAggroMaxDist;
|
||||
/*0724*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -448,7 +441,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 +734,7 @@ struct BandolierItem_Struct
|
||||
struct Bandolier_Struct
|
||||
{
|
||||
char Name[32];
|
||||
BandolierItem_Struct Items[EQ::profile::BANDOLIER_ITEM_COUNT];
|
||||
BandolierItem_Struct Items[EQEmu::profile::BANDOLIER_ITEM_COUNT];
|
||||
};
|
||||
|
||||
//len = 72
|
||||
@@ -756,7 +748,7 @@ struct PotionBeltItem_Struct
|
||||
//len = 288
|
||||
struct PotionBelt_Struct
|
||||
{
|
||||
PotionBeltItem_Struct Items[EQ::profile::POTION_BELT_SIZE];
|
||||
PotionBeltItem_Struct Items[EQEmu::profile::POTION_BELT_SIZE];
|
||||
};
|
||||
|
||||
struct MovePotionToBelt_Struct
|
||||
@@ -832,7 +824,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 +839,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*/
|
||||
};
|
||||
@@ -939,7 +931,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[EQEmu::spells::SPELL_GEM_COUNT]; //in ms
|
||||
/*0292*/ uint32 abilitySlotRefresh;
|
||||
/*0296*/ uint8 haircolor; // Player hair color
|
||||
/*0297*/ uint8 beardcolor; // Player beard color
|
||||
@@ -952,9 +944,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 +970,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[EQEmu::spells::SPELLBOOK_SIZE];
|
||||
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
|
||||
/*4632*/ uint32 mem_spells[EQ::spells::SPELL_GEM_COUNT];
|
||||
/*4632*/ uint32 mem_spells[EQEmu::spells::SPELL_GEM_COUNT];
|
||||
/*4668*/ uint8 unknown4704[32]; //
|
||||
/*4700*/ float y; // Player y position
|
||||
/*4704*/ float x; // Player x position
|
||||
@@ -1056,7 +1048,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::invtype::TRIBUTE_SIZE];
|
||||
/*7264*/ Disciplines_Struct disciplines;
|
||||
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
|
||||
/*7744*/ char unknown7780[160];
|
||||
@@ -1083,7 +1075,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::profile::BANDOLIERS_SIZE];
|
||||
/*14124*/ uint8 unknown14160[4506];
|
||||
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
|
||||
/*19240*/ uint32 timeentitledonaccount;
|
||||
@@ -1101,16 +1093,16 @@ struct PlayerProfile_Struct
|
||||
/*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) { }
|
||||
PlayerProfile_Struct() : m_player_profile_version(EQEmu::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)); }
|
||||
EQEmu::versions::MobVersion PlayerProfileVersion() { return m_player_profile_version; }
|
||||
void SetPlayerProfileVersion(EQEmu::versions::MobVersion mob_version) { m_player_profile_version = EQEmu::versions::ValidateMobVersion(mob_version); }
|
||||
void SetPlayerProfileVersion(EQEmu::versions::ClientVersion client_version) { SetPlayerProfileVersion(EQEmu::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;
|
||||
EQEmu::versions::MobVersion m_player_profile_version;
|
||||
};
|
||||
|
||||
|
||||
@@ -1221,7 +1213,7 @@ struct WearChange_Struct {
|
||||
/*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;
|
||||
/*022*/ EQEmu::textures::Tint_Struct color;
|
||||
/*026*/ uint8 wear_slot_id;
|
||||
/*027*/
|
||||
};
|
||||
@@ -1366,24 +1358,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 +1383,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 +1762,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
|
||||
@@ -1793,17 +1780,6 @@ struct GMSummon_Struct {
|
||||
/*104*/ uint32 unknown2; // E0 E0 56 00
|
||||
};
|
||||
|
||||
struct GMFind_Struct {
|
||||
char charname[64];
|
||||
char gmname[64];
|
||||
uint32 success;
|
||||
uint32 zoneID;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
uint32 unknown2;
|
||||
};
|
||||
|
||||
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
|
||||
/* 0*/ char charname[64];
|
||||
|
||||
@@ -2140,36 +2116,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*/
|
||||
};
|
||||
|
||||
@@ -2199,23 +2175,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 {
|
||||
@@ -2335,12 +2310,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
|
||||
@@ -2559,10 +2531,7 @@ struct GMEmoteZone_Struct {
|
||||
struct BookText_Struct {
|
||||
uint8 window; // where to display the text (0xFF means new window)
|
||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||
int16 invslot; // Only used in SoF and later clients.
|
||||
int32 target_id;
|
||||
int8 can_cast;
|
||||
int8 can_scribe;
|
||||
uint32 invslot; // Only used in SoF and later clients.
|
||||
char booktext[1]; // Variable Length
|
||||
};
|
||||
// This is the request to read a book.
|
||||
@@ -2571,18 +2540,11 @@ struct BookText_Struct {
|
||||
struct BookRequest_Struct {
|
||||
uint8 window; // where to display the text (0xFF means new window)
|
||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||
int16 invslot; // Only used in Sof and later clients;
|
||||
int32 target_id;
|
||||
uint32 invslot; // Only used in Sof and later clients;
|
||||
int16 subslot; // The subslot inside of a bag if it is inside one.
|
||||
char txtfile[20];
|
||||
};
|
||||
|
||||
// used by Scribe and CastSpell book buttons
|
||||
struct BookButton_Struct
|
||||
{
|
||||
int16 invslot; // server slot
|
||||
int32 target_id;
|
||||
};
|
||||
|
||||
/*
|
||||
** Object/Ground Spawn struct
|
||||
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
||||
@@ -2794,7 +2756,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;
|
||||
@@ -3005,12 +2967,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];
|
||||
@@ -3282,7 +3238,7 @@ struct TraderClick_Struct{
|
||||
};
|
||||
|
||||
struct FormattedMessage_Struct{
|
||||
uint32 unknown0; // 1 means from world server
|
||||
uint32 unknown0;
|
||||
uint32 string_id;
|
||||
uint32 type;
|
||||
char message[0];
|
||||
@@ -3290,7 +3246,7 @@ struct FormattedMessage_Struct{
|
||||
struct SimpleMessage_Struct{
|
||||
uint32 string_id;
|
||||
uint32 color;
|
||||
uint32 unknown8; // 1 means from world server
|
||||
uint32 unknown8;
|
||||
};
|
||||
|
||||
struct GuildMemberUpdate_Struct {
|
||||
@@ -3527,8 +3483,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::invtype::TRIBUTE_SIZE]; //-1 == NONE
|
||||
uint32 tiers[EQEmu::invtype::TRIBUTE_SIZE]; //all 00's
|
||||
uint32 tribute_master_id;
|
||||
};
|
||||
|
||||
@@ -3653,19 +3609,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 {
|
||||
@@ -3754,66 +3705,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
|
||||
@@ -3906,7 +3808,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
|
||||
};
|
||||
@@ -4115,9 +4017,7 @@ struct UpdateLeadershipAA_Struct {
|
||||
|
||||
enum
|
||||
{
|
||||
GroupLeadershipAbility_MarkNPC = 0,
|
||||
RaidLeadershipAbility_MarkNPC = 16,
|
||||
RaidLeadershipAbility_MainAssist = 19
|
||||
GroupLeadershipAbility_MarkNPC = 0
|
||||
};
|
||||
|
||||
struct DoGroupLeadershipAbility_Struct
|
||||
@@ -4161,9 +4061,8 @@ struct InspectBuffs_Struct {
|
||||
struct RaidGeneral_Struct {
|
||||
/*00*/ uint32 action; //=10
|
||||
/*04*/ char player_name[64]; //should both be the player's name
|
||||
/*68*/ uint32 unknown1;
|
||||
/*72*/ char leader_name[64];
|
||||
/*136*/ uint32 parameter;
|
||||
/*64*/ char leader_name[64];
|
||||
/*132*/ uint32 parameter;
|
||||
};
|
||||
|
||||
struct RaidAddMember_Struct {
|
||||
@@ -4174,14 +4073,9 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidNote_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char note[64];
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general;
|
||||
/*140*/ char motd[1024];
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*136*/ char motd[0]; // max size is 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
@@ -4388,8 +4282,8 @@ struct AARankPrereq_Struct
|
||||
struct AARankEffect_Struct
|
||||
{
|
||||
int32 effect_id;
|
||||
int32 base_value;
|
||||
int32 limit_value;
|
||||
int32 base1;
|
||||
int32 base2;
|
||||
int32 slot;
|
||||
};
|
||||
|
||||
@@ -4397,8 +4291,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;
|
||||
};
|
||||
|
||||
@@ -4501,7 +4395,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[EQEmu::spells::SPELL_GEM_COUNT]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
|
||||
uint32 unknown; //there seems to be an extra field in this packet...
|
||||
};
|
||||
|
||||
@@ -4576,7 +4470,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*/
|
||||
};
|
||||
|
||||
@@ -4932,99 +4826,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
|
||||
@@ -5032,67 +4844,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
|
||||
@@ -5194,10 +4987,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;
|
||||
@@ -5542,24 +5335,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;
|
||||
bool attuned;
|
||||
std::string custom_data;
|
||||
uint32 ornamenticon {};
|
||||
uint32 ornamentidfile {};
|
||||
uint32 ornament_hero_model {};
|
||||
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:
|
||||
@@ -5631,28 +5418,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);
|
||||
|
||||
+13
-13
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
|
||||
}
|
||||
}
|
||||
|
||||
void EQStreamIdentifier::RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
|
||||
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
|
||||
auto p = new Patch;
|
||||
p->signature = sig;
|
||||
p->name = name;
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ void EQStreamIdentifier::Process() {
|
||||
}
|
||||
|
||||
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
|
||||
m_streams.emplace_back(Record(eqs));
|
||||
m_streams.push_back(Record(eqs));
|
||||
eqs = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
~EQStreamIdentifier();
|
||||
|
||||
//registration interface.
|
||||
void RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
|
||||
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
|
||||
|
||||
//main processing interface
|
||||
void Process();
|
||||
|
||||
@@ -30,7 +30,7 @@ struct EQStreamManagerInterfaceOptions
|
||||
|
||||
//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
|
||||
//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;
|
||||
@@ -100,8 +100,7 @@ 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 const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; }
|
||||
virtual Stats GetStats() const = 0;
|
||||
virtual void ResetStats() = 0;
|
||||
virtual EQStreamManagerInterface* GetManager() const = 0;
|
||||
|
||||
@@ -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();
|
||||
@@ -108,8 +112,3 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
|
||||
{
|
||||
return (*m_opcodes);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,21 +28,19 @@ 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;
|
||||
|
||||
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_*/
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
|
||||
EQDB EQDB::s_EQDB;
|
||||
|
||||
EQDB::EQDB() {
|
||||
}
|
||||
|
||||
unsigned int EQDB::field_count() {
|
||||
return mysql_field_count(mysql_ref);
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
//this is the main object exported to perl.
|
||||
class EQDB {
|
||||
EQDB() = default;
|
||||
EQDB();
|
||||
public:
|
||||
static EQDB *Singleton() { return(&s_EQDB); }
|
||||
|
||||
|
||||
+19
-52
@@ -19,7 +19,6 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "eqemu_config.h"
|
||||
#include "misc_functions.h"
|
||||
#include "strings.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -34,23 +33,17 @@ void EQEmuConfig::parse_config()
|
||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString());
|
||||
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 = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").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();
|
||||
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 {
|
||||
char str[32];
|
||||
@@ -63,61 +56,44 @@ void EQEmuConfig::parse_config()
|
||||
|
||||
auto loginconfig = new LoginConfig;
|
||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").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;
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
auto_database_updates = false;
|
||||
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
|
||||
auto_database_updates = true;
|
||||
}
|
||||
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").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();
|
||||
TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").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; }
|
||||
|
||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString());
|
||||
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"].get("disable_config_checks", "false").asString() == "true") {
|
||||
DisableConfigChecks = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* UCS
|
||||
*/
|
||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
|
||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
|
||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
/**
|
||||
* Database
|
||||
@@ -125,23 +101,14 @@ void EQEmuConfig::parse_config()
|
||||
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 = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").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 = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString());
|
||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||
|
||||
/**
|
||||
* QS
|
||||
*/
|
||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").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();
|
||||
@@ -149,9 +116,9 @@ void EQEmuConfig::parse_config()
|
||||
/**
|
||||
* Zones
|
||||
*/
|
||||
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString());
|
||||
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString());
|
||||
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString());
|
||||
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());
|
||||
|
||||
/**
|
||||
* Files
|
||||
@@ -181,11 +148,11 @@ void EQEmuConfig::parse_config()
|
||||
/**
|
||||
* Launcher
|
||||
*/
|
||||
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString());
|
||||
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString());
|
||||
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString());
|
||||
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString());
|
||||
#ifdef WIN32
|
||||
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();
|
||||
#else
|
||||
ZoneExe = _root["server"]["launcher"].get("exe", "./zone").asString();
|
||||
|
||||
+14
-28
@@ -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;
|
||||
@@ -120,8 +110,6 @@ class EQEmuConfig
|
||||
uint16 ZonePortHigh;
|
||||
uint8 DefaultStatus;
|
||||
|
||||
bool auto_database_updates;
|
||||
|
||||
// uint16 DynamicCount;
|
||||
|
||||
// map<string,uint16> StaticZones;
|
||||
@@ -135,7 +123,7 @@ class EQEmuConfig
|
||||
void parse_config();
|
||||
|
||||
EQEmuConfig()
|
||||
{
|
||||
{
|
||||
|
||||
}
|
||||
virtual ~EQEmuConfig() {}
|
||||
@@ -149,39 +137,37 @@ class EQEmuConfig
|
||||
return (_config);
|
||||
}
|
||||
|
||||
// Allow the use to set the conf file to be used.
|
||||
static void SetConfigFile(std::string file)
|
||||
{
|
||||
EQEmuConfig::ConfigFile = file;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
+260
-571
File diff suppressed because it is too large
Load Diff
+94
-252
@@ -23,23 +23,15 @@
|
||||
|
||||
#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 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -53,7 +45,7 @@ namespace Logs {
|
||||
AI,
|
||||
Aggro,
|
||||
Attack,
|
||||
DeprecatedCS, // deprecated
|
||||
Client_Server_Packet,
|
||||
Combat,
|
||||
Commands,
|
||||
Crash,
|
||||
@@ -64,94 +56,56 @@ namespace Logs {
|
||||
Inventory,
|
||||
Launcher,
|
||||
Netcode,
|
||||
Normal, // deprecated
|
||||
Normal,
|
||||
Object,
|
||||
Pathing,
|
||||
QSServer, // deprecated
|
||||
QS_Server,
|
||||
Quests,
|
||||
Rules,
|
||||
Skills,
|
||||
Spawns,
|
||||
Spells,
|
||||
Status, // deprecated
|
||||
TCPConnection,
|
||||
Status,
|
||||
TCP_Connection,
|
||||
Tasks,
|
||||
Tradeskills,
|
||||
Trading,
|
||||
Tribute,
|
||||
UCSServer, // deprecated
|
||||
WebInterfaceServer, // deprecated
|
||||
WorldServer, // deprecated
|
||||
ZoneServer, // deprecated
|
||||
UCS_Server,
|
||||
WebInterface_Server,
|
||||
World_Server,
|
||||
Zone_Server,
|
||||
MySQLError,
|
||||
MySQLQuery,
|
||||
Mercenaries,
|
||||
QuestDebug,
|
||||
DeprecatedSC, // deprecated
|
||||
DeprecatedCSU, // deprecated
|
||||
DeprecatedSCD, // deprecated
|
||||
DeprecatedCSD, // deprecated
|
||||
Loginserver, // deprecated
|
||||
ClientLogin,
|
||||
HeadlessClient, // deprecated
|
||||
HPUpdate,
|
||||
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,
|
||||
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,
|
||||
DataBuckets,
|
||||
Zoning,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
/**
|
||||
* If you add to this, make sure you update LogCategory
|
||||
*/
|
||||
static const char *LogCategoryName[LogCategory::MaxCategoryID] = {
|
||||
static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
|
||||
"",
|
||||
"AA",
|
||||
"AI",
|
||||
"Aggro",
|
||||
"Attack",
|
||||
"Deprecated",
|
||||
"Packet :: Client -> Server",
|
||||
"Combat",
|
||||
"Commands",
|
||||
"Crash",
|
||||
@@ -162,89 +116,55 @@ namespace Logs {
|
||||
"Inventory",
|
||||
"Launcher",
|
||||
"Netcode",
|
||||
"Normal (Deprecated)",
|
||||
"Normal",
|
||||
"Object",
|
||||
"Pathing",
|
||||
"QS Server (Deprecated)",
|
||||
"QS Server",
|
||||
"Quests",
|
||||
"Rules",
|
||||
"Skills",
|
||||
"Spawns",
|
||||
"Spells",
|
||||
"Status (Deprecated)",
|
||||
"Status",
|
||||
"TCP Connection",
|
||||
"Tasks",
|
||||
"Tradeskills",
|
||||
"Trading",
|
||||
"Tribute",
|
||||
"UCS Server (Deprecated)",
|
||||
"Web Interface (Deprecated)",
|
||||
"World Server (Deprecated)",
|
||||
"Zone Server (Deprecated)",
|
||||
"QueryErr",
|
||||
"Query",
|
||||
"UCS Server",
|
||||
"WebInterface Server",
|
||||
"World Server",
|
||||
"Zone Server",
|
||||
"MySQL Error",
|
||||
"MySQL Query",
|
||||
"Mercenaries",
|
||||
"Quest Debug",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Legacy Packet Logging (Deprecated)",
|
||||
"Login Server (Deprecated)",
|
||||
"Packet :: Server -> Client",
|
||||
"Packet :: Client -> Server Unhandled",
|
||||
"Packet :: Server -> Client (Dump)",
|
||||
"Packet :: Client -> Server (Dump)",
|
||||
"Login Server",
|
||||
"Client Login",
|
||||
"Headless Client (Deprecated)",
|
||||
"Headless Client",
|
||||
"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",
|
||||
"DataBuckets",
|
||||
"Zoning",
|
||||
"Mob Appearance"
|
||||
};
|
||||
}
|
||||
|
||||
#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)\
|
||||
OutF(LogSys, debug_level, log_category, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
class EQEmuLogSys {
|
||||
public:
|
||||
@@ -256,12 +176,7 @@ public:
|
||||
* This should be handled on deconstructor but to be safe we use it anyways.
|
||||
*/
|
||||
void CloseFileLogs();
|
||||
EQEmuLogSys *LoadLogSettingsDefaults();
|
||||
EQEmuLogSys *LoadLogDatabaseSettings();
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void LoadLogSettingsDefaults();
|
||||
void MakeDirectory(const std::string &directory_name);
|
||||
|
||||
/**
|
||||
@@ -273,25 +188,12 @@ public:
|
||||
* - 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, ...);
|
||||
|
||||
/**
|
||||
* Used in file logs to prepend a timestamp entry for logs
|
||||
* @param time_stamp
|
||||
*/
|
||||
void SetCurrentTimeStamp(char *time_stamp);
|
||||
|
||||
/**
|
||||
* @param log_name
|
||||
*/
|
||||
void SetCurrentTimeStamp(char* time_stamp);
|
||||
void StartFileLogs(const std::string &log_name = "");
|
||||
|
||||
/**
|
||||
@@ -308,129 +210,69 @@ public:
|
||||
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();
|
||||
* Database loaded via Database::LoadLogSettings(log_settings)
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID];
|
||||
|
||||
// temporary bucket to re-load after silencing
|
||||
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
bool file_logs_enabled;
|
||||
|
||||
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;
|
||||
};
|
||||
/**
|
||||
* Sets Executable platform (Zone/World/UCS) etc.
|
||||
*/
|
||||
int log_platform;
|
||||
|
||||
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
/**
|
||||
* File name used in writing logs
|
||||
*/
|
||||
std::string platform_file_name;
|
||||
|
||||
struct DiscordWebhooks {
|
||||
int id;
|
||||
std::string webhook_name;
|
||||
std::string webhook_url;
|
||||
};
|
||||
|
||||
const DiscordWebhooks *GetDiscordWebhooks() const;
|
||||
|
||||
// gmsay
|
||||
/**
|
||||
* GMSay Client Message colors mapped by category
|
||||
*
|
||||
* @param log_category
|
||||
* @return
|
||||
*/
|
||||
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 DisableMySQLErrorLogs();
|
||||
void EnableMySQLErrorLogs();
|
||||
void SetGMSayHandler(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
|
||||
void SetConsoleHandler(std::function<void(uint16 debug_level, uint16 log_type, const std::string&)> f) { on_log_console_hook = f; }
|
||||
|
||||
private:
|
||||
|
||||
// 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;
|
||||
/**
|
||||
* Callback pointer to zone process for hooking logs to zone using GMSay
|
||||
*/
|
||||
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook;
|
||||
std::function<void(uint16 debug_level, uint16 log_category, const std::string&)> on_log_console_hook;
|
||||
|
||||
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();
|
||||
/**
|
||||
* Formats log messages like '[Category] This is a log message'
|
||||
*/
|
||||
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
|
||||
|
||||
/**
|
||||
* Linux console color messages mapped by category
|
||||
* @param log_category
|
||||
* @return
|
||||
*/
|
||||
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
|
||||
|
||||
/**
|
||||
* Windows console color messages mapped by category
|
||||
*/
|
||||
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||
|
||||
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||
};
|
||||
|
||||
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,6 +1,6 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
* 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
|
||||
@@ -16,20 +16,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef WORLD_EXPEDITION_DATABASE_H
|
||||
#define WORLD_EXPEDITION_DATABASE_H
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <fmt/format.h>
|
||||
|
||||
class Expedition;
|
||||
|
||||
namespace ExpeditionDatabase
|
||||
template <typename... Args>
|
||||
void OutF(EQEmuLogSys &ls, Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args)
|
||||
{
|
||||
void PurgeExpiredExpeditions();
|
||||
void PurgeExpiredCharacterLockouts();
|
||||
};
|
||||
|
||||
#endif
|
||||
std::string log_str = fmt::format(fmt, args...);
|
||||
ls.Out(debug_level, log_category, log_str);
|
||||
}
|
||||
@@ -1,828 +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 LogDataBuckets(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::DataBuckets))\
|
||||
OutF(LogSys, Logs::General, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDataBucketsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DataBuckets))\
|
||||
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoning(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::General, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoningDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Zoning, __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
|
||||
+5
-23
@@ -58,6 +58,10 @@ EQTime::EQTime()
|
||||
SetCurrentEQTimeOfDay(start, time(0));
|
||||
}
|
||||
|
||||
EQTime::~EQTime()
|
||||
{
|
||||
}
|
||||
|
||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
||||
//This function was written by the ShowEQ Project.
|
||||
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
|
||||
@@ -199,26 +203,4 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
||||
t->month, t->day, t->year, t->hour, t->minute);
|
||||
buf[127] = '\0';
|
||||
str = buf;
|
||||
}
|
||||
|
||||
bool EQTime::IsDayTime() {
|
||||
TimeOfDay_Struct tod; //Day time is 5am to 6:59pm (14 hours in-game)
|
||||
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||
|
||||
if (tod.hour >= 5 || tod.hour < 19) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQTime::IsNightTime() {
|
||||
TimeOfDay_Struct tod; //Night time is 7pm to 4:59am (10 hours in-game)
|
||||
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
|
||||
|
||||
if (tod.hour >= 19 || tod.hour < 5) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -18,7 +18,7 @@ public:
|
||||
//Constructor/destructor
|
||||
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
|
||||
EQTime();
|
||||
~EQTime() = default;
|
||||
~EQTime();
|
||||
|
||||
//Get functions
|
||||
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
||||
@@ -28,8 +28,6 @@ public:
|
||||
uint32 getEQTimeZone() { return timezone; }
|
||||
uint32 getEQTimeZoneHr() { return timezone/60; }
|
||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||
bool IsDayTime();
|
||||
bool IsNightTime();
|
||||
|
||||
//Set functions
|
||||
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
||||
|
||||
+12
-20
@@ -8,38 +8,30 @@ namespace EQ
|
||||
class EventLoop
|
||||
{
|
||||
public:
|
||||
static EventLoop &Get() {
|
||||
static thread_local EventLoop inst;
|
||||
return inst;
|
||||
EventLoop() {
|
||||
memset(&m_loop, 0, sizeof(uv_loop_t));
|
||||
uv_loop_init(&m_loop);
|
||||
}
|
||||
|
||||
~EventLoop() {
|
||||
uv_loop_close(&m_loop);
|
||||
}
|
||||
|
||||
EventLoop(const EventLoop&) = delete;
|
||||
EventLoop& operator=(const EventLoop&) = delete;
|
||||
|
||||
static EventLoop &GetDefault() {
|
||||
static thread_local EventLoop inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
void Process() {
|
||||
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:
|
||||
EventLoop() {
|
||||
memset(&m_loop, 0, sizeof(uv_loop_t));
|
||||
uv_loop_init(&m_loop);
|
||||
}
|
||||
|
||||
EventLoop(const EventLoop&);
|
||||
EventLoop& operator=(const EventLoop&);
|
||||
|
||||
private:
|
||||
uv_loop_t m_loop;
|
||||
};
|
||||
}
|
||||
|
||||
+26
-21
@@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <exception>
|
||||
#include "event_loop.h"
|
||||
#include "../any.h"
|
||||
|
||||
namespace EQ {
|
||||
class Task
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(const std::any&)> ResolveFn;
|
||||
typedef std::function<void(const EQEmu::Any&)> ResolveFn;
|
||||
typedef std::function<void(const std::exception&)> RejectFn;
|
||||
typedef std::function<void()> FinallyFn;
|
||||
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
|
||||
@@ -19,13 +19,17 @@ namespace EQ {
|
||||
RejectFn on_catch;
|
||||
FinallyFn on_finally;
|
||||
bool has_result;
|
||||
std::any result;
|
||||
EQEmu::Any result;
|
||||
bool has_error;
|
||||
std::exception error;
|
||||
};
|
||||
|
||||
Task(TaskFn fn) {
|
||||
m_fn = fn;
|
||||
Task(EventLoop &loop, TaskFn fn) : _loop(loop) {
|
||||
_fn = fn;
|
||||
}
|
||||
|
||||
Task(TaskFn fn) : _loop(EventLoop::GetDefault()) {
|
||||
_fn = fn;
|
||||
}
|
||||
|
||||
~Task() {
|
||||
@@ -33,37 +37,37 @@ namespace EQ {
|
||||
}
|
||||
|
||||
Task& Then(ResolveFn fn) {
|
||||
m_then = fn;
|
||||
_then = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Task& Catch(RejectFn fn) {
|
||||
m_catch = fn;
|
||||
_catch = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Task& Finally(FinallyFn fn) {
|
||||
m_finally = fn;
|
||||
_fin = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Run() {
|
||||
uv_work_t *m_work = new uv_work_t;
|
||||
memset(m_work, 0, sizeof(uv_work_t));
|
||||
uv_work_t *work = new uv_work_t;
|
||||
memset(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->fn = _fn;
|
||||
baton->on_then = _then;
|
||||
baton->on_catch = _catch;
|
||||
baton->on_finally = _fin;
|
||||
baton->has_result = false;
|
||||
baton->has_error = false;
|
||||
|
||||
m_work->data = baton;
|
||||
work->data = baton;
|
||||
|
||||
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
||||
uv_queue_work(_loop.Handle(), work, [](uv_work_t* req) {
|
||||
TaskBaton *baton = (TaskBaton*)req->data;
|
||||
|
||||
baton->fn([baton](const std::any& result) {
|
||||
baton->fn([baton](const EQEmu::Any& result) {
|
||||
baton->has_error = false;
|
||||
baton->has_result = true;
|
||||
baton->result = result;
|
||||
@@ -92,9 +96,10 @@ namespace EQ {
|
||||
}
|
||||
|
||||
private:
|
||||
TaskFn m_fn;
|
||||
ResolveFn m_then;
|
||||
RejectFn m_catch;
|
||||
FinallyFn m_finally;
|
||||
TaskFn _fn;
|
||||
ResolveFn _then;
|
||||
RejectFn _catch;
|
||||
FinallyFn _fin;
|
||||
EventLoop &_loop;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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.emplace_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;
|
||||
};
|
||||
}
|
||||
}
|
||||
+35
-21
@@ -6,16 +6,29 @@ namespace EQ {
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
Timer(std::function<void(Timer *)> cb)
|
||||
Timer(EventLoop &loop, std::function<void(Timer *)> cb) : _loop(loop)
|
||||
{
|
||||
m_timer = nullptr;
|
||||
m_cb = cb;
|
||||
_timer = nullptr;
|
||||
_cb = cb;
|
||||
}
|
||||
|
||||
Timer(uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb)
|
||||
Timer(EventLoop &loop, uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb) : _loop(loop)
|
||||
{
|
||||
m_timer = nullptr;
|
||||
m_cb = cb;
|
||||
_timer = nullptr;
|
||||
_cb = cb;
|
||||
Start(duration_ms, repeats);
|
||||
}
|
||||
|
||||
Timer(std::function<void(Timer *)> cb) : _loop(EventLoop::GetDefault())
|
||||
{
|
||||
_timer = nullptr;
|
||||
_cb = cb;
|
||||
}
|
||||
|
||||
Timer(uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb) : _loop(EventLoop::GetDefault())
|
||||
{
|
||||
_timer = nullptr;
|
||||
_cb = cb;
|
||||
Start(duration_ms, repeats);
|
||||
}
|
||||
|
||||
@@ -25,21 +38,21 @@ namespace EQ {
|
||||
}
|
||||
|
||||
void Start(uint64_t duration_ms, bool repeats) {
|
||||
auto loop = EventLoop::Get().Handle();
|
||||
if (!m_timer) {
|
||||
m_timer = new uv_timer_t;
|
||||
memset(m_timer, 0, sizeof(uv_timer_t));
|
||||
uv_timer_init(loop, m_timer);
|
||||
m_timer->data = this;
|
||||
auto loop = EventLoop::GetDefault().Handle();
|
||||
if (!_timer) {
|
||||
_timer = new uv_timer_t;
|
||||
memset(_timer, 0, sizeof(uv_timer_t));
|
||||
uv_timer_init(loop, _timer);
|
||||
_timer->data = this;
|
||||
|
||||
if (repeats) {
|
||||
uv_timer_start(m_timer, [](uv_timer_t *handle) {
|
||||
uv_timer_start(_timer, [](uv_timer_t *handle) {
|
||||
Timer *t = (Timer*)handle->data;
|
||||
t->Execute();
|
||||
}, duration_ms, duration_ms);
|
||||
}
|
||||
else {
|
||||
uv_timer_start(m_timer, [](uv_timer_t *handle) {
|
||||
uv_timer_start(_timer, [](uv_timer_t *handle) {
|
||||
Timer *t = (Timer*)handle->data;
|
||||
t->Stop();
|
||||
t->Execute();
|
||||
@@ -49,19 +62,20 @@ namespace EQ {
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
if (m_timer) {
|
||||
uv_close((uv_handle_t*)m_timer, [](uv_handle_t* handle) {
|
||||
delete (uv_timer_t *)handle;
|
||||
if (_timer) {
|
||||
uv_close((uv_handle_t*)_timer, [](uv_handle_t* handle) {
|
||||
delete handle;
|
||||
});
|
||||
m_timer = nullptr;
|
||||
_timer = nullptr;
|
||||
}
|
||||
}
|
||||
private:
|
||||
void Execute() {
|
||||
m_cb(this);
|
||||
_cb(this);
|
||||
}
|
||||
|
||||
uv_timer_t *m_timer;
|
||||
std::function<void(Timer*)> m_cb;
|
||||
EventLoop &_loop;
|
||||
uv_timer_t *_timer;
|
||||
std::function<void(Timer*)> _cb;
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user