mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 09:06:46 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b7eeb3b2f9 | |||
| d2f8eead1f |
@@ -0,0 +1,21 @@
|
|||||||
|
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.101.1/containers/ubuntu-18.04-git
|
||||||
|
{
|
||||||
|
"name": "Ubuntu 18.04 EQEMU",
|
||||||
|
// Moved from dockerfile to image so it builds faster
|
||||||
|
"image": "eqemu/devcontainer:0.0.2",
|
||||||
|
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.shell.linux": "/bin/bash"
|
||||||
|
},
|
||||||
|
|
||||||
|
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
|
||||||
|
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": ["ms-vscode.cpptools", "ms-azuretools.vscode-docker"],
|
||||||
|
"mounts": ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"],
|
||||||
|
"remoteEnv": {
|
||||||
|
"HOST_PROJECT_PATH": "${localWorkspaceFolder}"
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-88
@@ -1,98 +1,16 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: Build Linux
|
name: EQEmulator Server Linux CI
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||||
concurrency:
|
concurrency:
|
||||||
limit: 1
|
limit: 1
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
host:
|
|
||||||
path: /var/lib/cache-release
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Build Linux X64
|
- name: server-build
|
||||||
image: akkadius/eqemu-server:v14
|
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
|
||||||
environment:
|
image: akkadius/eqemu-server:latest
|
||||||
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:
|
commands:
|
||||||
- ./utils/scripts/build/linux-build.sh
|
- sudo chown eqemu:eqemu /drone/src/ * -R
|
||||||
volumes:
|
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_BOTS=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
-17
@@ -54,20 +54,3 @@ bin/
|
|||||||
/Win32
|
/Win32
|
||||||
/x64
|
/x64
|
||||||
/client_files/**/CMakeFiles/
|
/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/*
|
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
language: cpp
|
||||||
|
compiler: gcc
|
||||||
|
dist: bionic
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libmysqlclient-dev
|
||||||
|
- libperl-dev
|
||||||
|
- libboost-dev
|
||||||
|
- liblua5.1-0-dev
|
||||||
|
- zlib1g-dev
|
||||||
|
- uuid-dev
|
||||||
|
- libssl-dev
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
||||||
|
- make -j2
|
||||||
|
- ./bin/tests
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/usr/include/mysql"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++17"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
Vendored
+164
@@ -0,0 +1,164 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "make",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cd bin && make",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "make clean",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cd bin && make clean",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "cmake",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p bin && cd bin && rm CMakeCache.txt && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' ..",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher":{
|
||||||
|
"owner": "cpp",
|
||||||
|
"fileLocation": "relative",
|
||||||
|
"pattern":[
|
||||||
|
{
|
||||||
|
"regexp": "([\\w+|\\\\]*\\.\\w+)\\((\\d+)\\)\\: (warning|error) (.*)$",
|
||||||
|
"file": 1,
|
||||||
|
"location": 2,
|
||||||
|
"severity": 3,
|
||||||
|
"message": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "download maps",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p bin && cd bin && wget https://codeload.github.com/Akkadius/EQEmuMaps/zip/master -O maps.zip && unzip -o maps.zip && rm ./maps -rf && mv EQEmuMaps-master maps && rm maps.zip",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "download quests",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p bin && cd bin && cd server && git -C ./quests pull 2> /dev/null || git clone https://github.com/ProjectEQ/projecteqquests.git quests",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "download eqemu_config",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p bin && cd bin && wget --no-check-certificate https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/eqemu_config_docker.json -O eqemu_config.json",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "rebuild database (mariadb must be started)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p bin && cd bin && docker run -i --rm --privileged -v ${HOST_PROJECT_PATH}/bin:/src --network=eqemu -it eqemu/server:0.0.3 bash -c './eqemu_server.pl source_peq_db && ./eqemu_server.pl check_db_updates && ./eqemu_server.pl linux_login_server_setup'",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "zone 7000",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop zone7000 | true && docker network create eqemu | true && docker run -i --rm --name zone7000 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu -p 7000:7000/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7000:7000",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "zone 7001",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop zone7001 | true && docker network create eqemu | true && docker run -i --rm --name zone7001 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu -p 7001:7001/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7001:7001",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "loginserver",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop loginserver | true && docker network create eqemu | true && docker run -i --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 --network=eqemu --name loginserver -p 5999:5999/udp -p 5998:5998/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./loginserver",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "shared_memory, world",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop sharedmemory | true && docker stop world | true && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --network=eqemu --name sharedmemory eqemu/server:0.0.3 ./shared_memory && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name world -p 9000:9000 -p 9000:9000/udp -p 9001:9001 -p 9080:9080 eqemu/server:0.0.3 gdb -ex run ./world",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "queryserv",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop queryserv | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name queryserv eqemu/server:0.0.3 gdb -ex run ./queryserv",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "mariadb",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop mariadb | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin/db:/bitnami/mariadb -p 3306:3306 -e MARIADB_DATABASE=peq -e MARIADB_USER=eqemu -e MARIADB_PASSWORD=eqemupass -e ALLOW_EMPTY_PASSWORD=yes --name mariadb --network=eqemu bitnami/mariadb:latest",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "ucs",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop ucs | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/bin:/src -p 7778:7778 --name ucs --network=eqemu eqemu/server:0.0.3 gdb -ex run ./ucs",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -40,14 +40,14 @@ Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extra
|
|||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd 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" ..
|
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
|
||||||
|
|
||||||
##### Linux
|
##### Linux
|
||||||
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
|
|||||||
-2654
File diff suppressed because it is too large
Load Diff
+13
-88
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
@@ -12,37 +12,16 @@ IF(NOT CMAKE_BUILD_TYPE)
|
|||||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
||||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||||
|
|
||||||
SET(CMAKE_CXX_STANDARD 20)
|
SET(CMAKE_CXX_STANDARD 14)
|
||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
|
||||||
OPTION(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON)
|
|
||||||
|
|
||||||
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)
|
IF(MSVC)
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
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)
|
ELSE(MSVC)
|
||||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
@@ -139,16 +118,11 @@ ELSE()
|
|||||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
||||||
ENDIF()
|
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 "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
|
|
||||||
#options
|
#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_COMMANDS_LOGGING "Enable GM Command logs" ON)
|
||||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
||||||
@@ -157,51 +131,14 @@ OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
|||||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
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)
|
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)
|
IF(EQEMU_COMMANDS_LOGGING)
|
||||||
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
||||||
ENDIF(EQEMU_COMMANDS_LOGGING)
|
ENDIF(EQEMU_COMMANDS_LOGGING)
|
||||||
|
|
||||||
|
IF(EQEMU_ENABLE_BOTS)
|
||||||
|
ADD_DEFINITIONS(-DBOTS)
|
||||||
|
ENDIF(EQEMU_ENABLE_BOTS)
|
||||||
|
|
||||||
#database
|
#database
|
||||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
IF(MySQL_FOUND AND MariaDB_FOUND)
|
||||||
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
|
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
|
||||||
@@ -246,9 +183,6 @@ IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
|
|||||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
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")
|
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
|
||||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
SET(TLS_LIBRARY_ENABLED ON)
|
||||||
@@ -264,9 +198,6 @@ ELSEIF(OpenSSL_FOUND)
|
|||||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
||||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
||||||
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
|
|
||||||
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(MBEDTLS_FOUND)
|
ELSEIF(MBEDTLS_FOUND)
|
||||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
SET(TLS_LIBRARY_ENABLED ON)
|
||||||
@@ -333,10 +264,6 @@ ELSE()
|
|||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (EQEMU_BUILD_STATIC)
|
|
||||||
SET(ZLIB_LIBRARY_LIBS libz.a)
|
|
||||||
ENDIF(EQEMU_BUILD_STATIC)
|
|
||||||
|
|
||||||
MESSAGE(STATUS "")
|
MESSAGE(STATUS "")
|
||||||
MESSAGE(STATUS "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
MESSAGE(STATUS "* Library Usage *")
|
MESSAGE(STATUS "* Library Usage *")
|
||||||
@@ -366,8 +293,10 @@ 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/recastnavigation/Recast/Include")
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
||||||
|
|
||||||
# silence obnoxious deprecation message
|
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
|
||||||
ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
|
IF(EQEMU_BUILD_LOGGING)
|
||||||
|
ADD_DEFINITIONS(-DBUILD_LOGGING)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(TLS_LIBRARY_ENABLED)
|
IF(TLS_LIBRARY_ENABLED)
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
||||||
@@ -397,14 +326,10 @@ ENDIF()
|
|||||||
IF(PERL_LIBRARY_ENABLED)
|
IF(PERL_LIBRARY_ENABLED)
|
||||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||||
IF(EQEMU_BUILD_PERL)
|
IF(EQEMU_BUILD_PERL)
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
|
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||||
ADD_DEFINITIONS(-DEMBPERL)
|
ADD_DEFINITIONS(-DEMBPERL)
|
||||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
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()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# EQEmulator Core Server
|
# EQEmulator Core Server
|
||||||
| Drone (Linux x64) | Drone (Windows x64) |
|
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
||||||
|:---:|:---:|
|
|:---:|:---:|:---:|
|
||||||
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -18,11 +18,11 @@
|
|||||||
|**Install Count**|||
|
|**Install Count**|||
|
||||||
### > Windows
|
### > Windows
|
||||||
|
|
||||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
|
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-windows)
|
||||||
|
|
||||||
### > Debian/Ubuntu/CentOS/Fedora
|
### > Debian/Ubuntu/CentOS/Fedora
|
||||||
|
|
||||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
|
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-linux)
|
||||||
|
|
||||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
* 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
|
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
||||||
@@ -56,7 +56,7 @@ forum, although pull requests will be much quicker and easier on all parties.
|
|||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
||||||
- [EQEmulator Wiki](https://docs.eqemu.io/)
|
- [EQEmulator Wiki](https://eqemu.gitbook.io/)
|
||||||
|
|
||||||
## Related Repositories
|
## Related Repositories
|
||||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
||||||
|
|||||||
@@ -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 C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||||
|
|
||||||
|
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 C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||||
|
|
||||||
|
appveyor PushArtifact build_x64-no-bots.zip
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
############################################
|
############################################
|
||||||
#
|
#
|
||||||
# New changelog can be found here
|
# New changelog can be found here
|
||||||
# https://docs.eqemu.io/server/changelog/server
|
# https://eqemu.gitbook.io/changelog/
|
||||||
#
|
#
|
||||||
############################################
|
############################################
|
||||||
# Deprecated
|
# Deprecated
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
add_subdirectory(import)
|
add_subdirectory(import)
|
||||||
add_subdirectory(export)
|
add_subdirectory(export)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(export_sources
|
SET(export_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|||||||
@@ -25,15 +25,11 @@
|
|||||||
#include "../../common/platform.h"
|
#include "../../common/platform.h"
|
||||||
#include "../../common/crash.h"
|
#include "../../common/crash.h"
|
||||||
#include "../../common/rulesys.h"
|
#include "../../common/rulesys.h"
|
||||||
#include "../../common/strings.h"
|
#include "../../common/string_util.h"
|
||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
|
||||||
#include "../../common/path_manager.h"
|
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
|
||||||
PathManager path;
|
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase *db);
|
void ExportSpells(SharedDatabase *db);
|
||||||
void ExportSkillCaps(SharedDatabase *db);
|
void ExportSkillCaps(SharedDatabase *db);
|
||||||
@@ -46,8 +42,6 @@ int main(int argc, char **argv)
|
|||||||
LogSys.LoadLogSettingsDefaults();
|
LogSys.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
path.LoadPaths();
|
|
||||||
|
|
||||||
LogInfo("Client Files Export Utility");
|
LogInfo("Client Files Export Utility");
|
||||||
if (!EQEmuConfig::LoadConfig()) {
|
if (!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Unable to load configuration file");
|
LogError("Unable to load configuration file");
|
||||||
@@ -86,13 +80,11 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMysql(database.getMySQL());
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
database.LoadLogSettings(LogSys.log_settings);
|
||||||
->SetLogPath(path.GetLogPath())
|
LogSys.StartFileLogs();
|
||||||
->LoadLogDatabaseSettings()
|
|
||||||
->StartFileLogs();
|
|
||||||
|
|
||||||
std::string arg_1;
|
std::string arg_1;
|
||||||
|
|
||||||
@@ -131,8 +123,7 @@ void ExportSpells(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting Spells");
|
LogInfo("Exporting Spells");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
FILE *f = fopen("export/spells_us.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@@ -183,7 +174,7 @@ bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
if (row[0] && atoi(row[0]) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,15 +198,14 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase *db)
|
void ExportSkillCaps(SharedDatabase *db)
|
||||||
{
|
{
|
||||||
LogInfo("Exporting Skill Caps");
|
LogInfo("Exporting Skill Caps");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@@ -245,8 +235,7 @@ void ExportBaseData(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting Base Data");
|
LogInfo("Exporting Base Data");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
FILE *f = fopen("export/BaseData.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@@ -279,8 +268,7 @@ void ExportDBStrings(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting DB Strings");
|
LogInfo("Exporting DB Strings");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(import_sources
|
SET(import_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|||||||
@@ -23,15 +23,11 @@
|
|||||||
#include "../../common/platform.h"
|
#include "../../common/platform.h"
|
||||||
#include "../../common/crash.h"
|
#include "../../common/crash.h"
|
||||||
#include "../../common/rulesys.h"
|
#include "../../common/rulesys.h"
|
||||||
#include "../../common/strings.h"
|
#include "../../common/string_util.h"
|
||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
|
||||||
#include "../../common/path_manager.h"
|
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
|
||||||
PathManager path;
|
|
||||||
|
|
||||||
void ImportSpells(SharedDatabase *db);
|
void ImportSpells(SharedDatabase *db);
|
||||||
void ImportSkillCaps(SharedDatabase *db);
|
void ImportSkillCaps(SharedDatabase *db);
|
||||||
@@ -43,8 +39,6 @@ int main(int argc, char **argv) {
|
|||||||
LogSys.LoadLogSettingsDefaults();
|
LogSys.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
path.LoadPaths();
|
|
||||||
|
|
||||||
LogInfo("Client Files Import Utility");
|
LogInfo("Client Files Import Utility");
|
||||||
if(!EQEmuConfig::LoadConfig()) {
|
if(!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Unable to load configuration file.");
|
LogError("Unable to load configuration file.");
|
||||||
@@ -83,13 +77,11 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMysql(database.getMySQL());
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
database.LoadLogSettings(LogSys.log_settings);
|
||||||
->SetLogPath(path.GetLogPath())
|
LogSys.StartFileLogs();
|
||||||
->LoadLogDatabaseSettings()
|
|
||||||
->StartFileLogs();
|
|
||||||
|
|
||||||
ImportSpells(&content_db);
|
ImportSpells(&content_db);
|
||||||
ImportSkillCaps(&content_db);
|
ImportSkillCaps(&content_db);
|
||||||
@@ -132,10 +124,9 @@ bool IsStringField(int i) {
|
|||||||
|
|
||||||
void ImportSpells(SharedDatabase *db) {
|
void ImportSpells(SharedDatabase *db) {
|
||||||
LogInfo("Importing Spells");
|
LogInfo("Importing Spells");
|
||||||
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
|
FILE *f = fopen("import/spells_us.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/spells_us.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,8 +145,8 @@ void ImportSpells(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string escaped = ::Strings::Escape(buffer);
|
std::string escaped = ::EscapeString(buffer);
|
||||||
auto split = Strings::Split(escaped, '^');
|
auto split = SplitString(escaped, '^');
|
||||||
int line_columns = (int)split.size();
|
int line_columns = (int)split.size();
|
||||||
|
|
||||||
std::string sql;
|
std::string sql;
|
||||||
@@ -222,10 +213,9 @@ void ImportSpells(SharedDatabase *db) {
|
|||||||
void ImportSkillCaps(SharedDatabase *db) {
|
void ImportSkillCaps(SharedDatabase *db) {
|
||||||
LogInfo("Importing Skill Caps");
|
LogInfo("Importing Skill Caps");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
|
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,17 +224,17 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
while(fgets(buffer, 2048, f)) {
|
while(fgets(buffer, 2048, f)) {
|
||||||
auto split = Strings::Split(buffer, '^');
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
if(split.size() < 4) {
|
if(split.size() < 4) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int class_id, skill_id, level, cap;
|
int class_id, skill_id, level, cap;
|
||||||
class_id = Strings::ToInt(split[0].c_str());
|
class_id = atoi(split[0].c_str());
|
||||||
skill_id = Strings::ToInt(split[1].c_str());
|
skill_id = atoi(split[1].c_str());
|
||||||
level = Strings::ToInt(split[2].c_str());
|
level = atoi(split[2].c_str());
|
||||||
cap = Strings::ToInt(split[3].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)",
|
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
||||||
class_id, skill_id, level, cap);
|
class_id, skill_id, level, cap);
|
||||||
@@ -258,10 +248,9 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
void ImportBaseData(SharedDatabase *db) {
|
void ImportBaseData(SharedDatabase *db) {
|
||||||
LogInfo("Importing Base Data");
|
LogInfo("Importing Base Data");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
FILE *f = fopen("import/BaseData.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/BaseData.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +259,7 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
while(fgets(buffer, 2048, f)) {
|
while(fgets(buffer, 2048, f)) {
|
||||||
auto split = Strings::Split(buffer, '^');
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
if(split.size() < 10) {
|
if(split.size() < 10) {
|
||||||
continue;
|
continue;
|
||||||
@@ -280,16 +269,16 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
int level, class_id;
|
int level, class_id;
|
||||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
||||||
|
|
||||||
level = Strings::ToInt(split[0].c_str());
|
level = atoi(split[0].c_str());
|
||||||
class_id = Strings::ToInt(split[1].c_str());
|
class_id = atoi(split[1].c_str());
|
||||||
hp = Strings::ToFloat(split[2].c_str());
|
hp = atof(split[2].c_str());
|
||||||
mana = Strings::ToFloat(split[3].c_str());
|
mana = atof(split[3].c_str());
|
||||||
end = Strings::ToFloat(split[4].c_str());
|
end = atof(split[4].c_str());
|
||||||
unk1 = Strings::ToFloat(split[5].c_str());
|
unk1 = atof(split[5].c_str());
|
||||||
unk2 = Strings::ToFloat(split[6].c_str());
|
unk2 = atof(split[6].c_str());
|
||||||
hp_fac = Strings::ToFloat(split[7].c_str());
|
hp_fac = atof(split[7].c_str());
|
||||||
mana_fac = Strings::ToFloat(split[8].c_str());
|
mana_fac = atof(split[8].c_str());
|
||||||
end_fac = Strings::ToFloat(split[9].c_str());
|
end_fac = atof(split[9].c_str());
|
||||||
|
|
||||||
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
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)",
|
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
|
||||||
@@ -304,10 +293,9 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
void ImportDBStrings(SharedDatabase *db) {
|
void ImportDBStrings(SharedDatabase *db) {
|
||||||
LogInfo("Importing DB Strings");
|
LogInfo("Importing DB Strings");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
|
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +317,7 @@ void ImportDBStrings(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto split = Strings::Split(buffer, '^');
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
if(split.size() < 2) {
|
if(split.size() < 2) {
|
||||||
continue;
|
continue;
|
||||||
@@ -339,11 +327,11 @@ void ImportDBStrings(SharedDatabase *db) {
|
|||||||
int id, type;
|
int id, type;
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
id = Strings::ToInt(split[0].c_str());
|
id = atoi(split[0].c_str());
|
||||||
type = Strings::ToInt(split[1].c_str());
|
type = atoi(split[1].c_str());
|
||||||
|
|
||||||
if(split.size() >= 3) {
|
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')",
|
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
|
||||||
|
|||||||
+35
-95
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(common_sources
|
SET(common_sources
|
||||||
base_packet.cpp
|
base_packet.cpp
|
||||||
@@ -7,7 +7,6 @@ SET(common_sources
|
|||||||
compression.cpp
|
compression.cpp
|
||||||
condition.cpp
|
condition.cpp
|
||||||
content/world_content_service.cpp
|
content/world_content_service.cpp
|
||||||
discord/discord.cpp
|
|
||||||
crash.cpp
|
crash.cpp
|
||||||
crc16.cpp
|
crc16.cpp
|
||||||
crc32.cpp
|
crc32.cpp
|
||||||
@@ -15,9 +14,6 @@ SET(common_sources
|
|||||||
database.cpp
|
database.cpp
|
||||||
database_conversions.cpp
|
database_conversions.cpp
|
||||||
database_instances.cpp
|
database_instances.cpp
|
||||||
database/database_update_manifest.cpp
|
|
||||||
database/database_update_manifest_bots.cpp
|
|
||||||
database/database_update.cpp
|
|
||||||
dbcore.cpp
|
dbcore.cpp
|
||||||
deity.cpp
|
deity.cpp
|
||||||
dynamic_zone_base.cpp
|
dynamic_zone_base.cpp
|
||||||
@@ -36,13 +32,11 @@ SET(common_sources
|
|||||||
eq_stream_proxy.cpp
|
eq_stream_proxy.cpp
|
||||||
eqtime.cpp
|
eqtime.cpp
|
||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
events/player_event_logs.cpp
|
expedition_base.cpp
|
||||||
events/player_event_discord_formatter.cpp
|
|
||||||
expedition_lockout_timer.cpp
|
expedition_lockout_timer.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
discord/discord_manager.cpp
|
|
||||||
faction.cpp
|
faction.cpp
|
||||||
file.cpp
|
file_util.cpp
|
||||||
guild_base.cpp
|
guild_base.cpp
|
||||||
guilds.cpp
|
guilds.cpp
|
||||||
inventory_profile.cpp
|
inventory_profile.cpp
|
||||||
@@ -66,11 +60,8 @@ SET(common_sources
|
|||||||
packet_dump.cpp
|
packet_dump.cpp
|
||||||
packet_dump_file.cpp
|
packet_dump_file.cpp
|
||||||
packet_functions.cpp
|
packet_functions.cpp
|
||||||
path_manager.cpp
|
|
||||||
perl_eqdb.cpp
|
perl_eqdb.cpp
|
||||||
perl_eqdb_res.cpp
|
perl_eqdb_res.cpp
|
||||||
process/process.cpp
|
|
||||||
process.cpp
|
|
||||||
proc_launcher.cpp
|
proc_launcher.cpp
|
||||||
profanity_manager.cpp
|
profanity_manager.cpp
|
||||||
ptimer.cpp
|
ptimer.cpp
|
||||||
@@ -81,19 +72,16 @@ SET(common_sources
|
|||||||
serialize_buffer.cpp
|
serialize_buffer.cpp
|
||||||
server_event_scheduler.cpp
|
server_event_scheduler.cpp
|
||||||
serverinfo.cpp
|
serverinfo.cpp
|
||||||
shared_tasks.cpp
|
|
||||||
shareddb.cpp
|
shareddb.cpp
|
||||||
skills.cpp
|
skills.cpp
|
||||||
spdat.cpp
|
spdat.cpp
|
||||||
strings.cpp
|
string_util.cpp
|
||||||
struct_strategy.cpp
|
struct_strategy.cpp
|
||||||
textures.cpp
|
textures.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
unix.cpp
|
unix.cpp
|
||||||
platform.cpp
|
platform.cpp
|
||||||
json/json.hpp
|
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
zone_store.cpp
|
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
net/console_server_connection.cpp
|
net/console_server_connection.cpp
|
||||||
net/crc32.cpp
|
net/crc32.cpp
|
||||||
@@ -130,9 +118,6 @@ SET(repositories
|
|||||||
# Criteria
|
# Criteria
|
||||||
repositories/criteria/content_filter_criteria.h
|
repositories/criteria/content_filter_criteria.h
|
||||||
|
|
||||||
repositories/base/base_grid_repository.h
|
|
||||||
repositories/base/base_grid_entries_repository.h
|
|
||||||
|
|
||||||
# Base Repositories
|
# Base Repositories
|
||||||
repositories/base/base_aa_ability_repository.h
|
repositories/base/base_aa_ability_repository.h
|
||||||
repositories/base/base_aa_ranks_repository.h
|
repositories/base/base_aa_ranks_repository.h
|
||||||
@@ -152,7 +137,6 @@ SET(repositories
|
|||||||
repositories/base/base_auras_repository.h
|
repositories/base/base_auras_repository.h
|
||||||
repositories/base/base_base_data_repository.h
|
repositories/base/base_base_data_repository.h
|
||||||
repositories/base/base_blocked_spells_repository.h
|
repositories/base/base_blocked_spells_repository.h
|
||||||
repositories/base/base_books_repository.h
|
|
||||||
repositories/base/base_bugs_repository.h
|
repositories/base/base_bugs_repository.h
|
||||||
repositories/base/base_bug_reports_repository.h
|
repositories/base/base_bug_reports_repository.h
|
||||||
repositories/base/base_buyer_repository.h
|
repositories/base/base_buyer_repository.h
|
||||||
@@ -169,15 +153,12 @@ SET(repositories
|
|||||||
repositories/base/base_character_data_repository.h
|
repositories/base/base_character_data_repository.h
|
||||||
repositories/base/base_character_disciplines_repository.h
|
repositories/base/base_character_disciplines_repository.h
|
||||||
repositories/base/base_character_expedition_lockouts_repository.h
|
repositories/base/base_character_expedition_lockouts_repository.h
|
||||||
repositories/base/base_character_exp_modifiers_repository.h
|
|
||||||
repositories/base/base_character_inspect_messages_repository.h
|
repositories/base/base_character_inspect_messages_repository.h
|
||||||
repositories/base/base_character_instance_safereturns_repository.h
|
|
||||||
repositories/base/base_character_item_recast_repository.h
|
repositories/base/base_character_item_recast_repository.h
|
||||||
repositories/base/base_character_languages_repository.h
|
repositories/base/base_character_languages_repository.h
|
||||||
repositories/base/base_character_leadership_abilities_repository.h
|
repositories/base/base_character_leadership_abilities_repository.h
|
||||||
repositories/base/base_character_material_repository.h
|
repositories/base/base_character_material_repository.h
|
||||||
repositories/base/base_character_memmed_spells_repository.h
|
repositories/base/base_character_memmed_spells_repository.h
|
||||||
repositories/base/base_character_peqzone_flags_repository.h
|
|
||||||
repositories/base/base_character_pet_buffs_repository.h
|
repositories/base/base_character_pet_buffs_repository.h
|
||||||
repositories/base/base_character_pet_info_repository.h
|
repositories/base/base_character_pet_info_repository.h
|
||||||
repositories/base/base_character_pet_inventory_repository.h
|
repositories/base/base_character_pet_inventory_repository.h
|
||||||
@@ -185,29 +166,21 @@ SET(repositories
|
|||||||
repositories/base/base_character_skills_repository.h
|
repositories/base/base_character_skills_repository.h
|
||||||
repositories/base/base_character_spells_repository.h
|
repositories/base/base_character_spells_repository.h
|
||||||
repositories/base/base_character_tasks_repository.h
|
repositories/base/base_character_tasks_repository.h
|
||||||
repositories/base/base_character_task_timers_repository.h
|
|
||||||
repositories/base/base_char_create_combinations_repository.h
|
repositories/base/base_char_create_combinations_repository.h
|
||||||
repositories/base/base_char_create_point_allocations_repository.h
|
repositories/base/base_char_create_point_allocations_repository.h
|
||||||
repositories/base/base_char_recipe_list_repository.h
|
repositories/base/base_char_recipe_list_repository.h
|
||||||
repositories/base/base_chatchannels_repository.h
|
|
||||||
repositories/base/base_chatchannel_reserved_names_repository.h
|
|
||||||
repositories/base/base_completed_shared_tasks_repository.h
|
|
||||||
repositories/base/base_completed_shared_task_activity_state_repository.h
|
|
||||||
repositories/base/base_completed_shared_task_members_repository.h
|
|
||||||
repositories/base/base_completed_tasks_repository.h
|
repositories/base/base_completed_tasks_repository.h
|
||||||
repositories/base/base_content_flags_repository.h
|
repositories/base/base_content_flags_repository.h
|
||||||
repositories/base/base_damageshieldtypes_repository.h
|
repositories/base/base_damageshieldtypes_repository.h
|
||||||
repositories/base/base_data_buckets_repository.h
|
repositories/base/base_data_buckets_repository.h
|
||||||
repositories/base/base_db_str_repository.h
|
repositories/base/base_db_str_repository.h
|
||||||
repositories/base/base_discord_webhooks_repository.h
|
|
||||||
repositories/base/base_discovered_items_repository.h
|
repositories/base/base_discovered_items_repository.h
|
||||||
repositories/base/base_doors_repository.h
|
repositories/base/base_doors_repository.h
|
||||||
repositories/base/base_dynamic_zones_repository.h
|
repositories/base/base_dynamic_zones_repository.h
|
||||||
repositories/base/base_dynamic_zone_members_repository.h
|
repositories/base/base_dynamic_zone_members_repository.h
|
||||||
repositories/base/base_dynamic_zone_templates_repository.h
|
repositories/base/base_eventlog_repository.h
|
||||||
repositories/base/base_expeditions_repository.h
|
repositories/base/base_expeditions_repository.h
|
||||||
repositories/base/base_expedition_lockouts_repository.h
|
repositories/base/base_expedition_lockouts_repository.h
|
||||||
repositories/base/base_faction_association_repository.h
|
|
||||||
repositories/base/base_faction_base_data_repository.h
|
repositories/base/base_faction_base_data_repository.h
|
||||||
repositories/base/base_faction_list_repository.h
|
repositories/base/base_faction_list_repository.h
|
||||||
repositories/base/base_faction_list_mod_repository.h
|
repositories/base/base_faction_list_mod_repository.h
|
||||||
@@ -217,14 +190,18 @@ SET(repositories
|
|||||||
repositories/base/base_friends_repository.h
|
repositories/base/base_friends_repository.h
|
||||||
repositories/base/base_global_loot_repository.h
|
repositories/base/base_global_loot_repository.h
|
||||||
repositories/base/base_gm_ips_repository.h
|
repositories/base/base_gm_ips_repository.h
|
||||||
|
repositories/base/base_goallists_repository.h
|
||||||
repositories/base/base_graveyard_repository.h
|
repositories/base/base_graveyard_repository.h
|
||||||
|
repositories/base/base_grid_repository.h
|
||||||
|
repositories/base/base_grid_entries_repository.h
|
||||||
repositories/base/base_ground_spawns_repository.h
|
repositories/base/base_ground_spawns_repository.h
|
||||||
repositories/base/base_group_id_repository.h
|
repositories/base/base_group_id_repository.h
|
||||||
repositories/base/base_group_leaders_repository.h
|
repositories/base/base_group_leaders_repository.h
|
||||||
repositories/base/base_guilds_repository.h
|
repositories/base/base_guilds_repository.h
|
||||||
|
repositories/base/base_guild_members_repository.h
|
||||||
repositories/base/base_guild_ranks_repository.h
|
repositories/base/base_guild_ranks_repository.h
|
||||||
repositories/base/base_guild_relations_repository.h
|
repositories/base/base_guild_relations_repository.h
|
||||||
repositories/base/base_horses_repository.h
|
repositories/base/base_hackers_repository.h
|
||||||
repositories/base/base_instance_list_repository.h
|
repositories/base/base_instance_list_repository.h
|
||||||
repositories/base/base_instance_list_player_repository.h
|
repositories/base/base_instance_list_player_repository.h
|
||||||
repositories/base/base_inventory_repository.h
|
repositories/base/base_inventory_repository.h
|
||||||
@@ -265,12 +242,10 @@ SET(repositories
|
|||||||
repositories/base/base_perl_event_export_settings_repository.h
|
repositories/base/base_perl_event_export_settings_repository.h
|
||||||
repositories/base/base_petitions_repository.h
|
repositories/base/base_petitions_repository.h
|
||||||
repositories/base/base_pets_repository.h
|
repositories/base/base_pets_repository.h
|
||||||
repositories/base/base_pets_beastlord_data_repository.h
|
|
||||||
repositories/base/base_pets_equipmentset_repository.h
|
repositories/base/base_pets_equipmentset_repository.h
|
||||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||||
repositories/base/base_player_titlesets_repository.h
|
repositories/base/base_player_titlesets_repository.h
|
||||||
repositories/base/base_player_event_log_settings_repository.h
|
repositories/base/base_proximities_repository.h
|
||||||
repositories/base/base_player_event_logs_repository.h
|
|
||||||
repositories/base/base_quest_globals_repository.h
|
repositories/base/base_quest_globals_repository.h
|
||||||
repositories/base/base_raid_details_repository.h
|
repositories/base/base_raid_details_repository.h
|
||||||
repositories/base/base_raid_members_repository.h
|
repositories/base/base_raid_members_repository.h
|
||||||
@@ -280,10 +255,6 @@ SET(repositories
|
|||||||
repositories/base/base_rule_values_repository.h
|
repositories/base/base_rule_values_repository.h
|
||||||
repositories/base/base_saylink_repository.h
|
repositories/base/base_saylink_repository.h
|
||||||
repositories/base/base_server_scheduled_events_repository.h
|
repositories/base/base_server_scheduled_events_repository.h
|
||||||
repositories/base/base_shared_tasks_repository.h
|
|
||||||
repositories/base/base_shared_task_activity_state_repository.h
|
|
||||||
repositories/base/base_shared_task_dynamic_zones_repository.h
|
|
||||||
repositories/base/base_shared_task_members_repository.h
|
|
||||||
repositories/base/base_skill_caps_repository.h
|
repositories/base/base_skill_caps_repository.h
|
||||||
repositories/base/base_spawn2_repository.h
|
repositories/base/base_spawn2_repository.h
|
||||||
repositories/base/base_spawnentry_repository.h
|
repositories/base/base_spawnentry_repository.h
|
||||||
@@ -330,7 +301,6 @@ SET(repositories
|
|||||||
repositories/auras_repository.h
|
repositories/auras_repository.h
|
||||||
repositories/base_data_repository.h
|
repositories/base_data_repository.h
|
||||||
repositories/blocked_spells_repository.h
|
repositories/blocked_spells_repository.h
|
||||||
repositories/books_repository.h
|
|
||||||
repositories/bugs_repository.h
|
repositories/bugs_repository.h
|
||||||
repositories/bug_reports_repository.h
|
repositories/bug_reports_repository.h
|
||||||
repositories/buyer_repository.h
|
repositories/buyer_repository.h
|
||||||
@@ -347,15 +317,12 @@ SET(repositories
|
|||||||
repositories/character_data_repository.h
|
repositories/character_data_repository.h
|
||||||
repositories/character_disciplines_repository.h
|
repositories/character_disciplines_repository.h
|
||||||
repositories/character_expedition_lockouts_repository.h
|
repositories/character_expedition_lockouts_repository.h
|
||||||
repositories/character_exp_modifiers_repository.h
|
|
||||||
repositories/character_inspect_messages_repository.h
|
repositories/character_inspect_messages_repository.h
|
||||||
repositories/character_instance_safereturns_repository.h
|
|
||||||
repositories/character_item_recast_repository.h
|
repositories/character_item_recast_repository.h
|
||||||
repositories/character_languages_repository.h
|
repositories/character_languages_repository.h
|
||||||
repositories/character_leadership_abilities_repository.h
|
repositories/character_leadership_abilities_repository.h
|
||||||
repositories/character_material_repository.h
|
repositories/character_material_repository.h
|
||||||
repositories/character_memmed_spells_repository.h
|
repositories/character_memmed_spells_repository.h
|
||||||
repositories/character_peqzone_flags_repository.h
|
|
||||||
repositories/character_pet_buffs_repository.h
|
repositories/character_pet_buffs_repository.h
|
||||||
repositories/character_pet_info_repository.h
|
repositories/character_pet_info_repository.h
|
||||||
repositories/character_pet_inventory_repository.h
|
repositories/character_pet_inventory_repository.h
|
||||||
@@ -363,29 +330,21 @@ SET(repositories
|
|||||||
repositories/character_skills_repository.h
|
repositories/character_skills_repository.h
|
||||||
repositories/character_spells_repository.h
|
repositories/character_spells_repository.h
|
||||||
repositories/character_tasks_repository.h
|
repositories/character_tasks_repository.h
|
||||||
repositories/character_task_timers_repository.h
|
|
||||||
repositories/char_create_combinations_repository.h
|
repositories/char_create_combinations_repository.h
|
||||||
repositories/char_create_point_allocations_repository.h
|
repositories/char_create_point_allocations_repository.h
|
||||||
repositories/char_recipe_list_repository.h
|
repositories/char_recipe_list_repository.h
|
||||||
repositories/chatchannels_repository.h
|
|
||||||
repositories/chatchannel_reserved_names_repository.h
|
|
||||||
repositories/completed_shared_tasks_repository.h
|
|
||||||
repositories/completed_shared_task_activity_state_repository.h
|
|
||||||
repositories/completed_shared_task_members_repository.h
|
|
||||||
repositories/completed_tasks_repository.h
|
repositories/completed_tasks_repository.h
|
||||||
repositories/content_flags_repository.h
|
repositories/content_flags_repository.h
|
||||||
repositories/damageshieldtypes_repository.h
|
repositories/damageshieldtypes_repository.h
|
||||||
repositories/data_buckets_repository.h
|
repositories/data_buckets_repository.h
|
||||||
repositories/db_str_repository.h
|
repositories/db_str_repository.h
|
||||||
repositories/discord_webhooks_repository.h
|
|
||||||
repositories/discovered_items_repository.h
|
repositories/discovered_items_repository.h
|
||||||
repositories/doors_repository.h
|
repositories/doors_repository.h
|
||||||
repositories/dynamic_zones_repository.h
|
repositories/dynamic_zones_repository.h
|
||||||
repositories/dynamic_zone_members_repository.h
|
repositories/dynamic_zone_members_repository.h
|
||||||
repositories/dynamic_zone_templates_repository.h
|
repositories/eventlog_repository.h
|
||||||
repositories/expeditions_repository.h
|
repositories/expeditions_repository.h
|
||||||
repositories/expedition_lockouts_repository.h
|
repositories/expedition_lockouts_repository.h
|
||||||
repositories/faction_association_repository.h
|
|
||||||
repositories/faction_base_data_repository.h
|
repositories/faction_base_data_repository.h
|
||||||
repositories/faction_list_repository.h
|
repositories/faction_list_repository.h
|
||||||
repositories/faction_list_mod_repository.h
|
repositories/faction_list_mod_repository.h
|
||||||
@@ -395,14 +354,18 @@ SET(repositories
|
|||||||
repositories/friends_repository.h
|
repositories/friends_repository.h
|
||||||
repositories/global_loot_repository.h
|
repositories/global_loot_repository.h
|
||||||
repositories/gm_ips_repository.h
|
repositories/gm_ips_repository.h
|
||||||
|
repositories/goallists_repository.h
|
||||||
repositories/graveyard_repository.h
|
repositories/graveyard_repository.h
|
||||||
|
repositories/grid_repository.h
|
||||||
|
repositories/grid_entries_repository.h
|
||||||
repositories/ground_spawns_repository.h
|
repositories/ground_spawns_repository.h
|
||||||
repositories/group_id_repository.h
|
repositories/group_id_repository.h
|
||||||
repositories/group_leaders_repository.h
|
repositories/group_leaders_repository.h
|
||||||
repositories/guilds_repository.h
|
repositories/guilds_repository.h
|
||||||
|
repositories/guild_members_repository.h
|
||||||
repositories/guild_ranks_repository.h
|
repositories/guild_ranks_repository.h
|
||||||
repositories/guild_relations_repository.h
|
repositories/guild_relations_repository.h
|
||||||
repositories/horses_repository.h
|
repositories/hackers_repository.h
|
||||||
repositories/instance_list_repository.h
|
repositories/instance_list_repository.h
|
||||||
repositories/instance_list_player_repository.h
|
repositories/instance_list_player_repository.h
|
||||||
repositories/inventory_repository.h
|
repositories/inventory_repository.h
|
||||||
@@ -443,12 +406,10 @@ SET(repositories
|
|||||||
repositories/perl_event_export_settings_repository.h
|
repositories/perl_event_export_settings_repository.h
|
||||||
repositories/petitions_repository.h
|
repositories/petitions_repository.h
|
||||||
repositories/pets_repository.h
|
repositories/pets_repository.h
|
||||||
repositories/pets_beastlord_data_repository.h
|
|
||||||
repositories/pets_equipmentset_repository.h
|
repositories/pets_equipmentset_repository.h
|
||||||
repositories/pets_equipmentset_entries_repository.h
|
repositories/pets_equipmentset_entries_repository.h
|
||||||
repositories/player_titlesets_repository.h
|
repositories/player_titlesets_repository.h
|
||||||
repositories/player_event_log_settings_repository.h
|
repositories/proximities_repository.h
|
||||||
repositories/player_event_logs_repository.h
|
|
||||||
repositories/quest_globals_repository.h
|
repositories/quest_globals_repository.h
|
||||||
repositories/raid_details_repository.h
|
repositories/raid_details_repository.h
|
||||||
repositories/raid_members_repository.h
|
repositories/raid_members_repository.h
|
||||||
@@ -458,10 +419,6 @@ SET(repositories
|
|||||||
repositories/rule_values_repository.h
|
repositories/rule_values_repository.h
|
||||||
repositories/saylink_repository.h
|
repositories/saylink_repository.h
|
||||||
repositories/server_scheduled_events_repository.h
|
repositories/server_scheduled_events_repository.h
|
||||||
repositories/shared_tasks_repository.h
|
|
||||||
repositories/shared_task_activity_state_repository.h
|
|
||||||
repositories/shared_task_dynamic_zones_repository.h
|
|
||||||
repositories/shared_task_members_repository.h
|
|
||||||
repositories/skill_caps_repository.h
|
repositories/skill_caps_repository.h
|
||||||
repositories/spawn2_repository.h
|
repositories/spawn2_repository.h
|
||||||
repositories/spawnentry_repository.h
|
repositories/spawnentry_repository.h
|
||||||
@@ -489,10 +446,12 @@ SET(repositories
|
|||||||
repositories/zone_repository.h
|
repositories/zone_repository.h
|
||||||
repositories/zone_points_repository.h
|
repositories/zone_points_repository.h
|
||||||
|
|
||||||
)
|
# Non-Comformative
|
||||||
|
repositories/character_recipe_list_repository.h
|
||||||
|
)
|
||||||
|
|
||||||
SET(common_headers
|
SET(common_headers
|
||||||
additive_lagged_fibonacci_engine.h
|
any.h
|
||||||
base_packet.h
|
base_packet.h
|
||||||
base_data.h
|
base_data.h
|
||||||
bodytypes.h
|
bodytypes.h
|
||||||
@@ -511,11 +470,8 @@ SET(common_headers
|
|||||||
data_verification.h
|
data_verification.h
|
||||||
database.h
|
database.h
|
||||||
database_schema.h
|
database_schema.h
|
||||||
database/database_update.h
|
|
||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
discord/discord.h
|
|
||||||
discord/discord_manager.h
|
|
||||||
dynamic_zone_base.h
|
dynamic_zone_base.h
|
||||||
emu_constants.h
|
emu_constants.h
|
||||||
emu_limits.h
|
emu_limits.h
|
||||||
@@ -538,15 +494,13 @@ SET(common_headers
|
|||||||
eq_stream_locator.h
|
eq_stream_locator.h
|
||||||
eq_stream_proxy.h
|
eq_stream_proxy.h
|
||||||
eqtime.h
|
eqtime.h
|
||||||
events/player_event_logs.h
|
|
||||||
events/player_event_discord_formatter.h
|
|
||||||
events/player_events.h
|
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
|
expedition_base.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
extprofile.h
|
extprofile.h
|
||||||
faction.h
|
faction.h
|
||||||
file.h
|
file_util.h
|
||||||
features.h
|
features.h
|
||||||
fixed_memory_hash_set.h
|
fixed_memory_hash_set.h
|
||||||
fixed_memory_variable_hash_set.h
|
fixed_memory_variable_hash_set.h
|
||||||
@@ -554,7 +508,6 @@ SET(common_headers
|
|||||||
guild_base.h
|
guild_base.h
|
||||||
guilds.h
|
guilds.h
|
||||||
http/httplib.h
|
http/httplib.h
|
||||||
http/uri.h
|
|
||||||
inventory_profile.h
|
inventory_profile.h
|
||||||
inventory_slot.h
|
inventory_slot.h
|
||||||
ipc_mutex.h
|
ipc_mutex.h
|
||||||
@@ -582,17 +535,13 @@ SET(common_headers
|
|||||||
packet_dump.h
|
packet_dump.h
|
||||||
packet_dump_file.h
|
packet_dump_file.h
|
||||||
packet_functions.h
|
packet_functions.h
|
||||||
path_manager.cpp
|
|
||||||
platform.h
|
platform.h
|
||||||
process/process.h
|
|
||||||
process.h
|
|
||||||
proc_launcher.h
|
proc_launcher.h
|
||||||
profanity_manager.h
|
profanity_manager.h
|
||||||
profiler.h
|
profiler.h
|
||||||
ptimer.h
|
ptimer.h
|
||||||
queue.h
|
queue.h
|
||||||
races.h
|
races.h
|
||||||
raid.h
|
|
||||||
random.h
|
random.h
|
||||||
rdtsc.h
|
rdtsc.h
|
||||||
rulesys.h
|
rulesys.h
|
||||||
@@ -603,24 +552,21 @@ SET(common_headers
|
|||||||
server_event_scheduler.h
|
server_event_scheduler.h
|
||||||
serverinfo.h
|
serverinfo.h
|
||||||
servertalk.h
|
servertalk.h
|
||||||
shared_tasks.h
|
|
||||||
shareddb.h
|
shareddb.h
|
||||||
skills.h
|
skills.h
|
||||||
spdat.h
|
spdat.h
|
||||||
strings.h
|
string_util.h
|
||||||
struct_strategy.h
|
struct_strategy.h
|
||||||
tasks.h
|
|
||||||
textures.h
|
textures.h
|
||||||
timer.h
|
timer.h
|
||||||
types.h
|
types.h
|
||||||
unix.h
|
unix.h
|
||||||
useperl.h
|
useperl.h
|
||||||
version.h
|
version.h
|
||||||
zone_store.h
|
zone_numbers.h
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/task.h
|
event/task.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
json/json_archive_single_line.h
|
|
||||||
json/json.h
|
json/json.h
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
net/console_server.h
|
net/console_server.h
|
||||||
@@ -669,25 +615,22 @@ SET(common_headers
|
|||||||
patches/uf_limits.h
|
patches/uf_limits.h
|
||||||
patches/uf_ops.h
|
patches/uf_ops.h
|
||||||
patches/uf_structs.h
|
patches/uf_structs.h
|
||||||
termcolor/rang.hpp
|
|
||||||
stacktrace/backward.hpp
|
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.h
|
util/uuid.h)
|
||||||
)
|
|
||||||
|
|
||||||
SOURCE_GROUP(Event FILES
|
SOURCE_GROUP(Event FILES
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
event/task.h
|
event/task.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Json FILES
|
SOURCE_GROUP(Json FILES
|
||||||
json/json.h
|
json/json.h
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Net FILES
|
SOURCE_GROUP(Net FILES
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
@@ -724,7 +667,7 @@ SOURCE_GROUP(Net FILES
|
|||||||
net/websocket_server.h
|
net/websocket_server.h
|
||||||
net/websocket_server_connection.cpp
|
net/websocket_server_connection.cpp
|
||||||
net/websocket_server_connection.h
|
net/websocket_server_connection.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Patches FILES
|
SOURCE_GROUP(Patches FILES
|
||||||
patches/patches.h
|
patches/patches.h
|
||||||
@@ -768,12 +711,12 @@ SOURCE_GROUP(Patches FILES
|
|||||||
patches/titanium_limits.cpp
|
patches/titanium_limits.cpp
|
||||||
patches/uf.cpp
|
patches/uf.cpp
|
||||||
patches/uf_limits.cpp
|
patches/uf_limits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(StackWalker FILES
|
SOURCE_GROUP(StackWalker FILES
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
StackWalker/StackWalker.cpp
|
StackWalker/StackWalker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Util FILES
|
SOURCE_GROUP(Util FILES
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
@@ -781,19 +724,16 @@ SOURCE_GROUP(Util FILES
|
|||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.cpp
|
util/uuid.cpp
|
||||||
util/uuid.h
|
util/uuid.h
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||||
|
|
||||||
ADD_LIBRARY(common ${common_sources} ${common_headers} ${repositories})
|
ADD_LIBRARY(common ${common_sources} ${common_headers} ${repositories})
|
||||||
|
|
||||||
IF (UNIX)
|
IF(UNIX)
|
||||||
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
|
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
|
||||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||||
ENDIF (UNIX)
|
ENDIF(UNIX)
|
||||||
|
|
||||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
|
||||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// EQ::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 EQ
|
||||||
|
{
|
||||||
|
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)
|
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
|
||||||
{
|
{
|
||||||
pBuffer=nullptr;
|
this->pBuffer=nullptr;
|
||||||
size=0;
|
this->size=0;
|
||||||
_wpos = 0;
|
this->_wpos = 0;
|
||||||
_rpos = 0;
|
this->_rpos = 0;
|
||||||
timestamp.tv_sec = 0;
|
this->timestamp.tv_sec = 0;
|
||||||
if (len>0) {
|
if (len>0) {
|
||||||
size=len;
|
this->size=len;
|
||||||
pBuffer= new unsigned char[len];
|
pBuffer= new unsigned char[len];
|
||||||
if (buf) {
|
if (buf) {
|
||||||
memcpy(pBuffer,buf,len);
|
memcpy(this->pBuffer,buf,len);
|
||||||
} else {
|
} else {
|
||||||
memset(pBuffer,0,len);
|
memset(this->pBuffer,0,len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-10
@@ -27,17 +27,16 @@ typedef enum {
|
|||||||
BT_Extraplanar = 6,
|
BT_Extraplanar = 6,
|
||||||
BT_Magical = 7, //this name might be a bit off,
|
BT_Magical = 7, //this name might be a bit off,
|
||||||
BT_SummonedUndead = 8,
|
BT_SummonedUndead = 8,
|
||||||
BT_RaidGiant = 9, //Velious era Raid Giant
|
BT_RaidGiant = 9,
|
||||||
BT_RaidColdain = 10, //Velious era Raid Coldain
|
// ...
|
||||||
BT_NoTarget = 11, //no name, can't target this bodytype
|
BT_NoTarget = 11, //no name, can't target this bodytype
|
||||||
BT_Vampire = 12,
|
BT_Vampire = 12,
|
||||||
BT_Atenha_Ra = 13,
|
BT_Atenha_Ra = 13,
|
||||||
BT_Greater_Akheva = 14,
|
BT_Greater_Akheva = 14,
|
||||||
BT_Khati_Sha = 15,
|
BT_Khati_Sha = 15,
|
||||||
BT_Seru = 16,
|
BT_Seru = 16, //not confirmed....
|
||||||
BT_Grieg_Veneficus = 17,
|
|
||||||
BT_Draz_Nurakk = 18,
|
BT_Draz_Nurakk = 18,
|
||||||
BT_Zek = 19, //"creatures from the Plane of War."
|
BT_Zek = 19,
|
||||||
BT_Luggald = 20,
|
BT_Luggald = 20,
|
||||||
BT_Animal = 21,
|
BT_Animal = 21,
|
||||||
BT_Insect = 22,
|
BT_Insect = 22,
|
||||||
@@ -47,18 +46,17 @@ typedef enum {
|
|||||||
BT_Dragon = 26,
|
BT_Dragon = 26,
|
||||||
BT_Summoned2 = 27,
|
BT_Summoned2 = 27,
|
||||||
BT_Summoned3 = 28,
|
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_VeliousDragon = 30, //might not be a tight set
|
||||||
BT_Familiar = 31,
|
// ...
|
||||||
BT_Dragon3 = 32,
|
BT_Dragon3 = 32,
|
||||||
BT_Boxes = 33,
|
BT_Boxes = 33,
|
||||||
BT_Muramite = 34, //tribal dudes
|
BT_Muramite = 34, //tribal dudes
|
||||||
// ...
|
// ...
|
||||||
BT_NoTarget2 = 60,
|
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_SwarmPet = 63, //is this valid, or made up?
|
||||||
BT_MonsterSummon = 64,
|
// ...
|
||||||
// 65, trap or effect related?
|
|
||||||
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
|
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
|
||||||
BT_Special = 67
|
BT_Special = 67
|
||||||
} bodyType;
|
} bodyType;
|
||||||
|
|||||||
+441
-342
File diff suppressed because it is too large
Load Diff
+93
-101
@@ -19,106 +19,98 @@
|
|||||||
#define CLASSES_CH
|
#define CLASSES_CH
|
||||||
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
#include "../common/rulesys.h"
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace Class {
|
#define WARRIOR 1
|
||||||
constexpr uint8 None = 0;
|
#define CLERIC 2
|
||||||
constexpr uint8 Warrior = 1;
|
#define PALADIN 3
|
||||||
constexpr uint8 Cleric = 2;
|
#define RANGER 4
|
||||||
constexpr uint8 Paladin = 3;
|
#define SHADOWKNIGHT 5
|
||||||
constexpr uint8 Ranger = 4;
|
#define DRUID 6
|
||||||
constexpr uint8 ShadowKnight = 5;
|
#define MONK 7
|
||||||
constexpr uint8 Druid = 6;
|
#define BARD 8
|
||||||
constexpr uint8 Monk = 7;
|
#define ROGUE 9
|
||||||
constexpr uint8 Bard = 8;
|
#define SHAMAN 10
|
||||||
constexpr uint8 Rogue = 9;
|
#define NECROMANCER 11
|
||||||
constexpr uint8 Shaman = 10;
|
#define WIZARD 12
|
||||||
constexpr uint8 Necromancer = 11;
|
#define MAGICIAN 13
|
||||||
constexpr uint8 Wizard = 12;
|
#define ENCHANTER 14
|
||||||
constexpr uint8 Magician = 13;
|
#define BEASTLORD 15
|
||||||
constexpr uint8 Enchanter = 14;
|
#define BERSERKER 16
|
||||||
constexpr uint8 Beastlord = 15;
|
#define WARRIORGM 20
|
||||||
constexpr uint8 Berserker = 16;
|
#define CLERICGM 21
|
||||||
constexpr uint8 WarriorGM = 20;
|
#define PALADINGM 22
|
||||||
constexpr uint8 ClericGM = 21;
|
#define RANGERGM 23
|
||||||
constexpr uint8 PaladinGM = 22;
|
#define SHADOWKNIGHTGM 24
|
||||||
constexpr uint8 RangerGM = 23;
|
#define DRUIDGM 25
|
||||||
constexpr uint8 ShadowKnightGM = 24;
|
#define MONKGM 26
|
||||||
constexpr uint8 DruidGM = 25;
|
#define BARDGM 27
|
||||||
constexpr uint8 MonkGM = 26;
|
#define ROGUEGM 28
|
||||||
constexpr uint8 BardGM = 27;
|
#define SHAMANGM 29
|
||||||
constexpr uint8 RogueGM = 28;
|
#define NECROMANCERGM 30
|
||||||
constexpr uint8 ShamanGM = 29;
|
#define WIZARDGM 31
|
||||||
constexpr uint8 NecromancerGM = 30;
|
#define MAGICIANGM 32
|
||||||
constexpr uint8 WizardGM = 31;
|
#define ENCHANTERGM 33
|
||||||
constexpr uint8 MagicianGM = 32;
|
#define BEASTLORDGM 34
|
||||||
constexpr uint8 EnchanterGM = 33;
|
#define BERSERKERGM 35
|
||||||
constexpr uint8 BeastlordGM = 34;
|
#define BANKER 40
|
||||||
constexpr uint8 BerserkerGM = 35;
|
#define MERCHANT 41
|
||||||
constexpr uint8 Banker = 40;
|
#define DISCORD_MERCHANT 59
|
||||||
constexpr uint8 Merchant = 41;
|
#define ADVENTURERECRUITER 60
|
||||||
constexpr uint8 DiscordMerchant = 59;
|
#define ADVENTUREMERCHANT 61
|
||||||
constexpr uint8 AdventureRecruiter = 60;
|
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs
|
||||||
constexpr uint8 AdventureMerchant = 61;
|
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
|
||||||
constexpr uint8 LDoNTreasure = 62;
|
#define TRIBUTE_MASTER 63
|
||||||
constexpr uint8 TributeMaster = 63;
|
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
||||||
constexpr uint8 GuildTributeMaster = 64;
|
#define GUILD_BANKER 66
|
||||||
constexpr uint8 GuildBanker = 66;
|
#define NORRATHS_KEEPERS_MERCHANT 67
|
||||||
constexpr uint8 NorrathsKeepersMerchant = 67;
|
#define DARK_REIGN_MERCHANT 68
|
||||||
constexpr uint8 DarkReignMerchant = 68;
|
#define FELLOWSHIP_MASTER 69
|
||||||
constexpr uint8 FellowshipMaster = 69;
|
#define ALT_CURRENCY_MERCHANT 70
|
||||||
constexpr uint8 AlternateCurrencyMerchant = 70;
|
#define MERCERNARY_MASTER 71
|
||||||
constexpr uint8 MercenaryLiaison = 71;
|
|
||||||
|
|
||||||
constexpr uint8 PLAYER_CLASS_COUNT = 16;
|
|
||||||
constexpr uint16 ALL_CLASSES_BITMASK = 65535;
|
|
||||||
};
|
|
||||||
|
|
||||||
static std::map<uint8, uint16> player_class_bitmasks = {
|
// player class values
|
||||||
{Class::Warrior, 1},
|
#define PLAYER_CLASS_UNKNOWN 0
|
||||||
{Class::Cleric, 2},
|
#define PLAYER_CLASS_WARRIOR 1
|
||||||
{Class::Paladin, 4},
|
#define PLAYER_CLASS_CLERIC 2
|
||||||
{Class::Ranger, 8},
|
#define PLAYER_CLASS_PALADIN 3
|
||||||
{Class::ShadowKnight, 16},
|
#define PLAYER_CLASS_RANGER 4
|
||||||
{Class::Druid, 32},
|
#define PLAYER_CLASS_SHADOWKNIGHT 5
|
||||||
{Class::Monk, 64},
|
#define PLAYER_CLASS_DRUID 6
|
||||||
{Class::Bard, 128},
|
#define PLAYER_CLASS_MONK 7
|
||||||
{Class::Rogue, 256},
|
#define PLAYER_CLASS_BARD 8
|
||||||
{Class::Shaman, 512},
|
#define PLAYER_CLASS_ROGUE 9
|
||||||
{Class::Necromancer, 1024},
|
#define PLAYER_CLASS_SHAMAN 10
|
||||||
{Class::Wizard, 2048},
|
#define PLAYER_CLASS_NECROMANCER 11
|
||||||
{Class::Magician, 4096},
|
#define PLAYER_CLASS_WIZARD 12
|
||||||
{Class::Enchanter, 8192},
|
#define PLAYER_CLASS_MAGICIAN 13
|
||||||
{Class::Beastlord, 16384},
|
#define PLAYER_CLASS_ENCHANTER 14
|
||||||
{Class::Berserker, 32768},
|
#define PLAYER_CLASS_BEASTLORD 15
|
||||||
};
|
#define PLAYER_CLASS_BERSERKER 16
|
||||||
|
|
||||||
static std::string shadow_knight_class_name = (
|
#define PLAYER_CLASS_COUNT 16
|
||||||
RuleB(World, UseOldShadowKnightClassExport) ?
|
|
||||||
"Shadowknight" :
|
|
||||||
"Shadow Knight"
|
|
||||||
);
|
|
||||||
|
|
||||||
static std::map<uint8, std::string> class_names = {
|
|
||||||
{Class::Warrior, "Warrior"},
|
// player class bits
|
||||||
{Class::Cleric, "Cleric"},
|
#define PLAYER_CLASS_UNKNOWN_BIT 0
|
||||||
{Class::Paladin, "Paladin"},
|
#define PLAYER_CLASS_WARRIOR_BIT 1
|
||||||
{Class::Ranger, "Ranger"},
|
#define PLAYER_CLASS_CLERIC_BIT 2
|
||||||
{Class::ShadowKnight, shadow_knight_class_name},
|
#define PLAYER_CLASS_PALADIN_BIT 4
|
||||||
{Class::Druid, "Druid"},
|
#define PLAYER_CLASS_RANGER_BIT 8
|
||||||
{Class::Monk, "Monk"},
|
#define PLAYER_CLASS_SHADOWKNIGHT_BIT 16
|
||||||
{Class::Bard, "Bard"},
|
#define PLAYER_CLASS_DRUID_BIT 32
|
||||||
{Class::Rogue, "Rogue"},
|
#define PLAYER_CLASS_MONK_BIT 64
|
||||||
{Class::Shaman, "Shaman"},
|
#define PLAYER_CLASS_BARD_BIT 128
|
||||||
{Class::Necromancer, "Necromancer"},
|
#define PLAYER_CLASS_ROGUE_BIT 256
|
||||||
{Class::Wizard, "Wizard"},
|
#define PLAYER_CLASS_SHAMAN_BIT 512
|
||||||
{Class::Magician, "Magician"},
|
#define PLAYER_CLASS_NECROMANCER_BIT 1024
|
||||||
{Class::Enchanter, "Enchanter"},
|
#define PLAYER_CLASS_WIZARD_BIT 2048
|
||||||
{Class::Beastlord, "Beastlord"},
|
#define PLAYER_CLASS_MAGICIAN_BIT 4096
|
||||||
{Class::Berserker, "Berserker"},
|
#define PLAYER_CLASS_ENCHANTER_BIT 8192
|
||||||
};
|
#define PLAYER_CLASS_BEASTLORD_BIT 16384
|
||||||
|
#define PLAYER_CLASS_BERSERKER_BIT 32768
|
||||||
|
|
||||||
|
#define PLAYER_CLASS_ALL_MASK 65535 // was 65536
|
||||||
|
|
||||||
|
|
||||||
#define ARMOR_TYPE_UNKNOWN 0
|
#define ARMOR_TYPE_UNKNOWN 0
|
||||||
@@ -133,12 +125,13 @@ static std::map<uint8, std::string> class_names = {
|
|||||||
|
|
||||||
|
|
||||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||||
|
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
||||||
|
|
||||||
bool IsPlayerClass(uint8 class_id);
|
uint32 GetPlayerClassValue(uint8 class_id);
|
||||||
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
uint32 GetPlayerClassBit(uint8 class_id);
|
||||||
|
|
||||||
uint8 GetPlayerClassValue(uint8 class_id);
|
uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value);
|
||||||
uint16 GetPlayerClassBit(uint8 class_id);
|
uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
||||||
|
|
||||||
bool IsFighterClass(uint8 class_id);
|
bool IsFighterClass(uint8 class_id);
|
||||||
bool IsSpellFighterClass(uint8 class_id);
|
bool IsSpellFighterClass(uint8 class_id);
|
||||||
@@ -147,8 +140,7 @@ bool IsHybridClass(uint8 class_id);
|
|||||||
bool IsCasterClass(uint8 class_id);
|
bool IsCasterClass(uint8 class_id);
|
||||||
bool IsINTCasterClass(uint8 class_id);
|
bool IsINTCasterClass(uint8 class_id);
|
||||||
bool IsWISCasterClass(uint8 class_id);
|
bool IsWISCasterClass(uint8 class_id);
|
||||||
bool IsHeroicINTCasterClass(uint8 class_id);
|
|
||||||
bool IsHeroicWISCasterClass(uint8 class_id);
|
|
||||||
bool IsPlateClass(uint8 class_id);
|
bool IsPlateClass(uint8 class_id);
|
||||||
bool IsChainClass(uint8 class_id);
|
bool IsChainClass(uint8 class_id);
|
||||||
bool IsLeatherClass(uint8 class_id);
|
bool IsLeatherClass(uint8 class_id);
|
||||||
|
|||||||
@@ -39,15 +39,15 @@ namespace EQEmuCommand {
|
|||||||
{
|
{
|
||||||
if (cmd[{"-d", "--debug"}]) {
|
if (cmd[{"-d", "--debug"}]) {
|
||||||
std::cout << "Positional args:\n";
|
std::cout << "Positional args:\n";
|
||||||
for (auto &pos_arg: cmd.pos_args())
|
for (auto &pos_arg : cmd.pos_args())
|
||||||
std::cout << '\t' << pos_arg << std::endl;
|
std::cout << '\t' << pos_arg << std::endl;
|
||||||
|
|
||||||
std::cout << "\nFlags:\n";
|
std::cout << "\nFlags:\n";
|
||||||
for (auto &flag: cmd.flags())
|
for (auto &flag : cmd.flags())
|
||||||
std::cout << '\t' << flag << std::endl;
|
std::cout << '\t' << flag << std::endl;
|
||||||
|
|
||||||
std::cout << "\nParameters:\n";
|
std::cout << "\nParameters:\n";
|
||||||
for (auto ¶m: cmd.params())
|
for (auto ¶m : cmd.params())
|
||||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,21 +70,21 @@ namespace EQEmuCommand {
|
|||||||
bool arguments_filled = true;
|
bool arguments_filled = true;
|
||||||
|
|
||||||
int index = 2;
|
int index = 2;
|
||||||
for (auto &arg: arguments) {
|
for (auto &arg : arguments) {
|
||||||
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
||||||
arguments_filled = false;
|
arguments_filled = false;
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
|
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
|
||||||
std::string arguments_string;
|
std::string arguments_string;
|
||||||
for (auto &arg: arguments) {
|
for (auto &arg : arguments) {
|
||||||
arguments_string += " " + arg;
|
arguments_string += " " + arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string options_string;
|
std::string options_string;
|
||||||
for (auto &opt: options) {
|
for (auto &opt : options) {
|
||||||
options_string += " " + opt + "\n";
|
options_string += " " + opt + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,6 +124,14 @@ namespace EQEmuCommand {
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::string description;
|
std::string description;
|
||||||
|
bool ran_command = false;
|
||||||
|
for (auto &it: in_function_map) {
|
||||||
|
if (it.first == argv[1]) {
|
||||||
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
ran_command = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd[{"-h", "--help"}]) {
|
if (cmd[{"-h", "--help"}]) {
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout <<
|
std::cout <<
|
||||||
@@ -134,7 +142,9 @@ namespace EQEmuCommand {
|
|||||||
<< std::endl
|
<< std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
// Get max command length for padding length
|
/**
|
||||||
|
* Get max command length for padding length
|
||||||
|
*/
|
||||||
int max_command_length = 0;
|
int max_command_length = 0;
|
||||||
|
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
@@ -145,14 +155,18 @@ namespace EQEmuCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display command menu
|
/**
|
||||||
|
* Display command menu
|
||||||
|
*/
|
||||||
std::string command_section;
|
std::string command_section;
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
description.clear();
|
description = "";
|
||||||
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
|
||||||
// Print section header
|
/**
|
||||||
|
* Print section header
|
||||||
|
*/
|
||||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
||||||
|
|
||||||
if (command_prefix.find("test") != std::string::npos) {
|
if (command_prefix.find("test") != std::string::npos) {
|
||||||
@@ -164,7 +178,9 @@ namespace EQEmuCommand {
|
|||||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
std::cout << termcolor::reset << command_prefix << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print commands
|
/**
|
||||||
|
* Print commands
|
||||||
|
*/
|
||||||
std::stringstream command;
|
std::stringstream command;
|
||||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
||||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
||||||
@@ -175,15 +191,6 @@ namespace EQEmuCommand {
|
|||||||
std::exit(0);
|
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) {
|
if (ran_command) {
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "../database.h"
|
#include "../database.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../loottable.h"
|
|
||||||
#include "../repositories/content_flags_repository.h"
|
#include "../repositories/content_flags_repository.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -36,12 +35,8 @@ int WorldContentService::GetCurrentExpansion() const
|
|||||||
return current_expansion;
|
return current_expansion;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldContentService *WorldContentService::SetExpansionContext()
|
void 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);
|
int expansion = RuleI(Expansion, CurrentExpansion);
|
||||||
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
||||||
content_service.SetCurrentExpansion(expansion);
|
content_service.SetCurrentExpansion(expansion);
|
||||||
@@ -52,8 +47,6 @@ WorldContentService *WorldContentService::SetExpansionContext()
|
|||||||
GetCurrentExpansion(),
|
GetCurrentExpansion(),
|
||||||
GetCurrentExpansionName()
|
GetCurrentExpansionName()
|
||||||
);
|
);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WorldContentService::GetCurrentExpansionName()
|
std::string WorldContentService::GetCurrentExpansionName()
|
||||||
@@ -80,47 +73,15 @@ void WorldContentService::SetCurrentExpansion(int current_expansion)
|
|||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::vector<ContentFlagsRepository::ContentFlags> &WorldContentService::GetContentFlags() const
|
const std::vector<std::string> &WorldContentService::GetContentFlags() const
|
||||||
{
|
{
|
||||||
return content_flags;
|
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
|
* @param content_flags
|
||||||
*/
|
*/
|
||||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags)
|
void WorldContentService::SetContentFlags(std::vector<std::string> content_flags)
|
||||||
{
|
{
|
||||||
WorldContentService::content_flags = content_flags;
|
WorldContentService::content_flags = content_flags;
|
||||||
}
|
}
|
||||||
@@ -129,10 +90,10 @@ void WorldContentService::SetContentFlags(const std::vector<ContentFlagsReposito
|
|||||||
* @param content_flag
|
* @param content_flag
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
bool WorldContentService::IsContentFlagEnabled(const std::string& content_flag)
|
||||||
{
|
{
|
||||||
for (auto &f: GetContentFlags()) {
|
for (auto &flag : GetContentFlags()) {
|
||||||
if (f.flag_name == content_flag && f.enabled == true) {
|
if (flag == content_flag) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,102 +101,20 @@ bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void WorldContentService::ReloadContentFlags(Database &db)
|
||||||
* @param content_flag
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
|
|
||||||
{
|
{
|
||||||
for (auto &f: GetContentFlags()) {
|
std::vector<std::string> set_content_flags;
|
||||||
if (f.flag_name == content_flag && f.enabled == false) {
|
auto content_flags = ContentFlagsRepository::GetWhere(db, "enabled = 1");
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
set_content_flags.reserve(content_flags.size());
|
||||||
}
|
for (auto &flags: content_flags) {
|
||||||
|
set_content_flags.push_back(flags.flag_name);
|
||||||
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(
|
LogInfo(
|
||||||
"Loaded content flag [{}] [{}]",
|
"Enabled content flags [{}]",
|
||||||
f.flag_name,
|
implode(", ", set_content_flags)
|
||||||
(f.enabled ? "Enabled" : "Disabled")
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
SetContentFlags(set_content_flags);
|
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();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../loottable.h"
|
|
||||||
#include "../repositories/content_flags_repository.h"
|
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
@@ -54,7 +52,7 @@ namespace Expansion {
|
|||||||
VeilOfAlaris,
|
VeilOfAlaris,
|
||||||
RainOfFear,
|
RainOfFear,
|
||||||
CallOfTheForsaken,
|
CallOfTheForsaken,
|
||||||
TheDarkenedSea,
|
TheDarkendSea,
|
||||||
TheBrokenMirror,
|
TheBrokenMirror,
|
||||||
EmpiresOfKunark,
|
EmpiresOfKunark,
|
||||||
RingOfScale,
|
RingOfScale,
|
||||||
@@ -127,7 +125,7 @@ public:
|
|||||||
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || 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 IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || 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 IsTheDarkendSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkendSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || 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 IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
@@ -155,35 +153,22 @@ public:
|
|||||||
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
|
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
|
||||||
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
|
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
|
||||||
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
|
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
|
||||||
bool IsCurrentExpansionTheDarkenedSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkenedSea; }
|
bool IsCurrentExpansionTheDarkendSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkendSea; }
|
||||||
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
|
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
|
||||||
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
|
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
|
||||||
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
|
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
|
||||||
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
|
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
|
||||||
bool IsCurrentExpansionTormentOfVelious() { return current_expansion == Expansion::ExpansionNumber::TormentOfVelious; }
|
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:
|
private:
|
||||||
int current_expansion{};
|
int current_expansion{};
|
||||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
std::vector<std::string> content_flags;
|
||||||
|
public:
|
||||||
// reference to database
|
const std::vector<std::string> &GetContentFlags() const;
|
||||||
Database *m_database;
|
bool IsContentFlagEnabled(const std::string& content_flag);
|
||||||
|
void SetContentFlags(std::vector<std::string> content_flags);
|
||||||
|
void ReloadContentFlags(Database &db);
|
||||||
|
void SetExpansionContext();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WorldContentService content_service;
|
extern WorldContentService content_service;
|
||||||
|
|||||||
+8
-141
@@ -1,95 +1,6 @@
|
|||||||
#include "global_define.h"
|
#include "global_define.h"
|
||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
#include "crash.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(_WINDOWS) && defined(CRASH_LOGGING)
|
||||||
#include "StackWalker.h"
|
#include "StackWalker.h"
|
||||||
@@ -101,30 +12,22 @@ public:
|
|||||||
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
||||||
virtual void OnOutput(LPCSTR szText) {
|
virtual void OnOutput(LPCSTR szText) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
for (int i = 0; i < 4096; ++i) {
|
for(int i = 0; i < 4096; ++i) {
|
||||||
if (szText[i] == 0) {
|
if(szText[i] == 0) {
|
||||||
buffer[i] = '\0';
|
buffer[i] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szText[i] == '\n' || szText[i] == '\r') {
|
if(szText[i] == '\n' || szText[i] == '\r') {
|
||||||
buffer[i] = ' ';
|
buffer[i] = ' ';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
buffer[i] = szText[i];
|
buffer[i] = szText[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line = buffer;
|
|
||||||
_lines.push_back(line);
|
|
||||||
|
|
||||||
Log(Logs::General, Logs::Crash, buffer);
|
Log(Logs::General, Logs::Crash, buffer);
|
||||||
StackWalker::OnOutput(szText);
|
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)
|
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)
|
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||||
{
|
{
|
||||||
EQEmuStackWalker sw;
|
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
@@ -235,27 +125,9 @@ void set_exception_handler() {
|
|||||||
|
|
||||||
void print_trace()
|
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();
|
auto uid = geteuid();
|
||||||
std::string temp_output_file = fmt::format("/tmp/dump-output-{}", Strings::Random(10));
|
|
||||||
|
|
||||||
// check for passwordless sudo if not root
|
std::string temp_output_file = "/tmp/dump-output";
|
||||||
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];
|
char pid_buf[30];
|
||||||
sprintf(pid_buf, "%d", getpid());
|
sprintf(pid_buf, "%d", getpid());
|
||||||
@@ -264,6 +136,7 @@ void print_trace()
|
|||||||
int child_pid = fork();
|
int child_pid = fork();
|
||||||
if (!child_pid) {
|
if (!child_pid) {
|
||||||
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
dup2(fd, 1); // redirect output to stderr
|
dup2(fd, 1); // redirect output to stderr
|
||||||
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
||||||
if (uid == 0) {
|
if (uid == 0) {
|
||||||
@@ -278,22 +151,16 @@ void print_trace()
|
|||||||
abort(); /* If gdb failed to start */
|
abort(); /* If gdb failed to start */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
waitpid(child_pid, nullptr, 0);
|
waitpid(child_pid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream input(temp_output_file);
|
std::ifstream input(temp_output_file);
|
||||||
std::string crash_report;
|
|
||||||
for (std::string line; getline(input, line);) {
|
for (std::string line; getline(input, line);) {
|
||||||
LogCrash("{}", line);
|
LogCrash("{}", line);
|
||||||
crash_report += fmt::format("{}\n", line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::remove(temp_output_file.c_str());
|
std::remove(temp_output_file.c_str());
|
||||||
|
|
||||||
if (RuleB(Analytics, CrashReporting)) {
|
|
||||||
SendCrashReport(crash_report);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ namespace cron
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return static_cast<cron_int>(Strings::ToUnsignedInt(text.data()));
|
return static_cast<cron_int>(std::stoul(text.data()));
|
||||||
}
|
}
|
||||||
catch (std::exception const & ex)
|
catch (std::exception const & ex)
|
||||||
{
|
{
|
||||||
|
|||||||
+591
-567
File diff suppressed because it is too large
Load Diff
+41
-36
@@ -34,6 +34,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
//atoi is not uint32 or uint32 safe!!!!
|
||||||
|
#define atoul(str) strtoul(str, nullptr, 10)
|
||||||
|
|
||||||
class MySQLRequestResult;
|
class MySQLRequestResult;
|
||||||
class Client;
|
class Client;
|
||||||
@@ -76,7 +78,6 @@ class PTimerList;
|
|||||||
|
|
||||||
#define SQL(...) #__VA_ARGS__
|
#define SQL(...) #__VA_ARGS__
|
||||||
|
|
||||||
class LogSettings;
|
|
||||||
class Database : public DBcore {
|
class Database : public DBcore {
|
||||||
public:
|
public:
|
||||||
Database();
|
Database();
|
||||||
@@ -86,6 +87,7 @@ public:
|
|||||||
|
|
||||||
/* Character Creation */
|
/* Character Creation */
|
||||||
|
|
||||||
|
bool AddToNameFilter(const char *name);
|
||||||
bool CreateCharacter(
|
bool CreateCharacter(
|
||||||
uint32 account_id,
|
uint32 account_id,
|
||||||
char *name,
|
char *name,
|
||||||
@@ -106,27 +108,30 @@ public:
|
|||||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||||
bool ReserveName(uint32 account_id, char *name);
|
bool ReserveName(uint32 account_id, char *name);
|
||||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
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 SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
|
||||||
bool UpdateName(const char *oldname, const char *newname);
|
bool UpdateName(const char *oldname, const char *newname);
|
||||||
bool CopyCharacter(
|
bool CopyCharacter(
|
||||||
const std::string& source_character_name,
|
std::string source_character_name,
|
||||||
const std::string& destination_character_name,
|
std::string destination_character_name,
|
||||||
const std::string& destination_account_name
|
std::string destination_account_name
|
||||||
);
|
);
|
||||||
|
|
||||||
/* General Information Queries */
|
/* General Information Queries */
|
||||||
|
|
||||||
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
|
||||||
bool AddToNameFilter(std::string name);
|
bool AddGMIP(char* ip_address, char* name);
|
||||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
||||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||||
bool CheckNameFilter(std::string name, bool surname = false);
|
bool CheckNameFilter(const char* name, bool surname = false);
|
||||||
bool CheckUsedName(std::string name);
|
bool CheckUsedName(const char* name);
|
||||||
|
|
||||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||||
uint32 GetAccountIDByChar(uint32 char_id);
|
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, const char *loginserver, int16* status = 0, uint32* lsid = 0);
|
||||||
uint32 GetCharacterID(const char *name);
|
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 GetGuildIDByCharID(uint32 char_id);
|
||||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||||
@@ -135,41 +140,41 @@ public:
|
|||||||
void GetCharName(uint32 char_id, char* name);
|
void GetCharName(uint32 char_id, char* name);
|
||||||
std::string GetCharNameByID(uint32 char_id);
|
std::string GetCharNameByID(uint32 char_id);
|
||||||
std::string GetNPCNameByID(uint32 npc_id);
|
std::string GetNPCNameByID(uint32 npc_id);
|
||||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
void LoginIP(uint32 AccountID, const char* LoginIP);
|
||||||
void LoginIP(uint32 account_id, std::string login_ip);
|
|
||||||
|
|
||||||
/* Instancing */
|
/* Instancing */
|
||||||
|
|
||||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
bool AddClientToInstance(uint16 instance_id, uint32 char_id);
|
||||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
bool CharacterInInstanceGroup(uint16 instance_id, uint32 char_id);
|
||||||
bool CheckInstanceExists(uint16 instance_id);
|
bool CheckInstanceExists(uint16 instance_id);
|
||||||
bool CheckInstanceExpired(uint16 instance_id);
|
bool CheckInstanceExpired(uint16 instance_id);
|
||||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
||||||
bool GetUnusedInstanceID(uint16 &instance_id);
|
bool GetUnusedInstanceID(uint16 &instance_id);
|
||||||
bool IsGlobalInstance(uint16 instance_id);
|
bool GlobalInstance(uint16 instance_id);
|
||||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||||
bool RemoveClientsFromInstance(uint16 instance_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);
|
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||||
|
|
||||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
uint16 GetInstanceVersion(uint16 instance_id);
|
||||||
uint8_t GetInstanceVersion(uint16 instance_id);
|
|
||||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
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 AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
||||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
||||||
|
void BuryCorpsesInInstance(uint16 instance_id);
|
||||||
void DeleteInstance(uint16 instance_id);
|
void DeleteInstance(uint16 instance_id);
|
||||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
void FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid);
|
||||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
void FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid);
|
||||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list);
|
||||||
void PurgeExpiredInstances();
|
void PurgeExpiredInstances();
|
||||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||||
|
|
||||||
/* Adventure related. */
|
/* 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 remove = false);
|
||||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
||||||
|
|
||||||
/* Account Related */
|
/* Account Related */
|
||||||
@@ -183,25 +188,22 @@ public:
|
|||||||
|
|
||||||
int16 CheckStatus(uint32 account_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 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 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 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||||
uint8 GetAgreementFlag(uint32 account_id);
|
uint8 GetAgreementFlag(uint32 acctid);
|
||||||
|
|
||||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||||
void SetAgreementFlag(uint32 account_id);
|
void SetAgreementFlag(uint32 acctid);
|
||||||
|
|
||||||
int GetIPExemption(std::string account_ip);
|
int GetIPExemption(std::string account_ip);
|
||||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
|
||||||
|
|
||||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||||
|
|
||||||
|
|
||||||
/* Groups */
|
/* Groups */
|
||||||
|
|
||||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
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);
|
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);
|
uint32 GetGroupID(const char* name);
|
||||||
@@ -235,16 +237,19 @@ public:
|
|||||||
/* Database Variables */
|
/* Database Variables */
|
||||||
|
|
||||||
bool GetVariable(std::string varname, std::string &varvalue);
|
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();
|
bool LoadVariables();
|
||||||
|
|
||||||
/* General Queries */
|
/* General Queries */
|
||||||
|
|
||||||
|
bool GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, float* safe_heading = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr);
|
||||||
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 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 LoadPTimers(uint32 charid, PTimerList &into);
|
||||||
|
|
||||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
|
||||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
|
|
||||||
|
uint8 GetPEQZone(uint32 zoneID, uint32 version);
|
||||||
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
||||||
uint8 GetServerType();
|
uint8 GetServerType();
|
||||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||||
@@ -262,8 +267,8 @@ public:
|
|||||||
int CountInvSnapshots();
|
int CountInvSnapshots();
|
||||||
void ClearInvSnapshots(bool from_now = false);
|
void ClearInvSnapshots(bool from_now = false);
|
||||||
|
|
||||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
/* EQEmuLogSys */
|
||||||
void SourceSqlFromUrl(std::string url);
|
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,10 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include "database_dump_service.h"
|
#include "database_dump_service.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../strings.h"
|
#include "../string_util.h"
|
||||||
#include "../eqemu_config.h"
|
#include "../eqemu_config.h"
|
||||||
#include "../database_schema.h"
|
#include "../database_schema.h"
|
||||||
#include "../file.h"
|
#include "../file_util.h"
|
||||||
#include "../process/process.h"
|
|
||||||
#include "../termcolor/rang.hpp"
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
@@ -37,12 +35,43 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DATABASE_DUMP_PATH "backups/"
|
#define DATABASE_DUMP_PATH "backups/"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cmd
|
||||||
|
* @param return_result
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string DatabaseDumpService::execute(const std::string &cmd, bool return_result = true)
|
||||||
|
{
|
||||||
|
const char *file_name = "db-exec-result.txt";
|
||||||
|
|
||||||
|
if (return_result) {
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||||
|
#else
|
||||||
|
std::system((cmd + " > " + file_name).c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::system((cmd).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if (return_result) {
|
||||||
|
std::ifstream file(file_name);
|
||||||
|
result = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
|
||||||
|
std::remove(file_name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -59,7 +88,7 @@ bool DatabaseDumpService::IsMySQLInstalled()
|
|||||||
*/
|
*/
|
||||||
bool DatabaseDumpService::IsTarAvailable()
|
bool DatabaseDumpService::IsTarAvailable()
|
||||||
{
|
{
|
||||||
std::string version_output = Process::execute("tar --version");
|
std::string version_output = execute("tar --version");
|
||||||
|
|
||||||
return version_output.find("GNU tar") != std::string::npos;
|
return version_output.find("GNU tar") != std::string::npos;
|
||||||
}
|
}
|
||||||
@@ -70,7 +99,7 @@ bool DatabaseDumpService::IsTarAvailable()
|
|||||||
*/
|
*/
|
||||||
bool DatabaseDumpService::Is7ZipAvailable()
|
bool DatabaseDumpService::Is7ZipAvailable()
|
||||||
{
|
{
|
||||||
std::string version_output = Process::execute("7z --help");
|
std::string version_output = execute("7z --help");
|
||||||
|
|
||||||
return version_output.find("7-Zip") != std::string::npos;
|
return version_output.find("7-Zip") != std::string::npos;
|
||||||
}
|
}
|
||||||
@@ -88,13 +117,11 @@ bool DatabaseDumpService::HasCompressionBinary()
|
|||||||
*/
|
*/
|
||||||
std::string DatabaseDumpService::GetMySQLVersion()
|
std::string DatabaseDumpService::GetMySQLVersion()
|
||||||
{
|
{
|
||||||
std::string version_output = Process::execute("mysql --version");
|
std::string version_output = execute("mysql --version");
|
||||||
|
|
||||||
return Strings::Trim(version_output);
|
return trim(version_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CREDENTIALS_FILE = "login.my.cnf";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -103,66 +130,114 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
|||||||
auto config = EQEmuConfig::get();
|
auto config = EQEmuConfig::get();
|
||||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"mysqldump --defaults-extra-file={} {}",
|
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||||
CREDENTIALS_FILE,
|
config->ContentDbUsername,
|
||||||
|
config->ContentDbPassword,
|
||||||
|
config->ContentDbHost,
|
||||||
|
config->ContentDbPort,
|
||||||
config->ContentDbName
|
config->ContentDbName
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"mysqldump --defaults-extra-file={} {}",
|
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||||
CREDENTIALS_FILE,
|
config->DatabaseUsername,
|
||||||
|
config->DatabasePassword,
|
||||||
|
config->DatabaseHost,
|
||||||
|
config->DatabasePort,
|
||||||
config->DatabaseDB
|
config->DatabaseDB
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetPlayerTablesList()
|
std::string DatabaseDumpService::GetPlayerTablesList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetPlayerTables(), " ");
|
std::string tables_list;
|
||||||
}
|
std::vector<std::string> tables = DatabaseSchema::GetPlayerTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
std::string DatabaseDumpService::GetBotTablesList()
|
tables_list += table + " ";
|
||||||
{
|
}
|
||||||
return Strings::Join(DatabaseSchema::GetBotTables(), " ");
|
|
||||||
}
|
return trim(tables_list);
|
||||||
|
|
||||||
std::string DatabaseDumpService::GetMercTablesList()
|
|
||||||
{
|
|
||||||
return Strings::Join(DatabaseSchema::GetMercTables(), " ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetLoginTableList()
|
std::string DatabaseDumpService::GetLoginTableList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
|
std::string tables_list;
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetLoginTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetQueryServTables()
|
std::string DatabaseDumpService::GetQueryServTables()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
|
std::string tables_list;
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetQueryServerTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetSystemTablesList()
|
std::string DatabaseDumpService::GetSystemTablesList()
|
||||||
{
|
{
|
||||||
auto system_tables = DatabaseSchema::GetServerTables();
|
std::string tables_list;
|
||||||
auto version_tables = DatabaseSchema::GetVersionTables();
|
|
||||||
|
|
||||||
system_tables.insert(
|
std::vector<std::string> tables = DatabaseSchema::GetServerTables();
|
||||||
std::end(system_tables),
|
for (const auto &table : tables) {
|
||||||
std::begin(version_tables),
|
tables_list += table + " ";
|
||||||
std::end(version_tables)
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return Strings::Join(system_tables, " ");
|
tables = DatabaseSchema::GetVersionTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetStateTablesList()
|
std::string DatabaseDumpService::GetStateTablesList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetStateTables(), " ");
|
std::string tables_list;
|
||||||
|
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetStateTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetContentTablesList()
|
std::string DatabaseDumpService::GetContentTablesList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetContentTables(), " ");
|
std::string tables_list;
|
||||||
|
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetContentTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,7 +272,7 @@ std::string DatabaseDumpService::GetDumpFileNameWithPath()
|
|||||||
return GetSetDumpPath() + GetDumpFileName();
|
return GetSetDumpPath() + GetDumpFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseDumpService::DatabaseDump()
|
void DatabaseDumpService::Dump()
|
||||||
{
|
{
|
||||||
if (!IsMySQLInstalled()) {
|
if (!IsMySQLInstalled()) {
|
||||||
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
||||||
@@ -243,16 +318,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
dump_descriptor += "-player";
|
dump_descriptor += "-player";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDumpBotTables()) {
|
|
||||||
tables_to_dump += GetBotTablesList() + " ";
|
|
||||||
dump_descriptor += "-bots";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpMercTables()) {
|
|
||||||
tables_to_dump += GetMercTablesList() + " ";
|
|
||||||
dump_descriptor += "-mercs";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpSystemTables()) {
|
if (IsDumpSystemTables()) {
|
||||||
tables_to_dump += GetSystemTablesList() + " ";
|
tables_to_dump += GetSystemTablesList() + " ";
|
||||||
dump_descriptor += "-system";
|
dump_descriptor += "-system";
|
||||||
@@ -279,11 +344,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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()) {
|
if (!dump_descriptor.empty()) {
|
||||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
||||||
}
|
}
|
||||||
@@ -296,25 +356,7 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
std::string execute_command = fmt::format(
|
||||||
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(),
|
GetBaseMySQLDumpCommand(),
|
||||||
options,
|
options,
|
||||||
@@ -322,50 +364,40 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
pipe_file
|
pipe_file
|
||||||
);
|
);
|
||||||
|
|
||||||
LogInfo("Backing up database [{}]", execute_command);
|
if (!FileUtil::exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||||
LogInfo("This can take a few minutes depending on the size of your database");
|
FileUtil::mkdir(GetSetDumpPath());
|
||||||
LogInfo("LOADING... PLEASE WAIT...");
|
}
|
||||||
|
|
||||||
BuildCredentialsFile();
|
if (IsDumpDropTableSyntaxOnly()) {
|
||||||
std::string execution_result = Process::execute(execute_command);
|
std::vector<std::string> tables = SplitString(tables_to_dump, ' ');
|
||||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
|
||||||
|
for (auto &table : tables) {
|
||||||
|
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tables_to_dump.empty()) {
|
||||||
|
std::cerr << "No tables were specified" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::string execution_result = execute(execute_command, IsDumpOutputToConsole());
|
||||||
|
if (!execution_result.empty()) {
|
||||||
std::cout << execution_result;
|
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()) {
|
if (!tables_to_dump.empty()) {
|
||||||
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
|
LogInfo("Dumping Tables [{}]", tables_to_dump);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
||||||
if (HasCompressionBinary()) {
|
if (HasCompressionBinary()) {
|
||||||
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsTarAvailable()) {
|
if (IsTarAvailable()) {
|
||||||
Process::execute(
|
execute(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
||||||
GetDumpFileNameWithPath(),
|
GetDumpFileNameWithPath(),
|
||||||
@@ -374,10 +406,9 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
||||||
RemoveSqlBackup();
|
|
||||||
}
|
}
|
||||||
else if (Is7ZipAvailable()) {
|
else if (Is7ZipAvailable()) {
|
||||||
Process::execute(
|
execute(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"7z a -t7z {}.zip {}.sql",
|
"7z a -t7z {}.zip {}.sql",
|
||||||
GetDumpFileNameWithPath(),
|
GetDumpFileNameWithPath(),
|
||||||
@@ -385,7 +416,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
||||||
RemoveSqlBackup();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogInfo("Compression requested, but no available compression binary was found");
|
LogInfo("Compression requested, but no available compression binary was found");
|
||||||
@@ -396,8 +426,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveCredentialsFile();
|
|
||||||
|
|
||||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||||
@@ -408,7 +436,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] bot", (IsDumpBotTables() ? "true" : "false"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpSystemTables() const
|
bool DatabaseDumpService::IsDumpSystemTables() const
|
||||||
@@ -550,78 +577,3 @@ void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
|
|||||||
{
|
{
|
||||||
DatabaseDumpService::dump_state_tables = 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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
class DatabaseDumpService {
|
class DatabaseDumpService {
|
||||||
public:
|
public:
|
||||||
void DatabaseDump();
|
void Dump();
|
||||||
bool IsDumpAllTables() const;
|
bool IsDumpAllTables() const;
|
||||||
void SetDumpAllTables(bool dump_all_tables);
|
void SetDumpAllTables(bool dump_all_tables);
|
||||||
bool IsDumpWithNoData() const;
|
bool IsDumpWithNoData() const;
|
||||||
@@ -53,13 +53,6 @@ public:
|
|||||||
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
||||||
bool IsDumpStateTables() const;
|
bool IsDumpStateTables() const;
|
||||||
void SetDumpStateTables(bool dump_state_tables);
|
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:
|
private:
|
||||||
bool dump_all_tables = false;
|
bool dump_all_tables = false;
|
||||||
@@ -74,19 +67,14 @@ private:
|
|||||||
bool dump_with_compression = false;
|
bool dump_with_compression = false;
|
||||||
bool dump_output_to_console = false;
|
bool dump_output_to_console = false;
|
||||||
bool dump_drop_table_syntax_only = 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_path;
|
||||||
std::string dump_file_name;
|
std::string dump_file_name;
|
||||||
|
|
||||||
|
std::string execute(const std::string &cmd, bool return_result);
|
||||||
bool IsMySQLInstalled();
|
bool IsMySQLInstalled();
|
||||||
std::string GetMySQLVersion();
|
std::string GetMySQLVersion();
|
||||||
std::string GetBaseMySQLDumpCommand();
|
std::string GetBaseMySQLDumpCommand();
|
||||||
std::string GetPlayerTablesList();
|
std::string GetPlayerTablesList();
|
||||||
std::string GetBotTablesList();
|
|
||||||
std::string GetMercTablesList();
|
|
||||||
std::string GetSystemTablesList();
|
std::string GetSystemTablesList();
|
||||||
std::string GetStateTablesList();
|
std::string GetStateTablesList();
|
||||||
std::string GetContentTablesList();
|
std::string GetContentTablesList();
|
||||||
@@ -97,9 +85,6 @@ private:
|
|||||||
std::string GetDumpFileNameWithPath();
|
std::string GetDumpFileNameWithPath();
|
||||||
std::string GetSetDumpPath();
|
std::string GetSetDumpPath();
|
||||||
std::string GetQueryServTables();
|
std::string GetQueryServTables();
|
||||||
void RemoveSqlBackup();
|
|
||||||
void BuildCredentialsFile();
|
|
||||||
void RemoveCredentialsFile();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,129 +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;
|
|
||||||
)",
|
|
||||||
},
|
|
||||||
ManifestEntry{
|
|
||||||
.version = 9041,
|
|
||||||
.description = "2023_12_04_bot_timers.sql",
|
|
||||||
.check = "SHOW COLUMNS FROM `bot_timers` LIKE 'recast_time'",
|
|
||||||
.condition = "empty",
|
|
||||||
.match = "",
|
|
||||||
.sql = R"(
|
|
||||||
ALTER TABLE `bot_timers`
|
|
||||||
ADD COLUMN `recast_time` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `timer_value`,
|
|
||||||
ADD COLUMN `is_spell` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `recast_time`,
|
|
||||||
ADD COLUMN `is_disc` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `is_spell`,
|
|
||||||
ADD COLUMN `spell_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `is_disc`,
|
|
||||||
ADD COLUMN `is_item` TINYINT(2) UNSIGNED NOT NULL DEFAULT 0 AFTER `spell_id`,
|
|
||||||
ADD COLUMN `item_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `is_item`;
|
|
||||||
ALTER TABLE `bot_timers`
|
|
||||||
DROP FOREIGN KEY `FK_bot_timers_1`;
|
|
||||||
ALTER TABLE `bot_timers`
|
|
||||||
DROP PRIMARY KEY;
|
|
||||||
ALTER TABLE `bot_timers`
|
|
||||||
ADD PRIMARY KEY (`bot_id`, `timer_id`, `spell_id`, `item_id`);
|
|
||||||
)"
|
|
||||||
}
|
|
||||||
// -- 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
|
|
||||||
// };
|
|
||||||
+1795
-13
File diff suppressed because it is too large
Load Diff
+360
-333
@@ -18,19 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
#include "../common/repositories/character_corpses_repository.h"
|
|
||||||
#include "../common/repositories/dynamic_zone_members_repository.h"
|
#include "../common/repositories/dynamic_zone_members_repository.h"
|
||||||
#include "../common/repositories/dynamic_zones_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"
|
#include "database.h"
|
||||||
|
|
||||||
@@ -50,242 +41,251 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#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;
|
auto results = QueryDatabase(query);
|
||||||
e.charid = character_id;
|
|
||||||
|
|
||||||
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(
|
std::string query = StringFormat("SELECT charid FROM instance_list_player where id=%u AND charid=%u", instance_id, char_id);
|
||||||
*this,
|
auto results = QueryDatabase(query);
|
||||||
fmt::format(
|
|
||||||
"id = {} AND charid = {}",
|
if (!results.Success())
|
||||||
instance_id,
|
return false;
|
||||||
character_id
|
|
||||||
)
|
if (results.RowCount() != 1)
|
||||||
);
|
|
||||||
if (l.empty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckInstanceExists(uint16 instance_id)
|
bool Database::CheckInstanceExists(uint16 instance_id) {
|
||||||
{
|
std::string query = StringFormat(
|
||||||
if (!instance_id) {
|
"SELECT "
|
||||||
return false;
|
"`id` "
|
||||||
}
|
"FROM "
|
||||||
|
"`instance_list` "
|
||||||
|
"WHERE "
|
||||||
|
"`id` = %u",
|
||||||
|
instance_id
|
||||||
|
);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
if (!results.Success())
|
||||||
if (!i.id) {
|
return false;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckInstanceExpired(uint16 instance_id)
|
bool Database::CheckInstanceExpired(uint16 instance_id)
|
||||||
{
|
{
|
||||||
if (!instance_id) {
|
|
||||||
|
int32 start_time = 0;
|
||||||
|
int32 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()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
if (results.RowCount() == 0) {
|
||||||
if (!i.id) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.never_expires) {
|
auto row = results.begin();
|
||||||
|
|
||||||
|
start_time = atoi(row[0]);
|
||||||
|
duration = atoi(row[1]);
|
||||||
|
never_expires = atoi(row[2]);
|
||||||
|
|
||||||
|
if (never_expires == 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval tv{};
|
timeval tv{};
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
|
|
||||||
return (i.start_time + i.duration) <= tv.tv_sec;
|
return (start_time + duration) <= tv.tv_sec;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
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 (%u, %u, %u, UNIX_TIMESTAMP(), %u)",
|
||||||
|
instance_id,
|
||||||
|
zone_id,
|
||||||
|
version,
|
||||||
|
duration
|
||||||
|
);
|
||||||
|
|
||||||
e.id = instance_id;
|
auto results = QueryDatabase(query);
|
||||||
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)
|
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||||
{
|
{
|
||||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||||
uint32 max_instance_id = 32000;
|
uint32 max = 32000;
|
||||||
|
|
||||||
// sanity check reserved
|
std::string query = StringFormat(
|
||||||
if (max_reserved_instance_id >= max_instance_id) {
|
"SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u",
|
||||||
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,
|
||||||
max_reserved_instance_id
|
max_reserved_instance_id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||||
|
query = (
|
||||||
|
SQL(
|
||||||
|
SELECT i.id + 1 AS next_available
|
||||||
|
FROM instance_list i
|
||||||
|
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
||||||
|
WHERE i2.id IS NULL
|
||||||
|
ORDER BY i.id
|
||||||
|
LIMIT 0, 1;
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
// could not successfully query - bail out
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// did not retrieve any rows - bail out
|
if (results.RowCount() == 0) {
|
||||||
|
instance_id = max_reserved_instance_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
if (atoi(row[0]) <= max) {
|
||||||
|
instance_id = atoi(row[0]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance_id < max_reserved_instance_id) {
|
||||||
|
instance_id = max_reserved_instance_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", max_reserved_instance_id);
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0) {
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
max_reserved_instance_id++;
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
// no instances currently used
|
if (max_reserved_instance_id < atoi(row[0])) {
|
||||||
if (!row[0]) {
|
instance_id = max_reserved_instance_id;
|
||||||
instance_id = max_reserved_instance_id + 1;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that id is within limits
|
if (max_reserved_instance_id > max) {
|
||||||
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
|
||||||
instance_id = Strings::ToInt(row[0]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no available instance ids
|
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_reserved_instance_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance_id = max_reserved_instance_id;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
bool Database::GlobalInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
if (!instance_id) {
|
std::string query = StringFormat(
|
||||||
return false;
|
"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 (!results.Success())
|
||||||
if (!i.id) {
|
|
||||||
return false;
|
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)
|
bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id)
|
||||||
{
|
{
|
||||||
return InstanceListPlayerRepository::DeleteWhere(
|
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu",
|
||||||
*this,
|
(unsigned long)instance_id, (unsigned long)char_id);
|
||||||
fmt::format(
|
auto results = QueryDatabase(query);
|
||||||
"id = {} AND charid = {}",
|
|
||||||
instance_id,
|
return results.Success();
|
||||||
char_id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Database::RemoveClientsFromInstance(uint16 instance_id)
|
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
|
//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;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (CheckInstanceExpired(instance_id)) {
|
if (CheckInstanceExpired(instance_id))
|
||||||
|
{
|
||||||
DeleteInstance(instance_id);
|
DeleteInstance(instance_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -295,102 +295,99 @@ bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
|
|||||||
|
|
||||||
bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id)
|
bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id)
|
||||||
{
|
{
|
||||||
auto l = InstanceListRepository::GetWhere(
|
|
||||||
*this,
|
std::string query = StringFormat("SELECT id FROM instance_list where id=%u AND zone=%u", instance_id, zone_id);
|
||||||
fmt::format(
|
auto results = QueryDatabase(query);
|
||||||
"id = {} AND zone = {}",
|
|
||||||
instance_id,
|
if (!results.Success())
|
||||||
zone_id
|
return false;
|
||||||
)
|
|
||||||
);
|
if (results.RowCount() == 0)
|
||||||
if (l.empty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 version)
|
uint16 Database::GetInstanceID(uint32 zone, uint32 character_id, int16 version)
|
||||||
{
|
{
|
||||||
if (!zone_id) {
|
if (!zone)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
const auto query = fmt::format(
|
std::string query = StringFormat(
|
||||||
"SELECT instance_list.id FROM "
|
"SELECT "
|
||||||
"instance_list, instance_list_player WHERE "
|
"instance_list.id "
|
||||||
"instance_list.zone = {} AND "
|
"FROM "
|
||||||
"instance_list.version = {} AND "
|
"instance_list, "
|
||||||
"instance_list.id = instance_list_player.id AND "
|
"instance_list_player "
|
||||||
"instance_list_player.charid = {} "
|
"WHERE "
|
||||||
"LIMIT 1;",
|
"instance_list.zone = %u "
|
||||||
zone_id,
|
"AND instance_list.version = %u "
|
||||||
|
"AND instance_list.id = instance_list_player.id "
|
||||||
|
"AND instance_list_player.charid = %u "
|
||||||
|
"LIMIT 1; ",
|
||||||
|
zone,
|
||||||
version,
|
version,
|
||||||
character_id
|
character_id
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
{
|
||||||
|
is_perma = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
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)
|
if (never_expires == 1)
|
||||||
{
|
{
|
||||||
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) {
|
|
||||||
is_perma = true;
|
is_perma = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -399,174 +396,204 @@ uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
|||||||
|
|
||||||
timeval tv;
|
timeval tv;
|
||||||
gettimeofday(&tv, nullptr);
|
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);
|
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
|
||||||
if (!i.id) {
|
auto results = QueryDatabase(query);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
||||||
{
|
{
|
||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
|
||||||
auto version = GetInstanceVersion(instance_id);
|
|
||||||
|
|
||||||
auto l = GroupIdRepository::GetWhere(
|
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
|
||||||
*this,
|
uint16 version = VersionFromInstanceID(instance_id);
|
||||||
fmt::format(
|
|
||||||
"groupid = {}",
|
std::string query = StringFormat("SELECT `charid` FROM `group_id` WHERE `groupid` = %u", group_id);
|
||||||
group_id
|
auto results = QueryDatabase(query);
|
||||||
)
|
|
||||||
);
|
if (!results.Success())
|
||||||
if (l.empty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& e : l) {
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
{
|
||||||
AddClientToInstance(instance_id, e.charid);
|
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)
|
void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
||||||
{
|
{
|
||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
|
||||||
auto version = GetInstanceVersion(instance_id);
|
|
||||||
|
|
||||||
auto l = RaidMembersRepository::GetWhere(
|
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
|
||||||
*this,
|
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 (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) {
|
||||||
|
QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"raidid = {}",
|
"UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id = {}",
|
||||||
raid_id
|
instance_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (l.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& e : l) {
|
|
||||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
|
||||||
AddClientToInstance(instance_id, e.charid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::DeleteInstance(uint16 instance_id)
|
void Database::DeleteInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
std::string query;
|
||||||
|
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
query = StringFormat("DELETE FROM respawn_times WHERE instance_id=%u", instance_id);
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
|
query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id);
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||||
|
|
||||||
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
|
BuryCorpsesInInstance(instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id)
|
void Database::FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid)
|
||||||
{
|
{
|
||||||
auto instance_id = GetInstanceID(zone_id, character_id, version);
|
uint16 id = GetInstanceID(zone, charid, version);
|
||||||
if (instance_id) {
|
if (id != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
char ln[128];
|
char ln[128];
|
||||||
memset(ln, 0, 128);
|
memset(ln, 0, 128);
|
||||||
GetGroupLeadershipInfo(group_id, 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);
|
if (l_id == 0)
|
||||||
auto group_leader_instance_id = GetInstanceID(zone_id, group_leader_id, version);
|
|
||||||
|
|
||||||
if (!group_leader_instance_id) {
|
|
||||||
return;
|
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);
|
uint16 id = GetInstanceID(zone, charid, version);
|
||||||
if (instance_id) {
|
if (id != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
uint32 l_charid = GetCharacterID(GetRaidLeaderName(rid));
|
||||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
uint16 l_id = GetInstanceID(zone, l_charid, version);
|
||||||
|
|
||||||
if (!raid_leader_instance_id) {
|
if (l_id == 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
AddClientToInstance(raid_leader_instance_id, character_id);
|
AddClientToInstance(l_id, charid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids)
|
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list) {
|
||||||
{
|
|
||||||
auto l = InstanceListPlayerRepository::GetWhere(*this, fmt::format("id = {}", instance_id));
|
|
||||||
if (l.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& e : l) {
|
std::string query = StringFormat("SELECT `charid` FROM `instance_list_player` WHERE `id` = %u", instance_id);
|
||||||
character_ids.push_back(e.charid);
|
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()
|
void Database::PurgeExpiredInstances()
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delay purging by a day so that we can continue using adjacent free instance id's
|
* 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
|
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
||||||
* has not been fully de-allocated
|
* has not been fully de-allocated
|
||||||
*/
|
*/
|
||||||
auto l = InstanceListRepository::GetWhere(
|
std::string query =
|
||||||
*this,
|
SQL(
|
||||||
"(start_time + duration) <= (UNIX_TIMESTAMP() - 86400) AND never_expires = 0"
|
SELECT
|
||||||
|
id
|
||||||
|
FROM
|
||||||
|
instance_list
|
||||||
|
where
|
||||||
|
(start_time + duration) <= (UNIX_TIMESTAMP() - 86400)
|
||||||
|
and never_expires = 0
|
||||||
);
|
);
|
||||||
if (l.empty()) {
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> instance_ids;
|
std::vector<std::string> instance_ids;
|
||||||
for (const auto& e : l) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
instance_ids.emplace_back(std::to_string(e.id));
|
instance_ids.emplace_back(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
|
std::string imploded_instance_ids = implode(",", instance_ids);
|
||||||
|
|
||||||
InstanceListRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM instance_list WHERE id IN ({})", imploded_instance_ids));
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM instance_list_player WHERE id IN ({})", imploded_instance_ids));
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM respawn_times WHERE instance_id IN ({})", imploded_instance_ids));
|
||||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM spawn_condition_values WHERE instance_id IN ({})", imploded_instance_ids));
|
||||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
QueryDatabase(fmt::format("UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", imploded_instance_ids));
|
||||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", 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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||||
{
|
{
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), "
|
||||||
if (!i.id) {
|
"duration=%u WHERE id=%u", new_duration, instance_id);
|
||||||
return;
|
auto results = QueryDatabase(query);
|
||||||
}
|
|
||||||
|
|
||||||
i.start_time = std::time(nullptr);
|
|
||||||
i.duration = new_duration;
|
|
||||||
|
|
||||||
InstanceListRepository::UpdateOne(*this, i);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ namespace DatabaseSchema {
|
|||||||
{"character_expedition_lockouts", "character_id"},
|
{"character_expedition_lockouts", "character_id"},
|
||||||
{"character_exp_modifiers", "character_id"},
|
{"character_exp_modifiers", "character_id"},
|
||||||
{"character_inspect_messages", "id"},
|
{"character_inspect_messages", "id"},
|
||||||
{"character_instance_safereturns", "character_id"},
|
|
||||||
{"character_item_recast", "id"},
|
{"character_item_recast", "id"},
|
||||||
{"character_languages", "id"},
|
{"character_languages", "id"},
|
||||||
{"character_leadership_abilities", "id"},
|
{"character_leadership_abilities", "id"},
|
||||||
@@ -62,16 +61,13 @@ namespace DatabaseSchema {
|
|||||||
{"character_pet_buffs", "char_id"},
|
{"character_pet_buffs", "char_id"},
|
||||||
{"character_pet_info", "char_id"},
|
{"character_pet_info", "char_id"},
|
||||||
{"character_pet_inventory", "char_id"},
|
{"character_pet_inventory", "char_id"},
|
||||||
{"character_peqzone_flags", "id"},
|
|
||||||
{"character_potionbelt", "id"},
|
{"character_potionbelt", "id"},
|
||||||
{"character_skills", "id"},
|
{"character_skills", "id"},
|
||||||
{"character_spells", "id"},
|
{"character_spells", "id"},
|
||||||
{"character_stats_record", "character_id"},
|
|
||||||
{"character_task_timers", "character_id"},
|
|
||||||
{"character_tasks", "charid"},
|
{"character_tasks", "charid"},
|
||||||
{"character_tribute", "character_id"},
|
{"character_tribute", "id"},
|
||||||
{"completed_tasks", "charid"},
|
{"completed_tasks", "charid"},
|
||||||
{"data_buckets", "character_id"},
|
{"data_buckets", "id"},
|
||||||
{"faction_values", "char_id"},
|
{"faction_values", "char_id"},
|
||||||
{"friends", "charid"},
|
{"friends", "charid"},
|
||||||
{"guild_members", "char_id"},
|
{"guild_members", "char_id"},
|
||||||
@@ -84,6 +80,7 @@ namespace DatabaseSchema {
|
|||||||
{"player_titlesets", "char_id"},
|
{"player_titlesets", "char_id"},
|
||||||
{"quest_globals", "charid"},
|
{"quest_globals", "charid"},
|
||||||
{"timers", "char_id"},
|
{"timers", "char_id"},
|
||||||
|
{"titles", "char_id"},
|
||||||
{"trader", "char_id"},
|
{"trader", "char_id"},
|
||||||
{"zone_flags", "charID"}
|
{"zone_flags", "charID"}
|
||||||
};
|
};
|
||||||
@@ -122,7 +119,6 @@ namespace DatabaseSchema {
|
|||||||
"character_expedition_lockouts",
|
"character_expedition_lockouts",
|
||||||
"character_exp_modifiers",
|
"character_exp_modifiers",
|
||||||
"character_inspect_messages",
|
"character_inspect_messages",
|
||||||
"character_instance_safereturns",
|
|
||||||
"character_item_recast",
|
"character_item_recast",
|
||||||
"character_languages",
|
"character_languages",
|
||||||
"character_leadership_abilities",
|
"character_leadership_abilities",
|
||||||
@@ -131,12 +127,9 @@ namespace DatabaseSchema {
|
|||||||
"character_pet_buffs",
|
"character_pet_buffs",
|
||||||
"character_pet_info",
|
"character_pet_info",
|
||||||
"character_pet_inventory",
|
"character_pet_inventory",
|
||||||
"character_peqzone_flags",
|
|
||||||
"character_potionbelt",
|
"character_potionbelt",
|
||||||
"character_skills",
|
"character_skills",
|
||||||
"character_spells",
|
"character_spells",
|
||||||
"character_stats_record",
|
|
||||||
"character_task_timers",
|
|
||||||
"character_tasks",
|
"character_tasks",
|
||||||
"character_tribute",
|
"character_tribute",
|
||||||
"completed_tasks",
|
"completed_tasks",
|
||||||
@@ -161,6 +154,7 @@ namespace DatabaseSchema {
|
|||||||
"spell_buckets",
|
"spell_buckets",
|
||||||
"spell_globals",
|
"spell_globals",
|
||||||
"timers",
|
"timers",
|
||||||
|
"titles",
|
||||||
"trader",
|
"trader",
|
||||||
"trader_audit",
|
"trader_audit",
|
||||||
"zone_flags"
|
"zone_flags"
|
||||||
@@ -191,14 +185,13 @@ namespace DatabaseSchema {
|
|||||||
"char_create_point_allocations",
|
"char_create_point_allocations",
|
||||||
"damageshieldtypes",
|
"damageshieldtypes",
|
||||||
"doors",
|
"doors",
|
||||||
"dynamic_zone_templates",
|
|
||||||
"faction_association",
|
|
||||||
"faction_base_data",
|
"faction_base_data",
|
||||||
"faction_list",
|
"faction_list",
|
||||||
"faction_list_mod",
|
"faction_list_mod",
|
||||||
"fishing",
|
"fishing",
|
||||||
"forage",
|
"forage",
|
||||||
"global_loot",
|
"global_loot",
|
||||||
|
"goallists",
|
||||||
"graveyard",
|
"graveyard",
|
||||||
"grid",
|
"grid",
|
||||||
"grid_entries",
|
"grid_entries",
|
||||||
@@ -224,9 +217,9 @@ namespace DatabaseSchema {
|
|||||||
"npc_types_tint",
|
"npc_types_tint",
|
||||||
"object",
|
"object",
|
||||||
"pets",
|
"pets",
|
||||||
"pets_beastlord_data",
|
|
||||||
"pets_equipmentset",
|
"pets_equipmentset",
|
||||||
"pets_equipmentset_entries",
|
"pets_equipmentset_entries",
|
||||||
|
"proximities",
|
||||||
"skill_caps",
|
"skill_caps",
|
||||||
"spawn2",
|
"spawn2",
|
||||||
"spawn_conditions",
|
"spawn_conditions",
|
||||||
@@ -258,9 +251,7 @@ namespace DatabaseSchema {
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"chatchannels",
|
"chatchannels",
|
||||||
"chatchannel_reserved_names",
|
|
||||||
"command_settings",
|
"command_settings",
|
||||||
"command_subsettings",
|
|
||||||
"content_flags",
|
"content_flags",
|
||||||
"db_str",
|
"db_str",
|
||||||
"eqtime",
|
"eqtime",
|
||||||
@@ -274,7 +265,6 @@ namespace DatabaseSchema {
|
|||||||
"perl_event_export_settings",
|
"perl_event_export_settings",
|
||||||
"profanity_list",
|
"profanity_list",
|
||||||
"rule_sets",
|
"rule_sets",
|
||||||
"titles",
|
|
||||||
"rule_values",
|
"rule_values",
|
||||||
"variables",
|
"variables",
|
||||||
};
|
};
|
||||||
@@ -319,24 +309,20 @@ namespace DatabaseSchema {
|
|||||||
"banned_ips",
|
"banned_ips",
|
||||||
"bug_reports",
|
"bug_reports",
|
||||||
"bugs",
|
"bugs",
|
||||||
"completed_shared_task_activity_state",
|
|
||||||
"completed_shared_task_members",
|
|
||||||
"completed_shared_tasks",
|
|
||||||
"discord_webhooks",
|
|
||||||
"dynamic_zone_members",
|
"dynamic_zone_members",
|
||||||
"dynamic_zones",
|
"dynamic_zones",
|
||||||
|
"eventlog",
|
||||||
"expedition_lockouts",
|
"expedition_lockouts",
|
||||||
"expeditions",
|
"expeditions",
|
||||||
"gm_ips",
|
"gm_ips",
|
||||||
"group_id",
|
"group_id",
|
||||||
"group_leaders",
|
"group_leaders",
|
||||||
"instance_list",
|
"hackers",
|
||||||
"ip_exemptions",
|
"ip_exemptions",
|
||||||
|
"instance_list",
|
||||||
"item_tick",
|
"item_tick",
|
||||||
"lfguild",
|
"lfguild",
|
||||||
"merc_buffs",
|
|
||||||
"merchantlist_temp",
|
"merchantlist_temp",
|
||||||
"mercs",
|
|
||||||
"object_contents",
|
"object_contents",
|
||||||
"raid_details",
|
"raid_details",
|
||||||
"raid_leaders",
|
"raid_leaders",
|
||||||
@@ -345,13 +331,6 @@ namespace DatabaseSchema {
|
|||||||
"respawn_times",
|
"respawn_times",
|
||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"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",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,57 +363,6 @@ namespace DatabaseSchema {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
#endif //EQEMU_DATABASE_SCHEMA_H
|
||||||
|
|||||||
+45
-183
@@ -13,7 +13,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "strings.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@@ -35,8 +34,7 @@
|
|||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore()
|
||||||
{
|
{
|
||||||
mysql = mysql_init(nullptr);
|
mysql_init(&mysql);
|
||||||
mysqlOwner = true;
|
|
||||||
pHost = nullptr;
|
pHost = nullptr;
|
||||||
pUser = nullptr;
|
pUser = nullptr;
|
||||||
pPassword = nullptr;
|
pPassword = nullptr;
|
||||||
@@ -44,7 +42,6 @@ DBcore::DBcore()
|
|||||||
pCompress = false;
|
pCompress = false;
|
||||||
pSSL = false;
|
pSSL = false;
|
||||||
pStatus = Closed;
|
pStatus = Closed;
|
||||||
m_mutex = new Mutex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBcore::~DBcore()
|
DBcore::~DBcore()
|
||||||
@@ -54,10 +51,16 @@ DBcore::~DBcore()
|
|||||||
* are re-using the default database connection pointer when we dont have an
|
* are re-using the default database connection pointer when we dont have an
|
||||||
* external configuration setup ex: (content_database)
|
* external configuration setup ex: (content_database)
|
||||||
*/
|
*/
|
||||||
if (mysqlOwner) {
|
std::string mysql_connection_host;
|
||||||
mysql_close(mysql);
|
if (mysql.host) {
|
||||||
|
mysql_connection_host = mysql.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetOriginHost() != mysql_connection_host) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_close(&mysql);
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
safe_delete_array(pPassword);
|
safe_delete_array(pPassword);
|
||||||
@@ -67,21 +70,20 @@ DBcore::~DBcore()
|
|||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping()
|
||||||
{
|
{
|
||||||
if (!m_mutex->trylock()) {
|
if (!MDatabase.trylock()) {
|
||||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mysql_ping(mysql);
|
mysql_ping(&mysql);
|
||||||
m_mutex->unlock();
|
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 QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::DoesTableExist(const std::string& table_name)
|
bool DBcore::DoesTableExist(std::string table_name)
|
||||||
{
|
{
|
||||||
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
|
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
|
||||||
|
|
||||||
@@ -93,16 +95,18 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
LockMutex lock(&MDatabase);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
Open();
|
Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// request query. != 0 indicates some kind of error.
|
// request query. != 0 indicates some kind of error.
|
||||||
if (mysql_real_query(mysql, query, querylen) != 0) {
|
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
||||||
unsigned int errorNumber = mysql_errno(mysql);
|
unsigned int errorNumber = mysql_errno(&mysql);
|
||||||
|
|
||||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
@@ -126,26 +130,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
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];
|
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
|
* Error logging
|
||||||
*/
|
*/
|
||||||
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
||||||
LogMySQLError("MySQL Error ({}) [{}] Query [{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
LogMySQLError("[{}] [{}]\n[{}]", 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.
|
// successful query. get results.
|
||||||
MYSQL_RES *res = mysql_store_result(mysql);
|
MYSQL_RES *res = mysql_store_result(&mysql);
|
||||||
uint32 rowCount = 0;
|
uint32 rowCount = 0;
|
||||||
|
|
||||||
if (res != nullptr) {
|
if (res != nullptr) {
|
||||||
@@ -154,16 +158,16 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
MySQLRequestResult requestResult(
|
MySQLRequestResult requestResult(
|
||||||
res,
|
res,
|
||||||
(uint32) mysql_affected_rows(mysql),
|
(uint32) mysql_affected_rows(&mysql),
|
||||||
rowCount,
|
rowCount,
|
||||||
(uint32) mysql_field_count(mysql),
|
(uint32) mysql_field_count(&mysql),
|
||||||
(uint32) mysql_insert_id(mysql)
|
(uint32) mysql_insert_id(&mysql)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||||
if ((strncasecmp(query, "select", 6) == 0)) {
|
if ((strncasecmp(query, "select", 6) == 0)) {
|
||||||
LogMySQLQuery(
|
LogMySQLQuery(
|
||||||
"{0} -- ({1} row{2} returned) ({3}s)",
|
"{0} ({1} row{2} returned) ({3}s)",
|
||||||
query,
|
query,
|
||||||
requestResult.RowCount(),
|
requestResult.RowCount(),
|
||||||
requestResult.RowCount() == 1 ? "" : "s",
|
requestResult.RowCount() == 1 ? "" : "s",
|
||||||
@@ -172,7 +176,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogMySQLQuery(
|
LogMySQLQuery(
|
||||||
"{0} -- ({1} row{2} affected) ({3}s)",
|
"{0} ({1} row{2} affected) ({3}s)",
|
||||||
query,
|
query,
|
||||||
requestResult.RowsAffected(),
|
requestResult.RowsAffected(),
|
||||||
requestResult.RowsAffected() == 1 ? "" : "s",
|
requestResult.RowsAffected() == 1 ? "" : "s",
|
||||||
@@ -203,7 +207,7 @@ 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.
|
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
||||||
// LockMutex lock(&MDatabase);
|
// LockMutex lock(&MDatabase);
|
||||||
return mysql_real_escape_string(mysql, tobuf, frombuf, fromlen);
|
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::Open(
|
bool DBcore::Open(
|
||||||
@@ -218,7 +222,7 @@ bool DBcore::Open(
|
|||||||
bool iSSL
|
bool iSSL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LockMutex lock(m_mutex);
|
LockMutex lock(&MDatabase);
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
safe_delete_array(pPassword);
|
safe_delete_array(pPassword);
|
||||||
@@ -238,13 +242,13 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
}
|
||||||
LockMutex lock(m_mutex);
|
LockMutex lock(&MDatabase);
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (GetStatus() == Error) {
|
if (GetStatus() == Error) {
|
||||||
mysql_close(mysql);
|
mysql_close(&mysql);
|
||||||
mysql_init(mysql); // Initialize structure again
|
mysql_init(&mysql); // Initialize structure again
|
||||||
}
|
}
|
||||||
if (!pHost) {
|
if (!pHost) {
|
||||||
return false;
|
return false;
|
||||||
@@ -261,7 +265,7 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (pSSL) {
|
if (pSSL) {
|
||||||
flags |= CLIENT_SSL;
|
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;
|
pStatus = Connected;
|
||||||
|
|
||||||
std::string connected_origin_host = pHost;
|
std::string connected_origin_host = pHost;
|
||||||
@@ -271,16 +275,21 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (errnum) {
|
if (errnum) {
|
||||||
*errnum = mysql_errno(mysql);
|
*errnum = mysql_errno(&mysql);
|
||||||
}
|
}
|
||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
}
|
}
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DBcore::SetMysql(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
DBcore::mysql = *mysql;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string &DBcore::GetOriginHost() const
|
const std::string &DBcore::GetOriginHost() const
|
||||||
{
|
{
|
||||||
return origin_host;
|
return origin_host;
|
||||||
@@ -290,150 +299,3 @@ void DBcore::SetOriginHost(const std::string &origin_host)
|
|||||||
{
|
{
|
||||||
DBcore::origin_host = 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;
|
|
||||||
}
|
|
||||||
|
|||||||
+7
-30
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
@@ -24,26 +23,19 @@ public:
|
|||||||
~DBcore();
|
~DBcore();
|
||||||
eStatus GetStatus() { return pStatus; }
|
eStatus GetStatus() { return pStatus; }
|
||||||
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
||||||
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
|
||||||
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
|
||||||
void TransactionBegin();
|
void TransactionBegin();
|
||||||
void TransactionCommit();
|
void TransactionCommit();
|
||||||
void TransactionRollback();
|
void TransactionRollback();
|
||||||
std::string Escape(const std::string& s);
|
|
||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
void ping();
|
void ping();
|
||||||
|
MYSQL *getMySQL() { return &mysql; }
|
||||||
|
void SetMysql(MYSQL *mysql);
|
||||||
|
|
||||||
const std::string &GetOriginHost() const;
|
const std::string &GetOriginHost() const;
|
||||||
void SetOriginHost(const std::string &origin_host);
|
void SetOriginHost(const std::string &origin_host);
|
||||||
|
|
||||||
bool DoesTableExist(const std::string& table_name);
|
bool DoesTableExist(std::string table_name);
|
||||||
|
|
||||||
void SetMySQL(const DBcore &o)
|
|
||||||
{
|
|
||||||
mysql = o.mysql;
|
|
||||||
mysqlOwner = false;
|
|
||||||
}
|
|
||||||
void SetMutex(Mutex *mutex);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Open(
|
bool Open(
|
||||||
@@ -61,13 +53,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||||
|
|
||||||
MYSQL* mysql;
|
MYSQL mysql;
|
||||||
bool mysqlOwner;
|
Mutex MDatabase;
|
||||||
Mutex *m_mutex;
|
|
||||||
eStatus pStatus;
|
eStatus pStatus;
|
||||||
|
|
||||||
std::mutex m_query_lock{};
|
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
char *pHost;
|
char *pHost;
|
||||||
@@ -78,20 +67,8 @@ private:
|
|||||||
uint32 pPort;
|
uint32 pPort;
|
||||||
bool pSSL;
|
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
|
#endif
|
||||||
|
|
||||||
|
|||||||
+84
-34
@@ -19,7 +19,8 @@
|
|||||||
|
|
||||||
#include "deity.h"
|
#include "deity.h"
|
||||||
|
|
||||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
|
||||||
|
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
||||||
{
|
{
|
||||||
switch (deity_type) {
|
switch (deity_type) {
|
||||||
case DeityBertoxxulous:
|
case DeityBertoxxulous:
|
||||||
@@ -59,41 +60,90 @@ EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
|||||||
return bit_DeityAgnostic;
|
return bit_DeityAgnostic;
|
||||||
default:
|
default:
|
||||||
return bit_DeityAll;
|
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" }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return deity_map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
||||||
{
|
{
|
||||||
|
switch (deity_type_bit) {
|
||||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
case bit_DeityAgnostic:
|
||||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
return DeityAgnostic;
|
||||||
}
|
case bit_DeityBertoxxulous:
|
||||||
|
return DeityBertoxxulous;
|
||||||
return std::string();
|
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* EQ::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";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-6
@@ -21,8 +21,6 @@
|
|||||||
#define COMMON_DEITY_H
|
#define COMMON_DEITY_H
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
@@ -51,6 +49,7 @@ namespace EQ
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum DeityTypeBit : uint32 {
|
enum DeityTypeBit : uint32 {
|
||||||
|
bit_DeityNone = 0x00000000,
|
||||||
bit_DeityAgnostic = 0x00000001,
|
bit_DeityAgnostic = 0x00000001,
|
||||||
bit_DeityBertoxxulous = 0x00000002,
|
bit_DeityBertoxxulous = 0x00000002,
|
||||||
bit_DeityBrellSirilis = 0x00000004,
|
bit_DeityBrellSirilis = 0x00000004,
|
||||||
@@ -68,12 +67,12 @@ namespace EQ
|
|||||||
bit_DeityTheTribunal = 0x00004000,
|
bit_DeityTheTribunal = 0x00004000,
|
||||||
bit_DeityTunare = 0x00008000,
|
bit_DeityTunare = 0x00008000,
|
||||||
bit_DeityVeeshan = 0x00010000,
|
bit_DeityVeeshan = 0x00010000,
|
||||||
bit_DeityAll = UINT32_MAX
|
bit_DeityAll = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
|
||||||
extern std::string GetDeityName(DeityType deity_type);
|
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
|
||||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
extern const char* DeityName(DeityType deity_type);
|
||||||
|
|
||||||
} /*deity*/
|
} /*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
|
|
||||||
+48
-267
@@ -5,7 +5,6 @@
|
|||||||
#include "repositories/instance_list_player_repository.h"
|
#include "repositories/instance_list_player_repository.h"
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
#include "servertalk.h"
|
#include "servertalk.h"
|
||||||
#include "util/uuid.h"
|
|
||||||
|
|
||||||
DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry)
|
DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry)
|
||||||
{
|
{
|
||||||
@@ -14,12 +13,16 @@ DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& e
|
|||||||
|
|
||||||
uint32_t DynamicZoneBase::Create()
|
uint32_t DynamicZoneBase::Create()
|
||||||
{
|
{
|
||||||
|
if (m_id != 0)
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetInstanceID() == 0)
|
if (GetInstanceID() == 0)
|
||||||
{
|
{
|
||||||
CreateInstance();
|
CreateInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_uuid = EQ::Util::UUID::Generate().ToString();
|
|
||||||
m_id = SaveToDatabase();
|
m_id = SaveToDatabase();
|
||||||
|
|
||||||
return m_id;
|
return m_id;
|
||||||
@@ -72,14 +75,8 @@ uint32_t DynamicZoneBase::CreateInstance()
|
|||||||
void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry)
|
void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry)
|
||||||
{
|
{
|
||||||
m_id = dz_entry.id;
|
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_instance_id = dz_entry.instance_id;
|
||||||
m_type = static_cast<DynamicZoneType>(dz_entry.type);
|
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.zone_id = dz_entry.compass_zone_id;
|
||||||
m_compass.x = dz_entry.compass_x;
|
m_compass.x = dz_entry.compass_x;
|
||||||
m_compass.y = dz_entry.compass_y;
|
m_compass.y = dz_entry.compass_y;
|
||||||
@@ -107,12 +104,6 @@ void DynamicZoneBase::AddMemberFromRepositoryResult(
|
|||||||
DynamicZoneMembersRepository::MemberWithName&& entry)
|
DynamicZoneMembersRepository::MemberWithName&& entry)
|
||||||
{
|
{
|
||||||
auto status = DynamicZoneMemberStatus::Unknown;
|
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 });
|
AddInternalMember({ entry.character_id, std::move(entry.character_name), status });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,14 +114,8 @@ uint32_t DynamicZoneBase::SaveToDatabase()
|
|||||||
if (m_instance_id != 0)
|
if (m_instance_id != 0)
|
||||||
{
|
{
|
||||||
auto insert_dz = DynamicZonesRepository::NewEntity();
|
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.instance_id = m_instance_id,
|
||||||
insert_dz.type = static_cast<int>(m_type);
|
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_zone_id = m_compass.zone_id;
|
||||||
insert_dz.compass_x = m_compass.x;
|
insert_dz.compass_x = m_compass.x;
|
||||||
insert_dz.compass_y = m_compass.y;
|
insert_dz.compass_y = m_compass.y;
|
||||||
@@ -152,80 +137,34 @@ uint32_t DynamicZoneBase::SaveToDatabase()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicZoneBase::AddMember(const DynamicZoneMember& add_member)
|
void DynamicZoneBase::AddCharacter(uint32_t character_id)
|
||||||
{
|
{
|
||||||
if (HasMember(add_member.id))
|
DynamicZoneMembersRepository::AddMember(GetDatabase(), m_id, character_id);
|
||||||
|
GetDatabase().AddClientToInstance(m_instance_id, character_id);
|
||||||
|
SendInstanceAddRemoveCharacter(character_id, false); // stops client kick timer
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicZoneBase::RemoveCharacter(uint32_t character_id)
|
||||||
|
{
|
||||||
|
DynamicZoneMembersRepository::RemoveMember(GetDatabase(), m_id, character_id);
|
||||||
|
GetDatabase().RemoveClientFromInstance(m_instance_id, character_id);
|
||||||
|
SendInstanceAddRemoveCharacter(character_id, true); // start client kick timer
|
||||||
|
}
|
||||||
|
|
||||||
|
void DynamicZoneBase::RemoveAllCharacters(bool enable_removal_timers)
|
||||||
|
{
|
||||||
|
if (GetInstanceID() == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicZoneMembersRepository::AddMember(GetDatabase(), m_id, add_member.id);
|
if (enable_removal_timers)
|
||||||
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;
|
SendInstanceRemoveAllCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
DynamicZoneMembersRepository::RemoveAllMembers(GetDatabase(), m_id);
|
||||||
GetDatabase().RemoveClientsFromInstance(GetInstanceID());
|
GetDatabase().RemoveClientsFromInstance(GetInstanceID());
|
||||||
|
|
||||||
ProcessRemoveAllMembers();
|
|
||||||
SendServerPacket(CreateServerRemoveAllMembersPacket().get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
|
void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
|
||||||
@@ -242,6 +181,7 @@ void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
|
|||||||
DynamicZoneMembersRepository::DynamicZoneMembers member_entry{};
|
DynamicZoneMembersRepository::DynamicZoneMembers member_entry{};
|
||||||
member_entry.dynamic_zone_id = m_id;
|
member_entry.dynamic_zone_id = m_id;
|
||||||
member_entry.character_id = member.id;
|
member_entry.character_id = member.id;
|
||||||
|
member_entry.is_current_member = true;
|
||||||
insert_members.emplace_back(member_entry);
|
insert_members.emplace_back(member_entry);
|
||||||
|
|
||||||
InstanceListPlayerRepository::InstanceListPlayer player_entry;
|
InstanceListPlayerRepository::InstanceListPlayer player_entry;
|
||||||
@@ -266,7 +206,7 @@ void DynamicZoneBase::SetCompass(const DynamicZoneLocation& location, bool updat
|
|||||||
DynamicZonesRepository::UpdateCompass(GetDatabase(),
|
DynamicZonesRepository::UpdateCompass(GetDatabase(),
|
||||||
m_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z);
|
m_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z);
|
||||||
|
|
||||||
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetCompass, location).get());
|
SendGlobalLocationChange(ServerOP_DzSetCompass, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +227,7 @@ void DynamicZoneBase::SetSafeReturn(const DynamicZoneLocation& location, bool up
|
|||||||
DynamicZonesRepository::UpdateSafeReturn(GetDatabase(), m_id, m_safereturn.zone_id,
|
DynamicZonesRepository::UpdateSafeReturn(GetDatabase(), m_id, m_safereturn.zone_id,
|
||||||
m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading);
|
m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading);
|
||||||
|
|
||||||
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetSafeReturn, location).get());
|
SendGlobalLocationChange(ServerOP_DzSetSafeReturn, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +249,7 @@ void DynamicZoneBase::SetZoneInLocation(const DynamicZoneLocation& location, boo
|
|||||||
DynamicZonesRepository::UpdateZoneIn(GetDatabase(), m_id, m_zone_id,
|
DynamicZonesRepository::UpdateZoneIn(GetDatabase(), m_id, m_zone_id,
|
||||||
m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading, m_has_zonein);
|
m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading, m_has_zonein);
|
||||||
|
|
||||||
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetZoneIn, location).get());
|
SendGlobalLocationChange(ServerOP_DzSetZoneIn, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,82 +258,35 @@ void DynamicZoneBase::SetZoneInLocation(float x, float y, float z, float heading
|
|||||||
SetZoneInLocation({ 0, x, y, z, heading }, 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
|
uint32_t DynamicZoneBase::GetSecondsRemaining() const
|
||||||
{
|
{
|
||||||
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(GetDurationRemaining()).count();
|
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(GetDurationRemaining()).count();
|
||||||
return std::max(0, static_cast<int>(remaining));
|
return std::max(0, static_cast<int>(remaining));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberAddRemovePacket(
|
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerAddRemoveCharacterPacket(
|
||||||
const DynamicZoneMember& member, bool removed)
|
uint32_t character_id, bool removed)
|
||||||
{
|
{
|
||||||
constexpr uint32_t pack_size = sizeof(ServerDzMember_Struct);
|
constexpr uint32_t pack_size = sizeof(ServerDzCharacter_Struct);
|
||||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzAddRemoveMember, pack_size);
|
auto pack = std::make_unique<ServerPacket>(ServerOP_DzAddRemoveCharacter, pack_size);
|
||||||
auto buf = reinterpret_cast<ServerDzMember_Struct*>(pack->pBuffer);
|
auto buf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
||||||
buf->dz_id = GetID();
|
buf->zone_id = GetZoneID();
|
||||||
buf->dz_zone_id = GetZoneID();
|
buf->instance_id = GetInstanceID();
|
||||||
buf->dz_instance_id = GetInstanceID();
|
buf->remove = removed;
|
||||||
buf->sender_zone_id = GetCurrentZoneID();
|
buf->character_id = character_id;
|
||||||
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;
|
return pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberSwapPacket(
|
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerRemoveAllCharactersPacket()
|
||||||
const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member)
|
|
||||||
{
|
{
|
||||||
constexpr uint32_t pack_size = sizeof(ServerDzMemberSwap_Struct);
|
constexpr uint32_t pack_size = sizeof(ServerDzCharacter_Struct);
|
||||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSwapMembers, pack_size);
|
auto pack = std::make_unique<ServerPacket>(ServerOP_DzRemoveAllCharacters, pack_size);
|
||||||
auto buf = reinterpret_cast<ServerDzMemberSwap_Struct*>(pack->pBuffer);
|
auto buf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
||||||
buf->dz_id = GetID();
|
buf->zone_id = GetZoneID();
|
||||||
buf->dz_zone_id = GetZoneID();
|
buf->instance_id = GetInstanceID();
|
||||||
buf->dz_instance_id = GetInstanceID();
|
buf->remove = true;
|
||||||
buf->sender_zone_id = GetCurrentZoneID();
|
buf->character_id = 0;
|
||||||
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;
|
return pack;
|
||||||
}
|
}
|
||||||
@@ -416,36 +309,10 @@ std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzLocationPacket(
|
|||||||
return pack;
|
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()
|
uint32_t DynamicZoneBase::GetDatabaseMemberCount()
|
||||||
{
|
{
|
||||||
return DynamicZoneMembersRepository::GetCountWhere(GetDatabase(),
|
return DynamicZoneMembersRepository::GetCountWhere(GetDatabase(),
|
||||||
fmt::format("dynamic_zone_id = {}", m_id));
|
fmt::format("dynamic_zone_id = {} AND is_current_member = TRUE", m_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DynamicZoneBase::HasDatabaseMember(uint32_t character_id)
|
bool DynamicZoneBase::HasDatabaseMember(uint32_t character_id)
|
||||||
@@ -456,7 +323,7 @@ bool DynamicZoneBase::HasDatabaseMember(uint32_t character_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto entries = DynamicZoneMembersRepository::GetWhere(GetDatabase(), fmt::format(
|
auto entries = DynamicZoneMembersRepository::GetWhere(GetDatabase(), fmt::format(
|
||||||
"dynamic_zone_id = {} AND character_id = {}",
|
"dynamic_zone_id = {} AND character_id = {} AND is_current_member = TRUE",
|
||||||
m_id, character_id
|
m_id, character_id
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -544,33 +411,6 @@ bool DynamicZoneBase::SetInternalMemberStatus(uint32_t character_id, DynamicZone
|
|||||||
return false;
|
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)
|
std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
|
||||||
{
|
{
|
||||||
switch (dz_type)
|
switch (dz_type)
|
||||||
@@ -585,65 +425,6 @@ std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
|
|||||||
return "Mission";
|
return "Mission";
|
||||||
case DynamicZoneType::Quest:
|
case DynamicZoneType::Quest:
|
||||||
return "Quest";
|
return "Quest";
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
}
|
||||||
}
|
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-81
@@ -2,10 +2,8 @@
|
|||||||
#define COMMON_DYNAMIC_ZONE_BASE_H
|
#define COMMON_DYNAMIC_ZONE_BASE_H
|
||||||
|
|
||||||
#include "eq_constants.h"
|
#include "eq_constants.h"
|
||||||
#include "net/packet.h"
|
|
||||||
#include "repositories/dynamic_zones_repository.h"
|
#include "repositories/dynamic_zones_repository.h"
|
||||||
#include "repositories/dynamic_zone_members_repository.h"
|
#include "repositories/dynamic_zone_members_repository.h"
|
||||||
#include "repositories/dynamic_zone_templates_repository.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -20,7 +18,7 @@ struct DynamicZoneMember
|
|||||||
{
|
{
|
||||||
uint32_t id = 0;
|
uint32_t id = 0;
|
||||||
std::string name;
|
std::string name;
|
||||||
DynamicZoneMemberStatus status = DynamicZoneMemberStatus::Unknown;
|
DynamicZoneMemberStatus status = DynamicZoneMemberStatus::Online;
|
||||||
|
|
||||||
DynamicZoneMember() = default;
|
DynamicZoneMember() = default;
|
||||||
DynamicZoneMember(uint32_t id, std::string name_)
|
DynamicZoneMember(uint32_t id, std::string name_)
|
||||||
@@ -31,12 +29,6 @@ struct DynamicZoneMember
|
|||||||
bool IsOnline() const { return status == DynamicZoneMemberStatus::Online ||
|
bool IsOnline() const { return status == DynamicZoneMemberStatus::Online ||
|
||||||
status == DynamicZoneMemberStatus::InDynamicZone; }
|
status == DynamicZoneMemberStatus::InDynamicZone; }
|
||||||
bool IsValid() const { return id != 0 && !name.empty(); }
|
bool IsValid() const { return id != 0 && !name.empty(); }
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& archive)
|
|
||||||
{
|
|
||||||
archive(id, name, status);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DynamicZoneLocation
|
struct DynamicZoneLocation
|
||||||
@@ -50,12 +42,6 @@ struct DynamicZoneLocation
|
|||||||
DynamicZoneLocation() = default;
|
DynamicZoneLocation() = default;
|
||||||
DynamicZoneLocation(uint32_t zone_id_, float x_, float y_, float z_, float heading_)
|
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_) {}
|
: 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
|
class DynamicZoneBase
|
||||||
@@ -75,11 +61,9 @@ public:
|
|||||||
|
|
||||||
virtual void SetSecondsRemaining(uint32_t seconds_remaining) = 0;
|
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); }
|
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
||||||
uint32_t GetID() const { return m_id; }
|
uint32_t GetID() const { return m_id; }
|
||||||
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_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 GetMaxPlayers() const { return m_max_players; }
|
||||||
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
|
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
|
||||||
uint32_t GetMinPlayers() const { return m_min_players; }
|
uint32_t GetMinPlayers() const { return m_min_players; }
|
||||||
@@ -87,11 +71,9 @@ public:
|
|||||||
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
|
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 GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
|
||||||
uint32_t GetZoneVersion() const { return m_zone_version; }
|
uint32_t GetZoneVersion() const { return m_zone_version; }
|
||||||
int GetSwitchID() const { return m_dz_switch_id; }
|
|
||||||
DynamicZoneType GetType() const { return m_type; }
|
DynamicZoneType GetType() const { return m_type; }
|
||||||
const std::string& GetLeaderName() const { return m_leader.name; }
|
const std::string& GetLeaderName() const { return m_leader.name; }
|
||||||
const std::string& GetName() const { return m_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 DynamicZoneMember& GetLeader() const { return m_leader; }
|
||||||
const std::vector<DynamicZoneMember>& GetMembers() const { return m_members; }
|
const std::vector<DynamicZoneMember>& GetMembers() const { return m_members; }
|
||||||
const DynamicZoneLocation& GetCompassLocation() const { return m_compass; }
|
const DynamicZoneLocation& GetCompassLocation() const { return m_compass; }
|
||||||
@@ -99,12 +81,14 @@ public:
|
|||||||
const DynamicZoneLocation& GetZoneInLocation() const { return m_zonein; }
|
const DynamicZoneLocation& GetZoneInLocation() const { return m_zonein; }
|
||||||
std::chrono::system_clock::duration GetDurationRemaining() const { return m_expire_time - std::chrono::system_clock::now(); }
|
std::chrono::system_clock::duration GetDurationRemaining() const { return m_expire_time - std::chrono::system_clock::now(); }
|
||||||
|
|
||||||
bool AddMember(const DynamicZoneMember& add_member);
|
void AddCharacter(uint32_t character_id);
|
||||||
|
void AddInternalMember(const DynamicZoneMember& member);
|
||||||
void AddMemberFromRepositoryResult(DynamicZoneMembersRepository::MemberWithName&& entry);
|
void AddMemberFromRepositoryResult(DynamicZoneMembersRepository::MemberWithName&& entry);
|
||||||
|
void ClearInternalMembers() { m_members.clear(); }
|
||||||
|
uint32_t Create();
|
||||||
uint32_t GetDatabaseMemberCount();
|
uint32_t GetDatabaseMemberCount();
|
||||||
DynamicZoneMember GetMemberData(uint32_t character_id);
|
DynamicZoneMember GetMemberData(uint32_t character_id);
|
||||||
DynamicZoneMember GetMemberData(const std::string& character_name);
|
DynamicZoneMember GetMemberData(const std::string& character_name);
|
||||||
EQ::Net::DynamicPacket GetSerializedDzPacket();
|
|
||||||
bool HasDatabaseMember(uint32_t character_id);
|
bool HasDatabaseMember(uint32_t character_id);
|
||||||
bool HasMember(uint32_t character_id);
|
bool HasMember(uint32_t character_id);
|
||||||
bool HasMember(const std::string& character_name);
|
bool HasMember(const std::string& character_name);
|
||||||
@@ -114,56 +98,38 @@ public:
|
|||||||
bool IsInstanceID(uint32_t instance_id) const { return (m_instance_id != 0 && m_instance_id == instance_id); }
|
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 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; }
|
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 RemoveAllCharacters(bool enable_removal_timers = true);
|
||||||
void LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template);
|
void RemoveCharacter(uint32_t character_id);
|
||||||
void RemoveAllMembers();
|
void RemoveInternalMember(uint32_t character_id);
|
||||||
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 SaveMembers(const std::vector<DynamicZoneMember>& members);
|
||||||
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
|
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 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); }
|
bool SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||||
void SetLeader(const DynamicZoneMember& leader, bool update_db = false);
|
void SetLeader(const DynamicZoneMember& leader) { m_leader = leader; }
|
||||||
void SetMaxPlayers(uint32_t max_players) { m_max_players = max_players; }
|
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 SetMinPlayers(uint32_t min_players) { m_min_players = min_players; }
|
||||||
void SetName(const std::string& name) { m_name = name; }
|
void SetName(const std::string& name) { m_name = name; }
|
||||||
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
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 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(const DynamicZoneLocation& location, bool update_db = false);
|
||||||
void SetZoneInLocation(float x, float y, float z, float heading, 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:
|
protected:
|
||||||
virtual uint16_t GetCurrentInstanceID() { return 0; }
|
virtual uint16_t GetCurrentInstanceID() { return 0; }
|
||||||
virtual uint16_t GetCurrentZoneID() { return 0; }
|
virtual uint16_t GetCurrentZoneID() { return 0; }
|
||||||
virtual Database& GetDatabase() = 0;
|
virtual Database& GetDatabase() = 0;
|
||||||
virtual void ProcessCompassChange(const DynamicZoneLocation& location) { m_compass = location; }
|
virtual void ProcessCompassChange(const DynamicZoneLocation& location) { m_compass = location; }
|
||||||
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
|
virtual void SendInstanceAddRemoveCharacter(uint32_t character_id, bool remove) = 0;
|
||||||
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
|
virtual void SendInstanceRemoveAllCharacters() = 0;
|
||||||
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
|
virtual void SendGlobalLocationChange(uint16_t server_opcode, const DynamicZoneLocation& location) = 0;
|
||||||
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();
|
uint32_t CreateInstance();
|
||||||
void LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry);
|
void LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry);
|
||||||
void RemoveInternalMember(uint32_t character_id);
|
|
||||||
uint32_t SaveToDatabase();
|
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> CreateServerAddRemoveCharacterPacket(uint32_t character_id, bool removed);
|
||||||
|
std::unique_ptr<ServerPacket> CreateServerRemoveAllCharactersPacket();
|
||||||
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
|
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_id = 0;
|
||||||
uint32_t m_zone_id = 0;
|
uint32_t m_zone_id = 0;
|
||||||
@@ -171,12 +137,9 @@ protected:
|
|||||||
uint32_t m_zone_version = 0;
|
uint32_t m_zone_version = 0;
|
||||||
uint32_t m_min_players = 0;
|
uint32_t m_min_players = 0;
|
||||||
uint32_t m_max_players = 0;
|
uint32_t m_max_players = 0;
|
||||||
int m_dz_switch_id = 0;
|
|
||||||
bool m_never_expires = false;
|
bool m_never_expires = false;
|
||||||
bool m_has_zonein = false;
|
bool m_has_zonein = false;
|
||||||
bool m_has_member_statuses = false;
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::string m_uuid;
|
|
||||||
DynamicZoneMember m_leader;
|
DynamicZoneMember m_leader;
|
||||||
DynamicZoneType m_type{ DynamicZoneType::None };
|
DynamicZoneType m_type{ DynamicZoneType::None };
|
||||||
DynamicZoneLocation m_compass;
|
DynamicZoneLocation m_compass;
|
||||||
@@ -186,35 +149,6 @@ protected:
|
|||||||
std::chrono::time_point<std::chrono::system_clock> m_start_time;
|
std::chrono::time_point<std::chrono::system_clock> m_start_time;
|
||||||
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
|
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
|
||||||
std::vector<DynamicZoneMember> m_members;
|
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
|
#endif
|
||||||
|
|||||||
+2
-430
@@ -18,12 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu_constants.h"
|
#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 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||||
static const int16 local_array[] = {
|
static const int16 local_array[] = {
|
||||||
@@ -152,431 +147,8 @@ const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
if (stance_type >= EQ::constants::stancePassive && stance_type <= EQ::constants::stanceBurnAE)
|
||||||
return (stance_type - EQ::constants::stancePassive);
|
return (stance_type - EQ::constants::stancePassive);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
+11
-295
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "eq_limits.h"
|
#include "eq_limits.h"
|
||||||
#include "emu_versions.h"
|
#include "emu_versions.h"
|
||||||
#include "bodytypes.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -33,6 +32,10 @@ namespace EQ
|
|||||||
using RoF2::IINVALID;
|
using RoF2::IINVALID;
|
||||||
using RoF2::INULL;
|
using RoF2::INULL;
|
||||||
|
|
||||||
|
namespace inventory {
|
||||||
|
|
||||||
|
} /*inventory*/
|
||||||
|
|
||||||
namespace invtype {
|
namespace invtype {
|
||||||
using namespace RoF2::invtype::enum_;
|
using namespace RoF2::invtype::enum_;
|
||||||
|
|
||||||
@@ -217,186 +220,9 @@ namespace EQ
|
|||||||
stanceBurnAE
|
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);
|
const char *GetStanceName(StanceType stance_type);
|
||||||
int ConvertStanceTypeToIndex(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_FIRST = stancePassive;
|
||||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||||
@@ -499,123 +325,13 @@ namespace EQ
|
|||||||
Guild
|
Guild
|
||||||
};
|
};
|
||||||
}; // namespace consent
|
}; // namespace consent
|
||||||
|
|
||||||
} /*EQEmu*/
|
} /*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*/
|
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||||
|
|
||||||
|
/* hack list to prevent circular references
|
||||||
|
|
||||||
|
eq_limits.h:EQ::inventory::LookupEntry::InventoryTypeSize[n];
|
||||||
|
|
||||||
|
*/
|
||||||
|
|||||||
+5
-27
@@ -35,7 +35,7 @@ N(OP_AltCurrencyMerchantRequest),
|
|||||||
N(OP_AltCurrencyPurchase),
|
N(OP_AltCurrencyPurchase),
|
||||||
N(OP_AltCurrencyReclaim),
|
N(OP_AltCurrencyReclaim),
|
||||||
N(OP_AltCurrencySell),
|
N(OP_AltCurrencySell),
|
||||||
N(OP_AltCurrencySellSelection), // Used by eqstr_us.txt 8066, 8068, 8069
|
N(OP_AltCurrencySellSelection),
|
||||||
N(OP_Animation),
|
N(OP_Animation),
|
||||||
N(OP_AnnoyingZoneUnknown),
|
N(OP_AnnoyingZoneUnknown),
|
||||||
N(OP_ApplyPoison),
|
N(OP_ApplyPoison),
|
||||||
@@ -62,7 +62,6 @@ N(OP_BeginCast),
|
|||||||
N(OP_Bind_Wound),
|
N(OP_Bind_Wound),
|
||||||
N(OP_BlockedBuffs),
|
N(OP_BlockedBuffs),
|
||||||
N(OP_BoardBoat),
|
N(OP_BoardBoat),
|
||||||
N(OP_BookButton),
|
|
||||||
N(OP_Buff),
|
N(OP_Buff),
|
||||||
N(OP_BuffCreate),
|
N(OP_BuffCreate),
|
||||||
N(OP_BuffRemoveRequest),
|
N(OP_BuffRemoveRequest),
|
||||||
@@ -72,7 +71,6 @@ N(OP_Camp),
|
|||||||
N(OP_CancelSneakHide),
|
N(OP_CancelSneakHide),
|
||||||
N(OP_CancelTask),
|
N(OP_CancelTask),
|
||||||
N(OP_CancelTrade),
|
N(OP_CancelTrade),
|
||||||
N(OP_CashReward),
|
|
||||||
N(OP_CastSpell),
|
N(OP_CastSpell),
|
||||||
N(OP_ChangeSize),
|
N(OP_ChangeSize),
|
||||||
N(OP_ChannelMessage),
|
N(OP_ChannelMessage),
|
||||||
@@ -131,8 +129,8 @@ N(OP_DisciplineTimer),
|
|||||||
N(OP_DisciplineUpdate),
|
N(OP_DisciplineUpdate),
|
||||||
N(OP_DiscordMerchantInventory),
|
N(OP_DiscordMerchantInventory),
|
||||||
N(OP_DoGroupLeadershipAbility),
|
N(OP_DoGroupLeadershipAbility),
|
||||||
N(OP_DuelDecline),
|
N(OP_DuelResponse),
|
||||||
N(OP_DuelAccept),
|
N(OP_DuelResponse2),
|
||||||
N(OP_DumpName),
|
N(OP_DumpName),
|
||||||
N(OP_Dye),
|
N(OP_Dye),
|
||||||
N(OP_DynamicWall),
|
N(OP_DynamicWall),
|
||||||
@@ -305,7 +303,6 @@ N(OP_LockoutTimerInfo),
|
|||||||
N(OP_Login),
|
N(OP_Login),
|
||||||
N(OP_LoginAccepted),
|
N(OP_LoginAccepted),
|
||||||
N(OP_LoginComplete),
|
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_LoginUnknown1),
|
||||||
N(OP_LoginUnknown2),
|
N(OP_LoginUnknown2),
|
||||||
N(OP_Logout),
|
N(OP_Logout),
|
||||||
@@ -317,7 +314,6 @@ N(OP_LootRequest),
|
|||||||
N(OP_ManaChange),
|
N(OP_ManaChange),
|
||||||
N(OP_ManaUpdate),
|
N(OP_ManaUpdate),
|
||||||
N(OP_MarkNPC),
|
N(OP_MarkNPC),
|
||||||
N(OP_MarkRaidNPC),
|
|
||||||
N(OP_Marquee),
|
N(OP_Marquee),
|
||||||
N(OP_MemorizeSpell),
|
N(OP_MemorizeSpell),
|
||||||
N(OP_Mend),
|
N(OP_Mend),
|
||||||
@@ -359,6 +355,7 @@ N(OP_OpenContainer),
|
|||||||
N(OP_OpenDiscordMerchant),
|
N(OP_OpenDiscordMerchant),
|
||||||
N(OP_OpenGuildTributeMaster),
|
N(OP_OpenGuildTributeMaster),
|
||||||
N(OP_OpenInventory),
|
N(OP_OpenInventory),
|
||||||
|
N(OP_OpenNewTasksWindow),
|
||||||
N(OP_OpenTributeMaster),
|
N(OP_OpenTributeMaster),
|
||||||
N(OP_PDeletePetition),
|
N(OP_PDeletePetition),
|
||||||
N(OP_PetBuffWindow),
|
N(OP_PetBuffWindow),
|
||||||
@@ -400,8 +397,6 @@ N(OP_PVPLeaderBoardRequest),
|
|||||||
N(OP_PVPStats),
|
N(OP_PVPStats),
|
||||||
N(OP_QueryResponseThing),
|
N(OP_QueryResponseThing),
|
||||||
N(OP_QueryUCSServerStatus),
|
N(OP_QueryUCSServerStatus),
|
||||||
N(OP_RaidDelegateAbility),
|
|
||||||
N(OP_RaidClearNPCMarks),
|
|
||||||
N(OP_RaidInvite),
|
N(OP_RaidInvite),
|
||||||
N(OP_RaidJoin),
|
N(OP_RaidJoin),
|
||||||
N(OP_RaidUpdate),
|
N(OP_RaidUpdate),
|
||||||
@@ -461,7 +456,6 @@ N(OP_ServerListResponse),
|
|||||||
N(OP_SessionReady),
|
N(OP_SessionReady),
|
||||||
N(OP_SetChatServer),
|
N(OP_SetChatServer),
|
||||||
N(OP_SetChatServer2),
|
N(OP_SetChatServer2),
|
||||||
N(OP_SetFace),
|
|
||||||
N(OP_SetGroupTarget),
|
N(OP_SetGroupTarget),
|
||||||
N(OP_SetGuildMOTD),
|
N(OP_SetGuildMOTD),
|
||||||
N(OP_SetGuildRank),
|
N(OP_SetGuildRank),
|
||||||
@@ -470,19 +464,6 @@ N(OP_SetServerFilter),
|
|||||||
N(OP_SetStartCity),
|
N(OP_SetStartCity),
|
||||||
N(OP_SetTitle),
|
N(OP_SetTitle),
|
||||||
N(OP_SetTitleReply),
|
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_Shielding),
|
||||||
N(OP_ShopDelItem),
|
N(OP_ShopDelItem),
|
||||||
N(OP_ShopEnd),
|
N(OP_ShopEnd),
|
||||||
@@ -518,8 +499,7 @@ N(OP_TaskActivityComplete),
|
|||||||
N(OP_TaskDescription),
|
N(OP_TaskDescription),
|
||||||
N(OP_TaskHistoryReply),
|
N(OP_TaskHistoryReply),
|
||||||
N(OP_TaskHistoryRequest),
|
N(OP_TaskHistoryRequest),
|
||||||
N(OP_TaskRequestTimer),
|
N(OP_TaskMemberList),
|
||||||
N(OP_TaskSelectWindow),
|
|
||||||
N(OP_Taunt),
|
N(OP_Taunt),
|
||||||
N(OP_TestBuff),
|
N(OP_TestBuff),
|
||||||
N(OP_TGB),
|
N(OP_TGB),
|
||||||
@@ -565,7 +545,6 @@ N(OP_WhoAllRequest),
|
|||||||
N(OP_WhoAllResponse),
|
N(OP_WhoAllResponse),
|
||||||
N(OP_World_Client_CRC1),
|
N(OP_World_Client_CRC1),
|
||||||
N(OP_World_Client_CRC2),
|
N(OP_World_Client_CRC2),
|
||||||
N(OP_World_Client_CRC3),
|
|
||||||
N(OP_WorldClientReady),
|
N(OP_WorldClientReady),
|
||||||
N(OP_WorldComplete),
|
N(OP_WorldComplete),
|
||||||
N(OP_WorldLogout),
|
N(OP_WorldLogout),
|
||||||
@@ -588,5 +567,4 @@ N(OP_ZoneServerReady),
|
|||||||
N(OP_ZoneSpawns),
|
N(OP_ZoneSpawns),
|
||||||
N(OP_ZoneUnavail),
|
N(OP_ZoneUnavail),
|
||||||
N(OP_ResetAA),
|
N(OP_ResetAA),
|
||||||
N(OP_UnderWorld),
|
|
||||||
// mail and chat opcodes located in ../mail_oplist.h
|
// mail and chat opcodes located in ../mail_oplist.h
|
||||||
|
|||||||
+11
-596
@@ -65,7 +65,6 @@
|
|||||||
#define AT_FindBits 46 // set FindBits, whatever those are!
|
#define AT_FindBits 46 // set FindBits, whatever those are!
|
||||||
#define AT_TextureType 48 // TextureType
|
#define AT_TextureType 48 // TextureType
|
||||||
#define AT_FacePick 49 // Turns off face pick window? maybe ...
|
#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_GuildShow 52 // this is what MQ2 call sit, not sure
|
||||||
#define AT_Offline 53 // Offline mode
|
#define AT_Offline 53 // Offline mode
|
||||||
|
|
||||||
@@ -79,8 +78,6 @@
|
|||||||
#define ANIM_DEATH 0x73
|
#define ANIM_DEATH 0x73
|
||||||
#define ANIM_LOOT 0x69
|
#define ANIM_LOOT 0x69
|
||||||
|
|
||||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eaStanding = 0,
|
eaStanding = 0,
|
||||||
eaSitting, //1
|
eaSitting, //1
|
||||||
@@ -200,491 +197,13 @@ namespace Chat {
|
|||||||
const uint16 Stun = 340;
|
const uint16 Stun = 340;
|
||||||
};
|
};
|
||||||
|
|
||||||
// generation SQL:
|
//ZoneChange_Struct->success values
|
||||||
// SELECT CONCAT(' constexpr uint16 ', UPPER(short_name), ' = ' , zoneidnumber, '; // ', long_name) from zone group by zoneidnumber ORDER BY zoneidnumber;
|
#define ZONE_ERROR_NOMSG 0
|
||||||
namespace Zones {
|
#define ZONE_ERROR_NOTREADY -1
|
||||||
constexpr uint16 QEYNOS = 1; // South Qeynos
|
#define ZONE_ERROR_VALIDPC -2
|
||||||
constexpr uint16 QEYNOS2 = 2; // North Qeynos
|
#define ZONE_ERROR_STORYZONE -3
|
||||||
constexpr uint16 QRG = 3; // The Surefall Glade
|
#define ZONE_ERROR_NOEXPANSION -6
|
||||||
constexpr uint16 QEYTOQRG = 4; // The Qeynos Hills
|
#define ZONE_ERROR_NOEXPERIENCE -7
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -712,7 +231,7 @@ typedef enum {
|
|||||||
FilterPetMisses = 21, //0=show, 1=hide
|
FilterPetMisses = 21, //0=show, 1=hide
|
||||||
FilterFocusEffects = 22, //0=show, 1=hide
|
FilterFocusEffects = 22, //0=show, 1=hide
|
||||||
FilterPetSpells = 23, //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,
|
FilterUnknown25 = 25,
|
||||||
FilterUnknown26 = 26,
|
FilterUnknown26 = 26,
|
||||||
FilterUnknown27 = 27,
|
FilterUnknown27 = 27,
|
||||||
@@ -919,6 +438,9 @@ static const uint8 SkillDamageTypes[EQ::skills::HIGHEST_SKILL + 1] = // change t
|
|||||||
|
|
||||||
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
|
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
|
||||||
|
|
||||||
|
static const uint32 DB_SPELL_CAZIC_TOUCH = 982;
|
||||||
|
static const uint32 DB_SPELL_TOUCH_OF_VINITRAS = 2859;
|
||||||
|
|
||||||
static const uint32 DB_FACTION_GEM_CHOPPERS = 255;
|
static const uint32 DB_FACTION_GEM_CHOPPERS = 255;
|
||||||
static const uint32 DB_FACTION_HERETICS = 265;
|
static const uint32 DB_FACTION_HERETICS = 265;
|
||||||
static const uint32 DB_FACTION_KING_AKANON = 333;
|
static const uint32 DB_FACTION_KING_AKANON = 333;
|
||||||
@@ -968,111 +490,4 @@ enum class DynamicZoneMemberStatus : uint8_t
|
|||||||
LinkDead
|
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
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MoneyTypes
|
|
||||||
{
|
|
||||||
Copper,
|
|
||||||
Silver,
|
|
||||||
Gold,
|
|
||||||
Platinum
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MoneySubtypes
|
|
||||||
{
|
|
||||||
Personal,
|
|
||||||
Bank,
|
|
||||||
Cursor,
|
|
||||||
SharedBank // Platinum Only
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
static bool global_dictionary_init = false;
|
static bool global_dictionary_init = false;
|
||||||
void EQ::InitializeDynamicLookups() {
|
void EQ::InitializeDynamicLookups() {
|
||||||
if (global_dictionary_init)
|
if (global_dictionary_init == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
constants::InitializeDynamicLookups();
|
constants::InitializeDynamicLookups();
|
||||||
|
|||||||
+1
-1
@@ -129,7 +129,7 @@ namespace EQ
|
|||||||
|
|
||||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||||
LookupEntry(
|
LookupEntry(
|
||||||
const InventoryTypeSize_Struct& InventoryTypeSize,
|
InventoryTypeSize_Struct InventoryTypeSize,
|
||||||
uint64 EquipmentBitmask,
|
uint64 EquipmentBitmask,
|
||||||
uint64 GeneralBitmask,
|
uint64 GeneralBitmask,
|
||||||
uint64 CursorBitmask,
|
uint64 CursorBitmask,
|
||||||
|
|||||||
@@ -236,6 +236,26 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
|
|||||||
return size+OpCodeBytes;
|
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 EQProtocolPacket::combine(const EQProtocolPacket *rhs)
|
||||||
{
|
{
|
||||||
bool result=false;
|
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 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
|
||||||
{
|
{
|
||||||
uint32 newlen=0;
|
uint32 newlen=0;
|
||||||
@@ -315,6 +403,55 @@ uint32 flag_offset=1,newlength;
|
|||||||
return 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 {
|
EQApplicationPacket *EQApplicationPacket::Copy() const {
|
||||||
return(new EQApplicationPacket(*this));
|
return(new EQApplicationPacket(*this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
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 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 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); }
|
uint16 GetRawOpcode() const { return(opcode); }
|
||||||
|
|
||||||
|
|||||||
+37
-166
@@ -29,7 +29,7 @@
|
|||||||
#include "textures.h"
|
#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 PET_BUFF_COUNT = 30;
|
||||||
static const uint32 MAX_MERC = 100;
|
static const uint32 MAX_MERC = 100;
|
||||||
static const uint32 MAX_MERC_GRADES = 10;
|
static const uint32 MAX_MERC_GRADES = 10;
|
||||||
@@ -124,12 +124,6 @@ struct LDoNTrapTemplate
|
|||||||
uint8 locked;
|
uint8 locked;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CrystalReclaimTypes
|
|
||||||
{
|
|
||||||
Ebon = 5,
|
|
||||||
Radiant = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
@@ -384,15 +378,13 @@ struct NewZone_Struct {
|
|||||||
// 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
|
// 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
|
// Just wastes some bandwidth sending to tit clients /shrug
|
||||||
/*0700*/ float fog_density;
|
/*0700*/ float fog_density;
|
||||||
/*0704*/ uint32 suspend_buffs;
|
/*0704*/ uint32 SuspendBuffs;
|
||||||
/*0708*/ uint32 fast_regen_hp;
|
/*0708*/ uint32 FastRegenHP;
|
||||||
/*0712*/ uint32 fast_regen_mana;
|
/*0712*/ uint32 FastRegenMana;
|
||||||
/*0716*/ uint32 fast_regen_endurance;
|
/*0716*/ uint32 FastRegenEndurance;
|
||||||
/*0720*/ uint32 npc_aggro_max_dist;
|
/*0720*/ uint32 NPCAggroMaxDist;
|
||||||
/*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
|
/*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
|
/*0728*/
|
||||||
/*0732*/ uint32 min_lava_damage; // Seen 10
|
|
||||||
/*0736*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -454,7 +446,6 @@ struct ManaChange_Struct
|
|||||||
/*08*/ uint32 spell_id;
|
/*08*/ uint32 spell_id;
|
||||||
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
|
/*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
|
/*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
|
struct SwapSpell_Struct
|
||||||
@@ -1799,17 +1790,6 @@ struct GMSummon_Struct {
|
|||||||
/*104*/ uint32 unknown2; // E0 E0 56 00
|
/*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
|
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
|
||||||
/* 0*/ char charname[64];
|
/* 0*/ char charname[64];
|
||||||
|
|
||||||
@@ -2209,19 +2189,11 @@ struct QuestReward_Struct
|
|||||||
/*068*/
|
/*068*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CashReward_Struct
|
|
||||||
{
|
|
||||||
/*000*/ uint32 copper;
|
|
||||||
/*004*/ uint32 silver;
|
|
||||||
/*008*/ uint32 gold;
|
|
||||||
/*012*/ uint32 platinum;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Size: 8
|
// Size: 8
|
||||||
struct Camera_Struct
|
struct Camera_Struct
|
||||||
{
|
{
|
||||||
uint32 duration; // Duration in ms
|
uint32 duration; // Duration in ms
|
||||||
float intensity;
|
uint32 intensity; // Between 1023410176 and 1090519040
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZonePoint_Entry {
|
struct ZonePoint_Entry {
|
||||||
@@ -2341,12 +2313,9 @@ struct FaceChange_Struct {
|
|||||||
/*004*/ uint8 hairstyle;
|
/*004*/ uint8 hairstyle;
|
||||||
/*005*/ uint8 beard;
|
/*005*/ uint8 beard;
|
||||||
/*006*/ uint8 face;
|
/*006*/ uint8 face;
|
||||||
/*007*/ uint8 unused_padding;
|
/*007*/ uint32 drakkin_heritage;
|
||||||
/*008*/ uint32 drakkin_heritage;
|
/*011*/ uint32 drakkin_tattoo;
|
||||||
/*012*/ uint32 drakkin_tattoo;
|
/*015*/ uint32 drakkin_details;
|
||||||
/*016*/ uint32 drakkin_details;
|
|
||||||
/*020*/ uint32 entity_id;
|
|
||||||
/*024*/
|
|
||||||
//there are only 10 faces for barbs changing woad just
|
//there are only 10 faces for barbs changing woad just
|
||||||
//increase the face value by ten so if there were 8 woad
|
//increase the face value by ten so if there were 8 woad
|
||||||
//designs then there would be 80 barb faces
|
//designs then there would be 80 barb faces
|
||||||
@@ -2565,10 +2534,7 @@ struct GMEmoteZone_Struct {
|
|||||||
struct BookText_Struct {
|
struct BookText_Struct {
|
||||||
uint8 window; // where to display the text (0xFF means new window)
|
uint8 window; // where to display the text (0xFF means new window)
|
||||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||||
int16 invslot; // Only used in SoF and later clients.
|
uint32 invslot; // Only used in SoF and later clients.
|
||||||
int32 target_id;
|
|
||||||
int8 can_cast;
|
|
||||||
int8 can_scribe;
|
|
||||||
char booktext[1]; // Variable Length
|
char booktext[1]; // Variable Length
|
||||||
};
|
};
|
||||||
// This is the request to read a book.
|
// This is the request to read a book.
|
||||||
@@ -2577,18 +2543,11 @@ struct BookText_Struct {
|
|||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
uint8 window; // where to display the text (0xFF means new window)
|
uint8 window; // where to display the text (0xFF means new window)
|
||||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||||
int16 invslot; // Only used in Sof and later clients;
|
uint32 invslot; // Only used in Sof and later clients;
|
||||||
int32 target_id;
|
int16 subslot; // The subslot inside of a bag if it is inside one.
|
||||||
char txtfile[20];
|
char txtfile[20];
|
||||||
};
|
};
|
||||||
|
|
||||||
// used by Scribe and CastSpell book buttons
|
|
||||||
struct BookButton_Struct
|
|
||||||
{
|
|
||||||
int16 invslot; // server slot
|
|
||||||
int32 target_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Object/Ground Spawn struct
|
** Object/Ground Spawn struct
|
||||||
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
||||||
@@ -2600,11 +2559,11 @@ struct BookButton_Struct
|
|||||||
struct Object_Struct {
|
struct Object_Struct {
|
||||||
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
|
||||||
/*08*/ float size; //
|
/*08*/ float size; //
|
||||||
/*10*/ uint16 solid_type; //
|
/*10*/ uint16 solidtype; //
|
||||||
/*12*/ uint32 drop_id; // Unique object id for zone
|
/*12*/ uint32 drop_id; // Unique object id for zone
|
||||||
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
|
||||||
/*18*/ uint16 zone_instance; //
|
/*18*/ uint16 zone_instance; //
|
||||||
/*20*/ uint32 incline; //
|
/*20*/ uint32 unknown020; //
|
||||||
/*24*/ uint32 unknown024; //
|
/*24*/ uint32 unknown024; //
|
||||||
/*28*/ float tilt_x;
|
/*28*/ float tilt_x;
|
||||||
/*32*/ float tilt_y;
|
/*32*/ float tilt_y;
|
||||||
@@ -2800,7 +2759,7 @@ struct EnvDamage2_Struct {
|
|||||||
/*0004*/ uint16 unknown4;
|
/*0004*/ uint16 unknown4;
|
||||||
/*0006*/ uint32 damage;
|
/*0006*/ uint32 damage;
|
||||||
/*0010*/ uint8 unknown10[12];
|
/*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];
|
/*0023*/ uint8 unknown2[4];
|
||||||
/*0027*/ uint16 constant; //Always FFFF
|
/*0027*/ uint16 constant; //Always FFFF
|
||||||
/*0029*/ uint16 unknown29;
|
/*0029*/ uint16 unknown29;
|
||||||
@@ -3664,14 +3623,9 @@ struct MerchantList {
|
|||||||
uint32 item;
|
uint32 item;
|
||||||
int16 faction_required;
|
int16 faction_required;
|
||||||
int8 level_required;
|
int8 level_required;
|
||||||
uint8 min_status;
|
|
||||||
uint8 max_status;
|
|
||||||
uint16 alt_currency_cost;
|
uint16 alt_currency_cost;
|
||||||
uint32 classes_required;
|
uint32 classes_required;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
std::string bucket_name;
|
|
||||||
std::string bucket_value;
|
|
||||||
uint8 bucket_comparison;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TempMerchantList {
|
struct TempMerchantList {
|
||||||
@@ -3760,66 +3714,17 @@ struct SetTitleReply_Struct {
|
|||||||
uint32 entity_id;
|
uint32 entity_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SharedTaskMemberList_Struct {
|
struct TaskMemberList_Struct {
|
||||||
/*00*/ uint32 gopher_id;
|
/*00*/ uint32 gopher_id;
|
||||||
/*04*/ uint32 unknown04;
|
/*04*/ uint32 unknown04;
|
||||||
/*08*/ uint32 member_count; //1 less than the number of members
|
/*08*/ uint32 member_count; //1 less than the number of members
|
||||||
///*12*/ char list_pointer[0];
|
/*12*/ char list_pointer[0];
|
||||||
char member_name[1]; //null terminated string
|
|
||||||
uint32 monster_mission; // class chosen
|
|
||||||
uint8 task_leader; //boolean flag
|
|
||||||
|
|
||||||
/* list is of the form:
|
/* list is of the form:
|
||||||
|
char member_name[1] //null terminated string
|
||||||
uint8 task_leader //boolean flag
|
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
|
#if 0
|
||||||
|
|
||||||
// Old struct not used by Task System implementation but left for reference
|
// Old struct not used by Task System implementation but left for reference
|
||||||
@@ -3912,7 +3817,7 @@ struct TaskHistory_Struct {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct AcceptNewTask_Struct {
|
struct AcceptNewTask_Struct {
|
||||||
uint32 task_type; // type sent in selection window
|
uint32 unknown00;
|
||||||
uint32 task_id; //set to 0 for 'decline'
|
uint32 task_id; //set to 0 for 'decline'
|
||||||
uint32 task_master_id; //entity ID
|
uint32 task_master_id; //entity ID
|
||||||
};
|
};
|
||||||
@@ -4121,9 +4026,7 @@ struct UpdateLeadershipAA_Struct {
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
GroupLeadershipAbility_MarkNPC = 0,
|
GroupLeadershipAbility_MarkNPC = 0
|
||||||
RaidLeadershipAbility_MarkNPC = 16,
|
|
||||||
RaidLeadershipAbility_MainAssist = 19
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DoGroupLeadershipAbility_Struct
|
struct DoGroupLeadershipAbility_Struct
|
||||||
@@ -4167,9 +4070,8 @@ struct InspectBuffs_Struct {
|
|||||||
struct RaidGeneral_Struct {
|
struct RaidGeneral_Struct {
|
||||||
/*00*/ uint32 action; //=10
|
/*00*/ uint32 action; //=10
|
||||||
/*04*/ char player_name[64]; //should both be the player's name
|
/*04*/ char player_name[64]; //should both be the player's name
|
||||||
/*68*/ uint32 unknown1;
|
/*64*/ char leader_name[64];
|
||||||
/*72*/ char leader_name[64];
|
/*132*/ uint32 parameter;
|
||||||
/*136*/ uint32 parameter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidAddMember_Struct {
|
struct RaidAddMember_Struct {
|
||||||
@@ -4180,14 +4082,9 @@ struct RaidAddMember_Struct {
|
|||||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidNote_Struct {
|
|
||||||
/*000*/ RaidGeneral_Struct general;
|
|
||||||
/*140*/ char note[64];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RaidMOTD_Struct {
|
struct RaidMOTD_Struct {
|
||||||
/*000*/ RaidGeneral_Struct general;
|
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||||
/*140*/ char motd[1024];
|
/*136*/ char motd[0]; // max size is 1024, but reply is variable
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidLeadershipUpdate_Struct {
|
struct RaidLeadershipUpdate_Struct {
|
||||||
@@ -4394,8 +4291,8 @@ struct AARankPrereq_Struct
|
|||||||
struct AARankEffect_Struct
|
struct AARankEffect_Struct
|
||||||
{
|
{
|
||||||
int32 effect_id;
|
int32 effect_id;
|
||||||
int32 base_value;
|
int32 base1;
|
||||||
int32 limit_value;
|
int32 base2;
|
||||||
int32 slot;
|
int32 slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4403,8 +4300,8 @@ struct AARankEffect_Struct
|
|||||||
|
|
||||||
struct AA_Ability {
|
struct AA_Ability {
|
||||||
/*00*/ uint32 skill_id;
|
/*00*/ uint32 skill_id;
|
||||||
/*04*/ uint32 base_value;
|
/*04*/ uint32 base1;
|
||||||
/*08*/ uint32 limit_value;
|
/*08*/ uint32 base2;
|
||||||
/*12*/ uint32 slot;
|
/*12*/ uint32 slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4582,7 +4479,7 @@ struct ItemVerifyReply_Struct {
|
|||||||
struct ItemRecastDelay_Struct {
|
struct ItemRecastDelay_Struct {
|
||||||
/*000*/ uint32 recast_delay; // in seconds
|
/*000*/ uint32 recast_delay; // in seconds
|
||||||
/*004*/ uint32 recast_type;
|
/*004*/ uint32 recast_type;
|
||||||
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5043,7 +4940,7 @@ struct DynamicZoneCompassEntry_Struct
|
|||||||
/*000*/ uint16 dz_zone_id; // target dz id pair
|
/*000*/ uint16 dz_zone_id; // target dz id pair
|
||||||
/*002*/ uint16 dz_instance_id;
|
/*002*/ uint16 dz_instance_id;
|
||||||
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
|
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
|
||||||
/*008*/ uint32 dz_switch_id;
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/ float y;
|
/*012*/ float y;
|
||||||
/*016*/ float x;
|
/*016*/ float x;
|
||||||
/*020*/ float z;
|
/*020*/ float z;
|
||||||
@@ -5200,10 +5097,10 @@ struct AltCurrencySelectItemReply_Struct {
|
|||||||
/*000*/ uint32 unknown000;
|
/*000*/ uint32 unknown000;
|
||||||
/*004*/ uint8 unknown004; //0xff
|
/*004*/ uint8 unknown004; //0xff
|
||||||
/*005*/ uint8 unknown005; //0xff
|
/*005*/ uint8 unknown005; //0xff
|
||||||
/*006*/ uint16 unknown006; //0xffff
|
/*006*/ uint8 unknown006; //0xff
|
||||||
/*008*/ uint16 unknown008; //0xffff
|
/*007*/ uint8 unknown007; //0xff
|
||||||
/*010*/ char item_name[64];
|
/*008*/ char item_name[64];
|
||||||
/*074*/ uint16 unknown074;
|
/*072*/ uint32 unknown074;
|
||||||
/*076*/ uint32 cost;
|
/*076*/ uint32 cost;
|
||||||
/*080*/ uint32 unknown080;
|
/*080*/ uint32 unknown080;
|
||||||
/*084*/ uint32 unknown084;
|
/*084*/ uint32 unknown084;
|
||||||
@@ -5557,11 +5454,7 @@ struct ServerLootItem_Struct {
|
|||||||
uint32 aug_4; // uint32 aug_4;
|
uint32 aug_4; // uint32 aug_4;
|
||||||
uint32 aug_5; // uint32 aug_5;
|
uint32 aug_5; // uint32 aug_5;
|
||||||
uint32 aug_6; // uint32 aug_5;
|
uint32 aug_6; // uint32 aug_5;
|
||||||
bool attuned;
|
uint8 attuned;
|
||||||
std::string custom_data;
|
|
||||||
uint32 ornamenticon {};
|
|
||||||
uint32 ornamentidfile {};
|
|
||||||
uint32 ornament_hero_model {};
|
|
||||||
uint16 trivial_min_level;
|
uint16 trivial_min_level;
|
||||||
uint16 trivial_max_level;
|
uint16 trivial_max_level;
|
||||||
uint16 npc_min_level;
|
uint16 npc_min_level;
|
||||||
@@ -5637,28 +5530,6 @@ struct SayLinkBodyFrame_Struct {
|
|||||||
/*056*/
|
/*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
|
// Restore structure packing to default
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "op_codes.h"
|
#include "op_codes.h"
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|||||||
@@ -243,11 +243,6 @@ class EQStream : public EQStreamInterface {
|
|||||||
|
|
||||||
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
||||||
|
|
||||||
virtual OpcodeManager* GetOpcodeManager() const
|
|
||||||
{
|
|
||||||
return (*OpMgr);
|
|
||||||
};
|
|
||||||
|
|
||||||
void CheckTimeout(uint32 now, uint32 timeout=30);
|
void CheckTimeout(uint32 now, uint32 timeout=30);
|
||||||
bool HasOutgoingData();
|
bool HasOutgoingData();
|
||||||
void Process(const unsigned char *data, const uint32 length);
|
void Process(const unsigned char *data, const uint32 length);
|
||||||
|
|||||||
@@ -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;
|
auto p = new Patch;
|
||||||
p->signature = sig;
|
p->signature = sig;
|
||||||
p->name = name;
|
p->name = name;
|
||||||
@@ -145,7 +145,7 @@ void EQStreamIdentifier::Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
|
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
|
||||||
m_streams.emplace_back(Record(eqs));
|
m_streams.push_back(Record(eqs));
|
||||||
eqs = nullptr;
|
eqs = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
~EQStreamIdentifier();
|
~EQStreamIdentifier();
|
||||||
|
|
||||||
//registration interface.
|
//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
|
//main processing interface
|
||||||
void Process();
|
void Process();
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ public:
|
|||||||
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
||||||
virtual EQStreamState GetState() = 0;
|
virtual EQStreamState GetState() = 0;
|
||||||
virtual void SetOpcodeManager(OpcodeManager **opm) = 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 EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
|
||||||
virtual Stats GetStats() const = 0;
|
virtual Stats GetStats() const = 0;
|
||||||
virtual void ResetStats() = 0;
|
virtual void ResetStats() = 0;
|
||||||
|
|||||||
@@ -38,8 +38,12 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||||
if (p == nullptr) {
|
if(p == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (p->GetOpcode() != OP_SpecialMesg) {
|
||||||
|
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||||
|
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
EQApplicationPacket *newp = p->Copy();
|
EQApplicationPacket *newp = p->Copy();
|
||||||
@@ -108,8 +112,3 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
|
|
||||||
{
|
|
||||||
return (*m_opcodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,13 @@ public:
|
|||||||
virtual Stats GetStats() const;
|
virtual Stats GetStats() const;
|
||||||
virtual void ResetStats();
|
virtual void ResetStats();
|
||||||
virtual EQStreamManagerInterface* GetManager() const;
|
virtual EQStreamManagerInterface* GetManager() const;
|
||||||
virtual OpcodeManager* GetOpcodeManager() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
||||||
const StructStrategy *const m_structs; //we do not own this 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
|
//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.
|
//reference an invalid opcode manager when they are being reloaded.
|
||||||
OpcodeManager **const m_opcodes;
|
OpcodeManager **const m_opcodes; //we do not own this object.
|
||||||
//we do not own this object.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*EQSTREAMPROXY_H_*/
|
#endif /*EQSTREAMPROXY_H_*/
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
|
|
||||||
EQDB EQDB::s_EQDB;
|
EQDB EQDB::s_EQDB;
|
||||||
|
|
||||||
|
EQDB::EQDB() {
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int EQDB::field_count() {
|
unsigned int EQDB::field_count() {
|
||||||
return mysql_field_count(mysql_ref);
|
return mysql_field_count(mysql_ref);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
//this is the main object exported to perl.
|
//this is the main object exported to perl.
|
||||||
class EQDB {
|
class EQDB {
|
||||||
EQDB() = default;
|
EQDB();
|
||||||
public:
|
public:
|
||||||
static EQDB *Singleton() { return(&s_EQDB); }
|
static EQDB *Singleton() { return(&s_EQDB); }
|
||||||
|
|
||||||
|
|||||||
+18
-42
@@ -19,7 +19,6 @@
|
|||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "eqemu_config.h"
|
#include "eqemu_config.h"
|
||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
#include "strings.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -34,23 +33,17 @@ void EQEmuConfig::parse_config()
|
|||||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||||
LocalAddress = _root["server"]["world"].get("localaddress", "").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();
|
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||||
LoginCount = 0;
|
LoginCount = 0;
|
||||||
|
|
||||||
if (_root["server"]["world"]["loginserver"].isObject()) {
|
if (_root["server"]["world"]["loginserver"].isObject()) {
|
||||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
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;
|
LoginLegacy = false;
|
||||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
||||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||||
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
||||||
|
|
||||||
// at least today, this is wrong a majority of the time
|
|
||||||
// remove this if eqemulator ever upgrades its loginserver
|
|
||||||
if (LoginHost.find("login.eqemulator.net") != std::string::npos) {
|
|
||||||
LoginLegacy = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char str[32];
|
char str[32];
|
||||||
@@ -63,19 +56,12 @@ void EQEmuConfig::parse_config()
|
|||||||
|
|
||||||
auto loginconfig = new LoginConfig;
|
auto loginconfig = new LoginConfig;
|
||||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
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->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||||
|
|
||||||
loginconfig->LoginLegacy = false;
|
loginconfig->LoginLegacy = false;
|
||||||
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
|
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);
|
loginlist.Insert(loginconfig);
|
||||||
} while (LoginCount < 100);
|
} while (LoginCount < 100);
|
||||||
}
|
}
|
||||||
@@ -85,39 +71,29 @@ void EQEmuConfig::parse_config()
|
|||||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||||
Locked = false;
|
Locked = false;
|
||||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
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();
|
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();
|
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;
|
TelnetEnabled = false;
|
||||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
||||||
|
|
||||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
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;
|
WorldHTTPEnabled = false;
|
||||||
|
|
||||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||||
WorldHTTPEnabled = true;
|
WorldHTTPEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_root["server"].get("disable_config_checks", "false").asString() == "true") {
|
|
||||||
DisableConfigChecks = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UCS
|
* UCS
|
||||||
*/
|
*/
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
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();
|
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
|
* Database
|
||||||
@@ -125,7 +101,7 @@ void EQEmuConfig::parse_config()
|
|||||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").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();
|
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,14 +110,14 @@ void EQEmuConfig::parse_config()
|
|||||||
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
||||||
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
||||||
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
||||||
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString());
|
ContentDbPort = atoi(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QS
|
* QS
|
||||||
*/
|
*/
|
||||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
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();
|
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||||
@@ -149,9 +125,9 @@ void EQEmuConfig::parse_config()
|
|||||||
/**
|
/**
|
||||||
* Zones
|
* Zones
|
||||||
*/
|
*/
|
||||||
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString());
|
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||||
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString());
|
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||||
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString());
|
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Files
|
* Files
|
||||||
@@ -181,10 +157,10 @@ void EQEmuConfig::parse_config()
|
|||||||
/**
|
/**
|
||||||
* Launcher
|
* Launcher
|
||||||
*/
|
*/
|
||||||
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString());
|
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||||
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString());
|
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||||
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString());
|
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||||
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString());
|
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||||
#else
|
#else
|
||||||
|
|||||||
+11
-18
@@ -20,9 +20,7 @@
|
|||||||
|
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
#include "linked_list.h"
|
#include "linked_list.h"
|
||||||
#include "path_manager.h"
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
struct LoginConfig {
|
struct LoginConfig {
|
||||||
std::string LoginHost;
|
std::string LoginHost;
|
||||||
@@ -60,7 +58,6 @@ class EQEmuConfig
|
|||||||
uint16 WorldHTTPPort;
|
uint16 WorldHTTPPort;
|
||||||
std::string WorldHTTPMimeFile;
|
std::string WorldHTTPMimeFile;
|
||||||
std::string SharedKey;
|
std::string SharedKey;
|
||||||
bool DisableConfigChecks;
|
|
||||||
|
|
||||||
// From <chatserver/>
|
// From <chatserver/>
|
||||||
std::string ChatHost;
|
std::string ChatHost;
|
||||||
@@ -120,8 +117,6 @@ class EQEmuConfig
|
|||||||
uint16 ZonePortHigh;
|
uint16 ZonePortHigh;
|
||||||
uint8 DefaultStatus;
|
uint8 DefaultStatus;
|
||||||
|
|
||||||
bool auto_database_updates;
|
|
||||||
|
|
||||||
// uint16 DynamicCount;
|
// uint16 DynamicCount;
|
||||||
|
|
||||||
// map<string,uint16> StaticZones;
|
// map<string,uint16> StaticZones;
|
||||||
@@ -149,32 +144,30 @@ class EQEmuConfig
|
|||||||
return (_config);
|
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
|
// Load the config
|
||||||
static bool LoadConfig(const std::string& path = "")
|
static bool LoadConfig()
|
||||||
{
|
{
|
||||||
if (_config != nullptr) {
|
if (_config != nullptr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_config = new EQEmuConfig;
|
_config = new EQEmuConfig;
|
||||||
|
|
||||||
return parseFile(path);
|
return parseFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config file and parse data
|
// Load config file and parse data
|
||||||
static bool parseFile(const std::string& file_path = ".")
|
static bool parseFile() {
|
||||||
{
|
|
||||||
if (_config == nullptr) {
|
if (_config == nullptr) {
|
||||||
return LoadConfig(file_path);
|
return LoadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file = fmt::format(
|
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
|
||||||
"{}/{}",
|
|
||||||
(file_path.empty() ? path.GetServerPath() : file_path),
|
|
||||||
EQEmuConfig::ConfigFile
|
|
||||||
);
|
|
||||||
|
|
||||||
std::ifstream fconfig(file, std::ifstream::binary);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fconfig >> _config->_root;
|
fconfig >> _config->_root;
|
||||||
_config->parse_config();
|
_config->parse_config();
|
||||||
|
|||||||
+292
-509
File diff suppressed because it is too large
Load Diff
+129
-168
@@ -23,9 +23,8 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstdio>
|
#include <stdio.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef utf16_to_utf8
|
#ifdef utf16_to_utf8
|
||||||
@@ -38,8 +37,9 @@
|
|||||||
|
|
||||||
namespace Logs {
|
namespace Logs {
|
||||||
enum DebugLevel {
|
enum DebugLevel {
|
||||||
General = 1, // 1 - Low-Level general debugging, useful info on single line
|
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
|
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 +53,7 @@ namespace Logs {
|
|||||||
AI,
|
AI,
|
||||||
Aggro,
|
Aggro,
|
||||||
Attack,
|
Attack,
|
||||||
DeprecatedCS, // deprecated
|
PacketClientServer,
|
||||||
Combat,
|
Combat,
|
||||||
Commands,
|
Commands,
|
||||||
Crash,
|
Crash,
|
||||||
@@ -64,36 +64,36 @@ namespace Logs {
|
|||||||
Inventory,
|
Inventory,
|
||||||
Launcher,
|
Launcher,
|
||||||
Netcode,
|
Netcode,
|
||||||
Normal, // deprecated
|
Normal,
|
||||||
Object,
|
Object,
|
||||||
Pathing,
|
Pathing,
|
||||||
QSServer, // deprecated
|
QSServer,
|
||||||
Quests,
|
Quests,
|
||||||
Rules,
|
Rules,
|
||||||
Skills,
|
Skills,
|
||||||
Spawns,
|
Spawns,
|
||||||
Spells,
|
Spells,
|
||||||
Status, // deprecated
|
Status,
|
||||||
TCPConnection,
|
TCPConnection,
|
||||||
Tasks,
|
Tasks,
|
||||||
Tradeskills,
|
Tradeskills,
|
||||||
Trading,
|
Trading,
|
||||||
Tribute,
|
Tribute,
|
||||||
UCSServer, // deprecated
|
UCSServer,
|
||||||
WebInterfaceServer, // deprecated
|
WebInterfaceServer,
|
||||||
WorldServer, // deprecated
|
WorldServer,
|
||||||
ZoneServer, // deprecated
|
ZoneServer,
|
||||||
MySQLError,
|
MySQLError,
|
||||||
MySQLQuery,
|
MySQLQuery,
|
||||||
Mercenaries,
|
Mercenaries,
|
||||||
QuestDebug,
|
QuestDebug,
|
||||||
DeprecatedSC, // deprecated
|
PacketServerClient,
|
||||||
DeprecatedCSU, // deprecated
|
PacketClientServerUnhandled,
|
||||||
DeprecatedSCD, // deprecated
|
PacketServerClientWithDump,
|
||||||
DeprecatedCSD, // deprecated
|
PacketClientServerWithDump,
|
||||||
Loginserver, // deprecated
|
Loginserver,
|
||||||
ClientLogin,
|
ClientLogin,
|
||||||
HeadlessClient, // deprecated
|
HeadlessClient,
|
||||||
HPUpdate,
|
HPUpdate,
|
||||||
FixZ,
|
FixZ,
|
||||||
Food,
|
Food,
|
||||||
@@ -103,10 +103,10 @@ namespace Logs {
|
|||||||
MobAppearance,
|
MobAppearance,
|
||||||
Info,
|
Info,
|
||||||
Warning,
|
Warning,
|
||||||
Critical, // deprecated
|
Critical,
|
||||||
Emergency, // deprecated
|
Emergency,
|
||||||
Alert, // deprecated
|
Alert,
|
||||||
Notice, // deprecated
|
Notice,
|
||||||
AIScanClose,
|
AIScanClose,
|
||||||
AIYellForHelp,
|
AIYellForHelp,
|
||||||
AICastBeneficialClose,
|
AICastBeneficialClose,
|
||||||
@@ -121,38 +121,19 @@ namespace Logs {
|
|||||||
Expeditions,
|
Expeditions,
|
||||||
DynamicZones,
|
DynamicZones,
|
||||||
Scheduler,
|
Scheduler,
|
||||||
Cheat,
|
|
||||||
ClientList,
|
|
||||||
DiaWind,
|
|
||||||
HTTP,
|
|
||||||
Saylink,
|
|
||||||
ChecksumVerification,
|
|
||||||
CombatRecord,
|
|
||||||
Hate,
|
|
||||||
Discord,
|
|
||||||
Faction,
|
|
||||||
PacketServerClient,
|
|
||||||
PacketClientServer,
|
|
||||||
PacketServerToServer,
|
|
||||||
Bugs,
|
|
||||||
QuestErrors,
|
|
||||||
PlayerEvents,
|
|
||||||
DataBuckets,
|
|
||||||
Zoning,
|
|
||||||
EqTime,
|
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If you add to this, make sure you update LogCategory
|
* If you add to this, make sure you update LogCategory
|
||||||
*/
|
*/
|
||||||
static const char *LogCategoryName[LogCategory::MaxCategoryID] = {
|
static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
|
||||||
"",
|
"",
|
||||||
"AA",
|
"AA",
|
||||||
"AI",
|
"AI",
|
||||||
"Aggro",
|
"Aggro",
|
||||||
"Attack",
|
"Attack",
|
||||||
"Deprecated",
|
"Packet :: Client -> Server",
|
||||||
"Combat",
|
"Combat",
|
||||||
"Commands",
|
"Commands",
|
||||||
"Crash",
|
"Crash",
|
||||||
@@ -163,52 +144,52 @@ namespace Logs {
|
|||||||
"Inventory",
|
"Inventory",
|
||||||
"Launcher",
|
"Launcher",
|
||||||
"Netcode",
|
"Netcode",
|
||||||
"Normal (Deprecated)",
|
"Normal",
|
||||||
"Object",
|
"Object",
|
||||||
"Pathing",
|
"Pathing",
|
||||||
"QS Server (Deprecated)",
|
"QS Server",
|
||||||
"Quests",
|
"Quests",
|
||||||
"Rules",
|
"Rules",
|
||||||
"Skills",
|
"Skills",
|
||||||
"Spawns",
|
"Spawns",
|
||||||
"Spells",
|
"Spells",
|
||||||
"Status (Deprecated)",
|
"Status",
|
||||||
"TCP Connection",
|
"TCP Connection",
|
||||||
"Tasks",
|
"Tasks",
|
||||||
"Tradeskills",
|
"Tradeskills",
|
||||||
"Trading",
|
"Trading",
|
||||||
"Tribute",
|
"Tribute",
|
||||||
"UCS Server (Deprecated)",
|
"UCS Server",
|
||||||
"Web Interface (Deprecated)",
|
"WebInterface Server",
|
||||||
"World Server (Deprecated)",
|
"World Server",
|
||||||
"Zone Server (Deprecated)",
|
"Zone Server",
|
||||||
"QueryErr",
|
"MySQL Error",
|
||||||
"Query",
|
"MySQL Query",
|
||||||
"Mercenaries",
|
"Mercenaries",
|
||||||
"Quest Debug",
|
"Quest Debug",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Server -> Client",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Client -> Server Unhandled",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Server -> Client (Dump)",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Client -> Server (Dump)",
|
||||||
"Login Server (Deprecated)",
|
"Login Server",
|
||||||
"Client Login",
|
"Client Login",
|
||||||
"Headless Client (Deprecated)",
|
"Headless Client",
|
||||||
"HP Update",
|
"HP Update",
|
||||||
"FixZ",
|
"FixZ",
|
||||||
"Food",
|
"Food",
|
||||||
"Traps",
|
"Traps",
|
||||||
"NPC Roam Box",
|
"NPC Roam Box",
|
||||||
"NPC Scaling",
|
"NPC Scaling",
|
||||||
"MobAppearance",
|
"Mob Appearance",
|
||||||
"Info",
|
"Info",
|
||||||
"Warning",
|
"Warning",
|
||||||
"Critical (Deprecated)",
|
"Critical",
|
||||||
"Emergency (Deprecated)",
|
"Emergency",
|
||||||
"Alert (Deprecated)",
|
"Alert",
|
||||||
"Notice (Deprecated)",
|
"Notice",
|
||||||
"AI Scan",
|
"AI Scan Close",
|
||||||
"AI Yell",
|
"AI Yell For Help",
|
||||||
"AI CastBeneficial",
|
"AI Cast Beneficial Close",
|
||||||
"AOE Cast",
|
"AOE Cast",
|
||||||
"Entity Management",
|
"Entity Management",
|
||||||
"Flee",
|
"Flee",
|
||||||
@@ -220,34 +201,11 @@ namespace Logs {
|
|||||||
"Expeditions",
|
"Expeditions",
|
||||||
"DynamicZones",
|
"DynamicZones",
|
||||||
"Scheduler",
|
"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",
|
|
||||||
"EqTime",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "eqemu_logsys_log_aliases.h"
|
#include "eqemu_logsys_log_aliases.h"
|
||||||
|
|
||||||
class Database;
|
|
||||||
|
|
||||||
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
|
|
||||||
|
|
||||||
class EQEmuLogSys {
|
class EQEmuLogSys {
|
||||||
public:
|
public:
|
||||||
EQEmuLogSys();
|
EQEmuLogSys();
|
||||||
@@ -258,8 +216,7 @@ public:
|
|||||||
* This should be handled on deconstructor but to be safe we use it anyways.
|
* This should be handled on deconstructor but to be safe we use it anyways.
|
||||||
*/
|
*/
|
||||||
void CloseFileLogs();
|
void CloseFileLogs();
|
||||||
EQEmuLogSys *LoadLogSettingsDefaults();
|
void LoadLogSettingsDefaults();
|
||||||
EQEmuLogSys *LoadLogDatabaseSettings();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param directory_name
|
* @param directory_name
|
||||||
@@ -289,7 +246,7 @@ public:
|
|||||||
* Used in file logs to prepend a timestamp entry for logs
|
* Used in file logs to prepend a timestamp entry for logs
|
||||||
* @param time_stamp
|
* @param time_stamp
|
||||||
*/
|
*/
|
||||||
void SetCurrentTimeStamp(char *time_stamp);
|
void SetCurrentTimeStamp(char* time_stamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param log_name
|
* @param log_name
|
||||||
@@ -310,104 +267,108 @@ public:
|
|||||||
uint8 log_to_file;
|
uint8 log_to_file;
|
||||||
uint8 log_to_console;
|
uint8 log_to_console;
|
||||||
uint8 log_to_gmsay;
|
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) */
|
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
|
* Internally used memory reference for all log settings per category
|
||||||
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
* 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
|
bool file_logs_enabled = false;
|
||||||
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
|
|
||||||
|
|
||||||
struct LogEnabled {
|
/**
|
||||||
bool log_to_file_enabled;
|
* Sets Executable platform (Zone/World/UCS) etc.
|
||||||
bool log_to_console_enabled;
|
*/
|
||||||
bool log_to_gmsay_enabled;
|
int log_platform = 0;
|
||||||
bool log_to_discord_enabled;
|
|
||||||
bool log_enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
* GMSay Client Message colors mapped by category
|
||||||
std::string webhook_name;
|
*
|
||||||
std::string webhook_url;
|
* @param log_category
|
||||||
};
|
* @return
|
||||||
|
*/
|
||||||
const DiscordWebhooks *GetDiscordWebhooks() const;
|
|
||||||
|
|
||||||
// gmsay
|
|
||||||
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
||||||
|
|
||||||
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)>& f)
|
/**
|
||||||
{
|
* @param f
|
||||||
m_on_log_gmsay_hook = f;
|
*/
|
||||||
return this;
|
void SetGMSayHandler(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
|
||||||
}
|
|
||||||
|
|
||||||
EQEmuLogSys *SetDiscordHandler(std::function<void(uint16 log_category, int webhook_id, const std::string &)> f)
|
/**
|
||||||
{
|
* @param f
|
||||||
m_on_log_discord_hook = f;
|
*/
|
||||||
return this;
|
void SetConsoleHandler(std::function<void(uint16 debug_level, uint16 log_type, const std::string&)> f) { on_log_console_hook = f; }
|
||||||
}
|
|
||||||
|
|
||||||
// console
|
/**
|
||||||
void SetConsoleHandler(
|
* Silence console logging
|
||||||
std::function<void(
|
*/
|
||||||
uint16 log_type,
|
|
||||||
const std::string &
|
|
||||||
)> f
|
|
||||||
) { m_on_log_console_hook = f; }
|
|
||||||
void SilenceConsoleLogging();
|
void SilenceConsoleLogging();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn on all console logging
|
||||||
|
*/
|
||||||
void EnableConsoleLogging();
|
void EnableConsoleLogging();
|
||||||
|
|
||||||
// database
|
|
||||||
EQEmuLogSys *SetDatabase(Database *db);
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &GetLogPath() const;
|
|
||||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
|
||||||
|
|
||||||
void DisableMySQLErrorLogs();
|
|
||||||
void EnableMySQLErrorLogs();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// reference to database
|
/**
|
||||||
Database *m_database;
|
* Callback pointer to zone process for hooking logs to zone using GMSay
|
||||||
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&)> on_log_gmsay_hook;
|
||||||
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
|
std::function<void(uint16 debug_level, uint16 log_category, const std::string&)> 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;
|
|
||||||
|
|
||||||
void ProcessConsoleMessage(
|
/**
|
||||||
uint16 log_category,
|
* Formats log messages like '[Category] This is a log message'
|
||||||
const std::string &message,
|
*/
|
||||||
const char *file,
|
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
|
||||||
const char *func,
|
|
||||||
int line
|
/**
|
||||||
);
|
* Linux console color messages mapped by category
|
||||||
void ProcessLogWrite(uint16 log_category, const std::string &message);
|
*
|
||||||
void InjectTablesIfNotExist();
|
* @param log_category
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows console color messages mapped by category
|
||||||
|
*/
|
||||||
|
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param debug_level
|
||||||
|
* @param log_category
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param debug_level
|
||||||
|
* @param log_category
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param debug_level
|
||||||
|
* @param log_category
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param log_category
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool IsRfc5424LogCategory(uint16 log_category);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EQEmuLogSys LogSys;
|
extern EQEmuLogSys LogSys;
|
||||||
|
|||||||
+563
-373
File diff suppressed because it is too large
Load Diff
+11
-51
@@ -46,16 +46,20 @@ EQTime::EQTime()
|
|||||||
timezone = 0;
|
timezone = 0;
|
||||||
memset(&eqTime, 0, sizeof(eqTime));
|
memset(&eqTime, 0, sizeof(eqTime));
|
||||||
//Defaults for time
|
//Defaults for time
|
||||||
TimeOfDay_Struct t{};
|
TimeOfDay_Struct start;
|
||||||
t.day = 1;
|
start.day = 1;
|
||||||
t.hour = 9;
|
start.hour = 9;
|
||||||
t.minute = 0;
|
start.minute = 0;
|
||||||
t.month = 1;
|
start.month = 1;
|
||||||
t.year = 3100;
|
start.year = 3100;
|
||||||
//Set default time zone
|
//Set default time zone
|
||||||
timezone = 0;
|
timezone = 0;
|
||||||
//Start EQTimer
|
//Start EQTimer
|
||||||
SetCurrentEQTimeOfDay(t, time(nullptr));
|
SetCurrentEQTimeOfDay(start, time(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
EQTime::~EQTime()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
||||||
@@ -200,47 +204,3 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
|
|||||||
buf[127] = '\0';
|
buf[127] = '\0';
|
||||||
str = buf;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQTime::IsInbetweenTime(uint8 min_time, uint8 max_time) {
|
|
||||||
TimeOfDay_Struct tod{};
|
|
||||||
GetCurrentEQTimeOfDay(&tod);
|
|
||||||
|
|
||||||
if (min_time == 0 || max_time == 0 || min_time > 24 || max_time > 24) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_time < min_time) {
|
|
||||||
if ((tod.hour >= min_time && tod.hour > max_time) || (tod.hour < min_time && tod.hour <= max_time)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (tod.hour >= min_time && tod.hour <= max_time) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-4
@@ -18,7 +18,7 @@ public:
|
|||||||
//Constructor/destructor
|
//Constructor/destructor
|
||||||
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
|
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
|
||||||
EQTime();
|
EQTime();
|
||||||
~EQTime() = default;
|
~EQTime();
|
||||||
|
|
||||||
//Get functions
|
//Get functions
|
||||||
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
||||||
@@ -28,9 +28,6 @@ public:
|
|||||||
uint32 getEQTimeZone() { return timezone; }
|
uint32 getEQTimeZone() { return timezone; }
|
||||||
uint32 getEQTimeZoneHr() { return timezone/60; }
|
uint32 getEQTimeZoneHr() { return timezone/60; }
|
||||||
uint32 getEQTimeZoneMin() { return timezone%60; }
|
uint32 getEQTimeZoneMin() { return timezone%60; }
|
||||||
bool IsDayTime();
|
|
||||||
bool IsNightTime();
|
|
||||||
bool IsInbetweenTime(uint8 min_time, uint8 max_time);
|
|
||||||
|
|
||||||
//Set functions
|
//Set functions
|
||||||
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
|
||||||
|
|||||||
+4
-4
@@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <any>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include "event_loop.h"
|
#include "event_loop.h"
|
||||||
|
#include "../any.h"
|
||||||
|
|
||||||
namespace EQ {
|
namespace EQ {
|
||||||
class Task
|
class Task
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(const std::any&)> ResolveFn;
|
typedef std::function<void(const EQ::Any&)> ResolveFn;
|
||||||
typedef std::function<void(const std::exception&)> RejectFn;
|
typedef std::function<void(const std::exception&)> RejectFn;
|
||||||
typedef std::function<void()> FinallyFn;
|
typedef std::function<void()> FinallyFn;
|
||||||
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
|
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
|
||||||
@@ -19,7 +19,7 @@ namespace EQ {
|
|||||||
RejectFn on_catch;
|
RejectFn on_catch;
|
||||||
FinallyFn on_finally;
|
FinallyFn on_finally;
|
||||||
bool has_result;
|
bool has_result;
|
||||||
std::any result;
|
EQ::Any result;
|
||||||
bool has_error;
|
bool has_error;
|
||||||
std::exception error;
|
std::exception error;
|
||||||
};
|
};
|
||||||
@@ -63,7 +63,7 @@ namespace EQ {
|
|||||||
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
||||||
TaskBaton *baton = (TaskBaton*)req->data;
|
TaskBaton *baton = (TaskBaton*)req->data;
|
||||||
|
|
||||||
baton->fn([baton](const std::any& result) {
|
baton->fn([baton](const EQ::Any& result) {
|
||||||
baton->has_error = false;
|
baton->has_error = false;
|
||||||
baton->has_result = true;
|
baton->has_result = true;
|
||||||
baton->result = result;
|
baton->result = result;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace EQ
|
|||||||
_running = true;
|
_running = true;
|
||||||
|
|
||||||
for (size_t i = 0; i < threads; ++i) {
|
for (size_t i = 0; i < threads; ++i) {
|
||||||
_threads.emplace_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,8 +60,8 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fn, typename... Args>
|
template<typename Fn, typename... Args>
|
||||||
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::invoke_result<Fn, Args...>::type> {
|
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::result_of<Fn(Args...)>::type> {
|
||||||
using return_type = typename std::invoke_result<Fn, Args...>::type;
|
using return_type = typename std::result_of<Fn(Args...)>::type;
|
||||||
|
|
||||||
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
||||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,214 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../repositories/base/base_player_event_logs_repository.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <cereal/types/vector.hpp>
|
|
||||||
|
|
||||||
struct DiscordField {
|
|
||||||
std::string name;
|
|
||||||
std::string value;
|
|
||||||
bool is_inline;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(name),
|
|
||||||
CEREAL_NVP(value),
|
|
||||||
cereal::make_nvp("inline", is_inline)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordAuthor {
|
|
||||||
std::string name;
|
|
||||||
std::string icon_url;
|
|
||||||
std::string url;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(name),
|
|
||||||
CEREAL_NVP(icon_url),
|
|
||||||
CEREAL_NVP(url)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordEmbed {
|
|
||||||
std::vector<DiscordField> fields;
|
|
||||||
std::string title;
|
|
||||||
std::string description;
|
|
||||||
std::string timestamp;
|
|
||||||
DiscordAuthor author;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(fields),
|
|
||||||
CEREAL_NVP(title),
|
|
||||||
CEREAL_NVP(description),
|
|
||||||
CEREAL_NVP(timestamp),
|
|
||||||
CEREAL_NVP(author)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordWebhook {
|
|
||||||
std::vector<DiscordEmbed> embeds;
|
|
||||||
std::string content;
|
|
||||||
std::string avatar_url;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(embeds),
|
|
||||||
CEREAL_NVP(avatar_url),
|
|
||||||
CEREAL_NVP(content)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PlayerEventDiscordFormatter {
|
|
||||||
public:
|
|
||||||
static std::string GetCurrentTimestamp();
|
|
||||||
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
|
|
||||||
static std::string
|
|
||||||
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
|
|
||||||
static void BuildDiscordField(
|
|
||||||
std::vector<DiscordField> *f,
|
|
||||||
const std::string &name,
|
|
||||||
const std::string &value,
|
|
||||||
bool is_inline = true
|
|
||||||
);
|
|
||||||
static void BuildBaseEmbed(
|
|
||||||
std::vector<DiscordEmbed> *e,
|
|
||||||
const std::vector<DiscordField> &f,
|
|
||||||
PlayerEvent::PlayerEventContainer c
|
|
||||||
);
|
|
||||||
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
|
|
||||||
|
|
||||||
static std::string FormatAAGainedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::AAGainedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatAAPurchasedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::AAPurchasedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDeathEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DeathEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatFishSuccessEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::FishSuccessEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatForageSuccessEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ForageSuccessEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDestroyItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DestroyItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDiscoverItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DiscoverItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDroppedItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DroppedItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLevelGainedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LevelGainedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLevelLostEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LevelLostEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLootItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LootItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatGroundSpawnPickupEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::GroundSpawnPickupEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatMerchantPurchaseEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::MerchantPurchaseEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatMerchantSellEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::MerchantSellEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatNPCHandinEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::HandinEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatSkillUpEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::SkillUpEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskAcceptEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskAcceptEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskCompleteEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskCompleteEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskUpdateEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskUpdateEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTradeEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TradeEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTraderPurchaseEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TraderPurchaseEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTraderSellEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TraderSellEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatResurrectAcceptEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ResurrectAcceptEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatSplitMoneyEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::SplitMoneyEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatCombineEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::CombineEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatZoningEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ZoningEvent &e
|
|
||||||
);
|
|
||||||
static DiscordWebhook BuildDiscordWebhook(
|
|
||||||
const PlayerEvent::PlayerEventContainer &p,
|
|
||||||
std::vector<DiscordEmbed> &embeds
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
@@ -1,704 +0,0 @@
|
|||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include "player_event_logs.h"
|
|
||||||
#include "player_event_discord_formatter.h"
|
|
||||||
#include "../platform.h"
|
|
||||||
#include "../rulesys.h"
|
|
||||||
|
|
||||||
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
|
||||||
|
|
||||||
// general initialization routine
|
|
||||||
void PlayerEventLogs::Init()
|
|
||||||
{
|
|
||||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
|
||||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
|
||||||
|
|
||||||
ValidateDatabaseConnection();
|
|
||||||
|
|
||||||
// initialize settings array
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
m_settings[i].id = i;
|
|
||||||
m_settings[i].event_name = PlayerEvent::EventName[i];
|
|
||||||
m_settings[i].event_enabled = 1;
|
|
||||||
m_settings[i].retention_days = 0;
|
|
||||||
m_settings[i].discord_webhook_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSettingsDefaults();
|
|
||||||
|
|
||||||
// initialize settings from database
|
|
||||||
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
|
||||||
std::vector<int> db{};
|
|
||||||
db.reserve(s.size());
|
|
||||||
for (auto &e: s) {
|
|
||||||
if (e.id >= PlayerEvent::MAX) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_settings[e.id] = e;
|
|
||||||
db.emplace_back(e.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
|
||||||
|
|
||||||
// insert entries that don't exist in database
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
|
||||||
bool is_deprecated = Strings::Contains(PlayerEvent::EventName[i], "Deprecated");
|
|
||||||
bool is_implemented = !Strings::Contains(PlayerEvent::EventName[i], "Unimplemented");
|
|
||||||
|
|
||||||
// remove when deprecated
|
|
||||||
if (is_deprecated && is_in_database) {
|
|
||||||
LogInfo("[Deprecated] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
|
||||||
}
|
|
||||||
// remove when unimplemented if present
|
|
||||||
if (!is_implemented && is_in_database) {
|
|
||||||
LogInfo("[Unimplemented] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
|
||||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
|
||||||
LogInfo("[New] PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
|
|
||||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
|
||||||
c.id = i;
|
|
||||||
c.event_name = PlayerEvent::EventName[i];
|
|
||||||
c.event_enabled = m_settings[i].event_enabled;
|
|
||||||
c.retention_days = m_settings[i].retention_days;
|
|
||||||
settings_to_insert.emplace_back(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!settings_to_insert.empty()) {
|
|
||||||
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
|
||||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
|
||||||
|
|
||||||
// on initial boot process truncation
|
|
||||||
if (processing_in_world || processing_in_qs) {
|
|
||||||
ProcessRetentionTruncation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the database object, during initialization
|
|
||||||
PlayerEventLogs *PlayerEventLogs::SetDatabase(Database *db)
|
|
||||||
{
|
|
||||||
m_database = db;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validates whether the connection is valid or not, used in initialization
|
|
||||||
bool PlayerEventLogs::ValidateDatabaseConnection()
|
|
||||||
{
|
|
||||||
if (!m_database) {
|
|
||||||
LogError("No database connection");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determines if the passed in event is enabled or not
|
|
||||||
// this is used to gate logic or events from firing off
|
|
||||||
// this is used prior to building the events, we don't want to
|
|
||||||
// build the events, send them through the stack in a function call
|
|
||||||
// only to discard them immediately afterwards, very wasteful on resources
|
|
||||||
// the quest api currently does this
|
|
||||||
bool PlayerEventLogs::IsEventEnabled(PlayerEvent::EventType event)
|
|
||||||
{
|
|
||||||
return m_settings[event].event_enabled ? m_settings[event].event_enabled : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this processes any current player events on the queue
|
|
||||||
void PlayerEventLogs::ProcessBatchQueue()
|
|
||||||
{
|
|
||||||
m_batch_queue_lock.lock();
|
|
||||||
if (m_record_batch_queue.empty()) {
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BenchTimer benchmark;
|
|
||||||
|
|
||||||
// flush many
|
|
||||||
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
|
||||||
LogPlayerEventsDetail(
|
|
||||||
"Processing batch player event log queue of [{}] took [{}]",
|
|
||||||
m_record_batch_queue.size(),
|
|
||||||
benchmark.elapsed()
|
|
||||||
);
|
|
||||||
|
|
||||||
// empty
|
|
||||||
m_record_batch_queue = {};
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// adds a player event to the queue
|
|
||||||
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
|
||||||
{
|
|
||||||
m_batch_queue_lock.lock();
|
|
||||||
m_record_batch_queue.emplace_back(log);
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// fills common event data in the SendEvent function
|
|
||||||
void PlayerEventLogs::FillPlayerEvent(
|
|
||||||
const PlayerEvent::PlayerEvent &p,
|
|
||||||
PlayerEventLogsRepository::PlayerEventLogs &n
|
|
||||||
)
|
|
||||||
{
|
|
||||||
n.account_id = p.account_id;
|
|
||||||
n.character_id = p.character_id;
|
|
||||||
n.zone_id = p.zone_id;
|
|
||||||
n.instance_id = p.instance_id;
|
|
||||||
n.x = p.x;
|
|
||||||
n.y = p.y;
|
|
||||||
n.z = p.z;
|
|
||||||
n.heading = p.heading;
|
|
||||||
}
|
|
||||||
|
|
||||||
// builds the dynamic packet used to ship the player event over the wire
|
|
||||||
// supports serializing the struct so it can be rebuilt on the other end
|
|
||||||
std::unique_ptr<ServerPacket>
|
|
||||||
PlayerEventLogs::BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e)
|
|
||||||
{
|
|
||||||
EQ::Net::DynamicPacket dyn_pack;
|
|
||||||
dyn_pack.PutSerialize(0, e);
|
|
||||||
auto pack_size = sizeof(ServerSendPlayerEvent_Struct) + dyn_pack.Length();
|
|
||||||
auto pack = std::make_unique<ServerPacket>(ServerOP_PlayerEvent, static_cast<uint32_t>(pack_size));
|
|
||||||
auto buf = reinterpret_cast<ServerSendPlayerEvent_Struct *>(pack->pBuffer);
|
|
||||||
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
|
|
||||||
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
|
|
||||||
|
|
||||||
return pack;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PlayerEventLogSettingsRepository::PlayerEventLogSettings *PlayerEventLogs::GetSettings() const
|
|
||||||
{
|
|
||||||
return m_settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
|
|
||||||
{
|
|
||||||
// out of bounds check
|
|
||||||
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure webhook id is set
|
|
||||||
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure there is a matching webhook to begin with
|
|
||||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_type_id)
|
|
||||||
{
|
|
||||||
// out of bounds check
|
|
||||||
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure webhook id is set
|
|
||||||
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure there is a matching webhook to begin with
|
|
||||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
|
||||||
return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// GM_COMMAND | [x] Implemented Formatter
|
|
||||||
// ZONING | [x] Implemented Formatter
|
|
||||||
// AA_GAIN | [x] Implemented Formatter
|
|
||||||
// AA_PURCHASE | [x] Implemented Formatter
|
|
||||||
// FORAGE_SUCCESS | [x] Implemented Formatter
|
|
||||||
// FORAGE_FAILURE | [x] Implemented Formatter
|
|
||||||
// FISH_SUCCESS | [x] Implemented Formatter
|
|
||||||
// FISH_FAILURE | [x] Implemented Formatter
|
|
||||||
// ITEM_DESTROY | [x] Implemented Formatter
|
|
||||||
// WENT_ONLINE | [x] Implemented Formatter
|
|
||||||
// WENT_OFFLINE | [x] Implemented Formatter
|
|
||||||
// LEVEL_GAIN | [x] Implemented Formatter
|
|
||||||
// LEVEL_LOSS | [x] Implemented Formatter
|
|
||||||
// LOOT_ITEM | [x] Implemented Formatter
|
|
||||||
// MERCHANT_PURCHASE | [x] Implemented Formatter
|
|
||||||
// MERCHANT_SELL | [x] Implemented Formatter
|
|
||||||
// GROUP_JOIN | [] Implemented Formatter
|
|
||||||
// GROUP_LEAVE | [] Implemented Formatter
|
|
||||||
// RAID_JOIN | [] Implemented Formatter
|
|
||||||
// RAID_LEAVE | [] Implemented Formatter
|
|
||||||
// GROUNDSPAWN_PICKUP | [x] Implemented Formatter
|
|
||||||
// NPC_HANDIN | [x] Implemented Formatter
|
|
||||||
// SKILL_UP | [x] Implemented Formatter
|
|
||||||
// TASK_ACCEPT | [x] Implemented Formatter
|
|
||||||
// TASK_UPDATE | [x] Implemented Formatter
|
|
||||||
// TASK_COMPLETE | [x] Implemented Formatter
|
|
||||||
// TRADE | [] Implemented Formatter
|
|
||||||
// GIVE_ITEM | [] Implemented Formatter
|
|
||||||
// SAY | [x] Implemented Formatter
|
|
||||||
// REZ_ACCEPTED | [x] Implemented Formatter
|
|
||||||
// DEATH | [x] Implemented Formatter
|
|
||||||
// COMBINE_FAILURE | [x] Implemented Formatter
|
|
||||||
// COMBINE_SUCCESS | [x] Implemented Formatter
|
|
||||||
// DROPPED_ITEM | [x] Implemented Formatter
|
|
||||||
// SPLIT_MONEY | [x] Implemented Formatter
|
|
||||||
// DZ_JOIN | [] Implemented Formatter
|
|
||||||
// DZ_LEAVE | [] Implemented Formatter
|
|
||||||
// TRADER_PURCHASE | [x] Implemented Formatter
|
|
||||||
// TRADER_SELL | [x] Implemented Formatter
|
|
||||||
// BANDOLIER_CREATE | [] Implemented Formatter
|
|
||||||
// BANDOLIER_SWAP | [] Implemented Formatter
|
|
||||||
// DISCOVER_ITEM | [X] Implemented Formatter
|
|
||||||
|
|
||||||
std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e)
|
|
||||||
{
|
|
||||||
std::string payload;
|
|
||||||
switch (e.player_event_log.event_type_id) {
|
|
||||||
case PlayerEvent::AA_GAIN: {
|
|
||||||
PlayerEvent::AAGainedEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatAAGainedEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::AA_PURCHASE: {
|
|
||||||
PlayerEvent::AAPurchasedEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatAAPurchasedEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::COMBINE_FAILURE:
|
|
||||||
case PlayerEvent::COMBINE_SUCCESS: {
|
|
||||||
PlayerEvent::CombineEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatCombineEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::DEATH: {
|
|
||||||
PlayerEvent::DeathEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDeathEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::DISCOVER_ITEM: {
|
|
||||||
PlayerEvent::DiscoverItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDiscoverItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::DROPPED_ITEM: {
|
|
||||||
PlayerEvent::DroppedItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FISH_FAILURE:
|
|
||||||
case PlayerEvent::FORAGE_FAILURE:
|
|
||||||
case PlayerEvent::WENT_ONLINE:
|
|
||||||
case PlayerEvent::WENT_OFFLINE: {
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FISH_SUCCESS: {
|
|
||||||
PlayerEvent::FishSuccessEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FORAGE_SUCCESS: {
|
|
||||||
PlayerEvent::ForageSuccessEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatForageSuccessEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::ITEM_DESTROY: {
|
|
||||||
PlayerEvent::DestroyItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDestroyItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::LEVEL_GAIN: {
|
|
||||||
PlayerEvent::LevelGainedEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatLevelGainedEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::LEVEL_LOSS: {
|
|
||||||
PlayerEvent::LevelLostEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatLevelLostEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::LOOT_ITEM: {
|
|
||||||
PlayerEvent::LootItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatLootItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::GROUNDSPAWN_PICKUP: {
|
|
||||||
PlayerEvent::GroundSpawnPickupEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatGroundSpawnPickupEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::NPC_HANDIN: {
|
|
||||||
PlayerEvent::HandinEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatNPCHandinEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::SAY: {
|
|
||||||
PlayerEvent::SayEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatEventSay(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::GM_COMMAND: {
|
|
||||||
PlayerEvent::GMCommandEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatGMCommand(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::SKILL_UP: {
|
|
||||||
PlayerEvent::SkillUpEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatSkillUpEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::SPLIT_MONEY: {
|
|
||||||
PlayerEvent::SplitMoneyEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatSplitMoneyEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TASK_ACCEPT: {
|
|
||||||
PlayerEvent::TaskAcceptEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTaskAcceptEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TASK_COMPLETE: {
|
|
||||||
PlayerEvent::TaskCompleteEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTaskCompleteEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TASK_UPDATE: {
|
|
||||||
PlayerEvent::TaskUpdateEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTaskUpdateEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TRADE: {
|
|
||||||
PlayerEvent::TradeEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTradeEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TRADER_PURCHASE: {
|
|
||||||
PlayerEvent::TraderPurchaseEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTraderPurchaseEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TRADER_SELL: {
|
|
||||||
PlayerEvent::TraderSellEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTraderSellEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::REZ_ACCEPTED: {
|
|
||||||
PlayerEvent::ResurrectAcceptEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::MERCHANT_PURCHASE: {
|
|
||||||
PlayerEvent::MerchantPurchaseEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatMerchantPurchaseEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::MERCHANT_SELL: {
|
|
||||||
PlayerEvent::MerchantSellEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatMerchantSellEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::ZONING: {
|
|
||||||
PlayerEvent::ZoningEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatZoningEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
LogInfo(
|
|
||||||
"Player event [{}] ({}) Discord formatter not implemented",
|
|
||||||
e.player_event_log.event_type_name,
|
|
||||||
e.player_event_log.event_type_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
|
||||||
void PlayerEventLogs::Process()
|
|
||||||
{
|
|
||||||
if (m_process_batch_events_timer.Check() || m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
|
||||||
ProcessBatchQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_process_retention_truncation_timer.Check()) {
|
|
||||||
ProcessRetentionTruncation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
|
||||||
{
|
|
||||||
LogPlayerEvents("Running truncation");
|
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
if (m_settings[i].retention_days > 0) {
|
|
||||||
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
|
||||||
*m_database,
|
|
||||||
fmt::format(
|
|
||||||
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
|
|
||||||
i,
|
|
||||||
m_settings[i].retention_days
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (deleted_count > 0) {
|
|
||||||
LogInfo(
|
|
||||||
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
|
|
||||||
deleted_count,
|
|
||||||
PlayerEvent::EventName[i],
|
|
||||||
i,
|
|
||||||
m_settings[i].retention_days
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerEventLogs::ReloadSettings()
|
|
||||||
{
|
|
||||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
|
||||||
m_settings[e.id] = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32_t RETENTION_DAYS_DEFAULT = 7;
|
|
||||||
|
|
||||||
void PlayerEventLogs::SetSettingsDefaults()
|
|
||||||
{
|
|
||||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
|
||||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
|
||||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
#define EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
|
|
||||||
#include "../repositories/player_event_log_settings_repository.h"
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../servertalk.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../timer.h"
|
|
||||||
#include "../json/json_archive_single_line.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class PlayerEventLogs {
|
|
||||||
public:
|
|
||||||
void Init();
|
|
||||||
void ReloadSettings();
|
|
||||||
PlayerEventLogs *SetDatabase(Database *db);
|
|
||||||
bool ValidateDatabaseConnection();
|
|
||||||
bool IsEventEnabled(PlayerEvent::EventType event);
|
|
||||||
|
|
||||||
void Process();
|
|
||||||
|
|
||||||
// batch queue
|
|
||||||
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
|
||||||
|
|
||||||
// main event record generic function
|
|
||||||
// can ingest any struct event types
|
|
||||||
template<typename T>
|
|
||||||
std::unique_ptr<ServerPacket> RecordEvent(
|
|
||||||
PlayerEvent::EventType t,
|
|
||||||
const PlayerEvent::PlayerEvent &p,
|
|
||||||
T e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto n = PlayerEventLogsRepository::NewEntity();
|
|
||||||
FillPlayerEvent(p, n);
|
|
||||||
n.event_type_id = t;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
cereal::JSONOutputArchiveSingleLine ar(ss);
|
|
||||||
e.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
n.event_type_name = PlayerEvent::EventName[t];
|
|
||||||
n.event_data = Strings::Contains(ss.str(), "noop") ? "{}" : ss.str();
|
|
||||||
n.created_at = std::time(nullptr);
|
|
||||||
|
|
||||||
auto c = PlayerEvent::PlayerEventContainer{
|
|
||||||
.player_event = p,
|
|
||||||
.player_event_log = n
|
|
||||||
};
|
|
||||||
|
|
||||||
return BuildPlayerEventPacket(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
|
|
||||||
bool IsEventDiscordEnabled(int32_t event_type_id);
|
|
||||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
|
||||||
|
|
||||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
|
||||||
private:
|
|
||||||
Database *m_database; // reference to database
|
|
||||||
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
|
||||||
|
|
||||||
// batch queue is used to record events in batch
|
|
||||||
std::vector<PlayerEventLogsRepository::PlayerEventLogs> m_record_batch_queue{};
|
|
||||||
static void FillPlayerEvent(const PlayerEvent::PlayerEvent &p, PlayerEventLogsRepository::PlayerEventLogs &n);
|
|
||||||
static std::unique_ptr<ServerPacket>
|
|
||||||
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
|
||||||
|
|
||||||
// timers
|
|
||||||
Timer m_process_batch_events_timer; // events processing timer
|
|
||||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
|
||||||
|
|
||||||
// processing
|
|
||||||
std::mutex m_batch_queue_lock{};
|
|
||||||
void ProcessBatchQueue();
|
|
||||||
void ProcessRetentionTruncation();
|
|
||||||
void SetSettingsDefaults();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern PlayerEventLogs player_event_logs;
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
@@ -1,971 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENTS_H
|
|
||||||
#define EQEMU_PLAYER_EVENTS_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cereal/cereal.hpp>
|
|
||||||
#include "../types.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
|
|
||||||
namespace PlayerEvent {
|
|
||||||
|
|
||||||
enum EventType {
|
|
||||||
GM_COMMAND = 1,
|
|
||||||
ZONING,
|
|
||||||
AA_GAIN,
|
|
||||||
AA_PURCHASE,
|
|
||||||
FORAGE_SUCCESS,
|
|
||||||
FORAGE_FAILURE,
|
|
||||||
FISH_SUCCESS,
|
|
||||||
FISH_FAILURE,
|
|
||||||
ITEM_DESTROY,
|
|
||||||
WENT_ONLINE,
|
|
||||||
WENT_OFFLINE,
|
|
||||||
LEVEL_GAIN,
|
|
||||||
LEVEL_LOSS,
|
|
||||||
LOOT_ITEM,
|
|
||||||
MERCHANT_PURCHASE,
|
|
||||||
MERCHANT_SELL,
|
|
||||||
GROUP_JOIN, // unimplemented
|
|
||||||
GROUP_LEAVE, // unimplemented
|
|
||||||
RAID_JOIN, // unimplemented
|
|
||||||
RAID_LEAVE, // unimplemented
|
|
||||||
GROUNDSPAWN_PICKUP,
|
|
||||||
NPC_HANDIN,
|
|
||||||
SKILL_UP,
|
|
||||||
TASK_ACCEPT,
|
|
||||||
TASK_UPDATE,
|
|
||||||
TASK_COMPLETE,
|
|
||||||
TRADE,
|
|
||||||
GIVE_ITEM, // unimplemented
|
|
||||||
SAY,
|
|
||||||
REZ_ACCEPTED,
|
|
||||||
DEATH,
|
|
||||||
COMBINE_FAILURE,
|
|
||||||
COMBINE_SUCCESS,
|
|
||||||
DROPPED_ITEM,
|
|
||||||
SPLIT_MONEY,
|
|
||||||
DZ_JOIN, // unimplemented
|
|
||||||
DZ_LEAVE, // unimplemented
|
|
||||||
TRADER_PURCHASE,
|
|
||||||
TRADER_SELL,
|
|
||||||
BANDOLIER_CREATE, // unimplemented
|
|
||||||
BANDOLIER_SWAP, // unimplemented
|
|
||||||
DISCOVER_ITEM,
|
|
||||||
POSSIBLE_HACK,
|
|
||||||
KILLED_NPC,
|
|
||||||
KILLED_NAMED_NPC,
|
|
||||||
KILLED_RAID_NPC,
|
|
||||||
ITEM_CREATION,
|
|
||||||
MAX // dont remove
|
|
||||||
};
|
|
||||||
|
|
||||||
// Don't ever remove items, even if they are deprecated
|
|
||||||
// If event is deprecated just tag (Deprecated) in the name
|
|
||||||
// If event is unimplemented just tag (Unimplemented) in the name
|
|
||||||
// Events don't get saved to the database if unimplemented or deprecated
|
|
||||||
// Events tagged as deprecated will get automatically removed
|
|
||||||
static const char *EventName[PlayerEvent::MAX] = {
|
|
||||||
"None",
|
|
||||||
"GM Command",
|
|
||||||
"Zoning",
|
|
||||||
"AA Gain",
|
|
||||||
"AA Purchase",
|
|
||||||
"Forage Success",
|
|
||||||
"Forage Failure",
|
|
||||||
"Fish Success",
|
|
||||||
"Fish Failure",
|
|
||||||
"Item Destroy",
|
|
||||||
"Went Online",
|
|
||||||
"Went Offline",
|
|
||||||
"Level Gain",
|
|
||||||
"Level Loss",
|
|
||||||
"Loot Item",
|
|
||||||
"Merchant Purchase",
|
|
||||||
"Merchant Sell",
|
|
||||||
"Group Join (Unimplemented)",
|
|
||||||
"Group Leave (Unimplemented)",
|
|
||||||
"Raid Join (Unimplemented)",
|
|
||||||
"Raid Leave (Unimplemented)",
|
|
||||||
"Groundspawn Pickup",
|
|
||||||
"NPC Handin",
|
|
||||||
"Skill Up",
|
|
||||||
"Task Accept",
|
|
||||||
"Task Update",
|
|
||||||
"Task Complete",
|
|
||||||
"Trade",
|
|
||||||
"Given Item (Unimplemented)",
|
|
||||||
"Say",
|
|
||||||
"Rez Accepted",
|
|
||||||
"Death",
|
|
||||||
"Combine Failure",
|
|
||||||
"Combine Success",
|
|
||||||
"Dropped Item",
|
|
||||||
"Split Money",
|
|
||||||
"DZ Join (Unimplemented)",
|
|
||||||
"DZ Leave (Unimplemented)",
|
|
||||||
"Trader Purchase",
|
|
||||||
"Trader Sell",
|
|
||||||
"Bandolier Create (Unimplemented)",
|
|
||||||
"Bandolier Swap (Unimplemented)",
|
|
||||||
"Discover Item",
|
|
||||||
"Possible Hack",
|
|
||||||
"Killed NPC",
|
|
||||||
"Killed Named NPC",
|
|
||||||
"Killed Raid NPC",
|
|
||||||
"Item Creation"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic struct used by all events
|
|
||||||
struct PlayerEvent {
|
|
||||||
int64 account_id;
|
|
||||||
std::string account_name;
|
|
||||||
int64 character_id;
|
|
||||||
std::string character_name;
|
|
||||||
int64 guild_id;
|
|
||||||
std::string guild_name;
|
|
||||||
int zone_id;
|
|
||||||
std::string zone_short_name;
|
|
||||||
std::string zone_long_name;
|
|
||||||
int instance_id;
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float heading;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(account_id),
|
|
||||||
CEREAL_NVP(account_name),
|
|
||||||
CEREAL_NVP(character_id),
|
|
||||||
CEREAL_NVP(character_name),
|
|
||||||
CEREAL_NVP(guild_id),
|
|
||||||
CEREAL_NVP(guild_name),
|
|
||||||
CEREAL_NVP(zone_id),
|
|
||||||
CEREAL_NVP(zone_short_name),
|
|
||||||
CEREAL_NVP(zone_long_name),
|
|
||||||
CEREAL_NVP(instance_id),
|
|
||||||
CEREAL_NVP(x),
|
|
||||||
CEREAL_NVP(y),
|
|
||||||
CEREAL_NVP(z),
|
|
||||||
CEREAL_NVP(heading)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// contains metadata in use for things like log/discord formatters
|
|
||||||
// along with the actual event to be persisted
|
|
||||||
struct PlayerEventContainer {
|
|
||||||
PlayerEvent player_event;
|
|
||||||
PlayerEventLogsRepository::PlayerEventLogs player_event_log;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(player_event),
|
|
||||||
CEREAL_NVP(player_event_log)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in events with no extra data
|
|
||||||
struct EmptyEvent {
|
|
||||||
std::string noop; // noop, gets discard upstream
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(noop)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
struct ItemCreationEvent {
|
|
||||||
int64 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 to_slot;
|
|
||||||
int16 charges;
|
|
||||||
uint32 aug1;
|
|
||||||
uint32 aug2;
|
|
||||||
uint32 aug3;
|
|
||||||
uint32 aug4;
|
|
||||||
uint32 aug5;
|
|
||||||
uint32 aug6;
|
|
||||||
bool attuned;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(to_slot),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(aug1),
|
|
||||||
CEREAL_NVP(aug2),
|
|
||||||
CEREAL_NVP(aug3),
|
|
||||||
CEREAL_NVP(aug4),
|
|
||||||
CEREAL_NVP(aug5),
|
|
||||||
CEREAL_NVP(aug6),
|
|
||||||
CEREAL_NVP(attuned)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
struct TradeItem {
|
|
||||||
int64 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int32 slot;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(slot)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
class TradeItemEntry {
|
|
||||||
public:
|
|
||||||
uint16 slot;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 charges;
|
|
||||||
uint32 aug_1_item_id;
|
|
||||||
std::string aug_1_item_name;
|
|
||||||
uint32 aug_2_item_id;
|
|
||||||
std::string aug_2_item_name;
|
|
||||||
uint32 aug_3_item_id;
|
|
||||||
std::string aug_3_item_name;
|
|
||||||
uint32 aug_4_item_id;
|
|
||||||
std::string aug_4_item_name;
|
|
||||||
uint32 aug_5_item_id;
|
|
||||||
std::string aug_5_item_name;
|
|
||||||
uint32 aug_6_item_id;
|
|
||||||
std::string aug_6_item_name;
|
|
||||||
bool in_bag;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(slot),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(aug_1_item_id),
|
|
||||||
CEREAL_NVP(aug_2_item_id),
|
|
||||||
CEREAL_NVP(aug_3_item_id),
|
|
||||||
CEREAL_NVP(aug_4_item_id),
|
|
||||||
CEREAL_NVP(aug_5_item_id),
|
|
||||||
CEREAL_NVP(in_bag)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Events
|
|
||||||
*/
|
|
||||||
struct Money {
|
|
||||||
int32 platinum;
|
|
||||||
int32 gold;
|
|
||||||
int32 silver;
|
|
||||||
int32 copper;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(platinum),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(copper)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TradeEvent {
|
|
||||||
uint32 character_1_id;
|
|
||||||
std::string character_1_name;
|
|
||||||
uint32 character_2_id;
|
|
||||||
std::string character_2_name;
|
|
||||||
Money character_1_give_money;
|
|
||||||
Money character_2_give_money;
|
|
||||||
std::vector<TradeItemEntry> character_1_give_items;
|
|
||||||
std::vector<TradeItemEntry> character_2_give_items;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(character_1_id),
|
|
||||||
CEREAL_NVP(character_1_name),
|
|
||||||
CEREAL_NVP(character_2_id),
|
|
||||||
CEREAL_NVP(character_2_name),
|
|
||||||
CEREAL_NVP(character_1_give_money),
|
|
||||||
CEREAL_NVP(character_2_give_money),
|
|
||||||
CEREAL_NVP(character_1_give_items),
|
|
||||||
CEREAL_NVP(character_2_give_items)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GMCommandEvent {
|
|
||||||
std::string message;
|
|
||||||
std::string target;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message),
|
|
||||||
CEREAL_NVP(target)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZoningEvent {
|
|
||||||
std::string from_zone_long_name;
|
|
||||||
std::string from_zone_short_name;
|
|
||||||
int32 from_zone_id;
|
|
||||||
int32 from_instance_id;
|
|
||||||
int32 from_instance_version;
|
|
||||||
std::string to_zone_long_name;
|
|
||||||
std::string to_zone_short_name;
|
|
||||||
int32 to_zone_id;
|
|
||||||
int32 to_instance_id;
|
|
||||||
int32 to_instance_version;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_zone_long_name),
|
|
||||||
CEREAL_NVP(from_zone_short_name),
|
|
||||||
CEREAL_NVP(from_zone_id),
|
|
||||||
CEREAL_NVP(from_instance_id),
|
|
||||||
CEREAL_NVP(from_instance_version),
|
|
||||||
CEREAL_NVP(to_zone_long_name),
|
|
||||||
CEREAL_NVP(to_zone_short_name),
|
|
||||||
CEREAL_NVP(to_zone_id),
|
|
||||||
CEREAL_NVP(to_instance_id),
|
|
||||||
CEREAL_NVP(to_instance_version)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAGainedEvent {
|
|
||||||
uint32 aa_gained;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(CEREAL_NVP(aa_gained));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAPurchasedEvent {
|
|
||||||
uint32 aa_id;
|
|
||||||
int32 aa_cost;
|
|
||||||
int32 aa_previous_id;
|
|
||||||
int32 aa_next_id;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(aa_id),
|
|
||||||
CEREAL_NVP(aa_cost),
|
|
||||||
CEREAL_NVP(aa_previous_id),
|
|
||||||
CEREAL_NVP(aa_next_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ForageSuccessEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FishSuccessEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DestroyItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
std::string reason;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(reason),
|
|
||||||
CEREAL_NVP(charges)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LevelGainedEvent {
|
|
||||||
uint32 from_level;
|
|
||||||
uint8 to_level;
|
|
||||||
int levels_gained;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_level),
|
|
||||||
CEREAL_NVP(to_level),
|
|
||||||
CEREAL_NVP(levels_gained)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LevelLostEvent {
|
|
||||||
uint32 from_level;
|
|
||||||
uint8 to_level;
|
|
||||||
int levels_lost;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_level),
|
|
||||||
CEREAL_NVP(to_level),
|
|
||||||
CEREAL_NVP(levels_lost)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LootItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string corpse_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(corpse_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MerchantPurchaseEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string merchant_name;
|
|
||||||
uint32 merchant_type;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
uint32 cost;
|
|
||||||
uint32 alternate_currency_id;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
uint64 player_currency_balance;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(merchant_name),
|
|
||||||
CEREAL_NVP(merchant_type),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(cost),
|
|
||||||
CEREAL_NVP(alternate_currency_id),
|
|
||||||
CEREAL_NVP(player_money_balance),
|
|
||||||
CEREAL_NVP(player_currency_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MerchantSellEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string merchant_name;
|
|
||||||
uint32 merchant_type;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
uint32 cost;
|
|
||||||
uint32 alternate_currency_id;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
uint64 player_currency_balance;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(merchant_name),
|
|
||||||
CEREAL_NVP(merchant_type),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(cost),
|
|
||||||
CEREAL_NVP(alternate_currency_id),
|
|
||||||
CEREAL_NVP(player_money_balance),
|
|
||||||
CEREAL_NVP(player_currency_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SkillUpEvent {
|
|
||||||
uint32 skill_id;
|
|
||||||
int value;
|
|
||||||
int16 max_skill;
|
|
||||||
std::string against_who;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(skill_id),
|
|
||||||
CEREAL_NVP(value),
|
|
||||||
CEREAL_NVP(max_skill),
|
|
||||||
CEREAL_NVP(against_who)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TaskAcceptEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string npc_name;
|
|
||||||
uint32 task_id;
|
|
||||||
std::string task_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(npc_name),
|
|
||||||
CEREAL_NVP(task_id),
|
|
||||||
CEREAL_NVP(task_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TaskUpdateEvent {
|
|
||||||
uint32 task_id;
|
|
||||||
std::string task_name;
|
|
||||||
uint32 activity_id;
|
|
||||||
uint32 done_count;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(task_id),
|
|
||||||
CEREAL_NVP(task_name),
|
|
||||||
CEREAL_NVP(activity_id),
|
|
||||||
CEREAL_NVP(done_count)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TaskCompleteEvent {
|
|
||||||
uint32 task_id;
|
|
||||||
std::string task_name;
|
|
||||||
uint32 activity_id;
|
|
||||||
uint32 done_count;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(task_id),
|
|
||||||
CEREAL_NVP(task_name),
|
|
||||||
CEREAL_NVP(activity_id),
|
|
||||||
CEREAL_NVP(done_count)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GroundSpawnPickupEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SayEvent {
|
|
||||||
std::string message;
|
|
||||||
std::string target;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message),
|
|
||||||
CEREAL_NVP(target)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ResurrectAcceptEvent {
|
|
||||||
std::string resurrecter_name;
|
|
||||||
std::string spell_name;
|
|
||||||
uint32 spell_id;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(resurrecter_name),
|
|
||||||
CEREAL_NVP(spell_name),
|
|
||||||
CEREAL_NVP(spell_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CombineEvent {
|
|
||||||
uint32 recipe_id;
|
|
||||||
std::string recipe_name;
|
|
||||||
uint32 made_count;
|
|
||||||
uint32 tradeskill_id;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(recipe_id),
|
|
||||||
CEREAL_NVP(recipe_name),
|
|
||||||
CEREAL_NVP(made_count),
|
|
||||||
CEREAL_NVP(tradeskill_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DroppedItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 slot_id;
|
|
||||||
uint32 charges;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(slot_id),
|
|
||||||
CEREAL_NVP(charges)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DeathEvent {
|
|
||||||
uint32 killer_id;
|
|
||||||
std::string killer_name;
|
|
||||||
int64 damage;
|
|
||||||
uint32 spell_id;
|
|
||||||
std::string spell_name;
|
|
||||||
int skill_id;
|
|
||||||
std::string skill_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(killer_id),
|
|
||||||
CEREAL_NVP(killer_name),
|
|
||||||
CEREAL_NVP(damage),
|
|
||||||
CEREAL_NVP(spell_id),
|
|
||||||
CEREAL_NVP(spell_name),
|
|
||||||
CEREAL_NVP(skill_id),
|
|
||||||
CEREAL_NVP(skill_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SplitMoneyEvent {
|
|
||||||
uint32 copper;
|
|
||||||
uint32 silver;
|
|
||||||
uint32 gold;
|
|
||||||
uint32 platinum;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(copper),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(platinum),
|
|
||||||
CEREAL_NVP(player_money_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraderPurchaseEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint32 trader_id;
|
|
||||||
std::string trader_name;
|
|
||||||
uint32 price;
|
|
||||||
uint32 charges;
|
|
||||||
uint32 total_cost;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(trader_id),
|
|
||||||
CEREAL_NVP(trader_name),
|
|
||||||
CEREAL_NVP(price),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(total_cost),
|
|
||||||
CEREAL_NVP(player_money_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraderSellEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint32 buyer_id;
|
|
||||||
std::string buyer_name;
|
|
||||||
uint32 price;
|
|
||||||
uint32 charges;
|
|
||||||
uint32 total_cost;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(buyer_id),
|
|
||||||
CEREAL_NVP(buyer_name),
|
|
||||||
CEREAL_NVP(price),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(total_cost),
|
|
||||||
CEREAL_NVP(player_money_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscoverItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class HandinEntry {
|
|
||||||
public:
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 charges;
|
|
||||||
bool attuned;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(attuned)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class HandinMoney {
|
|
||||||
public:
|
|
||||||
uint32 copper;
|
|
||||||
uint32 silver;
|
|
||||||
uint32 gold;
|
|
||||||
uint32 platinum;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(copper),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(platinum)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HandinEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string npc_name;
|
|
||||||
std::vector<HandinEntry> handin_items;
|
|
||||||
HandinMoney handin_money;
|
|
||||||
std::vector<HandinEntry> return_items;
|
|
||||||
HandinMoney return_money;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(npc_name),
|
|
||||||
CEREAL_NVP(handin_items),
|
|
||||||
CEREAL_NVP(handin_money),
|
|
||||||
CEREAL_NVP(return_items),
|
|
||||||
CEREAL_NVP(return_money)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PossibleHackEvent {
|
|
||||||
std::string message;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct KilledNPCEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string npc_name;
|
|
||||||
uint32 combat_time_seconds;
|
|
||||||
uint64 total_damage_per_second_taken;
|
|
||||||
uint64 total_heal_per_second_taken;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(npc_name),
|
|
||||||
CEREAL_NVP(combat_time_seconds),
|
|
||||||
CEREAL_NVP(total_damage_per_second_taken),
|
|
||||||
CEREAL_NVP(total_heal_per_second_taken)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENTS_H
|
|
||||||
|
|
||||||
#define RecordPlayerEventLog(event_type, event_data) do {\
|
|
||||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
|
||||||
worldserver.SendPacket(\
|
|
||||||
player_event_logs.RecordEvent(\
|
|
||||||
event_type,\
|
|
||||||
GetPlayerEvent(),\
|
|
||||||
event_data\
|
|
||||||
).get()\
|
|
||||||
);\
|
|
||||||
}\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
|
||||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
|
||||||
worldserver.SendPacket(\
|
|
||||||
player_event_logs.RecordEvent(\
|
|
||||||
event_type,\
|
|
||||||
(c)->GetPlayerEvent(),\
|
|
||||||
event_data\
|
|
||||||
).get()\
|
|
||||||
);\
|
|
||||||
}\
|
|
||||||
} while (0)
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#include "expedition_base.h"
|
||||||
|
#include "repositories/expeditions_repository.h"
|
||||||
|
|
||||||
|
ExpeditionBase::ExpeditionBase(uint32_t id, const std::string& uuid,
|
||||||
|
const std::string& expedition_name, const DynamicZoneMember& leader
|
||||||
|
) :
|
||||||
|
m_id(id),
|
||||||
|
m_uuid(uuid),
|
||||||
|
m_expedition_name(expedition_name),
|
||||||
|
m_leader(leader)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpeditionBase::LoadRepositoryResult(ExpeditionsRepository::ExpeditionWithLeader&& entry)
|
||||||
|
{
|
||||||
|
m_id = entry.id;
|
||||||
|
m_uuid = std::move(entry.uuid);
|
||||||
|
m_expedition_name = std::move(entry.expedition_name);
|
||||||
|
m_add_replay_on_join = entry.add_replay_on_join;
|
||||||
|
m_is_locked = entry.is_locked;
|
||||||
|
m_leader.id = entry.leader_id;
|
||||||
|
m_leader.name = std::move(entry.leader_name);
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#ifndef COMMON_EXPEDITION_BASE_H
|
||||||
|
#define COMMON_EXPEDITION_BASE_H
|
||||||
|
|
||||||
|
#include "dynamic_zone_base.h"
|
||||||
|
#include "repositories/expeditions_repository.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ExpeditionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ExpeditionBase() = default;
|
||||||
|
ExpeditionBase(const ExpeditionBase&) = default;
|
||||||
|
ExpeditionBase(ExpeditionBase&&) = default;
|
||||||
|
ExpeditionBase& operator=(const ExpeditionBase&) = default;
|
||||||
|
ExpeditionBase& operator=(ExpeditionBase&&) = default;
|
||||||
|
|
||||||
|
uint32_t GetID() const { return m_id; }
|
||||||
|
uint32_t GetLeaderID() const { return m_leader.id; }
|
||||||
|
const std::string& GetName() const { return m_expedition_name; }
|
||||||
|
const std::string& GetLeaderName() const { return m_leader.name; }
|
||||||
|
const std::string& GetUUID() const { return m_uuid; }
|
||||||
|
const DynamicZoneMember& GetLeader() const { return m_leader; }
|
||||||
|
|
||||||
|
void LoadRepositoryResult(ExpeditionsRepository::ExpeditionWithLeader&& entry);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ExpeditionBase() = default;
|
||||||
|
ExpeditionBase(uint32_t id, const std::string& uuid, const std::string& expedition_name,
|
||||||
|
const DynamicZoneMember& leader);
|
||||||
|
|
||||||
|
uint32_t m_id = 0;
|
||||||
|
bool m_is_locked = false;
|
||||||
|
bool m_add_replay_on_join = true;
|
||||||
|
std::string m_uuid;
|
||||||
|
std::string m_expedition_name;
|
||||||
|
DynamicZoneMember m_leader;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "expedition_lockout_timer.h"
|
#include "expedition_lockout_timer.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/util/uuid.h"
|
#include "../common/util/uuid.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|||||||
+24
-24
@@ -20,31 +20,31 @@
|
|||||||
#include "races.h"
|
#include "races.h"
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
|
|
||||||
const char *FactionValueToString(FACTION_VALUE faction_value)
|
const char *FactionValueToString(FACTION_VALUE fv)
|
||||||
{
|
{
|
||||||
switch (faction_value) {
|
switch (fv) {
|
||||||
case FACTION_ALLY:
|
case FACTION_ALLY:
|
||||||
return "Ally";
|
return ("Ally");
|
||||||
case FACTION_WARMLY:
|
case FACTION_WARMLY:
|
||||||
return "Warmly";
|
return ("Warmly");
|
||||||
case FACTION_KINDLY:
|
case FACTION_KINDLY:
|
||||||
return "Kindly";
|
return ("Kindly");
|
||||||
case FACTION_AMIABLY:
|
case FACTION_AMIABLE:
|
||||||
return "Amiably";
|
return ("Amiable");
|
||||||
case FACTION_INDIFFERENTLY:
|
case FACTION_INDIFFERENT:
|
||||||
return "Indifferently";
|
return ("Indifferent");
|
||||||
case FACTION_APPREHENSIVELY:
|
case FACTION_APPREHENSIVE:
|
||||||
return "Apprehensively";
|
return ("Apprehensive");
|
||||||
case FACTION_DUBIOUSLY:
|
case FACTION_DUBIOUS:
|
||||||
return "Dubiously";
|
return ("Dubious");
|
||||||
case FACTION_THREATENINGLY:
|
case FACTION_THREATENLY:
|
||||||
return "Threateningly";
|
return ("Threatenly");
|
||||||
case FACTION_SCOWLS:
|
case FACTION_SCOWLS:
|
||||||
return "Scowls";
|
return ("Scowls, ready to attack.");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return ("Unknown Faction Con");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -70,19 +70,19 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
|
|||||||
return FACTION_KINDLY;
|
return FACTION_KINDLY;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
|
||||||
return FACTION_AMIABLY;
|
return FACTION_AMIABLE;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
|
||||||
return FACTION_INDIFFERENTLY;
|
return FACTION_INDIFFERENT;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
|
||||||
return FACTION_APPREHENSIVELY;
|
return FACTION_APPREHENSIVE;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
|
||||||
return FACTION_DUBIOUSLY;
|
return FACTION_DUBIOUS;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
|
||||||
return FACTION_THREATENINGLY;
|
return FACTION_THREATENLY;
|
||||||
}
|
}
|
||||||
return FACTION_SCOWLS;
|
return FACTION_SCOWLS;
|
||||||
}
|
}
|
||||||
@@ -96,12 +96,12 @@ bool IsOfEqualRace(int r1, int r2)
|
|||||||
// TODO: add more values
|
// TODO: add more values
|
||||||
switch (r1) {
|
switch (r1) {
|
||||||
case DARK_ELF:
|
case DARK_ELF:
|
||||||
if (r2 == Race::NeriakCitizen) {
|
if (r2 == 77) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BARBARIAN:
|
case BARBARIAN:
|
||||||
if (r2 == Race::HalasCitizen) {
|
if (r2 == 90) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-27
@@ -27,13 +27,13 @@ enum FACTION_VALUE {
|
|||||||
FACTION_ALLY = 1,
|
FACTION_ALLY = 1,
|
||||||
FACTION_WARMLY = 2,
|
FACTION_WARMLY = 2,
|
||||||
FACTION_KINDLY = 3,
|
FACTION_KINDLY = 3,
|
||||||
FACTION_AMIABLY = 4,
|
FACTION_AMIABLE = 4,
|
||||||
|
|
||||||
FACTION_INDIFFERENTLY = 5,
|
FACTION_INDIFFERENT = 5,
|
||||||
|
|
||||||
FACTION_APPREHENSIVELY = 6,
|
FACTION_APPREHENSIVE = 6,
|
||||||
FACTION_DUBIOUSLY = 7,
|
FACTION_DUBIOUS = 7,
|
||||||
FACTION_THREATENINGLY = 8,
|
FACTION_THREATENLY = 8,
|
||||||
FACTION_SCOWLS = 9
|
FACTION_SCOWLS = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ struct NPCFactionList {
|
|||||||
struct FactionMods
|
struct FactionMods
|
||||||
{
|
{
|
||||||
int32 base;
|
int32 base;
|
||||||
int16 min; // The lowest your personal earned faction can go - before race/class/deity adjustments.
|
int16 min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
|
||||||
int16 max; // The highest your personal earned faction can go - before race/class/deity adjustments.
|
int16 max; // The highest your personal earned faction can go - before race/class/diety adjustments.
|
||||||
int32 class_mod;
|
int32 class_mod;
|
||||||
int32 race_mod;
|
int32 race_mod;
|
||||||
int32 deity_mod;
|
int32 deity_mod;
|
||||||
@@ -61,8 +61,8 @@ struct Faction {
|
|||||||
int32 id;
|
int32 id;
|
||||||
std::map<std::string, int16> mods;
|
std::map<std::string, int16> mods;
|
||||||
int16 base;
|
int16 base;
|
||||||
int16 min; // The lowest your personal earned faction can go - before race/class/deity adjustments.
|
int16 min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
|
||||||
int16 max; // The highest your personal earned faction can go - before race/class/deity adjustments.
|
int16 max; // The highest your personal earned faction can go - before race/class/diety adjustments.
|
||||||
char name[50];
|
char name[50];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,23 +75,6 @@ struct NPCFaction
|
|||||||
uint8 temp;
|
uint8 temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Faction Associations give a much more live like faction system
|
const char *FactionValueToString(FACTION_VALUE fv);
|
||||||
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
|
|
||||||
|
|
||||||
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
|
|
||||||
#define MAX_FACTION_ASSOC 10
|
|
||||||
|
|
||||||
// this is the ID of a faction association and it's multiplier
|
|
||||||
struct FactionAssociationHit {
|
|
||||||
int id;
|
|
||||||
float multiplier;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FactionAssociations {
|
|
||||||
// maybe there should be more data here, fine for now
|
|
||||||
FactionAssociationHit hits[MAX_FACTION_ASSOC];
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *FactionValueToString(FACTION_VALUE faction_value);
|
|
||||||
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+40
-5
@@ -132,7 +132,7 @@ enum { //reuse times
|
|||||||
InstillDoubtReuseTime = 9,
|
InstillDoubtReuseTime = 9,
|
||||||
FishingReuseTime = 11,
|
FishingReuseTime = 11,
|
||||||
ForagingReuseTime = 50,
|
ForagingReuseTime = 50,
|
||||||
MendReuseTime = 360,
|
MendReuseTime = 290,
|
||||||
BashReuseTime = 5,
|
BashReuseTime = 5,
|
||||||
BackstabReuseTime = 9,
|
BackstabReuseTime = 9,
|
||||||
KickReuseTime = 5,
|
KickReuseTime = 5,
|
||||||
@@ -204,7 +204,7 @@ enum { //some random constants
|
|||||||
#define MIN_LEVEL_ALCHEMY 25
|
#define MIN_LEVEL_ALCHEMY 25
|
||||||
|
|
||||||
//chance ratio that a
|
//chance ratio that a
|
||||||
#define THREATENINGLY_AGGRO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
|
#define THREATENLY_ARRGO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
|
||||||
|
|
||||||
//max factions per npc faction list
|
//max factions per npc faction list
|
||||||
#define MAX_NPC_FACTIONS 20
|
#define MAX_NPC_FACTIONS 20
|
||||||
@@ -218,14 +218,14 @@ enum { //some random constants
|
|||||||
#define HARD_LEVEL_CAP 127
|
#define HARD_LEVEL_CAP 127
|
||||||
|
|
||||||
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
||||||
#define USE_NPC_RANGE2 40000 //arbitrary right now
|
#define USE_NPC_RANGE2 200*200 //arbitrary right now
|
||||||
|
|
||||||
// Squared range for rampage 75.0 * 75.0 for now
|
// Squared range for rampage 75.0 * 75.0 for now
|
||||||
#define NPC_RAMPAGE_RANGE2 5625.0f
|
#define NPC_RAMPAGE_RANGE2 5625.0f
|
||||||
|
|
||||||
//the formula for experience for killing a mob.
|
//the formula for experience for killing a mob.
|
||||||
//level is the only valid variable to use
|
//level is the only valid variable to use
|
||||||
#define EXP_FORMULA (level * level * 75 * 35 / 10)
|
#define EXP_FORMULA level*level*75*35/10
|
||||||
|
|
||||||
#define HIGHEST_AA_VALUE 35
|
#define HIGHEST_AA_VALUE 35
|
||||||
|
|
||||||
@@ -238,6 +238,41 @@ enum { //some random constants
|
|||||||
// Timer to update aggrometer
|
// Timer to update aggrometer
|
||||||
#define AGGRO_METER_UPDATE_MS 1000
|
#define AGGRO_METER_UPDATE_MS 1000
|
||||||
|
|
||||||
|
//Some hard coded statuses from commands and other places:
|
||||||
|
enum {
|
||||||
|
minStatusToBeGM = 40,
|
||||||
|
minStatusToUseGMCommands = 80,
|
||||||
|
minStatusToKick = 150,
|
||||||
|
minStatusToAvoidFalling = 100,
|
||||||
|
minStatusToHaveInvalidSpells = 80,
|
||||||
|
minStatusToHaveInvalidSkills = 80,
|
||||||
|
minStatusToIgnoreZoneFlags = 80,
|
||||||
|
minStatusToSeeOthersZoneFlags = 80,
|
||||||
|
minStatusToEditOtherGuilds = 80,
|
||||||
|
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
||||||
|
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
||||||
|
commandZoneToSpecials = 80, //zone to cshome, out of load zones
|
||||||
|
commandToggleAI = 250, //can turn NPC AI on and off
|
||||||
|
commandCastSpecials = 100, //can cast special spells
|
||||||
|
commandInstacast = 100, //insta-cast all #casted spells
|
||||||
|
commandLevelAboveCap = 100, //can #level players above level cap
|
||||||
|
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
|
||||||
|
commandSetSkillsOther = 100, //ability to setskills on others
|
||||||
|
commandRaceOthers = 100, //ability to #race on others
|
||||||
|
commandGenderOthers = 100, //ability to #gender on others
|
||||||
|
commandTextureOthers = 100, //ability to #texture on others
|
||||||
|
commandDoAnimOthers = 100, //can #doanim on others
|
||||||
|
commandLockZones = 101, //can lock or unlock zones
|
||||||
|
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
||||||
|
commandChangeFlags = 200, //ability to set/refresh flags
|
||||||
|
commandBanPlayers = 100, //can set bans on players
|
||||||
|
commandChangeDatarate = 201, //edit client's data rate
|
||||||
|
commandZoneToCoords = 0, //can #zone with coords
|
||||||
|
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
||||||
|
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
||||||
#define SAYLINK_ITEM_ID 0xFFFFF
|
#define SAYLINK_ITEM_ID 0xFFFFF
|
||||||
|
|
||||||
@@ -260,7 +295,7 @@ Developer configuration
|
|||||||
|
|
||||||
#define COMMON_PROFILE
|
#define COMMON_PROFILE
|
||||||
|
|
||||||
#define PROFILE_DUMP_TIME 180
|
#define PROFILE_DUMP_TIME 3*60
|
||||||
#endif //EQPROFILE
|
#endif //EQPROFILE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-112
@@ -1,112 +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 <fstream>
|
|
||||||
#include "file.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#include <direct.h>
|
|
||||||
#include <conio.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <dos.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <process.h>
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool File::Exists(const std::string &name)
|
|
||||||
{
|
|
||||||
return fs::exists(fs::path{name});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param directory_name
|
|
||||||
*/
|
|
||||||
void File::Makedir(const std::string &directory_name)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
fs::create_directory(directory_name);
|
|
||||||
fs::permissions(directory_name, fs::perms::owner_all);
|
|
||||||
}
|
|
||||||
catch (const fs::filesystem_error &ex) {
|
|
||||||
std::cout << "Failed to create directory: " << directory_name << std::endl;
|
|
||||||
std::cout << ex.what() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string File::FindEqemuConfigPath()
|
|
||||||
{
|
|
||||||
if (File::Exists(fs::path{File::GetCwd() + "/eqemu_config.json"}.string())) {
|
|
||||||
return File::GetCwd();
|
|
||||||
}
|
|
||||||
else if (File::Exists(fs::path{File::GetCwd() + "/../eqemu_config.json"}.string())) {
|
|
||||||
return canonical(fs::path{File::GetCwd() + "/../"}).string();
|
|
||||||
}
|
|
||||||
else if (File::Exists(fs::path{File::GetCwd() + "/login.json"}.string())) {
|
|
||||||
return File::GetCwd();
|
|
||||||
}
|
|
||||||
else if (File::Exists(fs::path{File::GetCwd() + "/../login.json"}.string())) {
|
|
||||||
return canonical(fs::path{File::GetCwd() + "/../"}).string();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string File::GetCwd()
|
|
||||||
{
|
|
||||||
return fs::current_path().string();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileContentsResult File::GetContents(const std::string &file_name)
|
|
||||||
{
|
|
||||||
std::string error;
|
|
||||||
std::ifstream f;
|
|
||||||
f.open(file_name);
|
|
||||||
std::string line;
|
|
||||||
std::string lines;
|
|
||||||
if (f.is_open()) {
|
|
||||||
while (f) {
|
|
||||||
std::getline(f, line);
|
|
||||||
lines += line + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error = fmt::format("Couldn't open file [{}]", file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileContentsResult{
|
|
||||||
.contents = lines,
|
|
||||||
.error = error,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* 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 <fstream>
|
||||||
|
#include "file_util.h"
|
||||||
|
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
#include <direct.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool FileUtil::exists(const std::string &name)
|
||||||
|
{
|
||||||
|
std::ifstream f(name.c_str());
|
||||||
|
|
||||||
|
return f.good();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param directory_name
|
||||||
|
*/
|
||||||
|
void FileUtil::mkdir(const std::string& directory_name)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
struct _stat st;
|
||||||
|
if (_stat(directory_name.c_str(), &st) == 0) // exists
|
||||||
|
return;
|
||||||
|
_mkdir(directory_name.c_str());
|
||||||
|
#else
|
||||||
|
struct stat st{};
|
||||||
|
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
::mkdir(directory_name.c_str(), 0755);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -18,27 +18,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_FILE_H
|
#ifndef EQEMU_FILE_UTIL_H
|
||||||
#define EQEMU_FILE_H
|
#define EQEMU_FILE_UTIL_H
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
class FileUtil {
|
||||||
|
|
||||||
struct FileContentsResult {
|
|
||||||
std::string contents;
|
|
||||||
std::string error;
|
|
||||||
};
|
|
||||||
|
|
||||||
class File {
|
|
||||||
public:
|
public:
|
||||||
static bool Exists(const std::string &name);
|
static bool exists(const std::string &name);
|
||||||
static void Makedir(const std::string& directory_name);
|
static void mkdir(const std::string& directory_name);
|
||||||
static FileContentsResult GetContents(const std::string &file_name);
|
|
||||||
static std::string FindEqemuConfigPath();
|
|
||||||
static std::string GetCwd();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Exists(const std::string& name);
|
|
||||||
|
|
||||||
#endif //EQEMU_FILE_H
|
#endif //EQEMU_FILE_UTIL_H
|
||||||
+42
-86
@@ -20,7 +20,7 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
//#include "misc_functions.h"
|
//#include "misc_functions.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@@ -61,11 +61,9 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
_CreateGuild(Strings::ToUnsignedInt(row[0]), row[1], Strings::ToUnsignedInt(row[2]), Strings::ToUnsignedInt(row[3]), row[4], row[5], row[6], row[7]);
|
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
|
||||||
|
|
||||||
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
|
query = "SELECT guild_id,rank,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
|
||||||
|
|
||||||
query = "SELECT guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
|
|
||||||
results = m_db->QueryDatabase(query);
|
results = m_db->QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
@@ -75,8 +73,8 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
{
|
{
|
||||||
uint32 guild_id = Strings::ToUnsignedInt(row[0]);
|
uint32 guild_id = atoi(row[0]);
|
||||||
uint8 rankn = Strings::ToUnsignedInt(row[1]);
|
uint8 rankn = atoi(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||||
@@ -131,9 +129,9 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
info = _CreateGuild(guild_id, row[0], Strings::ToUnsignedInt(row[1]), Strings::ToUnsignedInt(row[2]), row[3], row[4], row[5], row[6]);
|
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(row[2]), row[3], row[4], row[5], row[6]);
|
||||||
|
|
||||||
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
query = StringFormat("SELECT guild_id, rank, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
||||||
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
||||||
results = m_db->QueryDatabase(query);
|
results = m_db->QueryDatabase(query);
|
||||||
|
|
||||||
@@ -144,7 +142,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
{
|
{
|
||||||
uint8 rankn = Strings::ToUnsignedInt(row[1]);
|
uint8 rankn = atoi(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||||
@@ -270,7 +268,7 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
|||||||
m_db->DoEscapeString(title_esc, rankInfo.name.c_str(), rankInfo.name.length());
|
m_db->DoEscapeString(title_esc, rankInfo.name.c_str(), rankInfo.name.length());
|
||||||
|
|
||||||
query = StringFormat("INSERT INTO guild_ranks "
|
query = StringFormat("INSERT INTO guild_ranks "
|
||||||
"(guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace)"
|
"(guild_id,rank,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace)"
|
||||||
" VALUES(%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%d)",
|
" VALUES(%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%d)",
|
||||||
guild_id, rank, title_esc,
|
guild_id, rank, title_esc,
|
||||||
rankInfo.permissions[GUILD_HEAR],
|
rankInfo.permissions[GUILD_HEAR],
|
||||||
@@ -740,7 +738,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
|||||||
std::string query;
|
std::string query;
|
||||||
|
|
||||||
if(guild_id != GUILD_NONE) {
|
if(guild_id != GUILD_NONE) {
|
||||||
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,`rank`,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
|
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -760,7 +758,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
|
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
|
||||||
std::string query = StringFormat("UPDATE guild_members SET `rank`=%d WHERE char_id=%d", rank, charid);
|
std::string query = StringFormat("UPDATE guild_members SET rank=%d WHERE char_id=%d", rank, charid);
|
||||||
return(QueryWithLogging(query, "setting a guild member's rank"));
|
return(QueryWithLogging(query, "setting a guild member's rank"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,7 +785,9 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return Strings::ToBool(row[0]);
|
bool IsBanker = atoi(row[0]);
|
||||||
|
|
||||||
|
return IsBanker;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
|
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
|
||||||
@@ -815,7 +815,9 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return Strings::ToBool(row[0]);
|
bool IsAlt = atoi(row[0]);
|
||||||
|
|
||||||
|
return IsAlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
|
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
|
||||||
@@ -862,26 +864,35 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//factored out so I dont have to copy this crap.
|
||||||
|
#ifdef BOTS
|
||||||
|
#define GuildMemberBaseQuery \
|
||||||
|
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
|
||||||
|
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
|
||||||
|
" g.`banker`, g.`public_note`, g.`alt`" \
|
||||||
|
" FROM `vw_bot_character_mobs` AS c LEFT JOIN `vw_guild_members` AS g ON c.`id` = g.`char_id` AND c.`mob_type` = g.`mob_type` "
|
||||||
|
#else
|
||||||
#define GuildMemberBaseQuery \
|
#define GuildMemberBaseQuery \
|
||||||
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
|
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
|
||||||
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
|
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
|
||||||
" g.`banker`, g.`public_note`, g.`alt` " \
|
" g.`banker`, g.`public_note`, g.`alt` " \
|
||||||
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
||||||
|
#endif
|
||||||
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
||||||
//fields from `characer_`
|
//fields from `characer_`
|
||||||
into.char_id = Strings::ToUnsignedInt(row[0]);
|
into.char_id = atoi(row[0]);
|
||||||
into.char_name = row[1];
|
into.char_name = row[1];
|
||||||
into.class_ = Strings::ToUnsignedInt(row[2]);
|
into.class_ = atoi(row[2]);
|
||||||
into.level = Strings::ToUnsignedInt(row[3]);
|
into.level = atoi(row[3]);
|
||||||
into.time_last_on = Strings::ToUnsignedInt(row[4]);
|
into.time_last_on = atoul(row[4]);
|
||||||
into.zone_id = Strings::ToUnsignedInt(row[5]);
|
into.zone_id = atoi(row[5]);
|
||||||
|
|
||||||
//fields from `guild_members`, leave at defaults if missing
|
//fields from `guild_members`, leave at defaults if missing
|
||||||
into.guild_id = row[6] ? Strings::ToUnsignedInt(row[6]) : GUILD_NONE;
|
into.guild_id = row[6] ? atoi(row[6]) : GUILD_NONE;
|
||||||
into.rank = row[7] ? Strings::ToUnsignedInt(row[7]) : (GUILD_MAX_RANK+1);
|
into.rank = row[7] ? atoi(row[7]) : (GUILD_MAX_RANK+1);
|
||||||
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
||||||
into.total_tribute = row[9] ? Strings::ToUnsignedInt(row[9]) : 0;
|
into.total_tribute = row[9] ? atoi(row[9]) : 0;
|
||||||
into.last_tribute = row[10]? Strings::ToUnsignedInt(row[10]) : 0; //timestamp
|
into.last_tribute = row[10]? atoul(row[10]) : 0; //timestamp
|
||||||
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
||||||
into.public_note = row[12]? row[12] : "";
|
into.public_note = row[12]? row[12] : "";
|
||||||
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
||||||
@@ -956,7 +967,12 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//load up the rank info for each guild.
|
//load up the rank info for each guild.
|
||||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
|
std::string query;
|
||||||
|
#ifdef BOTS
|
||||||
|
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C' AND c.deleted_at IS NULL", char_id);
|
||||||
|
#else
|
||||||
|
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
|
||||||
|
#endif
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1192,7 +1208,7 @@ BaseGuildManager::RankInfo::RankInfo() {
|
|||||||
|
|
||||||
BaseGuildManager::GuildInfo::GuildInfo() {
|
BaseGuildManager::GuildInfo::GuildInfo() {
|
||||||
leader_char_id = 0;
|
leader_char_id = 0;
|
||||||
minstatus = AccountStatus::Player;
|
minstatus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
||||||
@@ -1209,66 +1225,6 @@ uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
|||||||
return results.RowCount();
|
return results.RowCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGuildManager::GetGuildNameByID(uint32 guild_id) const {
|
|
||||||
if(guild_id == GUILD_NONE) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
|
||||||
res = m_guilds.find(guild_id);
|
|
||||||
if(res == m_guilds.end()) {
|
|
||||||
return "Invalid Guild";
|
|
||||||
}
|
|
||||||
|
|
||||||
return res->second->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string BaseGuildManager::GetGuildRankName(uint32 guild_id, uint8 rank) const
|
|
||||||
{
|
|
||||||
if(rank > GUILD_MAX_RANK) {
|
|
||||||
return "Invalid Rank";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
|
||||||
res = m_guilds.find(guild_id);
|
|
||||||
if(res == m_guilds.end()) {
|
|
||||||
return "Invalid Guild Rank";
|
|
||||||
}
|
|
||||||
|
|
||||||
return res->second->ranks[rank].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id)
|
|
||||||
{
|
|
||||||
if(!m_db) {
|
|
||||||
return GUILD_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string query = fmt::format(
|
|
||||||
"SELECT `guild_id` FROM `guild_members` WHERE char_id = {} LIMIT 1",
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = m_db->QueryDatabase(query);
|
|
||||||
if(!results.Success() || !results.RowCount()) {
|
|
||||||
return GUILD_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
auto guild_id = Strings::ToUnsignedInt(row[0]);
|
|
||||||
return guild_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseGuildManager::IsCharacterInGuild(uint32 character_id, uint32 guild_id)
|
|
||||||
{
|
|
||||||
auto current_guild_id = GetGuildIDByCharacterID(character_id);
|
|
||||||
|
|
||||||
if (current_guild_id == GUILD_NONE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guild_id && current_guild_id != guild_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -76,12 +76,8 @@ class BaseGuildManager
|
|||||||
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
||||||
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
||||||
const char *GetGuildName(uint32 guild_id) const;
|
const char *GetGuildName(uint32 guild_id) const;
|
||||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
|
||||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
|
||||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
|
||||||
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
||||||
uint32 GetGuildIDByName(const char *GuildName);
|
uint32 GetGuildIDByName(const char *GuildName);
|
||||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
|
||||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||||
|
|||||||
+1549
-7243
File diff suppressed because it is too large
Load Diff
@@ -1,633 +0,0 @@
|
|||||||
// Copyright (C) 2015 Ben Lewis <benjf5+github@gmail.com>
|
|
||||||
// Licensed under the MIT license.
|
|
||||||
// https://github.com/ben-zen/uri-library
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
class uri {
|
|
||||||
/* URIs are broadly divided into two categories: hierarchical and
|
|
||||||
* non-hierarchical. Both hierarchical URIs and non-hierarchical URIs have a
|
|
||||||
* few elements in common; all URIs have a scheme of one or more alphanumeric
|
|
||||||
* characters followed by a colon, and they all may optionally have a query
|
|
||||||
* component preceded by a question mark, and a fragment component preceded by
|
|
||||||
* an octothorpe (hash mark: '#'). The query consists of stanzas separated by
|
|
||||||
* either ampersands ('&') or semicolons (';') (but only one or the other),
|
|
||||||
* and each stanza consists of a key and an optional value; if the value
|
|
||||||
* exists, the key and value must be divided by an equals sign.
|
|
||||||
*
|
|
||||||
* The following is an example from Wikipedia of a hierarchical URI:
|
|
||||||
* scheme:[//[user:password@]domain[:port]][/]path[?query][#fragment]
|
|
||||||
*/
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum class scheme_category {
|
|
||||||
Hierarchical,
|
|
||||||
NonHierarchical
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class component {
|
|
||||||
Scheme,
|
|
||||||
Content,
|
|
||||||
Username,
|
|
||||||
Password,
|
|
||||||
Host,
|
|
||||||
Port,
|
|
||||||
Path,
|
|
||||||
Query,
|
|
||||||
Fragment
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class query_argument_separator {
|
|
||||||
ampersand,
|
|
||||||
semicolon
|
|
||||||
};
|
|
||||||
|
|
||||||
uri(
|
|
||||||
char const *uri_text, scheme_category category = scheme_category::Hierarchical,
|
|
||||||
query_argument_separator separator = query_argument_separator::ampersand
|
|
||||||
) :
|
|
||||||
m_category(category),
|
|
||||||
m_path_is_rooted(false),
|
|
||||||
m_port(0),
|
|
||||||
m_separator(separator)
|
|
||||||
{
|
|
||||||
setup(std::string(uri_text), category);
|
|
||||||
};
|
|
||||||
|
|
||||||
uri(
|
|
||||||
std::string const &uri_text, scheme_category category = scheme_category::Hierarchical,
|
|
||||||
query_argument_separator separator = query_argument_separator::ampersand
|
|
||||||
) :
|
|
||||||
m_category(category),
|
|
||||||
m_path_is_rooted(false),
|
|
||||||
m_port(0),
|
|
||||||
m_separator(separator)
|
|
||||||
{
|
|
||||||
setup(uri_text, category);
|
|
||||||
};
|
|
||||||
|
|
||||||
uri(
|
|
||||||
std::map<component, std::string> const &components,
|
|
||||||
scheme_category category,
|
|
||||||
bool rooted_path,
|
|
||||||
query_argument_separator separator = query_argument_separator::ampersand
|
|
||||||
) :
|
|
||||||
m_category(category),
|
|
||||||
m_path_is_rooted(rooted_path),
|
|
||||||
m_separator(separator)
|
|
||||||
{
|
|
||||||
if (components.count(component::Scheme)) {
|
|
||||||
if (components.at(component::Scheme).length() == 0) {
|
|
||||||
throw std::invalid_argument("Scheme cannot be empty.");
|
|
||||||
}
|
|
||||||
m_scheme = components.at(component::Scheme);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::invalid_argument("A URI must have a scheme.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (category == scheme_category::Hierarchical) {
|
|
||||||
if (components.count(component::Content)) {
|
|
||||||
throw std::invalid_argument("The content component is only for use in non-hierarchical URIs.");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_username = components.count(component::Username);
|
|
||||||
bool has_password = components.count(component::Password);
|
|
||||||
if (has_username && has_password) {
|
|
||||||
m_username = components.at(component::Username);
|
|
||||||
m_password = components.at(component::Password);
|
|
||||||
}
|
|
||||||
else if ((has_username && !has_password) || (!has_username && has_password)) {
|
|
||||||
throw std::invalid_argument("If a username or password is supplied, both must be provided.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.count(component::Host)) {
|
|
||||||
m_host = components.at(component::Host);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.count(component::Port)) {
|
|
||||||
m_port = std::stoul(components.at(component::Port));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.count(component::Path)) {
|
|
||||||
m_path = components.at(component::Path);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::invalid_argument("A path is required on a hierarchical URI, even an empty path.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (components.count(component::Username)
|
|
||||||
|| components.count(component::Password)
|
|
||||||
|| components.count(component::Host)
|
|
||||||
|| components.count(component::Port)
|
|
||||||
|| components.count(component::Path)) {
|
|
||||||
throw std::invalid_argument("None of the hierarchical components are allowed in a non-hierarchical URI.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.count(component::Content)) {
|
|
||||||
m_content = components.at(component::Content);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"Content is a required component for a non-hierarchical URI, even an empty string."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.count(component::Query)) {
|
|
||||||
m_query = components.at(component::Query);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.count(component::Fragment)) {
|
|
||||||
m_fragment = components.at(component::Fragment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uri(uri const &other, std::map<component, std::string> const &replacements) :
|
|
||||||
m_category(other.m_category),
|
|
||||||
m_path_is_rooted(other.m_path_is_rooted),
|
|
||||||
m_separator(other.m_separator)
|
|
||||||
{
|
|
||||||
m_scheme = (replacements.count(component::Scheme))
|
|
||||||
? replacements.at(component::Scheme) : other.m_scheme;
|
|
||||||
|
|
||||||
if (m_category == scheme_category::Hierarchical) {
|
|
||||||
m_username = (replacements.count(component::Username))
|
|
||||||
? replacements.at(component::Username) : other.m_username;
|
|
||||||
|
|
||||||
m_password = (replacements.count(component::Password))
|
|
||||||
? replacements.at(component::Password) : other.m_password;
|
|
||||||
|
|
||||||
m_host = (replacements.count(component::Host))
|
|
||||||
? replacements.at(component::Host) : other.m_host;
|
|
||||||
|
|
||||||
m_port = (replacements.count(component::Port))
|
|
||||||
? std::stoul(replacements.at(component::Port)) : other.m_port;
|
|
||||||
|
|
||||||
m_path = (replacements.count(component::Path))
|
|
||||||
? replacements.at(component::Path) : other.m_path;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_content = (replacements.count(component::Content))
|
|
||||||
? replacements.at(component::Content) : other.m_content;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_query = (replacements.count(component::Query))
|
|
||||||
? replacements.at(component::Query) : other.m_query;
|
|
||||||
|
|
||||||
m_fragment = (replacements.count(component::Fragment))
|
|
||||||
? replacements.at(component::Fragment) : other.m_fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy constructor; just use the copy assignment operator internally.
|
|
||||||
uri(uri const &other)
|
|
||||||
{
|
|
||||||
*this = other;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Copy assignment operator
|
|
||||||
uri &operator=(uri const &other)
|
|
||||||
{
|
|
||||||
if (this != &other) {
|
|
||||||
m_scheme = other.m_scheme;
|
|
||||||
m_content = other.m_content;
|
|
||||||
m_username = other.m_username;
|
|
||||||
m_password = other.m_password;
|
|
||||||
m_host = other.m_host;
|
|
||||||
m_path = other.m_path;
|
|
||||||
m_query = other.m_query;
|
|
||||||
m_fragment = other.m_fragment;
|
|
||||||
m_query_dict = other.m_query_dict;
|
|
||||||
m_category = other.m_category;
|
|
||||||
m_port = other.m_port;
|
|
||||||
m_path_is_rooted = other.m_path_is_rooted;
|
|
||||||
m_separator = other.m_separator;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~uri() {};
|
|
||||||
|
|
||||||
std::string const &get_scheme() const
|
|
||||||
{
|
|
||||||
return m_scheme;
|
|
||||||
};
|
|
||||||
|
|
||||||
scheme_category get_scheme_category() const
|
|
||||||
{
|
|
||||||
return m_category;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_content() const
|
|
||||||
{
|
|
||||||
if (m_category != scheme_category::NonHierarchical) {
|
|
||||||
throw std::domain_error("The content component is only valid for non-hierarchical URIs.");
|
|
||||||
}
|
|
||||||
return m_content;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_username() const
|
|
||||||
{
|
|
||||||
if (m_category != scheme_category::Hierarchical) {
|
|
||||||
throw std::domain_error("The username component is only valid for hierarchical URIs.");
|
|
||||||
}
|
|
||||||
return m_username;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_password() const
|
|
||||||
{
|
|
||||||
if (m_category != scheme_category::Hierarchical) {
|
|
||||||
throw std::domain_error("The password component is only valid for hierarchical URIs.");
|
|
||||||
}
|
|
||||||
return m_password;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_host() const
|
|
||||||
{
|
|
||||||
if (m_category != scheme_category::Hierarchical) {
|
|
||||||
throw std::domain_error("The host component is only valid for hierarchical URIs.");
|
|
||||||
}
|
|
||||||
return m_host;
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned long get_port() const
|
|
||||||
{
|
|
||||||
if (m_category != scheme_category::Hierarchical) {
|
|
||||||
throw std::domain_error("The port component is only valid for hierarchical URIs.");
|
|
||||||
}
|
|
||||||
return m_port;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_path() const
|
|
||||||
{
|
|
||||||
if (m_category != scheme_category::Hierarchical) {
|
|
||||||
throw std::domain_error("The path component is only valid for hierarchical URIs.");
|
|
||||||
}
|
|
||||||
return m_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_query() const
|
|
||||||
{
|
|
||||||
return m_query;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<std::string, std::string> const &get_query_dictionary() const
|
|
||||||
{
|
|
||||||
return m_query_dict;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string const &get_fragment() const
|
|
||||||
{
|
|
||||||
return m_fragment;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
std::string full_uri;
|
|
||||||
full_uri.append(m_scheme);
|
|
||||||
full_uri.append(":");
|
|
||||||
|
|
||||||
if (m_content.length() > m_path.length()) {
|
|
||||||
full_uri.append("//");
|
|
||||||
if (!(m_username.empty() || m_password.empty())) {
|
|
||||||
full_uri.append(m_username);
|
|
||||||
full_uri.append(":");
|
|
||||||
full_uri.append(m_password);
|
|
||||||
full_uri.append("@");
|
|
||||||
}
|
|
||||||
|
|
||||||
full_uri.append(m_host);
|
|
||||||
|
|
||||||
if (m_port != 0) {
|
|
||||||
full_uri.append(":");
|
|
||||||
full_uri.append(std::to_string(m_port));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_path_is_rooted) {
|
|
||||||
full_uri.append("/");
|
|
||||||
}
|
|
||||||
full_uri.append(m_path);
|
|
||||||
|
|
||||||
if (!m_query.empty()) {
|
|
||||||
full_uri.append("?");
|
|
||||||
full_uri.append(m_query);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_fragment.empty()) {
|
|
||||||
full_uri.append("#");
|
|
||||||
full_uri.append(m_fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
return full_uri;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void setup(std::string const &uri_text, scheme_category category)
|
|
||||||
{
|
|
||||||
size_t const uri_length = uri_text.length();
|
|
||||||
|
|
||||||
if (uri_length == 0) {
|
|
||||||
throw std::invalid_argument("URIs cannot be of zero length.");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string::const_iterator cursor = parse_scheme(
|
|
||||||
uri_text,
|
|
||||||
uri_text.begin());
|
|
||||||
// After calling parse_scheme, *cursor == ':'; none of the following parsers
|
|
||||||
// expect a separator character, so we advance the cursor upon calling them.
|
|
||||||
cursor = parse_content(uri_text, (cursor + 1));
|
|
||||||
|
|
||||||
if ((cursor != uri_text.end()) && (*cursor == '?')) {
|
|
||||||
cursor = parse_query(uri_text, (cursor + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cursor != uri_text.end()) && (*cursor == '#')) {
|
|
||||||
cursor = parse_fragment(uri_text, (cursor + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
init_query_dictionary(); // If the query string is empty, this will be empty too.
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_scheme(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string::const_iterator scheme_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator scheme_end = scheme_start;
|
|
||||||
while ((scheme_end != uri_text.end()) && (*scheme_end != ':')) {
|
|
||||||
if (!(std::isalnum(*scheme_end) || (*scheme_end == '-')
|
|
||||||
|| (*scheme_end == '+') || (*scheme_end == '.'))) {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"Invalid character found in the scheme component. Supplied URI was: \""
|
|
||||||
+ uri_text + "\"."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
++scheme_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scheme_end == uri_text.end()) {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"End of URI found while parsing the scheme. Supplied URI was: \""
|
|
||||||
+ uri_text + "\"."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scheme_start == scheme_end) {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"Scheme component cannot be zero-length. Supplied URI was: \""
|
|
||||||
+ uri_text + "\"."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_scheme = std::move(std::string(scheme_start, scheme_end));
|
|
||||||
return scheme_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_content(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string::const_iterator content_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator content_end = content_start;
|
|
||||||
while ((content_end != uri_text.end()) && (*content_end != '?') && (*content_end != '#')) {
|
|
||||||
++content_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_content = std::move(std::string(content_start, content_end));
|
|
||||||
|
|
||||||
if ((m_category == scheme_category::Hierarchical) && (m_content.length() > 0)) {
|
|
||||||
// If it's a hierarchical URI, the content should be parsed for the hierarchical components.
|
|
||||||
std::string::const_iterator path_start = m_content.begin();
|
|
||||||
std::string::const_iterator path_end = m_content.end();
|
|
||||||
if (!m_content.compare(0, 2, "//")) {
|
|
||||||
// In this case an authority component is present.
|
|
||||||
std::string::const_iterator authority_cursor = (m_content.begin() + 2);
|
|
||||||
if (m_content.find_first_of('@') != std::string::npos) {
|
|
||||||
std::string::const_iterator userpass_divider = parse_username(
|
|
||||||
uri_text,
|
|
||||||
m_content,
|
|
||||||
authority_cursor
|
|
||||||
);
|
|
||||||
authority_cursor = parse_password(uri_text, m_content, (userpass_divider + 1));
|
|
||||||
// After this call, *authority_cursor == '@', so we skip over it.
|
|
||||||
++authority_cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
authority_cursor = parse_host(uri_text, m_content, authority_cursor);
|
|
||||||
|
|
||||||
if ((authority_cursor != m_content.end()) && (*authority_cursor == ':')) {
|
|
||||||
authority_cursor = parse_port(uri_text, m_content, (authority_cursor + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((authority_cursor != m_content.end()) && (*authority_cursor == '/')) {
|
|
||||||
// Then the path is rooted, and we should note this.
|
|
||||||
m_path_is_rooted = true;
|
|
||||||
path_start = authority_cursor + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we've reached the end and no path is present then set path_start
|
|
||||||
// to the end.
|
|
||||||
if (authority_cursor == m_content.end()) {
|
|
||||||
path_start = m_content.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!m_content.compare(0, 1, "/")) {
|
|
||||||
m_path_is_rooted = true;
|
|
||||||
++path_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can now build the path based on what remains in the content string,
|
|
||||||
// since that's all that exists after the host and optional port component.
|
|
||||||
m_path = std::move(std::string(path_start, path_end));
|
|
||||||
}
|
|
||||||
return content_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_username(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string const &content,
|
|
||||||
std::string::const_iterator username_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator username_end = username_start;
|
|
||||||
// Since this is only reachable when '@' was in the content string, we can
|
|
||||||
// ignore the end-of-string case.
|
|
||||||
while (*username_end != ':') {
|
|
||||||
if (*username_end == '@') {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"Username must be followed by a password. Supplied URI was: \""
|
|
||||||
+ uri_text + "\"."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
++username_end;
|
|
||||||
}
|
|
||||||
m_username = std::move(std::string(username_start, username_end));
|
|
||||||
return username_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_password(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string const &content,
|
|
||||||
std::string::const_iterator password_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator password_end = password_start;
|
|
||||||
while (*password_end != '@') {
|
|
||||||
++password_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_password = std::move(std::string(password_start, password_end));
|
|
||||||
return password_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_host(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string const &content,
|
|
||||||
std::string::const_iterator host_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator host_end = host_start;
|
|
||||||
// So, the host can contain a few things. It can be a domain, it can be an
|
|
||||||
// IPv4 address, it can be an IPv6 address, or an IPvFuture literal. In the
|
|
||||||
// case of those last two, it's of the form [...] where what's between the
|
|
||||||
// brackets is a matter of which IPv?? version it is.
|
|
||||||
while (host_end != content.end()) {
|
|
||||||
if (*host_end == '[') {
|
|
||||||
// We're parsing an IPv6 or IPvFuture address, so we should handle that
|
|
||||||
// instead of the normal procedure.
|
|
||||||
while ((host_end != content.end()) && (*host_end != ']')) {
|
|
||||||
++host_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host_end == content.end()) {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"End of content component encountered "
|
|
||||||
"while parsing the host component. "
|
|
||||||
"Supplied URI was: \""
|
|
||||||
+ uri_text + "\"."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
++host_end;
|
|
||||||
break;
|
|
||||||
// We can stop looping, we found the end of the IP literal, which is the
|
|
||||||
// whole of the host component when one's in use.
|
|
||||||
}
|
|
||||||
else if ((*host_end == ':') || (*host_end == '/')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++host_end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_host = std::move(std::string(host_start, host_end));
|
|
||||||
return host_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_port(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string const &content,
|
|
||||||
std::string::const_iterator port_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator port_end = port_start;
|
|
||||||
while ((port_end != content.end()) && (*port_end != '/')) {
|
|
||||||
if (!std::isdigit(*port_end)) {
|
|
||||||
throw std::invalid_argument(
|
|
||||||
"Invalid character while parsing the port. "
|
|
||||||
"Supplied URI was: \"" + uri_text + "\"."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
++port_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_port = std::stoul(std::string(port_start, port_end));
|
|
||||||
return port_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_query(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string::const_iterator query_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string::const_iterator query_end = query_start;
|
|
||||||
while ((query_end != uri_text.end()) && (*query_end != '#')) {
|
|
||||||
// Queries can contain almost any character except hash, which is reserved
|
|
||||||
// for the start of the fragment.
|
|
||||||
++query_end;
|
|
||||||
}
|
|
||||||
m_query = std::move(std::string(query_start, query_end));
|
|
||||||
return query_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::const_iterator parse_fragment(
|
|
||||||
std::string const &uri_text,
|
|
||||||
std::string::const_iterator fragment_start
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_fragment = std::move(std::string(fragment_start, uri_text.end()));
|
|
||||||
return uri_text.end();
|
|
||||||
};
|
|
||||||
|
|
||||||
void init_query_dictionary()
|
|
||||||
{
|
|
||||||
if (!m_query.empty()) {
|
|
||||||
// Loop over the query string looking for '&'s, then check each one for
|
|
||||||
// an '=' to find keys and values; if there's not an '=' then the key
|
|
||||||
// will have an empty value in the map.
|
|
||||||
char separator = (m_separator == query_argument_separator::ampersand) ? '&' : ';';
|
|
||||||
size_t carat = 0;
|
|
||||||
size_t stanza_end = m_query.find_first_of(separator);
|
|
||||||
do {
|
|
||||||
std::string stanza = m_query.substr(
|
|
||||||
carat,
|
|
||||||
((stanza_end != std::string::npos) ? (stanza_end - carat) : std::string::npos));
|
|
||||||
size_t key_value_divider = stanza.find_first_of('=');
|
|
||||||
std::string key = stanza.substr(0, key_value_divider);
|
|
||||||
std::string value;
|
|
||||||
if (key_value_divider != std::string::npos) {
|
|
||||||
value = stanza.substr((key_value_divider + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_query_dict.count(key) != 0) {
|
|
||||||
throw std::invalid_argument("Bad key in the query string!");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_query_dict.emplace(key, value);
|
|
||||||
carat = ((stanza_end != std::string::npos) ? (stanza_end + 1)
|
|
||||||
: std::string::npos);
|
|
||||||
stanza_end = m_query.find_first_of(separator, carat);
|
|
||||||
} while ((stanza_end != std::string::npos)
|
|
||||||
|| (carat != std::string::npos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string m_scheme;
|
|
||||||
std::string m_content;
|
|
||||||
std::string m_username;
|
|
||||||
std::string m_password;
|
|
||||||
std::string m_host;
|
|
||||||
std::string m_path;
|
|
||||||
std::string m_query;
|
|
||||||
std::string m_fragment;
|
|
||||||
|
|
||||||
std::map<std::string, std::string> m_query_dict;
|
|
||||||
|
|
||||||
scheme_category m_category;
|
|
||||||
unsigned long m_port;
|
|
||||||
bool m_path_is_rooted;
|
|
||||||
query_argument_separator m_separator;
|
|
||||||
};
|
|
||||||
+29
-107
@@ -25,7 +25,7 @@
|
|||||||
//#include "races.h"
|
//#include "races.h"
|
||||||
//#include "rulesys.h"
|
//#include "rulesys.h"
|
||||||
//#include "shareddb.h"
|
//#include "shareddb.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
#include "../common/light_source.h"
|
#include "../common/light_source.h"
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ EQ::ItemInstance* EQ::InventoryProfile::GetItem(int16 slot_id, uint8 bagidx) con
|
|||||||
return GetItem(InventoryProfile::CalcSlotId(slot_id, bagidx));
|
return GetItem(InventoryProfile::CalcSlotId(slot_id, bagidx));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put an item into specified slot
|
// Put an item snto specified slot
|
||||||
int16 EQ::InventoryProfile::PutItem(int16 slot_id, const ItemInstance& inst)
|
int16 EQ::InventoryProfile::PutItem(int16 slot_id, const ItemInstance& inst)
|
||||||
{
|
{
|
||||||
if (slot_id <= EQ::invslot::POSSESSIONS_END && slot_id >= EQ::invslot::POSSESSIONS_BEGIN) {
|
if (slot_id <= EQ::invslot::POSSESSIONS_END && slot_id >= EQ::invslot::POSSESSIONS_BEGIN) {
|
||||||
@@ -353,7 +353,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapRaceClass;
|
fail_state = swapRaceClass;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
|
if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) {
|
||||||
fail_state = swapDeity;
|
fail_state = swapDeity;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapRaceClass;
|
fail_state = swapRaceClass;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
|
if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) {
|
||||||
fail_state = swapDeity;
|
fail_state = swapDeity;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -399,7 +399,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove item from inventory (with memory delete)
|
// Remove item from inventory (with memory delete)
|
||||||
bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
|
bool EQ::InventoryProfile::DeleteItem(int16 slot_id, uint8 quantity) {
|
||||||
// Pop item out of inventory map (or queue)
|
// Pop item out of inventory map (or queue)
|
||||||
ItemInstance *item_to_delete = PopItem(slot_id);
|
ItemInstance *item_to_delete = PopItem(slot_id);
|
||||||
|
|
||||||
@@ -412,11 +412,10 @@ bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
|
|||||||
// If there are no charges left on the item,
|
// If there are no charges left on the item,
|
||||||
if (item_to_delete->GetCharges() <= 0) {
|
if (item_to_delete->GetCharges() <= 0) {
|
||||||
// If the item is stackable (e.g arrows), or
|
// If the item is stackable (e.g arrows), or
|
||||||
// the item is not a charged item, or is expendable, delete it
|
// the item is not stackable, and is not a charged item, or is expendable, delete it
|
||||||
if (
|
if (item_to_delete->IsStackable() ||
|
||||||
item_to_delete->IsStackable() ||
|
(!item_to_delete->IsStackable() &&
|
||||||
item_to_delete->GetItem()->MaxCharges == 0 ||
|
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
|
||||||
item_to_delete->IsExpendable()
|
|
||||||
) {
|
) {
|
||||||
// Item can now be destroyed
|
// Item can now be destroyed
|
||||||
InventoryProfile::MarkDirty(item_to_delete);
|
InventoryProfile::MarkDirty(item_to_delete);
|
||||||
@@ -591,68 +590,6 @@ bool EQ::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Quan
|
|||||||
// Checks that user has at least 'quantity' number of items in a given inventory slot
|
// Checks that user has at least 'quantity' number of items in a given inventory slot
|
||||||
// Returns first slot it was found in, or SLOT_INVALID if not found
|
// Returns first slot it was found in, or SLOT_INVALID if not found
|
||||||
|
|
||||||
bool EQ::InventoryProfile::HasAugmentEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
bool has_equipped = false;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->ContainsAugmentByID(item_id)) {
|
|
||||||
has_equipped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return has_equipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::InventoryProfile::CountAugmentEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
int quantity = 0;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->ContainsAugmentByID(item_id)) {
|
|
||||||
quantity += item->CountAugmentByID(item_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQ::InventoryProfile::HasItemEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
bool has_equipped = false;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->GetID() == item_id) {
|
|
||||||
has_equipped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return has_equipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::InventoryProfile::CountItemEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
int quantity = 0;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->GetID() == item_id) {
|
|
||||||
quantity += item->IsStackable() ? item->GetCharges() : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This function has a flaw in that it only returns the last stack that it looked at
|
//This function has a flaw in that it only returns the last stack that it looked at
|
||||||
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
|
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
|
||||||
int16 EQ::InventoryProfile::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
int16 EQ::InventoryProfile::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
||||||
@@ -801,35 +738,34 @@ int16 EQ::InventoryProfile::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
|||||||
// Returns slot_id when there's one available, else SLOT_INVALID
|
// Returns slot_id when there's one available, else SLOT_INVALID
|
||||||
int16 EQ::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
int16 EQ::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
||||||
{
|
{
|
||||||
const int16 last_bag_slot = RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT ? EQ::invslot::slotGeneral10 : EQ::invslot::slotGeneral8;
|
// Check basic inventory
|
||||||
|
for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) {
|
||||||
for (int16 i = invslot::GENERAL_BEGIN; i <= last_bag_slot; i++) { // Check basic inventory
|
if ((((uint64)1 << i) & m_lookup->PossessionsBitmask) == 0)
|
||||||
if ((((uint64) 1 << i) & m_lookup->PossessionsBitmask) == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetItem(i)) {
|
if (!GetItem(i))
|
||||||
return i; // Found available slot in personal inventory
|
// Found available slot in personal inventory
|
||||||
}
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!for_bag) {
|
if (!for_bag) {
|
||||||
for (int16 i = invslot::GENERAL_BEGIN; i <= last_bag_slot; i++) {
|
for (int16 i = invslot::GENERAL_BEGIN; i <= invslot::GENERAL_END; i++) {
|
||||||
if ((((uint64) 1 << i) & m_lookup->PossessionsBitmask) == 0) {
|
if ((((uint64)1 << i) & m_lookup->PossessionsBitmask) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const ItemInstance* inst = GetItem(i);
|
||||||
|
if (inst && inst->IsClassBag() && inst->GetItem()->BagSize >= min_size)
|
||||||
|
{
|
||||||
|
if (inst->GetItem()->BagType == item::BagTypeQuiver && inst->GetItem()->ItemType != item::ItemTypeArrow)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto *inst = GetItem(i);
|
int16 base_slot_id = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN);
|
||||||
if (inst && inst->IsClassBag() && inst->GetItem()->BagSize >= min_size) {
|
|
||||||
if (inst->GetItem()->BagType == item::BagTypeQuiver &&
|
|
||||||
inst->GetItem()->ItemType != item::ItemTypeArrow) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int16 base_slot_id = InventoryProfile::CalcSlotId(i, invbag::SLOT_BEGIN);
|
uint8 slots = inst->GetItem()->BagSlots;
|
||||||
|
uint8 j;
|
||||||
const uint8 slots = inst->GetItem()->BagSlots;
|
for (j = invbag::SLOT_BEGIN; j<slots; j++) {
|
||||||
for (uint8 j = invbag::SLOT_BEGIN; j < slots; j++) {
|
|
||||||
if (!GetItem(base_slot_id + j)) {
|
if (!GetItem(base_slot_id + j)) {
|
||||||
// Found available slot within bag
|
// Found available slot within bag
|
||||||
return (base_slot_id + j);
|
return (base_slot_id + j);
|
||||||
@@ -1445,7 +1381,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == INVALID_INDEX) {
|
if (result == INVALID_INDEX) {
|
||||||
LogError("Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
||||||
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1720,17 +1656,3 @@ int16 EQ::InventoryProfile::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 lo
|
|||||||
|
|
||||||
return EQ::invslot::SLOT_INVALID;
|
return EQ::invslot::SLOT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32> EQ::InventoryProfile::GetAugmentIDsBySlotID(int16 slot_id)
|
|
||||||
{
|
|
||||||
std::vector<uint32> augments;
|
|
||||||
const auto* item = GetItem(slot_id);
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
for (uint8 i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
|
|
||||||
augments.push_back(item->GetAugment(i) ? item->GetAugmentItemID(i) : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return augments;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,11 +26,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "item_instance.h"
|
#include "item_instance.h"
|
||||||
#include "classes.h"
|
|
||||||
#include "races.h"
|
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
//FatherNitwit: location bits for searching specific
|
//FatherNitwit: location bits for searching specific
|
||||||
@@ -132,10 +129,10 @@ namespace EQ
|
|||||||
|
|
||||||
// Swap items in inventory
|
// Swap items in inventory
|
||||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = Race::Doug, uint8 class_id = Class::None, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = 0, uint8 class_id = 0, uint16 deity_id = 0, uint8 level = 0);
|
||||||
|
|
||||||
// Remove item from inventory
|
// Remove item from inventory
|
||||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
bool DeleteItem(int16 slot_id, uint8 quantity = 0);
|
||||||
|
|
||||||
// Checks All items in a bag for No Drop
|
// Checks All items in a bag for No Drop
|
||||||
bool CheckNoDrop(int16 slot_id, bool recurse = true);
|
bool CheckNoDrop(int16 slot_id, bool recurse = true);
|
||||||
@@ -143,21 +140,6 @@ namespace EQ
|
|||||||
// Remove item from inventory (and take control of memory)
|
// Remove item from inventory (and take control of memory)
|
||||||
ItemInstance* PopItem(int16 slot_id);
|
ItemInstance* PopItem(int16 slot_id);
|
||||||
|
|
||||||
// Check if player has a specific item equipped by Item ID
|
|
||||||
bool HasItemEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Check how many of a specific item the player has equipped by Item ID
|
|
||||||
int CountItemEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Check if player has a specific augment equipped by Item ID
|
|
||||||
bool HasAugmentEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Check how many of a specific augment the player has equipped by Item ID
|
|
||||||
int CountAugmentEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Get a list of augments from a specific slot ID
|
|
||||||
std::vector<uint32> GetAugmentIDsBySlotID(int16 slot_id);
|
|
||||||
|
|
||||||
// Check whether there is space for the specified number of the specified item.
|
// Check whether there is space for the specified number of the specified item.
|
||||||
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
|
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
|
||||||
|
|
||||||
@@ -203,12 +185,11 @@ namespace EQ
|
|||||||
void dumpBankItems();
|
void dumpBankItems();
|
||||||
void dumpSharedBankItems();
|
void dumpSharedBankItems();
|
||||||
|
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||||
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
|
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||||
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
|
|
||||||
protected:
|
protected:
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Protected Methods
|
// Protected Methods
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "inventory_slot.h"
|
#include "inventory_slot.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
|
|
||||||
int8 EQ::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
|
int8 EQ::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
|
||||||
|
|||||||
@@ -18,17 +18,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <csignal>
|
|
||||||
#include <vector>
|
|
||||||
#include "ip_util.h"
|
#include "ip_util.h"
|
||||||
#include "http/httplib.h"
|
|
||||||
#include "http/uri.h"
|
|
||||||
#include "eqemu_logsys.h"
|
|
||||||
#include "event/event_loop.h"
|
|
||||||
#include "net/dns.h"
|
|
||||||
#include "event/task_scheduler.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ip
|
* @param ip
|
||||||
@@ -80,148 +70,3 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
|||||||
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
|
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets local address - pings google to inspect what interface was used locally
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string IpUtil::GetLocalIPAddress()
|
|
||||||
{
|
|
||||||
char my_ip_address[16];
|
|
||||||
unsigned int my_port;
|
|
||||||
struct sockaddr_in server_address{};
|
|
||||||
struct sockaddr_in my_address{};
|
|
||||||
int sockfd;
|
|
||||||
|
|
||||||
// Connect to server
|
|
||||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set server_addr
|
|
||||||
memset(&server_address, 0, sizeof(server_address));
|
|
||||||
server_address.sin_family = AF_INET;
|
|
||||||
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
|
|
||||||
server_address.sin_port = htons(80);
|
|
||||||
|
|
||||||
// Connect to server
|
|
||||||
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
|
|
||||||
close(sockfd);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get my ip address and port
|
|
||||||
memset(&my_address, 0, sizeof(my_address));
|
|
||||||
socklen_t len = sizeof(my_address);
|
|
||||||
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
|
|
||||||
inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address));
|
|
||||||
my_port = ntohs(my_address.sin_port);
|
|
||||||
|
|
||||||
return fmt::format("{}", my_ip_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets public address
|
|
||||||
* Uses various websites as options to return raw public IP back to the client
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string IpUtil::GetPublicIPAddress()
|
|
||||||
{
|
|
||||||
std::vector<std::string> endpoints = {
|
|
||||||
"http://ifconfig.me",
|
|
||||||
"http://api.ipify.org",
|
|
||||||
"http://ipinfo.io/ip",
|
|
||||||
"http://ipecho.net/plain",
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto &s: endpoints) {
|
|
||||||
// http get request
|
|
||||||
uri u(s);
|
|
||||||
|
|
||||||
httplib::Client r(
|
|
||||||
fmt::format(
|
|
||||||
"{}://{}",
|
|
||||||
u.get_scheme(),
|
|
||||||
u.get_host()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
httplib::Headers headers = {
|
|
||||||
{"Content-type", "text/plain; charset=utf-8"},
|
|
||||||
{"User-Agent", "curl/7.81.0"}
|
|
||||||
};
|
|
||||||
|
|
||||||
r.set_connection_timeout(1, 0);
|
|
||||||
r.set_read_timeout(1, 0);
|
|
||||||
r.set_write_timeout(1, 0);
|
|
||||||
|
|
||||||
if (auto res = r.Get(fmt::format("/{}", u.get_path()).c_str(), headers)) {
|
|
||||||
if (res->status == 200) {
|
|
||||||
if (res->body.find('.') != std::string::npos) {
|
|
||||||
return res->body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string IpUtil::DNSLookupSync(const std::string &addr, int port)
|
|
||||||
{
|
|
||||||
auto task_runner = new EQ::Event::TaskScheduler();
|
|
||||||
auto res = task_runner->Enqueue(
|
|
||||||
[&]() -> std::string {
|
|
||||||
bool running = true;
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
EQ::Net::DNSLookup(
|
|
||||||
addr, port, false, [&](const std::string &addr) {
|
|
||||||
ret = addr;
|
|
||||||
if (addr.empty()) {
|
|
||||||
ret = "";
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
auto &loop = EQ::EventLoop::Get();
|
|
||||||
while (running) {
|
|
||||||
if (!ret.empty()) {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
|
||||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() > 1500) {
|
|
||||||
LogInfo(
|
|
||||||
"Deadline exceeded [{}]",
|
|
||||||
1500
|
|
||||||
);
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop.Process();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string result = res.get();
|
|
||||||
safe_delete(task_runner);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IpUtil::IsIPAddress(const std::string &ip_address)
|
|
||||||
{
|
|
||||||
struct sockaddr_in sa{};
|
|
||||||
int result = inet_pton(AF_INET, ip_address.c_str(), &(sa.sin_addr));
|
|
||||||
return result != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user