Compare commits

..

2 Commits

Author SHA1 Message Date
KimLS 17d3a3f042 Update fmtlib 2020-01-06 20:41:45 -08:00
KimLS a162313355 Removed platform code, refactored logging to account for it and removed logging global var. 2020-01-06 18:15:55 -08:00
2114 changed files with 249063 additions and 673467 deletions
-6
View File
@@ -1,6 +0,0 @@
!Makefile
base/*.sql
base/*.zip
base/db/
base/maps/
!base/expansion/Makefile
@@ -1,9 +0,0 @@
# This is a "dev" image for running eqemu in development, also for dev containers
ARG USERNAME=user-name-goes-here
ARG USER_UID=1000
ARG USER_GID=$USER_UID
FROM --platform=linux/arm64 mcr.microsoft.com/devcontainers/base:debian
RUN sudo apt update && sudo apt install -y --no-install-recommends build-essential libtool cmake curl debconf-utils git libluabind-dev libsodium-dev liblua5.2-0 liblua5.2-dev libmariadb-dev libssl-dev minizip make mariadb-client locales nano open-vm-tools unzip uuid-dev iputils-ping wget libcurl4-openssl-dev gdb libyaml-cpp-dev ccache ninja-build pv mariadb-server libperl-dev libjson-perl libio-stringy-perl liblua5.1-dev libluabind-dev libboost-dev mariadb-server valgrind telnet libgoogle-perftools-dev google-perftools
USER $USERNAME
-9
View File
@@ -1,9 +0,0 @@
# This is a "dev" image for running eqemu in development, also for dev containers
ARG USERNAME=user-name-goes-here
ARG USER_UID=1000
ARG USER_GID=$USER_UID
FROM mcr.microsoft.com/devcontainers/base:debian
RUN sudo apt update && sudo apt install -y --no-install-recommends build-essential libtool cmake curl debconf-utils git libluabind-dev libsodium-dev liblua5.2-0 liblua5.2-dev libmariadb-dev libssl-dev minizip make mariadb-client locales nano open-vm-tools unzip uuid-dev iputils-ping wget libcurl4-openssl-dev gdb libyaml-cpp-dev ccache ninja-build pv mariadb-server libperl-dev libjson-perl libio-stringy-perl liblua5.1-dev libluabind-dev libboost-dev mariadb-server valgrind telnet libgoogle-perftools-dev google-perftools
USER $USERNAME
-284
View File
@@ -1,284 +0,0 @@
NAME := eqemu-server
.ONESHELL:
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
.PHONY: build
build:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
exit
endif
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
.PHONY: cmake
cmake:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
exit
endif
@echo "working directory: $$PWD"
mkdir -p build$$BUILD_SUFFIX
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
-DEQEMU_BUILD_TESTS=ON \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
clean:
ifneq (,$(findstring .devcontainer,$$PWD))
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
endif
rm -rf build
docker-cmake:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
exit
endif
@echo "working directory: $$PWD"
git submodule update --init --recursive
docker run ${DOCKER_ARGS} make cmake
docker-build:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
exit
endif
docker run ${DOCKER_ARGS} make build
# Build image if it doesn't exist
docker-image-build:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
exit
endif
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
@echo "Docker image not found. Building..."
docker build -f Dockerfile.debian.dev -t ${NAME} .
endif
docker-arm-cmake: docker-arm-image-build
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
exit
endif
git submodule update --init --recursive
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
docker-arm-build: docker-arm-image-build
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
exit
endif
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
docker-arm-image-build:
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
@echo "Docker image not found. Building..."
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
endif
docker-clean: clean
.PHONY: prep
prep:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
exit
endif
@echo "Preparing build/bin for usage..."
mkdir -p build/bin/assets/patches
cp -R -u -p .devcontainer/base/eqemu_config.json build/bin/eqemu_config.json
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
mkdir -p build/bin/assets
cp -R -u -p utils/patches build/bin/assets/
-unlink build/bin/lua_modules
cd build/bin && ln -s quests/lua_modules lua_modules
-unlink build/bin/mods
cd build/bin && ln -s quests/mods mods
-unlink build/bin/maps
cd build/bin && ln -s ../../base/maps maps
mkdir -p build/bin/logs
mkdir -p build/bin/shared
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
maps:
@echo "Downloading maps..."
@mkdir -p base/maps
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
@cd base/maps && unzip -o master.zip
@cd base/maps && mv eqemu-maps-master/* .
@cd base/maps && rm -rf eqemu-maps-master
@echo "Maps downloaded."
quests:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
exit
endif
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
# Runs tests
.PHONY: test
test:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
exit
endif
cd build/bin && ./tests
# Runs login binary
.PHONY: login
login:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
exit
endif
cd build/bin && ./loginserver
# Runs shared_memory binary
.PHONY: shared
shared:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
exit
endif
cd build/bin && ./shared_memory
# Runs zone binary
.PHONY: zone
zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
exit
endif
@-rm build/bin/logs/zone/zone*.log
cd build/bin && ./zone
# Runs world binary
.PHONY: world
world:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
exit
endif
@-rm build/bin/logs/world*.log
cd build/bin && ./world
# Runs ucs binary
.PHONY: ucs
ucs:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
exit
endif
@-rm build/bin/logs/ucs*.log
cd build/bin && ./ucs
# Runs queryserv binary
.PHONY: queryserv
queryserv:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
exit
endif
@-rm build/bin/logs/query_server*.log
cd build/bin && ./queryserv
valgrind-%:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
exit
endif
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
# Start mariaDB standalone
.PHONY: mariadb
mariadb:
@sudo service mariadb start
.PHONY: inject-mariadb
inject-mariadb:
-sudo service mariadb start
-mkdir -p base/db/
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
-sudo mariadb -e 'CREATE DATABASE peq;'
-sudo mariadb -e "CREATE USER 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
-sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
ifeq (,$(wildcard base/db/db.sql.zip))
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
-cd base/db && unzip db.sql.zip
endif
@echo "Sourcing db may take a while, please wait..."
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
@echo "MariaDB is now injected."
.PHONY: gm-%
gm-%:
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
@echo "Account $* is now a GM. /camp to have it go into effect."
depends:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
exit
endif
sudo apt install graphviz pip time
pip3 install graphviz
mkdir -p build/depends
@if [ ! -f "build/depends/dependency_graph.py" ]; then \
wget https://raw.githubusercontent.com/pvigier/dependency-graph/master/dependency_graph.py -O build/depends/dependency_graph.py; \
fi
@echo "Generating dependency graphs (This may take a while)..."
@echo "Login..."
time python3 build/depends/dependency_graph.py -f png login build/depends/login.dot
@echo "World..."
time python3 build/depends/dependency_graph.py -f png world build/depends/world.dot
@echo "Zone..."
time python3 build/depends/dependency_graph.py -f png zone build/depends/zone.dot
@echo "Common..."
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
backup:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
exit
endif
@mkdir -p build/bin/backup
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
cpu-zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
exit
endif
@cd build/bin && mkdir -p tmp
cd build/bin && CPUPROFILE=prof.out ./zone
pprof-zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile pprof-zone --no-print-directory
exit
endif
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
pprof-web-zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile pprof-web-zone --no-print-directory
exit
endif
cd build/bin && google-pprof --web zone prof.out
pprof-gv-zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile pprof-gv-zone --no-print-directory
exit
endif
cd build/bin && google-pprof --gv zone prof.out > prof.gv
heap-zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile heap-zone --no-print-directory
exit
endif
@cd build/bin && mkdir -p tmp
cd build/bin && HEAPPROFILE=prof.out ./zone
-73
View File
@@ -1,73 +0,0 @@
{
"server": {
"zones": {
"defaultstatus": "0",
"ports": {
"low": "7000",
"high": "7400"
}
},
"qsdatabase": {
"host": "127.0.0.1",
"port": "3306",
"username": "peq",
"password": "peqpass",
"db": "peq"
},
"chatserver": {
"port": "7778",
"host": ""
},
"mailserver": {
"host": "",
"port": "7778"
},
"webinterface": {
"port": "9081"
},
"world": {
"longname": "New Devbox",
"address": "192.168.1.100",
"localaddress": "192.168.1.100",
"loginserver1": {
"account": "",
"password": "",
"legacy": 0,
"host": "login.projecteq.net",
"port": "5998"
},
"tcp": {
"ip": "127.0.0.1",
"port": "9001"
},
"telnet": {
"ip": "0.0.0.0",
"port": "9000",
"enabled": "true"
},
"key": "random-generate-here",
"http": {
"port": "9080",
"enabled": "true",
"mimefile": "mime.types"
},
"shortname": "dev"
},
"database": {
"db": "peq",
"host": "127.0.0.1",
"port": "3306",
"username": "peq",
"password": "peqpass"
},
"files": {
"opcodes": "assets/patches/opcodes.conf",
"mail_opcodes": "assets/patches/mail_opcodes.conf"
},
"directories": {
"patches": "assets/patches/",
"opcodes": "assets/patches/",
"plugins": "quests/plugins/"
}
}
}
-37
View File
@@ -1,37 +0,0 @@
{
"database": {
"host": "127.0.0.1",
"port": "3306",
"db": "peq",
"user": "peq",
"password": "peqpass"
},
"account": {
"auto_create_accounts": true
},
"worldservers": {
"unregistered_allowed": true,
"reject_duplicate_servers": false
},
"web_api": {
"enabled": true,
"port": 6000
},
"security": {
"mode": 14,
"allow_password_login": true,
"allow_token_login": true
},
"logging": {
"trace": false,
"world_trace": false,
"dump_packets_in": false,
"dump_packets_out": false
},
"client_configuration": {
"titanium_port": 5998,
"titanium_opcodes": "assets/patches/login_opcodes.conf",
"sod_port": 5999,
"sod_opcodes": "assets/patches/login_opcodes_sod.conf"
}
}
-49
View File
@@ -1,49 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
{
"name": "eqemu",
"build": {
"dockerfile": "Dockerfile.debian.dev"
},
"appPort": [
"5998:5998/udp",
"7000:7000/udp",
"7001:7001/udp",
"7002:7002/udp",
"7003:7003/udp",
"7004:7004/udp",
"7005:7005/udp",
"9000:9000/udp",
"9001:9001/udp"
],
"forwardPorts": [
3306
],
"remoteEnv": {
"LOCALWSF": "${localWorkspaceFolder}",
"CONTAINERWSF": "${containerWorkspaceFolder}"
},
"containerUser": "vscode",
// add ptrace
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt",
"seccomp=unconfined"
],
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools-extension-pack",
"vilicvane.sensitive-replace",
"maattdd.gitless",
"bibhasdn.unique-lines",
"GitHub.copilot",
"xackery.make-magic",
"Gruntfuggly.todo-tree",
"ms-vscode.cmake-tools"
]
}
},
"workspaceFolder": "/src",
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
}
-98
View File
@@ -1,98 +0,0 @@
---
kind: pipeline
type: docker
name: Build Linux
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
concurrency:
limit: 1
volumes:
- name: cache
host:
path: /var/lib/cache-release
steps:
- name: Build Linux X64
image: akkadius/eqemu-server:v14
environment:
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
commands:
- ./utils/scripts/build/linux-build.sh
volumes:
- name: cache
path: /home/eqemu/.ccache/
---
kind: pipeline
type: exec
name: Build Windows
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
concurrency:
limit: 1
platform:
os: windows
arch: amd64
steps:
- name: Build Windows X64
environment:
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
commands:
- .\utils\scripts\build\windows-build.ps1
---
kind: pipeline
type: docker
name: Publish Artifacts to Github
steps:
- name: Upload Artifacts
image: akkadius/eqemu-build-releaser:v3
environment:
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
GH_RELEASE_GITHUB_API_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
commands:
- ./utils/scripts/build/should-release/should-release
- rclone config create remote ftp env_auth true > /dev/null
- |
rclone copy remote: --include "eqemu-server*.zip" .
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
- |
rclone delete remote: --include "eqemu-server*.zip"
trigger:
branch:
- master
event:
- push
depends_on:
- Build Windows
- Build Linux
+1 -34
View File
@@ -17,8 +17,6 @@
*.out
*.app
.bash_history
# CMake
CMakeCache.txt
CMakeFiles
@@ -37,35 +35,4 @@ perl/
submodules/*
cmake-build-debug/
.nfs.*
# Visual Studio and CMAKE Generated Files
/.vs/
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.cmake
*.ilk
*.pdb
*.sln
*.dir/
libs/
bin/
/Win32
/x64
/client_files/**/CMakeFiles/
.idea
# Clangd Generated Files.
compile_flags.txt
.cache/
# 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/*
skill-caps.diff
.nfs.*
+27
View File
@@ -0,0 +1,27 @@
language: cpp
compiler: gcc
dist: trusty
before_install:
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get update -qq
- mkdir $HOME/usr
- export PATH="$HOME/usr/bin:$PATH"
- wget https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.sh
- chmod +x cmake-3.11.2-Linux-x86_64.sh
- ./cmake-3.11.2-Linux-x86_64.sh --prefix=$HOME/usr --exclude-subdir --skip-license
install:
- sudo apt-get install -qq g++-7
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90
- sudo apt-get install libmysqlclient-dev
- sudo apt-get install libperl-dev
- sudo apt-get install libboost-dev
- sudo apt-get install liblua5.1-0-dev
- sudo apt-get install zlib1g-dev
- sudo apt-get install uuid-dev
- sudo apt-get install libssl-dev
script:
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
- make -j2
- ./bin/tests
-23
View File
@@ -1,23 +0,0 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${default}",
"${workspaceFolder}/submodules/fmt/include",
"${workspaceFolder}/submodules/cereal/include",
"${workspaceFolder}/submodules/glm",
"${workspaceFolder}/submodules/libuv/include"
],
"defines": [
"LUA_EQEMU=1"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}
-173
View File
@@ -1,173 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) attach",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/build/bin/world",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) shared_memory",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/shared_memory",
"cwd": "${workspaceFolder}/build/bin",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) world",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/world",
"cwd": "${workspaceFolder}/build/bin",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) zone",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/zone",
"cwd": "${workspaceFolder}/build/bin",
"args": [
"",
],
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) zone neriakb",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/zone",
"cwd": "${workspaceFolder}/build/bin",
"args": [
"neriakb",
],
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) login",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/loginserver",
"cwd": "${workspaceFolder}/build/bin",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) ucs",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/ucs",
"cwd": "${workspaceFolder}/build/bin",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) queryserv",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/bin/queryserv",
"cwd": "${workspaceFolder}/build/bin",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
-136
View File
@@ -1,136 +0,0 @@
{
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"editor.tabSize": 4,
"editor.autoIndent": "full",
"editor.trimAutoWhitespace": true,
"files.trimTrailingWhitespace": true,
//"editor.formatOnSave": true,
"search.exclude": {
"dependencies": false,
},
"C_Cpp.default.includePath": [
"/usr/include/x86_64-linux-gnu",
"/usr/include/lua5.2",
"/usr/include/mariadb",
"${workspaceFolder}/dependencies/curl_x64/include",
"${workspaceFolder}/dependencies/fmt/include",
"${workspaceFolder}/dependencies/glm",
"${workspaceFolder}/dependencies/libuv/include",
"${workspaceFolder}/dependencies/sol2",
"${workspaceFolder}/dependencies/zlibng"
],
"telemetry.enableTelemetry": false,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.configureArgs": [
"-DEQEMU_BUILD_LOGIN=ON",
"-DEQEMU_BUILD_TESTS=ON",
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
"-DEQEMU_ADD_PROFILER=ON",
"Ninja"
],
"cmake.skipConfigureIfCachePresent": true,
"cmake.configureOnOpen": false,
"files.associations": {
"*.ipp": "cpp",
"functional": "cpp",
"string": "cpp",
"iostream": "cpp",
"map": "cpp",
"fstream": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"cstring": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"strstream": "cpp",
"bit": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"coroutine": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp",
"csetjmp": "cpp",
"charconv": "cpp",
"format": "cpp",
"ranges": "cpp",
"span": "cpp"
},
"cmake.statusbar.advanced": {
"kit": {
"visibility": "hidden",
},
"debug": {
"visibility": "hidden",
},
"buildTarget": {
"visibility": "hidden",
},
"launch": {
"visibility": "hidden",
},
"ctest": {
"visibility": "icon",
}
}
}
+2 -2
View File
@@ -40,14 +40,14 @@ Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extra
mkdir build
cd build
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
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
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
mkdir build
cd build
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON ..
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
### Building
-4356
View File
File diff suppressed because it is too large Load Diff
+24 -128
View File
@@ -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})
@@ -12,47 +12,16 @@ IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_CXX_STANDARD 20)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
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)
# Requires libgoogle-perftools-dev google-perftools packages for linux (debian)
IF(EQEMU_ADD_PROFILER)
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-as-needed,-lprofiler,--as-needed")
ENDIF(EQEMU_ADD_PROFILER)
IF(USE_MAP_MMFS)
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
ENDIF (USE_MAP_MMFS)
IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING)
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
IF(EQEMU_DISABLE_MSVC_WARNINGS)
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
ELSE(MSVC)
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC)
@@ -86,7 +55,6 @@ FIND_PACKAGE(MariaDB)
FIND_PACKAGE(ZLIB)
FIND_PACKAGE(OpenSSL)
FIND_PACKAGE(Lua51)
FIND_PACKAGE(LuaJit)
FIND_PACKAGE(PerlLibs)
FIND_PACKAGE(Sodium)
FIND_PACKAGE(mbedTLS)
@@ -119,12 +87,6 @@ ELSE()
MESSAGE(STATUS "* Lua: MISSING *")
ENDIF()
IF(LuaJit_FOUND)
MESSAGE(STATUS "* LuaJIT: FOUND *")
ELSE()
MESSAGE(STATUS "* LuaJIT: MISSING *")
ENDIF()
IF(PerlLibs_FOUND)
MESSAGE(STATUS "* Perl: FOUND *")
ELSE()
@@ -149,76 +111,33 @@ ELSE()
MESSAGE(STATUS "* mbedTLS: MISSING *")
ENDIF()
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
MESSAGE(STATUS "**************************************************")
#options
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
OPTION(EQEMU_PREFER_LUA "Build with normal Lua even if LuaJIT is found." OFF)
#PRNG options
OPTION(EQEMU_ADDITIVE_LFIB_PRNG "Use Additive LFib for PRNG." OFF)
MARK_AS_ADVANCED(EQEMU_ADDITIVE_LFIB_PRNG)
OPTION(EQEMU_BIASED_INT_DIST "Use biased int dist instead of uniform." OFF)
MARK_AS_ADVANCED(EQEMU_BIASED_INT_DIST)
SET(EQEMU_CUSTOM_PRNG_ENGINE "" CACHE STRING "Custom random engine. (ex. std::default_random_engine)")
MARK_AS_ADVANCED(EQEMU_CUSTOM_PRNG_ENGINE)
IF(CMAKE_COMPILER_IS_GNUCXX)
OPTION(EQEMU_SFMT19937 "Use GCC's extention for SIMD Fast MT19937." OFF)
MARK_AS_ADVANCED(EQEMU_SFMT19937)
ENDIF()
IF(EQEMU_ADDITIVE_LFIB_PRNG)
ADD_DEFINITIONS(-DUSE_ADDITIVE_LFIB_PRNG)
IF(EQEMU_SFMT19937)
MESSAGE(STATUS "SFMT19937 and ADDITITVE_LFIB_PRNG both set, SFMT19937 ignored.")
SET(EQEMU_SFMT19937 OFF)
ENDIF()
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
MESSAGE(STATUS "CUSTOM_PRNG_ENGINE and ADDITITVE_LFIB_PRNG both set, CUSTOM_PRNG_ENGINE ignored.")
SET(EQEMU_CUSTOM_PRNG_ENGINE "")
ENDIF()
ENDIF()
IF(EQEMU_SFMT19937)
ADD_DEFINITIONS(-DUSE_SFMT19937)
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
MESSAGE(STATUS "CUSTOM_PRNG_ENGINE and SFMT19937 both set, CUSTOM_PRNG_ENGINE ignored.")
SET(EQEMU_CUSTOM_PRNG_ENGINE "")
ENDIF()
ENDIF()
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
ADD_DEFINITIONS(-DUSE_CUSTOM_PRNG_ENGINE=${EQEMU_CUSTOM_PRNG_ENGINE})
ENDIF()
IF(EQEMU_BIASED_INT_DIST)
ADD_DEFINITIONS(-DBIASED_INT_DIST)
ENDIF()
IF(EQEMU_COMMANDS_LOGGING)
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
ENDIF(EQEMU_COMMANDS_LOGGING)
IF(EQEMU_ENABLE_BOTS)
ADD_DEFINITIONS(-DBOTS)
ENDIF(EQEMU_ENABLE_BOTS)
#database
IF(MySQL_FOUND AND MariaDB_FOUND)
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use:
MySQL
MariaDB"
)
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
SET(DATABASE_LIBRARY_TYPE " MySQL")
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
@@ -249,16 +168,13 @@ IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
OpenSSL
mbedTLS"
)
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
SET(TLS_LIBRARY_TYPE " OpenSSL")
SET(TLS_LIBRARY_ENABLED ON)
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
ENDIF()
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
SET(TLS_LIBRARY_TYPE " mbedTLS")
SET(TLS_LIBRARY_ENABLED ON)
@@ -274,9 +190,6 @@ ELSEIF(OpenSSL_FOUND)
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
ENDIF()
ELSEIF(MBEDTLS_FOUND)
SET(TLS_LIBRARY_TYPE " mbedTLS")
SET(TLS_LIBRARY_ENABLED ON)
@@ -299,12 +212,7 @@ ELSE()
SET(SODIUM_LIBRARY_ENABLED OFF)
ENDIF()
IF(LUAJIT_FOUND AND NOT (EQEMU_PREFER_LUA AND Lua51_FOUND))
SET(LUA_LIBRARY_TYPE " LuaJIT")
SET(LUA_LIBRARY_ENABLED ON)
SET(LUA_LIBRARY_LIBS ${LUAJIT_LIBRARY} luabind)
SET(LUA_LIBRARY_INCLUDE ${LUAJIT_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
ELSEIF(Lua51_FOUND )
IF(Lua51_FOUND)
SET(LUA_LIBRARY_TYPE " Lua 5.1")
SET(LUA_LIBRARY_ENABLED ON)
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
@@ -331,7 +239,6 @@ IF(ZLIB_FOUND)
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng")
ELSE()
SET(ZLIB_LIBRARY_TYPE " zlib")
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
@@ -343,10 +250,6 @@ ELSE()
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
ENDIF()
IF (EQEMU_BUILD_STATIC)
SET(ZLIB_LIBRARY_LIBS libz.a)
ENDIF(EQEMU_BUILD_STATIC)
MESSAGE(STATUS "")
MESSAGE(STATUS "**************************************************")
MESSAGE(STATUS "* Library Usage *")
@@ -376,8 +279,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/websocketpp")
# silence obnoxious deprecation message
ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
IF(EQEMU_BUILD_LOGGING)
ADD_DEFINITIONS(-DBUILD_LOGGING)
ENDIF()
IF(TLS_LIBRARY_ENABLED)
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
@@ -391,12 +296,12 @@ ENDIF()
IF(LUA_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
IF(EQEMU_BUILD_LUA)
ADD_DEFINITIONS(-DLUA_EQEMU)
SET(ZONE_LIBS ${LUA_LIBRARY_LIBS})
SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
@@ -407,14 +312,10 @@ ENDIF()
IF(PERL_LIBRARY_ENABLED)
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
IF(EQEMU_BUILD_PERL)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
IF (UNIX AND EQEMU_BUILD_STATIC)
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
ENDIF ()
ENDIF()
ENDIF()
@@ -427,14 +328,9 @@ IF(UNIX)
IF(NOT DARWIN)
SET(SERVER_LIBS ${SERVER_LIBS} "rt")
ENDIF()
# Freebsd provides uuids in the C library
IF(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
ENDIF()
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
ENDIF()
SET(ZONE_LIBS ${ZONE_LIBS} ${SERVER_LIBS})
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
ENDIF()
@@ -448,13 +344,13 @@ IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_H
ADD_SUBDIRECTORY(libs)
ADD_SUBDIRECTORY(submodules/fmt)
ADD_SUBDIRECTORY(submodules/libuv)
IF(EQEMU_BUILD_ZLIB)
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
ADD_SUBDIRECTORY(libs/zlibng)
ENDIF()
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
-22
View File
@@ -1,22 +0,0 @@
We expect contributors and community members to act professionally and respectfully, and we expect our forums and Discord channels to be dignified environments that expand the community and enhance the learning experience for new members.
Specifically:
* Respect people, their ideas, and their work.
* Be kind. Be courteous. Be welcoming.
* Listen. Consider and acknowledge people's points before responding.
* Be respectful of differing viewpoints and experience levels.
* Accept constructive criticism and work together toward decisions.
* Focus on what is best for the community and users.
Examples of unacceptable behavior by participants include:
* The use of violent threats, trolling, insulting/derogatory comments, abusive or discriminatory language, or personal attacks.
* Public or private harassment.
* Publishing others' private information, such as a physical or electronic address, without explicit permission.
* Conduct which could reasonably be considered inappropriate in a professional setting.
* Advocating for or encouraging any of the above behaviors.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, forum posts, Discord messages, and other contributions that are not aligned with this code of conduct.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project.
+6 -11
View File
@@ -1,7 +1,7 @@
# EQEmulator Core Server
| Drone (Linux x64) | Drone (Windows x64) |
|:---:|:---:|
|[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |
|Travis CI (Linux)|Appveyor w/ Bots (Windows) |Appveyor w/o Bots (Windows) |
|:---:|:---:|:---:|
|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Build status](https://ci.appveyor.com/api/projects/status/scr25kmntx36c1ub/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[![Build status](https://ci.appveyor.com/api/projects/status/mdwbr4o9l6mxqofj/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server-w0pq2/branch/master) |
***
@@ -17,17 +17,13 @@
|:---:|:---:|:---:|
|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)|
### > Windows
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
* [Install](https://github.com/EQEmu/Server/wiki/Windows-Server)
### > Debian/Ubuntu/CentOS/Fedora
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
* You can use curl or wget to kick off the installer (whichever your OS has)
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
## Supported Clients
@@ -56,7 +52,7 @@ forum, although pull requests will be much quicker and easier on all parties.
## Resources
- [EQEmulator Forums](http://www.eqemulator.org/forums)
- [EQEmulator Wiki](https://docs.eqemu.io/)
- [EQEmulator Wiki](https://github.com/EQEmu/Server/wiki)
## Related Repositories
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
@@ -80,4 +76,3 @@ forum, although pull requests will be much quicker and easier on all parties.
<a href="https://github.com/EQEmu/server/graphs/contributors">
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
</a>
+21
View File
@@ -0,0 +1,21 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
configuration: RelWithDebInfo
clone_folder: c:\projects\eqemu
init:
- ps: git config --global core.autocrlf input
cache: c:\tools\vcpkg\installed\
before_build:
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
build:
project: C:\projects\eqemu\build\EQEmu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: >-
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb
appveyor PushArtifact build_x64-bots.zip
+21
View File
@@ -0,0 +1,21 @@
version: 1.0.{build}
branches:
only:
- master
image: Visual Studio 2017
configuration: RelWithDebInfo
clone_folder: c:\projects\eqemu
init:
- ps: git config --global core.autocrlf input
cache: c:\tools\vcpkg\installed\
before_build:
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=OFF -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
build:
project: C:\projects\eqemu\build\EQEmu.sln
parallel: true
verbosity: minimal
after_build:
- cmd: >-
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb
appveyor PushArtifact build_x64-no-bots.zip
+1 -1
View File
@@ -3,7 +3,7 @@
############################################
#
# New changelog can be found here
# https://docs.eqemu.io/server/changelog/server
# https://eqemu.gitbook.io/changelog/
#
############################################
# Deprecated
+1 -1
View File
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
add_subdirectory(import)
add_subdirectory(export)
+1 -1
View File
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(export_sources
main.cpp
+152 -111
View File
@@ -22,44 +22,21 @@
#include "../../common/global_define.h"
#include "../../common/shareddb.h"
#include "../../common/eqemu_config.h"
#include "../../common/platform.h"
#include "../../common/crash.h"
#include "../../common/rulesys.h"
#include "../../common/strings.h"
#include "../../common/content/world_content_service.h"
#include "../../common/zone_store.h"
#include "../../common/path_manager.h"
#include "../../common/repositories/base_data_repository.h"
#include "../../common/repositories/db_str_repository.h"
#include "../../common/repositories/skill_caps_repository.h"
#include "../../common/repositories/spells_new_repository.h"
#include "../../common/file.h"
#include "../../common/events/player_event_logs.h"
#include "../../common/skill_caps.h"
#include "../../common/evolving_items.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
PlayerEventLogs player_event_logs;
EvolvingItemsManager evolving_items_manager;
#include "../../common/string_util.h"
void ExportSpells(SharedDatabase *db);
void ExportSkillCaps(SharedDatabase *db);
void ExportBaseData(SharedDatabase *db);
void ExportDBStrings(SharedDatabase *db);
int main(int argc, char **argv)
{
RegisterExecutablePlatform(ExePlatformClientExport);
LogSys.LoadLogSettingsDefaults();
int main(int argc, char **argv) {
EQEmuLogSys::Get()->LoadLogSettingsDefaults("client_export");
set_exception_handler();
path.LoadPaths();
LogInfo("Client Files Export Utility");
if (!EQEmuConfig::LoadConfig()) {
if(!EQEmuConfig::LoadConfig()) {
LogError("Unable to load configuration file");
return 1;
}
@@ -67,146 +44,210 @@ int main(int argc, char **argv)
auto Config = EQEmuConfig::get();
SharedDatabase database;
SharedDatabase content_db;
LogInfo("Connecting to database");
if (!database.Connect(
Config->DatabaseHost.c_str(),
Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(),
Config->DatabaseDB.c_str(),
Config->DatabasePort
)) {
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
LogError("Unable to connect to the database, cannot continue without a database connection");
return 1;
}
/**
* Multi-tenancy: Content database
*/
if (!Config->ContentDbHost.empty()) {
if (!content_db.Connect(
Config->ContentDbHost.c_str() ,
Config->ContentDbUsername.c_str(),
Config->ContentDbPassword.c_str(),
Config->ContentDbName.c_str(),
Config->ContentDbPort
)) {
LogError("Cannot continue without a content database connection");
return 1;
}
} else {
content_db.SetMySQL(database);
}
/* Register Log System and Settings */
database.LoadLogSettings(EQEmuLogSys::Get()->log_settings);
EQEmuLogSys::Get()->StartFileLogs();
LogSys.SetDatabase(&database)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings()
->StartFileLogs();
std::string export_type;
std::string arg_1;
if (argv[1]) {
export_type = argv[1];
arg_1 = argv[1];
}
if (Strings::EqualFold(export_type, "spells")) {
ExportSpells(&content_db);
if (arg_1 == "spells") {
ExportSpells(&database);
return 0;
} else if (Strings::EqualFold(export_type, "skills")) {
ExportSkillCaps(&content_db);
}
if (arg_1 == "skills") {
ExportSkillCaps(&database);
return 0;
} else if (Strings::EqualFold(export_type, "basedata") || Strings::EqualFold(export_type, "base_data")) {
ExportBaseData(&content_db);
}
if (arg_1 == "basedata") {
ExportBaseData(&database);
return 0;
} else if (Strings::EqualFold(export_type, "dbstr") || Strings::EqualFold(export_type, "dbstring")) {
}
if (arg_1 == "dbstring") {
ExportDBStrings(&database);
return 0;
}
ExportSpells(&content_db);
ExportSkillCaps(&content_db);
ExportBaseData(&content_db);
ExportSpells(&database);
ExportSkillCaps(&database);
ExportBaseData(&database);
ExportDBStrings(&database);
LogSys.CloseFileLogs();
EQEmuLogSys::Get()->CloseFileLogs();
return 0;
}
void ExportSpells(SharedDatabase* db)
{
std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
if (!file || !file.is_open()) {
void ExportSpells(SharedDatabase *db) {
LogInfo("Exporting Spells");
FILE *f = fopen("export/spells_us.txt", "w");
if(!f) {
LogError("Unable to open export/spells_us.txt to write, skipping.");
return;
}
const auto& lines = SpellsNewRepository::GetSpellFileLines(*db);
const std::string query = "SELECT * FROM spells_new ORDER BY id";
auto results = db->QueryDatabase(query);
const std::string& file_string = Strings::Implode("\n", lines);
if(results.Success()) {
for (auto row = results.begin(); row != results.end(); ++row) {
std::string line;
unsigned int fields = results.ColumnCount();
for(unsigned int i = 0; i < fields; ++i) {
if(i != 0) {
line.push_back('^');
}
file << file_string;
if(row[i] != nullptr) {
line += row[i];
}
}
file.close();
fprintf(f, "%s\n", line.c_str());
}
} else {
}
LogInfo("Exported [{}] Spell{}", lines.size(), lines.size() != 1 ? "s" : "");
fclose(f);
}
void ExportSkillCaps(SharedDatabase* db)
{
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
if (!file || !file.is_open()) {
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id) {
bool res = false;
std::string query = StringFormat("SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
class_id, skill_id);
auto results = db->QueryDatabase(query);
if(!results.Success()) {
return false;
}
if (results.RowCount() == 0)
return false;
auto row = results.begin();
if(row[0] && atoi(row[0]) > 0)
return true;
return false;
}
int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
std::string query = StringFormat("SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
class_id, skill_id, level);
auto results = db->QueryDatabase(query);
if (!results.Success()) {
return 0;
}
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
void ExportSkillCaps(SharedDatabase *db) {
LogInfo("Exporting Skill Caps");
FILE *f = fopen("export/SkillCaps.txt", "w");
if(!f) {
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
return;
}
const auto& lines = SkillCapsRepository::GetSkillCapFileLines(*db);
for(int cl = 1; cl <= 16; ++cl) {
for(int skill = 0; skill <= 77; ++skill) {
if(SkillUsable(db, skill, cl)) {
int previous_cap = 0;
for(int level = 1; level <= 100; ++level) {
int cap = GetSkill(db, skill, cl, level);
if(cap < previous_cap) {
cap = previous_cap;
}
const std::string& file_string = Strings::Implode("\n", lines);
fprintf(f, "%d^%d^%d^%d^0\n", cl, skill, level, cap);
previous_cap = cap;
}
}
}
}
file << file_string;
file.close();
LogInfo("Exported [{}] Skill Cap{}", lines.size(), lines.size() != 1 ? "s" : "");
fclose(f);
}
void ExportBaseData(SharedDatabase *db)
{
std::ofstream file(fmt::format("{}/export/BaseData.txt", path.GetServerPath()));
if (!file || !file.is_open()) {
void ExportBaseData(SharedDatabase *db) {
LogInfo("Exporting Base Data");
FILE *f = fopen("export/BaseData.txt", "w");
if(!f) {
LogError("Unable to open export/BaseData.txt to write, skipping.");
return;
}
const auto& lines = BaseDataRepository::GetBaseDataFileLines(*db);
const std::string query = "SELECT * FROM base_data ORDER BY level, class";
auto results = db->QueryDatabase(query);
if(results.Success()) {
for (auto row = results.begin();row != results.end();++row) {
std::string line;
unsigned int fields = results.ColumnCount();
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
if(rowIndex != 0)
line.push_back('^');
const std::string& file_string = Strings::Implode("\n", lines);
if(row[rowIndex] != nullptr) {
line += row[rowIndex];
}
}
file << file_string;
fprintf(f, "%s\n", line.c_str());
}
}
file.close();
LogInfo("Exported [{}] Base Data Entr{}", lines.size(), lines.size() != 1 ? "ies" : "y");
fclose(f);
}
void ExportDBStrings(SharedDatabase *db)
{
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", path.GetServerPath()));
if (!file || !file.is_open()) {
void ExportDBStrings(SharedDatabase *db) {
LogInfo("Exporting DB Strings");
FILE *f = fopen("export/dbstr_us.txt", "w");
if(!f) {
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
return;
}
const auto& lines = DbStrRepository::GetDBStrFileLines(*db);
fprintf(f, "Major^Minor^String(New)\n");
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
auto results = db->QueryDatabase(query);
if(results.Success()) {
for(auto row = results.begin(); row != results.end(); ++row) {
std::string line;
unsigned int fields = results.ColumnCount();
for(unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
if(rowIndex != 0)
line.push_back('^');
const std::string& file_string = Strings::Implode("\n", lines);
if(row[rowIndex] != nullptr) {
line += row[rowIndex];
}
}
file << file_string;
fprintf(f, "%s\n", line.c_str());
}
}
file.close();
LogInfo("Exported [{}] Database String{}", lines.size(), lines.size() != 1 ? "s" : "");
fclose(f);
}
+1 -1
View File
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(import_sources
main.cpp
+63 -106
View File
@@ -20,24 +20,9 @@
#include "../../common/global_define.h"
#include "../../common/shareddb.h"
#include "../../common/eqemu_config.h"
#include "../../common/platform.h"
#include "../../common/crash.h"
#include "../../common/rulesys.h"
#include "../../common/strings.h"
#include "../../common/content/world_content_service.h"
#include "../../common/zone_store.h"
#include "../../common/path_manager.h"
#include "../../common/repositories/base_data_repository.h"
#include "../../common/file.h"
#include "../../common/events/player_event_logs.h"
#include "../../common/evolving_items.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
PlayerEventLogs player_event_logs;
EvolvingItemsManager evolving_items_manager;
#include "../../common/string_util.h"
void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db);
@@ -45,12 +30,9 @@ void ImportBaseData(SharedDatabase *db);
void ImportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientImport);
LogSys.LoadLogSettingsDefaults();
EQEmuLogSys::Get()->LoadLogSettingsDefaults("client_import");
set_exception_handler();
path.LoadPaths();
LogInfo("Client Files Import Utility");
if(!EQEmuConfig::LoadConfig()) {
LogError("Unable to load configuration file.");
@@ -60,50 +42,24 @@ int main(int argc, char **argv) {
auto Config = EQEmuConfig::get();
SharedDatabase database;
SharedDatabase content_db;
LogInfo("Connecting to database");
if (!database.Connect(
Config->DatabaseHost.c_str(),
Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(),
Config->DatabaseDB.c_str(),
Config->DatabasePort
)) {
LogError("Unable to connect to the database, cannot continue without a database connection");
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
LogError("Unable to connect to the database, cannot continue without a "
"database connection");
return 1;
}
/**
* Multi-tenancy: Content database
*/
if (!Config->ContentDbHost.empty()) {
if (!content_db.Connect(
Config->ContentDbHost.c_str() ,
Config->ContentDbUsername.c_str(),
Config->ContentDbPassword.c_str(),
Config->ContentDbName.c_str(),
Config->ContentDbPort
)) {
LogError("Cannot continue without a content database connection");
return 1;
}
} else {
content_db.SetMySQL(database);
}
database.LoadLogSettings(EQEmuLogSys::Get()->log_settings);
EQEmuLogSys::Get()->StartFileLogs();
LogSys.SetDatabase(&database)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings()
->StartFileLogs();
ImportSpells(&content_db);
ImportSkillCaps(&content_db);
ImportBaseData(&content_db);
ImportSpells(&database);
ImportSkillCaps(&database);
ImportBaseData(&database);
ImportDBStrings(&database);
LogSys.CloseFileLogs();
EQEmuLogSys::Get()->CloseFileLogs();
return 0;
}
@@ -138,10 +94,9 @@ bool IsStringField(int i) {
void ImportSpells(SharedDatabase *db) {
LogInfo("Importing Spells");
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/spells_us.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/spells_us.txt to read, skipping.");
return;
}
@@ -160,8 +115,8 @@ void ImportSpells(SharedDatabase *db) {
}
}
std::string escaped = ::Strings::Escape(buffer);
auto split = Strings::Split(escaped, '^');
std::string escaped = ::EscapeString(buffer);
auto split = SplitString(escaped, '^');
int line_columns = (int)split.size();
std::string sql;
@@ -228,10 +183,9 @@ void ImportSpells(SharedDatabase *db) {
void ImportSkillCaps(SharedDatabase *db) {
LogInfo("Importing Skill Caps");
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/SkillCaps.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
return;
}
@@ -240,17 +194,17 @@ void ImportSkillCaps(SharedDatabase *db) {
char buffer[2048];
while(fgets(buffer, 2048, f)) {
auto split = Strings::Split(buffer, '^');
auto split = SplitString(buffer, '^');
if(split.size() < 4) {
continue;
}
int class_id, skill_id, level, cap;
class_id = Strings::ToInt(split[0].c_str());
skill_id = Strings::ToInt(split[1].c_str());
level = Strings::ToInt(split[2].c_str());
cap = Strings::ToInt(split[3].c_str());
class_id = atoi(split[0].c_str());
skill_id = atoi(split[1].c_str());
level = atoi(split[2].c_str());
cap = atoi(split[3].c_str());
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
class_id, skill_id, level, cap);
@@ -261,54 +215,57 @@ void ImportSkillCaps(SharedDatabase *db) {
fclose(f);
}
void ImportBaseData(SharedDatabase *db)
{
void ImportBaseData(SharedDatabase *db) {
LogInfo("Importing Base Data");
const std::string& file_name = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
const auto& file_contents = File::GetContents(file_name);
if (!file_contents.error.empty()) {
LogError("{}", file_contents.error);
FILE *f = fopen("import/BaseData.txt", "r");
if(!f) {
LogError("Unable to open import/BaseData.txt to read, skipping.");
return;
}
db->QueryDatabase("DELETE FROM base_data");
std::string delete_sql = "DELETE FROM base_data";
db->QueryDatabase(delete_sql);
std::vector<BaseDataRepository::BaseData> v;
char buffer[2048];
while(fgets(buffer, 2048, f)) {
auto split = SplitString(buffer, '^');
auto e = BaseDataRepository::NewEntity();
for (const auto& line: Strings::Split(file_contents.contents, "\n")) {
const auto& line_data = Strings::Split(line, '^');
if (line_data.size() < 10) {
if(split.size() < 10) {
continue;
}
e.level = static_cast<uint8_t>(Strings::ToUnsignedInt(line_data[0]));
e.class_ = static_cast<uint8_t>(Strings::ToUnsignedInt(line_data[1]));
e.hp = Strings::ToFloat(line_data[2]);
e.mana = Strings::ToFloat(line_data[3]);
e.end = Strings::ToFloat(line_data[4]);
e.hp_regen = Strings::ToFloat(line_data[5]);
e.end_regen = Strings::ToFloat(line_data[6]);
e.hp_fac = Strings::ToFloat(line_data[7]);
e.mana_fac = Strings::ToFloat(line_data[8]);
e.end_fac = Strings::ToFloat(line_data[9]);
std::string sql;
int level, class_id;
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
v.emplace_back(e);
level = atoi(split[0].c_str());
class_id = atoi(split[1].c_str());
hp = atof(split[2].c_str());
mana = atof(split[3].c_str());
end = atof(split[4].c_str());
unk1 = atof(split[5].c_str());
unk2 = atof(split[6].c_str());
hp_fac = atof(split[7].c_str());
mana_fac = atof(split[8].c_str());
end_fac = atof(split[9].c_str());
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
level, class_id, hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac);
db->QueryDatabase(sql);
}
BaseDataRepository::InsertMany(*db, v);
fclose(f);
}
void ImportDBStrings(SharedDatabase *db) {
LogInfo("Importing DB Strings");
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r");
FILE *f = fopen("import/dbstr_us.txt", "r");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
return;
}
@@ -330,7 +287,7 @@ void ImportDBStrings(SharedDatabase *db) {
}
}
auto split = Strings::Split(buffer, '^');
auto split = SplitString(buffer, '^');
if(split.size() < 2) {
continue;
@@ -339,12 +296,12 @@ void ImportDBStrings(SharedDatabase *db) {
std::string sql;
int id, type;
std::string value;
id = Strings::ToInt(split[0].c_str());
type = Strings::ToInt(split[1].c_str());
id = atoi(split[0].c_str());
type = atoi(split[1].c_str());
if(split.size() >= 3) {
value = ::Strings::Escape(split[2]);
value = ::EscapeString(split[2]);
}
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
+2 -2
View File
@@ -38,7 +38,7 @@ locations other than lua/
find_path(LUA_INCLUDE_DIR lua.h
HINTS
ENV LUA_DIR
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include/luajit include
PATHS
~/Library/Frameworks
/Library/Frameworks
@@ -49,7 +49,7 @@ find_path(LUA_INCLUDE_DIR lua.h
)
find_library(LUA_LIBRARY
NAMES lua51 lua5.1 lua-5.1 lua
NAMES lua51 lua5.1 lua-5.1 lua luajit
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
-91
View File
@@ -1,91 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# Modified from the FindLua51 that comes with CMake
#[=======================================================================[.rst:
FindLuaJit
---------
Locate LuaJit library This module defines
::
LUAJIT_FOUND, if false, do not try to link to Lua
LUAJIT_LIBRARIES
LUAJIT_INCLUDE_DIR, where to find lua.h
LUAJIT_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
Note that the expected include convention is
::
#include "lua.h"
and not
::
#include <lua/lua.h>
This is because, the lua location is not standardized and may exist in
locations other than lua/
#]=======================================================================]
find_path(LUAJIT_INCLUDE_DIR lua.h
HINTS
ENV LUA_DIR
PATH_SUFFIXES include/luajit include/luajit-2.0 include/luajit-2.1 include
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
find_library(LUAJIT_LIBRARY
NAMES luajit51 luajit5.1 luajit-5.1 luajit lua51
HINTS
ENV LUA_DIR
PATH_SUFFIXES lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
)
if(LUAJIT_LIBRARY)
# include the math library for Unix
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
find_library(LUAJIT_MATH_LIBRARY m)
set( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY};${LUAJIT_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
else()
set( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
endif()
endif()
if(LUAJIT_INCLUDE_DIR AND EXISTS "${LUAJIT_INCLUDE_DIR}/lua.h")
file(STRINGS "${LUAJIT_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUAJIT_VERSION_STRING "${lua_version_str}")
unset(lua_version_str)
endif()
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJit
REQUIRED_VARS LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR
VERSION_VAR LUAJIT_VERSION_STRING)
mark_as_advanced(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
+356 -817
View File
File diff suppressed because it is too large Load Diff
-147
View File
@@ -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
View File
@@ -0,0 +1,190 @@
/*
* Boost Software License - Version 1.0 - August 17th, 2003
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing.
#ifndef EQEMU_COMMON_ANY_H
#define EQEMU_COMMON_ANY_H
#include <algorithm>
#include <typeinfo>
namespace EQEmu
{
class Any
{
public:
Any()
: content(nullptr)
{
}
template<typename ValueType>
Any(const ValueType &value)
: content(new Holder<ValueType>(value))
{
}
Any(const Any &other)
: content(other.content ? other.content->clone() : 0)
{
}
~Any()
{
if(content)
delete content;
}
Any& swap(Any &rhs)
{
std::swap(content, rhs.content);
return *this;
}
template<typename ValueType>
Any& operator=(const ValueType &rhs)
{
Any(rhs).swap(*this);
return *this;
}
Any& operator=(Any rhs)
{
rhs.swap(*this);
return *this;
}
bool empty() const
{
return !content;
}
const std::type_info& type() const
{
return content ? content->type() : typeid(void);
}
class Placeholder
{
public:
virtual ~Placeholder()
{
}
virtual const std::type_info& type() const = 0;
virtual Placeholder* clone() const = 0;
};
template<typename ValueType>
class Holder : public Placeholder
{
public:
Holder(const ValueType &value)
: held(value)
{
}
virtual const std::type_info& type() const
{
return typeid(ValueType);
}
virtual Placeholder* clone() const
{
return new Holder(held);
}
ValueType held;
private:
Holder& operator=(const Holder&);
};
private:
template<typename ValueType>
friend ValueType* any_cast(Any*);
template<typename ValueType>
friend ValueType* unsafe_any_cast(Any*);
Placeholder* content;
};
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const throw()
{
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
}
};
template<typename ValueType>
ValueType* any_cast(Any* operand)
{
return operand &&
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
}
template<typename ValueType>
inline const ValueType* any_cast(const Any* operand)
{
return any_cast<ValueType>(const_cast<Any*>(operand));
}
template<typename ValueType>
ValueType any_cast(Any& operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
nonref* result = any_cast<nonref>(&operand);
if(!result)
throw bad_any_cast();
return *result;
}
template<typename ValueType>
inline ValueType any_cast(const Any& operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
return any_cast<const nonref&>(const_cast<Any&>(operand));
}
template<typename ValueType>
inline ValueType* unsafe_any_cast(Any* operand)
{
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
}
template<typename ValueType>
inline const ValueType* unsafe_any_cast(const Any* operand)
{
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
}
}
#endif
+34
View File
@@ -0,0 +1,34 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __EQEMU_COMMON_BASE_DATA_H
#define __EQEMU_COMMON_BASE_DATA_H
struct BaseDataStruct
{
double base_hp;
double base_mana;
double base_end;
double hp_regen;
double end_regen;
double hp_factor;
double mana_factor;
double endurance_factor;
};
#endif
+8 -8
View File
@@ -23,18 +23,18 @@
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
{
pBuffer=nullptr;
size=0;
_wpos = 0;
_rpos = 0;
timestamp.tv_sec = 0;
this->pBuffer=nullptr;
this->size=0;
this->_wpos = 0;
this->_rpos = 0;
this->timestamp.tv_sec = 0;
if (len>0) {
size=len;
this->size=len;
pBuffer= new unsigned char[len];
if (buf) {
memcpy(pBuffer,buf,len);
memcpy(this->pBuffer,buf,len);
} else {
memset(pBuffer,0,len);
memset(this->pBuffer,0,len);
}
}
}
-333
View File
@@ -1,333 +0,0 @@
#include "bazaar.h"
#include "../../common/item_instance.h"
#include "repositories/trader_repository.h"
#include <memory>
std::vector<BazaarSearchResultsFromDB_Struct>
Bazaar::GetSearchResults(
Database &db,
Database &content_db,
BazaarSearchCriteria_Struct search,
uint32 char_zone_id,
int32 char_zone_instance_id
)
{
LogTrading(
"Searching for items with search criteria - item_name [{}] min_cost [{}] max_cost [{}] min_level [{}] "
"max_level [{}] max_results [{}] prestige [{}] augment [{}] trader_entity_id [{}] trader_id [{}] "
"search_scope [{}] char_zone_id [{}], char_zone_instance_id [{}]",
search.item_name,
search.min_cost,
search.max_cost,
search.min_level,
search.max_level,
search.max_results,
search.prestige,
search.augment,
search.trader_entity_id,
search.trader_id,
search.search_scope,
char_zone_id,
char_zone_instance_id
);
static std::map<uint8, uint32> item_slot_searches_new = {
{EQ::invslot::slotCharm, 1},
{EQ::invslot::slotEar1, 2},
{EQ::invslot::slotHead, 4},
{EQ::invslot::slotFace, 8},
{EQ::invslot::slotEar2, 16},
{EQ::invslot::slotNeck, 32},
{EQ::invslot::slotShoulders, 64},
{EQ::invslot::slotArms, 128},
{EQ::invslot::slotBack, 256},
{EQ::invslot::slotWrist1, 512},
{EQ::invslot::slotWrist2, 1024},
{EQ::invslot::slotRange, 2048},
{EQ::invslot::slotHands, 4096},
{EQ::invslot::slotPrimary, 8192},
{EQ::invslot::slotSecondary, 16384},
{EQ::invslot::slotFinger1, 32768},
{EQ::invslot::slotFinger2, 65536},
{EQ::invslot::slotChest, 131072},
{EQ::invslot::slotLegs, 262144},
{EQ::invslot::slotFeet, 524288},
{EQ::invslot::slotWaist, 1048576},
{EQ::invslot::slotPowerSource, 2097152},
{EQ::invslot::slotAmmo, 4194304},
};
struct ItemSearchType {
EQ::item::ItemType type;
std::string condition;
};
std::vector<ItemSearchType> item_search_types_new = {
{EQ::item::ItemType::ItemTypeBook, " AND (items.itemclass = 2 or items.itemclass = 31)"},
{EQ::item::ItemType::ItemTypeContainer, " AND (items.itemclass = 1 or items.itemclass = 67)"},
{EQ::item::ItemType::ItemTypeAllEffects, " AND (items.scrolleffect > 0 && items.scrolleffect < 65000)"},
{EQ::item::ItemType::ItemTypeUnknown9, " AND items.worneffect = 998"},
{EQ::item::ItemType::ItemTypeUnknown10, " AND (items.worneffect >= 1298 && items.worneffect <= 1307)"},
{EQ::item::ItemType::ItemTypeFocusEffect, " AND items.focuseffect > 0"},
{EQ::item::ItemType::ItemTypeArmor, " AND items.itemtype = 10"},
{EQ::item::ItemType::ItemType1HBlunt, " AND items.itemtype = 3"},
{EQ::item::ItemType::ItemType1HPiercing, " AND items.itemtype = 2"},
{EQ::item::ItemType::ItemType1HSlash, " AND items.itemtype = 0"},
{EQ::item::ItemType::ItemType2HBlunt, " AND items.itemtype = 4"},
{EQ::item::ItemType::ItemType2HSlash, " AND items.itemtype = 1"},
{EQ::item::ItemType::ItemTypeBow, " AND items.itemtype = 5"},
{EQ::item::ItemType::ItemTypeShield, " AND items.itemtype = 8"},
{EQ::item::ItemType::ItemTypeMisc, " AND items.itemtype = 11"},
{EQ::item::ItemType::ItemTypeFood, " AND items.itemtype = 14"},
{EQ::item::ItemType::ItemTypeDrink, " AND items.itemtype = 15"},
{EQ::item::ItemType::ItemTypeLight, " AND items.itemtype = 16"},
{EQ::item::ItemType::ItemTypeCombinable, " AND items.itemtype = 17"},
{EQ::item::ItemType::ItemTypeBandage, " AND items.itemtype = 18"},
{EQ::item::ItemType::ItemTypeSmallThrowing, " AND (items.itemtype = 19 OR items.itemtype = 7)"},
{EQ::item::ItemType::ItemTypeSpell, " AND items.itemtype = 20"},
{EQ::item::ItemType::ItemTypePotion, " AND items.itemtype = 21"},
{EQ::item::ItemType::ItemTypeBrassInstrument, " AND items.itemtype = 25"},
{EQ::item::ItemType::ItemTypeWindInstrument, " AND items.itemtype = 23"},
{EQ::item::ItemType::ItemTypeStringedInstrument, " AND items.itemtype = 24"},
{EQ::item::ItemType::ItemTypePercussionInstrument, " AND items.itemtype = 26"},
{EQ::item::ItemType::ItemTypeArrow, " AND items.itemtype = 27"},
{EQ::item::ItemType::ItemTypeJewelry, " AND items.itemtype = 29"},
{EQ::item::ItemType::ItemTypeNote, " AND items.itemtype = 32"},
{EQ::item::ItemType::ItemTypeKey, " AND items.itemtype = 33"},
{EQ::item::ItemType::ItemType2HPiercing, " AND items.itemtype = 35"},
{EQ::item::ItemType::ItemTypeAlcohol, " AND items.itemtype = 38"},
{EQ::item::ItemType::ItemTypeMartial, " AND items.itemtype = 45"},
{EQ::item::ItemType::ItemTypeAugmentation, " AND items.itemtype = 54"},
{EQ::item::ItemType::ItemTypeAlternateAbility, " AND items.itemtype = 57"},
{EQ::item::ItemType::ItemTypeCount, " AND items.itemtype = 65"},
{EQ::item::ItemType::ItemTypeCollectible, " AND items.itemtype = 66"}
};
// item stat searches
struct ItemStatSearch {
std::string query_string;
EQ::skills::SkillType skill_type;
};
std::map<uint32, ItemStatSearch> item_stat_searches_new = {
{STAT_AC, {" items.ac" , static_cast<EQ::skills::SkillType>(0)} },
{STAT_AGI, {" items.aagi", static_cast<EQ::skills::SkillType>(0)} },
{STAT_CHA, {" items.acha", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DEX, {" items.adex", static_cast<EQ::skills::SkillType>(0)} },
{STAT_INT, {" items.aint", static_cast<EQ::skills::SkillType>(0)} },
{STAT_STA, {" items.asta", static_cast<EQ::skills::SkillType>(0)} },
{STAT_STR, {" items.astr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_WIS, {" items.awis", static_cast<EQ::skills::SkillType>(0)} },
{STAT_COLD, {" items.cr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DISEASE, {" items.dr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_FIRE, {" items.fr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_MAGIC, {" items.mr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_POISON, {" items.pr", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HP, {" items.hp", static_cast<EQ::skills::SkillType>(0)} },
{STAT_MANA, {" items.mana", static_cast<EQ::skills::SkillType>(0)} },
{STAT_ENDURANCE, {" items.endur", static_cast<EQ::skills::SkillType>(0)} },
{STAT_ATTACK, {" items.attack", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HP_REGEN, {" items.regen", static_cast<EQ::skills::SkillType>(0)} },
{STAT_MANA_REGEN, {" items.manaregen", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HASTE, {" items.haste", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DAMAGE_SHIELD, {" items.damageshield", static_cast<EQ::skills::SkillType>(0)} },
{STAT_DS_MITIGATION, {" items.dsmitigation", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEAL_AMOUNT, {" items.healamt", static_cast<EQ::skills::SkillType>(0)} },
{STAT_SPELL_DAMAGE, {" items.spelldmg", static_cast<EQ::skills::SkillType>(0)} },
{STAT_CLAIRVOYANCE, {" items.clairvoyance", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_AGILITY, {" items.heroic_agi", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_CHARISMA, {" items.heroic_cha", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_DEXTERITY, {" items.heroic_dex", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_INTELLIGENCE, {" items.heroic_int", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_STAMINA, {" items.heroic_sta", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_STRENGTH, {" items.heroic_str", static_cast<EQ::skills::SkillType>(0)} },
{STAT_HEROIC_WISDOM, {" items.heroic_wis", static_cast<EQ::skills::SkillType>(0)} },
{STAT_BASH, {" items.skillmodvalue", EQ::skills::SkillBash} },
{STAT_BACKSTAB, {" items.backstabdmg", EQ::skills::SkillBackstab} },
{STAT_DRAGON_PUNCH, {" items.skillmodvalue", EQ::skills::SkillDragonPunch} },
{STAT_EAGLE_STRIKE, {" items.skillmodvalue", EQ::skills::SkillEagleStrike} },
{STAT_FLYING_KICK, {" items.skillmodvalue", EQ::skills::SkillFlyingKick} },
{STAT_KICK, {" items.skillmodvalue", EQ::skills::SkillKick} },
{STAT_ROUND_KICK, {" items.skillmodvalue", EQ::skills::SkillRoundKick} },
{STAT_TIGER_CLAW, {" items.skillmodvalue", EQ::skills::SkillTigerClaw} },
{STAT_FRENZY, {" items.skillmodvalue", EQ::skills::SkillFrenzy} },
};
bool convert = false;
std::string search_criteria_trader("TRUE");
std::string field_criteria_items("FALSE");
std::string where_criteria_items(" TRUE ");
if (search.search_scope == NonRoFBazaarSearchScope) {
search_criteria_trader.append(
fmt::format(
" AND trader.char_entity_id = {} AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
search.trader_entity_id,
Zones::BAZAAR,
char_zone_instance_id
)
);
}
else if (search.search_scope == Local_Scope) {
search_criteria_trader.append(fmt::format(
" AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
char_zone_id,
char_zone_instance_id)
);
}
else if (search.trader_id > 0) {
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
if (search.trader_id >= TraderRepository::TRADER_CONVERT_ID) {
convert = true;
search_criteria_trader.append(fmt::format(
" AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
Zones::BAZAAR,
search.trader_id - TraderRepository::TRADER_CONVERT_ID)
);
}
else {
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
}
}
else {
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
}
}
if (search.min_cost != 0) {
search_criteria_trader.append(fmt::format(" AND trader.item_cost >= {}", search.min_cost * 1000));
}
if (search.max_cost != 0) {
search_criteria_trader.append(fmt::format(" AND trader.item_cost <= {}", (uint64) search.max_cost * 1000));
}
if (search.slot != std::numeric_limits<uint32>::max()) {
if (item_slot_searches_new.contains(search.slot)) {
where_criteria_items.append(
fmt::format(" AND items.slots & {0} = {0}", item_slot_searches_new[search.slot]));
}
}
if (search.type != std::numeric_limits<uint32>::max()) {
for (auto const &[type, condition]: item_search_types_new) {
if (type == search.type) {
where_criteria_items.append(condition);
break;
}
}
}
if (search.race != std::numeric_limits<uint32>::max()) {
where_criteria_items.append(
fmt::format(" AND items.races & {0} = {0}", GetPlayerRaceBit(GetRaceIDFromPlayerRaceValue(search.race))));
}
if (search._class != std::numeric_limits<uint32>::max()) {
where_criteria_items.append(fmt::format(" AND items.classes & {0} = {0}", GetPlayerClassBit(search._class)));
}
if (search.item_stat != std::numeric_limits<uint32>::max()) {
if (item_stat_searches_new.contains(search.item_stat)) {
field_criteria_items = fmt::format("{}", item_stat_searches_new[search.item_stat].query_string);
if (item_stat_searches_new[search.item_stat].skill_type) {
where_criteria_items.append(
fmt::format(" AND items.skillmodtype = {} ", item_stat_searches_new[search.item_stat].skill_type));
}
else {
where_criteria_items.append(
fmt::format(" AND {} > 0 ", item_stat_searches_new[search.item_stat].query_string));
}
}
}
if (search.augment) {
where_criteria_items.append(fmt::format(
" AND (items.augslot1type = {0} OR "
"items.augslot2type = {0} OR "
"items.augslot3type = {0} OR "
"items.augslot4type = {0} OR "
"items.augslot5type = {0} OR "
"items.augslot6type = {0})",
search.augment)
);
}
if (search.min_level != 1) {
where_criteria_items.append(fmt::format(" AND items.reclevel >= {}", search.min_level));
}
if (search.max_level != 100) {
where_criteria_items.append(fmt::format(" AND items.reclevel <= {}", search.max_level));
}
std::vector<BazaarSearchResultsFromDB_Struct> all_entries;
std::vector<std::string> trader_items_ids{};
auto const trader_results = TraderRepository::GetBazaarTraderDetails(db, search_criteria_trader);
if (trader_results.empty()) {
LogTradingDetail("Bazaar - No traders found in bazaar search.");
return all_entries;
}
for (auto const &i: trader_results) {
trader_items_ids.push_back(std::to_string(i.trader.item_id));
}
auto const item_results = ItemsRepository::GetItemsForBazaarSearch(
content_db,
trader_items_ids,
std::string(search.item_name),
field_criteria_items,
where_criteria_items
);
if (item_results.empty()) {
LogTradingDetail("Bazaar - No items found in bazaar search.");
return all_entries;
}
all_entries.reserve(trader_results.size());
for (auto const& t:trader_results) {
if (!item_results.contains(t.trader.item_id)) {
continue;
}
BazaarSearchResultsFromDB_Struct r{};
r.count = 1;
r.trader_id = t.trader.char_id;
r.serial_number = t.trader.item_sn;
r.cost = t.trader.item_cost;
r.slot_id = t.trader.slot_id;
r.charges = t.trader.item_charges;
r.stackable = item_results.at(t.trader.item_id).stackable;
r.icon_id = item_results.at(t.trader.item_id).icon;
r.trader_zone_id = t.trader.char_zone_id;
r.trader_zone_instance_id = t.trader.char_zone_instance_id;
r.trader_entity_id = t.trader.char_entity_id;
r.serial_number_RoF = fmt::format("{:016}\0", t.trader.item_sn);
r.item_name = fmt::format("{:.63}\0", item_results.at(t.trader.item_id).name);
r.trader_name = fmt::format("{:.63}\0", t.trader_name);
r.item_stat = item_results.at(t.trader.item_id).stats;
if (RuleB(Bazaar, UseAlternateBazaarSearch)) {
if (convert ||
char_zone_id != Zones::BAZAAR ||
(char_zone_id == Zones::BAZAAR && r.trader_zone_instance_id != char_zone_instance_id)
) {
r.trader_id = TraderRepository::TRADER_CONVERT_ID + r.trader_zone_instance_id;
}
}
all_entries.push_back(r);
}
if (all_entries.size() > search.max_results) {
all_entries.resize(search.max_results);
}
LogTrading("Returning [{}] items from search results", all_entries.size());
return all_entries;
}
-16
View File
@@ -1,16 +0,0 @@
#ifndef EQEMU_BAZAAR_H
#define EQEMU_BAZAAR_H
#include <vector>
#include "shareddb.h"
#include "../../common/item_instance.h"
class Bazaar {
public:
static std::vector<BazaarSearchResultsFromDB_Struct>
GetSearchResults(Database &content_db, Database &db, BazaarSearchCriteria_Struct search, unsigned int char_zone_id, int char_zone_instance_id);
};
#endif //EQEMU_BAZAAR_H
-12
View File
@@ -1,12 +0,0 @@
#include "../common/global_define.h"
#include "../common/bodytypes.h"
std::string BodyType::GetName(uint8 body_type_id)
{
return IsValid(body_type_id) ? body_type_names[body_type_id] : "UNKNOWN BODY TYPE";
}
bool BodyType::IsValid(uint8 body_type_id)
{
return body_type_names.find(body_type_id) != body_type_names.end();
}
+43 -91
View File
@@ -18,96 +18,48 @@
#ifndef BODYTYPES_H
#define BODYTYPES_H
#include "types.h"
#include <map>
#include <string>
// body types above 64 make the mob invisible
namespace BodyType {
constexpr uint8 Humanoid = 1;
constexpr uint8 Lycanthrope = 2;
constexpr uint8 Undead = 3;
constexpr uint8 Giant = 4;
constexpr uint8 Construct = 5;
constexpr uint8 Extraplanar = 6;
constexpr uint8 Magical = 7; // this name might be a bit off,
constexpr uint8 SummonedUndead = 8;
constexpr uint8 RaidGiant = 9; // Velious era Raid Giant
constexpr uint8 RaidColdain = 10; // Velious era Raid Coldain
constexpr uint8 NoTarget = 11; // no name, can't target this bodytype
constexpr uint8 Vampire = 12;
constexpr uint8 AtenHaRa = 13;
constexpr uint8 GreaterAkheva = 14;
constexpr uint8 KhatiSha = 15;
constexpr uint8 Seru = 16;
constexpr uint8 GriegVeneficus = 17;
constexpr uint8 DrazNurakk = 18;
constexpr uint8 Zek = 19; //"creatures from the Plane of War."
constexpr uint8 Luggald = 20;
constexpr uint8 Animal = 21;
constexpr uint8 Insect = 22;
constexpr uint8 Monster = 23;
constexpr uint8 Summoned = 24; // Elemental?
constexpr uint8 Plant = 25;
constexpr uint8 Dragon = 26;
constexpr uint8 Summoned2 = 27;
constexpr uint8 Summoned3 = 28;
constexpr uint8 Dragon2 = 29; // database data indicates this is a dragon type (Kunark and DoN?)
constexpr uint8 VeliousDragon = 30; // might not be a tight set
constexpr uint8 Familiar = 31;
constexpr uint8 Dragon3 = 32;
constexpr uint8 Boxes = 33;
constexpr uint8 Muramite = 34; // tribal dudes
constexpr uint8 NoTarget2 = 60;
constexpr uint8 SwarmPet = 63; // Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
constexpr uint8 MonsterSummon = 64;
constexpr uint8 InvisibleMan = 66; // no name, seen on 'InvisMan', can be /targeted
constexpr uint8 Special = 67;
std::string GetName(uint8 body_type_id);
bool IsValid(uint8 body_type_id);
}
static std::map<uint8, std::string> body_type_names = {
{ BodyType::Humanoid, "Humanoid" },
{ BodyType::Lycanthrope, "Lycanthrope" },
{ BodyType::Undead, "Undead" },
{ BodyType::Giant, "Giant" },
{ BodyType::Construct, "Construct" },
{ BodyType::Extraplanar, "Extraplanar" },
{ BodyType::Magical, "Magical" },
{ BodyType::SummonedUndead, "Summoned Undead" },
{ BodyType::RaidGiant, "Raid Giant" },
{ BodyType::RaidColdain, "Raid Coldain" },
{ BodyType::NoTarget, "Untargetable" },
{ BodyType::Vampire, "Vampire" },
{ BodyType::AtenHaRa, "Aten Ha Ra" },
{ BodyType::GreaterAkheva, "Greater Akheva" },
{ BodyType::KhatiSha, "Khati Sha" },
{ BodyType::Seru, "Seru" },
{ BodyType::GriegVeneficus, "Grieg Veneficus" },
{ BodyType::DrazNurakk, "Draz Nurakk" },
{ BodyType::Zek, "Zek" },
{ BodyType::Luggald, "Luggald" },
{ BodyType::Animal, "Animal" },
{ BodyType::Insect, "Insect" },
{ BodyType::Monster, "Monster" },
{ BodyType::Summoned, "Summoned" },
{ BodyType::Plant, "Plant" },
{ BodyType::Dragon, "Dragon" },
{ BodyType::Summoned2, "Summoned 2" },
{ BodyType::Summoned3, "Summoned 3" },
{ BodyType::Dragon2, "Dragon 2" },
{ BodyType::VeliousDragon, "Velious Dragon" },
{ BodyType::Familiar, "Familiar" },
{ BodyType::Dragon3, "Dragon 3" },
{ BodyType::Boxes, "Boxes" },
{ BodyType::Muramite, "Muramite" },
{ BodyType::NoTarget2, "Untargetable 2" },
{ BodyType::SwarmPet, "Swarm Pet" },
{ BodyType::MonsterSummon, "Monster Summon" },
{ BodyType::InvisibleMan, "Invisible Man" },
{ BodyType::Special, "Special" },
};
typedef enum {
BT_Humanoid = 1,
BT_Lycanthrope = 2,
BT_Undead = 3,
BT_Giant = 4,
BT_Construct = 5,
BT_Extraplanar = 6,
BT_Magical = 7, //this name might be a bit off,
BT_SummonedUndead = 8,
BT_RaidGiant = 9,
// ...
BT_NoTarget = 11, //no name, can't target this bodytype
BT_Vampire = 12,
BT_Atenha_Ra = 13,
BT_Greater_Akheva = 14,
BT_Khati_Sha = 15,
BT_Seru = 16, //not confirmed....
BT_Draz_Nurakk = 18,
BT_Zek = 19,
BT_Luggald = 20,
BT_Animal = 21,
BT_Insect = 22,
BT_Monster = 23,
BT_Summoned = 24, //Elemental?
BT_Plant = 25,
BT_Dragon = 26,
BT_Summoned2 = 27,
BT_Summoned3 = 28,
//29
BT_VeliousDragon = 30, //might not be a tight set
// ...
BT_Dragon3 = 32,
BT_Boxes = 33,
BT_Muramite = 34, //tribal dudes
// ...
BT_NoTarget2 = 60,
// ...
BT_SwarmPet = 63, //is this valid, or made up?
// ...
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
BT_Special = 67
} bodyType;
/* bodytypes above 64 make the mob not show up */
#endif
+441 -356
View File
File diff suppressed because it is too large Load Diff
+92 -103
View File
@@ -19,106 +19,97 @@
#define CLASSES_CH
#include "../common/types.h"
#include "../common/rulesys.h"
#include <string>
#include <map>
namespace Class {
constexpr uint8 None = 0;
constexpr uint8 Warrior = 1;
constexpr uint8 Cleric = 2;
constexpr uint8 Paladin = 3;
constexpr uint8 Ranger = 4;
constexpr uint8 ShadowKnight = 5;
constexpr uint8 Druid = 6;
constexpr uint8 Monk = 7;
constexpr uint8 Bard = 8;
constexpr uint8 Rogue = 9;
constexpr uint8 Shaman = 10;
constexpr uint8 Necromancer = 11;
constexpr uint8 Wizard = 12;
constexpr uint8 Magician = 13;
constexpr uint8 Enchanter = 14;
constexpr uint8 Beastlord = 15;
constexpr uint8 Berserker = 16;
constexpr uint8 WarriorGM = 20;
constexpr uint8 ClericGM = 21;
constexpr uint8 PaladinGM = 22;
constexpr uint8 RangerGM = 23;
constexpr uint8 ShadowKnightGM = 24;
constexpr uint8 DruidGM = 25;
constexpr uint8 MonkGM = 26;
constexpr uint8 BardGM = 27;
constexpr uint8 RogueGM = 28;
constexpr uint8 ShamanGM = 29;
constexpr uint8 NecromancerGM = 30;
constexpr uint8 WizardGM = 31;
constexpr uint8 MagicianGM = 32;
constexpr uint8 EnchanterGM = 33;
constexpr uint8 BeastlordGM = 34;
constexpr uint8 BerserkerGM = 35;
constexpr uint8 Banker = 40;
constexpr uint8 Merchant = 41;
constexpr uint8 DiscordMerchant = 59;
constexpr uint8 AdventureRecruiter = 60;
constexpr uint8 AdventureMerchant = 61;
constexpr uint8 LDoNTreasure = 62;
constexpr uint8 TributeMaster = 63;
constexpr uint8 GuildTributeMaster = 64;
constexpr uint8 GuildBanker = 66;
constexpr uint8 NorrathsKeepersMerchant = 67;
constexpr uint8 DarkReignMerchant = 68;
constexpr uint8 FellowshipMaster = 69;
constexpr uint8 AlternateCurrencyMerchant = 70;
constexpr uint8 MercenaryLiaison = 71;
#define WARRIOR 1
#define CLERIC 2
#define PALADIN 3
#define RANGER 4
#define SHADOWKNIGHT 5
#define DRUID 6
#define MONK 7
#define BARD 8
#define ROGUE 9
#define SHAMAN 10
#define NECROMANCER 11
#define WIZARD 12
#define MAGICIAN 13
#define ENCHANTER 14
#define BEASTLORD 15
#define BERSERKER 16
#define WARRIORGM 20
#define CLERICGM 21
#define PALADINGM 22
#define RANGERGM 23
#define SHADOWKNIGHTGM 24
#define DRUIDGM 25
#define MONKGM 26
#define BARDGM 27
#define ROGUEGM 28
#define SHAMANGM 29
#define NECROMANCERGM 30
#define WIZARDGM 31
#define MAGICIANGM 32
#define ENCHANTERGM 33
#define BEASTLORDGM 34
#define BERSERKERGM 35
#define BANKER 40
#define MERCHANT 41
#define DISCORD_MERCHANT 59
#define ADVENTURERECRUITER 60
#define ADVENTUREMERCHANT 61
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
#define TRIBUTE_MASTER 63
#define GUILD_TRIBUTE_MASTER 64 // not sure
#define NORRATHS_KEEPERS_MERCHANT 67
#define DARK_REIGN_MERCHANT 68
#define FELLOWSHIP_MASTER 69
#define ALT_CURRENCY_MERCHANT 70
#define MERCERNARY_MASTER 71
constexpr uint8 PLAYER_CLASS_COUNT = 16;
constexpr uint16 ALL_CLASSES_BITMASK = 65535;
};
static std::map<uint8, uint16> player_class_bitmasks = {
{Class::Warrior, 1},
{Class::Cleric, 2},
{Class::Paladin, 4},
{Class::Ranger, 8},
{Class::ShadowKnight, 16},
{Class::Druid, 32},
{Class::Monk, 64},
{Class::Bard, 128},
{Class::Rogue, 256},
{Class::Shaman, 512},
{Class::Necromancer, 1024},
{Class::Wizard, 2048},
{Class::Magician, 4096},
{Class::Enchanter, 8192},
{Class::Beastlord, 16384},
{Class::Berserker, 32768},
};
// player class values
#define PLAYER_CLASS_UNKNOWN 0
#define PLAYER_CLASS_WARRIOR 1
#define PLAYER_CLASS_CLERIC 2
#define PLAYER_CLASS_PALADIN 3
#define PLAYER_CLASS_RANGER 4
#define PLAYER_CLASS_SHADOWKNIGHT 5
#define PLAYER_CLASS_DRUID 6
#define PLAYER_CLASS_MONK 7
#define PLAYER_CLASS_BARD 8
#define PLAYER_CLASS_ROGUE 9
#define PLAYER_CLASS_SHAMAN 10
#define PLAYER_CLASS_NECROMANCER 11
#define PLAYER_CLASS_WIZARD 12
#define PLAYER_CLASS_MAGICIAN 13
#define PLAYER_CLASS_ENCHANTER 14
#define PLAYER_CLASS_BEASTLORD 15
#define PLAYER_CLASS_BERSERKER 16
static std::string shadow_knight_class_name = (
RuleB(World, UseOldShadowKnightClassExport) ?
"Shadowknight" :
"Shadow Knight"
);
#define PLAYER_CLASS_COUNT 16
static std::map<uint8, std::string> class_names = {
{Class::Warrior, "Warrior"},
{Class::Cleric, "Cleric"},
{Class::Paladin, "Paladin"},
{Class::Ranger, "Ranger"},
{Class::ShadowKnight, shadow_knight_class_name},
{Class::Druid, "Druid"},
{Class::Monk, "Monk"},
{Class::Bard, "Bard"},
{Class::Rogue, "Rogue"},
{Class::Shaman, "Shaman"},
{Class::Necromancer, "Necromancer"},
{Class::Wizard, "Wizard"},
{Class::Magician, "Magician"},
{Class::Enchanter, "Enchanter"},
{Class::Beastlord, "Beastlord"},
{Class::Berserker, "Berserker"},
};
// player class bits
#define PLAYER_CLASS_UNKNOWN_BIT 0
#define PLAYER_CLASS_WARRIOR_BIT 1
#define PLAYER_CLASS_CLERIC_BIT 2
#define PLAYER_CLASS_PALADIN_BIT 4
#define PLAYER_CLASS_RANGER_BIT 8
#define PLAYER_CLASS_SHADOWKNIGHT_BIT 16
#define PLAYER_CLASS_DRUID_BIT 32
#define PLAYER_CLASS_MONK_BIT 64
#define PLAYER_CLASS_BARD_BIT 128
#define PLAYER_CLASS_ROGUE_BIT 256
#define PLAYER_CLASS_SHAMAN_BIT 512
#define PLAYER_CLASS_NECROMANCER_BIT 1024
#define PLAYER_CLASS_WIZARD_BIT 2048
#define PLAYER_CLASS_MAGICIAN_BIT 4096
#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
@@ -131,16 +122,15 @@ static std::map<uint8, std::string> class_names = {
#define ARMOR_TYPE_LAST ARMOR_TYPE_PLATE
#define ARMOR_TYPE_COUNT 5
#define BOT_CLASS_BASE_ID_PREFIX 3000
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
bool IsPlayerClass(uint8 class_id);
const std::string GetPlayerClassAbbreviation(uint8 class_id);
uint32 GetPlayerClassValue(uint8 class_id);
uint32 GetPlayerClassBit(uint8 class_id);
uint8 GetPlayerClassValue(uint8 class_id);
uint16 GetPlayerClassBit(uint8 class_id);
uint8 GetClassIDFromPlayerClassValue(uint32 player_class_value);
uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
bool IsFighterClass(uint8 class_id);
bool IsSpellFighterClass(uint8 class_id);
@@ -149,8 +139,7 @@ bool IsHybridClass(uint8 class_id);
bool IsCasterClass(uint8 class_id);
bool IsINTCasterClass(uint8 class_id);
bool IsWISCasterClass(uint8 class_id);
bool IsHeroicINTCasterClass(uint8 class_id);
bool IsHeroicWISCasterClass(uint8 class_id);
bool IsPlateClass(uint8 class_id);
bool IsChainClass(uint8 class_id);
bool IsLeatherClass(uint8 class_id);
+35 -33
View File
@@ -21,7 +21,6 @@
#include <fmt/format.h>
#include "eqemu_command_handler.h"
#include "terminal_color.hpp"
#include "../platform.h"
namespace EQEmuCommand {
@@ -39,15 +38,15 @@ namespace EQEmuCommand {
{
if (cmd[{"-d", "--debug"}]) {
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 << "\nFlags:\n";
for (auto &flag: cmd.flags())
for (auto &flag : cmd.flags())
std::cout << '\t' << flag << std::endl;
std::cout << "\nParameters:\n";
for (auto &param: cmd.params())
for (auto &param : cmd.params())
std::cout << '\t' << param.first << " : " << param.second << std::endl;
}
}
@@ -69,22 +68,22 @@ namespace EQEmuCommand {
{
bool arguments_filled = true;
int index = 2;
for (auto &arg: arguments) {
int index = 2;
for (auto &arg : arguments) {
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
arguments_filled = false;
}
index++;
}
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
if (!arguments_filled || argc == 2) {
std::string arguments_string;
for (auto &arg: arguments) {
for (auto &arg : arguments) {
arguments_string += " " + arg;
}
std::string options_string;
for (auto &opt: options) {
for (auto &opt : options) {
options_string += " " + opt + "\n";
}
@@ -96,12 +95,12 @@ namespace EQEmuCommand {
"\nCommand" <<
termcolor::reset << "\n\n" <<
termcolor::green << argv[1] << arguments_string << termcolor::reset << "\n" <<
termcolor::yellow << (!options_string.empty() ? "\nOptions\n\n" : "") <<
termcolor::yellow << (!options_string.empty() ? "\nOptions\n" : "") <<
termcolor::reset << termcolor::cyan << options_string << termcolor::reset;
std::cout << command_string.str() << std::endl;
exit(0);
exit(1);
}
}
@@ -119,22 +118,33 @@ namespace EQEmuCommand {
std::string &description
)> &in_function_map,
argh::parser &cmd,
const std::string& platform,
int argc,
char **argv
)
{
std::string description;
bool ran_command = false;
for (auto &it: in_function_map) {
if (it.first == argv[1]) {
(it.second)(argc, argv, cmd, description);
ran_command = true;
}
}
if (cmd[{"-h", "--help"}]) {
std::cout << std::endl;
std::cout <<
"> " <<
termcolor::yellow <<
"EQEmulator [" + GetPlatformName() + "] CLI Menu" <<
"EQEmulator [" + platform + "] CLI Menu" <<
termcolor::reset
<< std::endl
<< std::endl;
// Get max command length for padding length
/**
* Get max command length for padding length
*/
int max_command_length = 0;
for (auto &it: in_function_map) {
@@ -145,26 +155,27 @@ namespace EQEmuCommand {
}
}
// Display command menu
/**
* Display command menu
*/
std::string command_section;
for (auto &it: in_function_map) {
description.clear();
description = "";
(it.second)(argc, argv, cmd, description);
// Print section header
/**
* Print section header
*/
std::string command_prefix = it.first.substr(0, it.first.find(":"));
if (command_prefix.find("test") != std::string::npos) {
continue;
}
if (command_section != command_prefix) {
command_section = command_prefix;
std::cout << termcolor::reset << command_prefix << std::endl;
}
// Print commands
/**
* Print commands
*/
std::stringstream command;
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
@@ -172,20 +183,11 @@ namespace EQEmuCommand {
std::cout << std::endl;
std::exit(0);
}
bool ran_command = false;
for (auto &it: in_function_map) {
if (it.first == argv[1]) {
(it.second)(argc, argv, cmd, description);
ran_command = true;
}
std::exit(1);
}
if (ran_command) {
std::exit(0);
std::exit(1);
}
}
+1
View File
@@ -66,6 +66,7 @@ namespace EQEmuCommand {
std::string &description
)> &in_function_map,
argh::parser &cmd,
const std::string &platform,
int argc,
char **argv
);
+1 -1
View File
@@ -3,7 +3,7 @@
#include <string.h>
#include <zlib.h>
namespace EQ
namespace EQEmu
{
uint32 EstimateDeflateBuffer(uint32 len) {
z_stream zstream;
+1 -1
View File
@@ -1,6 +1,6 @@
#pragma once
namespace EQ
namespace EQEmu
{
uint32 EstimateDeflateBuffer(uint32 len);
uint32 DeflateData(const char *buffer, uint32 len, char *out_buffer, uint32 out_len_max);
-349
View File
@@ -1,349 +0,0 @@
#include "world_content_service.h"
#include <utility>
#include <glm/vec3.hpp>
#include "../database.h"
#include "../rulesys.h"
#include "../eqemu_logsys.h"
#include "../repositories/instance_list_repository.h"
#include "../zone_store.h"
WorldContentService::WorldContentService()
{
SetCurrentExpansion(Expansion::EXPANSION_ALL);
}
int WorldContentService::GetCurrentExpansion() const
{
return current_expansion;
}
WorldContentService *WorldContentService::SetExpansionContext()
{
// do a rule manager reload until where we store expansion is changed to somewhere else
RuleManager::Instance()->LoadRules(GetDatabase(), "default", true);
// pull expansion from rules
int expansion = RuleI(Expansion, CurrentExpansion);
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
content_service.SetCurrentExpansion(expansion);
}
LogInfo(
"Current expansion is [{}] ({})",
GetCurrentExpansion(),
GetCurrentExpansionName()
);
return this;
}
std::string WorldContentService::GetCurrentExpansionName()
{
if (content_service.GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
return "All Expansions";
}
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
return Expansion::ExpansionName[content_service.GetCurrentExpansion()];
}
return "Unknown Expansion";
}
/**
* @param current_expansion
*/
void WorldContentService::SetCurrentExpansion(int current_expansion)
{
WorldContentService::current_expansion = current_expansion;
}
/**
* @return
*/
const std::vector<ContentFlagsRepository::ContentFlags> &WorldContentService::GetContentFlags() const
{
return content_flags;
}
/**
* @return
*/
std::vector<std::string> WorldContentService::GetContentFlagsEnabled()
{
std::vector<std::string> enabled_flags;
for (auto &f: GetContentFlags()) {
if (f.enabled) {
enabled_flags.emplace_back(f.flag_name);
}
}
return enabled_flags;
}
/**
* @return
*/
std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
{
std::vector<std::string> disabled_flags;
for (auto &f: GetContentFlags()) {
if (!f.enabled) {
disabled_flags.emplace_back(f.flag_name);
}
}
return disabled_flags;
}
/**
* @param content_flags
*/
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags> &content_flags)
{
WorldContentService::content_flags = content_flags;
}
/**
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
{
for (auto &f: GetContentFlags()) {
if (f.flag_name == content_flag && f.enabled == true) {
return true;
}
}
return false;
}
/**
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
{
for (auto &f: GetContentFlags()) {
if (f.flag_name == content_flag && f.enabled == false) {
return true;
}
}
return false;
}
bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
{
// if we're not set to (-1 All) then fail when we aren't within minimum expansion
if (f.min_expansion > Expansion::EXPANSION_ALL && current_expansion < f.min_expansion && current_expansion != -1) {
return false;
}
// if we're not set to (-1 All) then fail when we aren't within max expansion
if (f.max_expansion > Expansion::EXPANSION_ALL && current_expansion > f.max_expansion && current_expansion != -1) {
return false;
}
// if we don't have any enabled flag in enabled flags, we fail
for (const auto &flag: Strings::Split(f.content_flags)) {
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
return false;
}
}
// if we don't have any disabled flag in disabled flags, we fail
for (const auto &flag: Strings::Split(f.content_flags_disabled)) {
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
return false;
}
}
return true;
}
void WorldContentService::ReloadContentFlags()
{
std::vector<ContentFlagsRepository::ContentFlags> set_content_flags;
auto flags = ContentFlagsRepository::All(*GetDatabase());
set_content_flags.reserve(flags.size());
for (auto &f: flags) {
set_content_flags.push_back(f);
LogInfo(
"Loaded content flag [{}] [{}]",
f.flag_name,
(f.enabled ? "enabled" : "disabled")
);
}
SetContentFlags(set_content_flags);
LoadStaticGlobalZoneInstances();
zone_store.LoadZones(*m_content_database);
}
Database *WorldContentService::GetDatabase() const
{
return m_database;
}
WorldContentService *WorldContentService::SetDatabase(Database *database)
{
WorldContentService::m_database = database;
return this;
}
Database *WorldContentService::GetContentDatabase() const
{
return m_content_database;
}
WorldContentService *WorldContentService::SetContentDatabase(Database *database)
{
WorldContentService::m_content_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();
}
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
{
auto r = FindZone(zc->zoneID, zc->instanceID);
if (r.zone_id == 0) {
return;
}
zc->instanceID = r.instance.id;
}
// LoadStaticGlobalZoneInstances loads all static global zone instances
// these are zones that are never set to expire and are global
// these are used commonly in v1/v2/v3 versions of the same zone for expansion routing
WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
{
m_zone_static_instances = InstanceListRepository::GetWhere(
*GetDatabase(),
fmt::format("never_expires = 1 AND is_global = 1")
);
LogInfo("Loaded [{}] zone_instances", m_zone_static_instances.size());
return this;
}
// FindZone handles content and context aware zone routing (middleware)
//
// this is a middleware function that is meant to be used in the zone change process
// this hooks all core zone changes within the server and routes the player to the correct zone
// returning a zone_id of non-zero means the middleware will route the player
// returning a zone_id of 0 means the middleware will not route the player
// this is useful for handling multiple versions of the same zone
//
// implementation >
// the zoning and process spawning logic already is handled by two keys "zone_id" and "instance_id"
// we leverage static, never expires instances to handle this and client still sees it as a normal zone
//
// content awareness >
// simply use the zone_id, server content settings and the middleware will handle the rest
// you don't have to think about instances in any data tables (use instance_id 0)
// you don't have to keep track of instance ids in scripts (use instance_id 0)
// the versions of zones are represented by two zone entries that have potentially different min/max expansion and/or different content flags
// we decide to route the client to the correct version of the zone based on the current server side expansion
//
// example >
// we want to route players to the correct version of lavastorm based on the current server side expansion (DoesZonePassContentFiltering)
// lavastorm (pre-don) version 0 (classic)
// zone table entry for version = 0, min_expansion = 0, max_expansion = 8
// instance_list table entry for lavastorm has version = 0, is_global = 1, never_expires = 1
// lavastorm (don) version 1
// zone table entry for version = 1, min_expansion = 9, max_expansion = 99
// instance_list table entry for lavastorm has version = 1, is_global = 1, never_expires = 1
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
{
for (const auto &z: zone_store.GetZones()) {
for (auto &i: m_zone_static_instances) {
if (
z.zoneidnumber == zone_id &&
DoesZonePassContentFiltering(z) &&
i.zone == zone_id &&
i.version == z.version) {
if (instance_id > 0 && i.id != instance_id) {
continue;
}
LogInfo(
"Routed player to public static instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
i.id,
z.short_name,
z.zoneidnumber,
z.version,
z.long_name,
i.notes
);
return WorldContentService::FindZoneResult{
.zone_id = static_cast<uint32>(z.zoneidnumber),
.instance = i,
.zone = z
};
}
}
}
return WorldContentService::FindZoneResult{.zone_id = 0};
}
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
{
for (auto &i: m_zone_static_instances) {
if (i.id == instance_id) {
return true;
}
}
return false;
}
bool WorldContentService::DoesZonePassContentFiltering(const ZoneRepository::Zone &z)
{
auto f = ContentFlags{
.min_expansion = z.min_expansion,
.max_expansion = z.max_expansion,
.content_flags = z.content_flags,
.content_flags_disabled = z.content_flags_disabled
};
return DoesPassContentFiltering(f);
}
-199
View File
@@ -1,199 +0,0 @@
#ifndef EQEMU_WORLD_CONTENT_SERVICE_H
#define EQEMU_WORLD_CONTENT_SERVICE_H
#include <string>
#include <vector>
#include "../repositories/content_flags_repository.h"
#include "../repositories/zone_repository.h"
#include "../repositories/instance_list_repository.h"
class Database;
struct ContentFlags {
int16 min_expansion;
int16 max_expansion;
std::string content_flags;
std::string content_flags_disabled;
};
namespace Expansion {
static const int EXPANSION_ALL = -1;
static const int EXPANSION_FILTER_MAX = 99;
enum ExpansionNumber {
Classic = 0,
TheRuinsOfKunark,
TheScarsOfVelious,
TheShadowsOfLuclin,
ThePlanesOfPower,
TheLegacyOfYkesha,
LostDungeonsOfNorrath,
GatesOfDiscord,
OmensOfWar,
DragonsOfNorrath,
DepthsOfDarkhollow,
ProphecyOfRo,
TheSerpentsSpine,
TheBuriedSea,
SecretsOfFaydwer,
SeedsOfDestruction,
Underfoot,
HouseOfThule,
VeilOfAlaris,
RainOfFear,
CallOfTheForsaken,
TheDarkenedSea,
TheBrokenMirror,
EmpiresOfKunark,
RingOfScale,
TheBurningLands,
TormentOfVelious,
MaxId
};
/**
* If you add to this, make sure you update LogCategory
*/
static const char *ExpansionName[ExpansionNumber::MaxId] = {
"Classic",
"The Ruins of Kunark",
"The Scars of Velious",
"The Shadows of Luclin",
"The Planes of Power",
"The Legacy of Ykesha",
"Lost Dungeons of Norrath",
"Gates of Discord",
"Omens of War",
"Dragons of Norrath",
"Depths of Darkhollow",
"Prophecy of Ro",
"The Serpent's Spine",
"The Buried Sea",
"Secrets of Faydwer",
"Seeds of Destruction",
"Underfoot",
"House of Thule",
"Veil of Alaris",
"Rain of Fear",
"Call of the Forsaken",
"The Darkened Sea",
"The Broken Mirror",
"Empires of Kunark",
"Ring of Scale",
"The Burning Lands",
"Torment of Velious",
};
}
class WorldContentService {
public:
WorldContentService();
std::string GetCurrentExpansionName();
int GetCurrentExpansion() const;
void SetCurrentExpansion(int current_expansion);
bool IsClassicEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::Classic || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheRuinsOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheRuinsOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheScarsOfVeliousEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheScarsOfVelious || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheShadowsOfLuclinEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheShadowsOfLuclin || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsThePlanesOfPowerEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::ThePlanesOfPower || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheLegacyOfYkeshaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheLegacyOfYkesha || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsLostDungeonsOfNorrathEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::LostDungeonsOfNorrath || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsGatesOfDiscordEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::GatesOfDiscord || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsOmensOfWarEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::OmensOfWar || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsDragonsOfNorrathEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::DragonsOfNorrath || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsDepthsOfDarkhollowEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::DepthsOfDarkhollow || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsProphecyOfRoEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::ProphecyOfRo || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheSerpentsSpineEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheSerpentsSpine || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheBuriedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBuriedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsSecretsOfFaydwerEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::SecretsOfFaydwer || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsSeedsOfDestructionEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::SeedsOfDestruction || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsUnderfootEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::Underfoot || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsHouseOfThuleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::HouseOfThule || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheDarkenedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkenedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTheBurningLandsEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBurningLands || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsTormentOfVeliousEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TormentOfVelious || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
bool IsCurrentExpansionClassic() { return current_expansion == Expansion::ExpansionNumber::Classic; }
bool IsCurrentExpansionTheRuinsOfKunark() { return current_expansion == Expansion::ExpansionNumber::TheRuinsOfKunark; }
bool IsCurrentExpansionTheScarsOfVelious() { return current_expansion == Expansion::ExpansionNumber::TheScarsOfVelious; }
bool IsCurrentExpansionTheShadowsOfLuclin() { return current_expansion == Expansion::ExpansionNumber::TheShadowsOfLuclin; }
bool IsCurrentExpansionThePlanesOfPower() { return current_expansion == Expansion::ExpansionNumber::ThePlanesOfPower; }
bool IsCurrentExpansionTheLegacyOfYkesha() { return current_expansion == Expansion::ExpansionNumber::TheLegacyOfYkesha; }
bool IsCurrentExpansionLostDungeonsOfNorrath() { return current_expansion == Expansion::ExpansionNumber::LostDungeonsOfNorrath; }
bool IsCurrentExpansionGatesOfDiscord() { return current_expansion == Expansion::ExpansionNumber::GatesOfDiscord; }
bool IsCurrentExpansionOmensOfWar() { return current_expansion == Expansion::ExpansionNumber::OmensOfWar; }
bool IsCurrentExpansionDragonsOfNorrath() { return current_expansion == Expansion::ExpansionNumber::DragonsOfNorrath; }
bool IsCurrentExpansionDepthsOfDarkhollow() { return current_expansion == Expansion::ExpansionNumber::DepthsOfDarkhollow; }
bool IsCurrentExpansionProphecyOfRo() { return current_expansion == Expansion::ExpansionNumber::ProphecyOfRo; }
bool IsCurrentExpansionTheSerpentsSpine() { return current_expansion == Expansion::ExpansionNumber::TheSerpentsSpine; }
bool IsCurrentExpansionTheBuriedSea() { return current_expansion == Expansion::ExpansionNumber::TheBuriedSea; }
bool IsCurrentExpansionSecretsOfFaydwer() { return current_expansion == Expansion::ExpansionNumber::SecretsOfFaydwer; }
bool IsCurrentExpansionSeedsOfDestruction() { return current_expansion == Expansion::ExpansionNumber::SeedsOfDestruction; }
bool IsCurrentExpansionUnderfoot() { return current_expansion == Expansion::ExpansionNumber::Underfoot; }
bool IsCurrentExpansionHouseOfThule() { return current_expansion == Expansion::ExpansionNumber::HouseOfThule; }
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
bool IsCurrentExpansionTheDarkenedSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkenedSea; }
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
bool IsCurrentExpansionTormentOfVelious() { return current_expansion == Expansion::ExpansionNumber::TormentOfVelious; }
const std::vector<ContentFlagsRepository::ContentFlags> &GetContentFlags() const;
std::vector<std::string> GetContentFlagsEnabled();
std::vector<std::string> GetContentFlagsDisabled();
bool IsContentFlagEnabled(const std::string& content_flag);
bool IsContentFlagDisabled(const std::string& content_flag);
void SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags);
void ReloadContentFlags();
WorldContentService * SetExpansionContext();
bool DoesPassContentFiltering(const ContentFlags& f);
bool DoesZonePassContentFiltering(const ZoneRepository::Zone& z);
WorldContentService * SetDatabase(Database *database);
Database *GetDatabase() const;
WorldContentService * SetContentDatabase(Database *database);
Database *GetContentDatabase() const;
void SetContentFlag(const std::string &content_flag_name, bool enabled);
void HandleZoneRoutingMiddleware(ZoneChange_Struct *zc);
struct FindZoneResult {
uint32 zone_id = 0;
InstanceListRepository::InstanceList instance;
ZoneRepository::Zone zone;
};
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
bool IsInPublicStaticInstance(uint32 instance_id);
private:
int current_expansion{};
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
// reference to database
Database *m_database;
Database *m_content_database;
// holds a record of the zone table from the database
WorldContentService *LoadStaticGlobalZoneInstances();
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
};
extern WorldContentService content_service;
#endif //EQEMU_WORLD_CONTENT_SERVICE_H
+9 -149
View File
@@ -1,95 +1,6 @@
#include "global_define.h"
#include "eqemu_logsys.h"
#include "crash.h"
#include "strings.h"
#include "process/process.h"
#include "http/httplib.h"
#include "http/uri.h"
#include "json/json.h"
#include "version.h"
#include "eqemu_config.h"
#include "serverinfo.h"
#include "rulesys.h"
#include "platform.h"
#include <cstdio>
#include <vector>
#ifdef _WINDOWS
#define popen _popen
#endif
void SendCrashReport(const std::string &crash_report)
{
// can configure multiple endpoints if need be
std::vector<std::string> endpoints = {
"https://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)
#include "StackWalker.h"
@@ -101,30 +12,22 @@ public:
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
virtual void OnOutput(LPCSTR szText) {
char buffer[4096];
for (int i = 0; i < 4096; ++i) {
if (szText[i] == 0) {
for(int i = 0; i < 4096; ++i) {
if(szText[i] == 0) {
buffer[i] = '\0';
break;
}
if (szText[i] == '\n' || szText[i] == '\r') {
if(szText[i] == '\n' || szText[i] == '\r') {
buffer[i] = ' ';
}
else {
} else {
buffer[i] = szText[i];
}
}
std::string line = buffer;
_lines.push_back(line);
Log(Logs::General, Logs::Crash, buffer);
StackWalker::OnOutput(szText);
}
const std::vector<std::string>& GetLines() { return _lines; }
private:
std::vector<std::string> _lines;
};
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
@@ -198,20 +101,7 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
{
EQEmuStackWalker sw;
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
if (RuleB(Analytics, CrashReporting)) {
std::string crash_report;
auto& lines = sw.GetLines();
for (auto& line : lines) {
crash_report += line;
crash_report += "\n";
}
SendCrashReport(crash_report);
}
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
}
return EXCEPTION_EXECUTE_HANDLER;
@@ -228,34 +118,11 @@ void set_exception_handler() {
#include <unistd.h>
#include <sys/fcntl.h>
#ifdef __FreeBSD__
#include <signal.h>
#include <sys/stat.h>
#endif
void print_trace()
{
bool does_gdb_exist = Strings::Contains(Process::execute("gdb -v"), "GNU");
if (!does_gdb_exist) {
LogCrash(
"[Error] GDB is not installed, if you want crash dumps on Linux to work properly you will need GDB installed"
);
std::exit(1);
}
auto uid = geteuid();
auto uid = geteuid();
std::string temp_output_file = fmt::format("/tmp/dump-output-{}", Strings::Random(10));
// check for passwordless sudo if not root
if (uid != 0) {
bool sudo_password_required = Strings::Contains(Process::execute("sudo -n true"), "a password is required");
if (sudo_password_required) {
LogCrash(
"[Error] Current user does not have passwordless sudo installed. It is required to automatically process crash dumps with GDB as non-root."
);
std::exit(1);
}
}
std::string temp_output_file = "/tmp/dump-output";
char pid_buf[30];
sprintf(pid_buf, "%d", getpid());
@@ -264,6 +131,7 @@ void print_trace()
int child_pid = fork();
if (!child_pid) {
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
dup2(fd, 1); // redirect output to stderr
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
if (uid == 0) {
@@ -278,24 +146,16 @@ void print_trace()
abort(); /* If gdb failed to start */
}
else {
waitpid(child_pid, nullptr, 0);
waitpid(child_pid, NULL, 0);
}
std::ifstream input(temp_output_file);
std::string crash_report;
for (std::string line; getline(input, line);) {
LogCrash("{}", line);
crash_report += fmt::format("{}\n", line);
}
std::remove(temp_output_file.c_str());
if (RuleB(Analytics, CrashReporting)) {
SendCrashReport(crash_report);
}
LogSys.CloseFileLogs();
exit(1);
}
-876
View File
@@ -1,876 +0,0 @@
#pragma once
#include <vector>
#include <string>
#include <sstream>
#include <bitset>
#include <cctype>
#include <ctime>
#include <iomanip>
#include <algorithm>
#if __cplusplus > 201402L
#include <string_view>
#define CRONCPP_IS_CPP17
#endif
namespace cron
{
#ifdef CRONCPP_IS_CPP17
#define HAS_STRING_VIEW
#define STRING_VIEW std::string_view
#define STRING_VIEW_NPOS std::string_view::npos
#define CONSTEXPTR constexpr
#else
#define STRING_VIEW std::string const &
#define STRING_VIEW_NPOS std::string::npos
#define CONSTEXPTR
#endif
using cron_int = uint8_t;
constexpr std::time_t INVALID_TIME = static_cast<std::time_t>(-1);
constexpr size_t INVALID_CRON_INDEX = static_cast<size_t>(-1);
class cronexpr;
namespace detail
{
enum class cron_field
{
second,
minute,
hour_of_day,
day_of_week,
day_of_month,
month,
year
};
template <typename Traits>
static bool find_next(cronexpr const & cex,
std::tm& date,
size_t const dot);
}
struct bad_cronexpr : public std::runtime_error
{
public:
explicit bad_cronexpr(STRING_VIEW message) :
std::runtime_error(message.data())
{}
};
struct cron_standard_traits
{
static const cron_int CRON_MIN_SECONDS = 0;
static const cron_int CRON_MAX_SECONDS = 59;
static const cron_int CRON_MIN_MINUTES = 0;
static const cron_int CRON_MAX_MINUTES = 59;
static const cron_int CRON_MIN_HOURS = 0;
static const cron_int CRON_MAX_HOURS = 23;
static const cron_int CRON_MIN_DAYS_OF_WEEK = 0;
static const cron_int CRON_MAX_DAYS_OF_WEEK = 6;
static const cron_int CRON_MIN_DAYS_OF_MONTH = 1;
static const cron_int CRON_MAX_DAYS_OF_MONTH = 31;
static const cron_int CRON_MIN_MONTHS = 1;
static const cron_int CRON_MAX_MONTHS = 12;
static const cron_int CRON_MAX_YEARS_DIFF = 4;
#ifdef CRONCPP_IS_CPP17
static const inline std::vector<std::string> DAYS = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
static const inline std::vector<std::string> MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
#else
static std::vector<std::string>& DAYS()
{
static std::vector<std::string> days = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
return days;
}
static std::vector<std::string>& MONTHS()
{
static std::vector<std::string> months = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
return months;
}
#endif
};
struct cron_oracle_traits
{
static const cron_int CRON_MIN_SECONDS = 0;
static const cron_int CRON_MAX_SECONDS = 59;
static const cron_int CRON_MIN_MINUTES = 0;
static const cron_int CRON_MAX_MINUTES = 59;
static const cron_int CRON_MIN_HOURS = 0;
static const cron_int CRON_MAX_HOURS = 23;
static const cron_int CRON_MIN_DAYS_OF_WEEK = 1;
static const cron_int CRON_MAX_DAYS_OF_WEEK = 7;
static const cron_int CRON_MIN_DAYS_OF_MONTH = 1;
static const cron_int CRON_MAX_DAYS_OF_MONTH = 31;
static const cron_int CRON_MIN_MONTHS = 0;
static const cron_int CRON_MAX_MONTHS = 11;
static const cron_int CRON_MAX_YEARS_DIFF = 4;
#ifdef CRONCPP_IS_CPP17
static const inline std::vector<std::string> DAYS = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
static const inline std::vector<std::string> MONTHS = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
#else
static std::vector<std::string>& DAYS()
{
static std::vector<std::string> days = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
return days;
}
static std::vector<std::string>& MONTHS()
{
static std::vector<std::string> months = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
return months;
}
#endif
};
struct cron_quartz_traits
{
static const cron_int CRON_MIN_SECONDS = 0;
static const cron_int CRON_MAX_SECONDS = 59;
static const cron_int CRON_MIN_MINUTES = 0;
static const cron_int CRON_MAX_MINUTES = 59;
static const cron_int CRON_MIN_HOURS = 0;
static const cron_int CRON_MAX_HOURS = 23;
static const cron_int CRON_MIN_DAYS_OF_WEEK = 1;
static const cron_int CRON_MAX_DAYS_OF_WEEK = 7;
static const cron_int CRON_MIN_DAYS_OF_MONTH = 1;
static const cron_int CRON_MAX_DAYS_OF_MONTH = 31;
static const cron_int CRON_MIN_MONTHS = 1;
static const cron_int CRON_MAX_MONTHS = 12;
static const cron_int CRON_MAX_YEARS_DIFF = 4;
#ifdef CRONCPP_IS_CPP17
static const inline std::vector<std::string> DAYS = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
static const inline std::vector<std::string> MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
#else
static std::vector<std::string>& DAYS()
{
static std::vector<std::string> days = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
return days;
}
static std::vector<std::string>& MONTHS()
{
static std::vector<std::string> months = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
return months;
}
#endif
};
class cronexpr;
template <typename Traits = cron_standard_traits>
static cronexpr make_cron(STRING_VIEW expr);
class cronexpr
{
std::bitset<60> seconds;
std::bitset<60> minutes;
std::bitset<24> hours;
std::bitset<7> days_of_week;
std::bitset<31> days_of_month;
std::bitset<12> months;
friend bool operator==(cronexpr const & e1, cronexpr const & e2);
friend bool operator!=(cronexpr const & e1, cronexpr const & e2);
template <typename Traits>
friend bool detail::find_next(cronexpr const & cex,
std::tm& date,
size_t const dot);
friend std::string to_string(cronexpr const & cex);
template <typename Traits>
friend cronexpr make_cron(STRING_VIEW expr);
};
inline bool operator==(cronexpr const & e1, cronexpr const & e2)
{
return
e1.seconds == e2.seconds &&
e1.minutes == e2.minutes &&
e1.hours == e2.hours &&
e1.days_of_week == e2.days_of_week &&
e1.days_of_month == e2.days_of_month &&
e1.months == e2.months;
}
inline bool operator!=(cronexpr const & e1, cronexpr const & e2)
{
return !(e1 == e2);
}
inline std::string to_string(cronexpr const & cex)
{
return
cex.seconds.to_string() + " " +
cex.minutes.to_string() + " " +
cex.hours.to_string() + " " +
cex.days_of_month.to_string() + " " +
cex.months.to_string() + " " +
cex.days_of_week.to_string();
}
namespace utils
{
inline std::time_t tm_to_time(std::tm& date)
{
return std::mktime(&date);
}
inline std::tm* time_to_tm(std::time_t const * date, std::tm* const out)
{
#ifdef _WIN32
errno_t err = localtime_s(out, date);
return 0 == err ? out : nullptr;
#else
return localtime_r(date, out);
#endif
}
inline std::tm to_tm(STRING_VIEW time)
{
std::istringstream str(time.data());
str.imbue(std::locale(setlocale(LC_ALL, nullptr)));
std::tm result;
str >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
if (str.fail()) throw std::runtime_error("Parsing date failed!");
result.tm_isdst = -1; // DST info not available
return result;
}
inline std::string to_string(std::tm const & tm)
{
std::ostringstream str;
str.imbue(std::locale(setlocale(LC_ALL, nullptr)));
str << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
if (str.fail()) throw std::runtime_error("Writing date failed!");
return str.str();
}
inline std::string to_upper(std::string text)
{
std::transform(std::begin(text), std::end(text),
std::begin(text), static_cast<int(*)(int)>(std::toupper));
return text;
}
static std::vector<std::string> split(STRING_VIEW text, char const delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(text.data());
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
CONSTEXPTR inline bool contains(STRING_VIEW text, char const ch) noexcept
{
return STRING_VIEW_NPOS != text.find_first_of(ch);
}
}
namespace detail
{
inline cron_int to_cron_int(STRING_VIEW text)
{
try
{
return static_cast<cron_int>(Strings::ToUnsignedInt(text.data()));
}
catch (std::exception const & ex)
{
throw bad_cronexpr(ex.what());
}
}
static std::string replace_ordinals(
std::string text,
std::vector<std::string> const & replacement)
{
for (size_t i = 0; i < replacement.size(); ++i)
{
auto pos = text.find(replacement[i]);
if (std::string::npos != pos)
text.replace(pos, 3 ,std::to_string(i));
}
return text;
}
static std::pair<cron_int, cron_int> make_range(
STRING_VIEW field,
cron_int const minval,
cron_int const maxval)
{
cron_int first = 0;
cron_int last = 0;
if (field.size() == 1 && field[0] == '*')
{
first = minval;
last = maxval;
}
else if (!utils::contains(field, '-'))
{
first = to_cron_int(field);
last = first;
}
else
{
auto parts = utils::split(field, '-');
if (parts.size() != 2)
throw bad_cronexpr("Specified range requires two fields");
first = to_cron_int(parts[0]);
last = to_cron_int(parts[1]);
}
if (first > maxval || last > maxval)
{
throw bad_cronexpr("Specified range exceeds maximum");
}
if (first < minval || last < minval)
{
throw bad_cronexpr("Specified range is less than minimum");
}
if (first > last)
{
throw bad_cronexpr("Specified range start exceeds range end");
}
return { first, last };
}
template <size_t N>
static void set_cron_field(
STRING_VIEW value,
std::bitset<N>& target,
cron_int const minval,
cron_int const maxval)
{
if(value.length() > 0 && value[value.length()-1] == ',')
throw bad_cronexpr("Value cannot end with comma");
auto fields = utils::split(value, ',');
if (fields.empty())
throw bad_cronexpr("Expression parsing error");
for (auto const & field : fields)
{
if (!utils::contains(field, '/'))
{
#ifdef CRONCPP_IS_CPP17
auto[first, last] = detail::make_range(field, minval, maxval);
#else
auto range = detail::make_range(field, minval, maxval);
auto first = range.first;
auto last = range.second;
#endif
for (cron_int i = first - minval; i <= last - minval; ++i)
{
target.set(i);
}
}
else
{
auto parts = utils::split(field, '/');
if (parts.size() != 2)
throw bad_cronexpr("Incrementer must have two fields");
#ifdef CRONCPP_IS_CPP17
auto[first, last] = detail::make_range(parts[0], minval, maxval);
#else
auto range = detail::make_range(parts[0], minval, maxval);
auto first = range.first;
auto last = range.second;
#endif
if (!utils::contains(parts[0], '-'))
{
last = maxval;
}
auto delta = detail::to_cron_int(parts[1]);
if(delta <= 0)
throw bad_cronexpr("Incrementer must be a positive value");
for (cron_int i = first - minval; i <= last - minval; i += delta)
{
target.set(i);
}
}
}
}
template <typename Traits>
static void set_cron_days_of_week(
std::string value,
std::bitset<7>& target)
{
auto days = utils::to_upper(value);
auto days_replaced = detail::replace_ordinals(
days,
#ifdef CRONCPP_IS_CPP17
Traits::DAYS
#else
Traits::DAYS()
#endif
);
if (days_replaced.size() == 1 && days_replaced[0] == '?')
days_replaced[0] = '*';
set_cron_field(
days_replaced,
target,
Traits::CRON_MIN_DAYS_OF_WEEK,
Traits::CRON_MAX_DAYS_OF_WEEK);
}
template <typename Traits>
static void set_cron_days_of_month(
std::string value,
std::bitset<31>& target)
{
if (value.size() == 1 && value[0] == '?')
value[0] = '*';
set_cron_field(
value,
target,
Traits::CRON_MIN_DAYS_OF_MONTH,
Traits::CRON_MAX_DAYS_OF_MONTH);
}
template <typename Traits>
static void set_cron_month(
std::string value,
std::bitset<12>& target)
{
auto month = utils::to_upper(value);
auto month_replaced = replace_ordinals(
month,
#ifdef CRONCPP_IS_CPP17
Traits::MONTHS
#else
Traits::MONTHS()
#endif
);
set_cron_field(
month_replaced,
target,
Traits::CRON_MIN_MONTHS,
Traits::CRON_MAX_MONTHS);
}
template <size_t N>
inline size_t next_set_bit(
std::bitset<N> const & target,
size_t /*minimum*/,
size_t /*maximum*/,
size_t offset)
{
for (auto i = offset; i < N; ++i)
{
if (target.test(i)) return i;
}
return INVALID_CRON_INDEX;
}
inline void add_to_field(
std::tm& date,
cron_field const field,
int const val)
{
switch (field)
{
case cron_field::second:
date.tm_sec += val;
break;
case cron_field::minute:
date.tm_min += val;
break;
case cron_field::hour_of_day:
date.tm_hour += val;
break;
case cron_field::day_of_week:
case cron_field::day_of_month:
date.tm_mday += val;
break;
case cron_field::month:
date.tm_mon += val;
break;
case cron_field::year:
date.tm_year += val;
break;
}
if (INVALID_TIME == utils::tm_to_time(date))
throw bad_cronexpr("Invalid time expression");
}
inline void set_field(
std::tm& date,
cron_field const field,
int const val)
{
switch (field)
{
case cron_field::second:
date.tm_sec = val;
break;
case cron_field::minute:
date.tm_min = val;
break;
case cron_field::hour_of_day:
date.tm_hour = val;
break;
case cron_field::day_of_week:
date.tm_wday = val;
break;
case cron_field::day_of_month:
date.tm_mday = val;
break;
case cron_field::month:
date.tm_mon = val;
break;
case cron_field::year:
date.tm_year = val;
break;
}
if (INVALID_TIME == utils::tm_to_time(date))
throw bad_cronexpr("Invalid time expression");
}
inline void reset_field(
std::tm& date,
cron_field const field)
{
switch (field)
{
case cron_field::second:
date.tm_sec = 0;
break;
case cron_field::minute:
date.tm_min = 0;
break;
case cron_field::hour_of_day:
date.tm_hour = 0;
break;
case cron_field::day_of_week:
date.tm_wday = 0;
break;
case cron_field::day_of_month:
date.tm_mday = 1;
break;
case cron_field::month:
date.tm_mon = 0;
break;
case cron_field::year:
date.tm_year = 0;
break;
}
if (INVALID_TIME == utils::tm_to_time(date))
throw bad_cronexpr("Invalid time expression");
}
inline void reset_all_fields(
std::tm& date,
std::bitset<7> const & marked_fields)
{
for (size_t i = 0; i < marked_fields.size(); ++i)
{
if (marked_fields.test(i))
reset_field(date, static_cast<cron_field>(i));
}
}
inline void mark_field(
std::bitset<7> & orders,
cron_field const field)
{
if (!orders.test(static_cast<size_t>(field)))
orders.set(static_cast<size_t>(field));
}
template <size_t N>
static size_t find_next(
std::bitset<N> const & target,
std::tm& date,
unsigned int const minimum,
unsigned int const maximum,
unsigned int const value,
cron_field const field,
cron_field const next_field,
std::bitset<7> const & marked_fields)
{
auto next_value = next_set_bit(target, minimum, maximum, value);
if (INVALID_CRON_INDEX == next_value)
{
add_to_field(date, next_field, 1);
reset_field(date, field);
next_value = next_set_bit(target, minimum, maximum, 0);
}
if (INVALID_CRON_INDEX == next_value || next_value != value)
{
set_field(date, field, static_cast<int>(next_value));
reset_all_fields(date, marked_fields);
}
return next_value;
}
template <typename Traits>
static size_t find_next_day(
std::tm& date,
std::bitset<31> const & days_of_month,
size_t day_of_month,
std::bitset<7> const & days_of_week,
size_t day_of_week,
std::bitset<7> const & marked_fields)
{
unsigned int count = 0;
unsigned int maximum = 366;
while (
(!days_of_month.test(day_of_month - Traits::CRON_MIN_DAYS_OF_MONTH) ||
!days_of_week.test(day_of_week - Traits::CRON_MIN_DAYS_OF_WEEK))
&& count++ < maximum)
{
add_to_field(date, cron_field::day_of_month, 1);
day_of_month = date.tm_mday;
day_of_week = date.tm_wday;
reset_all_fields(date, marked_fields);
}
return day_of_month;
}
template <typename Traits>
static bool find_next(cronexpr const & cex,
std::tm& date,
size_t const dot)
{
bool res = true;
std::bitset<7> marked_fields{ 0 };
std::bitset<7> empty_list{ 0 };
unsigned int second = date.tm_sec;
auto updated_second = find_next(
cex.seconds,
date,
Traits::CRON_MIN_SECONDS,
Traits::CRON_MAX_SECONDS,
second,
cron_field::second,
cron_field::minute,
empty_list);
if (second == updated_second)
{
mark_field(marked_fields, cron_field::second);
}
unsigned int minute = date.tm_min;
auto update_minute = find_next(
cex.minutes,
date,
Traits::CRON_MIN_MINUTES,
Traits::CRON_MAX_MINUTES,
minute,
cron_field::minute,
cron_field::hour_of_day,
marked_fields);
if (minute == update_minute)
{
mark_field(marked_fields, cron_field::minute);
}
else
{
res = find_next<Traits>(cex, date, dot);
if (!res) return res;
}
unsigned int hour = date.tm_hour;
auto updated_hour = find_next(
cex.hours,
date,
Traits::CRON_MIN_HOURS,
Traits::CRON_MAX_HOURS,
hour,
cron_field::hour_of_day,
cron_field::day_of_week,
marked_fields);
if (hour == updated_hour)
{
mark_field(marked_fields, cron_field::hour_of_day);
}
else
{
res = find_next<Traits>(cex, date, dot);
if (!res) return res;
}
unsigned int day_of_week = date.tm_wday;
unsigned int day_of_month = date.tm_mday;
auto updated_day_of_month = find_next_day<Traits>(
date,
cex.days_of_month,
day_of_month,
cex.days_of_week,
day_of_week,
marked_fields);
if (day_of_month == updated_day_of_month)
{
mark_field(marked_fields, cron_field::day_of_month);
}
else
{
res = find_next<Traits>(cex, date, dot);
if (!res) return res;
}
unsigned int month = date.tm_mon;
auto updated_month = find_next(
cex.months,
date,
Traits::CRON_MIN_MONTHS,
Traits::CRON_MAX_MONTHS,
month,
cron_field::month,
cron_field::year,
marked_fields);
if (month != updated_month)
{
if (date.tm_year - dot > Traits::CRON_MAX_YEARS_DIFF)
return false;
res = find_next<Traits>(cex, date, dot);
if (!res) return res;
}
return res;
}
}
template <typename Traits>
static cronexpr make_cron(STRING_VIEW expr)
{
cronexpr cex;
if (expr.empty())
throw bad_cronexpr("Invalid empty cron expression");
auto fields = utils::split(expr, ' ');
fields.erase(
std::remove_if(std::begin(fields), std::end(fields),
[](STRING_VIEW s) {return s.empty(); }),
std::end(fields));
if (fields.size() != 6)
throw bad_cronexpr("cron expression must have six fields");
detail::set_cron_field(fields[0], cex.seconds, Traits::CRON_MIN_SECONDS, Traits::CRON_MAX_SECONDS);
detail::set_cron_field(fields[1], cex.minutes, Traits::CRON_MIN_MINUTES, Traits::CRON_MAX_MINUTES);
detail::set_cron_field(fields[2], cex.hours, Traits::CRON_MIN_HOURS, Traits::CRON_MAX_HOURS);
detail::set_cron_days_of_week<Traits>(fields[5], cex.days_of_week);
detail::set_cron_days_of_month<Traits>(fields[3], cex.days_of_month);
detail::set_cron_month<Traits>(fields[4], cex.months);
return cex;
}
template <typename Traits = cron_standard_traits>
static std::tm cron_next(cronexpr const & cex, std::tm date)
{
time_t original = utils::tm_to_time(date);
if (INVALID_TIME == original) return {};
if (!detail::find_next<Traits>(cex, date, date.tm_year))
return {};
time_t calculated = utils::tm_to_time(date);
if (INVALID_TIME == calculated) return {};
if (calculated == original)
{
add_to_field(date, detail::cron_field::second, 1);
if (!detail::find_next<Traits>(cex, date, date.tm_year))
return {};
}
return date;
}
template <typename Traits = cron_standard_traits>
static std::time_t cron_next(cronexpr const & cex, std::time_t const & date)
{
std::tm val;
std::tm* dt = utils::time_to_tm(&date, &val);
if (dt == nullptr) return INVALID_TIME;
time_t original = utils::tm_to_time(*dt);
if (INVALID_TIME == original) return INVALID_TIME;
if(!detail::find_next<Traits>(cex, *dt, dt->tm_year))
return INVALID_TIME;
time_t calculated = utils::tm_to_time(*dt);
if (INVALID_TIME == calculated) return calculated;
if (calculated == original)
{
add_to_field(*dt, detail::cron_field::second, 1);
if(!detail::find_next<Traits>(cex, *dt, dt->tm_year))
return INVALID_TIME;
}
return utils::tm_to_time(*dt);
}
}
+1 -1
View File
@@ -23,7 +23,7 @@
#include <algorithm>
#include <cmath>
namespace EQ {
namespace EQEmu {
template<typename T>
T Clamp(const T &value, const T &lower, const T &upper)
{
+1911 -1807
View File
File diff suppressed because it is too large Load Diff
+164 -166
View File
@@ -18,8 +18,8 @@
#ifndef EQEMU_DATABASE_H
#define EQEMU_DATABASE_H
#define AUTHENTICATION_TIMEOUT 60
#define INVALID_ID 0xFFFFFFFF
#define AUTHENTICATION_TIMEOUT 60
#define INVALID_ID 0xFFFFFFFF
#include "global_define.h"
#include "eqemu_logsys.h"
@@ -34,14 +34,35 @@
#include <vector>
#include <map>
//atoi is not uint32 or uint32 safe!!!!
#define atoul(str) strtoul(str, nullptr, 10)
class MySQLRequestResult;
class Client;
namespace EQ {
namespace EQEmu
{
class InventoryProfile;
}
struct EventLogDetails_Struct {
uint32 id;
char accountname[64];
uint32 account_id;
int16 status;
char charactername[64];
char targetname[64];
char timestamp[64];
char descriptiontype[64];
char details[128];
};
struct CharacterEventLog_Struct {
uint32 count;
uint8 eventid;
EventLogDetails_Struct eld[255];
};
struct npcDecayTimes_Struct {
uint16 minlvl;
uint16 maxlvl;
@@ -51,11 +72,10 @@ struct npcDecayTimes_Struct {
struct VarCache_Struct {
std::map<std::string, std::string> m_cache;
uint32 last_update;
uint32 last_update;
VarCache_Struct() : last_update(0) { }
void Add(const std::string& key, const std::string& value) { m_cache[key] = value; }
const std::string* Get(const std::string& key)
{
void Add(const std::string &key, const std::string &value) { m_cache[key] = value; }
const std::string *Get(const std::string &key) {
auto it = m_cache.find(key);
return (it != m_cache.end() ? &it->second : nullptr);
}
@@ -79,210 +99,188 @@ class PTimerList;
class Database : public DBcore {
public:
Database();
Database(
const std::string& host,
const std::string& user,
const std::string& password,
const std::string& database,
uint32 port
);
bool Connect(
const std::string& host,
const std::string& user,
const std::string& password,
const std::string& database,
uint32 port,
std::string connection_label = "default"
);
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
~Database();
/* Character Creation */
bool DeleteCharacter(const std::string& name);
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
bool ReserveName(uint32 account_id, const std::string& name);
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
bool UpdateName(const std::string& old_name, const std::string& new_name);
bool CopyCharacter(
const std::string& source_character_name,
const std::string& destination_character_name,
const std::string& destination_account_name
);
bool AddToNameFilter(const char* name);
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
bool DeleteCharacter(char* name);
bool MoveCharacterToZone(const char* charname, const char* zonename);
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
bool ReserveName(uint32 account_id, char* name);
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv);
bool UpdateName(const char* oldname, const char* newname);
/* General Information Queries */
bool AddBannedIP(const std::string& banned_ip, const std::string& notes); //Add IP address to the banned_ips table.
bool AddToNameFilter(const std::string& name);
bool CheckBannedIPs(const std::string& login_ip); //Check incoming connection against banned IP table.
bool CheckGMIPs(const std::string& login_ip, uint32 account_id);
bool CheckNameFilter(const std::string& name, bool surname = false);
bool IsNameUsed(const std::string& name);
uint32 GetAccountIDByChar(const std::string& name, uint32* character_id = 0);
uint32 GetAccountIDByChar(uint32 character_id);
uint32 GetAccountIDByName(const std::string& account_name, const std::string& loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const std::string& name);
uint32 GetGuildIDByCharID(uint32 character_id);
uint32 GetGroupIDByCharID(uint32 character_id);
uint32 GetRaidIDByCharID(uint32 character_id);
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
bool AddGMIP(char* ip_address, char* name);
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
bool CheckGMIPs(const char* loginIP, uint32 account_id);
bool CheckNameFilter(const char* name, bool surname = false);
bool CheckUsedName(const char* name);
const std::string GetAccountName(uint32 account_id, uint32* lsaccount_id = 0);
const std::string GetCharName(uint32 character_id);
const std::string GetCharNameByID(uint32 character_id);
const std::string GetNPCNameByID(uint32 npc_id);
const std::string GetCleanNPCNameByID(uint32 npc_id);
void LoginIP(uint32 account_id, const std::string& login_ip);
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
uint32 GetAccountIDByChar(uint32 char_id);
uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
uint32 GetCharacterID(const char *name);
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);
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
void GetCharName(uint32 char_id, char* name);
void LoginIP(uint32 AccountID, const char* LoginIP);
/* Instancing */
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
bool AddClientToInstance(uint16 instance_id, uint32 char_id);
bool CharacterInInstanceGroup(uint16 instance_id, uint32 char_id);
bool CheckInstanceExists(uint16 instance_id);
bool CheckInstanceExpired(uint16 instance_id);
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
bool GetUnusedInstanceID(uint16& instance_id);
bool IsGlobalInstance(uint16 instance_id);
bool GetUnusedInstanceID(uint16 &instance_id);
bool GlobalInstance(uint16 instance_id);
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
bool RemoveClientsFromInstance(uint16 instance_id);
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
bool VerifyInstanceAlive(uint16 instance_id, uint32 char_id);
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
uint16 GetInstanceID(uint32 zone, uint32 character_id, int16 version);
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
uint8_t GetInstanceVersion(uint16 instance_id);
uint32 GetTimeRemainingInstance(uint16 instance_id, bool& is_perma);
uint32 GetInstanceZoneID(uint16 instance_id);
uint16 GetInstanceID(const char* zone, uint32 charid, int16 version);
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
uint16 GetInstanceVersion(uint16 instance_id);
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
uint32 VersionFromInstanceID(uint16 instance_id);
uint32 ZoneIDFromInstanceID(uint16 instance_id);
void AssignGroupToInstance(uint32 group_id, uint32 instance_id);
void AssignRaidToInstance(uint32 raid_id, uint32 instance_id);
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
void BuryCorpsesInInstance(uint16 instance_id);
void DeleteInstance(uint16 instance_id);
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id);
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id);
void GetCharactersInInstance(uint16 instance_id, std::list<uint32>& character_ids);
void FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid);
void FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid);
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list);
void PurgeExpiredInstances();
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
void CleanupInstanceCorpses();
/* Adventure related. */
void UpdateAdventureStatsEntry(uint32 character_id, uint8 theme_id, bool is_win = false, bool is_remove = false);
bool GetAdventureStats(uint32 character_id, AdventureStats_Struct* as);
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win);
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
/* Account Related */
const std::string GetLiveChar(uint32 account_id);
bool SetAccountStatus(const std::string& account_name, int16 status);
bool SetLocalPassword(uint32 account_id, const std::string& password);
bool UpdateLiveChar(const std::string& name, uint32 account_id);
int16 GetAccountStatus(uint32 account_id);
void SetAccountCRCField(uint32 account_id, const std::string& field_name, uint64 checksum);
uint32 CheckLogin(const std::string& name, const std::string& password, const std::string& loginserver, int16* status = 0);
uint32 CreateAccount(
const std::string& name,
const std::string& password,
int16 status,
const std::string& 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
);
uint8 GetAgreementFlag(uint32 account_id);
void SetAgreementFlag(uint32 account_id);
bool DeleteAccount(const char *name, const char* loginserver);
bool GetLiveChar(uint32 account_id, char* cname);
bool SetAccountStatus(const char* name, int16 status);
bool SetAccountStatus(const std::string& account_name, int16 status);
bool SetLocalPassword(uint32 accid, const char* password);
bool UpdateLiveChar(char* charname, uint32 account_id);
int GetIPExemption(const std::string& account_ip);
void SetIPExemption(const std::string& account_ip, int exemption_amount);
int16 CheckStatus(uint32 account_id);
int GetInstanceID(uint32 character_id, uint32 zone_id);
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
uint8 GetAgreementFlag(uint32 acctid);
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
void SetAgreementFlag(uint32 acctid);
int GetIPExemption(std::string account_ip);
int GetInstanceID(uint32 char_id, uint32 zone_id);
/* Groups */
std::string GetGroupLeaderForLogin(const std::string& character_name);
char* GetGroupLeadershipInfo(
uint32 group_id,
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
);
std::string GetGroupLeaderName(uint32 group_id);
uint32 GetGroupID(const std::string& name);
void ClearGroup(uint32 group_id = 0);
void ClearGroupLeader(uint32 group_id = 0);
void SetGroupLeaderName(uint32 group_id, const std::string& 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);
uint32 GetGroupID(const char* name);
void ClearGroup(uint32 gid = 0);
void ClearGroupLeader(uint32 gid = 0);
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
void SetGroupLeaderName(uint32 gid, const char* name);
/* Raids */
const std::string GetRaidLeaderName(uint32 raid_id);
uint32 GetRaidID(const std::string& name);
void ClearRaid(uint32 raid_id = 0);
void ClearRaidDetails(uint32 raid_id = 0);
void ClearRaidLeader(uint32 group_id = std::numeric_limits<uint32>::max(), uint32 raid_id = 0);
void GetGroupLeadershipInfo(
uint32 group_id,
uint32 raid_id,
char* maintank = nullptr,
char* assist = nullptr,
char* puller = nullptr,
char* marknpc = nullptr,
char* mentoree = nullptr,
int* mentor_percent = nullptr,
GroupLeadershipAA_Struct* GLAA = nullptr
);
void GetRaidLeadershipInfo(
uint32 raid_id,
char* maintank = nullptr,
char* assist = nullptr,
char* puller = nullptr,
char* marknpc = nullptr,
RaidLeadershipAA_Struct* RLAA = nullptr
);
void SetRaidGroupLeaderInfo(uint32 group_id, uint32 raid_id);
void PurgeAllDeletedDataBuckets();
void ClearGuildOnlineStatus();
void ClearTraderDetails();
void ClearBuyerDetails();
const char *GetRaidLeaderName(uint32 rid);
uint32 GetRaidID(const char* name);
void ClearRaid(uint32 rid = 0);
void ClearRaidDetails(uint32 rid = 0);
void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0);
void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
void PurgeAllDeletedDataBuckets();
/* Database Conversions 'database_conversions.cpp' */
bool CheckDatabaseConversions();
bool CheckDatabaseConvertCorpseDeblob();
bool CheckDatabaseConvertPPDeblob();
/* Database Variables */
bool GetVariable(const std::string& name, std::string& value);
bool SetVariable(const std::string& name, const std::string& value);
bool LoadVariables();
uint8 GetPEQZone(uint32 zone_id, uint32 version);
uint32 GetServerType();
void AddReport(const std::string& who, const std::string& against, const std::string& lines);
struct TimeOfDay_Struct LoadTime(time_t& realtime);
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
void ClearMerchantTemp();
void ClearPTimers(uint32 character_id);
void SetFirstLogon(uint32 character_id, uint8 first_logon);
void SetLFG(uint32 character_id, bool is_lfg);
void SetLFP(uint32 character_id, bool is_lfp);
void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon);
bool GetVariable(std::string varname, std::string &varvalue);
bool SetVariable(const std::string varname, const std::string &varvalue);
bool LoadVariables();
int64 CountInvSnapshots();
void ClearInvSnapshots(bool from_now = false);
/* General Queries */
void SourceDatabaseTableFromUrl(const std::string& table_name, const std::string& url);
void SourceSqlFromUrl(const std::string& url);
void PurgeCharacterParcels();
void Encode(std::string &in);
void Decode(std::string &in);
bool GetSafePoints(const char* short_name, uint32 version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr);
bool GetSafePoints(uint32 zoneID, uint32 version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr) { return GetSafePoints(GetZoneName(zoneID), version, safe_x, safe_y, safe_z, minstatus, minlevel, flag_needed); }
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0);
bool LoadPTimers(uint32 charid, PTimerList &into);
bool LoadZoneNames();
uint64_t GetNextTableId(const std::string& table_name);
const char* GetZoneName(uint32 zoneID, bool ErrorUnknown = false);
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
uint32 GetZoneID(const char* zonename);
uint8 GetPEQZone(uint32 zoneID, uint32 version);
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
uint8 GetServerType();
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
void AddReport(std::string who, std::string against, std::string lines);
struct TimeOfDay_Struct LoadTime(time_t &realtime);
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
void ClearMerchantTemp();
void ClearPTimers(uint32 charid);
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
void SetLFG(uint32 CharID, bool LFG);
void SetLFP(uint32 CharID, bool LFP);
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
int CountInvSnapshots();
void ClearInvSnapshots(bool from_now = false);
/* EQEmuLogSys */
void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings);
private:
Mutex Mvarcache;
std::map<uint32,std::string> zonename_array;
Mutex Mvarcache;
VarCache_Struct varcache;
/* Groups, utility methods. */
void ClearAllGroupLeaders();
void ClearAllGroups();
void ClearAllGroupLeaders();
void ClearAllGroups();
/* Raid, utility methods. */
void ClearAllRaids();
-611
View File
@@ -1,611 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <string>
#include <cstdio>
#include <iterator>
#include "database_dump_service.h"
#include "../eqemu_logsys.h"
#include "../strings.h"
#include "../eqemu_config.h"
#include "../database_schema.h"
#include "../file.h"
#include "../process/process.h"
#include "../termcolor/rang.hpp"
#include <ctime>
#if _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#include <thread>
#endif
#define DATABASE_DUMP_PATH "backups/"
/**
* @return bool
*/
bool DatabaseDumpService::IsMySQLInstalled()
{
std::string version_output = GetMySQLVersion();
return version_output.find("mysql") != std::string::npos && version_output.find("Ver") != std::string::npos;
}
/**
* Linux
* @return bool
*/
bool DatabaseDumpService::IsTarAvailable()
{
std::string version_output = Process::execute("tar --version");
return version_output.find("GNU tar") != std::string::npos;
}
/**
* Windows
* @return bool
*/
bool DatabaseDumpService::Is7ZipAvailable()
{
std::string version_output = Process::execute("7z --help");
return version_output.find("7-Zip") != std::string::npos;
}
/**
* @return
*/
bool DatabaseDumpService::HasCompressionBinary()
{
return IsTarAvailable() || Is7ZipAvailable();
}
/**
* @return
*/
std::string DatabaseDumpService::GetMySQLVersion()
{
std::string version_output = Process::execute("mysql --version");
return Strings::Trim(version_output);
}
const std::string CREDENTIALS_FILE = "login.my.cnf";
/**
* @return
*/
std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
{
auto config = EQEmuConfig::get();
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
return fmt::format(
"mysqldump --defaults-extra-file={} {}",
CREDENTIALS_FILE,
config->ContentDbName
);
};
return fmt::format(
"mysqldump --defaults-extra-file={} {}",
CREDENTIALS_FILE,
config->DatabaseDB
);
}
std::string DatabaseDumpService::GetPlayerTablesList()
{
return Strings::Join(DatabaseSchema::GetPlayerTables(), " ");
}
std::string DatabaseDumpService::GetBotTablesList()
{
return Strings::Join(DatabaseSchema::GetBotTables(), " ");
}
std::string DatabaseDumpService::GetMercTablesList()
{
return Strings::Join(DatabaseSchema::GetMercTables(), " ");
}
std::string DatabaseDumpService::GetLoginTableList()
{
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
}
std::string DatabaseDumpService::GetSystemTablesList()
{
auto system_tables = DatabaseSchema::GetServerTables();
auto version_tables = DatabaseSchema::GetVersionTables();
system_tables.insert(
std::end(system_tables),
std::begin(version_tables),
std::end(version_tables)
);
return Strings::Join(system_tables, " ");
}
std::string DatabaseDumpService::GetStateTablesList()
{
return Strings::Join(DatabaseSchema::GetStateTables(), " ");
}
std::string DatabaseDumpService::GetContentTablesList()
{
return Strings::Join(DatabaseSchema::GetContentTables(), " ");
}
/**
* @return
*/
std::string GetDumpDate()
{
time_t now = time(nullptr);
struct tm time_struct{};
char buf[80];
time_struct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d", &time_struct);
std::string time = buf;
return time;
}
/**
* @return
*/
std::string DatabaseDumpService::GetSetDumpPath()
{
return !GetDumpPath().empty() ? GetDumpPath() : DATABASE_DUMP_PATH;
}
/**
* @return
*/
std::string DatabaseDumpService::GetDumpFileNameWithPath()
{
return GetSetDumpPath() + GetDumpFileName();
}
void DatabaseDumpService::DatabaseDump()
{
if (!IsMySQLInstalled()) {
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
return;
}
if (IsDumpDropTableSyntaxOnly()) {
SetDumpOutputToConsole(true);
}
if (IsDumpOutputToConsole()) {
LogSys.SilenceConsoleLogging();
}
LogInfo("MySQL installed [{}]", GetMySQLVersion());
SetDumpFileName(EQEmuConfig::get()->DatabaseDB + '-' + GetDumpDate());
auto config = EQEmuConfig::get();
LogInfo(
"Database [{}] Host [{}] Username [{}]",
config->DatabaseDB,
config->DatabaseHost,
config->DatabaseUsername
);
std::string options = "--allow-keywords --extended-insert --max-allowed-packet=1G --net-buffer-length=32704";
if (IsDumpWithNoData()) {
options += " --no-data";
}
if (!IsDumpTableLock()) {
options += " --skip-lock-tables";
}
std::string tables_to_dump;
std::string dump_descriptor;
if (!IsDumpAllTables()) {
if (IsDumpPlayerTables()) {
tables_to_dump += GetPlayerTablesList() + " ";
dump_descriptor += "-player";
}
if (IsDumpBotTables()) {
tables_to_dump += GetBotTablesList() + " ";
dump_descriptor += "-bots";
}
if (IsDumpMercTables()) {
tables_to_dump += GetMercTablesList() + " ";
dump_descriptor += "-mercs";
}
if (IsDumpSystemTables()) {
tables_to_dump += GetSystemTablesList() + " ";
dump_descriptor += "-system";
}
if (IsDumpStateTables()) {
tables_to_dump += GetStateTablesList() + " ";
dump_descriptor += "-state";
}
if (IsDumpContentTables()) {
tables_to_dump += GetContentTablesList() + " ";
dump_descriptor += "-content";
}
if (IsDumpLoginServerTables()) {
tables_to_dump += GetLoginTableList() + " ";
dump_descriptor += "-login";
}
}
if (IsDumpStaticInstanceData()) {
tables_to_dump += "instance_list";
options += " --no-create-info --where=\"instance_list.is_global > 0 and instance_list.never_expires > 0\"";
}
if (!dump_descriptor.empty()) {
SetDumpFileName(GetDumpFileName() + dump_descriptor);
}
/**
* If we are dumping to stdout then we don't generate a file
*/
std::string pipe_file;
if (!IsDumpOutputToConsole()) {
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
}
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
File::Makedir(GetSetDumpPath());
}
if (IsDumpDropTableSyntaxOnly()) {
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
for (auto &table: tables) {
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
}
if (tables_to_dump.empty()) {
std::cerr << "No tables were specified" << std::endl;
}
return;
}
else {
const auto execute_command = fmt::format(
"{} {} {} {}",
GetBaseMySQLDumpCommand(),
options,
tables_to_dump,
pipe_file
);
LogInfo("Backing up database [{}]", execute_command);
LogInfo("This can take a few minutes depending on the size of your database");
LogInfo("LOADING... PLEASE WAIT...");
BuildCredentialsFile();
std::string execution_result = Process::execute(execute_command);
if (!execution_result.empty() && IsDumpOutputToConsole()) {
std::cout << execution_result;
}
}
if (!IsDumpOutputToConsole()) {
LogSys.LoadLogSettingsDefaults();
}
if (!pipe_file.empty()) {
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
auto r = File::GetContents(file);
if (!r.error.empty()) {
LogError("{}", r.error);
}
for (auto &line: Strings::Split(r.contents, "\n")) {
if (Strings::Contains(line, "mysqldump:")) {
LogError("{}", line);
LogError("Database dump failed. Correct the error before continuing or trying again");
LogError("This is to prevent data loss on behalf of the server operator");
RemoveSqlBackup();
std::exit(1);
}
}
}
if (!tables_to_dump.empty()) {
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
}
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
if (HasCompressionBinary()) {
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
if (IsTarAvailable()) {
Process::execute(
fmt::format(
"tar -zcvf {}.tar.gz -C {} {}.sql",
GetDumpFileNameWithPath(),
GetSetDumpPath(),
GetDumpFileName()
)
);
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else if (Is7ZipAvailable()) {
Process::execute(
fmt::format(
"7z a -t7z {}.zip {}.sql",
GetDumpFileNameWithPath(),
GetDumpFileNameWithPath()
)
);
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
RemoveSqlBackup();
}
else {
LogInfo("Compression requested, but no available compression binary was found");
}
}
else {
LogWarning("Compression requested but binary not found... Skipping...");
}
}
RemoveCredentialsFile();
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
// LogDebug("[{}] dump-path", GetSetDumpPath());
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
// LogDebug("[{}] bot", (IsDumpBotTables() ? "true" : "false"));
}
bool DatabaseDumpService::IsDumpSystemTables() const
{
return dump_system_tables;
}
void DatabaseDumpService::SetDumpSystemTables(bool dump_system_tables)
{
DatabaseDumpService::dump_system_tables = dump_system_tables;
}
bool DatabaseDumpService::IsDumpContentTables() const
{
return dump_content_tables;
}
void DatabaseDumpService::SetDumpContentTables(bool dump_content_tables)
{
DatabaseDumpService::dump_content_tables = dump_content_tables;
}
bool DatabaseDumpService::IsDumpPlayerTables() const
{
return dump_player_tables;
}
void DatabaseDumpService::SetDumpPlayerTables(bool dump_player_tables)
{
DatabaseDumpService::dump_player_tables = dump_player_tables;
}
bool DatabaseDumpService::IsDumpLoginServerTables() const
{
return dump_login_server_tables;
}
void DatabaseDumpService::SetDumpLoginServerTables(bool dump_login_server_tables)
{
DatabaseDumpService::dump_login_server_tables = dump_login_server_tables;
}
bool DatabaseDumpService::IsDumpWithNoData() const
{
return dump_with_no_data;
}
void DatabaseDumpService::SetDumpWithNoData(bool dump_with_no_data)
{
DatabaseDumpService::dump_with_no_data = dump_with_no_data;
}
bool DatabaseDumpService::IsDumpAllTables() const
{
return dump_all_tables;
}
void DatabaseDumpService::SetDumpAllTables(bool dump_all_tables)
{
DatabaseDumpService::dump_all_tables = dump_all_tables;
}
bool DatabaseDumpService::IsDumpTableLock() const
{
return dump_table_lock;
}
void DatabaseDumpService::SetDumpTableLock(bool dump_table_lock)
{
DatabaseDumpService::dump_table_lock = dump_table_lock;
}
bool DatabaseDumpService::IsDumpWithCompression() const
{
return dump_with_compression;
}
void DatabaseDumpService::SetDumpWithCompression(bool dump_with_compression)
{
DatabaseDumpService::dump_with_compression = dump_with_compression;
}
const std::string &DatabaseDumpService::GetDumpPath() const
{
return dump_path;
}
void DatabaseDumpService::SetDumpPath(const std::string &dump_path)
{
DatabaseDumpService::dump_path = dump_path;
}
void DatabaseDumpService::SetDumpFileName(const std::string &dump_file_name)
{
DatabaseDumpService::dump_file_name = dump_file_name;
}
const std::string &DatabaseDumpService::GetDumpFileName() const
{
return dump_file_name;
}
bool DatabaseDumpService::IsDumpOutputToConsole() const
{
return dump_output_to_console;
}
void DatabaseDumpService::SetDumpOutputToConsole(bool dump_output_to_console)
{
DatabaseDumpService::dump_output_to_console = dump_output_to_console;
}
bool DatabaseDumpService::IsDumpDropTableSyntaxOnly() const
{
return dump_drop_table_syntax_only;
}
void DatabaseDumpService::SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only)
{
DatabaseDumpService::dump_drop_table_syntax_only = dump_drop_table_syntax_only;
}
bool DatabaseDumpService::IsDumpStateTables() const
{
return dump_state_tables;
}
void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
{
DatabaseDumpService::dump_state_tables = dump_state_tables;
}
bool DatabaseDumpService::IsDumpBotTables() const
{
return dump_bot_tables;
}
void DatabaseDumpService::SetDumpBotTables(bool dump_bot_tables)
{
DatabaseDumpService::dump_bot_tables = dump_bot_tables;
}
bool DatabaseDumpService::IsDumpMercTables() const
{
return dump_merc_tables;
}
void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
{
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
}
void DatabaseDumpService::RemoveSqlBackup()
{
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
if (File::Exists(file)) {
try {
std::filesystem::remove(file);
}
catch (std::exception &e) {
LogError("std::filesystem::remove err [{}]", e.what());
}
}
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;
}
-103
View File
@@ -1,103 +0,0 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef EQEMU_DATABASE_DUMP_SERVICE_H
#define EQEMU_DATABASE_DUMP_SERVICE_H
class DatabaseDumpService {
public:
void DatabaseDump();
bool IsDumpAllTables() const;
void SetDumpAllTables(bool dump_all_tables);
bool IsDumpWithNoData() const;
void SetDumpWithNoData(bool dump_with_no_data);
bool IsDumpSystemTables() const;
void SetDumpSystemTables(bool dump_system_tables);
bool IsDumpContentTables() const;
void SetDumpContentTables(bool dump_content_tables);
bool IsDumpPlayerTables() const;
void SetDumpPlayerTables(bool dump_player_tables);
bool IsDumpLoginServerTables() const;
void SetDumpLoginServerTables(bool dump_login_server_tables);
bool IsDumpTableLock() const;
void SetDumpTableLock(bool dump_table_lock);
bool IsDumpWithCompression() const;
void SetDumpWithCompression(bool dump_with_compression);
const std::string &GetDumpPath() const;
void SetDumpPath(const std::string &dump_path);
const std::string &GetDumpFileName() const;
void SetDumpFileName(const std::string &dump_file_name);
bool IsDumpOutputToConsole() const;
void SetDumpOutputToConsole(bool dump_output_to_console);
bool IsDumpDropTableSyntaxOnly() const;
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
bool IsDumpStateTables() const;
void SetDumpStateTables(bool dump_state_tables);
bool IsDumpBotTables() const;
void SetDumpBotTables(bool dump_bot_tables);
bool IsDumpMercTables() const;
void SetDumpMercTables(bool dump_bot_tables);
void SetDumpStaticInstanceData(bool b);
bool IsDumpStaticInstanceData();
private:
bool dump_all_tables = false;
bool dump_state_tables = false;
bool dump_system_tables = false;
bool dump_content_tables = false;
bool dump_player_tables = false;
bool dump_query_server_tables = false;
bool dump_login_server_tables = false;
bool dump_with_no_data = false;
bool dump_table_lock = false;
bool dump_with_compression = false;
bool dump_output_to_console = false;
bool dump_drop_table_syntax_only = false;
bool dump_bot_tables = false;
bool dump_merc_tables = false;
bool dump_static_instance_data = false;
std::string dump_path;
std::string dump_file_name;
bool IsMySQLInstalled();
std::string GetMySQLVersion();
std::string GetBaseMySQLDumpCommand();
std::string GetPlayerTablesList();
std::string GetBotTablesList();
std::string GetMercTablesList();
std::string GetSystemTablesList();
std::string GetStateTablesList();
std::string GetContentTablesList();
std::string GetLoginTableList();
bool IsTarAvailable();
bool Is7ZipAvailable();
bool HasCompressionBinary();
std::string GetDumpFileNameWithPath();
std::string GetSetDumpPath();
void RemoveSqlBackup();
void BuildCredentialsFile();
void RemoveCredentialsFile();
};
#endif //EQEMU_DATABASE_DUMP_SERVICE_H
-375
View File
@@ -1,375 +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(const ManifestEntry& e)
{
auto results = (e.content_schema_update ? m_content_database : m_database)->QueryDatabase(e.check);
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;
}
// check if we are running in a terminal
bool is_atty()
{
#ifdef _WINDOWS
return ::_isatty(_fileno(stdin));
#else
return isatty(fileno(stdin));
#endif
}
// 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();
bool force_interactive = false;
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);
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
);
if (!has_migration && e.force_interactive) {
force_interactive = true;
}
}
}
}
LogSys.EnableMySQLErrorLogs();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
if (!missing_migrations.empty() && m_skip_backup) {
LogInfo("Skipping database backup");
}
else 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));
}
if (force_interactive && !std::getenv("FORCE_INTERACTIVE")) {
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfo("Some migrations require user input. Running interactively");
LogInfo("This is usually due to a major change that could cause data loss");
LogInfo("Your server is automatically backed up before these updates are applied");
LogInfo("but you should also make sure you take a backup prior to running this update");
LogInfo("Would you like to run this update? [y/n] (Timeout 60s)");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
// 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") {
LogInfo("Exiting due to user input");
std::exit(1);
}
}
for (auto &m: missing_migrations) {
for (auto &e: entries) {
if (e.version == m) {
bool errored_migration = false;
auto r = (e.content_schema_update ? m_content_database : 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");
// if terminal attached then prompt for skip
if (is_atty()) {
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);
}
} else {
errored_migration = true;
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;
}
DatabaseUpdate *DatabaseUpdate::SetContentDatabase(Database *db)
{
m_content_database = db;
return this;
}
DatabaseUpdate *DatabaseUpdate::SetSkipBackup(bool skip)
{
m_skip_backup = skip;
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");
}
}
-44
View File
@@ -1,44 +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
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
bool force_interactive; // if true, this migration will always be run interactively
};
struct DatabaseVersion {
int server_database_version;
int bots_database_version;
};
class DatabaseUpdate {
public:
DatabaseVersion GetDatabaseVersions();
DatabaseVersion GetBinaryDatabaseVersions();
void CheckDbUpdates();
std::string GetQueryResult(const ManifestEntry& e);
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);
DatabaseUpdate *SetContentDatabase(Database *db);
DatabaseUpdate *SetSkipBackup(bool skip);
bool HasPendingUpdates();
private:
bool m_skip_backup = false;
Database *m_database;
Database *m_content_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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+367 -395
View File
@@ -18,19 +18,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/global_define.h"
#include "../common/rulesys.h"
#include "../common/strings.h"
#include "../common/string_util.h"
#include "../common/timer.h"
#include "../common/repositories/character_corpses_repository.h"
#include "../common/repositories/dynamic_zone_members_repository.h"
#include "../common/repositories/dynamic_zones_repository.h"
#include "../common/repositories/group_id_repository.h"
#include "../common/repositories/instance_list_repository.h"
#include "../common/repositories/instance_list_player_repository.h"
#include "../common/repositories/raid_members_repository.h"
#include "../common/repositories/respawn_times_repository.h"
#include "../common/repositories/spawn_condition_values_repository.h"
#include "repositories/spawn2_disabled_repository.h"
#include "database.h"
@@ -45,249 +34,226 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define strcasecmp _stricmp
#else
#include "unix.h"
#include "../zone/zonedb.h"
#include <netinet/in.h>
#include <sys/time.h>
#endif
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
/**
* @param instance_id
* @param char_id
* @return
*/
bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id)
{
auto e = InstanceListPlayerRepository::NewEntity();
std::string query = StringFormat(
"REPLACE INTO `instance_list_player` (id, charid) "
"VALUES "
"(%lu, %lu)",
(unsigned long) instance_id,
(unsigned long) char_id
);
e.id = instance_id;
e.charid = character_id;
auto results = QueryDatabase(query);
return InstanceListPlayerRepository::ReplaceOne(*this, e);
return results.Success();
}
bool Database::CheckInstanceByCharID(uint16 instance_id, uint32 character_id)
bool Database::CharacterInInstanceGroup(uint16 instance_id, uint32 char_id)
{
if (!instance_id) {
return false;
}
auto l = InstanceListPlayerRepository::GetWhere(
*this,
fmt::format(
"id = {} AND charid = {}",
instance_id,
character_id
)
);
if (l.empty()) {
std::string query = StringFormat("SELECT charid FROM instance_list_player where id=%u AND charid=%u", instance_id, char_id);
auto results = QueryDatabase(query);
if (!results.Success())
return false;
if (results.RowCount() != 1)
return false;
}
return true;
}
bool Database::CheckInstanceExists(uint16 instance_id)
{
if (!instance_id) {
return false;
}
bool Database::CheckInstanceExists(uint16 instance_id) {
std::string query = StringFormat(
"SELECT "
"`id` "
"FROM "
"`instance_list` "
"WHERE "
"`id` = %u",
instance_id
);
auto results = QueryDatabase(query);
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
if (!results.Success())
return false;
if (results.RowCount() == 0)
return false;
}
return true;
}
bool Database::CheckInstanceExpired(uint16 instance_id)
{
if (!instance_id) {
return true;
}
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
return true;
}
int32 start_time = 0;
int32 duration = 0;
uint32 never_expires = 0;
if (i.never_expires) {
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
return true;
if (results.RowCount() == 0)
return true;
auto row = results.begin();
start_time = atoi(row[0]);
duration = atoi(row[1]);
never_expires = atoi(row[2]);
if (never_expires == 1)
return false;
}
timeval tv{};
timeval tv;
gettimeofday(&tv, nullptr);
// Use uint64_t for the addition to prevent overflow
uint64_t expiration_time = static_cast<uint64_t>(i.start_time) + static_cast<uint64_t>(i.duration);
return expiration_time <= tv.tv_sec;
if ((start_time + duration) <= tv.tv_sec)
return true;
return false;
}
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
{
auto e = InstanceListRepository::NewEntity();
std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)"
" values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)",
(unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration);
auto results = QueryDatabase(query);
e.id = instance_id;
e.zone = zone_id;
e.version = version;
e.start_time = std::time(nullptr);
e.duration = duration;
return InstanceListRepository::InsertOne(*this, e).id;
return results.Success();
}
bool Database::GetUnusedInstanceID(uint16 &instance_id)
{
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
uint32 max_instance_id = 32000;
// sanity check reserved
if (max_reserved_instance_id >= max_instance_id) {
instance_id = 0;
return false;
}
// recycle instances
if (RuleB(Instances, RecycleInstanceIds)) {
//query to get first unused id above reserved
auto query = fmt::format(
SQL(
SELECT id
FROM instance_list
WHERE id = {};
),
max_reserved_instance_id + 1
);
auto results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) {
instance_id = 0;
return false;
}
// first id is available
if (results.RowCount() == 0) {
instance_id = max_reserved_instance_id + 1;
return true;
}
// now look for next available above reserved
query = fmt::format(
SQL(
SELECT MIN(i.id + 1) AS next_available
FROM instance_list i
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
WHERE i.id >= {}
AND i2.id IS NULL;
),
max_reserved_instance_id
);
results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) {
instance_id = 0;
return false;
}
// did not retrieve any rows - bail out
if (results.RowCount() == 0) {
instance_id = 0;
return false;
}
auto row = results.begin();
// check that id is within limits
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]);
return true;
}
// no available instance ids
instance_id = 0;
return false;
}
// get max unused id above reserved
auto query = fmt::format(
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
max_reserved_instance_id,
max_reserved_instance_id
);
uint32 count = RuleI(Zone, ReservedInstances);
uint32 max = 65535;
std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count);
auto results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) {
if (!results.Success())
{
instance_id = 0;
return false;
}
// did not retrieve any rows - bail out
if (results.RowCount() == 0) {
if (results.RowCount() == 0)
{
instance_id = 0;
return false;
}
auto row = results.begin();
// no instances currently used
if (!row[0]) {
instance_id = max_reserved_instance_id + 1;
if (atoi(row[0]) <= max)
{
instance_id = atoi(row[0]);
return true;
}
// check that id is within limits
if (Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]);
return true;
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count);
results = QueryDatabase(query);
if (!results.Success())
{
instance_id = 0;
return false;
}
// no available instance ids
instance_id = 0;
return false;
if (results.RowCount() == 0)
{
instance_id = 0;
return false;
}
count++;
for (auto row = results.begin(); row != results.end(); ++row)
{
if (count < atoi(row[0]))
{
instance_id = count;
return true;
}
if (count > max)
{
instance_id = 0;
return false;
}
count++;
}
instance_id = count;
return true;
}
bool Database::IsGlobalInstance(uint16 instance_id)
bool Database::GlobalInstance(uint16 instance_id)
{
if (!instance_id) {
return false;
}
std::string query = StringFormat(
"SELECT "
"is_global "
"FROM "
"instance_list "
"WHERE "
"id = %u "
"LIMIT 1 ",
instance_id
);
auto results = QueryDatabase(query);
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
if (!results.Success())
return false;
}
return i.is_global;
if (results.RowCount() == 0)
return false;
auto row = results.begin();
return (atoi(row[0]) == 1) ? true : false;
}
bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id)
{
return InstanceListPlayerRepository::DeleteWhere(
*this,
fmt::format(
"id = {} AND charid = {}",
instance_id,
char_id
)
);
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu",
(unsigned long)instance_id, (unsigned long)char_id);
auto results = QueryDatabase(query);
return results.Success();
}
bool Database::RemoveClientsFromInstance(uint16 instance_id)
{
return InstanceListPlayerRepository::DeleteOne(*this, instance_id);
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu", (unsigned long)instance_id);
auto results = QueryDatabase(query);
return results.Success();
}
bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 char_id)
{
//we are not saved to this instance so set our instance to 0
if (!IsGlobalInstance(instance_id) && !CheckInstanceByCharID(instance_id, character_id)) {
if (!GlobalInstance(instance_id) && !CharacterInInstanceGroup(instance_id, char_id))
return false;
}
if (CheckInstanceExpired(instance_id)) {
if (CheckInstanceExpired(instance_id))
{
DeleteInstance(instance_id);
return false;
}
@@ -297,102 +263,129 @@ bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id)
{
auto l = InstanceListRepository::GetWhere(
*this,
fmt::format(
"id = {} AND zone = {}",
instance_id,
zone_id
)
);
if (l.empty()) {
std::string query = StringFormat("SELECT id FROM instance_list where id=%u AND zone=%u", instance_id, zone_id);
auto results = QueryDatabase(query);
if (!results.Success())
return false;
if (results.RowCount() == 0)
return false;
}
return true;
}
uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 version)
uint16 Database::GetInstanceID(const char* zone, uint32 character_id, int16 version) {
std::string query = StringFormat(
"SELECT "
"instance_list.id "
"FROM "
"instance_list, "
"instance_list_player "
"WHERE "
"instance_list.zone = %u "
"AND instance_list.version = %u "
"AND instance_list.id = instance_list_player.id "
"AND instance_list_player.charid = %u "
"LIMIT 1 ",
GetZoneID(zone),
version,
character_id
);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
uint16 Database::GetInstanceID(uint32 zone, uint32 character_id, int16 version)
{
if (!zone_id) {
if (!zone)
return 0;
std::string query = StringFormat(
"SELECT "
"instance_list.id "
"FROM "
"instance_list, "
"instance_list_player "
"WHERE "
"instance_list.zone = %u "
"AND instance_list.version = %u "
"AND instance_list.id = instance_list_player.id "
"AND instance_list_player.charid = %u "
"LIMIT 1; ",
zone,
version,
character_id
);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
uint16 Database::GetInstanceVersion(uint16 instance_id) {
if (instance_id == 0)
return 0;
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
{
uint32 start_time = 0;
uint32 duration = 0;
uint32 never_expires = 0;
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
{
is_perma = false;
return 0;
}
const auto query = fmt::format(
"SELECT instance_list.id FROM "
"instance_list, instance_list_player WHERE "
"instance_list.zone = {} AND "
"instance_list.version = {} AND "
"instance_list.id = instance_list_player.id AND "
"instance_list_player.charid = {} "
"LIMIT 1;",
zone_id,
version,
character_id
);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
if (results.RowCount() == 0)
{
is_perma = false;
return 0;
}
auto row = results.begin();
return static_cast<uint16>(Strings::ToUnsignedInt(row[0]));
}
start_time = atoi(row[0]);
duration = atoi(row[1]);
never_expires = atoi(row[2]);
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
{
std::vector<uint16> l;
if (!zone_id) {
return l;
}
const auto query = fmt::format(
"SELECT instance_list.id FROM "
"instance_list, instance_list_player WHERE "
"instance_list.zone = {} AND "
"instance_list.id = instance_list_player.id AND "
"instance_list_player.charid = {}",
zone_id,
character_id
);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return l;
}
for (auto row : results) {
l.push_back(static_cast<uint16>(Strings::ToUnsignedInt(row[0])));
}
return l;
}
uint8_t Database::GetInstanceVersion(uint16 instance_id) {
if (!instance_id) {
return 0;
}
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
return 0;
}
return i.version;
}
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
{
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
is_perma = false;
return 0;
}
if (i.never_expires) {
if (never_expires == 1)
{
is_perma = true;
return 0;
}
@@ -401,197 +394,176 @@ uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
timeval tv;
gettimeofday(&tv, nullptr);
return ((i.start_time + i.duration) - tv.tv_sec);
return ((start_time + duration) - tv.tv_sec);
}
uint32 Database::GetInstanceZoneID(uint16 instance_id)
uint32 Database::VersionFromInstanceID(uint16 instance_id)
{
if (!instance_id) {
return 0;
}
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
return 0;
}
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
auto results = QueryDatabase(query);
return i.zone;
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
uint32 Database::ZoneIDFromInstanceID(uint16 instance_id)
{
std::string query = StringFormat("SELECT zone FROM instance_list where id=%u", instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
return 0;
if (results.RowCount() == 0)
return 0;
auto row = results.begin();
return atoi(row[0]);
}
void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
{
auto zone_id = GetInstanceZoneID(instance_id);
auto version = GetInstanceVersion(instance_id);
const auto& l = GroupIdRepository::GetWhere(
*this,
fmt::format(
"`group_id` = {}",
group_id
)
);
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
uint16 version = VersionFromInstanceID(instance_id);
if (l.empty()) {
std::string query = StringFormat("SELECT `charid` FROM `group_id` WHERE `groupid` = %u", group_id);
auto results = QueryDatabase(query);
if (!results.Success())
return;
}
for (const auto& e : l) {
if (!e.character_id) {
continue;
}
if (!GetInstanceID(zone_id, e.character_id, version)) {
AddClientToInstance(instance_id, e.character_id);
}
for (auto row = results.begin(); row != results.end(); ++row)
{
uint32 charid = atoi(row[0]);
if (GetInstanceID(zone_id, charid, version) == 0)
AddClientToInstance(instance_id, charid);
}
}
void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
{
auto zone_id = GetInstanceZoneID(instance_id);
auto version = GetInstanceVersion(instance_id);
auto l = RaidMembersRepository::GetWhere(
*this,
fmt::format(
"raidid = {}",
raid_id
)
);
if (l.empty()) {
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
uint16 version = VersionFromInstanceID(instance_id);
std::string query = StringFormat("SELECT `charid` FROM `raid_members` WHERE `raidid` = %u", raid_id);
auto results = QueryDatabase(query);
if (!results.Success())
return;
}
for (const auto& e : l) {
if (!GetInstanceID(zone_id, e.charid, version)) {
AddClientToInstance(instance_id, e.charid);
}
for (auto row = results.begin(); row != results.end(); ++row)
{
uint32 charid = atoi(row[0]);
if (GetInstanceID(zone_id, charid, version) == 0)
AddClientToInstance(instance_id, charid);
}
}
void Database::BuryCorpsesInInstance(uint16 instance_id) {
std::string query = StringFormat(
"UPDATE `character_corpses` "
"SET `is_buried` = 1, "
"`instance_id` = 0 "
"WHERE "
"`instance_id` = %u ",
instance_id
);
auto results = QueryDatabase(query);
}
void Database::DeleteInstance(uint16 instance_id)
{
// I'm not sure why this isn't in here but we should add it in a later change and make sure it's tested
// InstanceListRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
std::string query = StringFormat("DELETE FROM instance_list WHERE id=%u", instance_id);
QueryDatabase(query);
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
QueryDatabase(query);
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);
BuryCorpsesInInstance(instance_id);
}
void Database::FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id)
void Database::FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid)
{
auto instance_id = GetInstanceID(zone_id, character_id, version);
if (instance_id) {
uint16 id = GetInstanceID(zone, charid, version);
if (id != 0)
return;
}
char ln[128];
memset(ln, 0, 128);
GetGroupLeadershipInfo(group_id, ln);
strcpy(ln, GetGroupLeadershipInfo(gid, ln));
uint32 l_charid = GetCharacterID((const char*)ln);
uint16 l_id = GetInstanceID(zone, l_charid, version);
auto group_leader_id = GetCharacterID((const char*)ln);
auto group_leader_instance_id = GetInstanceID(zone_id, group_leader_id, version);
if (!group_leader_instance_id) {
if (l_id == 0)
return;
}
AddClientToInstance(group_leader_instance_id, character_id);
AddClientToInstance(l_id, charid);
}
void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id)
void Database::FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid)
{
uint16 instance_id = GetInstanceID(zone_id, character_id, version);
if (instance_id) {
uint16 id = GetInstanceID(zone, charid, version);
if (id != 0)
return;
}
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id).c_str());
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
uint32 l_charid = GetCharacterID(GetRaidLeaderName(rid));
uint16 l_id = GetInstanceID(zone, l_charid, version);
if (!raid_leader_instance_id) {
if (l_id == 0)
return;
}
AddClientToInstance(raid_leader_instance_id, character_id);
AddClientToInstance(l_id, charid);
}
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids)
{
auto l = InstanceListPlayerRepository::GetWhere(*this, fmt::format("id = {}", instance_id));
if (l.empty()) {
return;
}
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list) {
for (const auto& e : l) {
character_ids.push_back(e.charid);
}
std::string query = StringFormat("SELECT `charid` FROM `instance_list_player` WHERE `id` = %u", instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
return;
for (auto row = results.begin(); row != results.end(); ++row)
charid_list.push_back(atoi(row[0]));
}
void Database::PurgeExpiredInstances()
{
/**
* Delay purging by a day so that we can continue using adjacent free instance id's
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
* has not been fully de-allocated
*/
auto l = InstanceListRepository::GetWhere(
*this,
"(start_time + duration) <= (UNIX_TIMESTAMP() - 86400) AND never_expires = 0"
);
if (l.empty()) {
std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0");
auto results = QueryDatabase(query);
if (!results.Success())
return;
}
std::vector<std::string> instance_ids;
for (const auto& e : l) {
instance_ids.emplace_back(std::to_string(e.id));
}
if (results.RowCount() == 0)
return;
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
InstanceListRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
Spawn2DisabledRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
for (auto row = results.begin(); row != results.end(); ++row)
DeleteInstance(atoi(row[0]));
}
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
{
auto i = InstanceListRepository::FindOne(*this, instance_id);
if (!i.id) {
return;
}
i.start_time = std::time(nullptr);
i.duration = new_duration;
InstanceListRepository::UpdateOne(*this, i);
}
void Database::CleanupInstanceCorpses() {
auto l = InstanceListRepository::GetWhere(
*this,
"never_expires = 0"
);
if (l.empty()) {
return;
}
std::vector<std::string> instance_ids;
for (const auto& e : l) {
instance_ids.emplace_back(std::to_string(e.id));
}
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
}
std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), "
"duration=%u WHERE id=%u", new_duration, instance_id);
auto results = QueryDatabase(query);
}
+51 -196
View File
@@ -22,85 +22,18 @@
#define EQEMU_DATABASE_SCHEMA_H
#include <vector>
#include <map>
namespace DatabaseSchema {
/**
* Character-specific tables
*
* Does not included related meta-data tables such as 'guilds', 'accounts'
* @return
*/
static std::map<std::string, std::string> GetCharacterTables()
{
return {
{"adventure_stats", "player_id"},
{"char_recipe_list", "char_id"},
{"character_activities", "charid"},
{"character_alt_currency", "char_id"},
{"character_alternate_abilities", "id"},
{"character_auras", "id"},
{"character_bandolier", "id"},
{"character_bind", "id"},
{"character_buffs", "character_id"},
{"character_corpses", "id"},
{"character_currency", "id"},
{"character_data", "id"},
{"character_disciplines", "id"},
{"character_enabledtasks", "charid"},
{"character_expedition_lockouts", "character_id"},
{"character_exp_modifiers", "character_id"},
{"character_evolving_items", "character_id"},
{"character_inspect_messages", "id"},
{"character_instance_safereturns", "character_id"},
{"character_item_recast", "id"},
{"character_languages", "id"},
{"character_leadership_abilities", "id"},
{"character_material", "id"},
{"character_memmed_spells", "id"},
{"character_parcels", "char_id"},
{"character_parcels_containers", "id"},
{"character_pet_buffs", "char_id"},
{"character_pet_info", "char_id"},
{"character_pet_inventory", "char_id"},
{"character_pet_name", "character_id"},
{"character_peqzone_flags", "id"},
{"character_potionbelt", "id"},
{"character_skills", "id"},
{"character_spells", "id"},
{"character_stats_record", "character_id"},
{"character_task_timers", "character_id"},
{"character_tasks", "charid"},
{"character_tribute", "character_id"},
{"completed_tasks", "charid"},
{"data_buckets", "character_id"},
{"faction_values", "char_id"},
{"friends", "charid"},
{"guild_members", "char_id"},
{"guilds", "id"},
{"instance_list_player", "id"},
{"inventory", "charid"},
{"inventory_snapshots", "charid"},
{"keyring", "char_id"},
{"mail", "charid"},
{"player_titlesets", "char_id"},
{"quest_globals", "charid"},
{"timers", "char_id"},
{"trader", "char_id"},
{"zone_flags", "charID"}
};
}
/**
* @description Gets all player and meta-data tables
* @note These tables have no content in the PEQ daily dump
* Gets player tables
*
* @return
*/
static std::vector<std::string> GetPlayerTables()
{
return {
std::vector<std::string> tables = {
"aa_timers",
"account",
"account_ip",
"account_flags",
@@ -108,8 +41,6 @@ namespace DatabaseSchema {
"adventure_details",
"adventure_stats",
"buyer",
"buyer_buy_lines",
"buyer_trade_items",
"char_recipe_list",
"character_activities",
"character_alt_currency",
@@ -124,57 +55,45 @@ namespace DatabaseSchema {
"character_data",
"character_disciplines",
"character_enabledtasks",
"character_expedition_lockouts",
"character_exp_modifiers",
"character_evolving_items",
"character_inspect_messages",
"character_instance_safereturns",
"character_item_recast",
"character_languages",
"character_leadership_abilities",
"character_material",
"character_memmed_spells",
"character_parcels",
"character_parcels_containers",
"character_pet_buffs",
"character_pet_info",
"character_pet_inventory",
"character_peqzone_flags",
"character_potionbelt",
"character_skills",
"character_spells",
"character_stats_record",
"character_task_timers",
"character_tasks",
"character_tribute",
"completed_tasks",
"data_buckets",
"discovered_items",
"faction_values",
"friends",
"guild_bank",
"guild_members",
"guild_permissions",
"guild_ranks",
"guild_relations",
"guild_tributes",
"guilds",
"instance_list_player",
"inventory",
"inventory_snapshots",
"keyring",
"mail",
"petitions",
"player_titlesets",
"quest_globals",
"sharedbank",
"spell_buckets",
"spell_globals",
"timers",
"titles",
"trader",
"trader_audit",
"zone_flags"
};
return tables;
}
/**
@@ -184,14 +103,18 @@ namespace DatabaseSchema {
*/
static std::vector<std::string> GetContentTables()
{
return {
std::vector<std::string> tables = {
"aa_ability",
"aa_actions",
"aa_effects",
"aa_rank_effects",
"aa_rank_prereqs",
"aa_ranks",
"aa_required_level_cost",
"adventure_template",
"adventure_template_entry",
"adventure_template_entry_flavor",
"altadv_vars",
"alternate_currency",
"auras",
"base_data",
@@ -199,23 +122,24 @@ namespace DatabaseSchema {
"books",
"char_create_combinations",
"char_create_point_allocations",
"class_skill",
"damageshieldtypes",
"doors",
"dynamic_zone_templates",
"faction_association",
"faction_base_data",
"faction_list",
"faction_list_mod",
"fear_hints",
"fishing",
"forage",
"global_loot",
"goallists",
"graveyard",
"grid",
"grid_entries",
"ground_spawns",
"horses",
"instance_list",
"items",
"items_evolving_details",
"ldon_trap_entries",
"ldon_trap_templates",
"lootdrop",
@@ -232,15 +156,19 @@ namespace DatabaseSchema {
"npc_spells_effects_entries",
"npc_spells_entries",
"npc_types",
"npc_types_metadata",
"npc_types_tint",
"object",
"pets",
"pets_beastlord_data",
"pets_equipmentset",
"pets_equipmentset_entries",
"proximities",
"races",
"skill_caps",
"spawn2",
"spawn_condition_values",
"spawn_conditions",
"spawn_events",
"spawnentry",
"spawngroup",
"spells_new",
@@ -249,6 +177,7 @@ namespace DatabaseSchema {
"task_activities",
"tasks",
"tasksets",
"titles",
"tradeskill_recipe",
"tradeskill_recipe_entries",
"traps",
@@ -257,7 +186,11 @@ namespace DatabaseSchema {
"veteran_reward_templates",
"zone",
"zone_points",
"zone_server",
"zoneserver_auth",
};
return tables;
}
/**
@@ -267,28 +200,34 @@ namespace DatabaseSchema {
*/
static std::vector<std::string> GetServerTables()
{
return {
"chatchannels",
"chatchannel_reserved_names",
std::vector<std::string> tables = {
"banned_ips",
"bugs",
"bug_reports",
"command_settings",
"command_subsettings",
"content_flags",
"db_str",
"discovered_items",
"eqtime",
"eventlog",
"gm_ips",
"hackers",
"ip_exemptions",
"launcher",
"launcher_zones",
"spawn_condition_values",
"spawn_events",
"level_exp_mods",
"logsys_categories",
"name_filter",
"perl_event_export_settings",
"petitions",
"profanity_list",
"reports",
"rule_sets",
"titles",
"rule_values",
"saylink",
"variables",
};
return tables;
}
/**
@@ -299,59 +238,24 @@ namespace DatabaseSchema {
*/
static std::vector<std::string> GetStateTables()
{
return {
std::vector<std::string> tables = {
"adventure_members",
"banned_ips",
"bug_reports",
"bugs",
"buyer",
"buyer_buy_lines",
"buyer_trade_items",
"completed_shared_task_activity_state",
"completed_shared_task_members",
"completed_shared_tasks",
"discord_webhooks",
"dynamic_zone_members",
"dynamic_zones",
"expedition_lockouts",
"expeditions",
"gm_ips",
"chatchannels",
"group_id",
"group_leaders",
"instance_list",
"ip_exemptions",
"item_tick",
"lfguild",
"merc_buffs",
"merchantlist_temp",
"mercs",
"object_contents",
"raid_details",
"raid_leaders",
"raid_members",
"reports",
"respawn_times",
"saylink",
"server_scheduled_events",
"spawn2_disabled",
"player_event_aa_purchase",
"player_event_killed_npc",
"player_event_killed_named_npc",
"player_event_killed_raid_npc",
"player_event_log_settings",
"player_event_logs",
"player_event_loot_items",
"player_event_merchant_purchase",
"player_event_merchant_sell",
"player_event_npc_handin",
"player_event_npc_handin_entries",
"player_event_speech",
"player_event_trade",
"player_event_trade_entries",
"shared_task_activity_state",
"shared_task_dynamic_zones",
"shared_task_members",
"shared_tasks",
"spell_buckets",
"spell_globals",
};
return tables;
}
/**
@@ -361,13 +265,15 @@ namespace DatabaseSchema {
*/
static std::vector<std::string> GetLoginTables()
{
return {
std::vector<std::string> tables = {
"login_accounts",
"login_api_tokens",
"login_server_admins",
"login_server_list_types",
"login_world_servers",
};
return tables;
}
/**
@@ -377,63 +283,12 @@ namespace DatabaseSchema {
*/
static std::vector<std::string> GetVersionTables()
{
return {
std::vector<std::string> tables = {
"db_version",
"inventory_versions",
};
}
/**
* @description Gets all player bot tables
* @note These tables have no content in the PEQ daily dump
*
* @return
*/
static std::vector<std::string> GetBotTables()
{
return {
"bot_blocked_buffs",
"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_settings",
"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"
};
return tables;
}
}
+52 -227
View File
@@ -7,13 +7,12 @@
#include "timer.h"
#include "dbcore.h"
#include "mysql_stmt.h"
#include <errmsg.h>
#include <fstream>
#include <iostream>
#include <mysqld_error.h>
#include <string.h>
#include "strings.h"
#ifdef _WINDOWS
#define snprintf _snprintf
@@ -35,29 +34,19 @@
DBcore::DBcore()
{
mysql = mysql_init(nullptr);
mysqlOwner = true;
pHost = nullptr;
pUser = nullptr;
pPassword = nullptr;
pDatabase = nullptr;
pCompress = false;
pSSL = false;
pStatus = Closed;
m_mutex = new Mutex;
mysql_init(&mysql);
pHost = 0;
pUser = 0;
pPassword = 0;
pDatabase = 0;
pCompress = false;
pSSL = false;
pStatus = Closed;
}
DBcore::~DBcore()
{
/**
* This prevents us from doing a double free in multi-tenancy setups where we
* are re-using the default database connection pointer when we dont have an
* external configuration setup ex: (content_database)
*/
if (mysqlOwner) {
mysql_close(mysql);
}
mysql_close(&mysql);
safe_delete_array(pHost);
safe_delete_array(pUser);
safe_delete_array(pPassword);
@@ -67,25 +56,17 @@ DBcore::~DBcore()
// Sends the MySQL server a keepalive
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
return;
}
mysql_ping(mysql);
m_mutex->unlock();
mysql_ping(&mysql);
MDatabase.unlock();
}
MySQLRequestResult DBcore::QueryDatabase(const std::string& query, bool retryOnFailureOnce)
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
{
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
return r;
}
bool DBcore::DoesTableExist(const std::string& table_name)
{
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
return results.RowCount() > 0;
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
}
MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce)
@@ -93,7 +74,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
BenchTimer timer;
timer.reset();
LockMutex lock(m_mutex);
LockMutex lock(&MDatabase);
// Reconnect if we are not connected before hand.
if (pStatus != Connected) {
@@ -101,8 +82,8 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
}
// request query. != 0 indicates some kind of error.
if (mysql_real_query(mysql, query, querylen) != 0) {
unsigned int errorNumber = mysql_errno(mysql);
if (mysql_real_query(&mysql, query, querylen) != 0) {
unsigned int errorNumber = mysql_errno(&mysql);
if (errorNumber == CR_SERVER_GONE_ERROR) {
pStatus = Error;
@@ -126,26 +107,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(mysql), errorBuffer);
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
}
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
/**
* Error logging
*/
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
LogMySQLError("MySQL Error ({}) [{}] Query [{}]", mysql_errno(mysql), mysql_error(mysql), query);
/* Implement Logging at the Root */
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
if (EQEmuLogSys::Get()->log_settings[Logs::MySQLError].is_category_enabled == 1)
Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query);
}
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer);
}
// successful query. get results.
MYSQL_RES *res = mysql_store_result(mysql);
MYSQL_RES *res = mysql_store_result(&mysql);
uint32 rowCount = 0;
if (res != nullptr) {
@@ -154,16 +135,18 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
MySQLRequestResult requestResult(
res,
(uint32) mysql_affected_rows(mysql),
(uint32) mysql_affected_rows(&mysql),
rowCount,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
(uint32) mysql_field_count(&mysql),
(uint32) mysql_insert_id(&mysql)
);
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if (EQEmuLogSys::Get()->log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if ((strncasecmp(query, "select", 6) == 0)) {
LogMySQLQuery(
"{0} -- ({1} row{2} returned) ({3}s)",
LogF(
Logs::General,
Logs::MySQLQuery,
"{0} ({1} row{2} returned) ({3}s)",
query,
requestResult.RowCount(),
requestResult.RowCount() == 1 ? "" : "s",
@@ -171,8 +154,10 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
);
}
else {
LogMySQLQuery(
"{0} -- ({1} row{2} affected) ({3}s)",
LogF(
Logs::General,
Logs::MySQLQuery,
"{0} ({1} row{2} affected) ({3}s)",
query,
requestResult.RowsAffected(),
requestResult.RowsAffected() == 1 ? "" : "s",
@@ -203,7 +188,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.
// LockMutex lock(&MDatabase);
return mysql_real_escape_string(mysql, tobuf, frombuf, fromlen);
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
}
bool DBcore::Open(
@@ -218,11 +203,11 @@ bool DBcore::Open(
bool iSSL
)
{
LockMutex lock(m_mutex);
safe_delete_array(pHost);
safe_delete_array(pUser);
safe_delete_array(pPassword);
safe_delete_array(pDatabase);
LockMutex lock(&MDatabase);
safe_delete(pHost);
safe_delete(pUser);
safe_delete(pPassword);
safe_delete(pDatabase);
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
@@ -238,13 +223,13 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
if (errbuf) {
errbuf[0] = 0;
}
LockMutex lock(m_mutex);
LockMutex lock(&MDatabase);
if (GetStatus() == Connected) {
return true;
}
if (GetStatus() == Error) {
mysql_close(mysql);
mysql_init(mysql); // Initialize structure again
mysql_close(&mysql);
mysql_init(&mysql); // Initialize structure again
}
if (!pHost) {
return false;
@@ -261,184 +246,24 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
if (pSSL) {
flags |= CLIENT_SSL;
}
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
pStatus = Connected;
std::string connected_origin_host = pHost;
SetOriginHost(connected_origin_host);
return true;
}
else {
if (errnum) {
*errnum = mysql_errno(mysql);
*errnum = mysql_errno(&mysql);
}
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;
return false;
}
}
const std::string &DBcore::GetOriginHost() const
{
return origin_host;
}
void DBcore::SetOriginHost(const std::string &origin_host)
{
DBcore::origin_host = origin_host;
}
std::string DBcore::Escape(const std::string& s)
{
const std::size_t s_len = s.length();
std::vector<char> temp((s_len * 2) + 1, '\0');
mysql_real_escape_string(mysql, temp.data(), s.c_str(), s_len);
return temp.data();
}
void DBcore::SetMutex(Mutex *mutex)
{
safe_delete(m_mutex);
DBcore::m_mutex = mutex;
}
// executes multiple statements in one query
// do not use this in application logic
// this was built and maintained for database migrations only
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
{
SetMultiStatementsOn();
BenchTimer timer;
timer.reset();
LockMutex lock(m_mutex);
// Reconnect if we are not connected before hand.
if (pStatus != Connected) {
Open();
}
auto r = MySQLRequestResult{};
int status = mysql_real_query(mysql, query.c_str(), query.length());
// process single result
if (status != 0) {
unsigned int error_number = mysql_errno(mysql);
if (error_number == CR_SERVER_GONE_ERROR) {
pStatus = Error;
}
// error logging
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
std::string error_raw = fmt::format("{}", mysql_error(mysql));
std::string mysql_err = Strings::Trim(error_raw);
std::string clean_query = Strings::Replace(query, "\n", "");
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
MYSQL_RES *res = mysql_store_result(mysql);
uint32 row_count = 0;
if (res) {
row_count = (uint32) mysql_num_rows(res);
}
r = MySQLRequestResult(
res,
(uint32) mysql_affected_rows(mysql),
row_count,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
);
std::string error_message = mysql_error(mysql);
r.SetErrorMessage(error_message);
r.SetErrorNumber(mysql_errno(mysql));
if (res) {
mysql_free_result(res);
}
SetMultiStatementsOff();
return r;
}
}
int index = 0;
// there could be a query with a semicolon in the actual data, this is best effort for
// logging / display purposes
// rare that we see this when this is only used in DDL statements
auto pieces = Strings::Split(query, ";");
// process each statement result
do {
uint32 row_count = 0;
MYSQL_RES *res = mysql_store_result(mysql);
r = MySQLRequestResult(
res,
(uint32) mysql_affected_rows(mysql),
row_count,
(uint32) mysql_field_count(mysql),
(uint32) mysql_insert_id(mysql)
);
if (pieces.size() >= index) {
auto piece = pieces[index];
LogMySQLQuery(
"{} -- ({} row{} affected) ({}s)",
piece,
r.RowsAffected(),
r.RowsAffected() == 1 ? "" : "s",
std::to_string(timer.elapsed())
);
}
if (res) {
row_count = (uint32) mysql_num_rows(res);
}
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
if ((status = mysql_next_result(mysql)) > 0) {
if (mysql_errno(mysql) > 0) {
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
}
mysql_free_result(res);
// error logging
std::string error_message = mysql_error(mysql);
r.SetErrorMessage(error_message);
r.SetErrorNumber(mysql_errno(mysql));
SetMultiStatementsOff();
// we handle errors elsewhere
return r;
}
if (res) {
mysql_free_result(res);
}
index++;
} while (status == 0);
SetMultiStatementsOff();
return r;
}
mysql::PreparedStmt DBcore::Prepare(std::string query)
{
return mysql::PreparedStmt(*mysql, std::move(query), m_mutex);
}
+21 -75
View File
@@ -2,8 +2,8 @@
#define DBCORE_H
#ifdef _WINDOWS
#include <winsock2.h>
#include <windows.h>
#include <winsock2.h>
#include <windows.h>
#endif
#include "../common/mutex.h"
@@ -12,96 +12,42 @@
#include <mysql.h>
#include <string.h>
#include <mutex>
#define CR_SERVER_GONE_ERROR 2006
#define CR_SERVER_LOST 2013
namespace mysql { class PreparedStmt; }
class DBcore {
public:
enum eStatus {
Closed, Connected, Error
};
enum eStatus { Closed, Connected, Error };
DBcore();
~DBcore();
eStatus GetStatus() { return pStatus; }
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
eStatus GetStatus() { return pStatus; }
MySQLRequestResult QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
void TransactionBegin();
void TransactionCommit();
void TransactionRollback();
std::string Escape(const std::string& s);
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
void ping();
const std::string &GetOriginHost() const;
void SetOriginHost(const std::string &origin_host);
bool DoesTableExist(const std::string& table_name);
void SetMySQL(const DBcore &o)
{
mysql = o.mysql;
mysqlOwner = false;
}
void SetMutex(Mutex *mutex);
// only safe on connections shared with other threads if results buffered
// unsafe to use off main thread due to internal server logging
// throws std::runtime_error on failure
mysql::PreparedStmt Prepare(std::string query);
uint32 DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen);
void ping();
MYSQL* getMySQL(){ return &mysql; }
protected:
bool Open(
const char *iHost,
const char *iUser,
const char *iPassword,
const char *iDatabase,
uint32 iPort,
uint32 *errnum = 0,
char *errbuf = 0,
bool iCompress = false,
bool iSSL = false
);
bool Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase, uint32 iPort, uint32* errnum = 0, char* errbuf = 0, bool iCompress = false, bool iSSL = false);
private:
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
bool Open(uint32* errnum = 0, char* errbuf = 0);
MYSQL* mysql;
bool mysqlOwner;
Mutex *m_mutex;
MYSQL mysql;
Mutex MDatabase;
eStatus pStatus;
std::mutex m_query_lock{};
char* pHost;
char* pUser;
char* pPassword;
char* pDatabase;
bool pCompress;
uint32 pPort;
bool pSSL;
std::string origin_host;
char *pHost;
char *pUser;
char *pPassword;
char *pDatabase;
bool pCompress;
uint32 pPort;
bool pSSL;
// allows multiple queries to be executed within the same query
// do not use this under normal operation
// we use this during database migrations only currently
void SetMultiStatementsOn()
{
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
}
// disables multiple statements to be executed in one query
void SetMultiStatementsOff()
{
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
}
};
#endif
+121 -7
View File
@@ -11,7 +11,7 @@
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -19,17 +19,131 @@
#include "deity.h"
uint32 Deity::GetBitmask(uint32 deity_id)
EQEmu::deity::DeityTypeBit EQEmu::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
{
return IsValid(deity_id) ? deity_bitmasks[deity_id] : Deity::Bitmask::All;
switch (deity_type) {
case DeityBertoxxulous:
return bit_DeityBertoxxulous;
case DeityBrellSirilis:
return bit_DeityBrellSirilis;
case DeityCazicThule:
return bit_DeityCazicThule;
case DeityErollisiMarr:
return bit_DeityErollisiMarr;
case DeityBristlebane:
return bit_DeityBristlebane;
case DeityInnoruuk:
return bit_DeityInnoruuk;
case DeityKarana:
return bit_DeityKarana;
case DeityMithanielMarr:
return bit_DeityMithanielMarr;
case DeityPrexus:
return bit_DeityPrexus;
case DeityQuellious:
return bit_DeityQuellious;
case DeityRallosZek:
return bit_DeityRallosZek;
case DeityRodcetNife:
return bit_DeityRodcetNife;
case DeitySolusekRo:
return bit_DeitySolusekRo;
case DeityTheTribunal:
return bit_DeityTheTribunal;
case DeityTunare:
return bit_DeityTunare;
case DeityVeeshan:
return bit_DeityVeeshan;
case DeityAgnostic_LB:
case DeityAgnostic:
return bit_DeityAgnostic;
default:
return bit_DeityAll;
};
}
std::string Deity::GetName(uint32 deity_id)
EQEmu::deity::DeityType EQEmu::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
{
return IsValid(deity_id) ? deity_names[deity_id] : "UNKNOWN DEITY";
switch (deity_type_bit) {
case bit_DeityAgnostic:
return DeityAgnostic;
case bit_DeityBertoxxulous:
return DeityBertoxxulous;
case bit_DeityBrellSirilis:
return DeityBrellSirilis;
case bit_DeityCazicThule:
return DeityCazicThule;
case bit_DeityErollisiMarr:
return DeityErollisiMarr;
case bit_DeityBristlebane:
return DeityBristlebane;
case bit_DeityInnoruuk:
return DeityInnoruuk;
case bit_DeityKarana:
return DeityKarana;
case bit_DeityMithanielMarr:
return DeityMithanielMarr;
case bit_DeityPrexus:
return DeityPrexus;
case bit_DeityQuellious:
return DeityQuellious;
case bit_DeityRallosZek:
return DeityRallosZek;
case bit_DeityRodcetNife:
return DeityRodcetNife;
case bit_DeitySolusekRo:
return DeitySolusekRo;
case bit_DeityTheTribunal:
return DeityTheTribunal;
case bit_DeityTunare:
return DeityTunare;
case bit_DeityVeeshan:
return DeityVeeshan;
default:
return DeityUnknown;
};
}
bool Deity::IsValid(uint32 deity_id)
const char* EQEmu::deity::DeityName(DeityType deity_type)
{
return deity_names.find(deity_id) != deity_names.end();
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";
};
}
+51 -87
View File
@@ -21,97 +21,61 @@
#define COMMON_DEITY_H
#include "types.h"
#include <map>
#include <string>
#include <limits>
namespace Deity {
constexpr uint32 Unknown = 0;
constexpr uint32 Agnostic1 = 140;
constexpr uint32 Bertoxxulous = 201;
constexpr uint32 BrellSirilis = 202;
constexpr uint32 CazicThule = 203;
constexpr uint32 ErollisiMarr = 204;
constexpr uint32 Bristlebane = 205;
constexpr uint32 Innoruuk = 206;
constexpr uint32 Karana = 207;
constexpr uint32 MithanielMarr = 208;
constexpr uint32 Prexus = 209;
constexpr uint32 Quellious = 210;
constexpr uint32 RallosZek = 211;
constexpr uint32 RodcetNife = 212;
constexpr uint32 SolusekRo = 213;
constexpr uint32 TheTribunal = 214;
constexpr uint32 Tunare = 215;
constexpr uint32 Veeshan = 216;
constexpr uint32 Agnostic2 = 396;
namespace Bitmask {
constexpr uint32 Agnostic = 1;
constexpr uint32 Bertoxxulous = 2;
constexpr uint32 BrellSirilis = 4;
constexpr uint32 CazicThule = 8;
constexpr uint32 ErollisiMarr = 16;
constexpr uint32 Bristlebane = 32;
constexpr uint32 Innoruuk = 64;
constexpr uint32 Karana = 128;
constexpr uint32 MithanielMarr = 256;
constexpr uint32 Prexus = 512;
constexpr uint32 Quellious = 1024;
constexpr uint32 RallosZek = 2048;
constexpr uint32 RodcetNife = 4096;
constexpr uint32 SolusekRo = 8192;
constexpr uint32 TheTribunal = 16384;
constexpr uint32 Tunare = 32768;
constexpr uint32 Veeshan = 65536;
constexpr uint32 All = std::numeric_limits<uint32>::max();
}
namespace EQEmu
{
namespace deity {
enum DeityType {
DeityUnknown = 0,
DeityAgnostic_LB = 140,
DeityBertoxxulous = 201,
DeityBrellSirilis,
DeityCazicThule,
DeityErollisiMarr,
DeityBristlebane,
DeityInnoruuk,
DeityKarana,
DeityMithanielMarr,
DeityPrexus,
DeityQuellious,
DeityRallosZek,
DeityRodcetNife,
DeitySolusekRo,
DeityTheTribunal,
DeityTunare,
DeityVeeshan,
DeityAgnostic = 396
};
uint32 GetBitmask(uint32 deity_id);
std::string GetName(uint32 deity_id);
bool IsValid(uint32 deity_id);
}
enum DeityTypeBit : uint32 {
bit_DeityNone = 0x00000000,
bit_DeityAgnostic = 0x00000001,
bit_DeityBertoxxulous = 0x00000002,
bit_DeityBrellSirilis = 0x00000004,
bit_DeityCazicThule = 0x00000008,
bit_DeityErollisiMarr = 0x00000010,
bit_DeityBristlebane = 0x00000020,
bit_DeityInnoruuk = 0x00000040,
bit_DeityKarana = 0x00000080,
bit_DeityMithanielMarr = 0x00000100,
bit_DeityPrexus = 0x00000200,
bit_DeityQuellious = 0x00000400,
bit_DeityRallosZek = 0x00000800,
bit_DeityRodcetNife = 0x00001000,
bit_DeitySolusekRo = 0x00002000,
bit_DeityTheTribunal = 0x00004000,
bit_DeityTunare = 0x00008000,
bit_DeityVeeshan = 0x00010000,
bit_DeityAll = 0xFFFFFFFF
};
static std::map<uint32, std::string> deity_names = {
{ Deity::Agnostic1, "Agnostic" },
{ Deity::Agnostic2, "Agnostic" },
{ Deity::Bertoxxulous, "Bertoxxulous" },
{ Deity::BrellSirilis, "Brell Serilis" },
{ Deity::Bristlebane, "Bristlebane" },
{ Deity::CazicThule, "Cazic-Thule" },
{ Deity::ErollisiMarr, "Erollisi Marr" },
{ Deity::Innoruuk, "Innoruuk" },
{ Deity::Karana, "Karana" },
{ Deity::MithanielMarr, "Mithaniel Marr" },
{ Deity::Prexus, "Prexus" },
{ Deity::Quellious, "Quellious" },
{ Deity::RallosZek, "Rallos Zek" },
{ Deity::RodcetNife, "Rodcet Nife" },
{ Deity::SolusekRo, "Solusek Ro" },
{ Deity::TheTribunal, "The Tribunal" },
{ Deity::Tunare, "Tunare" },
{ Deity::Veeshan, "Veeshan" }
};
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
extern const char* DeityName(DeityType deity_type);
static std::map<uint32, uint32> deity_bitmasks = {
{ Deity::Agnostic1, Deity::Bitmask::Agnostic },
{ Deity::Agnostic2, Deity::Bitmask::Agnostic },
{ Deity::Bertoxxulous, Deity::Bitmask::Bertoxxulous },
{ Deity::BrellSirilis, Deity::Bitmask::BrellSirilis },
{ Deity::CazicThule, Deity::Bitmask::CazicThule },
{ Deity::ErollisiMarr, Deity::Bitmask::ErollisiMarr },
{ Deity::Bristlebane, Deity::Bitmask::Bristlebane },
{ Deity::Innoruuk, Deity::Bitmask::Innoruuk },
{ Deity::Karana, Deity::Bitmask::Karana },
{ Deity::MithanielMarr, Deity::Bitmask::MithanielMarr },
{ Deity::Prexus, Deity::Bitmask::Prexus },
{ Deity::Quellious, Deity::Bitmask::Quellious },
{ Deity::RallosZek, Deity::Bitmask::RallosZek },
{ Deity::RodcetNife, Deity::Bitmask::RodcetNife },
{ Deity::SolusekRo, Deity::Bitmask::SolusekRo },
{ Deity::TheTribunal, Deity::Bitmask::TheTribunal },
{ Deity::Tunare, Deity::Bitmask::Tunare },
{ Deity::Veeshan, Deity::Bitmask::Veeshan }
};
} /*deity*/
} /*EQEmu*/
#endif /* COMMON_DEITY_H */
-165
View File
@@ -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;
}
-20
View File
@@ -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
-75
View File
@@ -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);
}
}
-22
View File
@@ -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
-649
View File
@@ -1,649 +0,0 @@
#include "dynamic_zone_base.h"
#include "database.h"
#include "eqemu_logsys.h"
#include "repositories/instance_list_repository.h"
#include "repositories/instance_list_player_repository.h"
#include "rulesys.h"
#include "servertalk.h"
#include "util/uuid.h"
DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry)
{
LoadRepositoryResult(std::move(entry));
}
uint32_t DynamicZoneBase::Create()
{
if (GetInstanceID() == 0)
{
CreateInstance();
}
m_uuid = EQ::Util::UUID::Generate().ToString();
m_id = SaveToDatabase();
return m_id;
}
uint32_t DynamicZoneBase::CreateInstance()
{
if (m_instance_id)
{
LogDynamicZones("CreateInstance failed, instance id [{}] already created", m_instance_id);
return 0;
}
if (!m_zone_id)
{
LogDynamicZones("CreateInstance failed, invalid zone id [{}]", m_zone_id);
return 0;
}
uint16_t unused_instance_id = 0;
if (!GetDatabase().GetUnusedInstanceID(unused_instance_id)) // todo: doesn't this race with insert?
{
LogDynamicZones("Failed to find unused instance id");
return 0;
}
m_start_time = std::chrono::system_clock::now();
m_expire_time = m_start_time + m_duration;
auto insert_instance = InstanceListRepository::NewEntity();
insert_instance.id = unused_instance_id;
insert_instance.zone = m_zone_id;
insert_instance.version = m_zone_version;
insert_instance.start_time = static_cast<int>(std::chrono::system_clock::to_time_t(m_start_time));
insert_instance.duration = static_cast<int>(m_duration.count());
insert_instance.never_expires = m_never_expires;
auto instance = InstanceListRepository::InsertOne(GetDatabase(), insert_instance);
if (instance.id == 0)
{
LogDynamicZones("Failed to create instance [{}] for zone [{}]", unused_instance_id, m_zone_id);
return 0;
}
m_instance_id = instance.id;
return m_instance_id;
}
void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry)
{
m_id = dz_entry.id;
m_uuid = std::move(dz_entry.uuid);
m_name = std::move(dz_entry.name);
m_leader.id = dz_entry.leader_id;
m_min_players = dz_entry.min_players;
m_max_players = dz_entry.max_players;
m_instance_id = dz_entry.instance_id;
m_type = static_cast<DynamicZoneType>(dz_entry.type);
m_dz_switch_id = dz_entry.dz_switch_id;
m_compass.zone_id = dz_entry.compass_zone_id;
m_compass.x = dz_entry.compass_x;
m_compass.y = dz_entry.compass_y;
m_compass.z = dz_entry.compass_z;
m_safereturn.zone_id = dz_entry.safe_return_zone_id;
m_safereturn.x = dz_entry.safe_return_x;
m_safereturn.y = dz_entry.safe_return_y;
m_safereturn.z = dz_entry.safe_return_z;
m_safereturn.heading = dz_entry.safe_return_heading;
m_zonein.x = dz_entry.zone_in_x;
m_zonein.y = dz_entry.zone_in_y;
m_zonein.z = dz_entry.zone_in_z;
m_zonein.heading = dz_entry.zone_in_heading;
m_has_zonein = (dz_entry.has_zone_in != 0);
// instance_list portion
m_zone_id = dz_entry.zone;
m_zone_version = dz_entry.version;
m_start_time = std::chrono::system_clock::from_time_t(dz_entry.start_time);
m_duration = std::chrono::seconds(dz_entry.duration);
m_never_expires = (dz_entry.never_expires != 0);
m_expire_time = m_start_time + m_duration;
}
void DynamicZoneBase::AddMemberFromRepositoryResult(
DynamicZoneMembersRepository::MemberWithName&& entry)
{
auto status = DynamicZoneMemberStatus::Unknown;
if (m_leader.id == entry.character_id)
{
m_leader.name = entry.character_name;
}
AddInternalMember({ entry.character_id, std::move(entry.character_name), status });
}
uint32_t DynamicZoneBase::SaveToDatabase()
{
LogDynamicZonesDetail("Saving dz instance [{}] to database", m_instance_id);
if (m_instance_id != 0)
{
auto insert_dz = DynamicZonesRepository::NewEntity();
insert_dz.uuid = m_uuid;
insert_dz.name = m_name;
insert_dz.leader_id = m_leader.id;
insert_dz.min_players = m_min_players;
insert_dz.max_players = m_max_players;
insert_dz.instance_id = m_instance_id,
insert_dz.type = static_cast<int>(m_type);
insert_dz.dz_switch_id = m_dz_switch_id;
insert_dz.compass_zone_id = m_compass.zone_id;
insert_dz.compass_x = m_compass.x;
insert_dz.compass_y = m_compass.y;
insert_dz.compass_z = m_compass.z;
insert_dz.safe_return_zone_id = m_safereturn.zone_id;
insert_dz.safe_return_x = m_safereturn.x;
insert_dz.safe_return_y = m_safereturn.y;
insert_dz.safe_return_z = m_safereturn.z;
insert_dz.safe_return_heading = m_safereturn.heading;
insert_dz.zone_in_x = m_zonein.x;
insert_dz.zone_in_y = m_zonein.y;
insert_dz.zone_in_z = m_zonein.z;
insert_dz.zone_in_heading = m_zonein.heading;
insert_dz.has_zone_in = m_has_zonein;
auto inserted_dz = DynamicZonesRepository::InsertOne(GetDatabase(), insert_dz);
return inserted_dz.id;
}
return 0;
}
bool DynamicZoneBase::AddMember(const DynamicZoneMember& add_member)
{
if (HasMember(add_member.id))
{
return false;
}
DynamicZoneMembersRepository::AddMember(GetDatabase(), m_id, add_member.id);
GetDatabase().AddClientToInstance(m_instance_id, add_member.id);
ProcessMemberAddRemove(add_member, false);
SendServerPacket(CreateServerMemberAddRemovePacket(add_member, false).get());
return true;
}
bool DynamicZoneBase::RemoveMember(uint32_t character_id)
{
auto remove_member = GetMemberData(character_id);
return RemoveMember(remove_member);
}
bool DynamicZoneBase::RemoveMember(const std::string& character_name)
{
auto remove_member = GetMemberData(character_name);
return RemoveMember(remove_member);
}
bool DynamicZoneBase::RemoveMember(const DynamicZoneMember& remove_member)
{
if (remove_member.id == 0)
{
return false;
}
DynamicZoneMembersRepository::RemoveMember(GetDatabase(), m_id, remove_member.id);
GetDatabase().RemoveClientFromInstance(m_instance_id, remove_member.id);
ProcessMemberAddRemove(remove_member, true);
SendServerPacket(CreateServerMemberAddRemovePacket(remove_member, true).get());
return true;
}
bool DynamicZoneBase::SwapMember(
const DynamicZoneMember& add_member, const std::string& remove_char_name)
{
auto remove_member = GetMemberData(remove_char_name);
if (!add_member.IsValid() || !remove_member.IsValid())
{
return false;
}
// make remove and add atomic to avoid racing with separate world messages
DynamicZoneMembersRepository::RemoveMember(GetDatabase(), m_id, remove_member.id);
GetDatabase().RemoveClientFromInstance(m_instance_id, remove_member.id);
DynamicZoneMembersRepository::AddMember(GetDatabase(), m_id, add_member.id);
GetDatabase().AddClientToInstance(m_instance_id, add_member.id);
ProcessMemberAddRemove(remove_member, true);
ProcessMemberAddRemove(add_member, false);
SendServerPacket(CreateServerMemberSwapPacket(remove_member, add_member).get());
return true;
}
void DynamicZoneBase::RemoveAllMembers()
{
DynamicZoneMembersRepository::RemoveAllMembers(GetDatabase(), m_id);
GetDatabase().RemoveClientsFromInstance(GetInstanceID());
ProcessRemoveAllMembers();
SendServerPacket(CreateServerRemoveAllMembersPacket().get());
}
void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
{
LogDynamicZonesDetail("Saving [{}] member(s) for dz [{}]", members.size(), m_id);
m_members = members;
// the lower level instance_list_players needs to be kept updated as well
std::vector<DynamicZoneMembersRepository::DynamicZoneMembers> insert_members;
std::vector<InstanceListPlayerRepository::InstanceListPlayer> insert_players;
for (const auto& member : m_members)
{
DynamicZoneMembersRepository::DynamicZoneMembers member_entry{};
member_entry.dynamic_zone_id = m_id;
member_entry.character_id = member.id;
insert_members.emplace_back(member_entry);
InstanceListPlayerRepository::InstanceListPlayer player_entry;
player_entry.id = static_cast<int>(m_instance_id);
player_entry.charid = static_cast<int>(member.id);
insert_players.emplace_back(player_entry);
}
DynamicZoneMembersRepository::InsertOrUpdateMany(GetDatabase(), insert_members);
InstanceListPlayerRepository::InsertOrUpdateMany(GetDatabase(), insert_players);
}
void DynamicZoneBase::SetCompass(const DynamicZoneLocation& location, bool update_db)
{
ProcessCompassChange(location);
if (update_db)
{
LogDynamicZonesDetail("Saving [{}] compass zone: [{}] xyz: ([{}], [{}], [{}])",
m_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z);
DynamicZonesRepository::UpdateCompass(GetDatabase(),
m_id, m_compass.zone_id, m_compass.x, m_compass.y, m_compass.z);
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetCompass, location).get());
}
}
void DynamicZoneBase::SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db)
{
SetCompass({ zone_id, x, y, z, 0.0f }, update_db);
}
void DynamicZoneBase::SetSafeReturn(const DynamicZoneLocation& location, bool update_db)
{
m_safereturn = location;
if (update_db)
{
LogDynamicZonesDetail("Saving [{}] safereturn zone: [{}] xyzh: ([{}], [{}], [{}], [{}])",
m_id, m_safereturn.zone_id, m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading);
DynamicZonesRepository::UpdateSafeReturn(GetDatabase(), m_id, m_safereturn.zone_id,
m_safereturn.x, m_safereturn.y, m_safereturn.z, m_safereturn.heading);
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetSafeReturn, location).get());
}
}
void DynamicZoneBase::SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db)
{
SetSafeReturn({ zone_id, x, y, z, heading }, update_db);
}
void DynamicZoneBase::SetZoneInLocation(const DynamicZoneLocation& location, bool update_db)
{
m_zonein = location;
m_has_zonein = true;
if (update_db)
{
LogDynamicZonesDetail("Saving [{}] zonein zone: [{}] xyzh: ([{}], [{}], [{}], [{}])",
m_id, m_zone_id, m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading);
DynamicZonesRepository::UpdateZoneIn(GetDatabase(), m_id, m_zone_id,
m_zonein.x, m_zonein.y, m_zonein.z, m_zonein.heading, m_has_zonein);
SendServerPacket(CreateServerDzLocationPacket(ServerOP_DzSetZoneIn, location).get());
}
}
void DynamicZoneBase::SetZoneInLocation(float x, float y, float z, float heading, bool update_db)
{
SetZoneInLocation({ 0, x, y, z, heading }, update_db);
}
void DynamicZoneBase::SetSwitchID(int dz_switch_id, bool update_db)
{
m_dz_switch_id = dz_switch_id;
if (update_db)
{
DynamicZonesRepository::UpdateSwitchID(GetDatabase(), m_id, dz_switch_id);
SendServerPacket(CreateServerDzSwitchIDPacket().get());
}
}
void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update_db)
{
m_leader = new_leader;
if (update_db)
{
DynamicZonesRepository::UpdateLeaderID(GetDatabase(), m_id, new_leader.id);
}
}
uint32_t DynamicZoneBase::GetSecondsRemaining() const
{
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(GetDurationRemaining()).count();
return std::max(0, static_cast<int>(remaining));
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberAddRemovePacket(
const DynamicZoneMember& member, bool removed)
{
constexpr uint32_t pack_size = sizeof(ServerDzMember_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzAddRemoveMember, pack_size);
auto buf = reinterpret_cast<ServerDzMember_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->dz_zone_id = GetZoneID();
buf->dz_instance_id = GetInstanceID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->removed = removed;
buf->character_id = member.id;
buf->character_status = static_cast<uint8_t>(member.status);
strn0cpy(buf->character_name, member.name.c_str(), sizeof(buf->character_name));
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberSwapPacket(
const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member)
{
constexpr uint32_t pack_size = sizeof(ServerDzMemberSwap_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSwapMembers, pack_size);
auto buf = reinterpret_cast<ServerDzMemberSwap_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->dz_zone_id = GetZoneID();
buf->dz_instance_id = GetInstanceID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->add_character_status = static_cast<uint8_t>(add_member.status);
buf->add_character_id = add_member.id;
buf->remove_character_id = remove_member.id;
strn0cpy(buf->add_character_name, add_member.name.c_str(), sizeof(buf->add_character_name));
strn0cpy(buf->remove_character_name, remove_member.name.c_str(), sizeof(buf->remove_character_name));
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerRemoveAllMembersPacket()
{
constexpr uint32_t pack_size = sizeof(ServerDzID_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzRemoveAllMembers, pack_size);
auto buf = reinterpret_cast<ServerDzID_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->dz_zone_id = GetZoneID();
buf->dz_instance_id = GetInstanceID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzLocationPacket(
uint16_t server_opcode, const DynamicZoneLocation& location)
{
constexpr uint32_t pack_size = sizeof(ServerDzLocation_Struct);
auto pack = std::make_unique<ServerPacket>(server_opcode, pack_size);
auto buf = reinterpret_cast<ServerDzLocation_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->zone_id = location.zone_id;
buf->x = location.x;
buf->y = location.y;
buf->z = location.z;
buf->heading = location.heading;
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzSwitchIDPacket()
{
constexpr uint32_t pack_size = sizeof(ServerDzSwitchID_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSetSwitchID, pack_size);
auto buf = reinterpret_cast<ServerDzSwitchID_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->dz_switch_id = GetSwitchID();
return pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberStatusPacket(
uint32_t character_id, DynamicZoneMemberStatus status)
{
constexpr uint32_t pack_size = sizeof(ServerDzMemberStatus_Struct);
auto pack = std::make_unique<ServerPacket>(ServerOP_DzUpdateMemberStatus, pack_size);
auto buf = reinterpret_cast<ServerDzMemberStatus_Struct*>(pack->pBuffer);
buf->dz_id = GetID();
buf->sender_zone_id = GetCurrentZoneID();
buf->sender_instance_id = GetCurrentInstanceID();
buf->status = static_cast<uint8_t>(status);
buf->character_id = character_id;
return pack;
}
uint32_t DynamicZoneBase::GetDatabaseMemberCount()
{
return DynamicZoneMembersRepository::GetCountWhere(GetDatabase(),
fmt::format("dynamic_zone_id = {}", m_id));
}
bool DynamicZoneBase::HasDatabaseMember(uint32_t character_id)
{
if (character_id == 0)
{
return false;
}
auto entries = DynamicZoneMembersRepository::GetWhere(GetDatabase(), fmt::format(
"dynamic_zone_id = {} AND character_id = {}",
m_id, character_id
));
return entries.size() != 0;
}
void DynamicZoneBase::AddInternalMember(const DynamicZoneMember& member)
{
if (!HasMember(member.id))
{
m_members.emplace_back(member);
}
}
void DynamicZoneBase::RemoveInternalMember(uint32_t character_id)
{
m_members.erase(std::remove_if(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) { return member.id == character_id; }
), m_members.end());
}
bool DynamicZoneBase::HasMember(uint32_t character_id)
{
return std::any_of(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) { return member.id == character_id; });
}
bool DynamicZoneBase::HasMember(const std::string& character_name)
{
return std::any_of(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) {
return strcasecmp(member.name.c_str(), character_name.c_str()) == 0;
});
}
DynamicZoneMember DynamicZoneBase::GetMemberData(uint32_t character_id)
{
auto it = std::find_if(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) { return member.id == character_id; });
DynamicZoneMember member_data;
if (it != m_members.end())
{
member_data = *it;
}
return member_data;
}
DynamicZoneMember DynamicZoneBase::GetMemberData(const std::string& character_name)
{
auto it = std::find_if(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) {
return strcasecmp(member.name.c_str(), character_name.c_str()) == 0;
});
DynamicZoneMember member_data;
if (it != m_members.end())
{
member_data = *it;
}
return member_data;
}
bool DynamicZoneBase::SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status)
{
if (status == DynamicZoneMemberStatus::InDynamicZone && !RuleB(DynamicZone, EnableInDynamicZoneStatus))
{
status = DynamicZoneMemberStatus::Online;
}
if (character_id == m_leader.id)
{
m_leader.status = status;
}
auto it = std::find_if(m_members.begin(), m_members.end(),
[&](const DynamicZoneMember& member) { return member.id == character_id; });
if (it != m_members.end() && it->status != status)
{
it->status = status;
return true;
}
return false;
}
void DynamicZoneBase::SetMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status)
{
auto update_member = GetMemberData(character_id);
if (update_member.IsValid())
{
ProcessMemberStatusChange(character_id, status);
SendServerPacket(CreateServerMemberStatusPacket(character_id, status).get());
}
}
void DynamicZoneBase::ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed)
{
if (!removed)
{
AddInternalMember(member);
}
else
{
RemoveInternalMember(member.id);
}
}
bool DynamicZoneBase::ProcessMemberStatusChange(uint32_t character_id, DynamicZoneMemberStatus status)
{
return SetInternalMemberStatus(character_id, status);
}
std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
{
switch (dz_type)
{
case DynamicZoneType::Expedition:
return "Expedition";
case DynamicZoneType::Tutorial:
return "Tutorial";
case DynamicZoneType::Task:
return "Task";
case DynamicZoneType::Mission:
return "Mission";
case DynamicZoneType::Quest:
return "Quest";
default:
return "Unknown";
}
}
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
{
EQ::Net::DynamicPacket dyn_pack;
dyn_pack.PutSerialize(0, *this);
LogDynamicZonesDetail("Serialized server dz size [{}]", dyn_pack.Length());
return dyn_pack;
}
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzCreatePacket(
uint16_t origin_zone_id, uint16_t origin_instance_id)
{
EQ::Net::DynamicPacket dyn_pack = GetSerializedDzPacket();
auto pack_size = sizeof(ServerDzCreateSerialized_Struct) + dyn_pack.Length();
auto pack = std::make_unique<ServerPacket>(ServerOP_DzCreated, static_cast<uint32_t>(pack_size));
auto buf = reinterpret_cast<ServerDzCreateSerialized_Struct*>(pack->pBuffer);
buf->origin_zone_id = origin_zone_id;
buf->origin_instance_id = origin_instance_id;
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
return pack;
}
void DynamicZoneBase::LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size)
{
LogDynamicZonesDetail("Deserializing server dz size [{}]", cereal_size);
EQ::Util::MemoryStreamReader ss(cereal_data, cereal_size);
cereal::BinaryInputArchive archive(ss);
archive(*this);
}
void DynamicZoneBase::LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template)
{
m_zone_id = dz_template.zone_id;
m_zone_version = dz_template.zone_version;
m_name = dz_template.name;
m_min_players = dz_template.min_players;
m_max_players = dz_template.max_players;
m_duration = std::chrono::seconds(dz_template.duration_seconds);
m_dz_switch_id = dz_template.dz_switch_id;
m_compass.zone_id = dz_template.compass_zone_id;
m_compass.x = dz_template.compass_x;
m_compass.y = dz_template.compass_y;
m_compass.z = dz_template.compass_z;
m_safereturn.zone_id = dz_template.return_zone_id;
m_safereturn.x = dz_template.return_x;
m_safereturn.y = dz_template.return_y;
m_safereturn.z = dz_template.return_z;
m_safereturn.heading = dz_template.return_h;
m_has_zonein = dz_template.override_zone_in;
m_zonein.x = dz_template.zone_in_x;
m_zonein.y = dz_template.zone_in_y;
m_zonein.z = dz_template.zone_in_z;
m_zonein.heading = dz_template.zone_in_h;
}
-220
View File
@@ -1,220 +0,0 @@
#ifndef COMMON_DYNAMIC_ZONE_BASE_H
#define COMMON_DYNAMIC_ZONE_BASE_H
#include "eq_constants.h"
#include "net/packet.h"
#include "repositories/dynamic_zones_repository.h"
#include "repositories/dynamic_zone_members_repository.h"
#include "repositories/dynamic_zone_templates_repository.h"
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
class Database;
class ServerPacket;
struct DynamicZoneMember
{
uint32_t id = 0;
std::string name;
DynamicZoneMemberStatus status = DynamicZoneMemberStatus::Unknown;
DynamicZoneMember() = default;
DynamicZoneMember(uint32_t id, std::string name_)
: id(id), name{std::move(name_)} {}
DynamicZoneMember(uint32_t id, std::string name_, DynamicZoneMemberStatus status_)
: id(id), name{std::move(name_)}, status(status_) {}
bool IsOnline() const { return status == DynamicZoneMemberStatus::Online ||
status == DynamicZoneMemberStatus::InDynamicZone; }
bool IsValid() const { return id != 0 && !name.empty(); }
template<class Archive>
void serialize(Archive& archive)
{
archive(id, name, status);
}
};
struct DynamicZoneLocation
{
uint32_t zone_id = 0;
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
float heading = 0.0f;
DynamicZoneLocation() = default;
DynamicZoneLocation(uint32_t zone_id_, float x_, float y_, float z_, float heading_)
: zone_id(zone_id_), x(x_), y(y_), z(z_), heading(heading_) {}
template<class Archive>
void serialize(Archive& archive)
{
archive(zone_id, x, y, z, heading);
}
};
class DynamicZoneBase
{
public:
virtual ~DynamicZoneBase() = default;
DynamicZoneBase(const DynamicZoneBase&) = default;
DynamicZoneBase(DynamicZoneBase&&) = default;
DynamicZoneBase& operator=(const DynamicZoneBase&) = default;
DynamicZoneBase& operator=(DynamicZoneBase&&) = default;
DynamicZoneBase() = default;
DynamicZoneBase(uint32_t dz_id) : m_id(dz_id) {}
DynamicZoneBase(DynamicZoneType type) : m_type(type) {}
DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry);
static std::string GetDynamicZoneTypeName(DynamicZoneType dz_type);
virtual void SetSecondsRemaining(uint32_t seconds_remaining) = 0;
int GetDuration() const { return static_cast<int>(m_duration.count()); }
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
uint32_t GetID() const { return m_id; }
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); }
uint32_t GetLeaderID() const { return m_leader.id; }
uint32_t GetMaxPlayers() const { return m_max_players; }
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
uint32_t GetMinPlayers() const { return m_min_players; }
uint32_t GetSecondsRemaining() const;
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
uint32_t GetZoneVersion() const { return m_zone_version; }
int GetSwitchID() const { return m_dz_switch_id; }
DynamicZoneType GetType() const { return m_type; }
const std::string& GetLeaderName() const { return m_leader.name; }
const std::string& GetName() const { return m_name; }
const std::string& GetUUID() const { return m_uuid; }
const DynamicZoneMember& GetLeader() const { return m_leader; }
const std::vector<DynamicZoneMember>& GetMembers() const { return m_members; }
const DynamicZoneLocation& GetCompassLocation() const { return m_compass; }
const DynamicZoneLocation& GetSafeReturnLocation() const { return m_safereturn; }
const DynamicZoneLocation& GetZoneInLocation() const { return m_zonein; }
std::chrono::system_clock::duration GetDurationRemaining() const { return m_expire_time - std::chrono::system_clock::now(); }
bool AddMember(const DynamicZoneMember& add_member);
void AddMemberFromRepositoryResult(DynamicZoneMembersRepository::MemberWithName&& entry);
uint32_t GetDatabaseMemberCount();
DynamicZoneMember GetMemberData(uint32_t character_id);
DynamicZoneMember GetMemberData(const std::string& character_name);
EQ::Net::DynamicPacket GetSerializedDzPacket();
bool HasDatabaseMember(uint32_t character_id);
bool HasMember(uint32_t character_id);
bool HasMember(const std::string& character_name);
bool HasMembers() const { return !m_members.empty(); }
bool HasZoneInLocation() const { return m_has_zonein; }
bool IsExpired() const { return m_expire_time < std::chrono::system_clock::now(); }
bool IsInstanceID(uint32_t instance_id) const { return (m_instance_id != 0 && m_instance_id == instance_id); }
bool IsValid() const { return m_instance_id != 0; }
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const { return zone_id == m_zone_id && instance_id == m_instance_id; }
void LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size);
void LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template);
void RemoveAllMembers();
bool RemoveMember(uint32_t character_id);
bool RemoveMember(const std::string& character_name);
bool RemoveMember(const DynamicZoneMember& remove_member);
void SaveMembers(const std::vector<DynamicZoneMember>& members);
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
void SetCompass(uint32_t zone_id, float x, float y, float z, bool update_db = false);
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
void SetLeader(const DynamicZoneMember& leader, bool update_db = false);
void SetMaxPlayers(uint32_t max_players) { m_max_players = max_players; }
void SetMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
void SetMinPlayers(uint32_t min_players) { m_min_players = min_players; }
void SetName(const std::string& name) { m_name = name; }
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
void SetSwitchID(int dz_switch_id, bool update_db = false);
void SetType(DynamicZoneType type) { m_type = type; }
void SetUUID(std::string uuid) { m_uuid = std::move(uuid); }
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
void SetZoneInLocation(float x, float y, float z, float heading, bool update_db = false);
bool SwapMember(const DynamicZoneMember& add_member, const std::string& remove_char_name);
protected:
virtual uint16_t GetCurrentInstanceID() { return 0; }
virtual uint16_t GetCurrentZoneID() { return 0; }
virtual Database& GetDatabase() = 0;
virtual void ProcessCompassChange(const DynamicZoneLocation& location) { m_compass = location; }
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
virtual void ProcessSetSwitchID(int dz_switch_id) { m_dz_switch_id = dz_switch_id; }
virtual bool SendServerPacket(ServerPacket* packet) = 0;
void AddInternalMember(const DynamicZoneMember& member);
uint32_t Create();
uint32_t CreateInstance();
void LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry);
void RemoveInternalMember(uint32_t character_id);
uint32_t SaveToDatabase();
bool SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
std::unique_ptr<ServerPacket> CreateServerDzCreatePacket(uint16_t origin_zone_id, uint16_t origin_instance_id);
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
std::unique_ptr<ServerPacket> CreateServerDzSwitchIDPacket();
std::unique_ptr<ServerPacket> CreateServerMemberAddRemovePacket(const DynamicZoneMember& member, bool removed);
std::unique_ptr<ServerPacket> CreateServerMemberStatusPacket(uint32_t character_id, DynamicZoneMemberStatus status);
std::unique_ptr<ServerPacket> CreateServerMemberSwapPacket(const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member);
std::unique_ptr<ServerPacket> CreateServerRemoveAllMembersPacket();
uint32_t m_id = 0;
uint32_t m_zone_id = 0;
uint32_t m_instance_id = 0;
uint32_t m_zone_version = 0;
uint32_t m_min_players = 0;
uint32_t m_max_players = 0;
int m_dz_switch_id = 0;
bool m_never_expires = false;
bool m_has_zonein = false;
bool m_has_member_statuses = false;
std::string m_name;
std::string m_uuid;
DynamicZoneMember m_leader;
DynamicZoneType m_type{ DynamicZoneType::None };
DynamicZoneLocation m_compass;
DynamicZoneLocation m_safereturn;
DynamicZoneLocation m_zonein;
std::chrono::seconds m_duration;
std::chrono::time_point<std::chrono::system_clock> m_start_time;
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
std::vector<DynamicZoneMember> m_members;
public:
template<class Archive>
void serialize(Archive& archive)
{
archive(
m_id,
m_zone_id,
m_instance_id,
m_zone_version,
m_min_players,
m_max_players,
m_dz_switch_id,
m_never_expires,
m_has_zonein,
m_has_member_statuses,
m_name,
m_uuid,
m_leader,
m_type,
m_compass,
m_safereturn,
m_zonein,
m_duration,
m_start_time,
m_expire_time,
m_members
);
}
};
#endif
+90 -389
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -18,13 +18,9 @@
*/
#include "emu_constants.h"
#include "bodytypes.h"
#include "data_verification.h"
#include "eqemu_logsys.h"
#include "eqemu_logsys_log_aliases.h"
#include "rulesys.h"
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
int16 EQEmu::invtype::GetInvTypeSize(int16 inv_type) {
static const int16 local_array[] = {
POSSESSIONS_SIZE,
BANK_SIZE,
@@ -59,395 +55,100 @@ int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
return local_array[inv_type];
}
uint32 Bug::GetID(const std::string& category_name)
{
for (const auto& e : bug_category_names) {
if (e.second == category_name) {
return e.first;
}
const char* EQEmu::bug::CategoryIDToCategoryName(CategoryID category_id) {
switch (category_id) {
case catVideo:
return "Video";
case catAudio:
return "Audio";
case catPathing:
return "Pathing";
case catQuest:
return "Quest";
case catTradeskills:
return "Tradeskills";
case catSpellStacking:
return "Spell stacking";
case catDoorsPortals:
return "Doors/Portals";
case catItems:
return "Items";
case catNPC:
return "NPC";
case catDialogs:
return "Dialogs";
case catLoNTCG:
return "LoN - TCG";
case catMercenaries:
return "Mercenaries";
case catOther:
default:
return "Other";
}
return Bug::Category::Other;
}
std::string Bug::GetName(uint32 category_id)
{
return IsValid(category_id) ? bug_category_names[category_id] : "UNKNOWN BUG CATEGORY";
EQEmu::bug::CategoryID EQEmu::bug::CategoryNameToCategoryID(const char* category_name) {
if (!category_name)
return catOther;
if (!strcmp(category_name, "Video"))
return catVideo;
if (!strcmp(category_name, "Audio"))
return catAudio;
if (!strcmp(category_name, "Pathing"))
return catPathing;
if (!strcmp(category_name, "Quest"))
return catQuest;
if (!strcmp(category_name, "Tradeskills"))
return catTradeskills;
if (!strcmp(category_name, "Spell stacking"))
return catSpellStacking;
if (!strcmp(category_name, "Doors/Portals"))
return catDoorsPortals;
if (!strcmp(category_name, "Items"))
return catItems;
if (!strcmp(category_name, "NPC"))
return catNPC;
if (!strcmp(category_name, "Dialogs"))
return catDialogs;
if (!strcmp(category_name, "LoN - TCG"))
return catLoNTCG;
if (!strcmp(category_name, "Mercenaries"))
return catMercenaries;
return catOther;
}
bool Bug::IsValid(uint32 category_id)
{
return bug_category_names.find(category_id) != bug_category_names.end();
}
std::string Stance::GetName(uint8 stance_id)
{
return IsValid(stance_id) ? stance_names[stance_id] : "UNKNOWN STANCE";
}
bool Stance::IsValid(uint8 stance_id)
{
return stance_names.find(stance_id) != stance_names.end();
}
uint8 Stance::GetIndex(uint8 stance_id)
{
return IsValid(stance_id) ? (stance_id - Stance::Passive) : 0;
}
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
{
static const std::map<uint8, std::string> language_map = {
{ Language::CommonTongue, "Common Tongue" },
{ Language::Barbarian, "Barbarian" },
{ Language::Erudian, "Erudian" },
{ Language::Elvish, "Elvish" },
{ Language::DarkElvish, "Dark Elvish" },
{ Language::Dwarvish, "Dwarvish" },
{ Language::Troll, "Troll" },
{ Language::Ogre, "Ogre" },
{ Language::Gnomish, "Gnomish" },
{ Language::Halfling, "Halfling" },
{ Language::ThievesCant, "Thieves Cant" },
{ Language::OldErudian, "Old Erudian" },
{ Language::ElderElvish, "Elder Elvish" },
{ Language::Froglok, "Froglok" },
{ Language::Goblin, "Goblin" },
{ Language::Gnoll, "Gnoll" },
{ Language::CombineTongue, "Combine Tongue" },
{ Language::ElderTeirDal, "Elder Teir'Dal" },
{ Language::Lizardman, "Lizardman" },
{ Language::Orcish, "Orcish" },
{ Language::Faerie, "Faerie" },
{ Language::Dragon, "Dragon" },
{ Language::ElderDragon, "Elder Dragon" },
{ Language::DarkSpeech, "Dark Speech" },
{ Language::VahShir, "Vah Shir" },
{ Language::Alaran, "Alaran" },
{ Language::Hadal, "Hadal" },
{ Language::Unknown27, "Unknown" }
};
return language_map;
}
std::string EQ::constants::GetLanguageName(uint8 language_id)
{
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
return std::string();
const char *EQEmu::constants::GetStanceName(StanceType stance_type) {
switch (stance_type) {
case stanceUnknown:
return "Unknown";
case stancePassive:
return "Passive";
case stanceBalanced:
return "Balanced";
case stanceEfficient:
return "Efficient";
case stanceReactive:
return "Reactive";
case stanceAggressive:
return "Aggressive";
case stanceAssist:
return "Assist";
case stanceBurn:
return "Burn";
case stanceEfficient2:
return "Efficient2";
case stanceBurnAE:
return "BurnAE";
default:
return "Invalid";
}
return EQ::constants::GetLanguageMap().find(language_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" },
};
int EQEmu::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
if (stance_type >= EQEmu::constants::stancePassive && stance_type <= EQEmu::constants::stanceBurnAE)
return (stance_type - EQEmu::constants::stancePassive);
return 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<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<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::Say, "Say" },
{ 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::Say, EmoteTypes::Proximity)) {
return std::string();
}
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
}
const std::map<uint32, std::string>& EQ::constants::GetAppearanceTypeMap()
{
static const std::map<uint32, std::string> appearance_type_map = {
{ AppearanceType::Die, "Die" },
{ AppearanceType::WhoLevel, "Who Level" },
{ AppearanceType::MaxHealth, "Max Health" },
{ AppearanceType::Invisibility, "Invisibility" },
{ AppearanceType::PVP, "PVP" },
{ AppearanceType::Light, "Light" },
{ AppearanceType::Animation, "Animation" },
{ AppearanceType::Sneak, "Sneak" },
{ AppearanceType::SpawnID, "Spawn ID" },
{ AppearanceType::Health, "Health" },
{ AppearanceType::Linkdead, "Linkdead" },
{ AppearanceType::FlyMode, "Fly Mode" },
{ AppearanceType::GM, "GM" },
{ AppearanceType::Anonymous, "Anonymous" },
{ AppearanceType::GuildID, "Guild ID" },
{ AppearanceType::GuildRank, "Guild Rank" },
{ AppearanceType::AFK, "AFK" },
{ AppearanceType::Pet, "Pet" },
{ AppearanceType::Summoned, "Summoned" },
{ AppearanceType::Split, "Split" },
{ AppearanceType::Size, "Size" },
{ AppearanceType::SetType, "Set Type" },
{ AppearanceType::NPCName, "NPCName" },
{ AppearanceType::AARank, "AARank" },
{ AppearanceType::CancelSneakHide, "Cancel Sneak Hide" },
{ AppearanceType::AreaHealthRegen, "Area Health Regeneration" },
{ AppearanceType::AreaManaRegen, "Area Mana Regeneration" },
{ AppearanceType::AreaEnduranceRegen, "Area Endurance Regeneration" },
{ AppearanceType::FreezeBeneficialBuffs, "Freeze Beneficial Buffs" },
{ AppearanceType::NPCTintIndex, "NPC Tint Index" },
{ AppearanceType::GroupAutoConsent, "Group Auto Consent" },
{ AppearanceType::RaidAutoConsent, "Raid Auto Consent" },
{ AppearanceType::GuildAutoConsent, "Guild Auto Consent" },
{ AppearanceType::ShowHelm, "Show Helm" },
{ AppearanceType::DamageState, "Damage State" },
{ AppearanceType::EQPlayers, "EQ Players" },
{ AppearanceType::FindBits, "Find Bits" },
{ AppearanceType::TextureType, "Texture Type" },
{ AppearanceType::FacePick, "Face Pick" },
{ AppearanceType::AntiCheat, "Anti Cheat" },
{ AppearanceType::GuildShow, "Guild Show" },
{ AppearanceType::OfflineMode, "Offline Mode" }
};
return appearance_type_map;
}
std::string EQ::constants::GetAppearanceTypeName(uint32 appearance_type)
{
const auto& a = EQ::constants::GetAppearanceTypeMap().find(appearance_type);
if (a != EQ::constants::GetAppearanceTypeMap().end()) {
return a->second;
}
return std::string();
}
std::string SpecialAbility::GetName(int ability_id)
{
return IsValid(ability_id) ? special_ability_names[ability_id] : "UNKNOWN SPECIAL ABILITY";
}
bool SpecialAbility::IsValid(int ability_id)
{
return special_ability_names.find(ability_id) != special_ability_names.end();
}
const std::map<uint32, std::string>& EQ::constants::GetConsiderColorMap()
{
static const std::map<uint32, std::string> consider_color_map = {
{ ConsiderColor::Green, "Green" },
{ ConsiderColor::DarkBlue, "Dark Blue" },
{ ConsiderColor::Gray, "Gray" },
{ ConsiderColor::White, "White" },
{ ConsiderColor::Red, "Red" },
{ ConsiderColor::Yellow, "Yellow" },
{ ConsiderColor::LightBlue, "Light Blue" },
{ ConsiderColor::WhiteTitanium, "White" },
};
return consider_color_map;
}
std::string EQ::constants::GetConsiderColorName(uint32 consider_color)
{
const auto& c = EQ::constants::GetConsiderColorMap().find(consider_color);
return c != EQ::constants::GetConsiderColorMap().end() ? c->second : std::string();
}
std::string AccountStatus::GetName(uint8 account_status)
{
for (
auto e = account_status_names.rbegin();
e != account_status_names.rend();
++e
) {
if (account_status >= e->first) {
return e->second;
}
}
return "UNKNOWN ACCOUNT STATUS";
}
std::string ComparisonType::GetName(uint8 type)
{
return IsValid(type) ? comparison_types[type] : "UNKNOWN COMPARISON TYPE";
}
bool ComparisonType::IsValid(uint8 type)
{
return comparison_types.find(type) != comparison_types.end();
}
uint32 LDoNTheme::GetBitmask(uint32 theme_id)
{
return IsValid(theme_id) ? ldon_theme_names[theme_id].second : LDoNTheme::UnusedBit;
}
std::string LDoNTheme::GetName(uint32 theme_id)
{
return IsValid(theme_id) ? ldon_theme_names[theme_id].first : "UNKNOWN LDON THEME";
}
bool LDoNTheme::IsValid(uint32 theme_id)
{
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
return 0;
}
+95 -560
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -22,86 +22,19 @@
#include "eq_limits.h"
#include "emu_versions.h"
#include "bodytypes.h"
#include <string.h>
namespace AccountStatus {
constexpr uint8 Player = 0;
constexpr uint8 Steward = 10;
constexpr uint8 ApprenticeGuide = 20;
constexpr uint8 Guide = 50;
constexpr uint8 QuestTroupe = 80;
constexpr uint8 SeniorGuide = 81;
constexpr uint8 GMTester = 85;
constexpr uint8 EQSupport = 90;
constexpr uint8 GMStaff = 95;
constexpr uint8 GMAdmin = 100;
constexpr uint8 GMLeadAdmin = 150;
constexpr uint8 QuestMaster = 160;
constexpr uint8 GMAreas = 170;
constexpr uint8 GMCoder = 180;
constexpr uint8 GMMgmt = 200;
constexpr uint8 GMImpossible = 250;
constexpr uint8 Max = 255;
std::string GetName(uint8 account_status);
}
static std::map<uint8, std::string> account_status_names = {
{ 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" }
};
namespace ComparisonType {
constexpr uint8 Equal = 0;
constexpr uint8 NotEqual = 1;
constexpr uint8 GreaterOrEqual = 2;
constexpr uint8 LesserOrEqual = 3;
constexpr uint8 Greater = 4;
constexpr uint8 Lesser = 5;
constexpr uint8 Any = 6;
constexpr uint8 NotAny = 7;
constexpr uint8 Between = 8;
constexpr uint8 NotBetween = 9;
std::string GetName(uint8 type);
bool IsValid(uint8 type);
}
static std::map<uint8, std::string> comparison_types = {
{ ComparisonType::Equal, "Equal" },
{ ComparisonType::NotEqual, "Not Equal" },
{ ComparisonType::GreaterOrEqual, "Greater or Equal" },
{ ComparisonType::LesserOrEqual, "Lesser or Equal" },
{ ComparisonType::Greater, "Greater" },
{ ComparisonType::Lesser, "Lesser" },
{ ComparisonType::Any, "Any" },
{ ComparisonType::NotAny, "Not Any" },
{ ComparisonType::Between, "Between" },
{ ComparisonType::NotBetween, "Not Between" },
};
// local definitions are the result of using hybrid-client or server-only values and methods
namespace EQ
namespace EQEmu
{
using RoF2::IINVALID;
using RoF2::INULL;
namespace inventory {
} /*inventory*/
namespace invtype {
using namespace RoF2::invtype::enum_;
@@ -132,7 +65,7 @@ namespace EQ
using RoF2::invtype::KRONO_SIZE;
using RoF2::invtype::OTHER_SIZE;
using RoF2::invtype::TRADE_NPC_SIZE;
using Titanium::invtype::TRADE_NPC_SIZE;
using RoF2::invtype::TYPE_INVALID;
using RoF2::invtype::TYPE_BEGIN;
@@ -159,7 +92,7 @@ namespace EQ
using RoF2::invslot::SLOT_INVALID;
using RoF2::invslot::SLOT_BEGIN;
using RoF2::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
using Titanium::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE;
const int16 SLOT_AUGMENT_GENERIC_RETURN = 1001; // clients don't appear to use this method... (internal inventory return value)
@@ -179,28 +112,28 @@ namespace EQ
using RoF2::invslot::BONUS_STAT_END;
using RoF2::invslot::BONUS_SKILL_END;
using RoF2::invslot::BANK_BEGIN;
using RoF2::invslot::BANK_END;
using Titanium::invslot::BANK_BEGIN;
using SoF::invslot::BANK_END;
using RoF2::invslot::SHARED_BANK_BEGIN;
using RoF2::invslot::SHARED_BANK_END;
using Titanium::invslot::SHARED_BANK_BEGIN;
using Titanium::invslot::SHARED_BANK_END;
using RoF2::invslot::TRADE_BEGIN;
using RoF2::invslot::TRADE_END;
using Titanium::invslot::TRADE_BEGIN;
using Titanium::invslot::TRADE_END;
using RoF2::invslot::TRADE_NPC_END;
using Titanium::invslot::TRADE_NPC_END;
using RoF2::invslot::WORLD_BEGIN;
using RoF2::invslot::WORLD_END;
using Titanium::invslot::WORLD_BEGIN;
using Titanium::invslot::WORLD_END;
using RoF2::invslot::TRIBUTE_BEGIN;
using RoF2::invslot::TRIBUTE_END;
using Titanium::invslot::TRIBUTE_BEGIN;
using Titanium::invslot::TRIBUTE_END;
using RoF2::invslot::GUILD_TRIBUTE_BEGIN;
using RoF2::invslot::GUILD_TRIBUTE_END;
using Titanium::invslot::GUILD_TRIBUTE_BEGIN;
using Titanium::invslot::GUILD_TRIBUTE_END;
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
const int16 CORPSE_END = CORPSE_BEGIN + invslot::slotCursor;
using RoF2::invslot::EQUIPMENT_BITMASK;
using RoF2::invslot::GENERAL_BITMASK;
@@ -214,40 +147,38 @@ namespace EQ
} // namespace invslot
namespace invbag {
using RoF2::invbag::SLOT_INVALID;
using RoF2::invbag::SLOT_BEGIN;
using RoF2::invbag::SLOT_END;
using RoF2::invbag::SLOT_COUNT;
using Titanium::invbag::SLOT_INVALID;
using Titanium::invbag::SLOT_BEGIN;
using Titanium::invbag::SLOT_END;
using Titanium::invbag::SLOT_COUNT;
using RoF2::invslot::WORLD_END;
const int16 GENERAL_BAGS_BEGIN = WORLD_END + 1;
using Titanium::invbag::GENERAL_BAGS_BEGIN;
const int16 GENERAL_BAGS_COUNT = invslot::GENERAL_COUNT * SLOT_COUNT;
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
const int16 GENERAL_BAGS_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_COUNT) - 1;
const int16 GENERAL_BAGS_8_COUNT = 8 * SLOT_COUNT;
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
const int16 GENERAL_BAGS_8_END = (GENERAL_BAGS_BEGIN + GENERAL_BAGS_8_COUNT) - 1;
const int16 CURSOR_BAG_BEGIN = GENERAL_BAGS_END + 1;
const int16 CURSOR_BAG_BEGIN = 351;
const int16 CURSOR_BAG_COUNT = SLOT_COUNT;
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
const int16 CURSOR_BAG_END = (CURSOR_BAG_BEGIN + CURSOR_BAG_COUNT) - 1;
const int16 BANK_BAGS_BEGIN = CURSOR_BAG_END + 1;
using Titanium::invbag::BANK_BAGS_BEGIN;
const int16 BANK_BAGS_COUNT = (invtype::BANK_SIZE * SLOT_COUNT);
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
const int16 BANK_BAGS_END = (BANK_BAGS_BEGIN + BANK_BAGS_COUNT) - 1;
const int16 BANK_BAGS_16_COUNT = 16 * SLOT_COUNT;
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
const int16 BANK_BAGS_16_END = (BANK_BAGS_BEGIN + BANK_BAGS_16_COUNT) - 1;
const int16 SHARED_BANK_BAGS_BEGIN = BANK_BAGS_END + 1;
using Titanium::invbag::SHARED_BANK_BAGS_BEGIN;
const int16 SHARED_BANK_BAGS_COUNT = invtype::SHARED_BANK_SIZE * SLOT_COUNT;
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
const int16 SHARED_BANK_BAGS_END = (SHARED_BANK_BAGS_BEGIN + SHARED_BANK_BAGS_COUNT) - 1;
const int16 TRADE_BAGS_BEGIN = SHARED_BANK_BAGS_END + 1;
using Titanium::invbag::TRADE_BAGS_BEGIN;
const int16 TRADE_BAGS_COUNT = invtype::TRADE_SIZE * SLOT_COUNT;
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
const int16 TRADE_BAGS_END = (TRADE_BAGS_BEGIN + TRADE_BAGS_COUNT) - 1;
using RoF2::invbag::GetInvBagIndexName;
using Titanium::invbag::GetInvBagIndexName;
} // namespace invbag
@@ -262,134 +193,46 @@ namespace EQ
} // namespace invaug
namespace constants {
const EQ::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQ::versions::ClientVersion::Titanium;
const EQEmu::versions::ClientVersion CHARACTER_CREATION_CLIENT = EQEmu::versions::ClientVersion::Titanium;
using RoF2::constants::EXPANSION;
using RoF2::constants::EXPANSION_BIT;
using RoF2::constants::EXPANSIONS_MASK;
using RoF2::constants::CHARACTER_CREATION_LIMIT;
const size_t SAY_LINK_OPENER_SIZE = 1;
using RoF2::constants::SAY_LINK_BODY_SIZE;
const size_t SAY_LINK_TEXT_SIZE = 256; // this may be varied until it breaks something (tested:374) - the others are constant
const size_t SAY_LINK_CLOSER_SIZE = 1;
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
enum BotSpellIDs : int {
Warrior = 3001,
Cleric,
Paladin,
Ranger,
Shadowknight,
Druid,
Monk,
Bard,
Rogue,
Shaman,
Necromancer,
Wizard,
Magician,
Enchanter,
Beastlord,
Berserker
enum StanceType : int {
stanceUnknown = 0,
stancePassive,
stanceBalanced,
stanceEfficient,
stanceReactive,
stanceAggressive,
stanceAssist,
stanceBurn,
stanceEfficient2,
stanceBurnAE
};
enum GravityBehavior : int8 {
Ground,
Flying,
Levitating,
Water,
Floating,
LevitateWhileRunning
};
const char *GetStanceName(StanceType stance_type);
int ConvertStanceTypeToIndex(StanceType stance_type);
enum EnvironmentalDamage : uint8 {
Lava = 250,
Drowning,
Falling,
Trap
};
enum StuckBehavior : uint8 {
RunToTarget,
WarpToTarget,
TakeNoAction,
EvadeCombat
};
enum SpawnAnimations : uint8 {
Standing,
Sitting,
Crouching,
Laying,
Looting
};
enum WeatherTypes : uint8 {
None,
Raining,
Snowing
};
enum EmoteEventTypes : uint8 {
LeaveCombat,
EnterCombat,
OnDeath,
AfterDeath,
Hailed,
KilledPC,
KilledNPC,
OnSpawn,
OnDespawn
};
enum EmoteTypes : uint8 {
Say,
Emote,
Shout,
Proximity
};
extern const std::map<uint8, std::string>& GetLanguageMap();
std::string GetLanguageName(uint8 language_id);
extern const std::map<int8, std::string>& GetFlyModeMap();
std::string GetFlyModeName(int8 flymode_id);
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<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);
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
std::string GetAppearanceTypeName(uint32 animation_type);
extern const std::map<uint32, std::string>& GetConsiderColorMap();
std::string GetConsiderColorName(uint32 consider_color);
const int STANCE_TYPE_FIRST = stancePassive;
const int STANCE_TYPE_LAST = stanceBurnAE;
const int STANCE_TYPE_COUNT = stanceBurnAE;
} /*constants*/
namespace profile {
using RoF2::profile::BANDOLIERS_SIZE;
using RoF2::profile::BANDOLIER_ITEM_COUNT;
using RoF2::profile::POTION_BELT_SIZE;
using RoF2::profile::SKILL_ARRAY_SIZE;
@@ -437,357 +280,49 @@ namespace EQ
} // namespace spells
namespace bug {
enum CategoryID : uint32 {
catOther = 0,
catVideo,
catAudio,
catPathing,
catQuest,
catTradeskills,
catSpellStacking,
catDoorsPortals,
catItems,
catNPC,
catDialogs,
catLoNTCG,
catMercenaries
};
enum OptionalInfoFlag : uint32 {
infoNoOptionalInfo = 0x0,
infoCanDuplicate = 0x1,
infoCrashBug = 0x2,
infoTargetInfo = 0x4,
infoCharacterFlags = 0x8,
infoUnknownValue = 0xFFFFFFF0
};
const char* CategoryIDToCategoryName(CategoryID category_id);
CategoryID CategoryNameToCategoryID(const char* category_name);
} // namespace bug
enum WaypointStatus : int {
RoamBoxPauseInProgress = -3,
QuestControlNoGrid = -2,
QuestControlGrid = -1
};
namespace consent {
enum eConsentType : uint8 {
Normal = 0,
Group,
Raid,
Guild
};
};
} /*EQEmu*/
enum ServerLockType : int {
List,
Lock,
Unlock
};
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
};
namespace ConsiderColor {
constexpr uint32 Green = 2;
constexpr uint32 DarkBlue = 4;
constexpr uint32 Gray = 6;
constexpr uint32 White = 10;
constexpr uint32 Red = 13;
constexpr uint32 Yellow = 15;
constexpr uint32 LightBlue = 18;
constexpr uint32 WhiteTitanium = 20;
};
enum TargetDescriptionType : uint8 {
LCSelf,
UCSelf,
LCYou,
UCYou,
LCYour,
UCYour
};
enum ReloadWorld : uint8 {
NoRepop = 0,
Repop,
ForceRepop
};
enum class EntityFilterType {
All,
Bots,
Clients,
NPCs
};
enum class ApplySpellType {
Solo,
Group,
Raid
};
namespace SpecialAbility {
constexpr int Summon = 1;
constexpr int Enrage = 2;
constexpr int Rampage = 3;
constexpr int AreaRampage = 4;
constexpr int Flurry = 5;
constexpr int TripleAttack = 6;
constexpr int QuadrupleAttack = 7;
constexpr int DualWield = 8;
constexpr int BaneAttack = 9;
constexpr int MagicalAttack = 10;
constexpr int RangedAttack = 11;
constexpr int SlowImmunity = 12;
constexpr int MesmerizeImmunity = 13;
constexpr int CharmImmunity = 14;
constexpr int StunImmunity = 15;
constexpr int SnareImmunity = 16;
constexpr int FearImmunity = 17;
constexpr int DispellImmunity = 18;
constexpr int MeleeImmunity = 19;
constexpr int MagicImmunity = 20;
constexpr int FleeingImmunity = 21;
constexpr int MeleeImmunityExceptBane = 22;
constexpr int MeleeImmunityExceptMagical = 23;
constexpr int AggroImmunity = 24;
constexpr int BeingAggroImmunity = 25;
constexpr int CastingFromRangeImmunity = 26;
constexpr int FeignDeathImmunity = 27;
constexpr int TauntImmunity = 28;
constexpr int TunnelVision = 29;
constexpr int NoBuffHealFriends = 30;
constexpr int PacifyImmunity = 31;
constexpr int Leash = 32;
constexpr int Tether = 33;
constexpr int DestructibleObject = 34;
constexpr int HarmFromClientImmunity = 35;
constexpr int AlwaysFlee = 36;
constexpr int FleePercent = 37;
constexpr int AllowBeneficial = 38;
constexpr int DisableMelee = 39;
constexpr int NPCChaseDistance = 40;
constexpr int AllowedToTank = 41;
constexpr int IgnoreRootAggroRules = 42;
constexpr int CastingResistDifficulty = 43;
constexpr int CounterAvoidDamage = 44;
constexpr int ProximityAggro = 45;
constexpr int RangedAttackImmunity = 46;
constexpr int ClientDamageImmunity = 47;
constexpr int NPCDamageImmunity = 48;
constexpr int ClientAggroImmunity = 49;
constexpr int NPCAggroImmunity = 50;
constexpr int ModifyAvoidDamage = 51;
constexpr int MemoryFadeImmunity = 52;
constexpr int OpenImmunity = 53;
constexpr int AssassinateImmunity = 54;
constexpr int HeadshotImmunity = 55;
constexpr int BotAggroImmunity = 56;
constexpr int BotDamageImmunity = 57;
constexpr int Max = 58;
constexpr int MaxParameters = 9;
std::string GetName(int ability_id);
bool IsValid(int ability_id);
}
static std::map<int, std::string> special_ability_names = {
{ SpecialAbility::Summon, "Summon" },
{ SpecialAbility::Enrage, "Enrage" },
{ SpecialAbility::Rampage, "Rampage" },
{ SpecialAbility::AreaRampage, "Area Rampage" },
{ SpecialAbility::Flurry, "Flurry" },
{ SpecialAbility::TripleAttack, "Triple Attack" },
{ SpecialAbility::QuadrupleAttack, "Quadruple Attack" },
{ SpecialAbility::DualWield, "Dual Wield" },
{ SpecialAbility::BaneAttack, "Bane Attack" },
{ SpecialAbility::MagicalAttack, "Magical Attack" },
{ SpecialAbility::RangedAttack, "Ranged Attack" },
{ SpecialAbility::SlowImmunity, "Immune to Slow" },
{ SpecialAbility::MesmerizeImmunity, "Immune to Mesmerize" },
{ SpecialAbility::CharmImmunity, "Immune to Charm" },
{ SpecialAbility::StunImmunity, "Immune to Stun" },
{ SpecialAbility::SnareImmunity, "Immune to Snare" },
{ SpecialAbility::FearImmunity, "Immune to Fear" },
{ SpecialAbility::DispellImmunity, "Immune to Dispell" },
{ SpecialAbility::MeleeImmunity, "Immune to Melee" },
{ SpecialAbility::MagicImmunity, "Immune to Magic" },
{ SpecialAbility::FleeingImmunity, "Immune to Fleeing" },
{ SpecialAbility::MeleeImmunityExceptBane, "Immune to Melee except Bane" },
{ SpecialAbility::MeleeImmunityExceptMagical, "Immune to Non-Magical Melee" },
{ SpecialAbility::AggroImmunity, "Immune to Aggro" },
{ SpecialAbility::BeingAggroImmunity, "Immune to Being Aggro" },
{ SpecialAbility::CastingFromRangeImmunity, "Immune to Ranged Spells" },
{ SpecialAbility::FeignDeathImmunity, "Immune to Feign Death" },
{ SpecialAbility::TauntImmunity, "Immune to Taunt" },
{ SpecialAbility::TunnelVision, "Tunnel Vision" },
{ SpecialAbility::NoBuffHealFriends, "Does Not Heal or Buff Allies" },
{ SpecialAbility::PacifyImmunity, "Immune to Pacify" },
{ SpecialAbility::Leash, "Leashed" },
{ SpecialAbility::Tether, "Tethered" },
{ SpecialAbility::DestructibleObject, "Destructible Object" },
{ SpecialAbility::HarmFromClientImmunity, "Immune to Harm from Client" },
{ SpecialAbility::AlwaysFlee, "Always Flees" },
{ SpecialAbility::FleePercent, "Flee Percentage" },
{ SpecialAbility::AllowBeneficial, "Allows Beneficial Spells" },
{ SpecialAbility::DisableMelee, "Melee is Disabled" },
{ SpecialAbility::NPCChaseDistance, "Chase Distance" },
{ SpecialAbility::AllowedToTank, "Allowed to Tank" },
{ SpecialAbility::IgnoreRootAggroRules, "Ignores Root Aggro" },
{ SpecialAbility::CastingResistDifficulty, "Casting Resist Difficulty" },
{ SpecialAbility::CounterAvoidDamage, "Counter Damage Avoidance" },
{ SpecialAbility::ProximityAggro, "Proximity Aggro" },
{ SpecialAbility::RangedAttackImmunity, "Immune to Ranged Attacks" },
{ SpecialAbility::ClientDamageImmunity, "Immune to Client Damage" },
{ SpecialAbility::NPCDamageImmunity, "Immune to NPC Damage" },
{ SpecialAbility::ClientAggroImmunity, "Immune to Client Aggro" },
{ SpecialAbility::NPCAggroImmunity, "Immune to NPC Aggro" },
{ SpecialAbility::ModifyAvoidDamage, "Modify Damage Avoidance" },
{ SpecialAbility::MemoryFadeImmunity, "Immune to Memory Fades" },
{ SpecialAbility::OpenImmunity, "Immune to Open" },
{ SpecialAbility::AssassinateImmunity, "Immune to Assassinate" },
{ SpecialAbility::HeadshotImmunity, "Immune to Headshot" },
{ SpecialAbility::BotAggroImmunity, "Immune to Bot Aggro" },
{ SpecialAbility::BotDamageImmunity, "Immune to Bot Damage" },
};
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";
}
namespace Bug {
namespace Category {
constexpr uint32 Other = 0;
constexpr uint32 Video = 1;
constexpr uint32 Audio = 2;
constexpr uint32 Pathing = 3;
constexpr uint32 Quest = 4;
constexpr uint32 Tradeskills = 5;
constexpr uint32 SpellStacking = 6;
constexpr uint32 DoorsPortals = 7;
constexpr uint32 Items = 8;
constexpr uint32 NPC = 9;
constexpr uint32 Dialogs = 10;
constexpr uint32 LoNTCG = 11;
constexpr uint32 Mercenaries = 12;
}
namespace InformationFlag {
constexpr uint32 None = 0;
constexpr uint32 Repeatable = 1;
constexpr uint32 Crash = 2;
constexpr uint32 TargetInfo = 4;
constexpr uint32 CharacterFlags = 8;
constexpr uint32 Unknown = 4294967280;
}
uint32 GetID(const std::string& category_name);
std::string GetName(uint32 category_id);
bool IsValid(uint32 category_id);
}
static std::map<uint32, std::string> bug_category_names = {
{ Bug::Category::Other, "Other" },
{ Bug::Category::Video, "Video" },
{ Bug::Category::Audio, "Audio" },
{ Bug::Category::Pathing, "Pathing" },
{ Bug::Category::Quest, "Quest" },
{ Bug::Category::Tradeskills, "Tradeskills" },
{ Bug::Category::SpellStacking, "Spell Stacking" },
{ Bug::Category::DoorsPortals, "Doors and Portals" },
{ Bug::Category::Items, "Items" },
{ Bug::Category::NPC, "NPC" },
{ Bug::Category::Dialogs, "Dialogs" },
{ Bug::Category::LoNTCG, "LoN - TCG" },
{ Bug::Category::Mercenaries, "Mercenaries" }
};
namespace Stance {
constexpr uint32 Unknown = 0;
constexpr uint32 Passive = 1;
constexpr uint32 Balanced = 2;
constexpr uint32 Efficient = 3;
constexpr uint32 Reactive = 4;
constexpr uint32 Aggressive = 5;
constexpr uint32 Assist = 6;
constexpr uint32 Burn = 7;
constexpr uint32 Efficient2 = 8;
constexpr uint32 AEBurn = 9;
std::string GetName(uint8 stance_id);
uint8 GetIndex(uint8 stance_id);
bool IsValid(uint8 stance_id);
}
static std::map<uint32, std::string> stance_names = {
{ Stance::Unknown, "Unknown" },
{ Stance::Passive, "Passive" },
{ Stance::Balanced, "Balanced" },
{ Stance::Efficient, "Efficient" },
{ Stance::Reactive, "Reactive" },
{ Stance::Aggressive, "Aggressive" },
{ Stance::Assist, "Assist" },
{ Stance::Burn, "Burn" },
{ Stance::Efficient2, "Efficient" },
{ Stance::AEBurn, "AE Burn" }
};
namespace LDoNTheme {
constexpr uint32 Unused = 0;
constexpr uint32 GUK = 1;
constexpr uint32 MIR = 2;
constexpr uint32 MMC = 3;
constexpr uint32 RUJ = 4;
constexpr uint32 TAK = 5;
constexpr uint32 UnusedBit = 0;
constexpr uint32 GUKBit = 1;
constexpr uint32 MIRBit = 2;
constexpr uint32 MMCBit = 4;
constexpr uint32 RUJBit = 8;
constexpr uint32 TAKBit = 16;
uint32 GetBitmask(uint32 theme_id);
std::string GetName(uint32 theme_id);
bool IsValid(uint32 theme_id);
}
static std::map<uint32, std::pair<std::string, uint32>> ldon_theme_names = {
{ LDoNTheme::Unused, { "Unused", LDoNTheme::UnusedBit }, },
{ LDoNTheme::GUK, { "Deepest Guk", LDoNTheme::GUKBit }, },
{ LDoNTheme::MIR, { "Miragul's Menagerie", LDoNTheme::MIRBit }, },
{ LDoNTheme::MMC, { "Mistmoore Catacombs", LDoNTheme::MMCBit }, },
{ LDoNTheme::RUJ, { "Rujarkian Hills", LDoNTheme::RUJBit }, },
{ LDoNTheme::TAK, { "Takish-Hiz", LDoNTheme::TAKBit }, },
};
namespace PCNPCOnlyFlagType {
constexpr int PC = 1;
constexpr int NPC = 2;
}
namespace BookType {
constexpr uint8 Scroll = 0;
constexpr uint8 Book = 1;
constexpr uint8 ItemInfo = 2;
}
#endif /*COMMON_EMU_CONSTANTS_H*/
/* hack list to prevent circular references
eq_limits.h:EQEmu::inventory::LookupEntry::InventoryTypeSize[n];
*/
-1
View File
@@ -45,7 +45,6 @@ typedef enum { //EQEmu internal opcodes list
_maxEmuOpcode
} EmuOpcode;
constexpr int format_as(EmuOpcode opcode) { return static_cast<int>(opcode); }
extern const char *OpcodeNames[_maxEmuOpcode+1];
#endif
+11 -73
View File
@@ -35,7 +35,7 @@ N(OP_AltCurrencyMerchantRequest),
N(OP_AltCurrencyPurchase),
N(OP_AltCurrencyReclaim),
N(OP_AltCurrencySell),
N(OP_AltCurrencySellSelection), // Used by eqstr_us.txt 8066, 8068, 8069
N(OP_AltCurrencySellSelection),
N(OP_Animation),
N(OP_AnnoyingZoneUnknown),
N(OP_ApplyPoison),
@@ -62,22 +62,18 @@ N(OP_BeginCast),
N(OP_Bind_Wound),
N(OP_BlockedBuffs),
N(OP_BoardBoat),
N(OP_BookButton),
N(OP_Buff),
N(OP_BuffCreate),
N(OP_BuffRemoveRequest),
N(OP_Bug),
N(OP_BuyerItems),
N(OP_CameraEffect),
N(OP_Camp),
N(OP_CancelSneakHide),
N(OP_CancelTask),
N(OP_CancelTrade),
N(OP_CashReward),
N(OP_CastSpell),
N(OP_ChangeSize),
N(OP_ChannelMessage),
N(OP_ChangePetName),
N(OP_CharacterCreate),
N(OP_CharacterCreateRequest),
N(OP_CharInventory),
@@ -133,29 +129,27 @@ N(OP_DisciplineTimer),
N(OP_DisciplineUpdate),
N(OP_DiscordMerchantInventory),
N(OP_DoGroupLeadershipAbility),
N(OP_DuelDecline),
N(OP_DuelAccept),
N(OP_DuelResponse),
N(OP_DuelResponse2),
N(OP_DumpName),
N(OP_Dye),
N(OP_DynamicWall),
N(OP_DzAddPlayer),
N(OP_DzChooseZone),
N(OP_DzChooseZoneReply),
N(OP_DzCompass),
N(OP_DzExpeditionEndsWarning),
N(OP_DzExpeditionInfo),
N(OP_DzExpeditionInvite),
N(OP_DzExpeditionInviteResponse),
N(OP_DzExpeditionLockoutTimers),
N(OP_DzExpeditionList),
N(OP_DzJoinExpeditionConfirm),
N(OP_DzJoinExpeditionReply),
N(OP_DzLeaderStatus),
N(OP_DzListTimers),
N(OP_DzMakeLeader),
N(OP_DzMemberList),
N(OP_DzMemberListName),
N(OP_DzMemberListStatus),
N(OP_DzMemberStatus),
N(OP_DzPlayerList),
N(OP_DzQuit),
N(OP_DzRemovePlayer),
N(OP_DzSetLeaderName),
N(OP_DzSwapPlayer),
N(OP_Emote),
N(OP_EndLootRequest),
@@ -163,7 +157,6 @@ N(OP_EnduranceUpdate),
N(OP_EnterChat),
N(OP_EnterWorld),
N(OP_EnvDamage),
N(OP_EvolveItem),
N(OP_ExpansionInfo),
N(OP_ExpUpdate),
N(OP_FaceChange),
@@ -231,7 +224,6 @@ N(OP_GuildBank),
N(OP_GuildBankItemList),
N(OP_GuildCreate),
N(OP_GuildDelete),
N(OP_GuildDeleteGuild),
N(OP_GuildDemote),
N(OP_GuildInvite),
N(OP_GuildInviteAccept),
@@ -243,33 +235,15 @@ N(OP_GuildManageStatus),
N(OP_GuildMemberLevelUpdate),
N(OP_GuildMemberList),
N(OP_GuildMemberUpdate),
N(OP_GuildMemberLevel),
N(OP_GuildMemberRankAltBanker),
N(OP_GuildMemberPublicNote),
N(OP_GuildMemberAdd),
N(OP_GuildMemberRename),
N(OP_GuildMemberDelete),
N(OP_GuildMemberDetails),
N(OP_GuildRenameGuild),
N(OP_GuildMOTD),
N(OP_GuildPeace),
N(OP_GuildPromote),
N(OP_GuildPublicNote),
N(OP_GuildRemove),
N(OP_GuildSelectTribute),
N(OP_GuildModifyBenefits),
N(OP_GuildTributeToggleReq),
N(OP_GuildTributeToggleReply),
N(OP_GuildOptInOut),
N(OP_GuildSaveActiveTributes),
N(OP_GuildSendActiveTributes),
N(OP_GuildTributeFavorAndTimer),
N(OP_GuildsList),
N(OP_GuildStatus),
N(OP_GuildTributeInfo),
N(OP_GuildUpdate),
N(OP_GuildTributeDonateItem),
N(OP_GuildTributeDonatePlat),
N(OP_GuildUpdateURLAndChannel),
N(OP_GuildWar),
N(OP_Heartbeat),
N(OP_Hide),
@@ -285,22 +259,18 @@ N(OP_InspectMessageUpdate),
N(OP_InspectRequest),
N(OP_InstillDoubt),
N(OP_InterruptCast),
N(OP_InvokeChangePetName),
N(OP_InvokeChangePetNameImmediate),
N(OP_ItemLinkClick),
N(OP_ItemLinkResponse),
N(OP_ItemLinkText),
N(OP_ItemName),
N(OP_ItemPacket),
N(OP_ItemPreview),
N(OP_ItemPreviewRequest),
N(OP_ItemRecastDelay),
N(OP_ItemVerifyReply),
N(OP_ItemVerifyRequest),
N(OP_ItemViewUnknown),
N(OP_Jump),
N(OP_KeyRing),
N(OP_KickPlayers),
N(OP_KnowledgeBase),
N(OP_LDoNButton),
N(OP_LDoNDisarmTraps),
@@ -330,7 +300,6 @@ N(OP_LockoutTimerInfo),
N(OP_Login),
N(OP_LoginAccepted),
N(OP_LoginComplete),
N(OP_LoginExpansionPacketData), //added for Rof2 client to send expansion data packet. Requires login_opcodes_sod.conf to be updated.
N(OP_LoginUnknown1),
N(OP_LoginUnknown2),
N(OP_Logout),
@@ -342,7 +311,6 @@ N(OP_LootRequest),
N(OP_ManaChange),
N(OP_ManaUpdate),
N(OP_MarkNPC),
N(OP_MarkRaidNPC),
N(OP_Marquee),
N(OP_MemorizeSpell),
N(OP_Mend),
@@ -384,6 +352,7 @@ N(OP_OpenContainer),
N(OP_OpenDiscordMerchant),
N(OP_OpenGuildTributeMaster),
N(OP_OpenInventory),
N(OP_OpenNewTasksWindow),
N(OP_OpenTributeMaster),
N(OP_PDeletePetition),
N(OP_PetBuffWindow),
@@ -405,8 +374,6 @@ N(OP_PetitionSearchText),
N(OP_PetitionUnCheckout),
N(OP_PetitionUpdate),
N(OP_PickPocket),
N(OP_PickZone),
N(OP_PickZoneWindow),
N(OP_PlayerProfile),
N(OP_PlayerStateAdd),
N(OP_PlayerStateRemove),
@@ -427,8 +394,6 @@ N(OP_PVPLeaderBoardRequest),
N(OP_PVPStats),
N(OP_QueryResponseThing),
N(OP_QueryUCSServerStatus),
N(OP_RaidDelegateAbility),
N(OP_RaidClearNPCMarks),
N(OP_RaidInvite),
N(OP_RaidJoin),
N(OP_RaidUpdate),
@@ -452,7 +417,6 @@ N(OP_ReqClientSpawn),
N(OP_ReqNewZone),
N(OP_RequestClientZoneChange),
N(OP_RequestDuel),
N(OP_RequestGuildTributes),
N(OP_RequestKnowledgeBase),
N(OP_RequestTitles),
N(OP_RespawnWindow),
@@ -473,7 +437,6 @@ N(OP_SendAATable),
N(OP_SendCharInfo),
N(OP_SendExpZonein),
N(OP_SendFindableNPCs),
N(OP_SendFindableLocations),
N(OP_SendGuildTributes),
N(OP_SendLoginInfo),
N(OP_SendMaxCharacters),
@@ -490,7 +453,6 @@ N(OP_ServerListResponse),
N(OP_SessionReady),
N(OP_SetChatServer),
N(OP_SetChatServer2),
N(OP_SetFace),
N(OP_SetGroupTarget),
N(OP_SetGuildMOTD),
N(OP_SetGuildRank),
@@ -499,19 +461,6 @@ N(OP_SetServerFilter),
N(OP_SetStartCity),
N(OP_SetTitle),
N(OP_SetTitleReply),
N(OP_SharedTaskMemberList),
N(OP_SharedTaskAddPlayer),
N(OP_SharedTaskRemovePlayer),
N(OP_SharedTaskMakeLeader),
N(OP_SharedTaskMemberInvite),
N(OP_SharedTaskInvite),
N(OP_SharedTaskInviteResponse),
N(OP_SharedTaskAcceptNew),
N(OP_SharedTaskMemberChange),
N(OP_SharedTaskPlayerList),
N(OP_SharedTaskSelectWindow),
N(OP_SharedTaskQuit),
N(OP_TaskTimers),
N(OP_Shielding),
N(OP_ShopDelItem),
N(OP_ShopEnd),
@@ -519,11 +468,6 @@ N(OP_ShopEndConfirm),
N(OP_ShopItem),
N(OP_ShopPlayerBuy),
N(OP_ShopPlayerSell),
N(OP_ShopSendParcel),
N(OP_ShopDeleteParcel),
N(OP_ShopRespondParcel),
N(OP_ShopRetrieveParcel),
N(OP_ShopParcelIcon),
N(OP_ShopRequest),
N(OP_SimpleMessage),
N(OP_SkillUpdate),
@@ -542,7 +486,6 @@ N(OP_Stamina),
N(OP_Stun),
N(OP_Surname),
N(OP_SwapSpell),
N(OP_SystemFingerprint),
N(OP_TargetBuffs),
N(OP_TargetCommand),
N(OP_TargetHoTT),
@@ -553,8 +496,7 @@ N(OP_TaskActivityComplete),
N(OP_TaskDescription),
N(OP_TaskHistoryReply),
N(OP_TaskHistoryRequest),
N(OP_TaskRequestTimer),
N(OP_TaskSelectWindow),
N(OP_TaskMemberList),
N(OP_Taunt),
N(OP_TestBuff),
N(OP_TGB),
@@ -567,7 +509,6 @@ N(OP_TradeBusy),
N(OP_TradeCoins),
N(OP_TradeMoneyUpdate),
N(OP_Trader),
N(OP_TraderBulkSend),
N(OP_TraderBuy),
N(OP_TraderDelItem),
N(OP_TradeRequest),
@@ -575,7 +516,6 @@ N(OP_TradeRequestAck),
N(OP_TraderItemUpdate),
N(OP_TraderShop),
N(OP_TradeSkillCombine),
N(OP_TradeSkillRecipeInspect),
N(OP_Translocate),
N(OP_TributeInfo),
N(OP_TributeItem),
@@ -602,7 +542,6 @@ N(OP_WhoAllRequest),
N(OP_WhoAllResponse),
N(OP_World_Client_CRC1),
N(OP_World_Client_CRC2),
N(OP_World_Client_CRC3),
N(OP_WorldClientReady),
N(OP_WorldComplete),
N(OP_WorldLogout),
@@ -625,5 +564,4 @@ N(OP_ZoneServerReady),
N(OP_ZoneSpawns),
N(OP_ZoneUnavail),
N(OP_ResetAA),
N(OP_UnderWorld),
// mail and chat opcodes located in ../mail_oplist.h
+31 -31
View File
@@ -21,7 +21,7 @@
#include "emu_constants.h"
bool EQ::versions::IsValidClientVersion(ClientVersion client_version)
bool EQEmu::versions::IsValidClientVersion(ClientVersion client_version)
{
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
return false;
@@ -29,7 +29,7 @@ bool EQ::versions::IsValidClientVersion(ClientVersion client_version)
return true;
}
EQ::versions::ClientVersion EQ::versions::ValidateClientVersion(ClientVersion client_version)
EQEmu::versions::ClientVersion EQEmu::versions::ValidateClientVersion(ClientVersion client_version)
{
if (client_version <= ClientVersion::Unknown || client_version > LastClientVersion)
return ClientVersion::Unknown;
@@ -37,7 +37,7 @@ EQ::versions::ClientVersion EQ::versions::ValidateClientVersion(ClientVersion cl
return client_version;
}
const char* EQ::versions::ClientVersionName(ClientVersion client_version)
const char* EQEmu::versions::ClientVersionName(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
@@ -61,7 +61,7 @@ const char* EQ::versions::ClientVersionName(ClientVersion client_version)
};
}
uint32 EQ::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
uint32 EQEmu::versions::ConvertClientVersionToClientVersionBit(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Titanium:
@@ -81,7 +81,7 @@ uint32 EQ::versions::ConvertClientVersionToClientVersionBit(ClientVersion client
}
}
EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
EQEmu::versions::ClientVersion EQEmu::versions::ConvertClientVersionBitToClientVersion(uint32 client_version_bit)
{
switch (client_version_bit) {
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Titanium) - 1)) :
@@ -101,7 +101,7 @@ EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion
}
}
bool EQ::versions::IsValidMobVersion(MobVersion mob_version)
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
{
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
return false;
@@ -109,7 +109,7 @@ bool EQ::versions::IsValidMobVersion(MobVersion mob_version)
return true;
}
bool EQ::versions::IsValidPCMobVersion(MobVersion mob_version)
bool EQEmu::versions::IsValidPCMobVersion(MobVersion mob_version)
{
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
return false;
@@ -117,7 +117,7 @@ bool EQ::versions::IsValidPCMobVersion(MobVersion mob_version)
return true;
}
bool EQ::versions::IsValidNonPCMobVersion(MobVersion mob_version)
bool EQEmu::versions::IsValidNonPCMobVersion(MobVersion mob_version)
{
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
return false;
@@ -125,7 +125,7 @@ bool EQ::versions::IsValidNonPCMobVersion(MobVersion mob_version)
return true;
}
bool EQ::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
bool EQEmu::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
{
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
return false;
@@ -133,7 +133,7 @@ bool EQ::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
return true;
}
EQ::versions::MobVersion EQ::versions::ValidateMobVersion(MobVersion mob_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidateMobVersion(MobVersion mob_version)
{
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
return MobVersion::Unknown;
@@ -141,7 +141,7 @@ EQ::versions::MobVersion EQ::versions::ValidateMobVersion(MobVersion mob_version
return mob_version;
}
EQ::versions::MobVersion EQ::versions::ValidatePCMobVersion(MobVersion mob_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidatePCMobVersion(MobVersion mob_version)
{
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
return MobVersion::Unknown;
@@ -149,7 +149,7 @@ EQ::versions::MobVersion EQ::versions::ValidatePCMobVersion(MobVersion mob_versi
return mob_version;
}
EQ::versions::MobVersion EQ::versions::ValidateNonPCMobVersion(MobVersion mob_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidateNonPCMobVersion(MobVersion mob_version)
{
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
return MobVersion::Unknown;
@@ -157,7 +157,7 @@ EQ::versions::MobVersion EQ::versions::ValidateNonPCMobVersion(MobVersion mob_ve
return mob_version;
}
EQ::versions::MobVersion EQ::versions::ValidateOfflinePCMobVersion(MobVersion mob_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidateOfflinePCMobVersion(MobVersion mob_version)
{
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
return MobVersion::Unknown;
@@ -165,7 +165,7 @@ EQ::versions::MobVersion EQ::versions::ValidateOfflinePCMobVersion(MobVersion mo
return mob_version;
}
const char* EQ::versions::MobVersionName(MobVersion mob_version)
const char* EQEmu::versions::MobVersionName(MobVersion mob_version)
{
switch (mob_version) {
case MobVersion::Unknown:
@@ -217,7 +217,7 @@ const char* EQ::versions::MobVersionName(MobVersion mob_version)
};
}
EQ::versions::ClientVersion EQ::versions::ConvertMobVersionToClientVersion(MobVersion mob_version)
EQEmu::versions::ClientVersion EQEmu::versions::ConvertMobVersionToClientVersion(MobVersion mob_version)
{
switch (mob_version) {
case MobVersion::Unknown:
@@ -240,7 +240,7 @@ EQ::versions::ClientVersion EQ::versions::ConvertMobVersionToClientVersion(MobVe
}
}
EQ::versions::MobVersion EQ::versions::ConvertClientVersionToMobVersion(ClientVersion client_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
@@ -263,7 +263,7 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToMobVersion(ClientVe
}
}
EQ::versions::MobVersion EQ::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version)
{
switch (mob_version) {
case MobVersion::Titanium:
@@ -283,7 +283,7 @@ EQ::versions::MobVersion EQ::versions::ConvertPCMobVersionToOfflinePCMobVersion(
}
}
EQ::versions::MobVersion EQ::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version)
{
switch (mob_version) {
case MobVersion::OfflineTitanium:
@@ -303,7 +303,7 @@ EQ::versions::MobVersion EQ::versions::ConvertOfflinePCMobVersionToPCMobVersion(
}
}
EQ::versions::ClientVersion EQ::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version)
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version)
{
switch (mob_version) {
case MobVersion::OfflineTitanium:
@@ -323,7 +323,7 @@ EQ::versions::ClientVersion EQ::versions::ConvertOfflinePCMobVersionToClientVers
}
}
EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Titanium:
@@ -343,7 +343,7 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion
}
}
const char* EQ::expansions::ExpansionName(Expansion expansion)
const char* EQEmu::expansions::ExpansionName(Expansion expansion)
{
switch (expansion) {
case Expansion::EverQuest:
@@ -393,12 +393,12 @@ const char* EQ::expansions::ExpansionName(Expansion expansion)
}
}
const char* EQ::expansions::ExpansionName(uint32 expansion_bit)
const char* EQEmu::expansions::ExpansionName(uint32 expansion_bit)
{
return ExpansionName(ConvertExpansionBitToExpansion(expansion_bit));
}
uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
uint32 EQEmu::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
{
switch (expansion) {
case Expansion::RoK:
@@ -446,7 +446,7 @@ uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
}
}
EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
EQEmu::expansions::Expansion EQEmu::expansions::ConvertExpansionBitToExpansion(uint32 expansion_bit)
{
switch (expansion_bit) {
case bitRoK:
@@ -494,7 +494,7 @@ EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32
}
}
uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
uint32 EQEmu::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
{
switch (expansion) {
case Expansion::RoK:
@@ -542,17 +542,17 @@ uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
}
}
EQ::expansions::Expansion EQ::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
EQEmu::expansions::Expansion EQEmu::expansions::ConvertClientVersionToExpansion(versions::ClientVersion client_version)
{
return EQ::constants::StaticLookup(client_version)->Expansion;
return EQEmu::constants::StaticLookup(client_version)->Expansion;
}
uint32 EQ::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
uint32 EQEmu::expansions::ConvertClientVersionToExpansionBit(versions::ClientVersion client_version)
{
return EQ::constants::StaticLookup(client_version)->ExpansionBit;
return EQEmu::constants::StaticLookup(client_version)->ExpansionBit;
}
uint32 EQ::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
uint32 EQEmu::expansions::ConvertClientVersionToExpansionsMask(versions::ClientVersion client_version)
{
return EQ::constants::StaticLookup(client_version)->ExpansionsMask;
return EQEmu::constants::StaticLookup(client_version)->ExpansionsMask;
}
+1 -1
View File
@@ -25,7 +25,7 @@
#include <stdlib.h>
namespace EQ
namespace EQEmu
{
namespace versions {
enum class ClientVersion : uint32 {
+126 -777
View File
@@ -23,61 +23,60 @@
#include "skills.h"
#include "types.h"
namespace AppearanceType {
constexpr uint32 Die = 0; // Causes the client to keel over and zone to bind point (default action)
constexpr uint32 WhoLevel = 1; // Level that shows up on /who
constexpr uint32 MaxHealth = 2;
constexpr uint32 Invisibility = 3; // 0 = Visible, 1 = Invisible
constexpr uint32 PVP = 4; // 0 = Non-PVP, 1 = PVP
constexpr uint32 Light = 5; // Light type emitted by player (lightstone, shiny shield)
constexpr uint32 Animation = 14; // 100 = Standing, 102 = Freeze, 105 = Looting, 110 = Sitting, 111 = Crouching, 115 = Lying
constexpr uint32 Sneak = 15; // 0 = Normal, 1 = Sneaking
constexpr uint32 SpawnID = 16; // Server -> Client, sets player spawn ID
constexpr uint32 Health = 17; // Client->Server, my HP has changed (like regen tic)
constexpr uint32 Linkdead = 18; // 0 = Normal, 1 = Linkdead
constexpr uint32 FlyMode = 19; // 0 = Off, 1 = Flying, 2 = Levitating, 3 = Water, 4 = Floating, 5 = Levitating while Running
constexpr uint32 GM = 20; // 0 = Non-GM, 1 = GM
constexpr uint32 Anonymous = 21; // 0 = Non-Anonymous, 1 = Anonymous, 2 = Roleplaying
constexpr uint32 GuildID = 22;
constexpr uint32 GuildRank = 23;
constexpr uint32 AFK = 24; // 0 = Non-AFK, 1 = AFK
constexpr uint32 Pet = 25; // Parameter is Entity ID of owner, or 0 for when charm breaks
constexpr uint32 Summoned = 27;
constexpr uint32 Split = 28; // 0 = No Split, 1 = Auto Split
constexpr uint32 Size = 29; // Spawn's Size
constexpr uint32 SetType = 30; // 0 = PC, 1 = NPC, 2 = Corpse
constexpr uint32 NPCName = 31; // Change PC name color to NPC name color
constexpr uint32 AARank = 32; // AA Rank Title ID, title in /who?
constexpr uint32 CancelSneakHide = 33; // Turns off Hide and Sneak
constexpr uint32 AreaHealthRegen = 35; // Guild Hall Regeneration Pool sets to value * 0.001
constexpr uint32 AreaManaRegen = 36; // Guild Hall Regeneration Pool sets to value * 0.001
constexpr uint32 AreaEnduranceRegen = 37; // Guild Hall Regeneration Pool sets to value * 0.001
constexpr uint32 FreezeBeneficialBuffs = 38; // Freezes beneficial buff timers for PCs
constexpr uint32 NPCTintIndex = 39;
constexpr uint32 GroupAutoConsent = 40; // Auto Consent Group
constexpr uint32 RaidAutoConsent = 41; // Auto Consent Raid
constexpr uint32 GuildAutoConsent = 42; // Auto Consent Guild
constexpr uint32 ShowHelm = 43; // 0 = Hide, 1 = Show
constexpr uint32 DamageState = 44; // The damage state of a destructible object (0 through 10) plays sound IDs, most only have 2 or 4 states though
constexpr uint32 EQPlayers = 45; // EQ Players Update
constexpr uint32 FindBits = 46; // Set Find Bits?
constexpr uint32 TextureType = 48; // Texture Type?
constexpr uint32 FacePick = 49; // Turns off face pick window?
constexpr uint32 AntiCheat = 51; // Sent by the client randomly telling the server how long since last action has occurred
constexpr uint32 GuildShow = 52;
constexpr uint32 OfflineMode = 53; // Offline Mode
}
namespace Animation {
constexpr uint32 Standing = 100;
constexpr uint32 Freeze = 102;
constexpr uint32 Looting = 105;
constexpr uint32 Sitting = 110;
constexpr uint32 Crouching = 111;
constexpr uint32 Lying = 115;
}
//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2)
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
#define AT_WhoLevel 1 // the level that shows up on /who
#define AT_HPMax 2 // idk
#define AT_Invis 3 // 0 = visible, 1 = invisible
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
#define AT_Anim 14 // 100=standing, 110=sitting, 111=ducking, 115=feigned, 105=looting
#define AT_Sneak 15 // 0 = normal, 1 = sneaking
#define AT_SpawnID 16 // server to client, sets player spawn id
#define AT_HP 17 // Client->Server, my HP has changed (like regen tic)
#define AT_Linkdead 18 // 0 = normal, 1 = linkdead
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate max 5, see GravityBehavior enum
#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM
#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay
#define AT_GuildID 22
#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader
#define AT_AFK 24 // 0 = normal, 1 = afk
#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks
#define AT_Summoned 27 // Unsure
#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only)
#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2)
#define AT_SetType 30 // 0 = PC, 1 = NPC, 2 <= = corpse
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name, Trader on RoF2?
#define AT_AARank 32 // AA Rank Title ID thingy, does is this the title in /who?
#define AT_CancelSneakHide 33 // Turns off Hide and Sneak
//#define AT_34 34 // unknown (present: SoF, absent: RoF2)
#define AT_AreaHPRegen 35 // guild hall regen pool sets to value * 0.001
#define AT_AreaManaRegen 36 // guild hall regen pool sets to value * 0.001
#define AT_AreaEndRegen 37 // guild hall regen pool sets to value * 0.001
#define AT_FreezeBuffs 38 // Freezes beneficial buff timers
#define AT_NpcTintIndex 39 // not 100% sure
#define AT_GroupConsent 40 // auto consent group
#define AT_RaidConsent 41 // auto consent raid
#define AT_GuildConsent 42 // auto consent guild
#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic
#define AT_DamageState 44 // The damage state of a destructible object (0 through 10) plays soundids most only have 2 or 4 states though
#define AT_EQPlayers 45 // /eqplayersupdate
#define AT_FindBits 46 // set FindBits, whatever those are!
#define AT_TextureType 48 // TextureType
#define AT_FacePick 49 // Turns off face pick window? maybe ...
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
#define AT_Offline 53 // Offline mode
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
// animations for AT_Anim
#define ANIM_FREEZE 102
#define ANIM_STAND 0x64
#define ANIM_SIT 0x6e
#define ANIM_CROUCH 0x6f
#define ANIM_DEATH 0x73
#define ANIM_LOOT 0x69
typedef enum {
eaStanding = 0,
@@ -198,539 +197,14 @@ namespace Chat {
const uint16 Stun = 340;
};
// generation SQL:
// SELECT CONCAT(' constexpr uint16 ', UPPER(short_name), ' = ' , zoneidnumber, '; // ', long_name) from zone group by zoneidnumber ORDER BY zoneidnumber;
namespace Zones {
constexpr uint16 QEYNOS = 1; // South Qeynos
constexpr uint16 QEYNOS2 = 2; // North Qeynos
constexpr uint16 QRG = 3; // The Surefall Glade
constexpr uint16 QEYTOQRG = 4; // The Qeynos Hills
constexpr uint16 HIGHPASS = 5; // Highpass Hold
constexpr uint16 HIGHKEEP = 6; // High Keep
constexpr uint16 FREPORTN = 8; // North Freeport
constexpr uint16 FREPORTW = 9; // West Freeport
constexpr uint16 FREPORTE = 10; // East Freeport
constexpr uint16 RUNNYEYE = 11; // The Liberated Citadel of Runnyeye
constexpr uint16 QEY2HH1 = 12; // The Western Plains of Karana
constexpr uint16 NORTHKARANA = 13; // The Northern Plains of Karana
constexpr uint16 SOUTHKARANA = 14; // The Southern Plains of Karana
constexpr uint16 EASTKARANA = 15; // Eastern Plains of Karana
constexpr uint16 BEHOLDER = 16; // Gorge of King Xorbb
constexpr uint16 BLACKBURROW = 17; // Blackburrow
constexpr uint16 PAW = 18; // The Lair of the Splitpaw
constexpr uint16 RIVERVALE = 19; // Rivervale
constexpr uint16 KITHICOR = 20; // Kithicor Forest
constexpr uint16 COMMONS = 21; // West Commonlands
constexpr uint16 ECOMMONS = 22; // East Commonlands
constexpr uint16 ERUDNINT = 23; // The Erudin Palace
constexpr uint16 ERUDNEXT = 24; // Erudin
constexpr uint16 NEKTULOS = 25; // The Nektulos Forest
constexpr uint16 CSHOME = 26; // Sunset Home
constexpr uint16 LAVASTORM = 27; // The Lavastorm Mountains
constexpr uint16 NEKTROPOS = 28; // Nektropos
constexpr uint16 HALAS = 29; // Halas
constexpr uint16 EVERFROST = 30; // Everfrost Peaks
constexpr uint16 SOLDUNGA = 31; // Solusek's Eye
constexpr uint16 SOLDUNGB = 32; // Nagafen's Lair
constexpr uint16 MISTY = 33; // Misty Thicket
constexpr uint16 NRO = 34; // Northern Desert of Ro
constexpr uint16 SRO = 35; // Southern Desert of Ro
constexpr uint16 BEFALLEN = 36; // Befallen
constexpr uint16 OASIS = 37; // Oasis of Marr
constexpr uint16 TOX = 38; // Toxxulia Forest
constexpr uint16 HOLE = 39; // The Hole
constexpr uint16 NERIAKA = 40; // Neriak - Foreign Quarter
constexpr uint16 NERIAKB = 41; // Neriak - Commons
constexpr uint16 NERIAKC = 42; // Neriak - 3rd Gate
constexpr uint16 NERIAKD = 43; // Neriak Palace
constexpr uint16 NAJENA = 44; // Najena
constexpr uint16 QCAT = 45; // The Qeynos Aqueduct System
constexpr uint16 INNOTHULE = 46; // Innothule Swamp
constexpr uint16 FEERROTT = 47; // The Feerrott
constexpr uint16 CAZICTHULE = 48; // Accursed Temple of CazicThule
constexpr uint16 OGGOK = 49; // Oggok
constexpr uint16 RATHEMTN = 50; // The Rathe Mountains
constexpr uint16 LAKERATHE = 51; // Lake Rathetear
constexpr uint16 GROBB = 52; // Grobb
constexpr uint16 AVIAK = 53; // Aviak Village
constexpr uint16 GFAYDARK = 54; // The Greater Faydark
constexpr uint16 AKANON = 55; // Ak'Anon
constexpr uint16 STEAMFONT = 56; // Steamfont Mountains
constexpr uint16 LFAYDARK = 57; // The Lesser Faydark
constexpr uint16 CRUSHBONE = 58; // Crushbone
constexpr uint16 MISTMOORE = 59; // The Castle of Mistmoore
constexpr uint16 KALADIMA = 60; // South Kaladim
constexpr uint16 FELWITHEA = 61; // Northern Felwithe
constexpr uint16 FELWITHEB = 62; // Southern Felwithe
constexpr uint16 UNREST = 63; // The Estate of Unrest
constexpr uint16 KEDGE = 64; // Kedge Keep
constexpr uint16 GUKTOP = 65; // The City of Guk
constexpr uint16 GUKBOTTOM = 66; // The Ruins of Old Guk
constexpr uint16 KALADIMB = 67; // North Kaladim
constexpr uint16 BUTCHER = 68; // Butcherblock Mountains
constexpr uint16 OOT = 69; // Ocean of Tears
constexpr uint16 CAULDRON = 70; // Dagnor's Cauldron
constexpr uint16 AIRPLANE = 71; // The Plane of Sky
constexpr uint16 FEARPLANE = 72; // The Plane of Fear
constexpr uint16 PERMAFROST = 73; // The Permafrost Caverns
constexpr uint16 KERRARIDGE = 74; // Kerra Isle
constexpr uint16 PAINEEL = 75; // Paineel
constexpr uint16 HATEPLANE = 76; // Plane of Hate
constexpr uint16 ARENA = 77; // The Arena
constexpr uint16 FIELDOFBONE = 78; // The Field of Bone
constexpr uint16 WARSLIKSWOOD = 79; // The Warsliks Woods
constexpr uint16 SOLTEMPLE = 80; // The Temple of Solusek Ro
constexpr uint16 DROGA = 81; // The Temple of Droga
constexpr uint16 CABWEST = 82; // Cabilis West
constexpr uint16 SWAMPOFNOHOPE = 83; // The Swamp of No Hope
constexpr uint16 FIRIONA = 84; // Firiona Vie
constexpr uint16 LAKEOFILLOMEN = 85; // Lake of Ill Omen
constexpr uint16 DREADLANDS = 86; // The Dreadlands
constexpr uint16 BURNINGWOOD = 87; // The Burning Wood
constexpr uint16 KAESORA = 88; // Kaesora
constexpr uint16 SEBILIS = 89; // The Ruins of Sebilis
constexpr uint16 CITYMIST = 90; // The City of Mist
constexpr uint16 SKYFIRE = 91; // The Skyfire Mountains
constexpr uint16 FRONTIERMTNS = 92; // Frontier Mountains
constexpr uint16 OVERTHERE = 93; // The Overthere
constexpr uint16 EMERALDJUNGLE = 94; // The Emerald Jungle
constexpr uint16 TRAKANON = 95; // Trakanon's Teeth
constexpr uint16 TIMOROUS = 96; // Timorous Deep
constexpr uint16 KURN = 97; // Kurn's Tower
constexpr uint16 ERUDSXING = 98; // Erud's Crossing
constexpr uint16 STONEBRUNT = 100; // The Stonebrunt Mountains
constexpr uint16 WARRENS = 101; // The Warrens
constexpr uint16 KARNOR = 102; // Karnor's Castle
constexpr uint16 CHARDOK = 103; // Chardok
constexpr uint16 DALNIR = 104; // The Crypt of Dalnir
constexpr uint16 CHARASIS = 105; // The Howling Stones
constexpr uint16 CABEAST = 106; // Cabilis East
constexpr uint16 NURGA = 107; // The Mines of Nurga
constexpr uint16 VEESHAN = 108; // Veeshan's Peak
constexpr uint16 VEKSAR = 109; // Veksar
constexpr uint16 ICECLAD = 110; // The Iceclad Ocean
constexpr uint16 FROZENSHADOW = 111; // The Tower of Frozen Shadow
constexpr uint16 VELKETOR = 112; // Velketor's Labyrinth
constexpr uint16 KAEL = 113; // Kael Drakkel
constexpr uint16 SKYSHRINE = 114; // Skyshrine
constexpr uint16 THURGADINA = 115; // The City of Thurgadin
constexpr uint16 EASTWASTES = 116; // Eastern Wastes
constexpr uint16 COBALTSCAR = 117; // Cobaltscar
constexpr uint16 GREATDIVIDE = 118; // The Great Divide
constexpr uint16 WAKENING = 119; // The Wakening Land
constexpr uint16 WESTWASTES = 120; // The Western Wastes
constexpr uint16 CRYSTAL = 121; // The Crystal Caverns
constexpr uint16 NECROPOLIS = 123; // Dragon Necropolis
constexpr uint16 TEMPLEVEESHAN = 124; // The Temple of Veeshan
constexpr uint16 SIRENS = 125; // Siren's Grotto
constexpr uint16 MISCHIEFPLANE = 126; // The Plane of Mischief
constexpr uint16 GROWTHPLANE = 127; // The Plane of Growth
constexpr uint16 SLEEPER = 128; // The Sleeper's Tomb
constexpr uint16 THURGADINB = 129; // Icewell Keep
constexpr uint16 ERUDSXING2 = 130; // Marauders Mire
constexpr uint16 SHADOWHAVEN = 150; // Shadow Haven
constexpr uint16 BAZAAR = 151; // The Bazaar
constexpr uint16 NEXUS = 152; // Nexus
constexpr uint16 ECHO_ = 153; // The Echo Caverns
constexpr uint16 ACRYLIA = 154; // The Acrylia Caverns
constexpr uint16 SHARVAHL = 155; // The City of Shar Vahl
constexpr uint16 PALUDAL = 156; // The Paludal Caverns
constexpr uint16 FUNGUSGROVE = 157; // The Fungus Grove
constexpr uint16 VEXTHAL = 158; // Vex Thal
constexpr uint16 SSERU = 159; // Sanctus Seru
constexpr uint16 KATTA = 160; // Katta Castellum
constexpr uint16 NETHERBIAN = 161; // Netherbian Lair
constexpr uint16 SSRATEMPLE = 162; // Ssraeshza Temple
constexpr uint16 GRIEGSEND = 163; // Grieg's End
constexpr uint16 THEDEEP = 164; // The Deep
constexpr uint16 SHADEWEAVER = 165; // Shadeweaver's Thicket
constexpr uint16 HOLLOWSHADE = 166; // Hollowshade Moor
constexpr uint16 GRIMLING = 167; // Grimling Forest
constexpr uint16 MSERU = 168; // Marus Seru
constexpr uint16 LETALIS = 169; // Mons Letalis
constexpr uint16 TWILIGHT = 170; // The Twilight Sea
constexpr uint16 THEGREY = 171; // The Grey
constexpr uint16 TENEBROUS = 172; // The Tenebrous Mountains
constexpr uint16 MAIDEN = 173; // The Maiden's Eye
constexpr uint16 DAWNSHROUD = 174; // The Dawnshroud Peaks
constexpr uint16 SCARLET = 175; // The Scarlet Desert
constexpr uint16 UMBRAL = 176; // The Umbral Plains
constexpr uint16 AKHEVA = 179; // The Akheva Ruins
constexpr uint16 ARENA2 = 180; // The Arena Two
constexpr uint16 JAGGEDPINE = 181; // The Jaggedpine Forest
constexpr uint16 NEDARIA = 182; // Nedaria's Landing
constexpr uint16 TUTORIAL = 183; // EverQuest Tutorial
constexpr uint16 LOAD = 184; // Loading Zone
constexpr uint16 LOAD2 = 185; // New Loading Zone
constexpr uint16 HATEPLANEB = 186; // The Plane of Hate
constexpr uint16 SHADOWREST = 187; // Shadowrest
constexpr uint16 TUTORIALA = 188; // The Mines of Gloomingdeep
constexpr uint16 TUTORIALB = 189; // The Mines of Gloomingdeep
constexpr uint16 CLZ = 190; // Loading
constexpr uint16 CODECAY = 200; // The Crypt of Decay
constexpr uint16 POJUSTICE = 201; // The Plane of Justice
constexpr uint16 POKNOWLEDGE = 202; // The Plane of Knowledge
constexpr uint16 POTRANQUILITY = 203; // The Plane of Tranquility
constexpr uint16 PONIGHTMARE = 204; // The Plane of Nightmares
constexpr uint16 PODISEASE = 205; // The Plane of Disease
constexpr uint16 POINNOVATION = 206; // The Plane of Innovation
constexpr uint16 POTORMENT = 207; // Torment, the Plane of Pain
constexpr uint16 POVALOR = 208; // The Plane of Valor
constexpr uint16 BOTHUNDER = 209; // Bastion of Thunder
constexpr uint16 POSTORMS = 210; // The Plane of Storms
constexpr uint16 HOHONORA = 211; // The Halls of Honor
constexpr uint16 SOLROTOWER = 212; // The Tower of Solusek Ro
constexpr uint16 POWAR = 213; // Plane of War
constexpr uint16 POTACTICS = 214; // Drunder, the Fortress of Zek
constexpr uint16 POAIR = 215; // The Plane of Air
constexpr uint16 POWATER = 216; // The Plane of Water
constexpr uint16 POFIRE = 217; // The Plane of Fire
constexpr uint16 POEARTHA = 218; // The Plane of Earth
constexpr uint16 POTIMEA = 219; // The Plane of Time
constexpr uint16 HOHONORB = 220; // The Temple of Marr
constexpr uint16 NIGHTMAREB = 221; // The Lair of Terris Thule
constexpr uint16 POEARTHB = 222; // The Plane of Earth
constexpr uint16 POTIMEB = 223; // The Plane of Time
constexpr uint16 GUNTHAK = 224; // The Gulf of Gunthak
constexpr uint16 DULAK = 225; // Dulak's Harbor
constexpr uint16 TORGIRAN = 226; // The Torgiran Mines
constexpr uint16 NADOX = 227; // The Crypt of Nadox
constexpr uint16 HATESFURY = 228; // Hate's Fury
constexpr uint16 GUKA = 229; // Deepest Guk: Cauldron of Lost Souls
constexpr uint16 RUJA = 230; // The Rujarkian Hills: Bloodied Quarries
constexpr uint16 TAKA = 231; // Takish-Hiz: Sunken Library
constexpr uint16 MIRA = 232; // Miragul's Menagerie: Silent Gallery
constexpr uint16 MMCA = 233; // Mistmoore's Catacombs: Forlorn Caverns
constexpr uint16 GUKB = 234; // The Drowning Crypt
constexpr uint16 RUJB = 235; // The Rujarkian Hills: Halls of War
constexpr uint16 TAKB = 236; // Takish-Hiz: Shifting Tower
constexpr uint16 MIRB = 237; // Miragul's Menagerie: Frozen Nightmare
constexpr uint16 MMCB = 238; // Mistmoore's Catacombs: Dreary Grotto
constexpr uint16 GUKC = 239; // Deepest Guk: Ancient Aqueducts
constexpr uint16 RUJC = 240; // The Rujarkian Hills: Wind Bridges
constexpr uint16 TAKC = 241; // Takish-Hiz: Within the Compact
constexpr uint16 MIRC = 242; // The Spider Den
constexpr uint16 MMCC = 243; // Mistmoore's Catacombs: Struggles within the Progeny
constexpr uint16 GUKD = 244; // The Mushroom Grove
constexpr uint16 RUJD = 245; // The Rujarkian Hills: Prison Break
constexpr uint16 TAKD = 246; // Takish-Hiz: Royal Observatory
constexpr uint16 MIRD = 247; // Miragul's Menagerie: Hushed Banquet
constexpr uint16 MMCD = 248; // Mistmoore's Catacombs: Chambers of Eternal Affliction
constexpr uint16 GUKE = 249; // Deepest Guk: The Curse Reborn
constexpr uint16 RUJE = 250; // The Rujarkian Hills: Drudge Hollows
constexpr uint16 TAKE = 251; // Takish-Hiz: River of Recollection
constexpr uint16 MIRE = 252; // The Frosted Halls
constexpr uint16 MMCE = 253; // Mistmoore's Catacombs: Sepulcher of the Damned
constexpr uint16 GUKF = 254; // Deepest Guk: Chapel of the Witnesses
constexpr uint16 RUJF = 255; // The Rujarkian Hills: Fortified Lair of the Taskmasters
constexpr uint16 TAKF = 256; // Takish-Hiz: Sandfall Corridors
constexpr uint16 MIRF = 257; // The Forgotten Wastes
constexpr uint16 MMCF = 258; // Mistmoore's Catacombs: Scion Lair of Fury
constexpr uint16 GUKG = 259; // The Root Garden
constexpr uint16 RUJG = 260; // The Rujarkian Hills: Hidden Vale of Deceit
constexpr uint16 TAKG = 261; // Takish-Hiz: Balancing Chamber
constexpr uint16 MIRG = 262; // Miragul's Menagerie: Heart of the Menagerie
constexpr uint16 MMCG = 263; // Mistmoore's Catacombs: Cesspits of Putrescence
constexpr uint16 GUKH = 264; // Deepest Guk: Accursed Sanctuary
constexpr uint16 RUJH = 265; // The Rujarkian Hills: Blazing Forge
constexpr uint16 TAKH = 266; // Takish-Hiz: Sweeping Tides
constexpr uint16 MIRH = 267; // The Morbid Laboratory
constexpr uint16 MMCH = 268; // Mistmoore's Catacombs: Aisles of Blood
constexpr uint16 RUJI = 269; // The Rujarkian Hills: Arena of Chance
constexpr uint16 TAKI = 270; // Takish-Hiz: Antiquated Palace
constexpr uint16 MIRI = 271; // The Theater of Imprisoned Horror
constexpr uint16 MMCI = 272; // Mistmoore's Catacombs: Halls of Sanguinary Rites
constexpr uint16 RUJJ = 273; // The Rujarkian Hills: Barracks of War
constexpr uint16 TAKJ = 274; // Takish-Hiz: Prismatic Corridors
constexpr uint16 MIRJ = 275; // Miragul's Menagerie: Grand Library
constexpr uint16 MMCJ = 276; // Mistmoore's Catacombs: Infernal Sanctuary
constexpr uint16 CHARDOKB = 277; // Chardok: The Halls of Betrayal
constexpr uint16 SOLDUNGC = 278; // The Caverns of Exile
constexpr uint16 ABYSMAL = 279; // The Abysmal Sea
constexpr uint16 NATIMBI = 280; // Natimbi, the Broken Shores
constexpr uint16 QINIMI = 281; // Qinimi, Court of Nihilia
constexpr uint16 RIWWI = 282; // Riwwi, Coliseum of Games
constexpr uint16 BARINDU = 283; // Barindu, Hanging Gardens
constexpr uint16 FERUBI = 284; // Ferubi, Forgotten Temple of Taelosia
constexpr uint16 SNPOOL = 285; // Sewers of Nihilia, Pool of Sludg
constexpr uint16 SNLAIR = 286; // Sewers of Nihilia, Lair of Trapp
constexpr uint16 SNPLANT = 287; // Sewers of Nihilia, Purifying Pla
constexpr uint16 SNCREMATORY = 288; // Sewers of Nihilia, Emanating Cre
constexpr uint16 TIPT = 289; // Tipt, Treacherous Crags
constexpr uint16 VXED = 290; // Vxed, the Crumbling Caverns
constexpr uint16 YXTTA = 291; // Yxtta, Pulpit of Exiles
constexpr uint16 UQUA = 292; // Uqua, the Ocean God Chantry
constexpr uint16 KODTAZ = 293; // Kod'Taz, Broken Trial Grounds
constexpr uint16 IKKINZ = 294; // Ikkinz, Chambers of Transcendence
constexpr uint16 QVIC = 295; // Qvic, Prayer Grounds of Calling
constexpr uint16 INKTUTA = 296; // Inktu'Ta, the Unmasked Chapel
constexpr uint16 TXEVU = 297; // Txevu, Lair of the Elite
constexpr uint16 TACVI = 298; // Tacvi, The Broken Temple
constexpr uint16 QVICB = 299; // Qvic, the Hidden Vault
constexpr uint16 WALLOFSLAUGHTER = 300; // Wall of Slaughter
constexpr uint16 BLOODFIELDS = 301; // The Bloodfields
constexpr uint16 DRANIKSSCAR = 302; // Dranik's Scar
constexpr uint16 CAUSEWAY = 303; // Nobles' Causeway
constexpr uint16 CHAMBERSA = 304; // Muramite Proving Grounds
constexpr uint16 CHAMBERSB = 305; // Muramite Proving Grounds
constexpr uint16 CHAMBERSC = 306; // Muramite Proving Grounds
constexpr uint16 CHAMBERSD = 307; // Muramite Proving Grounds
constexpr uint16 CHAMBERSE = 308; // Muramite Proving Grounds
constexpr uint16 CHAMBERSF = 309; // Muramite Proving Grounds
constexpr uint16 PROVINGGROUNDS = 316; // Muramite Proving Grounds
constexpr uint16 ANGUISH = 317; // Anguish, the Fallen Palace
constexpr uint16 DRANIKHOLLOWSA = 318; // Dranik's Hollows
constexpr uint16 DRANIKHOLLOWSB = 319; // Dranik's Hollows
constexpr uint16 DRANIKHOLLOWSC = 320; // Dranik's Hollows
constexpr uint16 DRANIKCATACOMBSA = 328; // Catacombs of Dranik
constexpr uint16 DRANIKCATACOMBSB = 329; // Catacombs of Dranik
constexpr uint16 DRANIKCATACOMBSC = 330; // Catacombs of Dranik
constexpr uint16 DRANIKSEWERSA = 331; // Sewers of Dranik
constexpr uint16 DRANIKSEWERSB = 332; // Sewers of Dranik
constexpr uint16 DRANIKSEWERSC = 333; // Sewers of Dranik
constexpr uint16 RIFTSEEKERS = 334; // Riftseekers' Sanctum
constexpr uint16 HARBINGERS = 335; // Harbinger's Spire
constexpr uint16 DRANIK = 336; // The Ruined City of Dranik
constexpr uint16 BROODLANDS = 337; // The Broodlands
constexpr uint16 STILLMOONA = 338; // Stillmoon Temple
constexpr uint16 STILLMOONB = 339; // The Ascent
constexpr uint16 THUNDERCREST = 340; // Thundercrest Isles
constexpr uint16 DELVEA = 341; // Lavaspinner's Lair
constexpr uint16 DELVEB = 342; // Tirranun's Delve
constexpr uint16 THENEST = 343; // The Nest
constexpr uint16 GUILDLOBBY = 344; // Guild Lobby
constexpr uint16 GUILDHALL = 345; // Guild Hall
constexpr uint16 BARTER = 346; // The Barter Hall
constexpr uint16 ILLSALIN = 347; // Ruins of Illsalin
constexpr uint16 ILLSALINA = 348; // Illsalin Marketplace
constexpr uint16 ILLSALINB = 349; // Temple of Korlach
constexpr uint16 ILLSALINC = 350; // The Nargil Pits
constexpr uint16 DREADSPIRE = 351; // Dreadspire Keep
constexpr uint16 DRACHNIDHIVE = 354; // The Hive
constexpr uint16 DRACHNIDHIVEA = 355; // The Hatchery
constexpr uint16 DRACHNIDHIVEB = 356; // The Cocoons
constexpr uint16 DRACHNIDHIVEC = 357; // Queen Sendaii`s Lair
constexpr uint16 WESTKORLACH = 358; // Stoneroot Falls
constexpr uint16 WESTKORLACHA = 359; // Prince's Manor
constexpr uint16 WESTKORLACHB = 360; // Caverns of the Lost
constexpr uint16 WESTKORLACHC = 361; // Lair of the Korlach
constexpr uint16 EASTKORLACH = 362; // The Undershore
constexpr uint16 EASTKORLACHA = 363; // Snarlstone Dens
constexpr uint16 SHADOWSPINE = 364; // Shadow Spine
constexpr uint16 CORATHUS = 365; // Corathus Creep
constexpr uint16 CORATHUSA = 366; // Sporali Caverns
constexpr uint16 CORATHUSB = 367; // The Corathus Mines
constexpr uint16 NEKTULOSA = 368; // Shadowed Grove
constexpr uint16 ARCSTONE = 369; // Arcstone, Isle of Spirits
constexpr uint16 RELIC = 370; // Relic, the Artifact City
constexpr uint16 SKYLANCE = 371; // Skylance
constexpr uint16 DEVASTATION = 372; // The Devastation
constexpr uint16 DEVASTATIONA = 373; // The Seething Wall
constexpr uint16 RAGE = 374; // Sverag, Stronghold of Rage
constexpr uint16 RAGEA = 375; // Razorthorn, Tower of Sullon Zek
constexpr uint16 TAKISHRUINS = 376; // Ruins of Takish-Hiz
constexpr uint16 TAKISHRUINSA = 377; // The Root of Ro
constexpr uint16 ELDDAR = 378; // The Elddar Forest
constexpr uint16 ELDDARA = 379; // Tunare's Shrine
constexpr uint16 THEATER = 380; // Theater of Blood
constexpr uint16 THEATERA = 381; // Deathknell, Tower of Dissonance
constexpr uint16 FREEPORTEAST = 382; // East Freeport
constexpr uint16 FREEPORTWEST = 383; // West Freeport
constexpr uint16 FREEPORTSEWERS = 384; // Freeport Sewers
constexpr uint16 FREEPORTACADEMY = 385; // Academy of Arcane Sciences
constexpr uint16 FREEPORTTEMPLE = 386; // Temple of Marr
constexpr uint16 FREEPORTMILITIA = 387; // Freeport Militia House: My Precious
constexpr uint16 FREEPORTARENA = 388; // Arena
constexpr uint16 FREEPORTCITYHALL = 389; // City Hall
constexpr uint16 FREEPORTTHEATER = 390; // Theater of the Tranquil
constexpr uint16 FREEPORTHALL = 391; // Hall of Truth: Bounty
constexpr uint16 NORTHRO = 392; // North Desert of Ro
constexpr uint16 SOUTHRO = 393; // South Desert of Ro
constexpr uint16 CRESCENT = 394; // Crescent Reach
constexpr uint16 MOORS = 395; // Blightfire Moors
constexpr uint16 STONEHIVE = 396; // Stone Hive
constexpr uint16 MESA = 397; // Goru`kar Mesa
constexpr uint16 ROOST = 398; // Blackfeather Roost
constexpr uint16 STEPPES = 399; // The Steppes
constexpr uint16 ICEFALL = 400; // Icefall Glacier
constexpr uint16 VALDEHOLM = 401; // Valdeholm
constexpr uint16 FROSTCRYPT = 402; // Frostcrypt, Throne of the Shade King
constexpr uint16 SUNDEROCK = 403; // Sunderock Springs
constexpr uint16 VERGALID = 404; // Vergalid Mines
constexpr uint16 DIREWIND = 405; // Direwind Cliffs
constexpr uint16 ASHENGATE = 406; // Ashengate, Reliquary of the Scale
constexpr uint16 HIGHPASSHOLD = 407; // Highpass Hold
constexpr uint16 COMMONLANDS = 408; // The Commonlands
constexpr uint16 OCEANOFTEARS = 409; // The Ocean of Tears
constexpr uint16 KITHFOREST = 410; // Kithicor Forest
constexpr uint16 BEFALLENB = 411; // Befallen
constexpr uint16 HIGHPASSKEEP = 412; // HighKeep
constexpr uint16 INNOTHULEB = 413; // The Innothule Swamp
constexpr uint16 TOXXULIA = 414; // Toxxulia Forest
constexpr uint16 MISTYTHICKET = 415; // The Misty Thicket
constexpr uint16 KATTACASTRUM = 416; // Katta Castrum
constexpr uint16 THALASSIUS = 417; // Thalassius, the Coral Keep
constexpr uint16 ATIIKI = 418; // Jewel of Atiiki
constexpr uint16 ZHISZA = 419; // Zhisza, the Shissar Sanctuary
constexpr uint16 SILYSSAR = 420; // Silyssar, New Chelsith
constexpr uint16 SOLTERIS = 421; // Solteris, the Throne of Ro
constexpr uint16 BARREN = 422; // Barren Coast
constexpr uint16 BURIEDSEA = 423; // The Buried Sea
constexpr uint16 JARDELSHOOK = 424; // Jardel's Hook
constexpr uint16 MONKEYROCK = 425; // Monkey Rock
constexpr uint16 SUNCREST = 426; // Suncrest Isle
constexpr uint16 DEADBONE = 427; // Deadbone Reef
constexpr uint16 BLACKSAIL = 428; // Blacksail Folly
constexpr uint16 MAIDENSGRAVE = 429; // Maiden's Grave
constexpr uint16 REDFEATHER = 430; // Redfeather Isle
constexpr uint16 SHIPMVP = 431; // The Open Sea
constexpr uint16 SHIPMVU = 432; // The Open Sea
constexpr uint16 SHIPPVU = 433; // The Open Sea
constexpr uint16 SHIPUVU = 434; // The Open Sea
constexpr uint16 SHIPMVM = 435; // The Open Sea
constexpr uint16 MECHANOTUS = 436; // Fortress Mechanotus
constexpr uint16 MANSION = 437; // Meldrath's Majestic Mansion
constexpr uint16 STEAMFACTORY = 438; // The Steam Factory
constexpr uint16 SHIPWORKSHOP = 439; // S.H.I.P. Workshop
constexpr uint16 GYROSPIREB = 440; // Gyrospire Beza
constexpr uint16 GYROSPIREZ = 441; // Gyrospire Zeka
constexpr uint16 DRAGONSCALE = 442; // Dragonscale Hills
constexpr uint16 LOPINGPLAINS = 443; // Loping Plains
constexpr uint16 HILLSOFSHADE = 444; // Hills of Shade
constexpr uint16 BLOODMOON = 445; // Bloodmoon Keep
constexpr uint16 CRYSTALLOS = 446; // Crystallos, Lair of the Awakened
constexpr uint16 GUARDIAN = 447; // The Mechamatic Guardian
constexpr uint16 STEAMFONTMTS = 448; // The Steamfont Mountains
constexpr uint16 CRYPTOFSHADE = 449; // Crypt of Shade
constexpr uint16 DRAGONSCALEB = 451; // Deepscar's Den
constexpr uint16 OLDFIELDOFBONE = 452; // Field of Scale
constexpr uint16 OLDKAESORAA = 453; // Kaesora Library
constexpr uint16 OLDKAESORAB = 454; // Kaesora Hatchery
constexpr uint16 OLDKURN = 455; // Kurn's Tower
constexpr uint16 OLDKITHICOR = 456; // Bloody Kithicor
constexpr uint16 OLDCOMMONS = 457; // Old Commonlands
constexpr uint16 OLDHIGHPASS = 458; // Highpass Hold
constexpr uint16 THEVOIDA = 459; // The Void
constexpr uint16 THEVOIDB = 460; // The Void
constexpr uint16 THEVOIDC = 461; // The Void
constexpr uint16 THEVOIDD = 462; // The Void
constexpr uint16 THEVOIDE = 463; // The Void
constexpr uint16 THEVOIDF = 464; // The Void
constexpr uint16 THEVOIDG = 465; // The Void
constexpr uint16 OCEANGREENHILLS = 466; // Oceangreen Hills
constexpr uint16 OCEANGREENVILLAGE = 467; // Oceangreen Village
constexpr uint16 OLDBLACKBURROW = 468; // BlackBurrow
constexpr uint16 BERTOXTEMPLE = 469; // Temple of Bertoxxulous
constexpr uint16 DISCORD = 470; // Korafax, Home of the Riders
constexpr uint16 DISCORDTOWER = 471; // Citadel of the Worldslayer
constexpr uint16 OLDBLOODFIELD = 472; // Old Bloodfields
constexpr uint16 PRECIPICEOFWAR = 473; // The Precipice of War
constexpr uint16 OLDDRANIK = 474; // City of Dranik
constexpr uint16 TOSKIRAKK = 475; // Toskirakk
constexpr uint16 KORASCIAN = 476; // Korascian Warrens
constexpr uint16 RATHECHAMBER = 477; // Rathe Council Chamber
constexpr uint16 BRELLSREST = 480; // Brell's Rest
constexpr uint16 FUNGALFOREST = 481; // Fungal Forest
constexpr uint16 UNDERQUARRY = 482; // The Underquarry
constexpr uint16 COOLINGCHAMBER = 483; // The Cooling Chamber
constexpr uint16 SHININGCITY = 484; // Kernagir, the Shining City
constexpr uint16 ARTHICREX = 485; // Arthicrex
constexpr uint16 FOUNDATION = 486; // The Foundation
constexpr uint16 LICHENCREEP = 487; // Lichen Creep
constexpr uint16 PELLUCID = 488; // Pellucid Grotto
constexpr uint16 STONESNAKE = 489; // Volska's Husk
constexpr uint16 BRELLSTEMPLE = 490; // Brell's Temple
constexpr uint16 CONVORTEUM = 491; // The Convorteum
constexpr uint16 BRELLSARENA = 492; // Brell's Arena
constexpr uint16 WEDDINGCHAPEL = 493; // Wedding Chapel
constexpr uint16 WEDDINGCHAPELDARK = 494; // Wedding Chapel
constexpr uint16 DRAGONCRYPT = 495; // Lair of the Risen
constexpr uint16 FEERROTT2 = 700; // The Feerrott
constexpr uint16 THULEHOUSE1 = 701; // House of Thule
constexpr uint16 THULEHOUSE2 = 702; // House of Thule, Upper Floors
constexpr uint16 HOUSEGARDEN = 703; // The Grounds
constexpr uint16 THULELIBRARY = 704; // The Library
constexpr uint16 WELL = 705; // The Well
constexpr uint16 FALLEN = 706; // Erudin Burning
constexpr uint16 MORELLCASTLE = 707; // Morell's Castle
constexpr uint16 SOMNIUM = 708; // Sanctum Somnium
constexpr uint16 ALKABORMARE = 709; // Al'Kabor's Nightmare
constexpr uint16 MIRAGULMARE = 710; // Miragul's Nightmare
constexpr uint16 THULEDREAM = 711; // Fear Itself
constexpr uint16 NEIGHBORHOOD = 712; // Sunrise Hills
constexpr uint16 ARGATH = 724; // Argath, Bastion of Illdaera
constexpr uint16 ARELIS = 725; // Valley of Lunanyn
constexpr uint16 SARITHCITY = 726; // Sarith, City of Tides
constexpr uint16 RUBAK = 727; // Rubak Oseka, Temple of the Sea
constexpr uint16 BEASTDOMAIN = 728; // Beasts' Domain
constexpr uint16 RESPLENDENT = 729; // The Resplendent Temple
constexpr uint16 PILLARSALRA = 730; // Pillars of Alra
constexpr uint16 WINDSONG = 731; // Windsong Sanctuary
constexpr uint16 CITYOFBRONZE = 732; // Erillion, City of Bronze
constexpr uint16 SEPULCHER = 733; // Sepulcher of Order
constexpr uint16 EASTSEPULCHER = 734; // Sepulcher East
constexpr uint16 WESTSEPULCHER = 735; // Sepulcher West
constexpr uint16 SHARDSLANDING = 752; // Shard's Landing
constexpr uint16 XORBB = 753; // Valley of King Xorbb
constexpr uint16 KAELSHARD = 754; // Kael Drakkel: The King's Madness
constexpr uint16 EASTWASTESSHARD = 755; // East Wastes: Zeixshi-Kar's Awakening
constexpr uint16 CRYSTALSHARD = 756; // The Crystal Caverns: Fragment of Fear
constexpr uint16 BREEDINGGROUNDS = 757; // The Breeding Grounds
constexpr uint16 EVILTREE = 758; // Evantil, the Vile Oak
constexpr uint16 GRELLETH = 759; // Grelleth's Palace, the Chateau of Filth
constexpr uint16 CHAPTERHOUSE = 760; // Chapterhouse of the Fallen
constexpr uint16 ARTTEST = 996; // Art Testing Domain
constexpr uint16 FHALLS = 998; // The Forgotten Halls
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
}
//ZoneChange_Struct->success values
#define ZONE_ERROR_NOMSG 0
#define ZONE_ERROR_NOTREADY -1
#define ZONE_ERROR_VALIDPC -2
#define ZONE_ERROR_STORYZONE -3
#define ZONE_ERROR_NOEXPANSION -6
#define ZONE_ERROR_NOEXPERIENCE -7
namespace Language {
constexpr uint8 CommonTongue = 0;
constexpr uint8 Barbarian = 1;
constexpr uint8 Erudian = 2;
constexpr uint8 Elvish = 3;
constexpr uint8 DarkElvish = 4;
constexpr uint8 Dwarvish = 5;
constexpr uint8 Troll = 6;
constexpr uint8 Ogre = 7;
constexpr uint8 Gnomish = 8;
constexpr uint8 Halfling = 9;
constexpr uint8 ThievesCant = 10;
constexpr uint8 OldErudian = 11;
constexpr uint8 ElderElvish = 12;
constexpr uint8 Froglok = 13;
constexpr uint8 Goblin = 14;
constexpr uint8 Gnoll = 15;
constexpr uint8 CombineTongue = 16;
constexpr uint8 ElderTeirDal = 17;
constexpr uint8 Lizardman = 18;
constexpr uint8 Orcish = 19;
constexpr uint8 Faerie = 20;
constexpr uint8 Dragon = 21;
constexpr uint8 ElderDragon = 22;
constexpr uint8 DarkSpeech = 23;
constexpr uint8 VahShir = 24;
constexpr uint8 Alaran = 25;
constexpr uint8 Hadal = 26;
constexpr uint8 Unknown27 = 27;
constexpr uint8 MaxValue = 100;
}
namespace PetInfoType {
constexpr int Current = 0;
constexpr int Suspended = 1;
}
namespace BuffEffectType {
constexpr uint8 None = 0;
constexpr uint8 Buff = 2;
constexpr uint8 InverseBuff = 4;
}
namespace AlternateCurrencyMode {
constexpr uint32 Update = 7;
constexpr uint32 Populate = 8;
}
typedef enum {
FilterNone = 0,
@@ -757,11 +231,11 @@ typedef enum {
FilterPetMisses = 21, //0=show, 1=hide
FilterFocusEffects = 22, //0=show, 1=hide
FilterPetSpells = 23, //0=show, 1=hide
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
FilterItemSpeech = 25, //0=show, 1=hide // RoF2 Confirmed
FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed
FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed
FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed
FilterHealOverTime = 24, //0=show, 1=hide
FilterUnknown25 = 25,
FilterUnknown26 = 26,
FilterUnknown27 = 27,
FilterUnknown28 = 28,
_FilterCount
} eqFilterType;
@@ -772,47 +246,67 @@ typedef enum {
FilterShowSelfOnly
} eqFilterMode;
#define STAT_STR 0
#define STAT_STA 1
#define STAT_AGI 2
#define STAT_DEX 3
#define STAT_INT 4
#define STAT_WIS 5
#define STAT_CHA 6
#define STAT_MAGIC 7
#define STAT_COLD 8
#define STAT_FIRE 9
#define STAT_POISON 10
#define STAT_DISEASE 11
#define STAT_MANA 12
#define STAT_HP 13
#define STAT_AC 14
#define STAT_ENDURANCE 15
#define STAT_ATTACK 16
#define STAT_HP_REGEN 17
#define STAT_MANA_REGEN 18
#define STAT_HASTE 19
#define STAT_DAMAGE_SHIELD 20
#define STAT_DS_MITIGATION 22
#define STAT_HEAL_AMOUNT 23
#define STAT_SPELL_DAMAGE 24
#define STAT_CLAIRVOYANCE 25
#define STAT_HEROIC_AGILITY 26
#define STAT_HEROIC_CHARISMA 27
#define STAT_HEROIC_DEXTERITY 28
#define STAT_HEROIC_INTELLIGENCE 29
#define STAT_HEROIC_STAMINA 30
#define STAT_HEROIC_STRENGTH 31
#define STAT_HEROIC_WISDOM 32
#define STAT_BASH 33
#define STAT_BACKSTAB 34
#define STAT_DRAGON_PUNCH 35
#define STAT_EAGLE_STRIKE 36
#define STAT_FLYING_KICK 37
#define STAT_KICK 38
#define STAT_ROUND_KICK 39
#define STAT_TIGER_CLAW 40
#define STAT_FRENZY 41
#define STAT_STR 0
#define STAT_STA 1
#define STAT_AGI 2
#define STAT_DEX 3
#define STAT_INT 4
#define STAT_WIS 5
#define STAT_CHA 6
#define STAT_MAGIC 7
#define STAT_COLD 8
#define STAT_FIRE 9
#define STAT_POISON 10
#define STAT_DISEASE 11
#define STAT_MANA 12
#define STAT_HP 13
#define STAT_AC 14
#define STAT_ENDURANCE 15
#define STAT_ATTACK 16
#define STAT_HP_REGEN 17
#define STAT_MANA_REGEN 18
#define STAT_HASTE 19
#define STAT_DAMAGE_SHIELD 20
/*
** Recast timer types. Used as an off set to charProfileStruct timers.
**
** (Another orphaned enumeration...)
*/
enum RecastTimerTypes
{
RecTimer_0 = 0,
RecTimer_1,
RecTimer_WeaponHealClick, // 2
RecTimer_MuramiteBaneNukeClick, // 3
RecTimer_4,
RecTimer_DispellClick, // 5 (also click heal orbs?)
RecTimer_Epic, // 6
RecTimer_OoWBPClick, // 7
RecTimer_VishQuestClassItem, // 8
RecTimer_HealPotion, // 9
RecTimer_10,
RecTimer_11,
RecTimer_12,
RecTimer_13,
RecTimer_14,
RecTimer_15,
RecTimer_16,
RecTimer_17,
RecTimer_18,
RecTimer_ModRod, // 19
_RecTimerCount
};
enum GroupUpdateAction
{
GUA_Joined = 0,
GUA_Left = 1,
GUA_LastLeft = 6,
GUA_FullGroupInfo = 7,
GUA_MakeLeader = 8,
GUA_Started = 9
};
static const uint8 DamageTypeSomething = 0x1C; //0x1c is something...
static const uint8 DamageTypeFalling = 0xFC;
@@ -824,7 +318,7 @@ static const uint8 DamageTypeUnknown = 0xFF;
**
** (indexed by 'Skill' of SkillUseTypes)
*/
static const uint8 SkillDamageTypes[EQ::skills::HIGHEST_SKILL + 1] = // change to _SkillServerArraySize once activated
static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // change to _SkillServerArraySize once activated
{
/*1HBlunt*/ 0,
/*1HSlashing*/ 1,
@@ -944,10 +438,6 @@ static const uint8 SkillDamageTypes[EQ::skills::HIGHEST_SKILL + 1] = // change t
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
static const uint32 DB_FACTION_GEM_CHOPPERS = 255;
static const uint32 DB_FACTION_HERETICS = 265;
static const uint32 DB_FACTION_KING_AKANON = 333;
enum ChatChannelNames : uint16
{
ChatChannel_Guild = 0,
@@ -974,145 +464,4 @@ namespace ZoneBlockedSpellTypes {
const uint8 Region = 2;
};
enum class DynamicZoneType
{
None = 0,
Expedition,
Tutorial,
Task,
Mission, // Shared Task
Quest
};
enum class DynamicZoneMemberStatus : uint8_t
{
Unknown = 0,
Online,
Offline,
InDynamicZone,
LinkDead
};
enum 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
};
namespace RaidLootType {
constexpr uint32 LeaderOnly = 1;
constexpr uint32 LeaderAndGroupLeadersOnly = 2;
constexpr uint32 LeaderSelected = 3;
constexpr uint32 EntireRaid = 4;
}
namespace LeadershipAbilitySlot {
constexpr uint16 HealthOfTargetsTarget = 14;
}
enum ExpSource
{
Quest,
GM,
Kill,
Death,
Resurrection,
LDoNChest,
Task,
Sacrifice
};
#define PARCEL_SEND_ITEMS 0
#define PARCEL_SEND_MONEY 1
#define PARCEL_MONEY_ITEM_ID 99990 // item id of money
#define PARCEL_LIMIT 5
#define PARCEL_BEGIN_SLOT 1
namespace DoorType {
constexpr uint32 BuyerStall = 155;
}
#endif /*COMMON_EQ_CONSTANTS_H*/
+192 -200
View File
@@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
@@ -11,7 +11,7 @@
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -25,8 +25,8 @@
static bool global_dictionary_init = false;
void EQ::InitializeDynamicLookups() {
if (global_dictionary_init)
void EQEmu::InitializeDynamicLookups() {
if (global_dictionary_init == true)
return;
constants::InitializeDynamicLookups();
@@ -37,86 +37,78 @@ void EQ::InitializeDynamicLookups() {
global_dictionary_init = true;
}
static std::unique_ptr<EQ::constants::LookupEntry> constants_dynamic_nongm_lookup_entries[EQ::versions::ClientVersionCount];
static std::unique_ptr<EQ::constants::LookupEntry> constants_dynamic_gm_lookup_entries[EQ::versions::ClientVersionCount];
static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::versions::ClientVersionCount] =
static std::unique_ptr<EQEmu::constants::LookupEntry> constants_dynamic_nongm_lookup_entries[EQEmu::versions::ClientVersionCount];
static std::unique_ptr<EQEmu::constants::LookupEntry> constants_dynamic_gm_lookup_entries[EQEmu::versions::ClientVersionCount];
static const EQEmu::constants::LookupEntry constants_static_lookup_entries[EQEmu::versions::ClientVersionCount] =
{
/*[ClientVersion::Unknown] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
ClientUnknown::constants::EXPANSION,
ClientUnknown::constants::EXPANSION_BIT,
ClientUnknown::constants::EXPANSIONS_MASK,
ClientUnknown::INULL,
ClientUnknown::INULL,
ClientUnknown::INULL
),
/*[ClientVersion::Client62] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
Client62::constants::EXPANSION,
Client62::constants::EXPANSION_BIT,
Client62::constants::EXPANSIONS_MASK,
Client62::INULL,
Client62::INULL,
Client62::INULL
),
/*[ClientVersion::Titanium] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
Titanium::constants::EXPANSION,
Titanium::constants::EXPANSION_BIT,
Titanium::constants::EXPANSIONS_MASK,
Titanium::constants::CHARACTER_CREATION_LIMIT,
Titanium::constants::SAY_LINK_BODY_SIZE,
Titanium::INULL
Titanium::constants::SAY_LINK_BODY_SIZE
),
/*[ClientVersion::SoF] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
SoF::constants::EXPANSION,
SoF::constants::EXPANSION_BIT,
SoF::constants::EXPANSIONS_MASK,
SoF::constants::CHARACTER_CREATION_LIMIT,
SoF::constants::SAY_LINK_BODY_SIZE,
SoF::INULL
SoF::constants::SAY_LINK_BODY_SIZE
),
/*[ClientVersion::SoD] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
SoD::constants::EXPANSION,
SoD::constants::EXPANSION_BIT,
SoD::constants::EXPANSIONS_MASK,
SoD::constants::CHARACTER_CREATION_LIMIT,
SoD::constants::SAY_LINK_BODY_SIZE,
SoD::INULL
SoD::constants::SAY_LINK_BODY_SIZE
),
/*[ClientVersion::UF] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
UF::constants::EXPANSION,
UF::constants::EXPANSION_BIT,
UF::constants::EXPANSIONS_MASK,
UF::constants::CHARACTER_CREATION_LIMIT,
UF::constants::SAY_LINK_BODY_SIZE,
UF::INULL
UF::constants::SAY_LINK_BODY_SIZE
),
/*[ClientVersion::RoF] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
RoF::constants::EXPANSION,
RoF::constants::EXPANSION_BIT,
RoF::constants::EXPANSIONS_MASK,
RoF::constants::CHARACTER_CREATION_LIMIT,
RoF::constants::SAY_LINK_BODY_SIZE,
RoF::INULL
RoF::constants::SAY_LINK_BODY_SIZE
),
/*[ClientVersion::RoF2] =*/
EQ::constants::LookupEntry(
EQEmu::constants::LookupEntry(
RoF2::constants::EXPANSION,
RoF2::constants::EXPANSION_BIT,
RoF2::constants::EXPANSIONS_MASK,
RoF2::constants::CHARACTER_CREATION_LIMIT,
RoF2::constants::SAY_LINK_BODY_SIZE,
RoF2::constants::MAX_BAZAAR_TRADERS
RoF2::constants::SAY_LINK_BODY_SIZE
)
};
static bool constants_dictionary_init = false;
void EQ::constants::InitializeDynamicLookups() {
void EQEmu::constants::InitializeDynamicLookups() {
if (constants_dictionary_init == true)
return;
constants_dictionary_init = true;
@@ -127,7 +119,7 @@ void EQ::constants::InitializeDynamicLookups() {
// use static references for now
}
const EQ::constants::LookupEntry* EQ::constants::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
const EQEmu::constants::LookupEntry* EQEmu::constants::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
{
if (gm_flag)
return DynamicGMLookup(client_version);
@@ -135,7 +127,7 @@ const EQ::constants::LookupEntry* EQ::constants::DynamicLookup(versions::ClientV
return DynamicNonGMLookup(client_version);
}
const EQ::constants::LookupEntry* EQ::constants::DynamicNonGMLookup(versions::ClientVersion client_version)
const EQEmu::constants::LookupEntry* EQEmu::constants::DynamicNonGMLookup(versions::ClientVersion client_version)
{
client_version = versions::ValidateClientVersion(client_version);
if (constants_dynamic_nongm_lookup_entries[static_cast<int>(client_version)])
@@ -144,7 +136,7 @@ const EQ::constants::LookupEntry* EQ::constants::DynamicNonGMLookup(versions::Cl
return &constants_static_lookup_entries[static_cast<int>(client_version)];
}
const EQ::constants::LookupEntry* EQ::constants::DynamicGMLookup(versions::ClientVersion client_version)
const EQEmu::constants::LookupEntry* EQEmu::constants::DynamicGMLookup(versions::ClientVersion client_version)
{
client_version = versions::ValidateClientVersion(client_version);
if (constants_dynamic_gm_lookup_entries[static_cast<int>(client_version)])
@@ -153,18 +145,18 @@ const EQ::constants::LookupEntry* EQ::constants::DynamicGMLookup(versions::Clien
return &constants_static_lookup_entries[static_cast<int>(client_version)];
}
const EQ::constants::LookupEntry* EQ::constants::StaticLookup(versions::ClientVersion client_version)
const EQEmu::constants::LookupEntry* EQEmu::constants::StaticLookup(versions::ClientVersion client_version)
{
return &constants_static_lookup_entries[static_cast<int>(versions::ValidateClientVersion(client_version))];
}
static std::unique_ptr<EQ::inventory::LookupEntry> inventory_dynamic_nongm_lookup_entries[EQ::versions::MobVersionCount];
static std::unique_ptr<EQ::inventory::LookupEntry> inventory_dynamic_gm_lookup_entries[EQ::versions::MobVersionCount];
static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::versions::MobVersionCount] =
static std::unique_ptr<EQEmu::inventory::LookupEntry> inventory_dynamic_nongm_lookup_entries[EQEmu::versions::MobVersionCount];
static std::unique_ptr<EQEmu::inventory::LookupEntry> inventory_dynamic_gm_lookup_entries[EQEmu::versions::MobVersionCount];
static const EQEmu::inventory::LookupEntry inventory_static_lookup_entries[EQEmu::versions::MobVersionCount] =
{
/*[MobVersion::Unknown] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
@@ -175,7 +167,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL,
ClientUnknown::INULL
),
ClientUnknown::INULL,
ClientUnknown::INULL,
ClientUnknown::INULL,
@@ -183,15 +175,15 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
ClientUnknown::INULL,
ClientUnknown::INULL,
ClientUnknown::INULL,
false,
false,
false,
false
),
/*[MobVersion::Client62] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL, Client62::INULL, Client62::INULL,
@@ -202,7 +194,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Client62::INULL, Client62::INULL, Client62::INULL,
Client62::INULL
),
Client62::INULL,
Client62::INULL,
Client62::INULL,
@@ -210,16 +202,16 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Client62::INULL,
Client62::INULL,
Client62::INULL,
false,
false,
false,
false
),
/*[MobVersion::Titanium] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, Titanium::invtype::BANK_SIZE, Titanium::invtype::SHARED_BANK_SIZE,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, Titanium::invtype::BANK_SIZE, Titanium::invtype::SHARED_BANK_SIZE,
Titanium::invtype::TRADE_SIZE, Titanium::invtype::WORLD_SIZE, Titanium::invtype::LIMBO_SIZE,
Titanium::invtype::TRIBUTE_SIZE, Titanium::INULL, Titanium::invtype::GUILD_TRIBUTE_SIZE,
Titanium::invtype::MERCHANT_SIZE, Titanium::INULL, Titanium::invtype::CORPSE_SIZE,
@@ -229,7 +221,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Titanium::INULL, Titanium::INULL, Titanium::INULL,
Titanium::invtype::OTHER_SIZE
),
Titanium::invslot::EQUIPMENT_BITMASK,
Titanium::invslot::GENERAL_BITMASK,
Titanium::invslot::CURSOR_BITMASK,
@@ -237,16 +229,16 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
Titanium::invslot::CORPSE_BITMASK,
Titanium::invbag::SLOT_COUNT,
Titanium::invaug::SOCKET_COUNT,
Titanium::inventory::AllowEmptyBagInBag,
Titanium::inventory::AllowClickCastFromBag,
Titanium::inventory::ConcatenateInvTypeLimbo,
Titanium::inventory::AllowOverLevelEquipment
),
/*[MobVersion::SoF] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, SoF::invtype::BANK_SIZE, SoF::invtype::SHARED_BANK_SIZE,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, SoF::invtype::BANK_SIZE, SoF::invtype::SHARED_BANK_SIZE,
SoF::invtype::TRADE_SIZE, SoF::invtype::WORLD_SIZE, SoF::invtype::LIMBO_SIZE,
SoF::invtype::TRIBUTE_SIZE, SoF::INULL, SoF::invtype::GUILD_TRIBUTE_SIZE,
SoF::invtype::MERCHANT_SIZE, SoF::INULL, SoF::invtype::CORPSE_SIZE,
@@ -256,7 +248,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoF::INULL, SoF::INULL, SoF::INULL,
SoF::invtype::OTHER_SIZE
),
SoF::invslot::EQUIPMENT_BITMASK,
SoF::invslot::GENERAL_BITMASK,
SoF::invslot::CURSOR_BITMASK,
@@ -264,16 +256,16 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoF::invslot::CORPSE_BITMASK,
SoF::invbag::SLOT_COUNT,
SoF::invaug::SOCKET_COUNT,
SoF::inventory::AllowEmptyBagInBag,
SoF::inventory::AllowClickCastFromBag,
SoF::inventory::ConcatenateInvTypeLimbo,
SoF::inventory::AllowOverLevelEquipment
),
/*[MobVersion::SoD] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, SoD::invtype::BANK_SIZE, SoD::invtype::SHARED_BANK_SIZE,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, SoD::invtype::BANK_SIZE, SoD::invtype::SHARED_BANK_SIZE,
SoD::invtype::TRADE_SIZE, SoD::invtype::WORLD_SIZE, SoD::invtype::LIMBO_SIZE,
SoD::invtype::TRIBUTE_SIZE, SoD::INULL, SoD::invtype::GUILD_TRIBUTE_SIZE,
SoD::invtype::MERCHANT_SIZE, SoD::INULL, SoD::invtype::CORPSE_SIZE,
@@ -298,9 +290,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
SoD::inventory::AllowOverLevelEquipment
),
/*[MobVersion::UF] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, UF::invtype::BANK_SIZE, UF::invtype::SHARED_BANK_SIZE,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, UF::invtype::BANK_SIZE, UF::invtype::SHARED_BANK_SIZE,
UF::invtype::TRADE_SIZE, UF::invtype::WORLD_SIZE, UF::invtype::LIMBO_SIZE,
UF::invtype::TRIBUTE_SIZE, UF::INULL, UF::invtype::GUILD_TRIBUTE_SIZE,
UF::invtype::MERCHANT_SIZE, UF::INULL, UF::invtype::CORPSE_SIZE,
@@ -325,9 +317,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
UF::inventory::AllowOverLevelEquipment
),
/*[MobVersion::RoF] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, RoF::invtype::BANK_SIZE, RoF::invtype::SHARED_BANK_SIZE,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, RoF::invtype::BANK_SIZE, RoF::invtype::SHARED_BANK_SIZE,
RoF::invtype::TRADE_SIZE, RoF::invtype::WORLD_SIZE, RoF::invtype::LIMBO_SIZE,
RoF::invtype::TRIBUTE_SIZE, RoF::invtype::TROPHY_TRIBUTE_SIZE, RoF::invtype::GUILD_TRIBUTE_SIZE,
RoF::invtype::MERCHANT_SIZE, RoF::invtype::DELETED_SIZE, RoF::invtype::CORPSE_SIZE,
@@ -352,9 +344,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF::inventory::AllowOverLevelEquipment
),
/*[MobVersion::RoF2] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, RoF2::invtype::BANK_SIZE, RoF2::invtype::SHARED_BANK_SIZE,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, RoF2::invtype::BANK_SIZE, RoF2::invtype::SHARED_BANK_SIZE,
RoF2::invtype::TRADE_SIZE, RoF2::invtype::WORLD_SIZE, RoF2::invtype::LIMBO_SIZE,
RoF2::invtype::TRIBUTE_SIZE, RoF2::invtype::TROPHY_TRIBUTE_SIZE, RoF2::invtype::GUILD_TRIBUTE_SIZE,
RoF2::invtype::MERCHANT_SIZE, RoF2::invtype::DELETED_SIZE, RoF2::invtype::CORPSE_SIZE,
@@ -379,9 +371,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF2::inventory::AllowOverLevelEquipment
),
/*[MobVersion::NPC] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EntityLimits::NPC::invtype::TRADE_SIZE, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, /*InvTypeCorpseSize,*/
@@ -397,8 +389,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL,
EntityLimits::NPC::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -406,9 +398,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::NPCMerchant] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::invtype::TRADE_SIZE, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, /*InvTypeCorpseSize,*/
@@ -424,8 +416,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL,
EntityLimits::NPCMerchant::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -433,9 +425,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::Merc] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EntityLimits::Merc::invtype::TRADE_SIZE, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, /*InvTypeCorpseSize,*/
@@ -451,8 +443,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL,
EntityLimits::Merc::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -460,9 +452,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::Bot] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EntityLimits::Bot::invtype::TRADE_SIZE, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, /*InvTypeCorpseSize,*/
@@ -478,8 +470,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::Bot::invslot::CURSOR_BITMASK,
EntityLimits::Bot::invslot::POSSESSIONS_BITMASK,
EntityLimits::Bot::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
EQ::invaug::SOCKET_COUNT, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
EQEmu::invaug::SOCKET_COUNT, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -487,9 +479,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::ClientPet] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::invtype::TRADE_SIZE, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, /*InvTypeCorpseSize,*/
@@ -505,8 +497,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL,
EntityLimits::ClientPet::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -514,9 +506,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::NPCPet] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::invtype::TRADE_SIZE, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, /*InvTypeCorpseSize,*/
@@ -532,8 +524,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL,
EntityLimits::NPCPet::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -541,9 +533,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::MercPet] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EntityLimits::MercPet::invtype::TRADE_SIZE, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, /*InvTypeCorpseSize,*/
@@ -559,8 +551,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL,
EntityLimits::MercPet::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -568,9 +560,9 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::BotPet] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::invtype::POSSESSIONS_SIZE, /*InvTypePossessionsSize,*/ EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EntityLimits::BotPet::invtype::TRADE_SIZE, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, /*InvTypeCorpseSize,*/
@@ -586,8 +578,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL,
EntityLimits::BotPet::INULL,
0, //EQ::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQ::inventory::SocketCount, /*ItemAugSize,*/
0, //EQEmu::inventory::ContainerCount, /*ItemBagSize,*/
0, //EQEmu::inventory::SocketCount, /*ItemAugSize,*/
false,
false,
@@ -595,8 +587,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::OfflineTitanium] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
Titanium::INULL, Titanium::INULL, Titanium::INULL,
Titanium::invtype::TRADE_SIZE, Titanium::INULL, Titanium::INULL,
Titanium::INULL, Titanium::INULL, Titanium::INULL,
@@ -622,8 +614,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::OfflineSoF] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
SoF::INULL, SoF::INULL, SoF::INULL,
SoF::invtype::TRADE_SIZE, SoF::INULL, SoF::INULL,
SoF::INULL, SoF::INULL, SoF::INULL,
@@ -649,8 +641,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::OfflineSoD] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
SoD::INULL, SoD::INULL, SoD::INULL,
SoD::invtype::TRADE_SIZE, SoD::INULL, SoD::INULL,
SoD::INULL, SoD::INULL, SoD::INULL,
@@ -676,8 +668,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::OfflineUF] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
UF::INULL, UF::INULL, UF::INULL,
UF::invtype::TRADE_SIZE, UF::INULL, UF::INULL,
UF::INULL, UF::INULL, UF::INULL,
@@ -703,8 +695,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::OfflineRoF] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
RoF::INULL, RoF::INULL, RoF::INULL,
RoF::invtype::TRADE_SIZE, RoF::INULL, RoF::INULL,
RoF::INULL, RoF::INULL, RoF::INULL,
@@ -730,8 +722,8 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
false
),
/*[MobVersion::OfflineRoF2] =*/
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQEmu::inventory::LookupEntry(
EQEmu::inventory::LookupEntry::InventoryTypeSize_Struct(
RoF2::INULL, RoF2::INULL, RoF2::INULL,
RoF2::invtype::TRADE_SIZE, RoF2::INULL, RoF2::INULL,
RoF2::INULL, RoF2::INULL, RoF2::INULL,
@@ -759,7 +751,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
};
static bool inventory_dictionary_init = false;
void EQ::inventory::InitializeDynamicLookups() {
void EQEmu::inventory::InitializeDynamicLookups() {
if (inventory_dictionary_init == true)
return;
inventory_dictionary_init = true;
@@ -771,7 +763,7 @@ void EQ::inventory::InitializeDynamicLookups() {
// Notes:
// - Currently, there are only 3 known expansions that affect inventory-related settings in the clients..
// -- Expansion::PoR "Prophecy of Ro" - toggles between 24 (set) and 16 (clear) bank slots
// -- Expansion::TBS "The Buried Sea" - toggles slotPowerSource activated (set) and deactivated (clear)
// -- Expansion::TBS "The Buried Sea" - toggles slotPowerSource activated (set) and deactivated (clear)
// -- Expansion::HoT "House of Thule" - toggles slotGeneral9/slotGeneral10 activated (set) and deactivated (clear)
// - Corspe size does not appear to reflect loss of active possessions slots
// - Inspect size does not appear to reflect loss of active equipment slots
@@ -780,11 +772,11 @@ void EQ::inventory::InitializeDynamicLookups() {
// - General9 and General10 slots are activated by GM flag when expansion bit is (clear)
// - Obviously, the client must support the expansion to allow any (set) or override condition
const uint32 dynamic_check_mask =
const uint32 dynamic_check_mask =
(
EQ::expansions::bitPoR |
EQ::expansions::bitTBS |
EQ::expansions::bitHoT
EQEmu::expansions::bitPoR |
EQEmu::expansions::bitTBS |
EQEmu::expansions::bitHoT
);
// if all of the above expansion bits are present, then static references will suffice
@@ -792,7 +784,7 @@ void EQ::inventory::InitializeDynamicLookups() {
return;
// Dynamic Lookups (promotive methodology) (all mob versions allowed)
for (uint32 iter = static_cast<uint32>(EQ::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQ::versions::LastPCMobVersion); ++iter) {
for (uint32 iter = static_cast<uint32>(EQEmu::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQEmu::versions::LastPCMobVersion); ++iter) {
// no need to dynamic this condition since it is the lowest compatibility standard
if ((dynamic_check_mask & ~constants_static_lookup_entries[iter].ExpansionsMask) == dynamic_check_mask)
continue;
@@ -802,7 +794,7 @@ void EQ::inventory::InitializeDynamicLookups() {
continue;
// direct manipulation of lookup indices is safe so long as (int)ClientVersion::<mob> == (int)MobVersion::<mob>
inventory_dynamic_nongm_lookup_entries[iter] = std::make_unique<LookupEntry>(inventory_static_lookup_entries[iter]);
inventory_dynamic_nongm_lookup_entries[iter] = std::unique_ptr<LookupEntry>(new LookupEntry(inventory_static_lookup_entries[iter]));
// clamp affected fields to the lowest standard
inventory_dynamic_nongm_lookup_entries[iter]->InventoryTypeSize.Bank = Titanium::invtype::BANK_SIZE; // bank size
@@ -811,21 +803,21 @@ void EQ::inventory::InitializeDynamicLookups() {
inventory_dynamic_nongm_lookup_entries[iter]->PossessionsBitmask = 0; // we'll fix later
inventory_dynamic_nongm_lookup_entries[iter]->CorpseBitmask = 0; // we'll fix later
if (RuleI(World, ExpansionSettings) & EQ::expansions::bitPoR) {
if (RuleI(World, ExpansionSettings) & EQEmu::expansions::bitPoR) {
// update bank size
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitPoR)
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitPoR)
inventory_dynamic_nongm_lookup_entries[iter]->InventoryTypeSize.Bank = SoF::invtype::BANK_SIZE;
}
if (RuleI(World, ExpansionSettings) & EQ::expansions::bitTBS) {
if (RuleI(World, ExpansionSettings) & EQEmu::expansions::bitTBS) {
// update power source
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitTBS)
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitTBS)
inventory_dynamic_nongm_lookup_entries[iter]->EquipmentBitmask = SoF::invslot::EQUIPMENT_BITMASK;
}
if (RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT) {
if (RuleI(World, ExpansionSettings) & EQEmu::expansions::bitHoT) {
// update general size
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitHoT)
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitHoT)
inventory_dynamic_nongm_lookup_entries[iter]->GeneralBitmask = RoF::invslot::GENERAL_BITMASK;
}
@@ -849,7 +841,7 @@ void EQ::inventory::InitializeDynamicLookups() {
}
// Dynamic GM Lookups (demotive methodology) (client-linked mob versions only)
for (uint32 iter = static_cast<uint32>(EQ::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQ::versions::LastPCMobVersion); ++iter) {
for (uint32 iter = static_cast<uint32>(EQEmu::versions::MobVersion::Unknown); iter <= static_cast<uint32>(EQEmu::versions::LastPCMobVersion); ++iter) {
// no need to dynamic this condition since it is the lowest compatibility standard
if ((dynamic_check_mask & ~constants_static_lookup_entries[iter].ExpansionsMask) == dynamic_check_mask)
continue;
@@ -872,18 +864,18 @@ void EQ::inventory::InitializeDynamicLookups() {
}
// direct manipulation of lookup indices is safe so long as (int)ClientVersion::<client> == (int)MobVersion::<client>
inventory_dynamic_gm_lookup_entries[iter] = std::make_unique<LookupEntry>(inventory_static_lookup_entries[iter]);
inventory_dynamic_gm_lookup_entries[iter] = std::unique_ptr<LookupEntry>(new LookupEntry(inventory_static_lookup_entries[iter]));
inventory_dynamic_gm_lookup_entries[iter]->PossessionsBitmask = 0; // we'll fix later
inventory_dynamic_gm_lookup_entries[iter]->CorpseBitmask = 0; // we'll fix later
if (~RuleI(World, ExpansionSettings) & EQ::expansions::bitPoR) {
if (~RuleI(World, ExpansionSettings) & EQEmu::expansions::bitPoR) {
// update bank size
if (constants_static_lookup_entries[iter].ExpansionsMask & EQ::expansions::bitPoR)
if (constants_static_lookup_entries[iter].ExpansionsMask & EQEmu::expansions::bitPoR)
inventory_dynamic_gm_lookup_entries[iter]->InventoryTypeSize.Bank = Titanium::invtype::BANK_SIZE;
}
if (~RuleI(World, ExpansionSettings) & EQ::expansions::bitTBS) {
if (~RuleI(World, ExpansionSettings) & EQEmu::expansions::bitTBS) {
// update power source
switch (iter) {
case versions::bitUF:
@@ -898,7 +890,7 @@ void EQ::inventory::InitializeDynamicLookups() {
}
}
if (~RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT) {
if (~RuleI(World, ExpansionSettings) & EQEmu::expansions::bitHoT) {
// update general size
switch (iter) {
case versions::bitUF:
@@ -935,7 +927,7 @@ void EQ::inventory::InitializeDynamicLookups() {
// only client versions that require a change from their static definitions have been given a dynamic (gm) lookup entry
}
const EQ::inventory::LookupEntry* EQ::inventory::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
const EQEmu::inventory::LookupEntry* EQEmu::inventory::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
{
if (gm_flag)
return DynamicGMLookup(mob_version);
@@ -943,7 +935,7 @@ const EQ::inventory::LookupEntry* EQ::inventory::DynamicLookup(versions::MobVers
return DynamicNonGMLookup(mob_version);
}
const EQ::inventory::LookupEntry* EQ::inventory::DynamicNonGMLookup(versions::MobVersion mob_version)
const EQEmu::inventory::LookupEntry* EQEmu::inventory::DynamicNonGMLookup(versions::MobVersion mob_version)
{
mob_version = versions::ValidateMobVersion(mob_version);
if (inventory_dynamic_nongm_lookup_entries[static_cast<int>(mob_version)])
@@ -952,7 +944,7 @@ const EQ::inventory::LookupEntry* EQ::inventory::DynamicNonGMLookup(versions::Mo
return &inventory_static_lookup_entries[static_cast<int>(mob_version)];
}
const EQ::inventory::LookupEntry* EQ::inventory::DynamicGMLookup(versions::MobVersion mob_version)
const EQEmu::inventory::LookupEntry* EQEmu::inventory::DynamicGMLookup(versions::MobVersion mob_version)
{
mob_version = versions::ValidateMobVersion(mob_version);
if (inventory_dynamic_gm_lookup_entries[static_cast<int>(mob_version)])
@@ -961,107 +953,107 @@ const EQ::inventory::LookupEntry* EQ::inventory::DynamicGMLookup(versions::MobVe
return &inventory_static_lookup_entries[static_cast<int>(mob_version)];
}
const EQ::inventory::LookupEntry* EQ::inventory::StaticLookup(versions::MobVersion mob_version)
const EQEmu::inventory::LookupEntry* EQEmu::inventory::StaticLookup(versions::MobVersion mob_version)
{
return &inventory_static_lookup_entries[static_cast<int>(versions::ValidateMobVersion(mob_version))];
}
static std::unique_ptr<EQ::behavior::LookupEntry> behavior_dynamic_nongm_lookup_entries[EQ::versions::MobVersionCount];
static std::unique_ptr<EQ::behavior::LookupEntry> behavior_dynamic_gm_lookup_entries[EQ::versions::MobVersionCount];
static const EQ::behavior::LookupEntry behavior_static_lookup_entries[EQ::versions::MobVersionCount] =
static std::unique_ptr<EQEmu::behavior::LookupEntry> behavior_dynamic_nongm_lookup_entries[EQEmu::versions::MobVersionCount];
static std::unique_ptr<EQEmu::behavior::LookupEntry> behavior_dynamic_gm_lookup_entries[EQEmu::versions::MobVersionCount];
static const EQEmu::behavior::LookupEntry behavior_static_lookup_entries[EQEmu::versions::MobVersionCount] =
{
/*[MobVersion::Unknown] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
true
),
/*[MobVersion::Client62] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
true
),
/*[MobVersion::Titanium] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
Titanium::behavior::CoinHasWeight
),
/*[MobVersion::SoF] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
SoF::behavior::CoinHasWeight
),
/*[MobVersion::SoD] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
SoD::behavior::CoinHasWeight
),
/*[MobVersion::UF] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
UF::behavior::CoinHasWeight
),
/*[MobVersion::RoF] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
RoF::behavior::CoinHasWeight
),
/*[MobVersion::RoF2] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
RoF2::behavior::CoinHasWeight
),
/*[MobVersion::NPC] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::NPCMerchant] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::Merc] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::Bot] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::ClientPet] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::NPCPet] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::MercPet] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::BotPet] =*/
EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight
EQEmu::behavior::LookupEntry(
EQEmu::behavior::CoinHasWeight
),
/*[MobVersion::OfflineTitanium] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
Titanium::behavior::CoinHasWeight
),
/*[MobVersion::OfflineSoF] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
SoF::behavior::CoinHasWeight
),
/*[MobVersion::OfflineSoD] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
SoD::behavior::CoinHasWeight
),
/*[MobVersion::OfflineUF] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
UF::behavior::CoinHasWeight
),
/*[MobVersion::OfflineRoF] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
RoF::behavior::CoinHasWeight
),
/*[MobVersion::OfflineRoF2] =*/
EQ::behavior::LookupEntry(
EQEmu::behavior::LookupEntry(
RoF2::behavior::CoinHasWeight
)
};
static bool behavior_dictionary_init = false;
void EQ::behavior::InitializeDynamicLookups() {
void EQEmu::behavior::InitializeDynamicLookups() {
if (behavior_dictionary_init == true)
return;
behavior_dictionary_init = true;
@@ -1072,7 +1064,7 @@ void EQ::behavior::InitializeDynamicLookups() {
// use static references for now
}
const EQ::behavior::LookupEntry* EQ::behavior::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
const EQEmu::behavior::LookupEntry* EQEmu::behavior::DynamicLookup(versions::MobVersion mob_version, bool gm_flag)
{
if (gm_flag)
return DynamicGMLookup(mob_version);
@@ -1080,7 +1072,7 @@ const EQ::behavior::LookupEntry* EQ::behavior::DynamicLookup(versions::MobVersio
return DynamicNonGMLookup(mob_version);
}
const EQ::behavior::LookupEntry* EQ::behavior::DynamicNonGMLookup(versions::MobVersion mob_version)
const EQEmu::behavior::LookupEntry* EQEmu::behavior::DynamicNonGMLookup(versions::MobVersion mob_version)
{
mob_version = versions::ValidateMobVersion(mob_version);
if (behavior_dynamic_nongm_lookup_entries[static_cast<int>(mob_version)])
@@ -1089,7 +1081,7 @@ const EQ::behavior::LookupEntry* EQ::behavior::DynamicNonGMLookup(versions::MobV
return &behavior_static_lookup_entries[static_cast<int>(mob_version)];
}
const EQ::behavior::LookupEntry* EQ::behavior::DynamicGMLookup(versions::MobVersion mob_version)
const EQEmu::behavior::LookupEntry* EQEmu::behavior::DynamicGMLookup(versions::MobVersion mob_version)
{
mob_version = versions::ValidateMobVersion(mob_version);
if (behavior_dynamic_gm_lookup_entries[static_cast<int>(mob_version)])
@@ -1098,17 +1090,17 @@ const EQ::behavior::LookupEntry* EQ::behavior::DynamicGMLookup(versions::MobVers
return &behavior_static_lookup_entries[static_cast<int>(mob_version)];
}
const EQ::behavior::LookupEntry* EQ::behavior::StaticLookup(versions::MobVersion mob_version)
const EQEmu::behavior::LookupEntry* EQEmu::behavior::StaticLookup(versions::MobVersion mob_version)
{
return &behavior_static_lookup_entries[static_cast<int>(versions::ValidateMobVersion(mob_version))];
}
static std::unique_ptr<EQ::spells::LookupEntry> spells_dynamic_nongm_lookup_entries[EQ::versions::ClientVersionCount];
static std::unique_ptr<EQ::spells::LookupEntry> spells_dynamic_gm_lookup_entries[EQ::versions::ClientVersionCount];
static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::ClientVersionCount] =
static std::unique_ptr<EQEmu::spells::LookupEntry> spells_dynamic_nongm_lookup_entries[EQEmu::versions::ClientVersionCount];
static std::unique_ptr<EQEmu::spells::LookupEntry> spells_dynamic_gm_lookup_entries[EQEmu::versions::ClientVersionCount];
static const EQEmu::spells::LookupEntry spells_static_lookup_entries[EQEmu::versions::ClientVersionCount] =
{
/*[ClientVersion::Unknown] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
ClientUnknown::INULL,
ClientUnknown::INULL,
ClientUnknown::INULL,
@@ -1121,7 +1113,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
ClientUnknown::INULL
),
/*[ClientVersion::Client62] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
Client62::INULL,
Client62::INULL,
Client62::INULL,
@@ -1134,7 +1126,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
Client62::INULL
),
/*[ClientVersion::Titanium] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
Titanium::spells::SPELL_ID_MAX,
Titanium::spells::SPELLBOOK_SIZE,
Titanium::spells::SPELL_GEM_COUNT,
@@ -1147,7 +1139,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
Titanium::spells::MERC_BUFFS
),
/*[ClientVersion::SoF] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
SoF::spells::SPELL_ID_MAX,
SoF::spells::SPELLBOOK_SIZE,
SoF::spells::SPELL_GEM_COUNT,
@@ -1160,7 +1152,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
SoF::spells::MERC_BUFFS
),
/*[ClientVersion::SoD] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
SoD::spells::SPELL_ID_MAX,
SoD::spells::SPELLBOOK_SIZE,
SoD::spells::SPELL_GEM_COUNT,
@@ -1173,7 +1165,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
SoD::spells::MERC_BUFFS
),
/*[ClientVersion::UF] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
UF::spells::SPELL_ID_MAX,
UF::spells::SPELLBOOK_SIZE,
UF::spells::SPELL_GEM_COUNT,
@@ -1186,7 +1178,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
UF::spells::MERC_BUFFS
),
/*[ClientVersion::RoF] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
RoF::spells::SPELL_ID_MAX,
RoF::spells::SPELLBOOK_SIZE,
UF::spells::SPELL_GEM_COUNT, // client translators are setup to allow the max value a client supports..however, the top 4 indices are not valid in this case
@@ -1199,7 +1191,7 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
RoF::spells::MERC_BUFFS
),
/*[ClientVersion::RoF2] =*/
EQ::spells::LookupEntry(
EQEmu::spells::LookupEntry(
RoF2::spells::SPELL_ID_MAX,
RoF2::spells::SPELLBOOK_SIZE,
UF::spells::SPELL_GEM_COUNT, // client translators are setup to allow the max value a client supports..however, the top 4 indices are not valid in this case
@@ -1214,18 +1206,18 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
};
static bool spells_dictionary_init = false;
void EQ::spells::InitializeDynamicLookups() {
void EQEmu::spells::InitializeDynamicLookups() {
if (spells_dictionary_init == true)
return;
spells_dictionary_init = true;
if (RuleB(World, UseClientBasedExpansionSettings))
return;
// use static references for now
}
const EQ::spells::LookupEntry* EQ::spells::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
const EQEmu::spells::LookupEntry* EQEmu::spells::DynamicLookup(versions::ClientVersion client_version, bool gm_flag)
{
if (gm_flag)
return DynamicGMLookup(client_version);
@@ -1233,7 +1225,7 @@ const EQ::spells::LookupEntry* EQ::spells::DynamicLookup(versions::ClientVersion
return DynamicNonGMLookup(client_version);
}
const EQ::spells::LookupEntry* EQ::spells::DynamicNonGMLookup(versions::ClientVersion client_version)
const EQEmu::spells::LookupEntry* EQEmu::spells::DynamicNonGMLookup(versions::ClientVersion client_version)
{
client_version = versions::ValidateClientVersion(client_version);
if (spells_dynamic_nongm_lookup_entries[static_cast<int>(client_version)])
@@ -1242,16 +1234,16 @@ const EQ::spells::LookupEntry* EQ::spells::DynamicNonGMLookup(versions::ClientVe
return &spells_static_lookup_entries[static_cast<int>(client_version)];
}
const EQ::spells::LookupEntry* EQ::spells::DynamicGMLookup(versions::ClientVersion client_version)
const EQEmu::spells::LookupEntry* EQEmu::spells::DynamicGMLookup(versions::ClientVersion client_version)
{
client_version = versions::ValidateClientVersion(client_version);
if (spells_dynamic_gm_lookup_entries[static_cast<int>(client_version)])
return spells_dynamic_gm_lookup_entries[static_cast<int>(client_version)].get();
return &spells_static_lookup_entries[static_cast<int>(client_version)];
}
const EQ::spells::LookupEntry* EQ::spells::StaticLookup(versions::ClientVersion client_version)
const EQEmu::spells::LookupEntry* EQEmu::spells::StaticLookup(versions::ClientVersion client_version)
{
return &spells_static_lookup_entries[static_cast<int>(versions::ValidateClientVersion(client_version))];
}
+13 -16
View File
@@ -31,34 +31,31 @@
#include "../common/patches/rof2_limits.h"
namespace EQ
namespace EQEmu
{
void InitializeDynamicLookups();
namespace constants {
struct LookupEntry {
EQ::expansions::Expansion Expansion;
EQEmu::expansions::Expansion Expansion;
uint32 ExpansionBit;
uint32 ExpansionsMask;
int16 CharacterCreationLimit;
size_t SayLinkBodySize;
uint32 BazaarTraderLimit;
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
EQ::expansions::Expansion Expansion,
EQEmu::expansions::Expansion Expansion,
uint32 ExpansionBit,
uint32 ExpansionsMask,
int16 CharacterCreationLimit,
size_t SayLinkBodySize,
uint32 BazaarTraderLimit
size_t SayLinkBodySize
) :
Expansion(Expansion),
ExpansionBit(ExpansionBit),
ExpansionsMask(ExpansionsMask),
CharacterCreationLimit(CharacterCreationLimit),
SayLinkBodySize(SayLinkBodySize),
BazaarTraderLimit(BazaarTraderLimit)
SayLinkBodySize(SayLinkBodySize)
{ }
};
@@ -114,7 +111,7 @@ namespace EQ
union {
InventoryTypeSize_Struct InventoryTypeSize;
int16 InventoryTypeSizeArray[25]; // should reflect EQ::invtype::TYPE_COUNT referenced in emu_constants.h
int16 InventoryTypeSizeArray[25]; // should reflect EQEmu::invtype::TYPE_COUNT referenced in emu_constants.h
};
uint64 EquipmentBitmask;
@@ -132,7 +129,7 @@ namespace EQ
LookupEntry(const LookupEntry *lookup_entry) { }
LookupEntry(
const InventoryTypeSize_Struct& InventoryTypeSize,
InventoryTypeSize_Struct InventoryTypeSize,
uint64 EquipmentBitmask,
uint64 GeneralBitmask,
uint64 CursorBitmask,
@@ -247,9 +244,9 @@ namespace ClientUnknown
const int16 INULL = 0;
namespace constants {
const EQ::expansions::Expansion EXPANSION = EQ::expansions::Expansion::EverQuest;
const uint32 EXPANSION_BIT = EQ::expansions::bitEverQuest;
const uint32 EXPANSIONS_MASK = EQ::expansions::maskEverQuest;
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::EverQuest;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitEverQuest;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskEverQuest;
} // namespace constants
@@ -261,9 +258,9 @@ namespace Client62
const int16 INULL = 0;
namespace constants {
const EQ::expansions::Expansion EXPANSION = EQ::expansions::Expansion::EverQuest;
const uint32 EXPANSION_BIT = EQ::expansions::bitEverQuest;
const uint32 EXPANSIONS_MASK = EQ::expansions::maskEverQuest;
const EQEmu::expansions::Expansion EXPANSION = EQEmu::expansions::Expansion::EverQuest;
const uint32 EXPANSION_BIT = EQEmu::expansions::bitEverQuest;
const uint32 EXPANSIONS_MASK = EQEmu::expansions::maskEverQuest;
} // namespace constants
+137 -93
View File
@@ -21,7 +21,6 @@
#include "eq_packet.h"
#include "misc.h"
#include "op_codes.h"
#include "platform.h"
#include <iomanip>
#include <iostream>
#include <sstream>
@@ -154,52 +153,6 @@ void EQApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
#endif
}
void EQRawApplicationPacket::build_raw_header_dump(char *buffer, uint16 seq) const
{
BasePacket::build_raw_header_dump(buffer, seq);
buffer += strlen(buffer);
#ifdef STATIC_OPCODE
buffer += sprintf(buffer, "[OpCode 0x%04x (0x%04x) Size=%u]\n", emu_opcode, opcode,size);
#else
buffer += sprintf(buffer, "[OpCode %s (0x%04x) Size=%u]\n", OpcodeManager::EmuToName(emu_opcode), opcode,size);
#endif
}
void EQRawApplicationPacket::DumpRawHeader(uint16 seq, FILE *to) const
{
char buff[196];
build_raw_header_dump(buff, seq);
fprintf(to, "%s", buff);
}
void EQRawApplicationPacket::build_header_dump(char *buffer) const
{
#ifdef STATIC_OPCODE
sprintf(buffer, "[OpCode 0x%04x (0x%04x) Size=%u]\n", emu_opcode, opcode,size);
#else
sprintf(buffer, "[OpCode %s (0x%04x) Size=%u]", OpcodeManager::EmuToName(emu_opcode), opcode,size);
#endif
}
void EQRawApplicationPacket::DumpRawHeaderNoTime(uint16 seq, FILE *to) const
{
if (src_ip) {
std::string sIP,dIP;;
sIP=long2ip(src_ip);
dIP=long2ip(dst_ip);
fprintf(to, "[%s:%d->%s:%d] ",sIP.c_str(),src_port,dIP.c_str(),dst_port);
}
if (seq != 0xffff)
fprintf(to, "[Seq=%u] ",seq);
#ifdef STATIC_OPCODE
fprintf(to, "[OpCode 0x%04x (0x%04x) Size=%u]\n", emu_opcode, opcode,size);
#else
fprintf(to, "[OpCode %s (0x%04x) Size=%lu]\n", OpcodeManager::EmuToName(emu_opcode), opcode,(unsigned long)size);
#endif
}
uint32 EQProtocolPacket::serialize(unsigned char *dest) const
{
if (opcode>0xff) {
@@ -236,6 +189,26 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
return size+OpCodeBytes;
}
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
: BasePacket(buf, len),
opcode(op)
{
uint32 offset;
opcode=ntohs(*(const uint16 *)buf);
offset=2;
if (len-offset) {
pBuffer= new unsigned char[len-offset];
memcpy(pBuffer,buf+offset,len-offset);
size=len-offset;
} else {
pBuffer=nullptr;
size=0;
}
OpMgr=&RawOpcodeManager;
}*/
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
{
bool result=false;
@@ -267,6 +240,74 @@ bool result=false;
}
/*
this is the code to do app-layer combining, instead of protocol layer.
this was taken out due to complex interactions with the opcode manager,
and will require a bit more thinking (likely moving into EQStream) to
get running again... but might be a good thing some day.
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
{
uint32 newsize=0, offset=0;
unsigned char *tmpbuffer=nullptr;
if (opcode!=OP_AppCombined) {
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
offset=0;
if (size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(size);
offset+=1;
} else {
tmpbuffer[offset++]=size;
}
offset+=serialize(tmpbuffer+offset);
} else {
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
tmpbuffer=new unsigned char [newsize];
memcpy(tmpbuffer,pBuffer,size);
offset=size;
}
if (rhs->size>254) {
tmpbuffer[offset++]=0xff;
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
offset+=1;
} else {
tmpbuffer[offset++]=rhs->size;
}
offset+=rhs->serialize(tmpbuffer+offset);
size=offset;
opcode=OP_AppCombined;
delete[] pBuffer;
pBuffer=tmpbuffer;
return true;
}
*/
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
{
bool valid=false;
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
valid=true;
} else {
uint16 comp_crc=CRC16(buffer,length-2,Key);
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
#ifdef EQN_DEBUG
if (packet_crc && comp_crc != packet_crc) {
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
}
#endif
valid = (!packet_crc || comp_crc == packet_crc);
}
return valid;
}
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
{
uint32 newlen=0;
@@ -315,56 +356,59 @@ uint32 flag_offset=1,newlength;
return newlength;
}
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
{
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=DecodeKey;
unsigned char *test=(unsigned char *)malloc(size);
buffer+=2;
size-=2;
int i;
for (i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = (*(int*)&buffer[i]);
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
{
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
int Key=EncodeKey;
char *test=(char*)malloc(size);
int i;
buffer+=2;
size-=2;
for ( i = 0 ; i+4 <= size ; i+=4)
{
int pt = (*(int*)&buffer[i])^(Key);
Key = pt;
*(int*)&test[i]=pt;
}
unsigned char KC=Key&0xFF;
for ( ; i < size ; i++)
{
test[i]=buffer[i]^KC;
}
memcpy(buffer,test,size);
free(test);
}
}
EQApplicationPacket *EQApplicationPacket::Copy() const {
return(new EQApplicationPacket(*this));
}
EQRawApplicationPacket *EQProtocolPacket::MakeAppPacket() const {
auto res = new EQRawApplicationPacket(opcode, pBuffer, size);
res->copyInfo(this);
return(res);
}
EQRawApplicationPacket::EQRawApplicationPacket(uint16 opcode, const unsigned char *buf, const uint32 len)
: EQApplicationPacket(OP_Unknown, buf, len),
opcode(opcode)
{
}
EQRawApplicationPacket::EQRawApplicationPacket(const unsigned char *buf, const uint32 len)
: EQApplicationPacket(OP_Unknown, buf+sizeof(uint16), len-sizeof(uint16))
{
if(GetExecutablePlatform() != ExePlatformUCS) {
opcode = *((const uint16 *) buf);
if(opcode == 0x0000)
{
if(len >= 3)
{
opcode = *((const uint16 *) (buf + 1));
const unsigned char *packet_start = (buf + 3);
const int32 packet_length = len - 3;
safe_delete_array(pBuffer);
if(packet_length >= 0)
{
size = packet_length;
pBuffer = new unsigned char[size];
memcpy(pBuffer, packet_start, size);
}
else
{
size = 0;
}
}
else
{
safe_delete_array(pBuffer);
size = 0;
}
}
} else {
opcode = *((const uint8 *) buf);
}
}
void DumpPacket(const EQApplicationPacket* app, bool iShowInfo) {
if (iShowInfo) {
std::cout << "Dumping Applayer: 0x" << std::hex << std::setfill('0') << std::setw(4) << app->GetOpcode() << std::dec;
+8 -28
View File
@@ -19,7 +19,6 @@
#define _EQPACKET_H
#include "base_packet.h"
#include "platform.h"
#include <iostream>
#ifdef STATIC_OPCODE
@@ -57,8 +56,6 @@ protected:
};
class EQRawApplicationPacket;
class EQProtocolPacket : public BasePacket {
friend class EQStream;
friend class EQStreamPair;
@@ -68,7 +65,6 @@ public:
bool combine(const EQProtocolPacket *rhs);
uint32 serialize (unsigned char *dest) const;
EQProtocolPacket *Copy() { return new EQProtocolPacket(opcode,pBuffer,size); }
EQRawApplicationPacket *MakeAppPacket() const;
bool acked;
uint32 sent_time;
@@ -80,8 +76,11 @@ public:
protected:
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
uint16 GetRawOpcode() const { return(opcode); }
@@ -95,15 +94,15 @@ class EQApplicationPacket : public EQPacket {
friend class EQStream;
public:
EQApplicationPacket() : EQPacket(OP_Unknown, nullptr, 0), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
{ app_opcode_size = 2; }
EQApplicationPacket(const EmuOpcode op) : EQPacket(op, nullptr, 0), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
{ app_opcode_size = 2; }
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op, nullptr, len), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
{ app_opcode_size = 2; }
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
{ app_opcode_size = 2; }
EQApplicationPacket(const EmuOpcode op, SerializeBuffer &buf) : EQPacket(op, buf), opcode_bypass(0)
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
{ app_opcode_size = 2; }
bool combine(const EQApplicationPacket *rhs);
uint32 serialize (uint16 opcode, unsigned char *dest) const;
uint32 Size() const { return size+app_opcode_size; }
@@ -131,25 +130,6 @@ private:
};
class EQRawApplicationPacket : public EQApplicationPacket {
friend class EQStream;
public:
EQRawApplicationPacket(uint16 opcode, const unsigned char *buf, const uint32 len);
uint16 GetRawOpcode() const { return(opcode); }
virtual void build_raw_header_dump(char *buffer, uint16 seq=0xffff) const;
virtual void build_header_dump(char *buffer) const;
virtual void DumpRawHeader(uint16 seq=0xffff, FILE *to = stdout) const;
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
protected:
//the actual raw EQ opcode
uint16 opcode;
EQRawApplicationPacket(const unsigned char *buf, const uint32 len);
};
extern void DumpPacket(const EQApplicationPacket* app, bool iShowInfo = false);
extern std::string DumpPacketToString(const EQApplicationPacket* app);
+373 -1493
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -23,7 +23,7 @@
#include "op_codes.h"
#include "crc16.h"
#include "platform.h"
#include "strings.h"
#include "string_util.h"
#include <string>
#include <iomanip>
@@ -406,7 +406,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
}
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) {
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L,
@@ -453,7 +453,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
(unsigned long)ntohl(ClientStats->packets_received), (unsigned long)ntohl(ClientStats->packets_sent), (unsigned long)ntohl(ClientStats->last_local_delta),
(unsigned long)ntohl(ClientStats->low_delta), (unsigned long)ntohl(ClientStats->average_delta),
(unsigned long)ntohl(ClientStats->high_delta), (unsigned long)ntohl(ClientStats->last_remote_delta));
AdjustRates(ntohl(ClientStats->average_delta));
if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) {
@@ -951,7 +951,7 @@ EQRawApplicationPacket *p=nullptr;
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
if (emu_op == OP_Unknown) {
// Log(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str());
}
}
p->SetOpcode(emu_op);
}
}
@@ -1359,11 +1359,11 @@ void EQStream::AdjustRates(uint32 average_delta)
DecayRate=DECAYBASE/average_delta;
if (BytesWritten > RateThreshold)
BytesWritten = RateThreshold + DecayRate;
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
RateThreshold, DecayRate, average_delta);
MRate.unlock();
} else {
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
Log(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L,
average_delta, AVERAGE_DELTA_MAX);
AverageDelta = AVERAGE_DELTA_MAX;
}
@@ -1374,7 +1374,7 @@ void EQStream::AdjustRates(uint32 average_delta)
BytesWritten = 0;
RateThreshold=RATEBASE/average_delta;
DecayRate=DECAYBASE/average_delta;
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
Log(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L,
RateThreshold, DecayRate, average_delta);
MRate.unlock();
}
+6 -11
View File
@@ -218,13 +218,13 @@ class EQStream : public EQStreamInterface {
void init(bool resetSession=true);
public:
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
streamactive = false; }
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
create_time = Timer::GetTimeSeconds(); }
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
void SetMaxLen(uint32 length) { MaxLen=length; }
@@ -243,11 +243,6 @@ class EQStream : public EQStreamInterface {
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
virtual OpcodeManager* GetOpcodeManager() const
{
return (*OpMgr);
};
void CheckTimeout(uint32 now, uint32 timeout=30);
bool HasOutgoingData();
void Process(const unsigned char *data, const uint32 length);
+2 -2
View File
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
}
}
void EQStreamIdentifier::RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
auto p = new Patch;
p->signature = sig;
p->name = name;
@@ -145,7 +145,7 @@ void EQStreamIdentifier::Process() {
}
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
m_streams.emplace_back(Record(eqs));
m_streams.push_back(Record(eqs));
eqs = nullptr;
}
+1 -1
View File
@@ -18,7 +18,7 @@ public:
~EQStreamIdentifier();
//registration interface.
void RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
//main processing interface
void Process();
+2 -3
View File
@@ -30,7 +30,7 @@ struct EQStreamManagerInterfaceOptions
//World seems to support both compression and xor zone supports one or the others.
//Enforce one or the other in the convienence construct
//Login I had trouble getting to recognize compression at all
//Login I had trouble getting to recognize compression at all
//but that might be because it was still a bit buggy when i was testing that.
if (compressed) {
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
@@ -100,8 +100,7 @@ public:
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
virtual EQStreamState GetState() = 0;
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
virtual OpcodeManager* GetOpcodeManager() const = 0;
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
virtual const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; }
virtual Stats GetStats() const = 0;
virtual void ResetStats() = 0;
virtual EQStreamManagerInterface* GetManager() const = 0;
+6 -7
View File
@@ -22,7 +22,7 @@ std::string EQStreamProxy::Describe() const {
return(m_structs->Describe());
}
const EQ::versions::ClientVersion EQStreamProxy::ClientVersion() const
const EQEmu::versions::ClientVersion EQStreamProxy::ClientVersion() const
{
return m_structs->ClientVersion();
}
@@ -38,8 +38,12 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
}
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
if (p == nullptr) {
if(p == nullptr)
return;
if (p->GetOpcode() != OP_SpecialMesg) {
Log(Logs::General, Logs::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();
@@ -108,8 +112,3 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
return false;
}
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
{
return (*m_opcodes);
}
+2 -4
View File
@@ -28,21 +28,19 @@ public:
virtual void RemoveData();
virtual bool CheckState(EQStreamState state);
virtual std::string Describe() const;
virtual const EQ::versions::ClientVersion ClientVersion() const;
virtual const EQEmu::versions::ClientVersion ClientVersion() const;
virtual EQStreamState GetState();
virtual void SetOpcodeManager(OpcodeManager **opm);
virtual Stats GetStats() const;
virtual void ResetStats();
virtual EQStreamManagerInterface* GetManager() const;
virtual OpcodeManager* GetOpcodeManager() const;
protected:
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
const StructStrategy *const m_structs; //we do not own this object.
//this is a pointer to a pointer to make it less likely that a packet will
//reference an invalid opcode manager when they are being reloaded.
OpcodeManager **const m_opcodes;
//we do not own this object.
OpcodeManager **const m_opcodes; //we do not own this object.
};
#endif /*EQSTREAMPROXY_H_*/
+3
View File
@@ -23,6 +23,9 @@
EQDB EQDB::s_EQDB;
EQDB::EQDB() {
}
unsigned int EQDB::field_count() {
return mysql_field_count(mysql_ref);
}
+1 -1
View File
@@ -27,7 +27,7 @@
//this is the main object exported to perl.
class EQDB {
EQDB() = default;
EQDB();
public:
static EQDB *Singleton() { return(&s_EQDB); }
+32 -163
View File
@@ -19,13 +19,9 @@
#include "../common/global_define.h"
#include "eqemu_config.h"
#include "misc_functions.h"
#include "strings.h"
#include "eqemu_logsys.h"
#include "json/json.hpp"
#include <iostream>
#include <sstream>
#include <filesystem>
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
EQEmuConfig *EQEmuConfig::_config = nullptr;
@@ -37,23 +33,17 @@ void EQEmuConfig::parse_config()
LongName = _root["server"]["world"].get("longname", "").asString();
WorldAddress = _root["server"]["world"].get("address", "").asString();
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString());
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
SharedKey = _root["server"]["world"].get("key", "").asString();
LoginCount = 0;
if (_root["server"]["world"]["loginserver"].isObject()) {
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString());
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
LoginLegacy = false;
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
// at least today, this is wrong a majority of the time
// remove this if eqemulator ever upgrades its loginserver
if (LoginHost.find("login.eqemulator.net") != std::string::npos) {
LoginLegacy = true;
}
}
else {
char str[32];
@@ -66,60 +56,44 @@ void EQEmuConfig::parse_config()
auto loginconfig = new LoginConfig;
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString());
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
loginconfig->LoginLegacy = false;
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
// at least today, this is wrong a majority of the time
// remove this if eqemulator ever upgrades its loginserver
if (loginconfig->LoginHost.find("login.eqemulator.net") != std::string::npos) {
loginconfig->LoginLegacy = true;
}
loginlist.Insert(loginconfig);
} while (LoginCount < 100);
}
//<locked> from xml converts to json as locked: "", so i default to "false".
//<locked> from xml converts to json as locked: "", so i default to "false".
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
auto_database_updates = false;
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
auto_database_updates = true;
}
WorldIP = _root["server"]["world"]["tcp"].get("ip", "127.0.0.1").asString();
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString());
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
TelnetEnabled = false;
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString());
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
WorldHTTPEnabled = false;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
WorldHTTPEnabled = true;
}
if (_root["server"].get("disable_config_checks", "false").asString() == "true") {
DisableConfigChecks = true;
}
CheckUcsConfigConversion();
m_ucs_host = _root["server"]["ucs"].get("host", "eqchat.eqemulator.net").asString();
m_ucs_port = Strings::ToUnsignedInt(_root["server"]["ucs"].get("port", "7778").asString());
/**
* UCS
*/
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
/**
* Database
@@ -127,35 +101,24 @@ void EQEmuConfig::parse_config()
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString());
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
/**
* Content Database
*/
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString());
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
/**
* QS
*/
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString());
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
QSHost = _root["server"]["queryserver"].get("host", "localhost").asString();
QSPort = Strings::ToUnsignedInt(_root["server"]["queryserver"].get("port", "9500").asString());
/**
* Zones
*/
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString());
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString());
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString());
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
/**
* Files
@@ -173,7 +136,6 @@ void EQEmuConfig::parse_config()
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
OpcodeDir = _root["server"]["directories"].get("opcodes", "./").asString();
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
@@ -186,10 +148,10 @@ void EQEmuConfig::parse_config()
/**
* Launcher
*/
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString());
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString());
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString());
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString());
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
#ifdef WIN32
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
#else
@@ -251,16 +213,16 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
return (WorldHTTPEnabled ? "true" : "false");
}
if (var_name == "ChatHost") {
return (m_ucs_host);
return (ChatHost);
}
if (var_name == "ChatPort") {
return (itoa(m_ucs_port));
return (itoa(ChatPort));
}
if (var_name == "MailHost") {
return (m_ucs_host);
return (MailHost);
}
if (var_name == "MailPort") {
return (itoa(m_ucs_port));
return (itoa(MailPort));
}
if (var_name == "DatabaseHost") {
return (DatabaseHost);
@@ -367,8 +329,10 @@ void EQEmuConfig::Dump() const
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
std::cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << std::endl;
std::cout << "UCSHost = " << m_ucs_host << std::endl;
std::cout << "UCSPort = " << m_ucs_port << std::endl;
std::cout << "ChatHost = " << ChatHost << std::endl;
std::cout << "ChatPort = " << ChatPort << std::endl;
std::cout << "MailHost = " << MailHost << std::endl;
std::cout << "MailPort = " << MailPort << std::endl;
std::cout << "DatabaseHost = " << DatabaseHost << std::endl;
std::cout << "DatabaseUsername = " << DatabaseUsername << std::endl;
std::cout << "DatabasePassword = " << DatabasePassword << std::endl;
@@ -395,98 +359,3 @@ void EQEmuConfig::Dump() const
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
}
const std::string &EQEmuConfig::GetUCSHost() const
{
return m_ucs_host;
}
uint16 EQEmuConfig::GetUCSPort() const
{
return m_ucs_port;
}
void EQEmuConfig::CheckUcsConfigConversion()
{
std::string chat_host = _root["server"]["chatserver"].get("host", "").asString();
uint32 chat_port = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "0").asString());
std::string mail_host = _root["server"]["mailserver"].get("host", "").asString();
uint32 mail_port = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "0").asString());
std::string ucs_host = _root["server"]["ucs"].get("host", "").asString();
// automatic ucs legacy configuration migration
// if old configuration values are set, let's backup the existing configuration
// and migrate to to use the new fields and write the new config
if ((!chat_host.empty() || !mail_host.empty()) && ucs_host.empty()) {
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
std::string config_file_path = std::filesystem::path{
path.GetServerPath() + "/eqemu_config.json"
}.string();
std::string config_file_bak_path = std::filesystem::path{
path.GetServerPath() + "/eqemu_config.ucs-migrate-json.bak"
}.string();
// copy eqemu_config.json to eqemu_config.json.bak
std::ifstream src(config_file_path, std::ios::binary);
std::ofstream dst(config_file_bak_path, std::ios::binary);
dst << src.rdbuf();
src.close();
LogInfo("Old configuration backed up to [{}]", config_file_bak_path);
// read eqemu_config.json, transplant new fields and write to eqemu_config.json
Json::Value root;
Json::Reader reader;
std::ifstream file(config_file_path);
if (!reader.parse(file, root)) {
LogError("Failed to parse configuration file");
return;
}
file.close();
// get old fields
std::string host = !chat_host.empty() ? chat_host : mail_host;
if (host.empty()) {
host = "eqchat.eqemulator.net";
}
std::string port = chat_port > 0 ? std::to_string(chat_port) : std::to_string(mail_port);
if (port.empty()) {
port = "7778";
}
// set new fields
root["server"]["ucs"]["host"] = host;
root["server"]["ucs"]["port"] = port;
// unset old fields
root["server"].removeMember("chatserver");
root["server"].removeMember("mailserver");
// get Json::Value raw string
std::string config = root.toStyledString();
// format using more modern json library
nlohmann::json data = nlohmann::json::parse(config);
// write to file
std::ofstream o(config_file_path);
o << std::setw(1) << data << std::endl;
o.close();
// write new config
LogInfo("New configuration written to [{}]", config_file_path);
LogInfo("Migration complete, please review the new configuration file");
// reload config internally
try {
std::ifstream fconfig(config_file_path, std::ifstream::binary);
fconfig >> _config->_root;
_config->parse_config();
}
catch (std::exception &) {
return;
}
}
}
+24 -40
View File
@@ -20,9 +20,7 @@
#include "json/json.h"
#include "linked_list.h"
#include "path_manager.h"
#include <fstream>
#include <fmt/format.h>
struct LoginConfig {
std::string LoginHost;
@@ -60,7 +58,14 @@ class EQEmuConfig
uint16 WorldHTTPPort;
std::string WorldHTTPMimeFile;
std::string SharedKey;
bool DisableConfigChecks;
// From <chatserver/>
std::string ChatHost;
uint16 ChatPort;
// From <mailserver/>
std::string MailHost;
uint16 MailPort;
// From <database/>
std::string DatabaseHost;
@@ -69,21 +74,12 @@ class EQEmuConfig
std::string DatabaseDB;
uint16 DatabasePort;
// From <content_database/>
std::string ContentDbHost;
std::string ContentDbUsername;
std::string ContentDbPassword;
std::string ContentDbName;
uint16 ContentDbPort;
// From <qsdatabase> // QueryServ
std::string QSDatabaseHost;
std::string QSDatabaseUsername;
std::string QSDatabasePassword;
std::string QSDatabaseDB;
uint16 QSDatabasePort;
std::string QSHost;
int QSPort;
uint16 QSDatabasePort;
// From <files/>
std::string SpellsFile;
@@ -97,7 +93,6 @@ class EQEmuConfig
std::string PluginDir;
std::string LuaModuleDir;
std::string PatchDir;
std::string OpcodeDir;
std::string SharedMemDir;
std::string LogDir;
@@ -115,20 +110,12 @@ class EQEmuConfig
uint16 ZonePortHigh;
uint8 DefaultStatus;
bool auto_database_updates;
const std::string &GetUCSHost() const;
uint16 GetUCSPort() const;
// uint16 DynamicCount;
// map<string,uint16> StaticZones;
protected:
std::string m_ucs_host;
uint16 m_ucs_port;
static EQEmuConfig *_config;
Json::Value _root;
static std::string ConfigFile;
@@ -136,12 +123,12 @@ class EQEmuConfig
void parse_config();
EQEmuConfig()
{
{
}
virtual ~EQEmuConfig() {}
public:
virtual ~EQEmuConfig() {}
// Produce a const singleton
static const EQEmuConfig *get()
@@ -150,44 +137,41 @@ class EQEmuConfig
return (_config);
}
// Allow the use to set the conf file to be used.
static void SetConfigFile(std::string file)
{
EQEmuConfig::ConfigFile = file;
}
// Load the config
static bool LoadConfig(const std::string& path = "")
static bool LoadConfig()
{
if (_config != nullptr) {
return true;
}
_config = new EQEmuConfig;
return parseFile(path);
return parseFile();
}
// Load config file and parse data
static bool parseFile(const std::string& file_path = ".")
{
static bool parseFile() {
if (_config == nullptr) {
return LoadConfig(file_path);
return LoadConfig();
}
std::string file = fmt::format(
"{}/{}",
(file_path.empty() ? path.GetServerPath() : file_path),
EQEmuConfig::ConfigFile
);
std::ifstream fconfig(file, std::ifstream::binary);
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
try {
fconfig >> _config->_root;
_config->parse_config();
}
catch (std::exception &) {
catch (std::exception) {
return false;
}
}
return true;
}
void Dump() const;
void CheckUcsConfigConversion();
};
#endif
+1 -1
View File
@@ -18,7 +18,7 @@
#include "eqemu_exception.h"
namespace EQ
namespace EQEmu
{
Exception::Exception(const char* name, const std::string& description, const char* file, long line)
: line_(line),
+2 -2
View File
@@ -22,7 +22,7 @@
#include <sstream>
#include <exception>
namespace EQ
namespace EQEmu
{
//! EQEmu Exception Class
/*!
@@ -104,7 +104,7 @@ namespace EQ
} // EQEmu
#ifndef EQ_EXCEPT
#define EQ_EXCEPT(n, d) throw EQ::Exception(n, d, __FILE__, __LINE__)
#define EQ_EXCEPT(n, d) throw EQEmu::Exception(n, d, __FILE__, __LINE__)
#endif
#endif
+290 -550
View File
File diff suppressed because it is too large Load Diff
+135 -208
View File
@@ -23,9 +23,8 @@
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <functional>
#include <algorithm>
#ifdef _WIN32
#ifdef utf16_to_utf8
@@ -38,8 +37,9 @@
namespace Logs {
enum DebugLevel {
General = 1, // 1 - Low-Level general debugging, useful info on single line
Detail // 2 - Use this for very chatty logging you want to leave in but don't want on by default
General = 1, /* 1 - Low-Level general debugging, useful info on single line */
Moderate, /* 2 - Informational based, used in functions, when particular things load */
Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */
};
/**
@@ -53,7 +53,7 @@ namespace Logs {
AI,
Aggro,
Attack,
DeprecatedCS, // deprecated
PacketClientServer,
Combat,
Commands,
Crash,
@@ -64,36 +64,36 @@ namespace Logs {
Inventory,
Launcher,
Netcode,
Normal, // deprecated
Normal,
Object,
Pathing,
QSServer, // deprecated
QSServer,
Quests,
Rules,
Skills,
Spawns,
Spells,
Status, // deprecated
Status,
TCPConnection,
Tasks,
Tradeskills,
Trading,
Tribute,
UCSServer, // deprecated
WebInterfaceServer, // deprecated
WorldServer, // deprecated
ZoneServer, // deprecated
UCSServer,
WebInterfaceServer,
WorldServer,
ZoneServer,
MySQLError,
MySQLQuery,
Mercenaries,
QuestDebug,
DeprecatedSC, // deprecated
DeprecatedCSU, // deprecated
DeprecatedSCD, // deprecated
DeprecatedCSD, // deprecated
Loginserver, // deprecated
PacketServerClient,
PacketClientServerUnhandled,
PacketServerClientWithDump,
PacketClientServerWithDump,
Loginserver,
ClientLogin,
HeadlessClient, // deprecated
HeadlessClient,
HPUpdate,
FixZ,
Food,
@@ -103,65 +103,29 @@ namespace Logs {
MobAppearance,
Info,
Warning,
Critical, // deprecated
Emergency, // deprecated
Alert, // deprecated
Notice, // deprecated
Critical,
Emergency,
Alert,
Notice,
AIScanClose,
AIYellForHelp,
AICastBeneficialClose,
AoeCast,
EntityManagement,
Flee,
Aura,
HotReload,
Merchants,
ZonePoints,
Loot,
Expeditions,
DynamicZones,
Scheduler,
Cheat,
ClientList,
DiaWind,
HTTP,
Saylink,
ChecksumVerification,
CombatRecord,
Hate,
Discord,
Faction,
PacketServerClient,
PacketClientServer,
PacketServerToServer,
Bugs,
QuestErrors,
PlayerEvents,
DataBuckets,
Zoning,
EqTime,
Corpses,
XTargets,
EvolveItem,
PositionUpdate,
KSM,
BotSettings,
BotSpellChecks,
BotSpellTypeChecks,
NpcHandin,
MaxCategoryID /* Don't Remove this */
};
/**
* If you add to this, make sure you update LogCategory
*/
static const char *LogCategoryName[LogCategory::MaxCategoryID] = {
static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
"",
"AA",
"AI",
"Aggro",
"Attack",
"Deprecated",
"Packet :: Client -> Server",
"Combat",
"Commands",
"Crash",
@@ -172,112 +136,75 @@ namespace Logs {
"Inventory",
"Launcher",
"Netcode",
"Normal (Deprecated)",
"Normal",
"Object",
"Pathing",
"QS Server (Deprecated)",
"QS Server",
"Quests",
"Rules",
"Skills",
"Spawns",
"Spells",
"Status (Deprecated)",
"Status",
"TCP Connection",
"Tasks",
"Tradeskills",
"Trading",
"Tribute",
"UCS Server (Deprecated)",
"Web Interface (Deprecated)",
"World Server (Deprecated)",
"Zone Server (Deprecated)",
"QueryErr",
"Query",
"UCS Server",
"WebInterface Server",
"World Server",
"Zone Server",
"MySQL Error",
"MySQL Query",
"Mercenaries",
"Quest Debug",
"Legacy Packet Logging (Deprecated)",
"Legacy Packet Logging (Deprecated)",
"Legacy Packet Logging (Deprecated)",
"Legacy Packet Logging (Deprecated)",
"Login Server (Deprecated)",
"Packet :: Server -> Client",
"Packet :: Client -> Server Unhandled",
"Packet :: Server -> Client (Dump)",
"Packet :: Client -> Server (Dump)",
"Login Server",
"Client Login",
"Headless Client (Deprecated)",
"Headless Client",
"HP Update",
"FixZ",
"Food",
"Traps",
"NPC Roam Box",
"NPC Scaling",
"MobAppearance",
"Mob Appearance",
"Info",
"Warning",
"Critical (Deprecated)",
"Emergency (Deprecated)",
"Alert (Deprecated)",
"Notice (Deprecated)",
"AI Scan",
"AI Yell",
"AI CastBeneficial",
"Critical",
"Emergency",
"Alert",
"Notice",
"AI Scan Close",
"AI Yell For Help",
"AI Cast Beneficial Close",
"AOE Cast",
"Entity Management",
"Flee",
"Aura",
"HotReload",
"Merchants",
"ZonePoints",
"Loot",
"Expeditions",
"DynamicZones",
"Scheduler",
"Cheat",
"ClientList",
"DialogueWindow",
"HTTP",
"Saylink",
"ChecksumVer",
"CombatRecord",
"Hate",
"Discord",
"Faction",
"Packet S->C",
"Packet C->S",
"Packet S->S",
"Bugs",
"QuestErrors",
"PlayerEvents",
"DataBuckets",
"Zoning",
"EqTime",
"Corpses",
"XTargets",
"EvolveItem",
"PositionUpdate",
"KSM", // Kernel Samepage Merging
"Bot Settings",
"Bot Spell Checks",
"Bot Spell Type Checks",
"NpcHandin"
};
}
#include "eqemu_logsys_log_aliases.h"
class Database;
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
class EQEmuLogSys {
public:
EQEmuLogSys();
~EQEmuLogSys();
static EQEmuLogSys* Get() {
static EQEmuLogSys inst;
return &inst;
}
/**
* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else.
* This should be handled on deconstructor but to be safe we use it anyways.
*/
void CloseFileLogs();
EQEmuLogSys *LoadLogSettingsDefaults();
EQEmuLogSys *LoadLogDatabaseSettings();
void LoadLogSettingsDefaults(const std::string &platform);
/**
* @param directory_name
@@ -307,7 +234,7 @@ public:
* Used in file logs to prepend a timestamp entry for logs
* @param time_stamp
*/
void SetCurrentTimeStamp(char *time_stamp);
void SetCurrentTimeStamp(char* time_stamp);
/**
* @param log_name
@@ -328,112 +255,112 @@ public:
uint8 log_to_file;
uint8 log_to_console;
uint8 log_to_gmsay;
uint8 log_to_discord;
int discord_webhook_id;
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
};
struct OriginationInfo {
std::string zone_short_name;
std::string zone_long_name;
int instance_id;
};
OriginationInfo origination_info{};
/**
* Internally used memory reference for all log settings per category
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
* Database loaded via LogSys.SetDatabase(&database)->LoadLogDatabaseSettings();
* Database loaded via Database::LoadLogSettings(log_settings)
*/
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
// temporary bucket to re-load after silencing
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
bool file_logs_enabled = false;
struct LogEnabled {
bool log_to_file_enabled;
bool log_to_console_enabled;
bool log_to_gmsay_enabled;
bool log_to_discord_enabled;
bool log_enabled;
};
/**
* File name used in writing logs
*/
std::string platform_file_name;
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
struct DiscordWebhooks {
int id;
std::string webhook_name;
std::string webhook_url;
};
const DiscordWebhooks *GetDiscordWebhooks() const;
// gmsay
/**
* GMSay Client Message colors mapped by category
*
* @param log_category
* @return
*/
uint16 GetGMSayColorFromCategory(uint16 log_category);
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)>& f)
{
m_on_log_gmsay_hook = f;
return this;
}
/**
* @param f
*/
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)
{
m_on_log_discord_hook = f;
return this;
}
/**
* @param f
*/
void SetConsoleHandler(std::function<void(uint16 debug_level, uint16 log_type, const std::string&)> f) { on_log_console_hook = f; }
// console
void SetConsoleHandler(
std::function<void(
uint16 log_type,
const std::string &
)> f
) { m_on_log_console_hook = f; }
/**
* Silence console logging
*/
void SilenceConsoleLogging();
/**
* Turn on all console logging
*/
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:
EQEmuLogSys();
EQEmuLogSys(const EQEmuLogSys&);
EQEmuLogSys& operator=(const EQEmuLogSys&);
// reference to database
Database *m_database;
std::function<void(uint16 log_category, const char *func, const std::string &)> m_on_log_gmsay_hook;
std::function<void(uint16 log_category, int webhook_id, const std::string &)> m_on_log_discord_hook;
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
bool m_file_logs_enabled = false;
int m_log_platform = 0;
std::string m_platform_file_name;
std::string m_log_path;
/**
* Callback pointer to zone process for hooking logs to zone using GMSay
*/
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook;
std::function<void(uint16 debug_level, uint16 log_category, const std::string&)> on_log_console_hook;
void ProcessConsoleMessage(
uint16 log_category,
const std::string &message,
const char *file,
const char *func,
int line
);
void ProcessLogWrite(uint16 log_category, const std::string &message);
void InjectTablesIfNotExist();
/**
* Formats log messages like '[Category] This is a log message'
*/
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
/**
* Linux console color messages mapped by category
*
* @param log_category
* @return
*/
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
/**
* Windows console color messages mapped by category
*/
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
/**
* @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;
/**
template<typename... Args>
void OutF(
EQEmuLogSys &ls,
EQEmuLogSys *ls,
Logs::DebugLevel debug_level,
uint16 log_category,
const char *file,
@@ -450,7 +377,7 @@ void OutF(
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
do { \
ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
ls->Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
} while(0)
#endif
File diff suppressed because it is too large Load Diff
+12 -52
View File
@@ -46,16 +46,20 @@ EQTime::EQTime()
timezone = 0;
memset(&eqTime, 0, sizeof(eqTime));
//Defaults for time
TimeOfDay_Struct t{};
t.day = 1;
t.hour = 9;
t.minute = 0;
t.month = 1;
t.year = 3100;
TimeOfDay_Struct start;
start.day = 1;
start.hour = 9;
start.minute = 0;
start.month = 1;
start.year = 3100;
//Set default time zone
timezone = 0;
//Start EQTimer
SetCurrentEQTimeOfDay(t, time(nullptr));
SetCurrentEQTimeOfDay(start, time(0));
}
EQTime::~EQTime()
{
}
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
@@ -199,48 +203,4 @@ void EQTime::ToString(TimeOfDay_Struct *t, std::string &str) {
t->month, t->day, t->year, t->hour, t->minute);
buf[127] = '\0';
str = buf;
}
bool EQTime::IsDayTime() {
TimeOfDay_Struct tod{}; //Day time is 5am to 6:59pm (14 hours in-game)
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
if (tod.hour >= 5 || tod.hour < 19) {
return true;
}
return false;
}
bool EQTime::IsNightTime() {
TimeOfDay_Struct tod{}; //Night time is 7pm to 4:59am (10 hours in-game)
GetCurrentEQTimeOfDay(&tod); //TODO: what if it fails and returns zero?
if (tod.hour >= 19 || tod.hour < 5) {
return true;
}
return false;
}
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
View File
@@ -18,7 +18,7 @@ public:
//Constructor/destructor
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
EQTime();
~EQTime() = default;
~EQTime();
//Get functions
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
@@ -28,9 +28,6 @@ public:
uint32 getEQTimeZone() { return timezone; }
uint32 getEQTimeZoneHr() { return timezone/60; }
uint32 getEQTimeZoneMin() { return timezone%60; }
bool IsDayTime();
bool IsNightTime();
bool IsInbetweenTime(uint8 min_time, uint8 max_time);
//Set functions
int SetCurrentEQTimeOfDay(TimeOfDay_Struct start_eq, time_t start_real);
+59
View File
@@ -0,0 +1,59 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/* Error messages for mysql clients */
/* error messages for the demon is in share/language/errmsg.sys */
#ifdef __cplusplus
extern "C" {
#endif
void init_client_errs(void);
extern const char *client_errors[]; /* Error messages */
#ifdef __cplusplus
}
#endif
#define CR_MIN_ERROR 2000 /* For easier client code */
#define CR_MAX_ERROR 2999
#if defined(OS2) && defined( MYSQL_SERVER)
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
#else
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
#endif
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
#define CR_UNKNOWN_ERROR 2000
#define CR_SOCKET_CREATE_ERROR 2001
#define CR_CONNECTION_ERROR 2002
#define CR_CONN_HOST_ERROR 2003
#define CR_IPSOCK_ERROR 2004
#define CR_UNKNOWN_HOST 2005
#define CR_SERVER_GONE_ERROR 2006
#define CR_VERSION_ERROR 2007
#define CR_OUT_OF_MEMORY 2008
#define CR_WRONG_HOST_INFO 2009
#define CR_LOCALHOST_CONNECTION 2010
#define CR_TCP_CONNECTION 2011
#define CR_SERVER_HANDSHAKE_ERR 2012
#define CR_SERVER_LOST 2013
#define CR_COMMANDS_OUT_OF_SYNC 2014
#define CR_NAMEDPIPE_CONNECTION 2015
#define CR_NAMEDPIPEWAIT_ERROR 2016
#define CR_NAMEDPIPEOPEN_ERROR 2017
#define CR_NAMEDPIPESETSTATE_ERROR 2018
#define CR_CANT_READ_CHARSET 2019
#define CR_NET_PACKET_TOO_LARGE 2020

Some files were not shown because too many files have changed in this diff Show More