mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 20:33:01 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d6bdaa5c6e | |||
| 593127fb7e |
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
+1
-1
@@ -15,7 +15,7 @@ volumes:
|
||||
|
||||
steps:
|
||||
- name: Build Linux X64
|
||||
image: akkadius/eqemu-server:v14
|
||||
image: akkadius/eqemu-server:v11
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
|
||||
+3
-1
@@ -61,6 +61,9 @@ bin/
|
||||
compile_flags.txt
|
||||
.cache/
|
||||
|
||||
# vscode generated settings
|
||||
.vscode/
|
||||
|
||||
# Build pipeline
|
||||
!utils/scripts/build/
|
||||
!utils/scripts/build/should-release/should-release
|
||||
@@ -68,4 +71,3 @@ compile_flags.txt
|
||||
|
||||
# CMake Files
|
||||
cmake-build-relwithdebinfo/*
|
||||
skill-caps.diff
|
||||
|
||||
Vendored
-23
@@ -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
|
||||
}
|
||||
Vendored
-173
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
-136
@@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-3452
File diff suppressed because it is too large
Load Diff
+1
-45
@@ -16,31 +16,6 @@ SET(CMAKE_CXX_STANDARD 20)
|
||||
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)
|
||||
@@ -48,11 +23,7 @@ IF(MSVC)
|
||||
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)
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
ELSE(MSVC)
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
@@ -149,13 +120,6 @@ 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
|
||||
@@ -343,10 +307,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 *")
|
||||
@@ -411,10 +371,6 @@ IF(PERL_LIBRARY_ENABLED)
|
||||
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()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||
|
||||
add_subdirectory(import)
|
||||
add_subdirectory(export)
|
||||
|
||||
+154
-54
@@ -29,21 +29,11 @@
|
||||
#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;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ExportSpells(SharedDatabase *db);
|
||||
void ExportSkillCaps(SharedDatabase *db);
|
||||
@@ -104,22 +94,25 @@ int main(int argc, char **argv)
|
||||
->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")) {
|
||||
if (arg_1 == "spells") {
|
||||
ExportSpells(&content_db);
|
||||
return 0;
|
||||
} else if (Strings::EqualFold(export_type, "skills")) {
|
||||
}
|
||||
if (arg_1 == "skills") {
|
||||
ExportSkillCaps(&content_db);
|
||||
return 0;
|
||||
} else if (Strings::EqualFold(export_type, "basedata") || Strings::EqualFold(export_type, "base_data")) {
|
||||
}
|
||||
if (arg_1 == "basedata") {
|
||||
ExportBaseData(&content_db);
|
||||
return 0;
|
||||
} else if (Strings::EqualFold(export_type, "dbstr") || Strings::EqualFold(export_type, "dbstring")) {
|
||||
}
|
||||
if (arg_1 == "dbstring") {
|
||||
ExportDBStrings(&database);
|
||||
return 0;
|
||||
}
|
||||
@@ -134,79 +127,186 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExportSpells(SharedDatabase* db)
|
||||
void ExportSpells(SharedDatabase *db)
|
||||
{
|
||||
std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogInfo("Exporting Spells");
|
||||
|
||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||
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)
|
||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
||||
{
|
||||
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
|
||||
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] && Strings::ToInt(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 Strings::ToInt(row[0]);
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Skill Caps");
|
||||
|
||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
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()) {
|
||||
LogInfo("Exporting Base Data");
|
||||
|
||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||
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()) {
|
||||
LogInfo("Exporting DB Strings");
|
||||
|
||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,17 +27,11 @@
|
||||
#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;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ImportSpells(SharedDatabase *db);
|
||||
void ImportSkillCaps(SharedDatabase *db);
|
||||
@@ -261,45 +255,50 @@ 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);
|
||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "r");
|
||||
if(!f) {
|
||||
LogError("Unable to open {} to read, skipping.", file);
|
||||
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 = Strings::Split(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 = Strings::ToInt(split[0].c_str());
|
||||
class_id = Strings::ToInt(split[1].c_str());
|
||||
hp = Strings::ToFloat(split[2].c_str());
|
||||
mana = Strings::ToFloat(split[3].c_str());
|
||||
end = Strings::ToFloat(split[4].c_str());
|
||||
unk1 = Strings::ToFloat(split[5].c_str());
|
||||
unk2 = Strings::ToFloat(split[6].c_str());
|
||||
hp_fac = Strings::ToFloat(split[7].c_str());
|
||||
mana_fac = Strings::ToFloat(split[8].c_str());
|
||||
end_fac = Strings::ToFloat(split[9].c_str());
|
||||
|
||||
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) {
|
||||
|
||||
+23
-78
@@ -2,8 +2,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
|
||||
SET(common_sources
|
||||
base_packet.cpp
|
||||
bazaar.cpp
|
||||
bodytypes.cpp
|
||||
classes.cpp
|
||||
cli/eqemu_command_handler.cpp
|
||||
compression.cpp
|
||||
@@ -15,14 +13,11 @@ SET(common_sources
|
||||
crc32.cpp
|
||||
database/database_dump_service.cpp
|
||||
database.cpp
|
||||
database_conversions.cpp
|
||||
database_instances.cpp
|
||||
database/database_update_manifest.cpp
|
||||
database/database_update_manifest_bots.cpp
|
||||
database/database_update.cpp
|
||||
dbcore.cpp
|
||||
deity.cpp
|
||||
dynamic_zone_base.cpp
|
||||
dynamic_zone_lockout.cpp
|
||||
emu_constants.cpp
|
||||
emu_limits.cpp
|
||||
emu_opcodes.cpp
|
||||
@@ -40,7 +35,7 @@ SET(common_sources
|
||||
event_sub.cpp
|
||||
events/player_event_logs.cpp
|
||||
events/player_event_discord_formatter.cpp
|
||||
evolving_items.cpp
|
||||
expedition_lockout_timer.cpp
|
||||
extprofile.cpp
|
||||
discord/discord_manager.cpp
|
||||
faction.cpp
|
||||
@@ -63,7 +58,6 @@ SET(common_sources
|
||||
mutex.cpp
|
||||
mysql_request_result.cpp
|
||||
mysql_request_row.cpp
|
||||
mysql_stmt.cpp
|
||||
opcode_map.cpp
|
||||
opcodemgr.cpp
|
||||
packet_dump.cpp
|
||||
@@ -73,7 +67,6 @@ SET(common_sources
|
||||
perl_eqdb.cpp
|
||||
perl_eqdb_res.cpp
|
||||
process/process.cpp
|
||||
process.cpp
|
||||
proc_launcher.cpp
|
||||
profanity_manager.cpp
|
||||
ptimer.cpp
|
||||
@@ -87,19 +80,15 @@ SET(common_sources
|
||||
shared_tasks.cpp
|
||||
shareddb.cpp
|
||||
skills.cpp
|
||||
skill_caps.cpp
|
||||
spdat.cpp
|
||||
spdat_bot.cpp
|
||||
strings.cpp
|
||||
struct_strategy.cpp
|
||||
textures.cpp
|
||||
timer.cpp
|
||||
unix.cpp
|
||||
platform.cpp
|
||||
json/json.hpp
|
||||
json/jsoncpp.cpp
|
||||
zone_store.cpp
|
||||
memory/ksm.hpp
|
||||
net/console_server.cpp
|
||||
net/console_server_connection.cpp
|
||||
net/crc32.cpp
|
||||
@@ -162,7 +151,6 @@ SET(repositories
|
||||
repositories/base/base_bugs_repository.h
|
||||
repositories/base/base_bug_reports_repository.h
|
||||
repositories/base/base_buyer_repository.h
|
||||
repositories/base/base_buyer_trade_items_repository.h
|
||||
repositories/base/base_character_activities_repository.h
|
||||
repositories/base/base_character_alternate_abilities_repository.h
|
||||
repositories/base/base_character_alt_currency_repository.h
|
||||
@@ -175,7 +163,6 @@ SET(repositories
|
||||
repositories/base/base_character_currency_repository.h
|
||||
repositories/base/base_character_data_repository.h
|
||||
repositories/base/base_character_disciplines_repository.h
|
||||
repositories/base/base_character_evolving_items_repository.h
|
||||
repositories/base/base_character_expedition_lockouts_repository.h
|
||||
repositories/base/base_character_exp_modifiers_repository.h
|
||||
repositories/base/base_character_inspect_messages_repository.h
|
||||
@@ -185,8 +172,6 @@ SET(repositories
|
||||
repositories/base/base_character_leadership_abilities_repository.h
|
||||
repositories/base/base_character_material_repository.h
|
||||
repositories/base/base_character_memmed_spells_repository.h
|
||||
repositories/base/base_character_parcels_repository.h
|
||||
repositories/base/base_character_parcels_containers_repository.h
|
||||
repositories/base/base_character_peqzone_flags_repository.h
|
||||
repositories/base/base_character_pet_buffs_repository.h
|
||||
repositories/base/base_character_pet_info_repository.h
|
||||
@@ -213,9 +198,10 @@ SET(repositories
|
||||
repositories/base/base_discovered_items_repository.h
|
||||
repositories/base/base_doors_repository.h
|
||||
repositories/base/base_dynamic_zones_repository.h
|
||||
repositories/base/base_dynamic_zone_lockouts_repository.h
|
||||
repositories/base/base_dynamic_zone_members_repository.h
|
||||
repositories/base/base_dynamic_zone_templates_repository.h
|
||||
repositories/base/base_expeditions_repository.h
|
||||
repositories/base/base_expedition_lockouts_repository.h
|
||||
repositories/base/base_faction_association_repository.h
|
||||
repositories/base/base_faction_base_data_repository.h
|
||||
repositories/base/base_faction_list_repository.h
|
||||
@@ -232,9 +218,6 @@ SET(repositories
|
||||
repositories/base/base_group_leaders_repository.h
|
||||
repositories/base/base_guilds_repository.h
|
||||
repositories/base/base_guild_ranks_repository.h
|
||||
repositories/base/base_guild_permissions_repository.h
|
||||
repositories/base/base_guild_members_repository.h
|
||||
repositories/base/base_guild_bank_repository.h
|
||||
repositories/base/base_guild_relations_repository.h
|
||||
repositories/base/base_horses_repository.h
|
||||
repositories/base/base_instance_list_repository.h
|
||||
@@ -243,7 +226,7 @@ SET(repositories
|
||||
repositories/base/base_inventory_snapshots_repository.h
|
||||
repositories/base/base_ip_exemptions_repository.h
|
||||
repositories/base/base_items_repository.h
|
||||
repositories/base/base_items_evolving_details_repository.h
|
||||
repositories/base/base_item_tick_repository.h
|
||||
repositories/base/base_ldon_trap_entries_repository.h
|
||||
repositories/base/base_ldon_trap_templates_repository.h
|
||||
repositories/base/base_level_exp_mods_repository.h
|
||||
@@ -281,20 +264,8 @@ SET(repositories
|
||||
repositories/base/base_pets_equipmentset_repository.h
|
||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||
repositories/base/base_player_titlesets_repository.h
|
||||
repositories/base/base_player_event_aa_purchase_repository.h
|
||||
repositories/base/base_player_event_killed_npc_repository.h
|
||||
repositories/base/base_player_event_killed_named_npc_repository.h
|
||||
repositories/base/base_player_event_killed_raid_npc_repository.h
|
||||
repositories/base/base_player_event_log_settings_repository.h
|
||||
repositories/base/base_player_event_logs_repository.h
|
||||
repositories/base/base_player_event_loot_items_repository.h
|
||||
repositories/base/base_player_event_merchant_purchase_repository.h
|
||||
repositories/base/base_player_event_merchant_sell_repository.h
|
||||
repositories/base/base_player_event_npc_handin_repository.h
|
||||
repositories/base/base_player_event_npc_handin_entries_repository.h
|
||||
repositories/base/base_player_event_speech_repository.h
|
||||
repositories/base/base_player_event_trade_repository.h
|
||||
repositories/base/base_player_event_trade_entries_repository.h
|
||||
repositories/base/base_quest_globals_repository.h
|
||||
repositories/base/base_raid_details_repository.h
|
||||
repositories/base/base_raid_members_repository.h
|
||||
@@ -357,8 +328,7 @@ SET(repositories
|
||||
repositories/books_repository.h
|
||||
repositories/bugs_repository.h
|
||||
repositories/bug_reports_repository.h
|
||||
repositories/buyer_buy_lines_repository.h
|
||||
repositories/buyer_trade_items_repository.h
|
||||
repositories/buyer_repository.h
|
||||
repositories/character_activities_repository.h
|
||||
repositories/character_alternate_abilities_repository.h
|
||||
repositories/character_alt_currency_repository.h
|
||||
@@ -371,7 +341,6 @@ SET(repositories
|
||||
repositories/character_currency_repository.h
|
||||
repositories/character_data_repository.h
|
||||
repositories/character_disciplines_repository.h
|
||||
repositories/character_evolving_items_repository.h
|
||||
repositories/character_expedition_lockouts_repository.h
|
||||
repositories/character_exp_modifiers_repository.h
|
||||
repositories/character_inspect_messages_repository.h
|
||||
@@ -381,8 +350,6 @@ SET(repositories
|
||||
repositories/character_leadership_abilities_repository.h
|
||||
repositories/character_material_repository.h
|
||||
repositories/character_memmed_spells_repository.h
|
||||
repositories/character_parcels_repository.h
|
||||
repositories/character_parcels_containers_repository.h
|
||||
repositories/character_peqzone_flags_repository.h
|
||||
repositories/character_pet_buffs_repository.h
|
||||
repositories/character_pet_info_repository.h
|
||||
@@ -409,9 +376,10 @@ SET(repositories
|
||||
repositories/discovered_items_repository.h
|
||||
repositories/doors_repository.h
|
||||
repositories/dynamic_zones_repository.h
|
||||
repositories/dynamic_zone_lockouts_repository.h
|
||||
repositories/dynamic_zone_members_repository.h
|
||||
repositories/dynamic_zone_templates_repository.h
|
||||
repositories/expeditions_repository.h
|
||||
repositories/expedition_lockouts_repository.h
|
||||
repositories/faction_association_repository.h
|
||||
repositories/faction_base_data_repository.h
|
||||
repositories/faction_list_repository.h
|
||||
@@ -428,9 +396,6 @@ SET(repositories
|
||||
repositories/group_leaders_repository.h
|
||||
repositories/guilds_repository.h
|
||||
repositories/guild_ranks_repository.h
|
||||
repositories/guild_permissions_repository.h
|
||||
repositories/guild_members_repository.h
|
||||
repositories/guild_bank_repository.h
|
||||
repositories/guild_relations_repository.h
|
||||
repositories/horses_repository.h
|
||||
repositories/instance_list_repository.h
|
||||
@@ -439,7 +404,7 @@ SET(repositories
|
||||
repositories/inventory_snapshots_repository.h
|
||||
repositories/ip_exemptions_repository.h
|
||||
repositories/items_repository.h
|
||||
repositories/items_evolving_details_repository.h
|
||||
repositories/item_tick_repository.h
|
||||
repositories/ldon_trap_entries_repository.h
|
||||
repositories/ldon_trap_templates_repository.h
|
||||
repositories/level_exp_mods_repository.h
|
||||
@@ -477,20 +442,8 @@ SET(repositories
|
||||
repositories/pets_equipmentset_repository.h
|
||||
repositories/pets_equipmentset_entries_repository.h
|
||||
repositories/player_titlesets_repository.h
|
||||
repositories/player_event_aa_purchase_repository.h
|
||||
repositories/player_event_killed_npc_repository.h
|
||||
repositories/player_event_killed_named_npc_repository.h
|
||||
repositories/player_event_killed_raid_npc_repository.h
|
||||
repositories/player_event_log_settings_repository.h
|
||||
repositories/player_event_logs_repository.h
|
||||
repositories/player_event_loot_items_repository.h
|
||||
repositories/player_event_merchant_purchase_repository.h
|
||||
repositories/player_event_merchant_sell_repository.h
|
||||
repositories/player_event_npc_handin_repository.h
|
||||
repositories/player_event_npc_handin_entries_repository.h
|
||||
repositories/player_event_speech_repository.h
|
||||
repositories/player_event_trade_repository.h
|
||||
repositories/player_event_trade_entries_repository.h
|
||||
repositories/quest_globals_repository.h
|
||||
repositories/raid_details_repository.h
|
||||
repositories/raid_members_repository.h
|
||||
@@ -531,12 +484,12 @@ SET(repositories
|
||||
repositories/zone_repository.h
|
||||
repositories/zone_points_repository.h
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
SET(common_headers
|
||||
additive_lagged_fibonacci_engine.h
|
||||
bazaar.h
|
||||
base_packet.h
|
||||
base_data.h
|
||||
bodytypes.h
|
||||
classes.h
|
||||
compression.h
|
||||
@@ -553,13 +506,11 @@ SET(common_headers
|
||||
data_verification.h
|
||||
database.h
|
||||
database_schema.h
|
||||
database/database_update.h
|
||||
dbcore.h
|
||||
deity.h
|
||||
discord/discord.h
|
||||
discord/discord_manager.h
|
||||
dynamic_zone_base.h
|
||||
dynamic_zone_lockout.h
|
||||
emu_constants.h
|
||||
emu_limits.h
|
||||
emu_opcodes.h
|
||||
@@ -584,8 +535,9 @@ SET(common_headers
|
||||
events/player_event_logs.h
|
||||
events/player_event_discord_formatter.h
|
||||
events/player_events.h
|
||||
errmsg.h
|
||||
event_sub.h
|
||||
evolving_items.h
|
||||
expedition_lockout_timer.h
|
||||
extprofile.h
|
||||
faction.h
|
||||
file.h
|
||||
@@ -605,9 +557,10 @@ SET(common_headers
|
||||
item_fieldlist.h
|
||||
item_instance.h
|
||||
json_config.h
|
||||
languages.h
|
||||
light_source.h
|
||||
linked_list.h
|
||||
loot.h
|
||||
loottable.h
|
||||
mail_oplist.h
|
||||
md5.h
|
||||
memory_buffer.h
|
||||
@@ -617,7 +570,6 @@ SET(common_headers
|
||||
mutex.h
|
||||
mysql_request_result.h
|
||||
mysql_request_row.h
|
||||
mysql_stmt.h
|
||||
op_codes.h
|
||||
opcode_dispatch.h
|
||||
opcodemgr.h
|
||||
@@ -627,14 +579,12 @@ SET(common_headers
|
||||
path_manager.cpp
|
||||
platform.h
|
||||
process/process.h
|
||||
process.h
|
||||
proc_launcher.h
|
||||
profanity_manager.h
|
||||
profiler.h
|
||||
ptimer.h
|
||||
queue.h
|
||||
races.h
|
||||
raid.h
|
||||
random.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
@@ -645,11 +595,9 @@ SET(common_headers
|
||||
server_event_scheduler.h
|
||||
serverinfo.h
|
||||
servertalk.h
|
||||
server_reload_types.h
|
||||
shared_tasks.h
|
||||
shareddb.h
|
||||
skills.h
|
||||
skill_caps.h
|
||||
spdat.h
|
||||
strings.h
|
||||
struct_strategy.h
|
||||
@@ -660,6 +608,7 @@ SET(common_headers
|
||||
unix.h
|
||||
useperl.h
|
||||
version.h
|
||||
zone_numbers.h
|
||||
zone_store.h
|
||||
event/event_loop.h
|
||||
event/task.h
|
||||
@@ -718,20 +667,19 @@ SET(common_headers
|
||||
StackWalker/StackWalker.h
|
||||
util/memory_stream.h
|
||||
util/directory.h
|
||||
util/uuid.h
|
||||
)
|
||||
util/uuid.h)
|
||||
|
||||
SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
event/timer.h
|
||||
event/task.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Json FILES
|
||||
json/json.h
|
||||
json/jsoncpp.cpp
|
||||
json/json-forwards.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Net FILES
|
||||
net/console_server.cpp
|
||||
@@ -768,7 +716,7 @@ SOURCE_GROUP(Net FILES
|
||||
net/websocket_server.h
|
||||
net/websocket_server_connection.cpp
|
||||
net/websocket_server_connection.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patches FILES
|
||||
patches/patches.h
|
||||
@@ -812,12 +760,12 @@ SOURCE_GROUP(Patches FILES
|
||||
patches/titanium_limits.cpp
|
||||
patches/uf.cpp
|
||||
patches/uf_limits.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(StackWalker FILES
|
||||
StackWalker/StackWalker.h
|
||||
StackWalker/StackWalker.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Util FILES
|
||||
util/memory_stream.h
|
||||
@@ -825,7 +773,7 @@ SOURCE_GROUP(Util FILES
|
||||
util/directory.h
|
||||
util/uuid.cpp
|
||||
util/uuid.h
|
||||
)
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||
|
||||
@@ -836,8 +784,5 @@ IF (UNIX)
|
||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||
ENDIF (UNIX)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
+45
-91
@@ -18,96 +18,50 @@
|
||||
#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, //Velious era Raid Giant
|
||||
BT_RaidColdain = 10, //Velious era Raid Coldain
|
||||
BT_NoTarget = 11, //no name, can't target this bodytype
|
||||
BT_Vampire = 12,
|
||||
BT_Atenha_Ra = 13,
|
||||
BT_Greater_Akheva = 14,
|
||||
BT_Khati_Sha = 15,
|
||||
BT_Seru = 16,
|
||||
BT_Grieg_Veneficus = 17,
|
||||
BT_Draz_Nurakk = 18,
|
||||
BT_Zek = 19, //"creatures from the Plane of War."
|
||||
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,
|
||||
BT_Dragon2 = 29, //database data indicates this is a dragon type (kunark and DoN?)
|
||||
BT_VeliousDragon = 30, //might not be a tight set
|
||||
BT_Familiar = 31,
|
||||
BT_Dragon3 = 32,
|
||||
BT_Boxes = 33,
|
||||
BT_Muramite = 34, //tribal dudes
|
||||
// ...
|
||||
BT_NoTarget2 = 60,
|
||||
// ...
|
||||
BT_SwarmPet = 63, //Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
|
||||
BT_MonsterSummon = 64,
|
||||
// 65, trap or effect related?
|
||||
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
|
||||
BT_Special = 67
|
||||
} bodyType;
|
||||
/* bodytypes above 64 make the mob not show up */
|
||||
|
||||
#endif
|
||||
|
||||
+447
-348
File diff suppressed because it is too large
Load Diff
+93
-103
@@ -19,106 +19,98 @@
|
||||
#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 NO_CLASS 0
|
||||
#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 ADVENTURE_RECRUITER 60
|
||||
#define ADVENTURE_MERCHANT 61
|
||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
|
||||
#define TRIBUTE_MASTER 63
|
||||
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
||||
#define GUILD_BANKER 66
|
||||
#define NORRATHS_KEEPERS_MERCHANT 67
|
||||
#define DARK_REIGN_MERCHANT 68
|
||||
#define FELLOWSHIP_MASTER 69
|
||||
#define ALT_CURRENCY_MERCHANT 70
|
||||
#define MERCENARY_MASTER 71
|
||||
|
||||
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 +123,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 +140,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);
|
||||
|
||||
@@ -39,15 +39,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 ¶m: cmd.params())
|
||||
for (auto ¶m : cmd.params())
|
||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
||||
}
|
||||
}
|
||||
@@ -69,22 +69,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 || cmd[{"-h", "--help"}]) {
|
||||
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";
|
||||
}
|
||||
|
||||
@@ -124,6 +124,14 @@ namespace EQEmuCommand {
|
||||
)
|
||||
{
|
||||
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 <<
|
||||
@@ -134,7 +142,9 @@ namespace EQEmuCommand {
|
||||
<< 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,14 +155,18 @@ 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) {
|
||||
@@ -164,7 +178,9 @@ namespace EQEmuCommand {
|
||||
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());
|
||||
@@ -175,15 +191,6 @@ namespace EQEmuCommand {
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
bool ran_command = false;
|
||||
|
||||
for (auto &it: in_function_map) {
|
||||
if (it.first == argv[1]) {
|
||||
(it.second)(argc, argv, cmd, description);
|
||||
ran_command = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ran_command) {
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
#include "world_content_service.h"
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
#include <glm/vec3.hpp>
|
||||
#include "world_content_service.h"
|
||||
#include "../database.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
#include "../zone_store.h"
|
||||
#include "../loottable.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
|
||||
|
||||
WorldContentService::WorldContentService()
|
||||
@@ -103,7 +120,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
||||
/**
|
||||
* @param content_flags
|
||||
*/
|
||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags> &content_flags)
|
||||
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
|
||||
{
|
||||
WorldContentService::content_flags = content_flags;
|
||||
}
|
||||
@@ -151,14 +168,14 @@ bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
|
||||
}
|
||||
|
||||
// if we don't have any enabled flag in enabled flags, we fail
|
||||
for (const auto &flag: Strings::Split(f.content_flags)) {
|
||||
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)) {
|
||||
for (const auto& flag: Strings::Split(f.content_flags_disabled)) {
|
||||
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
|
||||
return false;
|
||||
}
|
||||
@@ -179,13 +196,11 @@ void WorldContentService::ReloadContentFlags()
|
||||
LogInfo(
|
||||
"Loaded content flag [{}] [{}]",
|
||||
f.flag_name,
|
||||
(f.enabled ? "enabled" : "disabled")
|
||||
(f.enabled ? "Enabled" : "Disabled")
|
||||
);
|
||||
}
|
||||
|
||||
SetContentFlags(set_content_flags);
|
||||
LoadStaticGlobalZoneInstances();
|
||||
zone_store.LoadZones(*m_content_database);
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetDatabase() const
|
||||
@@ -200,18 +215,6 @@ WorldContentService *WorldContentService::SetDatabase(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(
|
||||
@@ -236,114 +239,3 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
#define EQEMU_WORLD_CONTENT_SERVICE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../loottable.h"
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
#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;
|
||||
@@ -155,43 +167,23 @@ public:
|
||||
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 SetContentFlags(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;
|
||||
|
||||
+6
-5
@@ -15,7 +15,7 @@
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if WINDOWS
|
||||
#define popen _popen
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@ 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://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||
};
|
||||
|
||||
@@ -41,6 +41,9 @@ void SendCrashReport(const std::string &crash_report)
|
||||
r.set_connection_timeout(1, 0);
|
||||
r.set_read_timeout(1, 0);
|
||||
r.set_write_timeout(1, 0);
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// os info
|
||||
auto os = EQ::GetOS();
|
||||
@@ -122,7 +125,7 @@ public:
|
||||
StackWalker::OnOutput(szText);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& GetLines() { return _lines; }
|
||||
const std::vector<std::string>& const GetLines() { return _lines; }
|
||||
private:
|
||||
std::vector<std::string> _lines;
|
||||
};
|
||||
@@ -294,8 +297,6 @@ void print_trace()
|
||||
SendCrashReport(crash_report);
|
||||
}
|
||||
|
||||
LogSys.CloseFileLogs();
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
+1644
-1474
File diff suppressed because it is too large
Load Diff
+143
-153
@@ -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"
|
||||
@@ -38,7 +38,8 @@
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
namespace EQ {
|
||||
namespace EQ
|
||||
{
|
||||
class InventoryProfile;
|
||||
}
|
||||
|
||||
@@ -51,11 +52,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);
|
||||
}
|
||||
@@ -76,33 +76,37 @@ class PTimerList;
|
||||
|
||||
#define SQL(...) #__VA_ARGS__
|
||||
|
||||
class LogSettings;
|
||||
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, std::string connection_label = "default");
|
||||
~Database();
|
||||
|
||||
/* Character Creation */
|
||||
bool DeleteCharacter(const std::string& name);
|
||||
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
|
||||
|
||||
bool CreateCharacter(
|
||||
uint32 account_id,
|
||||
char *name,
|
||||
uint16 gender,
|
||||
uint16 race,
|
||||
uint16 class_,
|
||||
uint8 str,
|
||||
uint8 sta,
|
||||
uint8 cha,
|
||||
uint8 dex,
|
||||
uint8 int_,
|
||||
uint8 agi,
|
||||
uint8 wis,
|
||||
uint8 face
|
||||
);
|
||||
bool DeleteCharacter(char *character_name);
|
||||
bool MoveCharacterToZone(const char *charname, uint32 zone_id);
|
||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||
bool ReserveName(uint32 account_id, 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 ReserveName(uint32 account_id, char *name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||
bool UpdateName(const char *oldname, const char *newname);
|
||||
bool CopyCharacter(
|
||||
const std::string& source_character_name,
|
||||
const std::string& destination_character_name,
|
||||
@@ -110,179 +114,165 @@ public:
|
||||
);
|
||||
|
||||
/* 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(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(std::string name);
|
||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(std::string name, bool surname = false);
|
||||
bool CheckUsedName(std::string name);
|
||||
|
||||
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(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const char *name);
|
||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
std::string GetCharNameByID(uint32 char_id);
|
||||
std::string GetNPCNameByID(uint32 npc_id);
|
||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, std::string login_ip);
|
||||
|
||||
/* Instancing */
|
||||
|
||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_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 GetUnusedInstanceID(uint16 &instance_id);
|
||||
bool IsGlobalInstance(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 VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||
|
||||
uint16 GetInstanceID(uint32 zone, uint32 character_id, int16 version);
|
||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
||||
uint8_t GetInstanceVersion(uint16 instance_id);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool& is_perma);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
||||
uint32 GetInstanceZoneID(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 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_id, int16 version, uint32 charid, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
||||
void 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 = false, bool remove = false);
|
||||
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);
|
||||
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
|
||||
|
||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||
uint8 GetAgreementFlag(uint32 acctid);
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 acctid);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
||||
|
||||
int 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);
|
||||
|
||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
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 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 LoadPTimers(uint32 charid, PTimerList &into);
|
||||
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_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);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
|
||||
uint64_t GetNextTableId(const std::string& table_name);
|
||||
|
||||
private:
|
||||
Mutex Mvarcache;
|
||||
|
||||
Mutex Mvarcache;
|
||||
VarCache_Struct varcache;
|
||||
|
||||
/* Groups, utility methods. */
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
|
||||
/* Raid, utility methods. */
|
||||
void ClearAllRaids();
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "../database_schema.h"
|
||||
#include "../file.h"
|
||||
#include "../process/process.h"
|
||||
#include "../termcolor/rang.hpp"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
@@ -37,7 +36,6 @@
|
||||
#else
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <thread>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -93,8 +91,6 @@ std::string DatabaseDumpService::GetMySQLVersion()
|
||||
return Strings::Trim(version_output);
|
||||
}
|
||||
|
||||
const std::string CREDENTIALS_FILE = "login.my.cnf";
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
@@ -103,15 +99,21 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
||||
auto config = EQEmuConfig::get();
|
||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||
return fmt::format(
|
||||
"mysqldump --defaults-extra-file={} {}",
|
||||
CREDENTIALS_FILE,
|
||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||
config->ContentDbUsername,
|
||||
config->ContentDbPassword,
|
||||
config->ContentDbHost,
|
||||
config->ContentDbPort,
|
||||
config->ContentDbName
|
||||
);
|
||||
};
|
||||
|
||||
return fmt::format(
|
||||
"mysqldump --defaults-extra-file={} {}",
|
||||
CREDENTIALS_FILE,
|
||||
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||
config->DatabaseUsername,
|
||||
config->DatabasePassword,
|
||||
config->DatabaseHost,
|
||||
config->DatabasePort,
|
||||
config->DatabaseDB
|
||||
);
|
||||
}
|
||||
@@ -136,9 +138,14 @@ std::string DatabaseDumpService::GetLoginTableList()
|
||||
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetQueryServTables()
|
||||
{
|
||||
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
|
||||
}
|
||||
|
||||
std::string DatabaseDumpService::GetSystemTablesList()
|
||||
{
|
||||
auto system_tables = DatabaseSchema::GetServerTables();
|
||||
auto system_tables = DatabaseSchema::GetServerTables();
|
||||
auto version_tables = DatabaseSchema::GetVersionTables();
|
||||
|
||||
system_tables.insert(
|
||||
@@ -192,7 +199,7 @@ std::string DatabaseDumpService::GetDumpFileNameWithPath()
|
||||
return GetSetDumpPath() + GetDumpFileName();
|
||||
}
|
||||
|
||||
void DatabaseDumpService::DatabaseDump()
|
||||
void DatabaseDumpService::Dump()
|
||||
{
|
||||
if (!IsMySQLInstalled()) {
|
||||
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
||||
@@ -267,11 +274,11 @@ void DatabaseDumpService::DatabaseDump()
|
||||
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 (IsDumpQueryServerTables()) {
|
||||
tables_to_dump += GetQueryServTables();
|
||||
dump_descriptor += "-queryserv";
|
||||
}
|
||||
}
|
||||
|
||||
if (!dump_descriptor.empty()) {
|
||||
@@ -286,6 +293,14 @@ void DatabaseDumpService::DatabaseDump()
|
||||
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
||||
}
|
||||
|
||||
std::string execute_command = fmt::format(
|
||||
"{} {} {} {}",
|
||||
GetBaseMySQLDumpCommand(),
|
||||
options,
|
||||
tables_to_dump,
|
||||
pipe_file
|
||||
);
|
||||
|
||||
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||
File::Makedir(GetSetDumpPath());
|
||||
}
|
||||
@@ -293,66 +308,30 @@ void DatabaseDumpService::DatabaseDump()
|
||||
if (IsDumpDropTableSyntaxOnly()) {
|
||||
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
|
||||
|
||||
for (auto &table: tables) {
|
||||
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());
|
||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||
|
||||
if (IsTarAvailable()) {
|
||||
Process::execute(
|
||||
@@ -364,7 +343,6 @@ void DatabaseDumpService::DatabaseDump()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
||||
RemoveSqlBackup();
|
||||
}
|
||||
else if (Is7ZipAvailable()) {
|
||||
Process::execute(
|
||||
@@ -375,7 +353,6 @@ void DatabaseDumpService::DatabaseDump()
|
||||
)
|
||||
);
|
||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
||||
RemoveSqlBackup();
|
||||
}
|
||||
else {
|
||||
LogInfo("Compression requested, but no available compression binary was found");
|
||||
@@ -386,11 +363,10 @@ void DatabaseDumpService::DatabaseDump()
|
||||
}
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
|
||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||
// LogDebug("[{}] query-serv", (IsDumpQueryServerTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
|
||||
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
|
||||
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
|
||||
@@ -500,6 +476,16 @@ const std::string &DatabaseDumpService::GetDumpFileName() const
|
||||
return dump_file_name;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpQueryServerTables() const
|
||||
{
|
||||
return dump_query_server_tables;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpQueryServerTables(bool dump_query_server_tables)
|
||||
{
|
||||
DatabaseDumpService::dump_query_server_tables = dump_query_server_tables;
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpOutputToConsole() const
|
||||
{
|
||||
return dump_output_to_console;
|
||||
@@ -549,63 +535,3 @@ 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;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
class DatabaseDumpService {
|
||||
public:
|
||||
void DatabaseDump();
|
||||
void Dump();
|
||||
bool IsDumpAllTables() const;
|
||||
void SetDumpAllTables(bool dump_all_tables);
|
||||
bool IsDumpWithNoData() const;
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
void SetDumpPath(const std::string &dump_path);
|
||||
const std::string &GetDumpFileName() const;
|
||||
void SetDumpFileName(const std::string &dump_file_name);
|
||||
bool IsDumpQueryServerTables() const;
|
||||
void SetDumpQueryServerTables(bool dump_query_server_tables);
|
||||
bool IsDumpOutputToConsole() const;
|
||||
void SetDumpOutputToConsole(bool dump_output_to_console);
|
||||
bool IsDumpDropTableSyntaxOnly() const;
|
||||
@@ -56,9 +58,6 @@ public:
|
||||
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;
|
||||
@@ -74,8 +73,6 @@ private:
|
||||
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;
|
||||
|
||||
@@ -94,9 +91,7 @@ private:
|
||||
bool HasCompressionBinary();
|
||||
std::string GetDumpFileNameWithPath();
|
||||
std::string GetSetDumpPath();
|
||||
void RemoveSqlBackup();
|
||||
void BuildCredentialsFile();
|
||||
void RemoveCredentialsFile();
|
||||
std::string GetQueryServTables();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
+69
-129
@@ -29,8 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#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 "repositories/data_buckets_repository.h"
|
||||
|
||||
|
||||
#include "database.h"
|
||||
|
||||
@@ -50,7 +49,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
||||
{
|
||||
auto e = InstanceListPlayerRepository::NewEntity();
|
||||
@@ -114,9 +112,7 @@ bool Database::CheckInstanceExpired(uint16 instance_id)
|
||||
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;
|
||||
return (i.start_time + i.duration) <= tv.tv_sec;
|
||||
}
|
||||
|
||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
||||
@@ -135,118 +131,85 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
{
|
||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||
uint32 max_instance_id = 32000;
|
||||
uint32 max = 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
|
||||
);
|
||||
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
query = (
|
||||
SQL(
|
||||
SELECT i.id + 1 AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
||||
WHERE i2.id IS NULL
|
||||
ORDER BY i.id
|
||||
LIMIT 0, 1;
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// 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 = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (Strings::ToInt(row[0]) <= max) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (instance_id < max_reserved_instance_id) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
max_reserved_instance_id++;
|
||||
|
||||
// no instances currently used
|
||||
if (!row[0]) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
return true;
|
||||
for (auto row : results) {
|
||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (max_reserved_instance_id > max) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
}
|
||||
|
||||
// check that id is within limits
|
||||
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
return true;
|
||||
}
|
||||
instance_id = max_reserved_instance_id;
|
||||
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
||||
@@ -423,25 +386,20 @@ 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(
|
||||
auto l = GroupIdRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"`group_id` = {}",
|
||||
"groupid = {}",
|
||||
group_id
|
||||
)
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
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);
|
||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
||||
AddClientToInstance(instance_id, e.charid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -471,15 +429,18 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
||||
|
||||
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));
|
||||
std::string query;
|
||||
|
||||
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);
|
||||
DataBucketsRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||
}
|
||||
|
||||
void Database::FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id)
|
||||
@@ -510,7 +471,7 @@ void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 ch
|
||||
return;
|
||||
}
|
||||
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id).c_str());
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
||||
|
||||
if (!raid_leader_instance_id) {
|
||||
@@ -561,7 +522,6 @@ void Database::PurgeExpiredInstances()
|
||||
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));
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
@@ -576,23 +536,3 @@ void Database::SetInstanceDuration(uint16 instance_id, uint32 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);
|
||||
}
|
||||
|
||||
+35
-37
@@ -36,6 +36,7 @@ namespace DatabaseSchema {
|
||||
{
|
||||
return {
|
||||
{"adventure_stats", "player_id"},
|
||||
{"buyer", "charid"},
|
||||
{"char_recipe_list", "char_id"},
|
||||
{"character_activities", "charid"},
|
||||
{"character_alt_currency", "char_id"},
|
||||
@@ -51,7 +52,6 @@ namespace DatabaseSchema {
|
||||
{"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"},
|
||||
@@ -59,22 +59,18 @@ namespace DatabaseSchema {
|
||||
{"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"},
|
||||
{"character_tribute", "id"},
|
||||
{"completed_tasks", "charid"},
|
||||
{"data_buckets", "character_id"},
|
||||
{"data_buckets", "id"},
|
||||
{"faction_values", "char_id"},
|
||||
{"friends", "charid"},
|
||||
{"guild_members", "char_id"},
|
||||
@@ -108,8 +104,6 @@ namespace DatabaseSchema {
|
||||
"adventure_details",
|
||||
"adventure_stats",
|
||||
"buyer",
|
||||
"buyer_buy_lines",
|
||||
"buyer_trade_items",
|
||||
"char_recipe_list",
|
||||
"character_activities",
|
||||
"character_alt_currency",
|
||||
@@ -126,7 +120,6 @@ namespace DatabaseSchema {
|
||||
"character_enabledtasks",
|
||||
"character_expedition_lockouts",
|
||||
"character_exp_modifiers",
|
||||
"character_evolving_items",
|
||||
"character_inspect_messages",
|
||||
"character_instance_safereturns",
|
||||
"character_item_recast",
|
||||
@@ -134,8 +127,6 @@ namespace DatabaseSchema {
|
||||
"character_leadership_abilities",
|
||||
"character_material",
|
||||
"character_memmed_spells",
|
||||
"character_parcels",
|
||||
"character_parcels_containers",
|
||||
"character_pet_buffs",
|
||||
"character_pet_info",
|
||||
"character_pet_inventory",
|
||||
@@ -143,7 +134,6 @@ namespace DatabaseSchema {
|
||||
"character_potionbelt",
|
||||
"character_skills",
|
||||
"character_spells",
|
||||
"character_stats_record",
|
||||
"character_task_timers",
|
||||
"character_tasks",
|
||||
"character_tribute",
|
||||
@@ -154,10 +144,8 @@ namespace DatabaseSchema {
|
||||
"friends",
|
||||
"guild_bank",
|
||||
"guild_members",
|
||||
"guild_permissions",
|
||||
"guild_ranks",
|
||||
"guild_relations",
|
||||
"guild_tributes",
|
||||
"guilds",
|
||||
"instance_list_player",
|
||||
"inventory",
|
||||
@@ -215,7 +203,6 @@ namespace DatabaseSchema {
|
||||
"ground_spawns",
|
||||
"horses",
|
||||
"items",
|
||||
"items_evolving_details",
|
||||
"ldon_trap_entries",
|
||||
"ldon_trap_templates",
|
||||
"lootdrop",
|
||||
@@ -269,9 +256,7 @@ namespace DatabaseSchema {
|
||||
{
|
||||
return {
|
||||
"chatchannels",
|
||||
"chatchannel_reserved_names",
|
||||
"command_settings",
|
||||
"command_subsettings",
|
||||
"content_flags",
|
||||
"db_str",
|
||||
"eqtime",
|
||||
@@ -291,6 +276,32 @@ namespace DatabaseSchema {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets QueryServer tables
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static std::vector<std::string> GetQueryServerTables()
|
||||
{
|
||||
return {
|
||||
"qs_merchant_transaction_record",
|
||||
"qs_merchant_transaction_record_entries",
|
||||
"qs_player_aa_rate_hourly",
|
||||
"qs_player_delete_record",
|
||||
"qs_player_delete_record_entries",
|
||||
"qs_player_events",
|
||||
"qs_player_handin_record",
|
||||
"qs_player_handin_record_entries",
|
||||
"qs_player_move_record",
|
||||
"qs_player_move_record_entries",
|
||||
"qs_player_npc_kill_record",
|
||||
"qs_player_npc_kill_record_entries",
|
||||
"qs_player_speech",
|
||||
"qs_player_trade_record",
|
||||
"qs_player_trade_record_entries",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets state tables
|
||||
* Tables that keep track of server state
|
||||
@@ -304,21 +315,20 @@ namespace DatabaseSchema {
|
||||
"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_lockouts",
|
||||
"dynamic_zone_members",
|
||||
"dynamic_zones",
|
||||
"expedition_lockouts",
|
||||
"expeditions",
|
||||
"gm_ips",
|
||||
"group_id",
|
||||
"group_leaders",
|
||||
"instance_list",
|
||||
"ip_exemptions",
|
||||
"item_tick",
|
||||
"lfguild",
|
||||
"merc_buffs",
|
||||
"merchantlist_temp",
|
||||
@@ -331,21 +341,8 @@ namespace DatabaseSchema {
|
||||
"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",
|
||||
@@ -391,11 +388,13 @@ namespace DatabaseSchema {
|
||||
static std::vector<std::string> GetBotTables()
|
||||
{
|
||||
return {
|
||||
"bot_blocked_buffs",
|
||||
"bot_buffs",
|
||||
"bot_command_settings",
|
||||
"bot_create_combinations",
|
||||
"bot_data",
|
||||
"bot_group_members",
|
||||
"bot_groups",
|
||||
"bot_guild_members",
|
||||
"bot_heal_rotation_members",
|
||||
"bot_heal_rotation_targets",
|
||||
"bot_heal_rotations",
|
||||
@@ -405,7 +404,6 @@ namespace DatabaseSchema {
|
||||
"bot_pet_buffs",
|
||||
"bot_pet_inventories",
|
||||
"bot_pets",
|
||||
"bot_settings",
|
||||
"bot_spell_casting_chances",
|
||||
"bot_spell_settings",
|
||||
"bot_spells_entries",
|
||||
|
||||
+5
-142
@@ -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
|
||||
@@ -75,13 +74,13 @@ void DBcore::ping()
|
||||
m_mutex->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)
|
||||
bool DBcore::DoesTableExist(std::string table_name)
|
||||
{
|
||||
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
|
||||
|
||||
@@ -137,8 +136,8 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
/**
|
||||
* Error logging
|
||||
*/
|
||||
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
||||
LogMySQLError("MySQL Error ({}) [{}] Query [{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
||||
if (mysql_errno(mysql) > 0 && strlen(query) > 0) {
|
||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
||||
}
|
||||
|
||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
||||
@@ -306,139 +305,3 @@ void DBcore::SetMutex(Mutex *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);
|
||||
}
|
||||
|
||||
+3
-26
@@ -14,11 +14,6 @@
|
||||
#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 {
|
||||
@@ -29,8 +24,7 @@ public:
|
||||
~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);
|
||||
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
|
||||
void TransactionBegin();
|
||||
void TransactionCommit();
|
||||
void TransactionRollback();
|
||||
@@ -41,7 +35,7 @@ public:
|
||||
const std::string &GetOriginHost() const;
|
||||
void SetOriginHost(const std::string &origin_host);
|
||||
|
||||
bool DoesTableExist(const std::string& table_name);
|
||||
bool DoesTableExist(std::string table_name);
|
||||
|
||||
void SetMySQL(const DBcore &o)
|
||||
{
|
||||
@@ -50,11 +44,6 @@ public:
|
||||
}
|
||||
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);
|
||||
|
||||
protected:
|
||||
bool Open(
|
||||
const char *iHost,
|
||||
@@ -88,20 +77,8 @@ private:
|
||||
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
@@ -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)
|
||||
|
||||
EQ::deity::DeityTypeBit EQ::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)
|
||||
EQ::deity::DeityType EQ::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* EQ::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
@@ -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 EQ
|
||||
{
|
||||
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 */
|
||||
|
||||
@@ -27,6 +27,9 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// payload
|
||||
Json::Value p;
|
||||
@@ -93,6 +96,9 @@ void Discord::SendPlayerEventMessage(
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
|
||||
if (payload.empty()) {
|
||||
|
||||
@@ -37,7 +37,7 @@ void DiscordManager::ProcessMessageQueue()
|
||||
message,
|
||||
webhook.webhook_url
|
||||
);
|
||||
message.clear();
|
||||
message = "";
|
||||
}
|
||||
|
||||
message += m;
|
||||
@@ -51,7 +51,7 @@ void DiscordManager::ProcessMessageQueue()
|
||||
webhook.webhook_url
|
||||
);
|
||||
}
|
||||
message.clear();
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
// final flush
|
||||
|
||||
+64
-293
@@ -1,13 +1,11 @@
|
||||
#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"
|
||||
#include "repositories/character_expedition_lockouts_repository.h"
|
||||
#include "repositories/dynamic_zone_lockouts_repository.h"
|
||||
#include "repositories/instance_list_repository.h"
|
||||
#include "repositories/instance_list_player_repository.h"
|
||||
|
||||
DynamicZoneBase::DynamicZoneBase(DynamicZonesRepository::DynamicZoneInstance&& entry)
|
||||
{
|
||||
@@ -95,15 +93,13 @@ void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneIn
|
||||
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;
|
||||
m_is_locked = dz_entry.is_locked;
|
||||
m_add_replay = dz_entry.add_replay;
|
||||
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_never_expires = (dz_entry.never_expires != 0);
|
||||
m_expire_time = m_start_time + m_duration;
|
||||
}
|
||||
|
||||
@@ -123,40 +119,37 @@ void DynamicZoneBase::AddMemberFromRepositoryResult(
|
||||
uint32_t DynamicZoneBase::SaveToDatabase()
|
||||
{
|
||||
LogDynamicZonesDetail("Saving dz instance [{}] to database", m_instance_id);
|
||||
if (m_instance_id == 0)
|
||||
|
||||
if (m_instance_id != 0)
|
||||
{
|
||||
return 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;
|
||||
}
|
||||
|
||||
auto dz = DynamicZonesRepository::NewEntity();
|
||||
dz.uuid = m_uuid;
|
||||
dz.name = m_name;
|
||||
dz.leader_id = m_leader.id;
|
||||
dz.min_players = m_min_players;
|
||||
dz.max_players = m_max_players;
|
||||
dz.instance_id = static_cast<int32_t>(m_instance_id),
|
||||
dz.type = static_cast<uint8_t>(m_type);
|
||||
dz.dz_switch_id = m_dz_switch_id;
|
||||
dz.compass_zone_id = m_compass.zone_id;
|
||||
dz.compass_x = m_compass.x;
|
||||
dz.compass_y = m_compass.y;
|
||||
dz.compass_z = m_compass.z;
|
||||
dz.safe_return_zone_id = m_safereturn.zone_id;
|
||||
dz.safe_return_x = m_safereturn.x;
|
||||
dz.safe_return_y = m_safereturn.y;
|
||||
dz.safe_return_z = m_safereturn.z;
|
||||
dz.safe_return_heading = m_safereturn.heading;
|
||||
dz.zone_in_x = m_zonein.x;
|
||||
dz.zone_in_y = m_zonein.y;
|
||||
dz.zone_in_z = m_zonein.z;
|
||||
dz.zone_in_heading = m_zonein.heading;
|
||||
dz.has_zone_in = static_cast<uint8_t>(m_has_zonein);
|
||||
dz.is_locked = static_cast<int8_t>(m_is_locked);
|
||||
dz.add_replay = static_cast<int8_t>(m_add_replay);
|
||||
|
||||
dz = DynamicZonesRepository::InsertOne(GetDatabase(), std::move(dz));
|
||||
|
||||
return dz.id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::AddMember(const DynamicZoneMember& add_member)
|
||||
@@ -203,9 +196,10 @@ bool DynamicZoneBase::RemoveMember(const DynamicZoneMember& remove_member)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::SwapMember(const DynamicZoneMember& add_member, const std::string& remove_name)
|
||||
bool DynamicZoneBase::SwapMember(
|
||||
const DynamicZoneMember& add_member, const std::string& remove_char_name)
|
||||
{
|
||||
auto remove_member = GetMemberData(remove_name);
|
||||
auto remove_member = GetMemberData(remove_char_name);
|
||||
if (!add_member.IsValid() || !remove_member.IsValid())
|
||||
{
|
||||
return false;
|
||||
@@ -236,18 +230,9 @@ void DynamicZoneBase::RemoveAllMembers()
|
||||
|
||||
void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
|
||||
{
|
||||
if (members.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogDynamicZonesDetail("Saving [{}] member(s) for dz [{}]", members.size(), m_id);
|
||||
|
||||
m_members = members;
|
||||
if (m_members.size() > m_max_players)
|
||||
{
|
||||
m_members.resize(m_max_players);
|
||||
}
|
||||
|
||||
// the lower level instance_list_players needs to be kept updated as well
|
||||
std::vector<DynamicZoneMembersRepository::DynamicZoneMembers> insert_members;
|
||||
@@ -257,12 +242,12 @@ void DynamicZoneBase::SaveMembers(const std::vector<DynamicZoneMember>& members)
|
||||
DynamicZoneMembersRepository::DynamicZoneMembers member_entry{};
|
||||
member_entry.dynamic_zone_id = m_id;
|
||||
member_entry.character_id = member.id;
|
||||
insert_members.push_back(member_entry);
|
||||
insert_members.emplace_back(member_entry);
|
||||
|
||||
InstanceListPlayerRepository::InstanceListPlayer player_entry{};
|
||||
player_entry.id = m_instance_id;
|
||||
player_entry.charid = member.id;
|
||||
insert_players.push_back(player_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);
|
||||
@@ -354,44 +339,6 @@ void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetLocked(bool lock, bool update_db, DzLockMsg lock_msg, uint32_t color)
|
||||
{
|
||||
m_is_locked = lock;
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
DynamicZonesRepository::UpdateLocked(GetDatabase(), m_id, lock);
|
||||
|
||||
ServerPacket pack(ServerOP_DzLock, sizeof(ServerDzLock_Struct));
|
||||
auto buf = reinterpret_cast<ServerDzLock_Struct*>(pack.pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->lock = m_is_locked;
|
||||
buf->lock_msg = static_cast<uint8_t>(lock_msg);
|
||||
buf->color = color;
|
||||
SendServerPacket(&pack);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SetReplayOnJoin(bool enabled, bool update_db)
|
||||
{
|
||||
m_add_replay = enabled;
|
||||
|
||||
if (update_db)
|
||||
{
|
||||
DynamicZonesRepository::UpdateReplayOnJoin(GetDatabase(), m_id, enabled);
|
||||
|
||||
ServerPacket pack(ServerOP_DzReplayOnJoin, sizeof(ServerDzBool_Struct));
|
||||
auto buf = reinterpret_cast<ServerDzBool_Struct*>(pack.pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->enabled = enabled;
|
||||
SendServerPacket(&pack);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DynamicZoneBase::GetSecondsRemaining() const
|
||||
{
|
||||
auto remaining = std::chrono::duration_cast<std::chrono::seconds>(GetDurationRemaining()).count();
|
||||
@@ -531,13 +478,13 @@ void DynamicZoneBase::RemoveInternalMember(uint32_t character_id)
|
||||
), m_members.end());
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::HasMember(uint32_t character_id) const
|
||||
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) const
|
||||
bool DynamicZoneBase::HasMember(const std::string& character_name)
|
||||
{
|
||||
return std::any_of(m_members.begin(), m_members.end(),
|
||||
[&](const DynamicZoneMember& member) {
|
||||
@@ -643,34 +590,35 @@ std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerPacket(uint16_t zone_id, uint16_t instance_id)
|
||||
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
|
||||
{
|
||||
std::ostringstream ss = GetSerialized();
|
||||
std::string_view sv = ss.view();
|
||||
EQ::Net::DynamicPacket dyn_pack;
|
||||
dyn_pack.PutSerialize(0, *this);
|
||||
|
||||
auto pack_size = sizeof(ServerDzCreate_Struct) + sv.size();
|
||||
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<ServerDzCreate_Struct*>(pack->pBuffer);
|
||||
buf->origin_zone_id = zone_id;
|
||||
buf->origin_instance_id = instance_id;
|
||||
buf->dz_id = GetID();
|
||||
buf->cereal_size = static_cast<uint32_t>(sv.size());
|
||||
memcpy(buf->cereal_data, sv.data(), sv.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;
|
||||
}
|
||||
|
||||
std::ostringstream DynamicZoneBase::GetSerialized()
|
||||
void DynamicZoneBase::LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
cereal::BinaryOutputArchive archive(ss);
|
||||
archive(*this);
|
||||
return ss;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::Unserialize(std::span<char> buf)
|
||||
{
|
||||
EQ::Util::MemoryStreamReader ss(buf.data(), buf.size());
|
||||
LogDynamicZonesDetail("Deserializing server dz size [{}]", cereal_size);
|
||||
EQ::Util::MemoryStreamReader ss(cereal_data, cereal_size);
|
||||
cereal::BinaryInputArchive archive(ss);
|
||||
archive(*this);
|
||||
}
|
||||
@@ -699,180 +647,3 @@ void DynamicZoneBase::LoadTemplate(const DynamicZoneTemplatesRepository::Dynamic
|
||||
m_zonein.z = dz_template.zone_in_z;
|
||||
m_zonein.heading = dz_template.zone_in_h;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> DynamicZoneBase::GetMemberIds()
|
||||
{
|
||||
std::vector<uint32_t> ids;
|
||||
ids.reserve(m_members.size());
|
||||
for (const auto& member : m_members)
|
||||
{
|
||||
ids.push_back(member.id);
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::HasLockout(const std::string& event)
|
||||
{
|
||||
return std::ranges::any_of(m_lockouts, [&](const auto& l) { return l.IsEvent(event); });
|
||||
}
|
||||
|
||||
bool DynamicZoneBase::HasReplayLockout()
|
||||
{
|
||||
return HasLockout(DzLockout::ReplayTimer);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::AddLockout(const std::string& event, uint32_t seconds)
|
||||
{
|
||||
auto lockout = DzLockout::Create(m_name, event, seconds, m_uuid);
|
||||
AddLockout(lockout);
|
||||
}
|
||||
|
||||
void DynamicZoneBase::AddLockout(const DzLockout& lockout, bool members_only)
|
||||
{
|
||||
if (!members_only)
|
||||
{
|
||||
DynamicZoneLockoutsRepository::InsertLockouts(GetDatabase(), GetID(), { lockout });
|
||||
}
|
||||
|
||||
CharacterExpeditionLockoutsRepository::InsertLockout(GetDatabase(), GetMemberIds(), lockout);
|
||||
|
||||
HandleLockoutUpdate(lockout, false, members_only);
|
||||
SendServerPacket(CreateLockoutPacket(lockout, false, members_only).get());
|
||||
}
|
||||
|
||||
void DynamicZoneBase::AddLockoutDuration(const std::string& event, int seconds, bool members_only)
|
||||
{
|
||||
auto lockout = DzLockout::Create(m_name, event, std::max(0, seconds), m_uuid);
|
||||
|
||||
// lockout has unsigned duration, pass original seconds to support reducing existing timers
|
||||
int secs = static_cast<int>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
|
||||
CharacterExpeditionLockoutsRepository::AddLockoutDuration(GetDatabase(), GetMemberIds(), lockout, secs);
|
||||
|
||||
HandleLockoutDuration(lockout, seconds, members_only, true);
|
||||
SendServerPacket(CreateLockoutDurationPacket(lockout, seconds, members_only).get());
|
||||
}
|
||||
|
||||
void DynamicZoneBase::UpdateLockoutDuration(const std::string& event, uint32_t seconds, bool members_only)
|
||||
{
|
||||
// some live expeditions update existing lockout timers during progression
|
||||
auto it = std::ranges::find_if(m_lockouts, [&](const auto& l) { return l.IsEvent(event); });
|
||||
if (it != m_lockouts.end())
|
||||
{
|
||||
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
|
||||
DzLockout lockout(m_uuid, m_name, event, it->GetStartTime() + seconds, seconds);
|
||||
AddLockout(lockout, members_only);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::RemoveLockout(const std::string& event)
|
||||
{
|
||||
DynamicZoneLockoutsRepository::DeleteWhere(GetDatabase(), fmt::format(
|
||||
"dynamic_zone_id = {} AND event_name = '{}'", GetID(), Strings::Escape(event)));
|
||||
|
||||
CharacterExpeditionLockoutsRepository::DeleteWhere(GetDatabase(), fmt::format(
|
||||
"character_id IN ({}) AND expedition_name = '{}' AND event_name = '{}'",
|
||||
fmt::join(GetMemberIds(), ","), Strings::Escape(m_name), Strings::Escape(event)));
|
||||
|
||||
DzLockout lockout{m_uuid, m_name, event, 0, 0};
|
||||
HandleLockoutUpdate(lockout, true, false);
|
||||
SendServerPacket(CreateLockoutPacket(lockout, true).get());
|
||||
}
|
||||
|
||||
void DynamicZoneBase::HandleLockoutUpdate(const DzLockout& lockout, bool remove, bool members_only)
|
||||
{
|
||||
if (!members_only)
|
||||
{
|
||||
std::erase_if(m_lockouts, [&](const auto& l) { return l.IsEvent(lockout.Event()); });
|
||||
if (!remove)
|
||||
{
|
||||
m_lockouts.push_back(lockout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZoneBase::HandleLockoutDuration(const DzLockout& lockout, int seconds, bool members_only, bool insert_db)
|
||||
{
|
||||
if (!members_only)
|
||||
{
|
||||
auto it = std::ranges::find_if(m_lockouts, [&](const auto& l) { return l.IsEvent(lockout.Event()); });
|
||||
if (it != m_lockouts.end())
|
||||
{
|
||||
it->AddLockoutTime(seconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
it = m_lockouts.insert(m_lockouts.end(), lockout);
|
||||
}
|
||||
|
||||
if (insert_db)
|
||||
{
|
||||
DynamicZoneLockoutsRepository::InsertLockouts(GetDatabase(), GetID(), { *it });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateLockoutPacket(const DzLockout& lockout, bool remove, bool members_only) const
|
||||
{
|
||||
uint32_t pack_size = sizeof(ServerDzLockout_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzLockout, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzLockout_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->expire_time = lockout.GetExpireTime();
|
||||
buf->duration = lockout.GetDuration();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->remove = remove;
|
||||
buf->members_only = members_only;
|
||||
strn0cpy(buf->event_name, lockout.Event().c_str(), sizeof(buf->event_name));
|
||||
return pack;
|
||||
}
|
||||
|
||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateLockoutDurationPacket(const DzLockout& lockout, int seconds, bool members_only) const
|
||||
{
|
||||
uint32_t pack_size = sizeof(ServerDzLockout_Struct);
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzLockoutDuration, pack_size);
|
||||
auto buf = reinterpret_cast<ServerDzLockout_Struct*>(pack->pBuffer);
|
||||
buf->dz_id = GetID();
|
||||
buf->expire_time = lockout.GetExpireTime();
|
||||
buf->duration = lockout.GetDuration();
|
||||
buf->sender_zone_id = GetCurrentZoneID();
|
||||
buf->sender_instance_id = GetCurrentInstanceID();
|
||||
buf->members_only = members_only;
|
||||
buf->seconds = seconds;
|
||||
strn0cpy(buf->event_name, lockout.Event().c_str(), sizeof(buf->event_name));
|
||||
return pack;
|
||||
}
|
||||
|
||||
void DynamicZoneBase::SyncCharacterLockouts(uint32_t char_id, std::vector<DzLockout>& lockouts)
|
||||
{
|
||||
// adds missing event lockouts to client for this expedition and updates
|
||||
// client timers that are both shorter and from another expedition
|
||||
bool modified = false;
|
||||
|
||||
for (const auto& lockout : m_lockouts)
|
||||
{
|
||||
if (lockout.IsReplay() || lockout.IsExpired() || lockout.UUID() != m_uuid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto it = std::find_if(lockouts.begin(), lockouts.end(), [&](const DzLockout& l) { return l.IsSame(lockout); });
|
||||
if (it == lockouts.end())
|
||||
{
|
||||
modified = true;
|
||||
lockouts.push_back(lockout); // insert missing
|
||||
}
|
||||
else if (it->GetSecondsRemaining() < lockout.GetSecondsRemaining() && it->UUID() != m_uuid)
|
||||
{
|
||||
// only update lockout timer not uuid so loot event apis still work
|
||||
modified = true;
|
||||
it->SetDuration(lockout.GetDuration());
|
||||
it->SetExpireTime(lockout.GetExpireTime());
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
{
|
||||
CharacterExpeditionLockoutsRepository::InsertLockouts(GetDatabase(), char_id, lockouts);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-68
@@ -1,8 +1,8 @@
|
||||
#ifndef COMMON_DYNAMIC_ZONE_BASE_H
|
||||
#define COMMON_DYNAMIC_ZONE_BASE_H
|
||||
|
||||
#include "dynamic_zone_lockout.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"
|
||||
@@ -10,40 +10,12 @@
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Database;
|
||||
class ServerPacket;
|
||||
|
||||
// message string 8312 added in September 08 2020 Test patch (used by both dz and shared tasks)
|
||||
inline constexpr char DzNotAllAdded[] = "Not all players in your {0} were added to the {1}. The {1} can take a maximum of {2} players, and your {0} has {3}.";
|
||||
|
||||
enum class DzLockMsg : uint8_t
|
||||
{
|
||||
None = 0, Close, Begin
|
||||
};
|
||||
|
||||
enum class DynamicZoneType
|
||||
{
|
||||
None = 0,
|
||||
Expedition,
|
||||
Tutorial,
|
||||
Task,
|
||||
Mission, // Shared Task
|
||||
Quest
|
||||
};
|
||||
|
||||
enum class DynamicZoneMemberStatus
|
||||
{
|
||||
Unknown = 0,
|
||||
Online,
|
||||
Offline,
|
||||
InDynamicZone,
|
||||
LinkDead
|
||||
};
|
||||
|
||||
struct DynamicZoneMember
|
||||
{
|
||||
uint32_t id = 0;
|
||||
@@ -121,7 +93,6 @@ public:
|
||||
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<DzLockout>& GetLockouts() const { return m_lockouts; }
|
||||
const std::vector<DynamicZoneMember>& GetMembers() const { return m_members; }
|
||||
const DynamicZoneLocation& GetCompassLocation() const { return m_compass; }
|
||||
const DynamicZoneLocation& GetSafeReturnLocation() const { return m_safereturn; }
|
||||
@@ -133,34 +104,31 @@ public:
|
||||
uint32_t GetDatabaseMemberCount();
|
||||
DynamicZoneMember GetMemberData(uint32_t character_id);
|
||||
DynamicZoneMember GetMemberData(const std::string& character_name);
|
||||
std::vector<uint32_t> GetMemberIds();
|
||||
std::ostringstream GetSerialized();
|
||||
EQ::Net::DynamicPacket GetSerializedDzPacket();
|
||||
bool HasDatabaseMember(uint32_t character_id);
|
||||
bool HasMember(uint32_t character_id) const;
|
||||
bool HasMember(const std::string& character_name) const;
|
||||
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 IsExpedition() const { return m_type == DynamicZoneType::Expedition; }
|
||||
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 IsLocked() const { return m_is_locked; }
|
||||
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 SetLocked(bool lock, bool update_db = false, DzLockMsg lock_msg = DzLockMsg::None, uint32_t color = Chat::Yellow);
|
||||
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 SetReplayOnJoin(bool enabled, bool update_db = false);
|
||||
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
|
||||
void SetSwitchID(int dz_switch_id, bool update_db = false);
|
||||
@@ -168,48 +136,34 @@ public:
|
||||
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_name);
|
||||
|
||||
void AddLockout(const std::string& event, uint32_t seconds);
|
||||
void AddLockoutDuration(const std::string& event, int seconds, bool members_only = true);
|
||||
bool HasLockout(const std::string& event);
|
||||
bool HasReplayLockout();
|
||||
void RemoveLockout(const std::string& event);
|
||||
void SyncCharacterLockouts(uint32_t char_id, std::vector<DzLockout>& lockouts);
|
||||
void UpdateLockoutDuration(const std::string& event, uint32_t seconds, bool members_only = true);
|
||||
bool SwapMember(const DynamicZoneMember& add_member, const std::string& remove_char_name);
|
||||
|
||||
protected:
|
||||
virtual uint16_t GetCurrentInstanceID() const { return 0; }
|
||||
virtual uint16_t GetCurrentZoneID() const { return 0; }
|
||||
virtual uint16_t GetCurrentInstanceID() { return 0; }
|
||||
virtual uint16_t GetCurrentZoneID() { return 0; }
|
||||
virtual Database& GetDatabase() = 0;
|
||||
virtual void HandleLockoutDuration(const DzLockout& lockout, int seconds, bool members_only, bool insert_db);
|
||||
virtual void HandleLockoutUpdate(const DzLockout& lockout, bool remove, bool members_only);
|
||||
virtual void ProcessCompassChange(const DynamicZoneLocation& location) { m_compass = location; }
|
||||
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
|
||||
virtual bool ProcessMemberStatusChange(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||
virtual void ProcessRemoveAllMembers() { m_members.clear(); }
|
||||
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 AddLockout(const DzLockout& lockout, bool members_only = false);
|
||||
void AddInternalMember(const DynamicZoneMember& member);
|
||||
uint32_t Create();
|
||||
uint32_t CreateInstance();
|
||||
void LoadRepositoryResult(DynamicZonesRepository::DynamicZoneInstance&& dz_entry);
|
||||
void RemoveInternalMember(uint32_t character_id);
|
||||
void SaveMembers(const std::vector<DynamicZoneMember>& members);
|
||||
uint32_t SaveToDatabase();
|
||||
bool SetInternalMemberStatus(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||
|
||||
std::unique_ptr<ServerPacket> CreateServerPacket(uint16_t zone_id, uint16_t instance_id);
|
||||
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();
|
||||
std::unique_ptr<ServerPacket> CreateLockoutPacket(const DzLockout& lockout, bool remove, bool members_only = false) const;
|
||||
std::unique_ptr<ServerPacket> CreateLockoutDurationPacket(const DzLockout& lockout, int seconds, bool members_only = false) const;
|
||||
|
||||
uint32_t m_id = 0;
|
||||
uint32_t m_zone_id = 0;
|
||||
@@ -221,8 +175,6 @@ protected:
|
||||
bool m_never_expires = false;
|
||||
bool m_has_zonein = false;
|
||||
bool m_has_member_statuses = false;
|
||||
bool m_is_locked = false;
|
||||
bool m_add_replay = true;
|
||||
std::string m_name;
|
||||
std::string m_uuid;
|
||||
DynamicZoneMember m_leader;
|
||||
@@ -230,15 +182,12 @@ protected:
|
||||
DynamicZoneLocation m_compass;
|
||||
DynamicZoneLocation m_safereturn;
|
||||
DynamicZoneLocation m_zonein;
|
||||
std::chrono::seconds m_duration = {};
|
||||
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;
|
||||
std::vector<DzLockout> m_lockouts;
|
||||
|
||||
public:
|
||||
void Unserialize(std::span<char> buf);
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive& archive)
|
||||
{
|
||||
@@ -253,8 +202,6 @@ public:
|
||||
m_never_expires,
|
||||
m_has_zonein,
|
||||
m_has_member_statuses,
|
||||
m_is_locked,
|
||||
m_add_replay,
|
||||
m_name,
|
||||
m_uuid,
|
||||
m_leader,
|
||||
@@ -265,8 +212,7 @@ public:
|
||||
m_duration,
|
||||
m_start_time,
|
||||
m_expire_time,
|
||||
m_members,
|
||||
m_lockouts
|
||||
m_members
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#include "dynamic_zone_lockout.h"
|
||||
#include "strings.h"
|
||||
#include "rulesys.h"
|
||||
#include "util/uuid.h"
|
||||
#include <fmt/format.h>
|
||||
#include <cereal/types/chrono.hpp>
|
||||
|
||||
DzLockout::DzLockout(std::string uuid, std::string expedition, std::string event, uint64_t expire_time, uint32_t duration)
|
||||
: m_uuid(std::move(uuid))
|
||||
, m_name(std::move(expedition))
|
||||
, m_event(std::move(event))
|
||||
, m_expire_time(std::chrono::system_clock::from_time_t(expire_time))
|
||||
, m_duration(duration)
|
||||
{
|
||||
m_is_replay = m_event == ReplayTimer;
|
||||
}
|
||||
|
||||
DzLockout::DzLockout(std::string_view name, BaseDynamicZoneLockoutsRepository::DynamicZoneLockouts&& lockout)
|
||||
: m_uuid(std::move(lockout.from_expedition_uuid))
|
||||
, m_name(name)
|
||||
, m_event(std::move(lockout.event_name))
|
||||
, m_expire_time(std::chrono::system_clock::from_time_t(lockout.expire_time))
|
||||
, m_duration(lockout.duration)
|
||||
{
|
||||
m_is_replay = m_event == ReplayTimer;
|
||||
}
|
||||
|
||||
DzLockout DzLockout::Create(const std::string& expedition, const std::string& event, uint32_t seconds, std::string uuid)
|
||||
{
|
||||
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
|
||||
|
||||
if (uuid.empty())
|
||||
{
|
||||
uuid = EQ::Util::UUID::Generate().ToString();
|
||||
}
|
||||
|
||||
DzLockout lockout{uuid, expedition, event, 0, seconds};
|
||||
lockout.Reset(); // sets expire time
|
||||
return lockout;
|
||||
}
|
||||
|
||||
uint32_t DzLockout::GetSecondsRemaining() const
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
if (m_expire_time > now)
|
||||
{
|
||||
auto remaining = m_expire_time - now;
|
||||
return static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::seconds>(remaining).count());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DzLockout::TimeStrings DzLockout::GetTimeRemainingStrs() const
|
||||
{
|
||||
auto seconds = GetSecondsRemaining();
|
||||
return DzLockout::TimeStrings{
|
||||
fmt::format_int(seconds / 86400).str(), // days
|
||||
fmt::format_int(seconds / 3600 % 24).str(), // hours
|
||||
fmt::format_int(seconds / 60 % 60).str(), // minutes
|
||||
fmt::format_int(seconds % 60).str() // seconds
|
||||
};
|
||||
}
|
||||
|
||||
bool DzLockout::IsSame(const DzLockout& other) const
|
||||
{
|
||||
return other.IsSame(m_name, m_event);
|
||||
}
|
||||
|
||||
bool DzLockout::IsSame(const std::string& expedition, const std::string& event) const
|
||||
{
|
||||
return m_name == expedition && m_event == event;
|
||||
}
|
||||
|
||||
void DzLockout::AddLockoutTime(int seconds)
|
||||
{
|
||||
seconds = static_cast<int>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
|
||||
|
||||
auto new_duration = std::max(0, static_cast<int>(m_duration.count()) + seconds);
|
||||
|
||||
auto start_time = m_expire_time - m_duration;
|
||||
m_duration = std::chrono::seconds(new_duration);
|
||||
m_expire_time = start_time + m_duration;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DzLockout::serialize(T& archive)
|
||||
{
|
||||
archive(m_is_replay, m_uuid, m_name, m_event, m_duration, m_expire_time);
|
||||
}
|
||||
|
||||
template void DzLockout::serialize(cereal::BinaryOutputArchive&);
|
||||
template void DzLockout::serialize(cereal::BinaryInputArchive&);
|
||||
@@ -1,56 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include "repositories/base/base_dynamic_zone_lockouts_repository.h"
|
||||
|
||||
class DzLockout
|
||||
{
|
||||
public:
|
||||
DzLockout() = default;
|
||||
DzLockout(std::string uuid, std::string expedition, std::string event, uint64_t expire_time, uint32_t duration);
|
||||
DzLockout(std::string_view name, BaseDynamicZoneLockoutsRepository::DynamicZoneLockouts&& lockout);
|
||||
|
||||
static constexpr char ReplayTimer[] = "Replay Timer";
|
||||
|
||||
static DzLockout Create(const std::string& expedition, const std::string& event, uint32_t seconds, std::string uuid = {});
|
||||
|
||||
struct TimeStrings
|
||||
{
|
||||
std::string days;
|
||||
std::string hours;
|
||||
std::string mins;
|
||||
std::string secs;
|
||||
};
|
||||
|
||||
void AddLockoutTime(int seconds);
|
||||
uint32_t GetDuration() const { return static_cast<uint32_t>(m_duration.count()); }
|
||||
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
||||
uint64_t GetStartTime() const { return std::chrono::system_clock::to_time_t(m_expire_time - m_duration); }
|
||||
uint32_t GetSecondsRemaining() const;
|
||||
TimeStrings GetTimeRemainingStrs() const;
|
||||
const std::string& DzName() const { return m_name; }
|
||||
const std::string& Event() const { return m_event; }
|
||||
const std::string& UUID() const { return m_uuid; }
|
||||
bool IsEvent(std::string_view event) const { return m_event == event; }
|
||||
bool IsExpired() const { return GetSecondsRemaining() == 0; }
|
||||
bool IsReplay() const { return m_is_replay; }
|
||||
bool IsSame(const DzLockout& other) const;
|
||||
bool IsSame(const std::string& expedition, const std::string& event) const;
|
||||
bool IsUUID(const std::string& uuid) const { return uuid == m_uuid; }
|
||||
void Reset() { m_expire_time = std::chrono::system_clock::now() + m_duration; }
|
||||
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
|
||||
void SetExpireTime(uint64_t expire_time) { m_expire_time = std::chrono::system_clock::from_time_t(expire_time); }
|
||||
void SetUUID(const std::string& uuid) { m_uuid = uuid; }
|
||||
|
||||
template <typename T>
|
||||
void serialize(T& archive);
|
||||
|
||||
private:
|
||||
bool m_is_replay = false;
|
||||
std::string m_uuid; // dz received in
|
||||
std::string m_name;
|
||||
std::string m_event;
|
||||
std::chrono::seconds m_duration = {};
|
||||
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
|
||||
};
|
||||
+350
-222
@@ -22,6 +22,7 @@
|
||||
#include "data_verification.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
#include "languages.h"
|
||||
#include "rulesys.h"
|
||||
|
||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
@@ -59,85 +60,171 @@ 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* EQ::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";
|
||||
}
|
||||
}
|
||||
|
||||
EQ::bug::CategoryID EQ::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;
|
||||
}
|
||||
|
||||
const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
||||
switch (stance_type) {
|
||||
case stanceUnknown:
|
||||
return "Unknown";
|
||||
case stancePassive:
|
||||
return "Passive";
|
||||
case stanceBalanced:
|
||||
return "Balanced";
|
||||
case stanceEfficient:
|
||||
return "Efficient";
|
||||
case stanceReactive:
|
||||
return "Reactive";
|
||||
case stanceAggressive:
|
||||
return "Aggressive";
|
||||
case stanceAssist:
|
||||
return "Assist";
|
||||
case stanceBurn:
|
||||
return "Burn";
|
||||
case stanceEfficient2:
|
||||
return "Efficient2";
|
||||
case stanceBurnAE:
|
||||
return "BurnAE";
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
||||
return (stance_type - EQ::constants::stancePassive);
|
||||
}
|
||||
|
||||
return Bug::Category::Other;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string Bug::GetName(uint32 category_id)
|
||||
const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
||||
{
|
||||
return IsValid(category_id) ? bug_category_names[category_id] : "UNKNOWN BUG CATEGORY";
|
||||
}
|
||||
|
||||
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" }
|
||||
static const std::map<int, std::string> language_map = {
|
||||
{ LANG_COMMON_TONGUE, "Common Tongue" },
|
||||
{ LANG_BARBARIAN, "Barbarian" },
|
||||
{ LANG_ERUDIAN, "Erudian" },
|
||||
{ LANG_ELVISH, "Elvish" },
|
||||
{ LANG_DARK_ELVISH, "Dark Elvish" },
|
||||
{ LANG_DWARVISH, "Dwarvish" },
|
||||
{ LANG_TROLL, "Troll" },
|
||||
{ LANG_OGRE, "Ogre" },
|
||||
{ LANG_GNOMISH, "Gnomish" },
|
||||
{ LANG_HALFLING, "Halfling" },
|
||||
{ LANG_THIEVES_CANT, "Thieves Cant" },
|
||||
{ LANG_OLD_ERUDIAN, "Old Erudian" },
|
||||
{ LANG_ELDER_ELVISH, "Elder Elvish" },
|
||||
{ LANG_FROGLOK, "Froglok" },
|
||||
{ LANG_GOBLIN, "Goblin" },
|
||||
{ LANG_GNOLL, "Gnoll" },
|
||||
{ LANG_COMBINE_TONGUE, "Combine Tongue" },
|
||||
{ LANG_ELDER_TEIRDAL, "Elder Teirdal" },
|
||||
{ LANG_LIZARDMAN, "Lizardman" },
|
||||
{ LANG_ORCISH, "Orcish" },
|
||||
{ LANG_FAERIE, "Faerie" },
|
||||
{ LANG_DRAGON, "Dragon" },
|
||||
{ LANG_ELDER_DRAGON, "Elder Dragon" },
|
||||
{ LANG_DARK_SPEECH, "Dark Speech" },
|
||||
{ LANG_VAH_SHIR, "Vah Shir" },
|
||||
{ LANG_ALARAN, "Alaran" },
|
||||
{ LANG_HADAL, "Hadal" },
|
||||
{ LANG_UNKNOWN, "Unknown" }
|
||||
};
|
||||
|
||||
return language_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetLanguageName(uint8 language_id)
|
||||
std::string EQ::constants::GetLanguageName(int language_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
|
||||
{
|
||||
static const std::map<uint32, std::string> ldon_theme_map = {
|
||||
{ LDoNThemes::Unused, "Unused" },
|
||||
{ LDoNThemes::GUK, "Deepest Guk" },
|
||||
{ LDoNThemes::MIR, "Miragul's Menagerie" },
|
||||
{ LDoNThemes::MMC, "Mistmoore Catacombs" },
|
||||
{ LDoNThemes::RUJ, "Rujarkian Hills" },
|
||||
{ LDoNThemes::TAK, "Takish-Hiz" },
|
||||
};
|
||||
|
||||
return ldon_theme_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
|
||||
{
|
||||
if (EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
|
||||
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
||||
@@ -156,11 +243,107 @@ const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
||||
|
||||
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
|
||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
|
||||
{
|
||||
static const std::map<bodyType, std::string> bodytype_map = {
|
||||
{ BT_Humanoid, "Humanoid" },
|
||||
{ BT_Lycanthrope, "Lycanthrope" },
|
||||
{ BT_Undead, "Undead" },
|
||||
{ BT_Giant, "Giant" },
|
||||
{ BT_Construct, "Construct" },
|
||||
{ BT_Extraplanar, "Extraplanar" },
|
||||
{ BT_Magical, "Magical" },
|
||||
{ BT_SummonedUndead, "Summoned Undead" },
|
||||
{ BT_RaidGiant, "Raid Giant" },
|
||||
{ BT_RaidColdain, "Raid Coldain" },
|
||||
{ BT_NoTarget, "Untargetable" },
|
||||
{ BT_Vampire, "Vampire" },
|
||||
{ BT_Atenha_Ra, "Aten Ha Ra" },
|
||||
{ BT_Greater_Akheva, "Greater Akheva" },
|
||||
{ BT_Khati_Sha, "Khati Sha" },
|
||||
{ BT_Seru, "Seru" },
|
||||
{ BT_Grieg_Veneficus, "Grieg Veneficus" },
|
||||
{ BT_Draz_Nurakk, "Draz Nurakk" },
|
||||
{ BT_Zek, "Zek" },
|
||||
{ BT_Luggald, "Luggald" },
|
||||
{ BT_Animal, "Animal" },
|
||||
{ BT_Insect, "Insect" },
|
||||
{ BT_Monster, "Monster" },
|
||||
{ BT_Summoned, "Summoned" },
|
||||
{ BT_Plant, "Plant" },
|
||||
{ BT_Dragon, "Dragon" },
|
||||
{ BT_Summoned2, "Summoned 2" },
|
||||
{ BT_Summoned3, "Summoned 3" },
|
||||
{ BT_Dragon2, "Dragon 2" },
|
||||
{ BT_VeliousDragon, "Velious Dragon" },
|
||||
{ BT_Familiar, "Familiar" },
|
||||
{ BT_Dragon3, "Dragon 3" },
|
||||
{ BT_Boxes, "Boxes" },
|
||||
{ BT_Muramite, "Muramite" },
|
||||
{ BT_NoTarget2, "Untargetable 2" },
|
||||
{ BT_SwarmPet, "Swarm Pet" },
|
||||
{ BT_MonsterSummon, "Monster Summon" },
|
||||
{ BT_InvisMan, "Invisible Man" },
|
||||
{ BT_Special, "Special" },
|
||||
};
|
||||
|
||||
return bodytype_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
|
||||
{
|
||||
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
|
||||
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> account_status_map = {
|
||||
{ AccountStatus::Player, "Player" },
|
||||
{ AccountStatus::Steward, "Steward" },
|
||||
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
|
||||
{ AccountStatus::Guide, "Guide" },
|
||||
{ AccountStatus::QuestTroupe, "Quest Troupe" },
|
||||
{ AccountStatus::SeniorGuide, "Senior Guide" },
|
||||
{ AccountStatus::GMTester, "GM Tester" },
|
||||
{ AccountStatus::EQSupport, "EQ Support" },
|
||||
{ AccountStatus::GMStaff, "GM Staff" },
|
||||
{ AccountStatus::GMAdmin, "GM Admin" },
|
||||
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
|
||||
{ AccountStatus::QuestMaster, "Quest Master" },
|
||||
{ AccountStatus::GMAreas, "GM Areas" },
|
||||
{ AccountStatus::GMCoder, "GM Coder" },
|
||||
{ AccountStatus::GMMgmt, "GM Mgmt" },
|
||||
{ AccountStatus::GMImpossible, "GM Impossible" },
|
||||
{ AccountStatus::Max, "GM Max" }
|
||||
};
|
||||
|
||||
return account_status_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
|
||||
{
|
||||
for (
|
||||
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
|
||||
status_level != EQ::constants::GetAccountStatusMap().rend();
|
||||
++status_level
|
||||
) {
|
||||
if (account_status >= status_level->first) {
|
||||
return status_level->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
||||
@@ -182,11 +365,11 @@ const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
||||
|
||||
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
|
||||
{
|
||||
if (!EQ::ValueWithin(faction_consider_level, ConsiderLevel::Ally, ConsiderLevel::Scowls)) {
|
||||
return std::string();;
|
||||
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
|
||||
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
||||
@@ -203,11 +386,11 @@ const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
||||
|
||||
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
|
||||
{
|
||||
if (!EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
|
||||
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
||||
@@ -224,11 +407,11 @@ const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
||||
|
||||
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
|
||||
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
||||
@@ -246,11 +429,89 @@ const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
||||
|
||||
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
||||
{
|
||||
if (!EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
|
||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
||||
{
|
||||
static const std::map<int, std::string> object_type_map = {
|
||||
{ ObjectTypes::SmallBag, "Small Bag" },
|
||||
{ ObjectTypes::LargeBag, "Large Bag" },
|
||||
{ ObjectTypes::Quiver, "Quiver" },
|
||||
{ ObjectTypes::BeltPouch, "Belt Pouch" },
|
||||
{ ObjectTypes::WristPouch, "Wrist Pouch" },
|
||||
{ ObjectTypes::Backpack, "Backpack" },
|
||||
{ ObjectTypes::SmallChest, "Small Chest" },
|
||||
{ ObjectTypes::LargeChest, "Large Chest" },
|
||||
{ ObjectTypes::Bandolier, "Bandolier" },
|
||||
{ ObjectTypes::Medicine, "Medicine" },
|
||||
{ ObjectTypes::Tinkering, "Tinkering" },
|
||||
{ ObjectTypes::Lexicon, "Lexicon" },
|
||||
{ ObjectTypes::PoisonMaking, "Mortar and Pestle" },
|
||||
{ ObjectTypes::Quest, "Quest" },
|
||||
{ ObjectTypes::MixingBowl, "Mixing Bowl" },
|
||||
{ ObjectTypes::Baking, "Baking" },
|
||||
{ ObjectTypes::Tailoring, "Tailoring" },
|
||||
{ ObjectTypes::Blacksmithing, "Blacksmithing" },
|
||||
{ ObjectTypes::Fletching, "Fletching" },
|
||||
{ ObjectTypes::Brewing, "Brewing" },
|
||||
{ ObjectTypes::JewelryMaking, "Jewelry Making" },
|
||||
{ ObjectTypes::Pottery, "Pottery" },
|
||||
{ ObjectTypes::Kiln, "Kiln" },
|
||||
{ ObjectTypes::KeyMaker, "Key Maker" },
|
||||
{ ObjectTypes::ResearchWIZ, "Lexicon" },
|
||||
{ ObjectTypes::ResearchMAG, "Lexicon" },
|
||||
{ ObjectTypes::ResearchNEC, "Lexicon" },
|
||||
{ ObjectTypes::ResearchENC, "Lexicon" },
|
||||
{ ObjectTypes::Unknown, "Unknown" },
|
||||
{ ObjectTypes::ResearchPractice, "Lexicon" },
|
||||
{ ObjectTypes::Alchemy, "Alchemy" },
|
||||
{ ObjectTypes::HighElfForge, "High Elf Forge" },
|
||||
{ ObjectTypes::DarkElfForge, "Dark Elf Forge" },
|
||||
{ ObjectTypes::OgreForge, "Ogre Forge" },
|
||||
{ ObjectTypes::DwarfForge, "Dwarf Forge" },
|
||||
{ ObjectTypes::GnomeForge, "Gnome Forge" },
|
||||
{ ObjectTypes::BarbarianForge, "Barbarian Forge" },
|
||||
{ ObjectTypes::IksarForge, "Iksar Forge" },
|
||||
{ ObjectTypes::HumanForgeOne, "Human Forge" },
|
||||
{ ObjectTypes::HumanForgeTwo, "Human Forge" },
|
||||
{ ObjectTypes::HalflingTailoringOne, "Halfling Tailoring" },
|
||||
{ ObjectTypes::HalflingTailoringTwo, "Halfling Tailoring" },
|
||||
{ ObjectTypes::EruditeTailoring, "Erudite Tailoring" },
|
||||
{ ObjectTypes::WoodElfTailoring, "Wood Elf Tailoring" },
|
||||
{ ObjectTypes::WoodElfFletching, "Wood Elf Fletching" },
|
||||
{ ObjectTypes::IksarPottery, "Iksar Pottery" },
|
||||
{ ObjectTypes::Fishing, "Fishing" },
|
||||
{ ObjectTypes::TrollForge, "Troll Forge" },
|
||||
{ ObjectTypes::WoodElfForge, "Wood Elf Forge" },
|
||||
{ ObjectTypes::HalflingForge, "Halfling Forge" },
|
||||
{ ObjectTypes::EruditeForge, "Erudite Forge" },
|
||||
{ ObjectTypes::Merchant, "Merchant" },
|
||||
{ ObjectTypes::FroglokForge, "Froglok Forge" },
|
||||
{ ObjectTypes::Augmenter, "Augmenter" },
|
||||
{ ObjectTypes::Churn, "Churn" },
|
||||
{ ObjectTypes::TransformationMold, "Transformation Mold" },
|
||||
{ ObjectTypes::DetransformationMold, "Detransformation Mold" },
|
||||
{ ObjectTypes::Unattuner, "Unattuner" },
|
||||
{ ObjectTypes::TradeskillBag, "Tradeskill Bag" },
|
||||
{ ObjectTypes::CollectibleBag, "Collectible Bag" },
|
||||
{ ObjectTypes::NoDeposit, "No Deposit" }
|
||||
};
|
||||
|
||||
return object_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetObjectTypeName(int object_type)
|
||||
{
|
||||
if (EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||
@@ -266,11 +527,11 @@ const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||
|
||||
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
|
||||
{
|
||||
if (!EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
||||
@@ -292,17 +553,16 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
||||
|
||||
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
||||
{
|
||||
if (!EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
||||
return std::string();
|
||||
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
||||
}
|
||||
|
||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> emote_type_map = {
|
||||
{ EmoteTypes::Say, "Say" },
|
||||
{ EmoteTypes::Emote, "Emote" },
|
||||
{ EmoteTypes::Shout, "Shout" },
|
||||
{ EmoteTypes::Proximity, "Proximity" }
|
||||
@@ -313,141 +573,9 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||
|
||||
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;
|
||||
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->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();
|
||||
}
|
||||
|
||||
+195
-394
@@ -26,76 +26,6 @@
|
||||
|
||||
#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
|
||||
@@ -130,11 +60,9 @@ namespace EQ
|
||||
using RoF2::invtype::MAIL_SIZE;
|
||||
using RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE;
|
||||
using RoF2::invtype::KRONO_SIZE;
|
||||
using RoF2::invtype::GUILD_BANK_MAIN_SIZE;
|
||||
using RoF2::invtype::GUILD_BANK_DEPOSIT_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;
|
||||
@@ -161,7 +89,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)
|
||||
|
||||
@@ -181,28 +109,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;
|
||||
@@ -216,40 +144,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
|
||||
|
||||
@@ -278,6 +204,19 @@ namespace EQ
|
||||
const size_t SAY_LINK_CLOSER_SIZE = 1;
|
||||
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
|
||||
|
||||
enum StanceType : int {
|
||||
stanceUnknown = 0,
|
||||
stancePassive,
|
||||
stanceBalanced,
|
||||
stanceEfficient,
|
||||
stanceReactive,
|
||||
stanceAggressive,
|
||||
stanceAssist,
|
||||
stanceBurn,
|
||||
stanceEfficient2,
|
||||
stanceBurnAE
|
||||
};
|
||||
|
||||
enum BotSpellIDs : int {
|
||||
Warrior = 3001,
|
||||
Cleric,
|
||||
@@ -328,6 +267,70 @@ namespace EQ
|
||||
Looting
|
||||
};
|
||||
|
||||
enum ObjectTypes : int {
|
||||
SmallBag,
|
||||
LargeBag,
|
||||
Quiver,
|
||||
BeltPouch,
|
||||
WristPouch,
|
||||
Backpack,
|
||||
SmallChest,
|
||||
LargeChest,
|
||||
Bandolier,
|
||||
Medicine,
|
||||
Tinkering,
|
||||
Lexicon,
|
||||
PoisonMaking,
|
||||
Quest,
|
||||
MixingBowl,
|
||||
Baking,
|
||||
Tailoring,
|
||||
Blacksmithing,
|
||||
Fletching,
|
||||
Brewing,
|
||||
JewelryMaking,
|
||||
Pottery,
|
||||
Kiln,
|
||||
KeyMaker,
|
||||
ResearchWIZ,
|
||||
ResearchMAG,
|
||||
ResearchNEC,
|
||||
ResearchENC,
|
||||
Unknown,
|
||||
ResearchPractice,
|
||||
Alchemy,
|
||||
HighElfForge,
|
||||
DarkElfForge,
|
||||
OgreForge,
|
||||
DwarfForge,
|
||||
GnomeForge,
|
||||
BarbarianForge,
|
||||
IksarForge,
|
||||
HumanForgeOne,
|
||||
HumanForgeTwo,
|
||||
HalflingTailoringOne,
|
||||
HalflingTailoringTwo,
|
||||
EruditeTailoring,
|
||||
WoodElfTailoring,
|
||||
WoodElfFletching,
|
||||
IksarPottery,
|
||||
Fishing,
|
||||
TrollForge,
|
||||
WoodElfForge,
|
||||
HalflingForge,
|
||||
EruditeForge,
|
||||
Merchant,
|
||||
FroglokForge,
|
||||
Augmenter,
|
||||
Churn,
|
||||
TransformationMold,
|
||||
DetransformationMold,
|
||||
Unattuner,
|
||||
TradeskillBag,
|
||||
CollectibleBag,
|
||||
NoDeposit
|
||||
};
|
||||
|
||||
enum WeatherTypes : uint8 {
|
||||
None,
|
||||
Raining,
|
||||
@@ -347,18 +350,29 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum EmoteTypes : uint8 {
|
||||
Say,
|
||||
Emote,
|
||||
Shout,
|
||||
Proximity
|
||||
};
|
||||
|
||||
extern const std::map<uint8, std::string>& GetLanguageMap();
|
||||
std::string GetLanguageName(uint8 language_id);
|
||||
const char *GetStanceName(StanceType stance_type);
|
||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||
|
||||
extern const std::map<int, std::string>& GetLanguageMap();
|
||||
std::string GetLanguageName(int language_id);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
||||
std::string GetLDoNThemeName(uint32 theme_id);
|
||||
|
||||
extern const std::map<int8, std::string>& GetFlyModeMap();
|
||||
std::string GetFlyModeName(int8 flymode_id);
|
||||
|
||||
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
|
||||
std::string GetBodyTypeName(bodyType bodytype_id);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetAccountStatusMap();
|
||||
std::string GetAccountStatusName(uint8 account_status);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
||||
std::string GetConsiderLevelName(uint8 consider_level);
|
||||
|
||||
@@ -371,6 +385,9 @@ namespace EQ
|
||||
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
|
||||
std::string GetSpawnAnimationName(uint8 animation_id);
|
||||
|
||||
extern const std::map<int, std::string>& GetObjectTypeMap();
|
||||
std::string GetObjectTypeName(int object_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
|
||||
std::string GetWeatherTypeName(uint8 weather_type);
|
||||
|
||||
@@ -380,11 +397,9 @@ namespace EQ
|
||||
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*/
|
||||
|
||||
@@ -439,6 +454,37 @@ 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,
|
||||
@@ -452,7 +498,7 @@ namespace EQ
|
||||
Raid,
|
||||
Guild
|
||||
};
|
||||
};
|
||||
}; // namespace consent
|
||||
} /*EQEmu*/
|
||||
|
||||
enum ServerLockType : int {
|
||||
@@ -461,6 +507,26 @@ enum ServerLockType : int {
|
||||
Unlock
|
||||
};
|
||||
|
||||
enum AccountStatus : uint8 {
|
||||
Player = 0,
|
||||
Steward = 10,
|
||||
ApprenticeGuide = 20,
|
||||
Guide = 50,
|
||||
QuestTroupe = 80,
|
||||
SeniorGuide = 81,
|
||||
GMTester = 85,
|
||||
EQSupport = 90,
|
||||
GMStaff = 95,
|
||||
GMAdmin = 100,
|
||||
GMLeadAdmin = 150,
|
||||
QuestMaster = 160,
|
||||
GMAreas = 170,
|
||||
GMCoder = 180,
|
||||
GMMgmt = 200,
|
||||
GMImpossible = 250,
|
||||
Max = 255
|
||||
};
|
||||
|
||||
enum Invisibility : uint8 {
|
||||
Visible,
|
||||
Invisible,
|
||||
@@ -486,17 +552,6 @@ enum ConsiderLevel : uint8 {
|
||||
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,
|
||||
@@ -512,6 +567,19 @@ enum ReloadWorld : uint8 {
|
||||
ForceRepop
|
||||
};
|
||||
|
||||
enum BucketComparison : uint8 {
|
||||
BucketEqualTo = 0,
|
||||
BucketNotEqualTo,
|
||||
BucketGreaterThanOrEqualTo,
|
||||
BucketLesserThanOrEqualTo,
|
||||
BucketGreaterThan,
|
||||
BucketLesserThan,
|
||||
BucketIsAny,
|
||||
BucketIsNotAny,
|
||||
BucketIsBetween,
|
||||
BucketIsNotBetween
|
||||
};
|
||||
|
||||
enum class EntityFilterType {
|
||||
All,
|
||||
Bots,
|
||||
@@ -525,271 +593,4 @@ enum class ApplySpellType {
|
||||
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*/
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-42
@@ -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), // Used by eqstr_us.txt 8066, 8068, 8069
|
||||
N(OP_Animation),
|
||||
N(OP_AnnoyingZoneUnknown),
|
||||
N(OP_ApplyPoison),
|
||||
@@ -62,12 +62,10 @@ 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),
|
||||
@@ -77,7 +75,6 @@ N(OP_CashReward),
|
||||
N(OP_CastSpell),
|
||||
N(OP_ChangeSize),
|
||||
N(OP_ChannelMessage),
|
||||
N(OP_ChangePetName),
|
||||
N(OP_CharacterCreate),
|
||||
N(OP_CharacterCreateRequest),
|
||||
N(OP_CharInventory),
|
||||
@@ -163,7 +160,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 +227,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 +238,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,15 +262,12 @@ 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),
|
||||
@@ -342,7 +316,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),
|
||||
@@ -405,8 +378,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 +398,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 +421,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),
|
||||
@@ -518,11 +486,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),
|
||||
@@ -541,7 +504,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),
|
||||
@@ -566,7 +528,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),
|
||||
@@ -574,7 +535,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),
|
||||
|
||||
+156
-207
@@ -23,59 +23,61 @@
|
||||
#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_AntiCheat 51 // sent by the client randomly telling the server how long since last action has occured
|
||||
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
|
||||
#define AT_Offline 53 // Offline mode
|
||||
|
||||
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
||||
|
||||
// animations for AT_Anim
|
||||
#define ANIM_FREEZE 102
|
||||
#define ANIM_STAND 0x64
|
||||
#define ANIM_SIT 0x6e
|
||||
#define ANIM_CROUCH 0x6f
|
||||
#define ANIM_DEATH 0x73
|
||||
#define ANIM_LOOT 0x69
|
||||
|
||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||
|
||||
@@ -684,53 +686,6 @@ namespace Zones {
|
||||
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -758,10 +713,10 @@ typedef enum {
|
||||
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
|
||||
FilterUnknown25 = 25,
|
||||
FilterUnknown26 = 26,
|
||||
FilterUnknown27 = 27,
|
||||
FilterUnknown28 = 28,
|
||||
_FilterCount
|
||||
} eqFilterType;
|
||||
|
||||
@@ -772,47 +727,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;
|
||||
@@ -974,6 +949,43 @@ 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 LDoNThemes {
|
||||
Unused = 0,
|
||||
GUK,
|
||||
MIR,
|
||||
MMC,
|
||||
RUJ,
|
||||
TAK
|
||||
};
|
||||
|
||||
enum LDoNThemeBits {
|
||||
UnusedBit = 0,
|
||||
GUKBit = 1,
|
||||
MIRBit = 2,
|
||||
MMCBit = 4,
|
||||
RUJBit = 8,
|
||||
TAKBit = 16
|
||||
};
|
||||
|
||||
enum StartZoneIndex {
|
||||
Odus = 0,
|
||||
Qeynos,
|
||||
@@ -1033,67 +1045,4 @@ enum ResurrectionActions
|
||||
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*/
|
||||
|
||||
+28
-36
@@ -47,7 +47,6 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
ClientUnknown::constants::EXPANSION_BIT,
|
||||
ClientUnknown::constants::EXPANSIONS_MASK,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL,
|
||||
ClientUnknown::INULL
|
||||
),
|
||||
/*[ClientVersion::Client62] =*/
|
||||
@@ -56,7 +55,6 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
Client62::constants::EXPANSION_BIT,
|
||||
Client62::constants::EXPANSIONS_MASK,
|
||||
Client62::INULL,
|
||||
Client62::INULL,
|
||||
Client62::INULL
|
||||
),
|
||||
/*[ClientVersion::Titanium] =*/
|
||||
@@ -65,8 +63,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
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(
|
||||
@@ -74,8 +71,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
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(
|
||||
@@ -83,8 +79,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
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(
|
||||
@@ -92,8 +87,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
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(
|
||||
@@ -101,8 +95,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
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(
|
||||
@@ -110,8 +103,7 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
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
|
||||
)
|
||||
};
|
||||
|
||||
@@ -173,7 +165,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, ClientUnknown::INULL, ClientUnknown::INULL,
|
||||
ClientUnknown::INULL, ClientUnknown::INULL, ClientUnknown::INULL
|
||||
ClientUnknown::INULL
|
||||
),
|
||||
|
||||
ClientUnknown::INULL,
|
||||
@@ -200,7 +192,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, Client62::INULL, Client62::INULL,
|
||||
Client62::INULL, Client62::INULL, Client62::INULL
|
||||
Client62::INULL
|
||||
),
|
||||
|
||||
Client62::INULL,
|
||||
@@ -227,7 +219,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
Titanium::invtype::VIEW_MOD_PC_SIZE, Titanium::invtype::VIEW_MOD_BANK_SIZE, Titanium::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
Titanium::invtype::VIEW_MOD_LIMBO_SIZE, Titanium::invtype::ALT_STORAGE_SIZE, Titanium::invtype::ARCHIVED_SIZE,
|
||||
Titanium::INULL, Titanium::INULL, Titanium::INULL,
|
||||
Titanium::INULL, Titanium::INULL, Titanium::invtype::OTHER_SIZE
|
||||
Titanium::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
Titanium::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -254,7 +246,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoF::invtype::VIEW_MOD_PC_SIZE, SoF::invtype::VIEW_MOD_BANK_SIZE, SoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
SoF::invtype::VIEW_MOD_LIMBO_SIZE, SoF::invtype::ALT_STORAGE_SIZE, SoF::invtype::ARCHIVED_SIZE,
|
||||
SoF::INULL, SoF::INULL, SoF::INULL,
|
||||
SoF::INULL, SoF::INULL, SoF::invtype::OTHER_SIZE
|
||||
SoF::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
SoF::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -281,7 +273,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoD::invtype::VIEW_MOD_PC_SIZE, SoD::invtype::VIEW_MOD_BANK_SIZE, SoD::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
SoD::invtype::VIEW_MOD_LIMBO_SIZE, SoD::invtype::ALT_STORAGE_SIZE, SoD::invtype::ARCHIVED_SIZE,
|
||||
SoD::INULL, SoD::INULL, SoD::INULL,
|
||||
SoD::INULL, SoD::INULL, SoD::invtype::OTHER_SIZE
|
||||
SoD::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
SoD::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -308,7 +300,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
UF::invtype::VIEW_MOD_PC_SIZE, UF::invtype::VIEW_MOD_BANK_SIZE, UF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
UF::invtype::VIEW_MOD_LIMBO_SIZE, UF::invtype::ALT_STORAGE_SIZE, UF::invtype::ARCHIVED_SIZE,
|
||||
UF::INULL, UF::INULL, UF::INULL,
|
||||
UF::INULL, UF::INULL, UF::invtype::OTHER_SIZE
|
||||
UF::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
UF::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -335,7 +327,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF::invtype::VIEW_MOD_PC_SIZE, RoF::invtype::VIEW_MOD_BANK_SIZE, RoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
RoF::invtype::VIEW_MOD_LIMBO_SIZE, RoF::invtype::ALT_STORAGE_SIZE, RoF::invtype::ARCHIVED_SIZE,
|
||||
RoF::invtype::MAIL_SIZE, RoF::invtype::GUILD_TROPHY_TRIBUTE_SIZE, RoF::INULL,
|
||||
RoF::INULL,RoF::INULL,RoF::invtype::OTHER_SIZE
|
||||
RoF::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
RoF::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -362,7 +354,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::invtype::ALT_STORAGE_SIZE, RoF2::invtype::ARCHIVED_SIZE,
|
||||
RoF2::invtype::MAIL_SIZE, RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE, RoF2::invtype::KRONO_SIZE,
|
||||
RoF2::invtype::GUILD_BANK_MAIN_SIZE,RoF2::invtype::GUILD_BANK_DEPOSIT_SIZE, RoF2::invtype::OTHER_SIZE
|
||||
RoF2::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
RoF2::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -389,7 +381,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,
|
||||
EntityLimits::NPC::INULL, EntityLimits::NPC::INULL,EntityLimits::NPC::INULL
|
||||
EntityLimits::NPC::INULL
|
||||
),
|
||||
|
||||
EntityLimits::NPC::INULL,
|
||||
@@ -416,7 +408,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL,
|
||||
EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL, EntityLimits::NPCMerchant::INULL
|
||||
EntityLimits::NPCMerchant::INULL
|
||||
),
|
||||
|
||||
EntityLimits::NPCMerchant::INULL,
|
||||
@@ -443,7 +435,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL,
|
||||
EntityLimits::Merc::INULL, EntityLimits::Merc::INULL, EntityLimits::Merc::INULL
|
||||
EntityLimits::Merc::INULL
|
||||
),
|
||||
|
||||
EntityLimits::Merc::INULL,
|
||||
@@ -470,7 +462,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL,
|
||||
EntityLimits::Bot::INULL, EntityLimits::Bot::INULL, EntityLimits::Bot::INULL
|
||||
EntityLimits::Bot::INULL
|
||||
),
|
||||
|
||||
EntityLimits::Bot::invslot::EQUIPMENT_BITMASK,
|
||||
@@ -497,7 +489,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL,
|
||||
EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL, EntityLimits::ClientPet::INULL
|
||||
EntityLimits::ClientPet::INULL
|
||||
),
|
||||
|
||||
EntityLimits::ClientPet::INULL,
|
||||
@@ -524,7 +516,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL,
|
||||
EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL, EntityLimits::NPCPet::INULL
|
||||
EntityLimits::NPCPet::INULL
|
||||
),
|
||||
|
||||
EntityLimits::NPCPet::INULL,
|
||||
@@ -551,7 +543,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL,
|
||||
EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL, EntityLimits::MercPet::INULL
|
||||
EntityLimits::MercPet::INULL
|
||||
),
|
||||
|
||||
EntityLimits::MercPet::INULL,
|
||||
@@ -578,7 +570,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL,
|
||||
EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL, EntityLimits::BotPet::INULL
|
||||
EntityLimits::BotPet::INULL
|
||||
),
|
||||
|
||||
EntityLimits::BotPet::INULL,
|
||||
@@ -605,7 +597,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
Titanium::invtype::VIEW_MOD_PC_SIZE, Titanium::invtype::VIEW_MOD_BANK_SIZE, Titanium::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
Titanium::invtype::VIEW_MOD_LIMBO_SIZE, Titanium::INULL, Titanium::INULL,
|
||||
Titanium::INULL, Titanium::INULL, Titanium::INULL,
|
||||
Titanium::INULL, Titanium::INULL, Titanium::INULL
|
||||
Titanium::INULL
|
||||
),
|
||||
|
||||
Titanium::INULL,
|
||||
@@ -632,7 +624,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoF::invtype::VIEW_MOD_PC_SIZE, SoF::invtype::VIEW_MOD_BANK_SIZE, SoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
SoF::invtype::VIEW_MOD_LIMBO_SIZE, SoF::INULL, SoF::INULL,
|
||||
SoF::INULL, SoF::INULL, SoF::INULL,
|
||||
SoF::INULL, SoF::INULL, SoF::INULL
|
||||
SoF::INULL
|
||||
),
|
||||
|
||||
SoF::INULL,
|
||||
@@ -659,7 +651,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
SoD::invtype::VIEW_MOD_PC_SIZE, SoD::invtype::VIEW_MOD_BANK_SIZE, SoD::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
SoD::invtype::VIEW_MOD_LIMBO_SIZE, SoD::INULL, SoD::INULL,
|
||||
SoD::INULL, SoD::INULL, SoD::INULL,
|
||||
SoD::INULL, SoD::INULL, SoD::INULL
|
||||
SoD::INULL
|
||||
),
|
||||
|
||||
SoD::INULL,
|
||||
@@ -686,7 +678,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
UF::invtype::VIEW_MOD_PC_SIZE, UF::invtype::VIEW_MOD_BANK_SIZE, UF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
UF::invtype::VIEW_MOD_LIMBO_SIZE, UF::INULL, UF::INULL,
|
||||
UF::INULL, UF::INULL, UF::INULL,
|
||||
UF::INULL, UF::INULL, UF::INULL
|
||||
UF::INULL
|
||||
),
|
||||
|
||||
UF::INULL,
|
||||
@@ -713,7 +705,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF::invtype::VIEW_MOD_PC_SIZE, RoF::invtype::VIEW_MOD_BANK_SIZE, RoF::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
RoF::invtype::VIEW_MOD_LIMBO_SIZE, RoF::INULL, RoF::INULL,
|
||||
RoF::INULL, RoF::INULL, RoF::INULL,
|
||||
RoF::INULL, RoF::INULL, RoF::INULL
|
||||
RoF::INULL
|
||||
),
|
||||
|
||||
RoF::INULL,
|
||||
@@ -740,7 +732,7 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL
|
||||
RoF2::INULL
|
||||
),
|
||||
|
||||
RoF2::INULL,
|
||||
|
||||
+6
-9
@@ -42,7 +42,6 @@ namespace EQ
|
||||
uint32 ExpansionsMask;
|
||||
int16 CharacterCreationLimit;
|
||||
size_t SayLinkBodySize;
|
||||
uint32 BazaarTraderLimit;
|
||||
|
||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||
LookupEntry(
|
||||
@@ -50,15 +49,13 @@ namespace EQ
|
||||
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)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -87,7 +84,7 @@ namespace EQ
|
||||
int16 ViewMODPC, ViewMODBank, ViewMODSharedBank;
|
||||
int16 ViewMODLimbo, AltStorage, Archived;
|
||||
int16 Mail, GuildTrophyTribute, Krono;
|
||||
int16 GuildBankMain,GuildBankDeposit, Other;
|
||||
int16 Other;
|
||||
|
||||
InventoryTypeSize_Struct(
|
||||
int16 Possessions, int16 Bank, int16 SharedBank,
|
||||
@@ -98,7 +95,7 @@ namespace EQ
|
||||
int16 ViewMODPC, int16 ViewMODBank, int16 ViewMODSharedBank,
|
||||
int16 ViewMODLimbo, int16 AltStorage, int16 Archived,
|
||||
int16 Mail, int16 GuildTrophyTribute, int16 Krono,
|
||||
int16 GuildBankMain,int16 GuildBankDeposit, int16 Other
|
||||
int16 Other
|
||||
) :
|
||||
Possessions(Possessions), Bank(Bank), SharedBank(SharedBank),
|
||||
Trade(Trade), World(World), Limbo(Limbo),
|
||||
@@ -108,7 +105,7 @@ namespace EQ
|
||||
ViewMODPC(ViewMODPC), ViewMODBank(ViewMODBank), ViewMODSharedBank(ViewMODSharedBank),
|
||||
ViewMODLimbo(ViewMODLimbo), AltStorage(AltStorage), Archived(Archived),
|
||||
Mail(Mail), GuildTrophyTribute(GuildTrophyTribute), Krono(Krono),
|
||||
GuildBankMain(GuildBankMain), GuildBankDeposit(GuildBankDeposit), Other(Other)
|
||||
Other(Other)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
+138
-1
@@ -236,6 +236,26 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
|
||||
return size+OpCodeBytes;
|
||||
}
|
||||
|
||||
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
|
||||
: BasePacket(buf, len),
|
||||
opcode(op)
|
||||
{
|
||||
|
||||
uint32 offset;
|
||||
opcode=ntohs(*(const uint16 *)buf);
|
||||
offset=2;
|
||||
|
||||
if (len-offset) {
|
||||
pBuffer= new unsigned char[len-offset];
|
||||
memcpy(pBuffer,buf+offset,len-offset);
|
||||
size=len-offset;
|
||||
} else {
|
||||
pBuffer=nullptr;
|
||||
size=0;
|
||||
}
|
||||
OpMgr=&RawOpcodeManager;
|
||||
}*/
|
||||
|
||||
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
|
||||
{
|
||||
bool result=false;
|
||||
@@ -267,6 +287,74 @@ bool result=false;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
this is the code to do app-layer combining, instead of protocol layer.
|
||||
this was taken out due to complex interactions with the opcode manager,
|
||||
and will require a bit more thinking (likely moving into EQStream) to
|
||||
get running again... but might be a good thing some day.
|
||||
|
||||
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
|
||||
{
|
||||
uint32 newsize=0, offset=0;
|
||||
unsigned char *tmpbuffer=nullptr;
|
||||
|
||||
if (opcode!=OP_AppCombined) {
|
||||
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
|
||||
tmpbuffer=new unsigned char [newsize];
|
||||
offset=0;
|
||||
if (size>254) {
|
||||
tmpbuffer[offset++]=0xff;
|
||||
*(uint16 *)(tmpbuffer+offset)=htons(size);
|
||||
offset+=1;
|
||||
} else {
|
||||
tmpbuffer[offset++]=size;
|
||||
}
|
||||
offset+=serialize(tmpbuffer+offset);
|
||||
} else {
|
||||
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
|
||||
tmpbuffer=new unsigned char [newsize];
|
||||
memcpy(tmpbuffer,pBuffer,size);
|
||||
offset=size;
|
||||
}
|
||||
|
||||
if (rhs->size>254) {
|
||||
tmpbuffer[offset++]=0xff;
|
||||
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
|
||||
offset+=1;
|
||||
} else {
|
||||
tmpbuffer[offset++]=rhs->size;
|
||||
}
|
||||
offset+=rhs->serialize(tmpbuffer+offset);
|
||||
|
||||
size=offset;
|
||||
opcode=OP_AppCombined;
|
||||
|
||||
delete[] pBuffer;
|
||||
pBuffer=tmpbuffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
|
||||
{
|
||||
bool valid=false;
|
||||
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
|
||||
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
|
||||
valid=true;
|
||||
} else {
|
||||
uint16 comp_crc=CRC16(buffer,length-2,Key);
|
||||
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
|
||||
#ifdef EQN_DEBUG
|
||||
if (packet_crc && comp_crc != packet_crc) {
|
||||
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
|
||||
}
|
||||
#endif
|
||||
valid = (!packet_crc || comp_crc == packet_crc);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
|
||||
{
|
||||
uint32 newlen=0;
|
||||
@@ -315,6 +403,55 @@ uint32 flag_offset=1,newlength;
|
||||
return newlength;
|
||||
}
|
||||
|
||||
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
|
||||
{
|
||||
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
|
||||
int Key=DecodeKey;
|
||||
unsigned char *test=(unsigned char *)malloc(size);
|
||||
buffer+=2;
|
||||
size-=2;
|
||||
|
||||
int i;
|
||||
for (i = 0 ; i+4 <= size ; i+=4)
|
||||
{
|
||||
int pt = (*(int*)&buffer[i])^(Key);
|
||||
Key = (*(int*)&buffer[i]);
|
||||
*(int*)&test[i]=pt;
|
||||
}
|
||||
unsigned char KC=Key&0xFF;
|
||||
for ( ; i < size ; i++)
|
||||
{
|
||||
test[i]=buffer[i]^KC;
|
||||
}
|
||||
memcpy(buffer,test,size);
|
||||
free(test);
|
||||
}
|
||||
}
|
||||
|
||||
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
|
||||
{
|
||||
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
|
||||
int Key=EncodeKey;
|
||||
char *test=(char*)malloc(size);
|
||||
int i;
|
||||
buffer+=2;
|
||||
size-=2;
|
||||
for ( i = 0 ; i+4 <= size ; i+=4)
|
||||
{
|
||||
int pt = (*(int*)&buffer[i])^(Key);
|
||||
Key = pt;
|
||||
*(int*)&test[i]=pt;
|
||||
}
|
||||
unsigned char KC=Key&0xFF;
|
||||
for ( ; i < size ; i++)
|
||||
{
|
||||
test[i]=buffer[i]^KC;
|
||||
}
|
||||
memcpy(buffer,test,size);
|
||||
free(test);
|
||||
}
|
||||
}
|
||||
|
||||
EQApplicationPacket *EQApplicationPacket::Copy() const {
|
||||
return(new EQApplicationPacket(*this));
|
||||
}
|
||||
@@ -378,4 +515,4 @@ std::string DumpPacketToString(const EQApplicationPacket* app){
|
||||
std::ostringstream out;
|
||||
out << DumpPacketHexToString(app->pBuffer, app->size);
|
||||
return out.str();
|
||||
}
|
||||
}
|
||||
@@ -80,8 +80,11 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
|
||||
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
|
||||
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
|
||||
|
||||
uint16 GetRawOpcode() const { return(opcode); }
|
||||
|
||||
|
||||
+288
-1220
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
|
||||
EQDB EQDB::s_EQDB;
|
||||
|
||||
EQDB::EQDB() {
|
||||
}
|
||||
|
||||
unsigned int EQDB::field_count() {
|
||||
return mysql_field_count(mysql_ref);
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
|
||||
//this is the main object exported to perl.
|
||||
class EQDB {
|
||||
EQDB() = default;
|
||||
EQDB();
|
||||
public:
|
||||
static EQDB *Singleton() { return(&s_EQDB); }
|
||||
|
||||
|
||||
+32
-136
@@ -20,12 +20,9 @@
|
||||
#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,13 +34,13 @@ 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 = Strings::ToInt(_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 = Strings::ToInt(_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();
|
||||
@@ -66,7 +63,7 @@ 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 = Strings::ToInt(_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();
|
||||
|
||||
@@ -88,22 +85,16 @@ void EQEmuConfig::parse_config()
|
||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||
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 = Strings::ToInt(_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 = Strings::ToInt(_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 = Strings::ToInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||
WorldHTTPEnabled = false;
|
||||
|
||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||
@@ -114,12 +105,13 @@ void EQEmuConfig::parse_config()
|
||||
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 = Strings::ToInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||
MailPort = Strings::ToInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
/**
|
||||
* Database
|
||||
@@ -127,7 +119,7 @@ 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 = Strings::ToInt(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||
|
||||
/**
|
||||
@@ -136,26 +128,24 @@ void EQEmuConfig::parse_config()
|
||||
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());
|
||||
ContentDbPort = Strings::ToInt(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||
|
||||
/**
|
||||
* QS
|
||||
*/
|
||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString());
|
||||
QSDatabasePort = Strings::ToInt(_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 = Strings::ToInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||
ZonePortLow = Strings::ToInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||
ZonePortHigh = Strings::ToInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||
|
||||
/**
|
||||
* Files
|
||||
@@ -173,7 +163,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 +175,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 = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||
#ifdef WIN32
|
||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||
#else
|
||||
@@ -251,16 +240,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 +356,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 +386,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-14
@@ -62,6 +62,14 @@ class EQEmuConfig
|
||||
std::string SharedKey;
|
||||
bool DisableConfigChecks;
|
||||
|
||||
// From <chatserver/>
|
||||
std::string ChatHost;
|
||||
uint16 ChatPort;
|
||||
|
||||
// From <mailserver/>
|
||||
std::string MailHost;
|
||||
uint16 MailPort;
|
||||
|
||||
// From <database/>
|
||||
std::string DatabaseHost;
|
||||
std::string DatabaseUsername;
|
||||
@@ -81,9 +89,7 @@ class EQEmuConfig
|
||||
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 +103,6 @@ class EQEmuConfig
|
||||
std::string PluginDir;
|
||||
std::string LuaModuleDir;
|
||||
std::string PatchDir;
|
||||
std::string OpcodeDir;
|
||||
std::string SharedMemDir;
|
||||
std::string LogDir;
|
||||
|
||||
@@ -115,20 +120,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;
|
||||
@@ -139,9 +136,9 @@ class EQEmuConfig
|
||||
{
|
||||
|
||||
}
|
||||
virtual ~EQEmuConfig() {}
|
||||
|
||||
public:
|
||||
virtual ~EQEmuConfig() {}
|
||||
|
||||
// Produce a const singleton
|
||||
static const EQEmuConfig *get()
|
||||
@@ -150,6 +147,12 @@ 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 = "")
|
||||
{
|
||||
@@ -187,7 +190,6 @@ class EQEmuConfig
|
||||
}
|
||||
|
||||
void Dump() const;
|
||||
void CheckUcsConfigConversion();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+31
-121
@@ -25,8 +25,6 @@
|
||||
#include "repositories/discord_webhooks_repository.h"
|
||||
#include "repositories/logsys_categories_repository.h"
|
||||
#include "termcolor/rang.hpp"
|
||||
#include "path_manager.h"
|
||||
#include "file.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -87,7 +85,6 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
* Set Defaults
|
||||
*/
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
@@ -103,17 +100,13 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::EqTime].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::EqTime].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::NpcHandin].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::NpcHandin].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* RFC 5424
|
||||
*/
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
/**
|
||||
* Set Category enabled status on defaults
|
||||
@@ -194,10 +187,9 @@ void EQEmuLogSys::ProcessLogWrite(
|
||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
||||
{
|
||||
switch (log_category) {
|
||||
case Logs::Crash:
|
||||
case Logs::Error:
|
||||
case Logs::MySQLError:
|
||||
case Logs::QuestErrors:
|
||||
case Logs::Error:
|
||||
return Chat::Red;
|
||||
case Logs::MySQLQuery:
|
||||
case Logs::Debug:
|
||||
@@ -207,6 +199,8 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
||||
case Logs::Commands:
|
||||
case Logs::Mercenaries:
|
||||
return Chat::Magenta;
|
||||
case Logs::Crash:
|
||||
return Chat::Red;
|
||||
default:
|
||||
return Chat::Yellow;
|
||||
}
|
||||
@@ -226,7 +220,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
||||
int line
|
||||
)
|
||||
{
|
||||
bool is_error = (
|
||||
bool is_error = (
|
||||
log_category == Logs::LogCategory::Error ||
|
||||
log_category == Logs::LogCategory::MySQLError ||
|
||||
log_category == Logs::LogCategory::Crash ||
|
||||
@@ -268,7 +262,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
||||
}
|
||||
|
||||
if (log_category == Logs::LogCategory::MySQLQuery) {
|
||||
auto s = Strings::Split(message, "--");
|
||||
auto s = Strings::Split(message, "--");
|
||||
if (s.size() > 1) {
|
||||
std::string query = Strings::Trim(s[0]);
|
||||
std::string meta = Strings::Trim(s[1]);
|
||||
@@ -304,76 +298,19 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
||||
}
|
||||
}
|
||||
|
||||
// color matching in []
|
||||
// ex: [<red>variable] would produce [variable] with red inside brackets
|
||||
std::map<std::string, rang::fgB> colors = {
|
||||
{"<black>", rang::fgB::black},
|
||||
{"<green>", rang::fgB::green},
|
||||
{"<yellow>", rang::fgB::yellow},
|
||||
{"<blue>", rang::fgB::blue},
|
||||
{"<magenta>", rang::fgB::magenta},
|
||||
{"<cyan>", rang::fgB::cyan},
|
||||
{"<gray>", rang::fgB::gray},
|
||||
{"<red>", rang::fgB::red},
|
||||
};
|
||||
|
||||
bool match_color = false;
|
||||
for (auto &c: colors) {
|
||||
if (Strings::Contains(e, c.first)) {
|
||||
e = Strings::Replace(e, c.first, "");
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< c.second
|
||||
<< e
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< "] ";
|
||||
match_color = true;
|
||||
}
|
||||
if (!is_upper) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< rang::fgB::yellow
|
||||
<< e
|
||||
<< rang::fgB::gray
|
||||
<< "] "
|
||||
;
|
||||
}
|
||||
|
||||
// string match to colors
|
||||
std::map<std::string, rang::fgB> matches = {
|
||||
{"missing", rang::fgB::red},
|
||||
{"error", rang::fgB::red},
|
||||
{"ok", rang::fgB::green},
|
||||
};
|
||||
|
||||
for (auto &c: matches) {
|
||||
if (Strings::Contains(e, c.first)) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< c.second
|
||||
<< e
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< "] ";
|
||||
match_color = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't match a color in either the string matching or
|
||||
// the color tag matching, we default to yellow inside brackets
|
||||
// if uppercase, does not get colored
|
||||
if (!match_color) {
|
||||
if (!is_upper) {
|
||||
(!is_error ? std::cout : std::cerr)
|
||||
<< rang::fgB::gray
|
||||
<< "["
|
||||
<< rang::style::bold
|
||||
<< rang::fgB::yellow
|
||||
<< e
|
||||
<< rang::style::reset
|
||||
<< rang::fgB::gray
|
||||
<< "] ";
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||
}
|
||||
else {
|
||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -453,8 +390,6 @@ void EQEmuLogSys::Out(
|
||||
// remove this when we remove all legacy logs
|
||||
bool ignore_log_legacy_format = (
|
||||
log_category == Logs::Netcode ||
|
||||
log_category == Logs::MySQLQuery ||
|
||||
log_category == Logs::MySQLError ||
|
||||
log_category == Logs::PacketServerClient ||
|
||||
log_category == Logs::PacketClientServer ||
|
||||
log_category == Logs::PacketServerToServer
|
||||
@@ -537,11 +472,6 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
{
|
||||
EQEmuLogSys::CloseFileLogs();
|
||||
|
||||
if (!File::Exists(path.GetLogPath())) {
|
||||
LogInfo("Logs directory not found, creating [{}]", path.GetLogPath());
|
||||
File::Makedir(path.GetLogPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
|
||||
*/
|
||||
@@ -594,15 +524,11 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
||||
*/
|
||||
void EQEmuLogSys::SilenceConsoleLogging()
|
||||
{
|
||||
std::copy(std::begin(log_settings), std::end(log_settings), std::begin(pre_silence_settings));
|
||||
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = 0;
|
||||
log_settings[log_index].is_category_enabled = 0;
|
||||
}
|
||||
|
||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::MySQLError);
|
||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::Error);
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
}
|
||||
|
||||
@@ -611,7 +537,10 @@ void EQEmuLogSys::SilenceConsoleLogging()
|
||||
*/
|
||||
void EQEmuLogSys::EnableConsoleLogging()
|
||||
{
|
||||
std::copy(std::begin(pre_silence_settings), std::end(pre_silence_settings), std::begin(log_settings));
|
||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||
log_settings[log_index].log_to_console = Logs::General;
|
||||
log_settings[log_index].is_category_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
@@ -663,9 +592,6 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
}
|
||||
|
||||
// Auto inject categories that don't exist in the database...
|
||||
|
||||
std::vector<LogsysCategoriesRepository::LogsysCategories> db_categories_to_add{};
|
||||
|
||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||
|
||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||
@@ -680,7 +606,11 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
}
|
||||
|
||||
if (is_missing_in_database && !is_deprecated_category) {
|
||||
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
|
||||
LogInfo(
|
||||
"Automatically adding new log category [{}] ({})",
|
||||
Logs::LogCategoryName[i],
|
||||
i
|
||||
);
|
||||
|
||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||
new_category.log_category_id = i;
|
||||
@@ -689,14 +619,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
||||
new_category.log_to_file = log_settings[i].log_to_file;
|
||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
||||
db_categories_to_add.emplace_back(new_category);
|
||||
}
|
||||
}
|
||||
|
||||
if (!db_categories_to_add.empty()) {
|
||||
LogsysCategoriesRepository::ReplaceMany(*m_database, db_categories_to_add);
|
||||
LoadLogDatabaseSettings();
|
||||
return this;
|
||||
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
|
||||
}
|
||||
}
|
||||
|
||||
LogInfo("Loaded [{}] log categories", categories.size());
|
||||
@@ -713,8 +638,6 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_file = static_cast<uint8>(Logs::General);
|
||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -819,16 +742,3 @@ EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
|
||||
return this;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::DisableMySQLErrorLogs()
|
||||
{
|
||||
log_settings[Logs::MySQLError].log_to_file = 0;
|
||||
log_settings[Logs::MySQLError].log_to_console = 0;
|
||||
log_settings[Logs::MySQLError].log_to_gmsay = 0;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::EnableMySQLErrorLogs()
|
||||
{
|
||||
log_settings[Logs::MySQLError].log_to_file = 1;
|
||||
log_settings[Logs::MySQLError].log_to_console = 1;
|
||||
log_settings[Logs::MySQLError].log_to_gmsay = 1;
|
||||
}
|
||||
|
||||
@@ -137,18 +137,6 @@ namespace Logs {
|
||||
Bugs,
|
||||
QuestErrors,
|
||||
PlayerEvents,
|
||||
DataBuckets,
|
||||
Zoning,
|
||||
EqTime,
|
||||
Corpses,
|
||||
XTargets,
|
||||
EvolveItem,
|
||||
PositionUpdate,
|
||||
KSM,
|
||||
BotSettings,
|
||||
BotSpellChecks,
|
||||
BotSpellTypeChecks,
|
||||
NpcHandin,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -245,18 +233,6 @@ namespace Logs {
|
||||
"Bugs",
|
||||
"QuestErrors",
|
||||
"PlayerEvents",
|
||||
"DataBuckets",
|
||||
"Zoning",
|
||||
"EqTime",
|
||||
"Corpses",
|
||||
"XTargets",
|
||||
"EvolveItem",
|
||||
"PositionUpdate",
|
||||
"KSM", // Kernel Samepage Merging
|
||||
"Bot Settings",
|
||||
"Bot Spell Checks",
|
||||
"Bot Spell Type Checks",
|
||||
"NpcHandin"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -348,9 +324,6 @@ public:
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
// temporary bucket to re-load after silencing
|
||||
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
struct LogEnabled {
|
||||
bool log_to_file_enabled;
|
||||
bool log_to_console_enabled;
|
||||
@@ -401,9 +374,6 @@ public:
|
||||
[[nodiscard]] const std::string &GetLogPath() const;
|
||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
||||
|
||||
void DisableMySQLErrorLogs();
|
||||
void EnableMySQLErrorLogs();
|
||||
|
||||
private:
|
||||
|
||||
// reference to database
|
||||
|
||||
@@ -131,16 +131,6 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEvolveItem(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::EvolveItem))\
|
||||
OutF(LogSys, Logs::General, Logs::EvolveItem, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEvolveItemDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EvolveItem))\
|
||||
OutF(LogSys, Logs::Detail, Logs::EvolveItem, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogGuilds(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Guilds))\
|
||||
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
@@ -804,116 +794,6 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDataBuckets(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::DataBuckets))\
|
||||
OutF(LogSys, Logs::General, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogDataBucketsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DataBuckets))\
|
||||
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoning(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::General, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoningDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEqTime(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::EqTime))\
|
||||
OutF(LogSys, Logs::General, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogEqTimeDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::EqTime))\
|
||||
OutF(LogSys, Logs::Detail, Logs::EqTime, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCorpses(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Corpses))\
|
||||
OutF(LogSys, Logs::General, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogCorpsesDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Corpses))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogXTargets(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::XTargets))\
|
||||
OutF(LogSys, Logs::General, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogXTargetsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::XTargets))\
|
||||
OutF(LogSys, Logs::Detail, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPositionUpdate(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::PositionUpdate))\
|
||||
OutF(LogSys, Logs::General, Logs::PositionUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPositionUpdateDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PositionUpdate))\
|
||||
OutF(LogSys, Logs::Detail, Logs::PositionUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define LogKSM(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::KSM))\
|
||||
OutF(LogSys, Logs::General, Logs::KSM, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogKSMDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::KSM))\
|
||||
OutF(LogSys, Logs::Detail, Logs::KSM, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBotSettings(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSettings))\
|
||||
OutF(LogSys, Logs::General, Logs::BotSettings, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBotSettingsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSettings))\
|
||||
OutF(LogSys, Logs::Detail, Logs::BotSettings, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBotSpellChecks(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSpellChecks))\
|
||||
OutF(LogSys, Logs::General, Logs::BotSpellChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBotSpellChecksDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSpellChecks))\
|
||||
OutF(LogSys, Logs::Detail, Logs::BotSpellChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBotSpellTypeChecks(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::BotSpellTypeChecks))\
|
||||
OutF(LogSys, Logs::General, Logs::BotSpellTypeChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogBotSpellTypeChecksDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::BotSpellTypeChecks))\
|
||||
OutF(LogSys, Logs::Detail, Logs::BotSpellTypeChecks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNpcHandin(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::NpcHandin))\
|
||||
OutF(LogSys, Logs::General, Logs::NpcHandin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogNpcHandinDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::NpcHandin))\
|
||||
OutF(LogSys, Logs::Detail, Logs::NpcHandin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
+12
-52
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -38,7 +38,7 @@ namespace EQ
|
||||
_running = true;
|
||||
|
||||
for (size_t i = 0; i < threads; ++i) {
|
||||
_threads.emplace_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
||||
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -714,18 +714,6 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
||||
h.charges > 1 ? fmt::format(" Charges: {}", h.charges) : "",
|
||||
h.attuned ? " (Attuned)" : ""
|
||||
);
|
||||
|
||||
for (int i = 0; i < h.augment_ids.size(); i++) {
|
||||
if (!Strings::EqualFold(h.augment_names[i], "None")) {
|
||||
const uint8 slot_id = (i + 1);
|
||||
handin_items_info += fmt::format(
|
||||
"Augment {}: {} ({})\n",
|
||||
slot_id,
|
||||
h.augment_names[i],
|
||||
h.augment_ids[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -739,18 +727,6 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
||||
r.charges > 1 ? fmt::format(" Charges: {}", r.charges) : "",
|
||||
r.attuned ? " (Attuned)" : ""
|
||||
);
|
||||
|
||||
for (int i = 0; i < r.augment_ids.size(); i++) {
|
||||
if (!Strings::EqualFold(r.augment_names[i], "None")) {
|
||||
const uint8 slot_id = (i + 1);
|
||||
return_items_info += fmt::format(
|
||||
"Augment {}: {} ({})\n",
|
||||
slot_id,
|
||||
r.augment_names[i],
|
||||
r.augment_ids[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,36 +789,50 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
||||
);
|
||||
}
|
||||
|
||||
std::string npc_info = fmt::format(
|
||||
"{} ({})\n",
|
||||
e.npc_name,
|
||||
e.npc_id
|
||||
);
|
||||
|
||||
npc_info += fmt::format(
|
||||
"Is Quest Handin: {}",
|
||||
e.is_quest_handin ? "Yes" : "No"
|
||||
);
|
||||
|
||||
std::vector<DiscordField> f = {};
|
||||
|
||||
|
||||
BuildDiscordField(&f, "NPC", npc_info);
|
||||
|
||||
if (!handin_items_info.empty()) {
|
||||
BuildDiscordField(&f, "Handin Items", handin_items_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Handin Items",
|
||||
fmt::format(
|
||||
"{}",
|
||||
handin_items_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!handin_money_info.empty()) {
|
||||
BuildDiscordField(&f, "Handin Money", handin_money_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Handin Money",
|
||||
fmt::format(
|
||||
"{}",
|
||||
handin_money_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!return_items_info.empty()) {
|
||||
BuildDiscordField(&f, "Return Items", return_items_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Return Items",
|
||||
fmt::format(
|
||||
"{}",
|
||||
return_items_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!return_money_info.empty()) {
|
||||
BuildDiscordField(&f, "Return Money", return_money_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Return Money",
|
||||
fmt::format(
|
||||
"{}",
|
||||
return_money_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<DiscordEmbed> embeds = {};
|
||||
@@ -1081,51 +1071,51 @@ std::string PlayerEventDiscordFormatter::FormatTradeEvent(
|
||||
if (!e.character_1_give_items.empty()) {
|
||||
for (const auto &i: e.character_1_give_items) {
|
||||
std::string augment_info;
|
||||
if (i.augment_1_id > 0) {
|
||||
if (i.aug_1_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 1: {} ({})",
|
||||
i.augment_1_name,
|
||||
i.augment_1_id
|
||||
i.aug_1_item_name,
|
||||
i.aug_1_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_2_id > 0) {
|
||||
if (i.aug_2_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 2: {} ({})",
|
||||
i.augment_2_name,
|
||||
i.augment_2_id
|
||||
i.aug_2_item_name,
|
||||
i.aug_2_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_3_id > 0) {
|
||||
if (i.aug_3_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 3: {} ({})",
|
||||
i.augment_3_name,
|
||||
i.augment_3_id
|
||||
i.aug_3_item_name,
|
||||
i.aug_3_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_4_id > 0) {
|
||||
if (i.aug_4_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 4: {} ({})\n",
|
||||
i.augment_4_name,
|
||||
i.augment_4_id
|
||||
i.aug_4_item_name,
|
||||
i.aug_4_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_5_id > 0) {
|
||||
if (i.aug_5_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 5: {} ({})\n",
|
||||
i.augment_5_name,
|
||||
i.augment_5_id
|
||||
i.aug_5_item_name,
|
||||
i.aug_5_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_6_id > 0) {
|
||||
if (i.aug_6_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 6: {} ({})",
|
||||
i.augment_6_name,
|
||||
i.augment_6_id
|
||||
i.aug_6_item_name,
|
||||
i.aug_6_item_id
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1146,51 +1136,51 @@ std::string PlayerEventDiscordFormatter::FormatTradeEvent(
|
||||
if (!e.character_2_give_items.empty()) {
|
||||
for (const auto &i: e.character_2_give_items) {
|
||||
std::string augment_info;
|
||||
if (i.augment_1_id > 0) {
|
||||
if (i.aug_1_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 1: {} ({})",
|
||||
i.augment_1_name,
|
||||
i.augment_1_id
|
||||
i.aug_1_item_name,
|
||||
i.aug_1_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_2_id > 0) {
|
||||
if (i.aug_2_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 2: {} ({})",
|
||||
i.augment_2_name,
|
||||
i.augment_2_id
|
||||
i.aug_2_item_name,
|
||||
i.aug_2_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_3_id > 0) {
|
||||
if (i.aug_3_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 3: {} ({})",
|
||||
i.augment_3_name,
|
||||
i.augment_3_id
|
||||
i.aug_3_item_name,
|
||||
i.aug_3_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_4_id > 0) {
|
||||
if (i.aug_4_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 4: {} ({})\n",
|
||||
i.augment_4_name,
|
||||
i.augment_4_id
|
||||
i.aug_4_item_name,
|
||||
i.aug_4_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_5_id > 0) {
|
||||
if (i.aug_5_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 5: {} ({})\n",
|
||||
i.augment_5_name,
|
||||
i.augment_5_id
|
||||
i.aug_5_item_name,
|
||||
i.aug_5_item_id
|
||||
);
|
||||
}
|
||||
|
||||
if (i.augment_6_id > 0) {
|
||||
if (i.aug_6_item_id > 0) {
|
||||
augment_info += fmt::format(
|
||||
"Augment 6: {} ({})",
|
||||
i.augment_6_name,
|
||||
i.augment_6_id
|
||||
i.aug_6_item_name,
|
||||
i.aug_6_item_id
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
#include "player_event_logs.h"
|
||||
#include <cereal/archives/json.hpp>
|
||||
|
||||
#include "player_event_logs.h"
|
||||
#include "player_event_discord_formatter.h"
|
||||
#include "../platform.h"
|
||||
#include "../rulesys.h"
|
||||
#include "player_event_discord_formatter.h"
|
||||
#include "../repositories/player_event_loot_items_repository.h"
|
||||
#include "../repositories/player_event_merchant_sell_repository.h"
|
||||
#include "../repositories/player_event_merchant_purchase_repository.h"
|
||||
#include "../repositories/player_event_npc_handin_repository.h"
|
||||
#include "../repositories/player_event_npc_handin_entries_repository.h"
|
||||
|
||||
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
// general initialization routine
|
||||
void PlayerEventLogs::Init()
|
||||
{
|
||||
|
||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
||||
|
||||
@@ -28,7 +21,6 @@ void PlayerEventLogs::Init()
|
||||
m_settings[i].event_enabled = 1;
|
||||
m_settings[i].retention_days = 0;
|
||||
m_settings[i].discord_webhook_id = 0;
|
||||
m_settings[i].etl_enabled = false;
|
||||
}
|
||||
|
||||
SetSettingsDefaults();
|
||||
@@ -45,8 +37,6 @@ void PlayerEventLogs::Init()
|
||||
db.emplace_back(e.id);
|
||||
}
|
||||
|
||||
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
||||
|
||||
// insert entries that don't exist in database
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
||||
@@ -66,28 +56,26 @@ void PlayerEventLogs::Init()
|
||||
|
||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
||||
LogInfo("[New] PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||
LogInfo(
|
||||
"[New] PlayerEvent [{}] ({})",
|
||||
PlayerEvent::EventName[i],
|
||||
i
|
||||
);
|
||||
|
||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
||||
c.id = i;
|
||||
c.event_name = PlayerEvent::EventName[i];
|
||||
c.event_enabled = m_settings[i].event_enabled;
|
||||
c.retention_days = m_settings[i].retention_days;
|
||||
c.etl_enabled = false;
|
||||
settings_to_insert.emplace_back(c);
|
||||
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
||||
}
|
||||
}
|
||||
|
||||
if (!settings_to_insert.empty()) {
|
||||
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
|
||||
}
|
||||
|
||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||
|
||||
// on initial boot process truncation
|
||||
if (processing_in_world || processing_in_qs) {
|
||||
LoadEtlIds();
|
||||
ProcessRetentionTruncation();
|
||||
}
|
||||
}
|
||||
@@ -131,319 +119,23 @@ void PlayerEventLogs::ProcessBatchQueue()
|
||||
return;
|
||||
}
|
||||
|
||||
static std::map<uint32, uint32> counter{};
|
||||
counter.clear();
|
||||
for (auto const &e: m_record_batch_queue) {
|
||||
counter[e.event_type_id]++;
|
||||
}
|
||||
|
||||
BenchTimer benchmark;
|
||||
|
||||
EtlQueues etl_queues{};
|
||||
for (const auto &[type, count]: counter) {
|
||||
if (count > 0) {
|
||||
switch (type) {
|
||||
case PlayerEvent::TRADE:
|
||||
etl_queues.trade.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::SPEECH:
|
||||
etl_queues.speech.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::LOOT_ITEM:
|
||||
etl_queues.loot_items.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::KILLED_NPC:
|
||||
etl_queues.killed_npc.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::NPC_HANDIN:
|
||||
etl_queues.npc_handin.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::AA_PURCHASE:
|
||||
etl_queues.aa_purchase.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::MERCHANT_SELL:
|
||||
etl_queues.merchant_sell.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::KILLED_RAID_NPC:
|
||||
etl_queues.killed_raid_npc.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::KILLED_NAMED_NPC:
|
||||
etl_queues.killed_named_npc.reserve(count);
|
||||
break;
|
||||
case PlayerEvent::MERCHANT_PURCHASE:
|
||||
etl_queues.merchant_purchase.reserve(count);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to deserialize event data
|
||||
auto Deserialize = [](const std::string &data, auto &out) {
|
||||
std::stringstream ss(data);
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
out.serialize(ar);
|
||||
};
|
||||
|
||||
// Helper to assign ETL table ID
|
||||
auto AssignEtlId = [&](
|
||||
PlayerEventLogsRepository::PlayerEventLogs &r,
|
||||
PlayerEvent::EventType type
|
||||
) {
|
||||
if (m_etl_settings.contains(type)) {
|
||||
r.etl_table_id = m_etl_settings.at(type).next_id++;
|
||||
}
|
||||
};
|
||||
|
||||
// Define event processors
|
||||
std::unordered_map<PlayerEvent::EventType, std::function<void(PlayerEventLogsRepository::PlayerEventLogs &)>> event_processors = {
|
||||
{
|
||||
PlayerEvent::EventType::LOOT_ITEM, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::LootItemEvent in{};
|
||||
PlayerEventLootItemsRepository::PlayerEventLootItems out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.charges = in.charges;
|
||||
out.corpse_name = in.corpse_name;
|
||||
out.item_id = in.item_id;
|
||||
out.item_name = in.item_name;
|
||||
out.augment_1_id = in.augment_1_id;
|
||||
out.augment_2_id = in.augment_2_id;
|
||||
out.augment_3_id = in.augment_3_id;
|
||||
out.augment_4_id = in.augment_4_id;
|
||||
out.augment_5_id = in.augment_5_id;
|
||||
out.augment_6_id = in.augment_6_id;
|
||||
out.npc_id = in.npc_id;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::LOOT_ITEM);
|
||||
etl_queues.loot_items.push_back(out);
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::EventType::MERCHANT_SELL, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::MerchantSellEvent in{};
|
||||
PlayerEventMerchantSellRepository::PlayerEventMerchantSell out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.npc_id = in.npc_id;
|
||||
out.merchant_name = in.merchant_name;
|
||||
out.merchant_type = in.merchant_type;
|
||||
out.item_id = in.item_id;
|
||||
out.item_name = in.item_name;
|
||||
out.charges = in.charges;
|
||||
out.cost = in.cost;
|
||||
out.alternate_currency_id = in.alternate_currency_id;
|
||||
out.player_money_balance = in.player_money_balance;
|
||||
out.player_currency_balance = in.player_currency_balance;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::MERCHANT_SELL);
|
||||
etl_queues.merchant_sell.push_back(out);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::EventType::MERCHANT_PURCHASE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::MerchantPurchaseEvent in{};
|
||||
PlayerEventMerchantPurchaseRepository::PlayerEventMerchantPurchase out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.npc_id = in.npc_id;
|
||||
out.merchant_name = in.merchant_name;
|
||||
out.merchant_type = in.merchant_type;
|
||||
out.item_id = in.item_id;
|
||||
out.item_name = in.item_name;
|
||||
out.charges = in.charges;
|
||||
out.cost = in.cost;
|
||||
out.alternate_currency_id = in.alternate_currency_id;
|
||||
out.player_money_balance = in.player_money_balance;
|
||||
out.player_currency_balance = in.player_currency_balance;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::MERCHANT_PURCHASE);
|
||||
etl_queues.merchant_purchase.push_back(out);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::EventType::NPC_HANDIN, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::HandinEvent in{};
|
||||
PlayerEventNpcHandinRepository::PlayerEventNpcHandin out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.npc_id = in.npc_id;
|
||||
out.npc_name = in.npc_name;
|
||||
out.handin_copper = in.handin_money.copper;
|
||||
out.handin_silver = in.handin_money.silver;
|
||||
out.handin_gold = in.handin_money.gold;
|
||||
out.handin_platinum = in.handin_money.platinum;
|
||||
out.return_copper = in.return_money.copper;
|
||||
out.return_silver = in.return_money.silver;
|
||||
out.return_gold = in.return_money.gold;
|
||||
out.return_platinum = in.return_money.platinum;
|
||||
out.is_quest_handin = in.is_quest_handin;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::NPC_HANDIN);
|
||||
etl_queues.npc_handin.push_back(out);
|
||||
|
||||
for (const auto &i: in.handin_items) {
|
||||
PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries entry{};
|
||||
entry.player_event_npc_handin_id = r.etl_table_id;
|
||||
entry.item_id = i.item_id;
|
||||
entry.charges = i.charges;
|
||||
entry.type = 1;
|
||||
etl_queues.npc_handin_entries.push_back(entry);
|
||||
}
|
||||
for (const auto &i: in.return_items) {
|
||||
PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries entry{};
|
||||
entry.player_event_npc_handin_id = r.etl_table_id;
|
||||
entry.item_id = i.item_id;
|
||||
entry.charges = i.charges;
|
||||
entry.type = 2;
|
||||
etl_queues.npc_handin_entries.push_back(entry);
|
||||
}
|
||||
}},
|
||||
{
|
||||
PlayerEvent::EventType::TRADE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::TradeEvent in{};
|
||||
PlayerEventTradeRepository::PlayerEventTrade out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.char1_id = in.character_1_id;
|
||||
out.char2_id = in.character_2_id;
|
||||
out.char1_copper = in.character_1_give_money.copper;
|
||||
out.char1_silver = in.character_1_give_money.silver;
|
||||
out.char1_gold = in.character_1_give_money.gold;
|
||||
out.char1_platinum = in.character_1_give_money.platinum;
|
||||
out.char2_copper = in.character_2_give_money.copper;
|
||||
out.char2_silver = in.character_2_give_money.silver;
|
||||
out.char2_gold = in.character_2_give_money.gold;
|
||||
out.char2_platinum = in.character_2_give_money.platinum;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::TRADE);
|
||||
etl_queues.trade.push_back(out);
|
||||
|
||||
for (const auto &i: in.character_1_give_items) {
|
||||
PlayerEventTradeEntriesRepository::PlayerEventTradeEntries entry{};
|
||||
entry.player_event_trade_id = r.etl_table_id;
|
||||
entry.char_id = in.character_1_id;
|
||||
entry.item_id = i.item_id;
|
||||
entry.charges = i.charges;
|
||||
entry.slot = i.slot;
|
||||
etl_queues.trade_entries.push_back(entry);
|
||||
}
|
||||
for (const auto &i: in.character_2_give_items) {
|
||||
PlayerEventTradeEntriesRepository::PlayerEventTradeEntries entry{};
|
||||
entry.player_event_trade_id = r.etl_table_id;
|
||||
entry.char_id = in.character_2_id;
|
||||
entry.item_id = i.item_id;
|
||||
entry.charges = i.charges;
|
||||
entry.slot = i.slot;
|
||||
etl_queues.trade_entries.push_back(entry);
|
||||
}
|
||||
}},
|
||||
{
|
||||
PlayerEvent::EventType::SPEECH, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::PlayerSpeech in{};
|
||||
PlayerEventSpeechRepository::PlayerEventSpeech out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.from_char_id = in.from;
|
||||
out.to_char_id = in.to;
|
||||
out.type = in.type;
|
||||
out.min_status = in.min_status;
|
||||
out.message = in.message;
|
||||
out.guild_id = in.guild_id;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::SPEECH);
|
||||
etl_queues.speech.push_back(out);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::EventType::KILLED_NPC, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::KilledNPCEvent in{};
|
||||
PlayerEventKilledNpcRepository::PlayerEventKilledNpc out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.npc_id = in.npc_id;
|
||||
out.npc_name = in.npc_name;
|
||||
out.combat_time_seconds = in.combat_time_seconds;
|
||||
out.total_damage_per_second_taken = in.total_damage_per_second_taken;
|
||||
out.total_heal_per_second_taken = in.total_heal_per_second_taken;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::KILLED_NPC);
|
||||
etl_queues.killed_npc.push_back(out);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::EventType::AA_PURCHASE, [&](PlayerEventLogsRepository::PlayerEventLogs &r) {
|
||||
PlayerEvent::AAPurchasedEvent in{};
|
||||
PlayerEventAaPurchaseRepository::PlayerEventAaPurchase out{};
|
||||
Deserialize(r.event_data, in);
|
||||
|
||||
out.aa_ability_id = in.aa_id;
|
||||
out.cost = in.aa_cost;
|
||||
out.previous_id = in.aa_previous_id;
|
||||
out.next_id = in.aa_next_id;
|
||||
out.created_at = r.created_at;
|
||||
|
||||
AssignEtlId(r, PlayerEvent::EventType::AA_PURCHASE);
|
||||
etl_queues.aa_purchase.push_back(out);
|
||||
}},
|
||||
};
|
||||
|
||||
// Process the batch queue
|
||||
for (auto &r: m_record_batch_queue) {
|
||||
if (m_settings[r.event_type_id].etl_enabled) {
|
||||
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
|
||||
if (it != event_processors.end()) {
|
||||
it->second(r); // Call the appropriate lambda
|
||||
r.event_data = "{}"; // Clear event data
|
||||
}
|
||||
else {
|
||||
LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to flush and clear queues
|
||||
auto flush_queue = [&](auto insert_many, auto &queue) {
|
||||
if (!queue.empty()) {
|
||||
insert_many(*m_database, queue);
|
||||
queue.clear();
|
||||
}
|
||||
};
|
||||
|
||||
// flush many
|
||||
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
||||
|
||||
// flush etl queues
|
||||
flush_queue(PlayerEventLootItemsRepository::InsertMany, etl_queues.loot_items);
|
||||
flush_queue(PlayerEventMerchantSellRepository::InsertMany, etl_queues.merchant_sell);
|
||||
flush_queue(PlayerEventMerchantPurchaseRepository::InsertMany, etl_queues.merchant_purchase);
|
||||
flush_queue(PlayerEventNpcHandinRepository::InsertMany, etl_queues.npc_handin);
|
||||
flush_queue(PlayerEventNpcHandinEntriesRepository::InsertMany, etl_queues.npc_handin_entries);
|
||||
flush_queue(PlayerEventTradeRepository::InsertMany, etl_queues.trade);
|
||||
flush_queue(PlayerEventTradeEntriesRepository::InsertMany, etl_queues.trade_entries);
|
||||
flush_queue(PlayerEventSpeechRepository::InsertMany, etl_queues.speech);
|
||||
flush_queue(PlayerEventKilledNpcRepository::InsertMany, etl_queues.killed_npc);
|
||||
flush_queue(PlayerEventKilledNamedNpcRepository::InsertMany, etl_queues.killed_named_npc);
|
||||
flush_queue(PlayerEventKilledRaidNpcRepository::InsertMany, etl_queues.killed_raid_npc);
|
||||
flush_queue(PlayerEventAaPurchaseRepository::InsertMany, etl_queues.aa_purchase);
|
||||
|
||||
LogPlayerEvents(
|
||||
LogPlayerEventsDetail(
|
||||
"Processing batch player event log queue of [{}] took [{}]",
|
||||
m_record_batch_queue.size(),
|
||||
benchmark.elapsed()
|
||||
);
|
||||
|
||||
// empty
|
||||
m_record_batch_queue.clear();
|
||||
m_record_batch_queue = {};
|
||||
m_batch_queue_lock.unlock();
|
||||
}
|
||||
|
||||
// adds a player event to the queue
|
||||
void PlayerEventLogs::AddToQueue(PlayerEventLogsRepository::PlayerEventLogs &log)
|
||||
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
||||
{
|
||||
m_batch_queue_lock.lock();
|
||||
m_record_batch_queue.emplace_back(log);
|
||||
@@ -641,10 +333,7 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
||||
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FISH_FAILURE:
|
||||
case PlayerEvent::FORAGE_FAILURE:
|
||||
case PlayerEvent::WENT_ONLINE:
|
||||
case PlayerEvent::WENT_OFFLINE: {
|
||||
case PlayerEvent::FISH_FAILURE: {
|
||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||
break;
|
||||
}
|
||||
@@ -659,6 +348,10 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
||||
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FORAGE_FAILURE: {
|
||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FORAGE_SUCCESS: {
|
||||
PlayerEvent::ForageSuccessEvent n{};
|
||||
std::stringstream ss;
|
||||
@@ -857,6 +550,11 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
||||
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::WENT_ONLINE:
|
||||
case PlayerEvent::WENT_OFFLINE: {
|
||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::MERCHANT_PURCHASE: {
|
||||
PlayerEvent::MerchantPurchaseEvent n{};
|
||||
std::stringstream ss;
|
||||
@@ -894,7 +592,7 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogPlayerEventsDetail(
|
||||
LogInfo(
|
||||
"Player event [{}] ({}) Discord formatter not implemented",
|
||||
e.player_event_log.event_type_name,
|
||||
e.player_event_log.event_type_id
|
||||
@@ -908,8 +606,7 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
||||
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
||||
void PlayerEventLogs::Process()
|
||||
{
|
||||
if (m_process_batch_events_timer.Check() ||
|
||||
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
||||
if (m_process_batch_events_timer.Check() || m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
||||
ProcessBatchQueue();
|
||||
}
|
||||
|
||||
@@ -920,125 +617,35 @@ void PlayerEventLogs::Process()
|
||||
|
||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||
{
|
||||
LogPlayerEventsDetail("Running truncation");
|
||||
LogInfo("Running truncation");
|
||||
|
||||
// Map of repository-specific deletion functions
|
||||
std::unordered_map<PlayerEvent::EventType, std::function<uint32(const std::string &)>> repository_deleters = {
|
||||
{
|
||||
PlayerEvent::LOOT_ITEM, [&](const std::string &condition) {
|
||||
return PlayerEventLootItemsRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::MERCHANT_SELL, [&](const std::string &condition) {
|
||||
return PlayerEventMerchantSellRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::MERCHANT_PURCHASE, [&](const std::string &condition) {
|
||||
return PlayerEventMerchantPurchaseRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::NPC_HANDIN, [&](const std::string &condition) {
|
||||
uint32 deleted_count = PlayerEventNpcHandinRepository::DeleteWhere(*m_database, condition);
|
||||
deleted_count += PlayerEventNpcHandinEntriesRepository::DeleteWhere(*m_database, condition);
|
||||
return deleted_count;
|
||||
}},
|
||||
{
|
||||
PlayerEvent::TRADE, [&](const std::string &condition) {
|
||||
uint32 deleted_count = PlayerEventTradeRepository::DeleteWhere(*m_database, condition);
|
||||
deleted_count += PlayerEventTradeEntriesRepository::DeleteWhere(*m_database, condition);
|
||||
return deleted_count;
|
||||
}},
|
||||
{
|
||||
PlayerEvent::SPEECH, [&](const std::string &condition) {
|
||||
return PlayerEventSpeechRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::KILLED_NPC, [&](const std::string &condition) {
|
||||
return PlayerEventKilledNpcRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::KILLED_NAMED_NPC, [&](const std::string &condition) {
|
||||
return PlayerEventKilledNamedNpcRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::KILLED_RAID_NPC, [&](const std::string &condition) {
|
||||
return PlayerEventKilledRaidNpcRepository::DeleteWhere(*m_database, condition);
|
||||
}},
|
||||
{
|
||||
PlayerEvent::AA_PURCHASE, [&](const std::string &condition) {
|
||||
return PlayerEventAaPurchaseRepository::DeleteWhere(*m_database, condition);
|
||||
}}
|
||||
};
|
||||
|
||||
// Group event types by retention interval
|
||||
std::unordered_map<int, std::vector<int>> retention_groups;
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
if (m_settings[i].retention_days > 0) {
|
||||
retention_groups[m_settings[i].retention_days].push_back(i);
|
||||
}
|
||||
}
|
||||
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
||||
*m_database,
|
||||
fmt::format(
|
||||
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
|
||||
i,
|
||||
m_settings[i].retention_days
|
||||
)
|
||||
);
|
||||
|
||||
for (const auto &[retention_days, event_types]: retention_groups) {
|
||||
std::string condition = fmt::format(
|
||||
"created_at < (NOW() - INTERVAL {} DAY)",
|
||||
retention_days
|
||||
);
|
||||
|
||||
// Handle ETL deletions for each event type in the group
|
||||
uint32 total_deleted_count = 0;
|
||||
for (int event_type_id: event_types) {
|
||||
if (m_settings[event_type_id].etl_enabled) {
|
||||
auto it = repository_deleters.find(static_cast<PlayerEvent::EventType>(m_settings[event_type_id].id));
|
||||
if (it != repository_deleters.end()) {
|
||||
total_deleted_count += it->second(condition);
|
||||
}
|
||||
else {
|
||||
LogError("Non-Implemented ETL Event Type [{}]", static_cast<uint32>(m_settings[event_type_id].id));
|
||||
}
|
||||
if (deleted_count > 0) {
|
||||
LogInfo(
|
||||
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
|
||||
deleted_count,
|
||||
PlayerEvent::EventName[i],
|
||||
i,
|
||||
m_settings[i].retention_days
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (total_deleted_count > 0) {
|
||||
LogInfo(
|
||||
"Truncated [{}] ETL events older than [{}] days",
|
||||
total_deleted_count,
|
||||
retention_days
|
||||
);
|
||||
}
|
||||
|
||||
// Batch deletion for player_event_logs
|
||||
std::string event_type_ids = fmt::format(
|
||||
"({})",
|
||||
fmt::join(event_types, ", ")
|
||||
);
|
||||
|
||||
uint32 deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
||||
*m_database,
|
||||
fmt::format(
|
||||
"event_type_id IN {} AND {}",
|
||||
event_type_ids,
|
||||
condition
|
||||
)
|
||||
);
|
||||
|
||||
if (deleted_count > 0) {
|
||||
LogInfo(
|
||||
"Truncated [{}] events of types [{}] older than [{}] days",
|
||||
deleted_count,
|
||||
event_type_ids,
|
||||
retention_days
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerEventLogs::ReloadSettings()
|
||||
{
|
||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
||||
if (e.id >= PlayerEvent::MAX || e.id < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_settings[e.id] = e;
|
||||
}
|
||||
}
|
||||
@@ -1047,197 +654,55 @@ const int32_t RETENTION_DAYS_DEFAULT = 7;
|
||||
|
||||
void PlayerEventLogs::SetSettingsDefaults()
|
||||
{
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_PLAT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_SEND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_RETRIEVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_DELETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BARTER_TRANSACTION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::EVOLVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPEECH].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerEventLogs::LoadEtlIds()
|
||||
{
|
||||
auto e = [&](auto p) -> bool {
|
||||
for (PlayerEventLogSettingsRepository::PlayerEventLogSettings const &c: m_settings) {
|
||||
if (c.id == p) {
|
||||
return c.etl_enabled ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
m_etl_settings.clear();
|
||||
m_etl_settings = {
|
||||
{
|
||||
PlayerEvent::LOOT_ITEM,
|
||||
{
|
||||
.enabled = e(PlayerEvent::LOOT_ITEM),
|
||||
.table_name = "player_event_loot_items",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventLootItemsRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::MERCHANT_SELL,
|
||||
{
|
||||
.enabled = e(PlayerEvent::MERCHANT_SELL),
|
||||
.table_name = "player_event_merchant_sell",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventMerchantSellRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::MERCHANT_PURCHASE,
|
||||
{
|
||||
.enabled = e(PlayerEvent::MERCHANT_PURCHASE),
|
||||
.table_name = "player_event_merchant_purchase",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventMerchantPurchaseRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::NPC_HANDIN,
|
||||
{
|
||||
.enabled = e(PlayerEvent::NPC_HANDIN),
|
||||
.table_name = "player_event_npc_handin",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventNpcHandinRepository::TableName()))
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::TRADE,
|
||||
{
|
||||
.enabled = e(PlayerEvent::TRADE),
|
||||
.table_name = "player_event_trade",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventTradeRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::SPEECH,
|
||||
{
|
||||
.enabled = e(PlayerEvent::SPEECH),
|
||||
.table_name = "player_event_speech",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventSpeechRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::KILLED_NPC,
|
||||
{
|
||||
.enabled = e(PlayerEvent::KILLED_NPC),
|
||||
.table_name = "player_event_killed_npc",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledNpcRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::KILLED_NAMED_NPC,
|
||||
{
|
||||
.enabled = e(PlayerEvent::KILLED_NAMED_NPC),
|
||||
.table_name = "player_event_killed_named_npc",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledNamedNpcRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::KILLED_RAID_NPC,
|
||||
{
|
||||
.enabled = e(PlayerEvent::KILLED_RAID_NPC),
|
||||
.table_name = "player_event_killed_raid_npc",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventKilledRaidNpcRepository::TableName()))
|
||||
}
|
||||
},
|
||||
{
|
||||
PlayerEvent::AA_PURCHASE,
|
||||
{
|
||||
.enabled = e(PlayerEvent::AA_PURCHASE),
|
||||
.table_name = "player_event_aa_purchase",
|
||||
.next_id = static_cast<int64>(m_database->GetNextTableId(PlayerEventAaPurchaseRepository::TableName()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (auto &e: m_etl_settings) {
|
||||
LogPlayerEventsDetail(
|
||||
"ETL Settings [{}] Enabled [{}] Table [{}] NextId [{}]",
|
||||
PlayerEvent::EventName[e.first],
|
||||
e.second.enabled,
|
||||
e.second.table_name,
|
||||
e.second.next_id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerEventLogs::LoadDatabaseConnection()
|
||||
{
|
||||
const auto c = EQEmuConfig::get();
|
||||
|
||||
LogInfo(
|
||||
"Connecting to MySQL for PlayerEvents [{}]@[{}]:[{}]",
|
||||
c->DatabaseUsername.c_str(),
|
||||
c->DatabaseHost.c_str(),
|
||||
c->DatabasePort
|
||||
);
|
||||
|
||||
if (!player_event_database.Connect(
|
||||
c->DatabaseHost.c_str(),
|
||||
c->DatabaseUsername.c_str(),
|
||||
c->DatabasePassword.c_str(),
|
||||
c->DatabaseDB.c_str(),
|
||||
c->DatabasePort
|
||||
)) {
|
||||
LogError("Cannot continue without a database connection for player events.");
|
||||
return false;
|
||||
}
|
||||
|
||||
SetDatabase(&player_event_database);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,38 +1,19 @@
|
||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
||||
#define EQEMU_PLAYER_EVENT_LOGS_H
|
||||
|
||||
#include "../repositories/player_event_log_settings_repository.h"
|
||||
#include "player_events.h"
|
||||
#include "../servertalk.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../timer.h"
|
||||
#include "../json/json_archive_single_line.h"
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <mutex>
|
||||
#include "../json/json_archive_single_line.h"
|
||||
#include "../servertalk.h"
|
||||
#include "../timer.h"
|
||||
#include "../eqemu_config.h"
|
||||
|
||||
#include "../repositories/player_event_log_settings_repository.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../repositories/player_event_loot_items_repository.h"
|
||||
#include "../repositories/player_event_merchant_purchase_repository.h"
|
||||
#include "../repositories/player_event_merchant_sell_repository.h"
|
||||
#include "../repositories/player_event_npc_handin_repository.h"
|
||||
#include "../repositories/player_event_npc_handin_entries_repository.h"
|
||||
#include "../repositories/player_event_trade_repository.h"
|
||||
#include "../repositories/player_event_trade_entries_repository.h"
|
||||
#include "../repositories/player_event_speech_repository.h"
|
||||
#include "../repositories/player_event_killed_npc_repository.h"
|
||||
#include "../repositories/player_event_killed_named_npc_repository.h"
|
||||
#include "../repositories/player_event_killed_raid_npc_repository.h"
|
||||
#include "../repositories/player_event_aa_purchase_repository.h"
|
||||
|
||||
|
||||
|
||||
class PlayerEventLogs {
|
||||
public:
|
||||
Database player_event_database{};
|
||||
|
||||
void Init();
|
||||
bool LoadDatabaseConnection();
|
||||
void ReloadSettings();
|
||||
void LoadEtlIds();
|
||||
PlayerEventLogs *SetDatabase(Database *db);
|
||||
bool ValidateDatabaseConnection();
|
||||
bool IsEventEnabled(PlayerEvent::EventType event);
|
||||
@@ -40,7 +21,7 @@ public:
|
||||
void Process();
|
||||
|
||||
// batch queue
|
||||
void AddToQueue(PlayerEventLogsRepository::PlayerEventLogs &logs);
|
||||
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
||||
|
||||
// main event record generic function
|
||||
// can ingest any struct event types
|
||||
@@ -78,29 +59,7 @@ public:
|
||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
||||
|
||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
||||
|
||||
struct EtlQueues {
|
||||
std::vector<PlayerEventLootItemsRepository::PlayerEventLootItems> loot_items;
|
||||
std::vector<PlayerEventMerchantPurchaseRepository::PlayerEventMerchantPurchase> merchant_purchase;
|
||||
std::vector<PlayerEventMerchantSellRepository::PlayerEventMerchantSell> merchant_sell;
|
||||
std::vector<PlayerEventNpcHandinRepository::PlayerEventNpcHandin> npc_handin;
|
||||
std::vector<PlayerEventNpcHandinEntriesRepository::PlayerEventNpcHandinEntries> npc_handin_entries;
|
||||
std::vector<PlayerEventTradeRepository::PlayerEventTrade> trade;
|
||||
std::vector<PlayerEventTradeEntriesRepository::PlayerEventTradeEntries> trade_entries;
|
||||
std::vector<PlayerEventSpeechRepository::PlayerEventSpeech> speech;
|
||||
std::vector<PlayerEventKilledNpcRepository::PlayerEventKilledNpc> killed_npc;
|
||||
std::vector<PlayerEventKilledNamedNpcRepository::PlayerEventKilledNamedNpc> killed_named_npc;
|
||||
std::vector<PlayerEventKilledRaidNpcRepository::PlayerEventKilledRaidNpc> killed_raid_npc;
|
||||
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
|
||||
};
|
||||
|
||||
private:
|
||||
struct EtlSettings {
|
||||
bool enabled;
|
||||
std::string table_name;
|
||||
int64 next_id;
|
||||
};
|
||||
|
||||
Database *m_database; // reference to database
|
||||
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
||||
|
||||
@@ -110,8 +69,6 @@ private:
|
||||
static std::unique_ptr<ServerPacket>
|
||||
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
||||
|
||||
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
|
||||
|
||||
// timers
|
||||
Timer m_process_batch_events_timer; // events processing timer
|
||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
||||
@@ -121,9 +78,6 @@ private:
|
||||
void ProcessBatchQueue();
|
||||
void ProcessRetentionTruncation();
|
||||
void SetSettingsDefaults();
|
||||
|
||||
public:
|
||||
std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;}
|
||||
};
|
||||
|
||||
extern PlayerEventLogs player_event_logs;
|
||||
|
||||
+76
-474
@@ -4,7 +4,6 @@
|
||||
#include <string>
|
||||
#include <cereal/cereal.hpp>
|
||||
#include "../types.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
|
||||
namespace PlayerEvent {
|
||||
@@ -57,17 +56,6 @@ namespace PlayerEvent {
|
||||
KILLED_NAMED_NPC,
|
||||
KILLED_RAID_NPC,
|
||||
ITEM_CREATION,
|
||||
GUILD_TRIBUTE_DONATE_ITEM,
|
||||
GUILD_TRIBUTE_DONATE_PLAT,
|
||||
PARCEL_SEND,
|
||||
PARCEL_RETRIEVE,
|
||||
PARCEL_DELETE,
|
||||
BARTER_TRANSACTION,
|
||||
SPEECH,
|
||||
EVOLVE_ITEM,
|
||||
GUILD_BANK_DEPOSIT,
|
||||
GUILD_BANK_WITHDRAWAL,
|
||||
GUILD_BANK_MOVE_TO_BANK_AREA,
|
||||
MAX // dont remove
|
||||
};
|
||||
|
||||
@@ -76,7 +64,7 @@ namespace PlayerEvent {
|
||||
// If event is unimplemented just tag (Unimplemented) in the name
|
||||
// Events don't get saved to the database if unimplemented or deprecated
|
||||
// Events tagged as deprecated will get automatically removed
|
||||
static const char *EventName[EventType::MAX] = {
|
||||
static const char *EventName[PlayerEvent::MAX] = {
|
||||
"None",
|
||||
"GM Command",
|
||||
"Zoning",
|
||||
@@ -124,18 +112,7 @@ namespace PlayerEvent {
|
||||
"Killed NPC",
|
||||
"Killed Named NPC",
|
||||
"Killed Raid NPC",
|
||||
"Item Creation",
|
||||
"Guild Tribute Donate Item",
|
||||
"Guild Tribute Donate Platinum",
|
||||
"Parcel Item Sent",
|
||||
"Parcel Item Retrieved",
|
||||
"Parcel Prune Routine",
|
||||
"Barter Transaction",
|
||||
"Player Speech",
|
||||
"Evolve Item Update",
|
||||
"Guild Bank Item Deposit",
|
||||
"Guild Bank Item Withdrawal",
|
||||
"Guild Bank Move From Deposit Area to Bank Area"
|
||||
"Item Creation"
|
||||
};
|
||||
|
||||
// Generic struct used by all events
|
||||
@@ -215,12 +192,12 @@ namespace PlayerEvent {
|
||||
std::string item_name;
|
||||
uint16 to_slot;
|
||||
int16 charges;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
uint32 aug1;
|
||||
uint32 aug2;
|
||||
uint32 aug3;
|
||||
uint32 aug4;
|
||||
uint32 aug5;
|
||||
uint32 aug6;
|
||||
bool attuned;
|
||||
|
||||
// cereal
|
||||
@@ -232,57 +209,56 @@ namespace PlayerEvent {
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(to_slot),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(aug1),
|
||||
CEREAL_NVP(aug2),
|
||||
CEREAL_NVP(aug3),
|
||||
CEREAL_NVP(aug4),
|
||||
CEREAL_NVP(aug5),
|
||||
CEREAL_NVP(aug6),
|
||||
CEREAL_NVP(attuned)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// used in Trade event
|
||||
// struct TradeItem {
|
||||
// int64 item_id;
|
||||
// std::string item_name;
|
||||
// int32 slot;
|
||||
//
|
||||
// // cereal
|
||||
// template<class Archive>
|
||||
// void serialize(Archive &ar)
|
||||
// {
|
||||
// ar(
|
||||
// CEREAL_NVP(item_id),
|
||||
// CEREAL_NVP(item_name),
|
||||
// CEREAL_NVP(slot)
|
||||
// );
|
||||
// }
|
||||
// };
|
||||
struct TradeItem {
|
||||
int64 item_id;
|
||||
std::string item_name;
|
||||
int32 slot;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(slot)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// used in Trade event
|
||||
class TradeItemEntry {
|
||||
public:
|
||||
uint16 slot;
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
std::string augment_1_name;
|
||||
uint32 augment_2_id;
|
||||
std::string augment_2_name;
|
||||
uint32 augment_3_id;
|
||||
std::string augment_3_name;
|
||||
uint32 augment_4_id;
|
||||
std::string augment_4_name;
|
||||
uint32 augment_5_id;
|
||||
std::string augment_5_name;
|
||||
uint32 augment_6_id;
|
||||
std::string augment_6_name;
|
||||
std::string item_name;
|
||||
uint16 charges;
|
||||
uint32 aug_1_item_id;
|
||||
std::string aug_1_item_name;
|
||||
uint32 aug_2_item_id;
|
||||
std::string aug_2_item_name;
|
||||
uint32 aug_3_item_id;
|
||||
std::string aug_3_item_name;
|
||||
uint32 aug_4_item_id;
|
||||
std::string aug_4_item_name;
|
||||
uint32 aug_5_item_id;
|
||||
std::string aug_5_item_name;
|
||||
uint32 aug_6_item_id;
|
||||
std::string aug_6_item_name;
|
||||
bool in_bag;
|
||||
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
@@ -290,20 +266,12 @@ namespace PlayerEvent {
|
||||
ar(
|
||||
CEREAL_NVP(slot),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_1_name),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_2_name),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_1_name),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_4_name),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_5_name),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(augment_6_name),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(aug_1_item_id),
|
||||
CEREAL_NVP(aug_2_item_id),
|
||||
CEREAL_NVP(aug_3_item_id),
|
||||
CEREAL_NVP(aug_4_item_id),
|
||||
CEREAL_NVP(aug_5_item_id),
|
||||
CEREAL_NVP(in_bag)
|
||||
);
|
||||
}
|
||||
@@ -416,10 +384,10 @@ namespace PlayerEvent {
|
||||
};
|
||||
|
||||
struct AAPurchasedEvent {
|
||||
uint32 aa_id;
|
||||
int32 aa_cost;
|
||||
int32 aa_previous_id;
|
||||
int32 aa_next_id;
|
||||
int32 aa_id;
|
||||
int32 aa_cost;
|
||||
int32 aa_previous_id;
|
||||
int32 aa_next_id;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -436,12 +404,6 @@ namespace PlayerEvent {
|
||||
|
||||
struct ForageSuccessEvent {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
std::string item_name;
|
||||
|
||||
// cereal
|
||||
@@ -450,12 +412,6 @@ namespace PlayerEvent {
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(item_name)
|
||||
);
|
||||
}
|
||||
@@ -463,12 +419,6 @@ namespace PlayerEvent {
|
||||
|
||||
struct FishSuccessEvent {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
std::string item_name;
|
||||
|
||||
// cereal
|
||||
@@ -477,12 +427,6 @@ namespace PlayerEvent {
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(item_name)
|
||||
);
|
||||
}
|
||||
@@ -492,13 +436,6 @@ namespace PlayerEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 charges;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
bool attuned;
|
||||
std::string reason;
|
||||
|
||||
// cereal
|
||||
@@ -508,15 +445,8 @@ namespace PlayerEvent {
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(attuned),
|
||||
CEREAL_NVP(reason)
|
||||
CEREAL_NVP(reason),
|
||||
CEREAL_NVP(charges)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -559,12 +489,6 @@ namespace PlayerEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 charges;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
uint32 npc_id;
|
||||
std::string corpse_name;
|
||||
|
||||
@@ -576,12 +500,6 @@ namespace PlayerEvent {
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(corpse_name)
|
||||
);
|
||||
@@ -794,12 +712,6 @@ namespace PlayerEvent {
|
||||
|
||||
struct DroppedItemEvent {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
std::string item_name;
|
||||
int16 slot_id;
|
||||
uint32 charges;
|
||||
@@ -810,12 +722,6 @@ namespace PlayerEvent {
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(slot_id),
|
||||
CEREAL_NVP(charges)
|
||||
@@ -871,19 +777,12 @@ namespace PlayerEvent {
|
||||
|
||||
struct TraderPurchaseEvent {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
std::string item_name;
|
||||
uint32 trader_id;
|
||||
std::string trader_name;
|
||||
uint32 price;
|
||||
uint32 quantity;
|
||||
int32 charges;
|
||||
uint64 total_cost;
|
||||
uint32 charges;
|
||||
uint32 total_cost;
|
||||
uint64 player_money_balance;
|
||||
|
||||
|
||||
@@ -893,17 +792,10 @@ namespace PlayerEvent {
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(trader_id),
|
||||
CEREAL_NVP(trader_name),
|
||||
CEREAL_NVP(price),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(total_cost),
|
||||
CEREAL_NVP(player_money_balance)
|
||||
@@ -913,19 +805,12 @@ namespace PlayerEvent {
|
||||
|
||||
struct TraderSellEvent {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
std::string item_name;
|
||||
uint32 buyer_id;
|
||||
std::string buyer_name;
|
||||
uint32 price;
|
||||
uint32 quantity;
|
||||
int32 charges;
|
||||
uint64 total_cost;
|
||||
uint32 charges;
|
||||
uint32 total_cost;
|
||||
uint64 player_money_balance;
|
||||
|
||||
|
||||
@@ -935,17 +820,10 @@ namespace PlayerEvent {
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(buyer_id),
|
||||
CEREAL_NVP(buyer_name),
|
||||
CEREAL_NVP(price),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(total_cost),
|
||||
CEREAL_NVP(player_money_balance)
|
||||
@@ -970,12 +848,10 @@ namespace PlayerEvent {
|
||||
|
||||
class HandinEntry {
|
||||
public:
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
std::vector<uint32> augment_ids;
|
||||
std::vector<std::string> augment_names;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -984,8 +860,6 @@ namespace PlayerEvent {
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(augment_ids),
|
||||
CEREAL_NVP(augment_names),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(attuned)
|
||||
);
|
||||
@@ -1019,7 +893,6 @@ namespace PlayerEvent {
|
||||
HandinMoney handin_money;
|
||||
std::vector<HandinEntry> return_items;
|
||||
HandinMoney return_money;
|
||||
bool is_quest_handin;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -1031,8 +904,7 @@ namespace PlayerEvent {
|
||||
CEREAL_NVP(handin_items),
|
||||
CEREAL_NVP(handin_money),
|
||||
CEREAL_NVP(return_items),
|
||||
CEREAL_NVP(return_money),
|
||||
CEREAL_NVP(is_quest_handin)
|
||||
CEREAL_NVP(return_money)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1070,300 +942,30 @@ namespace PlayerEvent {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildTributeDonateItem {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
int16 charges;
|
||||
bool attuned;
|
||||
uint32 guild_favor;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(guild_favor)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildTributeDonatePlat {
|
||||
uint32 plat;
|
||||
uint32 guild_favor;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(plat),
|
||||
CEREAL_NVP(guild_favor)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelRetrieve {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
uint32 quantity;
|
||||
std::string from_player_name;
|
||||
uint32 sent_date;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(from_player_name),
|
||||
CEREAL_NVP(sent_date)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelSend {
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
uint32 quantity;
|
||||
int32 charges;
|
||||
std::string from_player_name;
|
||||
std::string to_player_name;
|
||||
uint32 sent_date;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(from_player_name),
|
||||
CEREAL_NVP(to_player_name),
|
||||
CEREAL_NVP(sent_date)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelDelete {
|
||||
uint32 char_id;
|
||||
uint32 item_id;
|
||||
uint32 augment_1_id;
|
||||
uint32 augment_2_id;
|
||||
uint32 augment_3_id;
|
||||
uint32 augment_4_id;
|
||||
uint32 augment_5_id;
|
||||
uint32 augment_6_id;
|
||||
uint32 quantity;
|
||||
uint32 sent_date;
|
||||
std::string from_name;
|
||||
std::string note;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(augment_1_id),
|
||||
CEREAL_NVP(augment_2_id),
|
||||
CEREAL_NVP(augment_3_id),
|
||||
CEREAL_NVP(augment_4_id),
|
||||
CEREAL_NVP(augment_5_id),
|
||||
CEREAL_NVP(augment_6_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(char_id),
|
||||
CEREAL_NVP(from_name),
|
||||
CEREAL_NVP(note),
|
||||
CEREAL_NVP(sent_date)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct BarterTransaction {
|
||||
std::string status;
|
||||
uint32 item_id;
|
||||
uint32 item_quantity;
|
||||
std::string item_name;
|
||||
std::vector<BuyerLineTradeItems_Struct> trade_items;
|
||||
std::string buyer_name;
|
||||
std::string seller_name;
|
||||
uint64 total_cost;
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(status),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_quantity),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(trade_items),
|
||||
CEREAL_NVP(buyer_name),
|
||||
CEREAL_NVP(seller_name),
|
||||
CEREAL_NVP(total_cost)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct EvolveItem {
|
||||
std::string status;
|
||||
uint32 item_id;
|
||||
uint64 unique_id;
|
||||
std::string item_name;
|
||||
uint32 level;
|
||||
double progression;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(status),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(unique_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(level),
|
||||
CEREAL_NVP(progression)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct PlayerSpeech {
|
||||
std::string to;
|
||||
std::string from;
|
||||
uint32 guild_id;
|
||||
int16 min_status;
|
||||
uint32 type;
|
||||
std::string message;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(to),
|
||||
CEREAL_NVP(from),
|
||||
CEREAL_NVP(guild_id),
|
||||
CEREAL_NVP(min_status),
|
||||
CEREAL_NVP(type),
|
||||
CEREAL_NVP(message)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildBankTransaction {
|
||||
uint32 char_id;
|
||||
uint32 guild_id;
|
||||
uint32 item_id;
|
||||
uint32 aug_slot_one;
|
||||
uint32 aug_slot_two;
|
||||
uint32 aug_slot_three;
|
||||
uint32 aug_slot_four;
|
||||
uint32 aug_slot_five;
|
||||
uint32 aug_slot_six;
|
||||
uint32 quantity;
|
||||
uint32 permission;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(char_id),
|
||||
CEREAL_NVP(guild_id),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(aug_slot_one),
|
||||
CEREAL_NVP(aug_slot_two),
|
||||
CEREAL_NVP(aug_slot_three),
|
||||
CEREAL_NVP(aug_slot_four),
|
||||
CEREAL_NVP(aug_slot_five),
|
||||
CEREAL_NVP(aug_slot_six),
|
||||
CEREAL_NVP(quantity)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENTS_H
|
||||
|
||||
#define RecordPlayerEventLog(event_type, event_data) do {\
|
||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||
if (RuleB(Logging, PlayerEventsQSProcess)) {\
|
||||
QServ->SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
} \
|
||||
else { \
|
||||
worldserver.SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
worldserver.SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||
if (RuleB(Logging, PlayerEventsQSProcess)) {\
|
||||
QServ->SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
(c)->GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
else {\
|
||||
worldserver.SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
(c)->GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
worldserver.SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
(c)->GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
@@ -1,303 +0,0 @@
|
||||
#include "evolving_items.h"
|
||||
#include "item_instance.h"
|
||||
#include "events/player_event_logs.h"
|
||||
#include "repositories/character_evolving_items_repository.h"
|
||||
|
||||
EvolvingItemsManager::EvolvingItemsManager()
|
||||
{
|
||||
m_db = nullptr;
|
||||
m_content_db = nullptr;
|
||||
}
|
||||
|
||||
void EvolvingItemsManager::LoadEvolvingItems() const
|
||||
{
|
||||
auto const &results = ItemsEvolvingDetailsRepository::All(*m_content_db);
|
||||
|
||||
if (results.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::ranges::transform(
|
||||
results.begin(),
|
||||
results.end(),
|
||||
std::inserter(
|
||||
evolving_items_manager.GetEvolvingItemsCache(),
|
||||
evolving_items_manager.GetEvolvingItemsCache().end()
|
||||
),
|
||||
[](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &x) {
|
||||
return std::make_pair(x.item_id, x);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void EvolvingItemsManager::SetDatabase(Database *db)
|
||||
{
|
||||
m_db = db;
|
||||
}
|
||||
|
||||
void EvolvingItemsManager::SetContentDatabase(Database *db)
|
||||
{
|
||||
m_content_db = db;
|
||||
}
|
||||
|
||||
double EvolvingItemsManager::CalculateProgression(const uint64 current_amount, const uint32 item_id)
|
||||
{
|
||||
if (!evolving_items_manager.GetEvolvingItemsCache().contains(item_id)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount > 0
|
||||
? static_cast<double>(current_amount)
|
||||
/ static_cast<double>(evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount) * 100
|
||||
: 0;
|
||||
}
|
||||
|
||||
void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_id, const EQ::ItemInstance &inst) const
|
||||
{
|
||||
inst.SetEvolveEquipped(false);
|
||||
if (inst.IsEvolving() && slot_id <= EQ::invslot::EQUIPMENT_END && slot_id >= EQ::invslot::EQUIPMENT_BEGIN) {
|
||||
inst.SetEvolveEquipped(true);
|
||||
}
|
||||
|
||||
if (!inst.IsEvolving()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inst.GetEvolveUniqueID()) {
|
||||
auto e = CharacterEvolvingItemsRepository::NewEntity();
|
||||
|
||||
e.character_id = char_id;
|
||||
e.item_id = inst.GetID();
|
||||
e.equipped = inst.GetEvolveEquipped();
|
||||
e.final_item_id = evolving_items_manager.GetFinalItemID(inst);
|
||||
|
||||
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
||||
e.id = r.id;
|
||||
|
||||
inst.SetEvolveUniqueID(e.id);
|
||||
inst.SetEvolveCharID(e.character_id);
|
||||
inst.SetEvolveItemID(e.item_id);
|
||||
inst.SetEvolveFinalItemID(e.final_item_id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterEvolvingItemsRepository::SetEquipped(*m_db, inst.GetEvolveUniqueID(), inst.GetEvolveEquipped());
|
||||
}
|
||||
|
||||
uint32 EvolvingItemsManager::GetFinalItemID(const EQ::ItemInstance &inst) const
|
||||
{
|
||||
const auto start_iterator = std::ranges::find_if(
|
||||
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
|
||||
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
||||
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
||||
return a.second.item_evo_id == inst.GetEvolveLoreID();
|
||||
}
|
||||
);
|
||||
|
||||
if (start_iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto final_id = std::ranges::max_element(
|
||||
start_iterator,
|
||||
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
||||
[&](
|
||||
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a,
|
||||
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &b
|
||||
) {
|
||||
return a.second.item_evo_id == b.second.item_evo_id &&
|
||||
a.second.item_evolve_level < b.second.item_evolve_level;
|
||||
}
|
||||
);
|
||||
|
||||
return final_id->first;
|
||||
}
|
||||
|
||||
uint32 EvolvingItemsManager::GetNextEvolveItemID(const EQ::ItemInstance &inst) const
|
||||
{
|
||||
int8 const current_level = inst.GetEvolveLvl();
|
||||
|
||||
const auto iterator = std::ranges::find_if(
|
||||
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
|
||||
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
||||
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
||||
return a.second.item_evo_id == inst.GetEvolveLoreID() &&
|
||||
a.second.item_evolve_level == current_level + 1;
|
||||
}
|
||||
);
|
||||
|
||||
if (iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return iterator->first;
|
||||
}
|
||||
|
||||
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails EvolvingItemsManager::GetEvolveItemDetails(const uint64 unique_id)
|
||||
{
|
||||
if (GetEvolvingItemsCache().contains(unique_id)) {
|
||||
return GetEvolvingItemsCache().at(unique_id);
|
||||
}
|
||||
|
||||
return ItemsEvolvingDetailsRepository::NewEntity();
|
||||
}
|
||||
|
||||
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> EvolvingItemsManager::GetEvolveIDItems(
|
||||
const uint32 evolve_id
|
||||
)
|
||||
{
|
||||
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> e{};
|
||||
|
||||
for (auto const &[key, value]: GetEvolvingItemsCache()) {
|
||||
if (value.item_evo_id == evolve_id) {
|
||||
e.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
std::ranges::sort(
|
||||
e.begin(),
|
||||
e.end(),
|
||||
[&](
|
||||
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails const &a,
|
||||
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails const &b
|
||||
) {
|
||||
return a.item_evolve_level < b.item_evolve_level;
|
||||
}
|
||||
);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
uint64 EvolvingItemsManager::GetTotalEarnedXP(const EQ::ItemInstance &inst)
|
||||
{
|
||||
if (!inst) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 xp = inst.GetEvolveCurrentAmount();
|
||||
auto evolve_id_item_cache = GetEvolveIDItems(inst.GetEvolveLoreID());
|
||||
auto current_level = inst.GetEvolveLvl();
|
||||
|
||||
for (auto const &i: evolve_id_item_cache) {
|
||||
if (i.item_evolve_level < current_level) {
|
||||
xp += i.required_amount;
|
||||
}
|
||||
}
|
||||
|
||||
return xp;
|
||||
}
|
||||
|
||||
EvolveGetNextItem EvolvingItemsManager::GetNextItemByXP(const EQ::ItemInstance &inst_in, const int64 in_xp)
|
||||
{
|
||||
EvolveGetNextItem ets{};
|
||||
const auto evolve_items = GetEvolveIDItems(inst_in.GetEvolveLoreID());
|
||||
uint32 max_transfer_level = 0;
|
||||
int64 xp = in_xp;
|
||||
|
||||
for (auto const &e: evolve_items) {
|
||||
if (e.item_evolve_level < inst_in.GetEvolveLvl()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int64 have = 0;
|
||||
if (e.item_evolve_level == inst_in.GetEvolveLvl()) {
|
||||
have = inst_in.GetEvolveCurrentAmount();
|
||||
}
|
||||
|
||||
const auto required = e.required_amount;
|
||||
const int64 need = required - have;
|
||||
const int64 balance = xp - need;
|
||||
|
||||
if (balance <= 0) {
|
||||
ets.new_current_amount = have + xp;
|
||||
ets.new_item_id = e.item_id;
|
||||
ets.from_current_amount = 0;
|
||||
ets.max_transfer_level = max_transfer_level;
|
||||
return ets;
|
||||
}
|
||||
|
||||
xp = balance;
|
||||
max_transfer_level += 1;
|
||||
|
||||
ets.new_current_amount = required;
|
||||
ets.new_item_id = e.item_id;
|
||||
ets.from_current_amount = balance - required;
|
||||
ets.max_transfer_level = max_transfer_level;
|
||||
}
|
||||
|
||||
return ets;
|
||||
}
|
||||
|
||||
EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
|
||||
const EQ::ItemInstance &inst_from,
|
||||
const EQ::ItemInstance &inst_to
|
||||
)
|
||||
{
|
||||
EvolveTransfer ets{};
|
||||
|
||||
auto evolving_details_inst_from = evolving_items_manager.GetEvolveItemDetails(inst_from.GetID());
|
||||
auto evolving_details_inst_to = evolving_items_manager.GetEvolveItemDetails(inst_to.GetID());
|
||||
|
||||
if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) {
|
||||
return ets;
|
||||
}
|
||||
|
||||
if (evolving_details_inst_from.type == evolving_details_inst_to.type) {
|
||||
uint32 compatibility = 0;
|
||||
uint64 xp = 0;
|
||||
if (evolving_details_inst_from.sub_type == evolving_details_inst_to.sub_type) {
|
||||
compatibility = 100;
|
||||
}
|
||||
else {
|
||||
compatibility = 30;
|
||||
}
|
||||
|
||||
xp = evolving_items_manager.GetTotalEarnedXP(inst_from) * compatibility / 100;
|
||||
auto results = evolving_items_manager.GetNextItemByXP(inst_to, xp);
|
||||
|
||||
ets.item_from_id = evolving_items_manager.GetFirstItemInLoreGroup(inst_from.GetEvolveLoreID());
|
||||
ets.item_from_current_amount = results.from_current_amount;
|
||||
ets.item_to_id = results.new_item_id;
|
||||
ets.item_to_current_amount = results.new_current_amount;
|
||||
ets.compatibility = compatibility;
|
||||
ets.max_transfer_level = results.max_transfer_level;
|
||||
}
|
||||
|
||||
return ets;
|
||||
}
|
||||
|
||||
uint32 EvolvingItemsManager::GetFirstItemInLoreGroup(const uint32 lore_id)
|
||||
{
|
||||
for (auto const &[key, value]: GetEvolvingItemsCache()) {
|
||||
if (value.item_evo_id == lore_id && value.item_evolve_level == 1) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 EvolvingItemsManager::GetFirstItemInLoreGroupByItemID(const uint32 item_id)
|
||||
{
|
||||
for (auto const &[key, value]: GetEvolvingItemsCache()) {
|
||||
if (value.item_id == item_id) {
|
||||
for (auto const &[key2, value2]: GetEvolvingItemsCache()) {
|
||||
if (value2.item_evo_id == value.item_evo_id && value2.item_evolve_level == 1) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EvolvingItemsManager::LoadPlayerEvent(const EQ::ItemInstance &inst, PlayerEvent::EvolveItem &e)
|
||||
{
|
||||
e.item_id = inst.GetID();
|
||||
e.item_name = inst.GetItem() ? inst.GetItem()->Name : std::string();
|
||||
e.level = inst.GetEvolveLvl();
|
||||
e.progression = inst.GetEvolveProgression();
|
||||
e.unique_id = inst.GetEvolveUniqueID();
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
#ifndef EVOLVING_H
|
||||
#define EVOLVING_H
|
||||
|
||||
#include "shareddb.h"
|
||||
#include "events/player_events.h"
|
||||
#include "repositories/items_evolving_details_repository.h"
|
||||
|
||||
namespace EQ {
|
||||
class ItemInstance;
|
||||
}
|
||||
|
||||
namespace EvolvingItems {
|
||||
namespace Actions {
|
||||
constexpr int8 UPDATE_ITEMS = 0;
|
||||
constexpr int8 TRANSFER_WINDOW_OPEN = 1;
|
||||
constexpr int8 TRANSFER_WINDOW_DETAILS = 2;
|
||||
constexpr int8 TRANSFER_XP = 3;
|
||||
constexpr int8 FINAL_RESULT = 4;
|
||||
}
|
||||
|
||||
namespace Types {
|
||||
constexpr int8 AMOUNT_OF_EXP = 1;
|
||||
constexpr int8 NUMBER_OF_KILLS = 2;
|
||||
constexpr int8 SPECIFIC_MOB_RACE = 3;
|
||||
constexpr int8 SPECIFIC_ZONE_ID = 4;
|
||||
}
|
||||
|
||||
namespace SubTypes {
|
||||
constexpr int8 ALL_EXP = 0;
|
||||
constexpr int8 SOLO_EXP = 1;
|
||||
constexpr int8 GROUP_EXP = 2;
|
||||
constexpr int8 RAID_EXP = 3;
|
||||
}
|
||||
}
|
||||
|
||||
class EvolvingItemsManager
|
||||
{
|
||||
public:
|
||||
EvolvingItemsManager();
|
||||
void SetDatabase(Database *db);
|
||||
void SetContentDatabase(Database *db);
|
||||
|
||||
void LoadEvolvingItems() const;
|
||||
void DoLootChecks(uint32 char_id, uint16 slot_id, const EQ::ItemInstance &inst) const;
|
||||
uint32 GetFinalItemID(const EQ::ItemInstance &inst) const;
|
||||
uint32 GetNextEvolveItemID(const EQ::ItemInstance &inst) const;
|
||||
uint32 GetFirstItemInLoreGroup(uint32 lore_id);
|
||||
uint32 GetFirstItemInLoreGroupByItemID(uint32 item_id);
|
||||
uint64 GetTotalEarnedXP(const EQ::ItemInstance &inst);
|
||||
static double CalculateProgression(uint64 current_amount, uint32 item_id);
|
||||
static void LoadPlayerEvent(const EQ::ItemInstance &inst, PlayerEvent::EvolveItem &e);
|
||||
|
||||
ItemsEvolvingDetailsRepository::ItemsEvolvingDetails GetEvolveItemDetails(uint64 id);
|
||||
EvolveTransfer DetermineTransferResults(const EQ::ItemInstance& inst_from, const EQ::ItemInstance& inst_to);
|
||||
EvolveGetNextItem GetNextItemByXP(const EQ::ItemInstance &inst_in, int64 in_xp);
|
||||
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails>& GetEvolvingItemsCache() { return evolving_items_cache; }
|
||||
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id);
|
||||
|
||||
private:
|
||||
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> evolving_items_cache;
|
||||
Database * m_db;
|
||||
Database * m_content_db;
|
||||
};
|
||||
|
||||
extern EvolvingItemsManager evolving_items_manager;
|
||||
|
||||
#endif //EVOLVING_H
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* 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 "expedition_lockout_timer.h"
|
||||
#include "../common/strings.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/util/uuid.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
const char* const DZ_REPLAY_TIMER_NAME = "Replay Timer"; // see December 14, 2016 patch notes
|
||||
|
||||
ExpeditionLockoutTimer::ExpeditionLockoutTimer(
|
||||
std::string expedition_uuid, std::string expedition_name,
|
||||
std::string event_name, uint64_t expire_time, uint32_t duration
|
||||
) :
|
||||
m_expedition_uuid{std::move(expedition_uuid)},
|
||||
m_expedition_name{std::move(expedition_name)},
|
||||
m_event_name{std::move(event_name)},
|
||||
m_expire_time(std::chrono::system_clock::from_time_t(expire_time)),
|
||||
m_duration(duration)
|
||||
{
|
||||
if (m_event_name == DZ_REPLAY_TIMER_NAME)
|
||||
{
|
||||
m_is_replay_timer = true;
|
||||
}
|
||||
}
|
||||
|
||||
ExpeditionLockoutTimer ExpeditionLockoutTimer::CreateLockout(
|
||||
const std::string& expedition_name, const std::string& event_name, uint32_t seconds, std::string uuid)
|
||||
{
|
||||
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
|
||||
|
||||
if (uuid.empty())
|
||||
{
|
||||
uuid = EQ::Util::UUID::Generate().ToString();
|
||||
}
|
||||
|
||||
ExpeditionLockoutTimer lockout{uuid, expedition_name, event_name, 0, seconds};
|
||||
lockout.Reset(); // sets expire time
|
||||
return lockout;
|
||||
}
|
||||
|
||||
uint32_t ExpeditionLockoutTimer::GetSecondsRemaining() const
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
if (m_expire_time > now)
|
||||
{
|
||||
auto remaining = m_expire_time - now;
|
||||
return static_cast<uint32_t>(std::chrono::duration_cast<std::chrono::seconds>(remaining).count());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExpeditionLockoutTimer::DaysHoursMinutes ExpeditionLockoutTimer::GetDaysHoursMinutesRemaining() const
|
||||
{
|
||||
auto seconds = GetSecondsRemaining();
|
||||
return ExpeditionLockoutTimer::DaysHoursMinutes{
|
||||
fmt::format_int(seconds / 86400).str(), // days
|
||||
fmt::format_int((seconds / 3600) % 24).str(), // hours
|
||||
fmt::format_int((seconds / 60) % 60).str() // minutes
|
||||
};
|
||||
}
|
||||
|
||||
bool ExpeditionLockoutTimer::IsSameLockout(const ExpeditionLockoutTimer& compare_lockout) const
|
||||
{
|
||||
return compare_lockout.IsSameLockout(GetExpeditionName(), GetEventName());
|
||||
}
|
||||
|
||||
bool ExpeditionLockoutTimer::IsSameLockout(
|
||||
const std::string& expedition_name, const std::string& event_name) const
|
||||
{
|
||||
return GetExpeditionName() == expedition_name && GetEventName() == event_name;
|
||||
}
|
||||
|
||||
void ExpeditionLockoutTimer::AddLockoutTime(int seconds)
|
||||
{
|
||||
seconds = static_cast<uint32_t>(seconds * RuleR(Expedition, LockoutDurationMultiplier));
|
||||
|
||||
auto new_duration = std::max(0, static_cast<int>(m_duration.count()) + seconds);
|
||||
|
||||
auto start_time = m_expire_time - m_duration;
|
||||
m_duration = std::chrono::seconds(new_duration);
|
||||
m_expire_time = start_time + m_duration;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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 EXPEDITION_LOCKOUT_TIMER_H
|
||||
#define EXPEDITION_LOCKOUT_TIMER_H
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
extern const char* const DZ_REPLAY_TIMER_NAME;
|
||||
|
||||
class ExpeditionLockoutTimer
|
||||
{
|
||||
public:
|
||||
ExpeditionLockoutTimer() = default;
|
||||
ExpeditionLockoutTimer(
|
||||
std::string expedition_uuid, std::string expedition_name,
|
||||
std::string event_name, uint64_t expire_time, uint32_t duration);
|
||||
|
||||
static ExpeditionLockoutTimer CreateLockout(
|
||||
const std::string& expedition_name, const std::string& event_name,
|
||||
uint32_t seconds, std::string uuid = {});
|
||||
|
||||
struct DaysHoursMinutes
|
||||
{
|
||||
std::string days;
|
||||
std::string hours;
|
||||
std::string mins;
|
||||
};
|
||||
|
||||
void AddLockoutTime(int seconds);
|
||||
uint32_t GetDuration() const { return static_cast<uint32_t>(m_duration.count()); }
|
||||
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
||||
uint64_t GetStartTime() const { return std::chrono::system_clock::to_time_t(m_expire_time - m_duration); }
|
||||
uint32_t GetSecondsRemaining() const;
|
||||
DaysHoursMinutes GetDaysHoursMinutesRemaining() const;
|
||||
const std::string& GetExpeditionName() const { return m_expedition_name; }
|
||||
const std::string& GetExpeditionUUID() const { return m_expedition_uuid; }
|
||||
const std::string& GetEventName() const { return m_event_name; }
|
||||
bool IsExpired() const { return GetSecondsRemaining() == 0; }
|
||||
bool IsFromExpedition(const std::string& uuid) const { return uuid == m_expedition_uuid; }
|
||||
bool IsReplayTimer() const { return m_is_replay_timer; }
|
||||
bool IsSameLockout(const ExpeditionLockoutTimer& compare_lockout) const;
|
||||
bool IsSameLockout(const std::string& expedition_name, const std::string& event_name) const;
|
||||
void Reset() { m_expire_time = std::chrono::system_clock::now() + m_duration; }
|
||||
void SetDuration(uint32_t seconds) { m_duration = std::chrono::seconds(seconds); }
|
||||
void SetExpireTime(uint64_t expire_time) { m_expire_time = std::chrono::system_clock::from_time_t(expire_time); }
|
||||
void SetUUID(const std::string& uuid) { m_expedition_uuid = uuid; }
|
||||
|
||||
private:
|
||||
bool m_is_replay_timer = false;
|
||||
std::string m_expedition_uuid; // expedition received in
|
||||
std::string m_expedition_name;
|
||||
std::string m_event_name;
|
||||
std::chrono::seconds m_duration;
|
||||
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
|
||||
};
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -96,12 +96,12 @@ bool IsOfEqualRace(int r1, int r2)
|
||||
// TODO: add more values
|
||||
switch (r1) {
|
||||
case DARK_ELF:
|
||||
if (r2 == Race::NeriakCitizen) {
|
||||
if (r2 == RACE_NERIAK_CITIZEN_77) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case BARBARIAN:
|
||||
if (r2 == Race::HalasCitizen) {
|
||||
if (r2 == RACE_HALAS_CITIZEN_90) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-8
@@ -24,15 +24,17 @@
|
||||
#include <string>
|
||||
|
||||
enum FACTION_VALUE {
|
||||
FACTION_ALLY = 1,
|
||||
FACTION_WARMLY = 2,
|
||||
FACTION_KINDLY = 3,
|
||||
FACTION_AMIABLY = 4,
|
||||
FACTION_INDIFFERENTLY = 5,
|
||||
FACTION_ALLY = 1,
|
||||
FACTION_WARMLY = 2,
|
||||
FACTION_KINDLY = 3,
|
||||
FACTION_AMIABLY = 4,
|
||||
|
||||
FACTION_INDIFFERENTLY = 5,
|
||||
|
||||
FACTION_APPREHENSIVELY = 6,
|
||||
FACTION_DUBIOUSLY = 7,
|
||||
FACTION_THREATENINGLY = 8,
|
||||
FACTION_SCOWLS = 9
|
||||
FACTION_DUBIOUSLY = 7,
|
||||
FACTION_THREATENINGLY = 8,
|
||||
FACTION_SCOWLS = 9
|
||||
};
|
||||
|
||||
struct NPCFactionList {
|
||||
@@ -73,6 +75,23 @@ struct NPCFaction
|
||||
uint8 temp;
|
||||
};
|
||||
|
||||
// Faction Associations give a much more live like faction system
|
||||
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
|
||||
|
||||
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
|
||||
#define MAX_FACTION_ASSOC 10
|
||||
|
||||
// this is the ID of a faction association and it's multiplier
|
||||
struct FactionAssociationHit {
|
||||
int id;
|
||||
float multiplier;
|
||||
};
|
||||
|
||||
struct FactionAssociations {
|
||||
// maybe there should be more data here, fine for now
|
||||
FactionAssociationHit hits[MAX_FACTION_ASSOC];
|
||||
};
|
||||
|
||||
const char *FactionValueToString(FACTION_VALUE faction_value);
|
||||
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
||||
#endif
|
||||
|
||||
+43
-3
@@ -35,6 +35,11 @@ Core Zone features
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//Uncomment this to cause a zone to basically idle
|
||||
//when there are no players in it, mobs stop wandering, etc..
|
||||
#define IDLE_WHEN_EMPTY
|
||||
|
||||
#ifdef EMBPERL
|
||||
//Enable the new XS based perl parser
|
||||
#define EMBPERL_XS
|
||||
@@ -213,14 +218,14 @@ enum { //some random constants
|
||||
#define HARD_LEVEL_CAP 127
|
||||
|
||||
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
||||
#define USE_NPC_RANGE2 40000 //arbitrary right now
|
||||
#define USE_NPC_RANGE2 200*200 //arbitrary right now
|
||||
|
||||
// Squared range for rampage 75.0 * 75.0 for now
|
||||
#define NPC_RAMPAGE_RANGE2 5625.0f
|
||||
|
||||
//the formula for experience for killing a mob.
|
||||
//level is the only valid variable to use
|
||||
#define EXP_FORMULA (level * level * 75 * 35 / 10)
|
||||
#define EXP_FORMULA level*level*75*35/10
|
||||
|
||||
#define HIGHEST_AA_VALUE 35
|
||||
|
||||
@@ -233,6 +238,41 @@ enum { //some random constants
|
||||
// Timer to update aggrometer
|
||||
#define AGGRO_METER_UPDATE_MS 1000
|
||||
|
||||
//Some hard coded statuses from commands and other places:
|
||||
enum {
|
||||
minStatusToBeGM = 40,
|
||||
minStatusToUseGMCommands = 80,
|
||||
minStatusToKick = 150,
|
||||
minStatusToAvoidFalling = 100,
|
||||
minStatusToHaveInvalidSpells = 80,
|
||||
minStatusToHaveInvalidSkills = 80,
|
||||
minStatusToIgnoreZoneFlags = 80,
|
||||
minStatusToSeeOthersZoneFlags = 80,
|
||||
minStatusToEditOtherGuilds = 80,
|
||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
||||
commandZoneToSpecials = 80, //zone to cshome, out of load zones
|
||||
commandToggleAI = 250, //can turn NPC AI on and off
|
||||
commandCastSpecials = 100, //can cast special spells
|
||||
commandInstacast = 100, //insta-cast all #casted spells
|
||||
commandLevelAboveCap = 100, //can #level players above level cap
|
||||
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
|
||||
commandSetSkillsOther = 100, //ability to setskills on others
|
||||
commandRaceOthers = 100, //ability to #race on others
|
||||
commandGenderOthers = 100, //ability to #gender on others
|
||||
commandTextureOthers = 100, //ability to #texture on others
|
||||
commandDoAnimOthers = 100, //can #doanim on others
|
||||
commandLockZones = 101, //can lock or unlock zones
|
||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
||||
commandChangeFlags = 200, //ability to set/refresh flags
|
||||
commandBanPlayers = 100, //can set bans on players
|
||||
commandChangeDatarate = 201, //edit client's data rate
|
||||
commandZoneToCoords = 0, //can #zone with coords
|
||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
||||
};
|
||||
|
||||
|
||||
// This is the item ID we use for say links, we use the max that fits in 5 ASCII chars
|
||||
#define SAYLINK_ITEM_ID 0xFFFFF
|
||||
|
||||
@@ -255,7 +295,7 @@ Developer configuration
|
||||
|
||||
#define COMMON_PROFILE
|
||||
|
||||
#define PROFILE_DUMP_TIME 180
|
||||
#define PROFILE_DUMP_TIME 3*60
|
||||
#endif //EQPROFILE
|
||||
|
||||
|
||||
|
||||
+10
-40
@@ -37,32 +37,25 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
bool File::Exists(const std::string &name)
|
||||
{
|
||||
struct stat sb{};
|
||||
if (stat(name.c_str(), &sb) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return fs::exists(fs::path{name});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param directory_name
|
||||
*/
|
||||
void File::Makedir(const std::string &directory_name)
|
||||
{
|
||||
try {
|
||||
fs::create_directory(directory_name);
|
||||
fs::permissions(directory_name, fs::perms::owner_all);
|
||||
}
|
||||
catch (const fs::filesystem_error &ex) {
|
||||
std::cout << "Failed to create directory: " << directory_name << std::endl;
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
fs::create_directory(directory_name);
|
||||
fs::permissions(directory_name, fs::perms::owner_all);
|
||||
}
|
||||
|
||||
std::string File::FindEqemuConfigPath()
|
||||
@@ -87,26 +80,3 @@ std::string File::GetCwd()
|
||||
{
|
||||
return fs::current_path().string();
|
||||
}
|
||||
|
||||
FileContentsResult File::GetContents(const std::string &file_name)
|
||||
{
|
||||
std::string error;
|
||||
std::ifstream f;
|
||||
f.open(file_name);
|
||||
std::string line;
|
||||
std::string lines;
|
||||
if (f.is_open()) {
|
||||
while (f) {
|
||||
std::getline(f, line);
|
||||
lines += line + "\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
error = fmt::format("Couldn't open file [{}]", file_name);
|
||||
}
|
||||
|
||||
return FileContentsResult{
|
||||
.contents = lines,
|
||||
.error = error,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -25,16 +25,10 @@
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct FileContentsResult {
|
||||
std::string contents;
|
||||
std::string error;
|
||||
};
|
||||
|
||||
class File {
|
||||
public:
|
||||
static bool Exists(const std::string &name);
|
||||
static void Makedir(const std::string& directory_name);
|
||||
static FileContentsResult GetContents(const std::string &file_name);
|
||||
static std::string FindEqemuConfigPath();
|
||||
static std::string GetCwd();
|
||||
};
|
||||
|
||||
+831
-1014
File diff suppressed because it is too large
Load Diff
+83
-136
@@ -5,42 +5,6 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "timer.h"
|
||||
#include "../common/repositories/guild_members_repository.h"
|
||||
#include "../common/repositories/guilds_repository.h"
|
||||
|
||||
struct DefaultPermissionStruct {
|
||||
GuildAction id;
|
||||
uint32 value;
|
||||
};
|
||||
|
||||
struct DefaultRankNamesStruct {
|
||||
uint32 id;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct GuildTributeStruct {
|
||||
Timer timer;
|
||||
uint32 id_1;
|
||||
uint32 id_2;
|
||||
uint32 id_1_tier;
|
||||
uint32 id_2_tier;
|
||||
uint32 favor;
|
||||
uint32 time_remaining;
|
||||
uint32 enabled;
|
||||
bool send_timer;
|
||||
};
|
||||
|
||||
class TributeData {
|
||||
public:
|
||||
//this level data stored in regular byte order and must be flipped before sending
|
||||
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
|
||||
uint8 tier_count;
|
||||
uint32 unknown;
|
||||
std::string name;
|
||||
std::string description;
|
||||
bool is_guild; //is a guild tribute item
|
||||
};
|
||||
|
||||
class Database;
|
||||
|
||||
@@ -48,23 +12,22 @@ class CharGuildInfo
|
||||
{
|
||||
public:
|
||||
//fields from `characer_`
|
||||
uint32 char_id;
|
||||
uint32 char_id;
|
||||
std::string char_name;
|
||||
uint8 class_;
|
||||
uint16 level;
|
||||
uint32 time_last_on;
|
||||
uint32 zone_id;
|
||||
uint8 class_;
|
||||
uint16 level;
|
||||
uint32 time_last_on;
|
||||
uint32 zone_id;
|
||||
|
||||
//fields from `guild_members`
|
||||
uint32 guild_id;
|
||||
uint8 rank;
|
||||
bool tribute_enable;
|
||||
uint32 total_tribute;
|
||||
uint32 last_tribute; //timestamp
|
||||
bool banker;
|
||||
bool alt;
|
||||
uint32 guild_id;
|
||||
uint8 rank;
|
||||
bool tribute_enable;
|
||||
uint32 total_tribute;
|
||||
uint32 last_tribute; //timestamp
|
||||
bool banker;
|
||||
bool alt;
|
||||
std::string public_note;
|
||||
bool online;
|
||||
};
|
||||
|
||||
//this object holds guild functionality shared between world and zone.
|
||||
@@ -75,31 +38,21 @@ class BaseGuildManager
|
||||
virtual ~BaseGuildManager();
|
||||
|
||||
//this must be called before doing anything else with this object
|
||||
BaseGuildManager * SetDatabase(Database *db)
|
||||
void SetDatabase(Database *db)
|
||||
{
|
||||
m_db = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
BaseGuildManager * SetContentDatabase(Database *db)
|
||||
{
|
||||
m_content_db = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
bool LoadGuilds();
|
||||
virtual bool RefreshGuild(uint32 guild_id);
|
||||
bool RefreshGuild(uint32 guild_id);
|
||||
|
||||
//guild edit actions.
|
||||
uint32 CreateGuild(std::string name, uint32 leader_char_id);
|
||||
bool StoreGuildDB(uint32 guild_id);
|
||||
uint32 CreateGuild(const char* name, uint32 leader_char_id);
|
||||
bool DeleteGuild(uint32 guild_id);
|
||||
bool RenameGuild(uint32 guild_id, std::string name);
|
||||
bool SetGuildMOTD(uint32 guild_id, std::string motd, std::string setter);
|
||||
bool SetGuildURL(uint32 guild_id, std::string URL);
|
||||
bool SetGuildChannel(uint32 guild_id, std::string Channel);
|
||||
bool RenameGuild(uint32 guild_id, const char* name);
|
||||
bool SetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
||||
bool SetGuildURL(uint32 GuildID, const char* URL);
|
||||
bool SetGuildChannel(uint32 GuildID, const char* Channel);
|
||||
|
||||
//character edit actions
|
||||
bool SetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
@@ -109,16 +62,9 @@ class BaseGuildManager
|
||||
bool ForceRankUpdate(uint32 charid);
|
||||
bool GetAltFlag(uint32 CharID);
|
||||
bool SetAltFlag(uint32 charid, bool is_alt);
|
||||
bool GetBankerFlag(uint32 CharID, bool compat_mode = false);
|
||||
bool GetGuildBankerStatus(uint32 guild_id, uint32 guild_rank);
|
||||
bool GetBankerFlag(uint32 CharID);
|
||||
bool SetTributeFlag(uint32 charid, bool enabled);
|
||||
bool SetPublicNote(uint32 charid, std::string public_note);
|
||||
uint32 UpdateDbGuildFavor(uint32 guild_id, uint32 enabled);
|
||||
bool UpdateDbGuildTributeEnabled(uint32 guild_id, uint32 enabled);
|
||||
bool UpdateDbMemberTributeEnabled(uint32 guild_id, uint32 char_id, uint32 enabled);
|
||||
bool UpdateDbTributeTimeRemaining(uint32 guild_id, uint32 enabled);
|
||||
uint32 UpdateDbMemberFavor(uint32 guild_id, uint32 char_id, uint32 favor);
|
||||
bool UpdateDbMemberOnline(uint32 char_id, bool status);
|
||||
bool SetPublicNote(uint32 charid, const char *note);
|
||||
|
||||
//queries
|
||||
bool GetCharInfo(const char *char_name, CharGuildInfo &into);
|
||||
@@ -128,24 +74,29 @@ class BaseGuildManager
|
||||
bool GetGuildMOTD(uint32 guild_id, char *motd_buffer, char *setter_buffer) const;
|
||||
bool GetGuildURL(uint32 GuildID, char *URLBuffer) const;
|
||||
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
||||
bool GetGuildNameByID(uint32 guild_id, std::string& into) const;
|
||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
||||
bool UpdateDbBankerFlag(uint32 charid, bool is_banker);
|
||||
GuildsListMessaging_Struct MakeGuildList();
|
||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||
uint32 GetGuildIDByName(const char *GuildName);
|
||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
||||
uint32 FindGuildByLeader(uint32 leader) const;
|
||||
uint32 NumberInGuild(uint32 guild_id);
|
||||
uint32 DoesAccountContainAGuildLeader(uint32 AccountID);
|
||||
const char* GetRankName(uint32 guild_id, uint8 rank) const;
|
||||
const char* GetGuildName(uint32 guild_id) const;
|
||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
||||
std::vector<GuildMembersRepository::GuildMembers> GetGuildMembers(uint32 guild_id);
|
||||
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
||||
const char *GetGuildName(uint32 guild_id) const;
|
||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
||||
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
||||
uint32 GetGuildIDByName(const char *GuildName);
|
||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
||||
// uint32 Getguild_id(uint32 eqid);
|
||||
uint32 FindGuildByLeader(uint32 leader) const;
|
||||
// void GetGuildMembers(uint32 guild_id,GuildMember_Struct* gms);
|
||||
uint32 NumberInGuild(uint32 guild_id);
|
||||
// bool GetGuildRanks(uint32 guildeqid, GuildRanks_Struct* gr);
|
||||
// bool EditGuild(uint32 guild_id, uint8 ranknum, GuildRankLevel_Struct* grl);
|
||||
|
||||
uint8 *MakeGuildList(const char *head_name, uint32 &length) const; //make a guild list packet, returns ownership of the buffer.
|
||||
|
||||
static const char *const GuildActionNames[_MaxGuildAction];
|
||||
uint32 DoesAccountContainAGuildLeader(uint32 AccountID);
|
||||
|
||||
protected:
|
||||
//the methods which must be defined by base classes.
|
||||
@@ -154,62 +105,58 @@ class BaseGuildManager
|
||||
virtual void SendRankUpdate(uint32 CharID) = 0;
|
||||
virtual void SendGuildDelete(uint32 guild_id) = 0;
|
||||
|
||||
uint32 UpdateDbCreateGuild(std::string name, uint32 leader_char_id);
|
||||
bool UpdateDbDeleteGuild(uint32 guild_id, bool local_delete = true, bool db_delete = true);
|
||||
bool UpdateDbRenameGuild(uint32 guild_id, std::string name);
|
||||
bool UpdateDbGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
bool UpdateDbGuildMOTD(uint32 guild_id, std::string motd, std::string setter);
|
||||
bool UpdateDbGuildURL(uint32 GuildID, std::string URL);
|
||||
bool UpdateDbGuildChannel(uint32 GuildID, std::string Channel);
|
||||
bool UpdateDbGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
||||
bool UpdateDbGuildRank(uint32 charid, uint8 rank);
|
||||
bool UpdateDbAltFlag(uint32 charid, bool is_alt);
|
||||
bool UpdateDbTributeFlag(uint32 charid, bool enabled);
|
||||
bool UpdateDbPublicNote(uint32 charid, std::string public_note);
|
||||
uint32 DBCreateGuild(const char* name, uint32 leader_char_id);
|
||||
bool DBDeleteGuild(uint32 guild_id);
|
||||
bool DBRenameGuild(uint32 guild_id, const char* name);
|
||||
bool DBSetGuildLeader(uint32 guild_id, uint32 leader_char_id);
|
||||
bool DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter);
|
||||
bool DBSetGuildURL(uint32 GuildID, const char* URL);
|
||||
bool DBSetGuildChannel(uint32 GuildID, const char* Channel);
|
||||
bool DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank);
|
||||
bool DBSetGuildRank(uint32 charid, uint8 rank);
|
||||
bool DBSetBankerFlag(uint32 charid, bool is_banker);
|
||||
bool DBSetAltFlag(uint32 charid, bool is_alt);
|
||||
bool DBSetTributeFlag(uint32 charid, bool enabled);
|
||||
bool DBSetPublicNote(uint32 charid, const char *note);
|
||||
bool QueryWithLogging(std::string query, const char *errmsg);
|
||||
// void DBSetPublicNote(uint32 guild_id,char* charname, char* note);
|
||||
|
||||
bool LocalDeleteGuild(uint32 guild_id);
|
||||
|
||||
struct RankInfo
|
||||
class RankInfo
|
||||
{
|
||||
RankInfo();
|
||||
std::string rank_name;
|
||||
public:
|
||||
RankInfo();
|
||||
std::string name;
|
||||
bool permissions[_MaxGuildAction];
|
||||
};
|
||||
struct Functions
|
||||
class GuildInfo
|
||||
{
|
||||
uint32 id;
|
||||
uint32 perm_id;
|
||||
uint32 guild_id;
|
||||
uint32 perm_value;
|
||||
};
|
||||
public:
|
||||
class GuildInfo {
|
||||
public:
|
||||
GuildInfo();
|
||||
std::string name;
|
||||
std::string motd;
|
||||
std::string motd_setter;
|
||||
std::string url;
|
||||
std::string channel;
|
||||
uint32 leader;
|
||||
uint8 minstatus;
|
||||
std::string rank_names[GUILD_MAX_RANK + 1];
|
||||
Functions functions[GUILD_MAX_FUNCTIONS + 1];
|
||||
GuildTributeStruct tribute;
|
||||
};
|
||||
virtual BaseGuildManager::GuildInfo* GetGuildByGuildID(uint32 guild_id);
|
||||
uint32 GetGuildTributeTimeRemaining(uint32 guild_id);
|
||||
public:
|
||||
GuildInfo();
|
||||
std::string name;
|
||||
std::string motd;
|
||||
std::string motd_setter;
|
||||
std::string url;
|
||||
std::string channel;
|
||||
|
||||
uint32 leader_char_id;
|
||||
uint8 minstatus;
|
||||
//tribute is not in here on purpose, since it is only valid in world!
|
||||
RankInfo ranks[GUILD_MAX_RANK + 1];
|
||||
};
|
||||
|
||||
protected:
|
||||
std::map<uint32, GuildInfo *> m_guilds; //we own the pointers in this map
|
||||
void ClearGuilds(); //clears internal structure
|
||||
|
||||
Database *m_db;
|
||||
Database *m_content_db;
|
||||
Database *m_db; //we do not own this
|
||||
|
||||
bool _StoreGuildDB(uint32 guild_id);
|
||||
GuildInfo* _CreateGuild(uint32 guild_id, std::string guild_name, uint32 leader_char_id, uint8 minstatus, std::string guild_motd, std::string motd_setter, std::string Channel, std::string URL, uint32 favour);
|
||||
GuildsRepository::Guilds CreateGuildRepoFromGuildInfo(uint32 guild_id, BaseGuildManager::GuildInfo& in);
|
||||
GuildInfo *_CreateGuild(uint32 guild_id, const char *guild_name, uint32 account_id, uint8 minstatus, const char *guild_motd, const char *motd_setter, const char *Channel, const char *URL);
|
||||
uint32 _GetFreeGuildID();
|
||||
};
|
||||
|
||||
|
||||
#endif /*GUILD_BASE_H_*/
|
||||
|
||||
|
||||
|
||||
+16
-56
@@ -16,71 +16,31 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef GUILDS_H
|
||||
#define GUILDS_H
|
||||
#ifndef GUILD_H
|
||||
#define GUILD_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define GUILD_NONE 0xFFFFFFFF // user has no guild
|
||||
|
||||
#define GUILD_MAX_RANK 8 // 0-2 - some places in the code assume a single digit, dont go above 9
|
||||
#define GUILD_MAX_FUNCTIONS 30
|
||||
#define GUILD_TRIBUTES_MODIFY 1
|
||||
#define GUILD_TRIBUTES_SAVE 0
|
||||
#define GUILD_TRIBUTES_OFF 0
|
||||
#define GUILD_TRIBUTES_ON 1
|
||||
#define GUILD_INVITE_DECLINE 9
|
||||
#define GUILD_MAX_RANK 8 // 0-2 - some places in the code assume a single digit, dont go above 9
|
||||
|
||||
//defines for standard ranks
|
||||
#define GUILD_MEMBER_TI 0
|
||||
#define GUILD_OFFICER_TI 1
|
||||
#define GUILD_LEADER_TI 2
|
||||
#define GUILD_RANK_NONE_TI (GUILD_MAX_RANK + 1)
|
||||
|
||||
//defines for standard ranks base on RoF2 definitions
|
||||
#define GUILD_RANK_NONE 0
|
||||
#define GUILD_LEADER 1
|
||||
#define GUILD_SENIOR_OFFICER 2
|
||||
#define GUILD_OFFICER 3
|
||||
#define GUILD_SENIOR_MEMBER 4
|
||||
#define GUILD_MEMBER 5
|
||||
#define GUILD_JUNIOR_MEMBER 6
|
||||
#define GUILD_INITIATE 7
|
||||
#define GUILD_RECRUIT 8
|
||||
#define GUILD_MEMBER 0
|
||||
#define GUILD_OFFICER 1
|
||||
#define GUILD_LEADER 2
|
||||
#define GUILD_RANK_NONE (GUILD_MAX_RANK+1)
|
||||
|
||||
typedef enum {
|
||||
GUILD_ACTION_BANNER_CHANGE = 1,
|
||||
GUILD_ACTION_BANNER_PLANT = 2,
|
||||
GUILD_ACTION_BANNER_REMOVE = 3,
|
||||
GUILD_ACTION_DISPLAY_GUILD_NAME = 4,
|
||||
GUILD_ACTION_RANKS_CHANGE_PERMISSIONS = 5,
|
||||
GUILD_ACTION_RANKS_CHANGE_RANK_NAMES = 6,
|
||||
GUILD_ACTION_MEMBERS_INVITE = 7,
|
||||
GUILD_ACTION_MEMBERS_PROMOTE = 8,
|
||||
GUILD_ACTION_MEMBERS_DEMOTE = 9,
|
||||
GUILD_ACTION_MEMBERS_REMOVE = 10,
|
||||
GUILD_ACTION_EDIT_RECRUITING_SETTINGS = 11,
|
||||
GUILD_ACTION_EDIT_PUBLIC_NOTES = 12,
|
||||
GUILD_ACTION_BANK_DEPOSIT_ITEMS = 13,
|
||||
GUILD_ACTION_BANK_WITHDRAW_ITEMS = 14,
|
||||
GUILD_ACTION_BANK_VIEW_ITEMS = 15,
|
||||
GUILD_ACTION_BANK_PROMOTE_ITEMS = 16,
|
||||
GUILD_ACTION_BANK_CHANGE_ITEM_PERMISSIONS = 17,
|
||||
GUILD_ACTION_CHANGE_THE_MOTD = 18,
|
||||
GUILD_ACTION_GUILD_CHAT_SEE = 19,
|
||||
GUILD_ACTION_GUILD_CHAT_SPEAK_IN = 20,
|
||||
GUILD_ACTION_SEND_THE_WHOLE_GUILD_E_MAIL = 21,
|
||||
GUILD_ACTION_TRIBUTE_CHANGE_FOR_OTHERS = 22,
|
||||
GUILD_ACTION_TRIBUTE_CHANGE_ACTIVE_BENEFIT = 23,
|
||||
GUILD_ACTION_TROPHY_TRIBUTE_CHANGE_FOR_OTHERS = 24,
|
||||
GUILD_ACTION_TROPHY_TRIBUTE_CHANGE_ACTIVE_BENEFIT = 25,
|
||||
GUILD_ACTION_MEMBERS_CHANGE_ALT_FLAG_FOR_OTHER = 26,
|
||||
GUILD_ACTION_REAL_ESTATE_GUILD_PLOT_BUY = 27,
|
||||
GUILD_ACTION_REAL_ESTATE_GUILD_PLOT_SELL = 28,
|
||||
GUILD_ACTION_REAL_ESTATE_MODIFY_TROPHIES = 29,
|
||||
GUILD_ACTION_MEMBERS_DEMOTE_SELF = 30,
|
||||
GUILD_HEAR = 0,
|
||||
GUILD_SPEAK = 1,
|
||||
GUILD_INVITE = 2,
|
||||
GUILD_REMOVE = 3,
|
||||
GUILD_PROMOTE = 4,
|
||||
GUILD_DEMOTE = 5,
|
||||
GUILD_MOTD = 6,
|
||||
GUILD_WARPEACE = 7,
|
||||
_MaxGuildAction
|
||||
} GuildAction;
|
||||
|
||||
constexpr int format_as(GuildAction action) { return static_cast<int>(action); }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6690,7 +6690,7 @@ static WSInit wsinit_;
|
||||
if (params.empty()) { return Get(path, headers); }
|
||||
|
||||
std::string path_with_query = append_query_params(path, params);
|
||||
return Get(path_with_query, headers, progress);
|
||||
return Get(path_with_query.c_str(), headers, progress);
|
||||
}
|
||||
|
||||
inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
||||
@@ -6710,7 +6710,7 @@ static WSInit wsinit_;
|
||||
}
|
||||
|
||||
std::string path_with_query = append_query_params(path, params);
|
||||
return Get(path_with_query, headers, response_handler,
|
||||
return Get(path_with_query.c_str(), headers, response_handler,
|
||||
content_receiver, progress);
|
||||
}
|
||||
|
||||
@@ -6807,7 +6807,7 @@ static WSInit wsinit_;
|
||||
std::string content_type;
|
||||
const auto &body = detail::serialize_multipart_formdata(
|
||||
items, detail::make_multipart_data_boundary(), content_type);
|
||||
return Post(path, headers, body, content_type);
|
||||
return Post(path, headers, body, content_type.c_str());
|
||||
}
|
||||
|
||||
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
||||
@@ -6820,7 +6820,7 @@ static WSInit wsinit_;
|
||||
std::string content_type;
|
||||
const auto &body =
|
||||
detail::serialize_multipart_formdata(items, boundary, content_type);
|
||||
return Post(path, headers, body, content_type);
|
||||
return Post(path, headers, body, content_type.c_str());
|
||||
}
|
||||
|
||||
inline Result ClientImpl::Put(const std::string &path) {
|
||||
|
||||
+479
-829
File diff suppressed because it is too large
Load Diff
+16
-21
@@ -57,8 +57,6 @@ public:
|
||||
|
||||
inline std::list<EQ::ItemInstance*>::const_iterator cbegin() { return m_list.cbegin(); }
|
||||
inline std::list<EQ::ItemInstance*>::const_iterator cend() { return m_list.cend(); }
|
||||
inline std::list<EQ::ItemInstance*>::iterator begin() { return m_list.begin(); }
|
||||
inline std::list<EQ::ItemInstance*>::iterator end() { return m_list.end(); }
|
||||
|
||||
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
|
||||
inline bool empty() { return m_list.empty(); }
|
||||
@@ -134,7 +132,7 @@ namespace EQ
|
||||
|
||||
// Swap items in inventory
|
||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = Race::Doug, uint8 class_id = Class::None, uint32 deity_id = Deity::Unknown, uint8 level = 0);
|
||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = RACE_DOUG_0, uint8 class_id = NO_CLASS, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
||||
|
||||
// Remove item from inventory
|
||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
||||
@@ -149,13 +147,13 @@ namespace EQ
|
||||
bool HasItemEquippedByID(uint32 item_id);
|
||||
|
||||
// Check how many of a specific item the player has equipped by Item ID
|
||||
uint32 CountItemEquippedByID(uint32 item_id);
|
||||
int CountItemEquippedByID(uint32 item_id);
|
||||
|
||||
// Check if player has a specific augment equipped by Item ID
|
||||
bool HasAugmentEquippedByID(uint32 item_id);
|
||||
|
||||
// Check how many of a specific augment the player has equipped by Item ID
|
||||
uint32 CountAugmentEquippedByID(uint32 item_id);
|
||||
int CountAugmentEquippedByID(uint32 item_id);
|
||||
|
||||
// Get a list of augments from a specific slot ID
|
||||
std::vector<uint32> GetAugmentIDsBySlotID(int16 slot_id);
|
||||
@@ -178,8 +176,6 @@ namespace EQ
|
||||
// Locate an available inventory slot
|
||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
||||
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
|
||||
int16 FindFirstFreeSlotThatFitsItemWithStacking(ItemInstance *inst) const;
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||
@@ -201,25 +197,26 @@ namespace EQ
|
||||
|
||||
uint8 FindBrightestLightType();
|
||||
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
|
||||
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
|
||||
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
|
||||
|
||||
std::map<int16, ItemInstance*>& GetWorn() { return m_worn; }
|
||||
std::map<int16, ItemInstance*>& GetPersonal() { return m_inv; }
|
||||
int16 HasEvolvingItem(uint64 evolve_unique_id, uint8 quantity, uint8 where);
|
||||
|
||||
inline int16 PushItem(int16 slot_id, ItemInstance* inst) { return _PutItem(slot_id, inst); }
|
||||
void dumpEntireInventory();
|
||||
void dumpWornItems();
|
||||
void dumpInventory();
|
||||
void dumpBankItems();
|
||||
void dumpSharedBankItems();
|
||||
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||
static const int GetItemStatValue(uint32 item_id, std::string identifier);
|
||||
protected:
|
||||
///////////////////////////////
|
||||
// Protected Methods
|
||||
///////////////////////////////
|
||||
|
||||
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
|
||||
void dumpItemCollection(const std::map<int16, ItemInstance*> &collection);
|
||||
void dumpBagContents(ItemInstance *inst, std::map<int16, ItemInstance*>::const_iterator *it);
|
||||
|
||||
// Retrieves item within an inventory bucket
|
||||
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
|
||||
@@ -234,8 +231,6 @@ namespace EQ
|
||||
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
|
||||
int16 _HasItemByLoreGroup(std::map<int16, ItemInstance*>& bucket, uint32 loregroup);
|
||||
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
|
||||
int16 _HasEvolvingItem(std::map<int16, ItemInstance*>& bucket, uint64 evolve_unique_id, uint8 quantity);
|
||||
int16 _HasEvolvingItem(ItemInstQueue& iqueue, uint64 evolve_unique_id, uint8 quantity);
|
||||
|
||||
|
||||
// Player inventory
|
||||
|
||||
+21
-55
@@ -81,79 +81,45 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* Gets local address - pings google to inspect what interface was used locally
|
||||
* @return
|
||||
*/
|
||||
std::string IpUtil::GetLocalIPAddress()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
char my_ip_address[INET_ADDRSTRLEN];
|
||||
char my_ip_address[16];
|
||||
unsigned int my_port;
|
||||
struct sockaddr_in server_address{};
|
||||
struct sockaddr_in my_address{};
|
||||
int sockfd;
|
||||
int sockfd;
|
||||
|
||||
// Create a UDP socket
|
||||
#ifdef _WIN32
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd == INVALID_SOCKET) {
|
||||
WSACleanup();
|
||||
return "";
|
||||
}
|
||||
#else
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) {
|
||||
// Connect to server
|
||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set server_addr (dummy address)
|
||||
// Set server_addr
|
||||
memset(&server_address, 0, sizeof(server_address));
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = inet_addr("8.8.8.8"); // Google DNS
|
||||
server_address.sin_port = htons(53); // DNS port
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
|
||||
server_address.sin_port = htons(80);
|
||||
|
||||
// Perform a dummy connection to the server (UDP)
|
||||
connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
|
||||
// Connect to server
|
||||
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
|
||||
close(sockfd);
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get my IP address
|
||||
// Get my ip address and port
|
||||
memset(&my_address, 0, sizeof(my_address));
|
||||
socklen_t len = sizeof(my_address);
|
||||
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
|
||||
inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address));
|
||||
my_port = ntohs(my_address.sin_port);
|
||||
|
||||
#ifdef _WIN32
|
||||
closesocket(sockfd);
|
||||
WSACleanup();
|
||||
#else
|
||||
close(sockfd);
|
||||
#endif
|
||||
|
||||
LogInfo("Local IP Address [{}]", my_ip_address);
|
||||
|
||||
return std::string(my_ip_address);
|
||||
return fmt::format("{}", my_ip_address);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets public address
|
||||
* Uses various websites as options to return raw public IP back to the client
|
||||
|
||||
@@ -220,34 +220,6 @@ bool EQ::ItemData::IsType1HWeapon() const
|
||||
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing) || (ItemType == item::ItemTypeMartial));
|
||||
}
|
||||
|
||||
bool EQ::ItemData::IsPetUsable() const
|
||||
{
|
||||
if (ItemClass == item::ItemClassBag) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if it's a misc item and has slots, it's wearable
|
||||
// this item type is conflated with many other item types
|
||||
if (ItemClass == item::ItemTypeMisc && Slots != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ItemType) {
|
||||
case item::ItemType1HBlunt:
|
||||
case item::ItemType1HSlash:
|
||||
case item::ItemType1HPiercing:
|
||||
case item::ItemType2HBlunt:
|
||||
case item::ItemType2HSlash:
|
||||
case item::ItemTypeMartial:
|
||||
case item::ItemTypeShield:
|
||||
case item::ItemTypeArmor:
|
||||
case item::ItemTypeJewelry:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::ItemData::IsType2HWeapon() const
|
||||
{
|
||||
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
|
||||
@@ -258,10 +230,6 @@ bool EQ::ItemData::IsTypeShield() const
|
||||
return (ItemType == item::ItemTypeShield);
|
||||
}
|
||||
|
||||
bool EQ::ItemData::IsQuestItem() const {
|
||||
return QuestItemFlag;
|
||||
}
|
||||
|
||||
bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
|
||||
{
|
||||
if (!l_item || !r_item)
|
||||
|
||||
+226
-237
@@ -58,75 +58,72 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum ItemType : uint8 {
|
||||
/*9138*/ ItemType1HSlash = 0,
|
||||
/*9141*/ ItemType2HSlash,
|
||||
/*9140*/ ItemType1HPiercing,
|
||||
/*9139*/ ItemType1HBlunt,
|
||||
/*9142*/ ItemType2HBlunt,
|
||||
/*5504*/ ItemTypeBow, // 5
|
||||
/*----*/ ItemTypeUnknown1,
|
||||
/*----*/ ItemTypeLargeThrowing,
|
||||
/*5505*/ ItemTypeShield,
|
||||
/*5506*/ ItemTypeScroll,
|
||||
/*5507*/ ItemTypeArmor, // 10
|
||||
/*5508*/ ItemTypeMisc, // a lot of random crap has this item use.
|
||||
/*7564*/ ItemTypeLockPick,
|
||||
/*----*/ ItemTypeUnknown2,
|
||||
/*5509*/ ItemTypeFood,
|
||||
/*5510*/ ItemTypeDrink, // 15
|
||||
/*5511*/ ItemTypeLight,
|
||||
/*5512*/ ItemTypeCombinable, // not all stackable items are this use...
|
||||
/*5513*/ ItemTypeBandage,
|
||||
/*----*/ ItemTypeSmallThrowing,
|
||||
/*----*/ ItemTypeSpell, // 20 // spells and tomes
|
||||
/*5514*/ ItemTypePotion,
|
||||
/*----*/ ItemTypeUnknown3,
|
||||
/*0406*/ ItemTypeWindInstrument,
|
||||
/*0407*/ ItemTypeStringedInstrument,
|
||||
/*0408*/ ItemTypeBrassInstrument, // 25
|
||||
/*0405*/ ItemTypePercussionInstrument,
|
||||
/*5515*/ ItemTypeArrow,
|
||||
/*----*/ ItemTypeUnknown4,
|
||||
/*5521*/ ItemTypeJewelry,
|
||||
/*----*/ ItemTypeSkull, // 30
|
||||
/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...)
|
||||
/*5517*/ ItemTypeNote,
|
||||
/*5518*/ ItemTypeKey,
|
||||
/*----*/ ItemTypeCoin,
|
||||
/*5520*/ ItemType2HPiercing, // 35
|
||||
/*----*/ ItemTypeFishingPole,
|
||||
/*----*/ ItemTypeFishingBait,
|
||||
/*5519*/ ItemTypeAlcohol,
|
||||
/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?)
|
||||
/*----*/ ItemTypeCompass, // 40
|
||||
/*----*/ ItemTypeUnknown5,
|
||||
/*----*/ ItemTypePoison, // might be wrong, but includes poisons
|
||||
/*----*/ ItemTypeUnknown6,
|
||||
/*----*/ ItemTypeUnknown7,
|
||||
/*5522*/ ItemTypeMartial, // 45
|
||||
/*----*/ ItemTypeAllEffects,
|
||||
/*----*/ ItemTypeUnknown9,
|
||||
/*----*/ ItemTypeUnknown10,
|
||||
/*----*/ ItemTypeFocusEffect,
|
||||
/*----*/ ItemTypeSinging, // 50
|
||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||
/*5776*/ ItemTypeCharm,
|
||||
/*----*/ ItemTypeDye,
|
||||
/*----*/ ItemTypeAugmentation,
|
||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||
/*----*/ ItemTypeAugmentationDistiller,
|
||||
/*----*/ ItemTypeAlternateAbility,
|
||||
/*----*/ ItemTypeFellowshipKit,
|
||||
/*----*/ ItemTypeUnknown13,
|
||||
/*----*/ ItemTypeRecipe, // 60
|
||||
/*----*/ ItemTypeAdvancedRecipe,
|
||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||
/*----*/ ItemTypeCount,
|
||||
/*----*/ ItemTypeCollectible,
|
||||
/*----*/ ItemTypeContainer,
|
||||
/*----*/ ItemTypeAll = 0xFF
|
||||
/*9138*/ ItemType1HSlash = 0,
|
||||
/*9141*/ ItemType2HSlash,
|
||||
/*9140*/ ItemType1HPiercing,
|
||||
/*9139*/ ItemType1HBlunt,
|
||||
/*9142*/ ItemType2HBlunt,
|
||||
/*5504*/ ItemTypeBow, // 5
|
||||
/*----*/ ItemTypeUnknown1,
|
||||
/*----*/ ItemTypeLargeThrowing,
|
||||
/*5505*/ ItemTypeShield,
|
||||
/*5506*/ ItemTypeScroll,
|
||||
/*5507*/ ItemTypeArmor, // 10
|
||||
/*5508*/ ItemTypeMisc, // a lot of random crap has this item use.
|
||||
/*7564*/ ItemTypeLockPick,
|
||||
/*----*/ ItemTypeUnknown2,
|
||||
/*5509*/ ItemTypeFood,
|
||||
/*5510*/ ItemTypeDrink, // 15
|
||||
/*5511*/ ItemTypeLight,
|
||||
/*5512*/ ItemTypeCombinable, // not all stackable items are this use...
|
||||
/*5513*/ ItemTypeBandage,
|
||||
/*----*/ ItemTypeSmallThrowing,
|
||||
/*----*/ ItemTypeSpell, // 20 // spells and tomes
|
||||
/*5514*/ ItemTypePotion,
|
||||
/*----*/ ItemTypeUnknown3,
|
||||
/*0406*/ ItemTypeWindInstrument,
|
||||
/*0407*/ ItemTypeStringedInstrument,
|
||||
/*0408*/ ItemTypeBrassInstrument, // 25
|
||||
/*0405*/ ItemTypePercussionInstrument,
|
||||
/*5515*/ ItemTypeArrow,
|
||||
/*----*/ ItemTypeUnknown4,
|
||||
/*5521*/ ItemTypeJewelry,
|
||||
/*----*/ ItemTypeSkull, // 30
|
||||
/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...)
|
||||
/*5517*/ ItemTypeNote,
|
||||
/*5518*/ ItemTypeKey,
|
||||
/*----*/ ItemTypeCoin,
|
||||
/*5520*/ ItemType2HPiercing, // 35
|
||||
/*----*/ ItemTypeFishingPole,
|
||||
/*----*/ ItemTypeFishingBait,
|
||||
/*5519*/ ItemTypeAlcohol,
|
||||
/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?)
|
||||
/*----*/ ItemTypeCompass, // 40
|
||||
/*----*/ ItemTypeUnknown5,
|
||||
/*----*/ ItemTypePoison, // might be wrong, but includes poisons
|
||||
/*----*/ ItemTypeUnknown6,
|
||||
/*----*/ ItemTypeUnknown7,
|
||||
/*5522*/ ItemTypeMartial, // 45
|
||||
/*----*/ ItemTypeUnknown8,
|
||||
/*----*/ ItemTypeUnknown9,
|
||||
/*----*/ ItemTypeUnknown10,
|
||||
/*----*/ ItemTypeUnknown11,
|
||||
/*----*/ ItemTypeSinging, // 50
|
||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||
/*5776*/ ItemTypeCharm,
|
||||
/*----*/ ItemTypeDye,
|
||||
/*----*/ ItemTypeAugmentation,
|
||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||
/*----*/ ItemTypeAugmentationDistiller,
|
||||
/*----*/ ItemTypeUnknown12,
|
||||
/*----*/ ItemTypeFellowshipKit,
|
||||
/*----*/ ItemTypeUnknown13,
|
||||
/*----*/ ItemTypeRecipe, // 60
|
||||
/*----*/ ItemTypeAdvancedRecipe,
|
||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||
/*----*/ ItemTypeCount
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
@@ -134,7 +131,7 @@ namespace EQ
|
||||
Mounts?
|
||||
Ornamentations?
|
||||
GuildBanners?
|
||||
Collectible?
|
||||
Collectible?
|
||||
Placeable?
|
||||
(others?)
|
||||
*/
|
||||
@@ -358,187 +355,181 @@ namespace EQ
|
||||
|
||||
struct ItemData {
|
||||
// Non packet based fields
|
||||
uint8 MinStatus {};
|
||||
char Comment[255] {};
|
||||
uint8 MinStatus;
|
||||
|
||||
// Packet based fields
|
||||
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
||||
char Name[64] {}; // Name
|
||||
char Lore[80] {}; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
|
||||
char IDFile[30] {}; // Visible model
|
||||
uint32 ID {}; // Unique ID (also PK for DB)
|
||||
int32 Weight {}; // Item weight * 10
|
||||
uint8 NoRent{} ; // No Rent: 0=norent, 255=not norent
|
||||
uint8 NoDrop {}; // No Drop: 0=nodrop, 255=not nodrop
|
||||
uint8 Size {}; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
|
||||
uint32 Slots {}; // Bitfield for which slots this item can be used in
|
||||
uint32 Price {}; // Item cost (?)
|
||||
uint32 Icon {}; // Icon Number
|
||||
int32 LoreGroup {}; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
|
||||
bool LoreFlag {}; // This will be true if LoreGroup is non-zero
|
||||
bool PendingLoreFlag {};
|
||||
bool ArtifactFlag {};
|
||||
bool SummonedFlag {};
|
||||
uint8 FVNoDrop {}; // Firiona Vie nodrop flag
|
||||
uint32 Favor {}; // Individual favor
|
||||
uint32 GuildFavor {}; // Guild favor
|
||||
uint32 PointType {};
|
||||
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
|
||||
char Name[64]; // Name
|
||||
char Lore[80]; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
|
||||
char IDFile[30]; // Visible model
|
||||
uint32 ID; // Unique ID (also PK for DB)
|
||||
int32 Weight; // Item weight * 10
|
||||
uint8 NoRent; // No Rent: 0=norent, 255=not norent
|
||||
uint8 NoDrop; // No Drop: 0=nodrop, 255=not nodrop
|
||||
uint8 Size; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
|
||||
uint32 Slots; // Bitfield for which slots this item can be used in
|
||||
uint32 Price; // Item cost (?)
|
||||
uint32 Icon; // Icon Number
|
||||
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
|
||||
bool LoreFlag; // This will be true if LoreGroup is non-zero
|
||||
bool PendingLoreFlag;
|
||||
bool ArtifactFlag;
|
||||
bool SummonedFlag;
|
||||
uint8 FVNoDrop; // Firiona Vie nodrop flag
|
||||
uint32 Favor; // Individual favor
|
||||
uint32 GuildFavor; // Guild favor
|
||||
uint32 PointType;
|
||||
|
||||
//uint32 Unk117;
|
||||
//uint32 Unk118;
|
||||
//uint32 Unk121;
|
||||
//uint32 Unk124;
|
||||
|
||||
uint8 BagType {}; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
|
||||
uint8 BagSlots {}; // Number of slots: can only be 2, 4, 6, 8, or 10
|
||||
uint8 BagSize {}; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
|
||||
uint8 BagWR {}; // 0->100
|
||||
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
|
||||
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
|
||||
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
|
||||
uint8 BagWR; // 0->100
|
||||
|
||||
bool BenefitFlag {};
|
||||
bool Tradeskills {}; // Is this a tradeskill item?
|
||||
int8 CR {}; // Save vs Cold
|
||||
int8 DR {}; // Save vs Disease
|
||||
int8 PR {}; // Save vs Poison
|
||||
int8 MR {}; // Save vs Magic
|
||||
int8 FR {}; // Save vs Fire
|
||||
int8 AStr {}; // Strength
|
||||
int8 ASta {}; // Stamina
|
||||
int8 AAgi {}; // Agility
|
||||
int8 ADex {}; // Dexterity
|
||||
int8 ACha {}; // Charisma
|
||||
int8 AInt {}; // Intelligence
|
||||
int8 AWis {}; // Wisdom
|
||||
int32 HP {}; // HP
|
||||
int32 Mana {}; // Mana
|
||||
int32 AC {}; // AC
|
||||
uint32 Deity {}; // Bitmask of Deities that can equip this item
|
||||
bool BenefitFlag;
|
||||
bool Tradeskills; // Is this a tradeskill item?
|
||||
int8 CR; // Save vs Cold
|
||||
int8 DR; // Save vs Disease
|
||||
int8 PR; // Save vs Poison
|
||||
int8 MR; // Save vs Magic
|
||||
int8 FR; // Save vs Fire
|
||||
int8 AStr; // Strength
|
||||
int8 ASta; // Stamina
|
||||
int8 AAgi; // Agility
|
||||
int8 ADex; // Dexterity
|
||||
int8 ACha; // Charisma
|
||||
int8 AInt; // Intelligence
|
||||
int8 AWis; // Wisdom
|
||||
int32 HP; // HP
|
||||
int32 Mana; // Mana
|
||||
int32 AC; // AC
|
||||
uint32 Deity; // Bitmask of Deities that can equip this item
|
||||
//uint32 Unk033
|
||||
int32 SkillModValue {}; // % Mod to skill specified in SkillModType
|
||||
int32 SkillModMax {}; // Max skill point modification
|
||||
uint32 SkillModType {}; // Type of skill for SkillModValue to apply to
|
||||
uint32 BaneDmgRace {}; // Bane Damage Race
|
||||
int32 BaneDmgAmt {}; // Bane Damage Body Amount
|
||||
uint32 BaneDmgBody {}; // Bane Damage Body
|
||||
bool Magic {}; // True=Magic Item, False=not
|
||||
int32 CastTime_ {};
|
||||
uint8 ReqLevel {}; // Required Level to use item
|
||||
uint32 BardType {}; // Bard Skill Type
|
||||
int32 BardValue {}; // Bard Skill Amount
|
||||
int8 Light {}; // Light
|
||||
uint8 Delay {}; // Delay * 10
|
||||
uint8 RecLevel {}; // Recommended level to use item
|
||||
uint8 RecSkill {}; // Recommended skill to use item (refers to primary skill of item)
|
||||
uint8 ElemDmgType {}; // Elemental Damage Type (1=magic, 2=fire)
|
||||
uint8 ElemDmgAmt {}; // Elemental Damage
|
||||
uint8 Range {}; // Range of item
|
||||
uint32 Damage {}; // Delay between item usage (in 0.1 sec increments)
|
||||
uint32 Color {}; // RR GG BB 00 <-- as it appears in pc
|
||||
uint32 Classes {}; // Bitfield of classes that can equip item (1 << class#)
|
||||
uint32 Races {}; // Bitfield of races that can equip item (1 << race#)
|
||||
//uint32 Unk054 {};
|
||||
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
|
||||
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
|
||||
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
||||
uint8 Material {}; // Item material type
|
||||
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
|
||||
float SellRate {}; // Sell rate
|
||||
//uint32 Unk059 {};
|
||||
int32 SkillModValue; // % Mod to skill specified in SkillModType
|
||||
int32 SkillModMax; // Max skill point modification
|
||||
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
||||
uint32 BaneDmgRace; // Bane Damage Race
|
||||
int32 BaneDmgAmt; // Bane Damage Body Amount
|
||||
uint32 BaneDmgBody; // Bane Damage Body
|
||||
bool Magic; // True=Magic Item, False=not
|
||||
int32 CastTime_;
|
||||
uint8 ReqLevel; // Required Level to use item
|
||||
uint32 BardType; // Bard Skill Type
|
||||
int32 BardValue; // Bard Skill Amount
|
||||
int8 Light; // Light
|
||||
uint8 Delay; // Delay * 10
|
||||
uint8 RecLevel; // Recommended level to use item
|
||||
uint8 RecSkill; // Recommended skill to use item (refers to primary skill of item)
|
||||
uint8 ElemDmgType; // Elemental Damage Type (1=magic, 2=fire)
|
||||
uint8 ElemDmgAmt; // Elemental Damage
|
||||
uint8 Range; // Range of item
|
||||
uint32 Damage; // Delay between item usage (in 0.1 sec increments)
|
||||
uint32 Color; // RR GG BB 00 <-- as it appears in pc
|
||||
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
|
||||
uint32 Races; // Bitfield of races that can equip item (1 << race#)
|
||||
//uint32 Unk054;
|
||||
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
|
||||
uint8 ItemType; // Item Type/Skill (itemClass* from above)
|
||||
int32 SubType; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
||||
uint8 Material; // Item material type
|
||||
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
|
||||
float SellRate; // Sell rate
|
||||
//uint32 Unk059;
|
||||
union {
|
||||
uint32 Fulfilment; // Food fulfilment (How long it lasts)
|
||||
uint32 CastTime; // Cast Time for clicky effects, in milliseconds
|
||||
};
|
||||
uint32 EliteMaterial {};
|
||||
int32 ProcRate {};
|
||||
int8 CombatEffects {}; // PoP: Combat Effects +
|
||||
int8 Shielding {}; // PoP: Shielding %
|
||||
int8 StunResist {}; // PoP: Stun Resist %
|
||||
int8 StrikeThrough {}; // PoP: Strike Through %
|
||||
int32 ExtraDmgSkill {};
|
||||
int32 ExtraDmgAmt {};
|
||||
int8 SpellShield {}; // PoP: Spell Shield %
|
||||
int8 Avoidance {}; // PoP: Avoidance +
|
||||
int8 Accuracy {}; // PoP: Accuracy +
|
||||
uint32 CharmFileID {};
|
||||
int32 FactionMod1 {}; // Faction Mod 1
|
||||
int32 FactionMod2 {}; // Faction Mod 2
|
||||
int32 FactionMod3 {}; // Faction Mod 3
|
||||
int32 FactionMod4 {}; // Faction Mod 4
|
||||
int32 FactionAmt1 {}; // Faction Amt 1
|
||||
int32 FactionAmt2 {}; // Faction Amt 2
|
||||
int32 FactionAmt3 {}; // Faction Amt 3
|
||||
int32 FactionAmt4 {}; // Faction Amt 4
|
||||
char CharmFile[32] {}; // ?
|
||||
uint32 AugType {};
|
||||
uint8 AugSlotType[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Type
|
||||
uint8 AugSlotVisible[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Visible
|
||||
uint8 AugSlotUnk2[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
||||
uint32 LDoNTheme {};
|
||||
uint32 LDoNPrice {};
|
||||
uint32 LDoNSold {};
|
||||
uint32 BaneDmgRaceAmt {};
|
||||
uint32 AugRestrict {};
|
||||
int32 Endur {};
|
||||
int32 DotShielding {};
|
||||
int32 Attack {};
|
||||
int32 Regen {};
|
||||
int32 ManaRegen {};
|
||||
int32 EnduranceRegen {};
|
||||
int32 Haste {};
|
||||
int32 DamageShield {};
|
||||
uint32 RecastDelay {};
|
||||
int RecastType {};
|
||||
uint32 AugDistiller {};
|
||||
bool Attuneable {};
|
||||
bool NoPet {};
|
||||
bool PotionBelt {};
|
||||
bool Stackable {};
|
||||
bool NoTransfer {};
|
||||
bool QuestItemFlag {};
|
||||
int16 StackSize {};
|
||||
uint8 PotionBeltSlots {};
|
||||
item::ItemEffect_Struct Click {};
|
||||
item::ItemEffect_Struct Proc {};
|
||||
item::ItemEffect_Struct Worn {};
|
||||
item::ItemEffect_Struct Focus {};
|
||||
item::ItemEffect_Struct Scroll {};
|
||||
item::ItemEffect_Struct Bard {};
|
||||
uint32 EliteMaterial;
|
||||
int32 ProcRate;
|
||||
int8 CombatEffects; // PoP: Combat Effects +
|
||||
int8 Shielding; // PoP: Shielding %
|
||||
int8 StunResist; // PoP: Stun Resist %
|
||||
int8 StrikeThrough; // PoP: Strike Through %
|
||||
uint32 ExtraDmgSkill;
|
||||
uint32 ExtraDmgAmt;
|
||||
int8 SpellShield; // PoP: Spell Shield %
|
||||
int8 Avoidance; // PoP: Avoidance +
|
||||
int8 Accuracy; // PoP: Accuracy +
|
||||
uint32 CharmFileID;
|
||||
int32 FactionMod1; // Faction Mod 1
|
||||
int32 FactionMod2; // Faction Mod 2
|
||||
int32 FactionMod3; // Faction Mod 3
|
||||
int32 FactionMod4; // Faction Mod 4
|
||||
int32 FactionAmt1; // Faction Amt 1
|
||||
int32 FactionAmt2; // Faction Amt 2
|
||||
int32 FactionAmt3; // Faction Amt 3
|
||||
int32 FactionAmt4; // Faction Amt 4
|
||||
char CharmFile[32]; // ?
|
||||
uint32 AugType;
|
||||
uint8 AugSlotType[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Type
|
||||
uint8 AugSlotVisible[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Visible
|
||||
uint8 AugSlotUnk2[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
||||
uint32 LDoNTheme;
|
||||
uint32 LDoNPrice;
|
||||
uint32 LDoNSold;
|
||||
uint32 BaneDmgRaceAmt;
|
||||
uint32 AugRestrict;
|
||||
int32 Endur;
|
||||
int32 DotShielding;
|
||||
int32 Attack;
|
||||
int32 Regen;
|
||||
int32 ManaRegen;
|
||||
int32 EnduranceRegen;
|
||||
int32 Haste;
|
||||
int32 DamageShield;
|
||||
uint32 RecastDelay;
|
||||
int RecastType;
|
||||
uint32 AugDistiller;
|
||||
bool Attuneable;
|
||||
bool NoPet;
|
||||
bool PotionBelt;
|
||||
bool Stackable;
|
||||
bool NoTransfer;
|
||||
bool QuestItemFlag;
|
||||
int16 StackSize;
|
||||
uint8 PotionBeltSlots;
|
||||
item::ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
|
||||
|
||||
uint8 Book {}; // 0=Not book, 1=Book
|
||||
uint32 BookType {};
|
||||
char Filename[33] {}; // Filename for book data
|
||||
uint8 Book; // 0=Not book, 1=Book
|
||||
uint32 BookType;
|
||||
char Filename[33]; // Filename for book data
|
||||
// Begin SoF Fields
|
||||
int32 SVCorruption {};
|
||||
uint32 Purity {};
|
||||
uint8 EvolvingItem {};
|
||||
uint32 EvolvingID {};
|
||||
uint8 EvolvingLevel {};
|
||||
uint8 EvolvingMax {};
|
||||
uint32 BackstabDmg {};
|
||||
uint32 DSMitigation {};
|
||||
int32 HeroicStr {};
|
||||
int32 HeroicInt {};
|
||||
int32 HeroicWis {};
|
||||
int32 HeroicAgi {};
|
||||
int32 HeroicDex {};
|
||||
int32 HeroicSta {};
|
||||
int32 HeroicCha {};
|
||||
int32 HeroicMR {};
|
||||
int32 HeroicFR {};
|
||||
int32 HeroicCR {};
|
||||
int32 HeroicDR {};
|
||||
int32 HeroicPR {};
|
||||
int32 HeroicSVCorrup {};
|
||||
int32 HealAmt {};
|
||||
int32 SpellDmg {};
|
||||
uint32 LDoNSellBackRate {};
|
||||
uint32 ScriptFileID {};
|
||||
uint16 ExpendableArrow {};
|
||||
uint32 Clairvoyance {};
|
||||
char ClickName[65] {};
|
||||
char ProcName[65] {};
|
||||
char WornName[65] {};
|
||||
char FocusName[65] {};
|
||||
char ScrollName[65] {};
|
||||
int32 SVCorruption;
|
||||
uint32 Purity;
|
||||
uint8 EvolvingItem;
|
||||
uint32 EvolvingID;
|
||||
uint8 EvolvingLevel;
|
||||
uint8 EvolvingMax;
|
||||
uint32 BackstabDmg;
|
||||
uint32 DSMitigation;
|
||||
int32 HeroicStr;
|
||||
int32 HeroicInt;
|
||||
int32 HeroicWis;
|
||||
int32 HeroicAgi;
|
||||
int32 HeroicDex;
|
||||
int32 HeroicSta;
|
||||
int32 HeroicCha;
|
||||
int32 HeroicMR;
|
||||
int32 HeroicFR;
|
||||
int32 HeroicCR;
|
||||
int32 HeroicDR;
|
||||
int32 HeroicPR;
|
||||
int32 HeroicSVCorrup;
|
||||
int32 HealAmt;
|
||||
int32 SpellDmg;
|
||||
uint32 LDoNSellBackRate;
|
||||
uint32 ScriptFileID;
|
||||
uint16 ExpendableArrow;
|
||||
uint32 Clairvoyance;
|
||||
char ClickName[65];
|
||||
char ProcName[65];
|
||||
char WornName[65];
|
||||
char FocusName[65];
|
||||
char ScrollName[65];
|
||||
//BardName
|
||||
|
||||
bool IsEquipable(uint16 Race, uint16 Class) const;
|
||||
@@ -550,8 +541,6 @@ namespace EQ
|
||||
bool IsType1HWeapon() const;
|
||||
bool IsType2HWeapon() const;
|
||||
bool IsTypeShield() const;
|
||||
bool IsPetUsable() const;
|
||||
bool IsQuestItem() const;
|
||||
|
||||
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
||||
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
|
||||
|
||||
+274
-439
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
|
||||
#include "inventory_profile.h"
|
||||
#include "../common/data_verification.h"
|
||||
//#include "classes.h"
|
||||
//#include "global_define.h"
|
||||
//#include "item_instance.h"
|
||||
@@ -25,19 +24,17 @@
|
||||
#include "rulesys.h"
|
||||
#include "shareddb.h"
|
||||
#include "strings.h"
|
||||
#include "evolving_items.h"
|
||||
|
||||
#include "util/uuid.h"
|
||||
//#include "../common/light_source.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
//#include <iostream>
|
||||
|
||||
int32 next_item_serial_number = 1;
|
||||
std::unordered_set<uint64> guids{};
|
||||
uint32 NextItemInstSerialNumber = 1;
|
||||
|
||||
static inline uint32 GetNextItemInstSerialNumber() {
|
||||
|
||||
static inline int32 GetNextItemInstSerialNumber()
|
||||
{
|
||||
// The Bazaar relies on each item a client has up for Trade having a unique
|
||||
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
||||
// is used in Bazaar packets to identify the item a player is buying or inspecting.
|
||||
@@ -48,88 +45,142 @@ static inline int32 GetNextItemInstSerialNumber()
|
||||
// NextItemInstSerialNumber is the next one to hand out.
|
||||
//
|
||||
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
||||
if (next_item_serial_number >= INT32_MAX) {
|
||||
next_item_serial_number = 1;
|
||||
}
|
||||
else {
|
||||
next_item_serial_number++;
|
||||
}
|
||||
if(NextItemInstSerialNumber >= UINT_MAX)
|
||||
NextItemInstSerialNumber = 1;
|
||||
else
|
||||
NextItemInstSerialNumber++;
|
||||
|
||||
while (guids.contains(next_item_serial_number)) {
|
||||
next_item_serial_number++;
|
||||
}
|
||||
|
||||
return next_item_serial_number;
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
//
|
||||
// class EQ::ItemInstance
|
||||
//
|
||||
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
||||
|
||||
if (item) {
|
||||
EQ::ItemInstance::ItemInstance(const ItemData* item, const std::string& guid, int16 charges) {
|
||||
m_use_type = ItemInstNormal;
|
||||
if(item) {
|
||||
m_item = new ItemData(*item);
|
||||
} else {
|
||||
m_item = nullptr;
|
||||
}
|
||||
|
||||
if (guid.empty()) {
|
||||
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||
}
|
||||
else {
|
||||
m_guid = guid;
|
||||
}
|
||||
|
||||
m_charges = charges;
|
||||
|
||||
if (m_item && m_item->IsClassCommon()) {
|
||||
m_price = 0;
|
||||
m_attuned = false;
|
||||
m_merchantslot = 0;
|
||||
if (m_item && m_item->IsClassCommon())
|
||||
m_color = m_item->Color;
|
||||
}
|
||||
else
|
||||
m_color = 0;
|
||||
m_merchantcount = 1;
|
||||
m_serial_number = GetNextItemInstSerialNumber();
|
||||
|
||||
if (IsEvolving()) {
|
||||
SetTimer("evolve", RuleI(EvolvingItems, DelayUponEquipping));
|
||||
}
|
||||
|
||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||
m_exp = 0;
|
||||
m_evolveLvl = 0;
|
||||
m_activated = false;
|
||||
m_scaledItem = nullptr;
|
||||
m_evolveInfo = nullptr;
|
||||
m_scaling = false;
|
||||
m_ornamenticon = 0;
|
||||
m_ornamentidfile = 0;
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
m_new_id_file = 0;
|
||||
m_currentslot = 0;
|
||||
}
|
||||
|
||||
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
|
||||
|
||||
m_item = db->GetItem(item_id);
|
||||
|
||||
if (m_item) {
|
||||
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, const std::string& guid, int16 charges) {
|
||||
m_use_type = ItemInstNormal;
|
||||
m_item = db->GetItem(item_id);
|
||||
if(m_item) {
|
||||
m_item = new ItemData(*m_item);
|
||||
}
|
||||
else {
|
||||
m_item = nullptr;
|
||||
}
|
||||
|
||||
if (guid.empty()) {
|
||||
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||
}
|
||||
else {
|
||||
m_guid = guid;
|
||||
}
|
||||
|
||||
m_charges = charges;
|
||||
|
||||
if (m_item && m_item->IsClassCommon()) {
|
||||
m_price = 0;
|
||||
m_merchantslot = 0;
|
||||
m_attuned=false;
|
||||
if (m_item && m_item->IsClassCommon())
|
||||
m_color = m_item->Color;
|
||||
} else {
|
||||
else
|
||||
m_color = 0;
|
||||
}
|
||||
m_merchantcount = 1;
|
||||
m_serial_number = GetNextItemInstSerialNumber();
|
||||
|
||||
if (IsEvolving()) {
|
||||
SetTimer("evolve", RuleI(EvolvingItems, DelayUponEquipping));
|
||||
}
|
||||
|
||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||
m_exp = 0;
|
||||
m_evolveLvl = 0;
|
||||
m_activated = false;
|
||||
m_scaledItem = nullptr;
|
||||
m_evolveInfo = nullptr;
|
||||
m_scaling = false;
|
||||
m_ornamenticon = 0;
|
||||
m_ornamentidfile = 0;
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
m_new_id_file = 0;
|
||||
m_currentslot = 0;
|
||||
}
|
||||
|
||||
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
||||
m_use_type = use_type;
|
||||
m_use_type = use_type;
|
||||
|
||||
m_guid = EQ::Util::UUID::Generate().ToString();
|
||||
m_item = nullptr;
|
||||
m_charges = 0;
|
||||
m_price = 0;
|
||||
m_attuned = false;
|
||||
m_merchantslot = 0;
|
||||
m_color = 0;
|
||||
m_serial_number = 0;
|
||||
m_exp = 0;
|
||||
m_evolveLvl = 0;
|
||||
m_activated = false;
|
||||
m_scaledItem = nullptr;
|
||||
m_evolveInfo = nullptr;
|
||||
m_scaling = false;
|
||||
m_ornamenticon = 0;
|
||||
m_ornamentidfile = 0;
|
||||
m_ornament_hero_model = 0;
|
||||
m_recast_timestamp = 0;
|
||||
m_new_id_file = 0;
|
||||
m_currentslot = 0;
|
||||
m_merchantcount = 0;
|
||||
}
|
||||
|
||||
// Make a copy of an EQ::ItemInstance object
|
||||
EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
||||
{
|
||||
m_use_type = copy.m_use_type;
|
||||
|
||||
if (copy.m_item) {
|
||||
m_use_type=copy.m_use_type;
|
||||
if(copy.m_item)
|
||||
m_item = new ItemData(*copy.m_item);
|
||||
} else {
|
||||
else
|
||||
m_item = nullptr;
|
||||
}
|
||||
|
||||
m_charges = copy.m_charges;
|
||||
m_price = copy.m_price;
|
||||
m_color = copy.m_color;
|
||||
m_merchantslot = copy.m_merchantslot;
|
||||
m_currentslot = copy.m_currentslot;
|
||||
m_attuned = copy.m_attuned;
|
||||
m_merchantcount = copy.m_merchantcount;
|
||||
|
||||
m_guid = copy.m_guid;
|
||||
m_charges=copy.m_charges;
|
||||
m_price=copy.m_price;
|
||||
m_color=copy.m_color;
|
||||
m_merchantslot=copy.m_merchantslot;
|
||||
m_currentslot=copy.m_currentslot;
|
||||
m_attuned=copy.m_attuned;
|
||||
m_merchantcount=copy.m_merchantcount;
|
||||
// Copy container contents
|
||||
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
|
||||
ItemInstance* inst_old = it->second;
|
||||
@@ -139,36 +190,37 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
||||
inst_new = inst_old->Clone();
|
||||
}
|
||||
|
||||
if (inst_new) {
|
||||
if (inst_new != nullptr) {
|
||||
m_contents[it->first] = inst_new;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, std::string>::const_iterator iter;
|
||||
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
|
||||
m_custom_data[iter->first] = iter->second;
|
||||
}
|
||||
m_serial_number = copy.m_serial_number;
|
||||
m_custom_data = copy.m_custom_data;
|
||||
m_timers = copy.m_timers;
|
||||
|
||||
m_SerialNumber = copy.m_SerialNumber;
|
||||
m_custom_data = copy.m_custom_data;
|
||||
m_timers = copy.m_timers;
|
||||
|
||||
m_exp = copy.m_exp;
|
||||
m_exp = copy.m_exp;
|
||||
m_evolveLvl = copy.m_evolveLvl;
|
||||
|
||||
if (copy.m_scaledItem) {
|
||||
m_activated = copy.m_activated;
|
||||
if (copy.m_scaledItem)
|
||||
m_scaledItem = new ItemData(*copy.m_scaledItem);
|
||||
} else {
|
||||
else
|
||||
m_scaledItem = nullptr;
|
||||
}
|
||||
|
||||
m_evolving_details = copy.m_evolving_details;
|
||||
m_scaling = copy.m_scaling;
|
||||
m_ornamenticon = copy.m_ornamenticon;
|
||||
m_ornamentidfile = copy.m_ornamentidfile;
|
||||
if(copy.m_evolveInfo)
|
||||
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
|
||||
else
|
||||
m_evolveInfo = nullptr;
|
||||
|
||||
m_scaling = copy.m_scaling;
|
||||
m_ornamenticon = copy.m_ornamenticon;
|
||||
m_ornamentidfile = copy.m_ornamentidfile;
|
||||
m_ornament_hero_model = copy.m_ornament_hero_model;
|
||||
m_recast_timestamp = copy.m_recast_timestamp;
|
||||
m_new_id_file = copy.m_new_id_file;
|
||||
m_recast_timestamp = copy.m_recast_timestamp;
|
||||
m_new_id_file = copy.m_new_id_file;
|
||||
}
|
||||
|
||||
// Clean up container contents
|
||||
@@ -177,6 +229,7 @@ EQ::ItemInstance::~ItemInstance()
|
||||
Clear();
|
||||
safe_delete(m_item);
|
||||
safe_delete(m_scaledItem);
|
||||
safe_delete(m_evolveInfo);
|
||||
}
|
||||
|
||||
// Query item type
|
||||
@@ -185,13 +238,11 @@ bool EQ::ItemInstance::IsType(item::ItemClass item_class) const
|
||||
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
|
||||
|
||||
// Check usage type
|
||||
if (m_use_type == ItemInstWorldContainer && item_class == item::ItemClassBag) {
|
||||
if ((m_use_type == ItemInstWorldContainer) && (item_class == item::ItemClassBag))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_item) {
|
||||
if (!m_item)
|
||||
return false;
|
||||
}
|
||||
|
||||
return (m_item->ItemClass == item_class);
|
||||
}
|
||||
@@ -214,20 +265,21 @@ bool EQ::ItemInstance::IsClassBook() const
|
||||
// Is item stackable?
|
||||
bool EQ::ItemInstance::IsStackable() const
|
||||
{
|
||||
return (m_item && m_item->Stackable);
|
||||
if (!m_item)
|
||||
return false;
|
||||
|
||||
return m_item->Stackable;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::IsCharged() const
|
||||
{
|
||||
if (!m_item) {
|
||||
if (!m_item)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_item->MaxCharges > 1) {
|
||||
if (m_item->MaxCharges > 1)
|
||||
return true;
|
||||
} else {
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Can item be equipped?
|
||||
@@ -276,30 +328,26 @@ bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
|
||||
|
||||
bool EQ::ItemInstance::IsAugmentable() const
|
||||
{
|
||||
if (!m_item) {
|
||||
if (!m_item)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
||||
if (m_item->AugSlotType[index] != 0) {
|
||||
if (m_item->AugSlotType[index] != 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
if (!m_item || !m_item->IsClassCommon())
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = invslot::EQUIPMENT_BEGIN;
|
||||
for (; index <= invslot::EQUIPMENT_END; ++index) {
|
||||
if (m_item->Slots & (1 << index)) {
|
||||
if (aug_wear_slots & (1 << index)) {
|
||||
if (aug_wear_slots & (1 << index))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,34 +360,47 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
for (int16 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||
if (IsAugmentSlotAvailable(augment_type, slot_id)) {
|
||||
return slot_id;
|
||||
auto i = invaug::SOCKET_BEGIN;
|
||||
for (; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetItem(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[i] &&
|
||||
((1 << (m_item->AugSlotType[i] - 1)) & augment_type)
|
||||
)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon() || GetItem(slot)) {
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
if (
|
||||
(
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
)
|
||||
) &&
|
||||
(
|
||||
RuleB(Items, AugmentItemAllowInvisibleAugments) ||
|
||||
!GetItem(slot) &&
|
||||
m_item->AugSlotVisible[slot]
|
||||
) &&
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
)
|
||||
);
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve item inside container
|
||||
@@ -355,10 +416,9 @@ EQ::ItemInstance* EQ::ItemInstance::GetItem(uint8 index) const
|
||||
|
||||
uint32 EQ::ItemInstance::GetItemID(uint8 slot) const
|
||||
{
|
||||
const auto item = GetItem(slot);
|
||||
if (item) {
|
||||
ItemInstance *item = GetItem(slot);
|
||||
if (item)
|
||||
return item->GetID();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -482,21 +542,14 @@ uint8 EQ::ItemInstance::FirstOpenSlot() const
|
||||
|
||||
uint8 EQ::ItemInstance::GetTotalItemCount() const
|
||||
{
|
||||
if (!m_item) {
|
||||
if (!m_item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 item_count = 1;
|
||||
|
||||
if (!m_item->IsClassBag()) {
|
||||
return item_count;
|
||||
}
|
||||
if (m_item && !m_item->IsClassBag()) { return item_count; }
|
||||
|
||||
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) {
|
||||
if (GetItem(index)) {
|
||||
++item_count;
|
||||
}
|
||||
}
|
||||
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } }
|
||||
|
||||
return item_count;
|
||||
}
|
||||
@@ -524,99 +577,78 @@ EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::IsOrnamentationAugment(EQ::ItemInstance* augment) const
|
||||
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugtype) const
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon() || !augment) {
|
||||
return false;
|
||||
}
|
||||
if (!m_item || !m_item->IsClassCommon()) { return nullptr; }
|
||||
if (ornamentationAugtype == 0) { return nullptr; }
|
||||
|
||||
const auto augment_item = augment->GetItem();
|
||||
if (!augment_item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& idfile = augment_item->IDFile;
|
||||
|
||||
if (
|
||||
EQ::ValueWithin(
|
||||
augment->GetAugmentType(),
|
||||
OrnamentationAugmentTypes::StandardOrnamentation,
|
||||
OrnamentationAugmentTypes::SpecialOrnamentation
|
||||
) ||
|
||||
(
|
||||
idfile != "IT63" &&
|
||||
idfile != "IT64"
|
||||
) ||
|
||||
augment_item->HerosForgeModel
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
|
||||
const auto augment = GetAugment(i);
|
||||
if (augment && IsOrnamentationAugment(augment)) {
|
||||
return augment;
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++)
|
||||
{
|
||||
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
|
||||
{
|
||||
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
|
||||
if (
|
||||
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
|
||||
|| strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
|
||||
&& GetAugment(i)->GetItem()->HerosForgeModel == 0
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return GetAugment(i);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
|
||||
{
|
||||
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
|
||||
// Not a Hero Forge item.
|
||||
if (m_ornament_hero_model == 0 || material_slot < 0) {
|
||||
if (m_ornament_hero_model == 0 || material_slot < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Item is using an explicit Hero Forge ID
|
||||
if (m_ornament_hero_model >= 1000) {
|
||||
if (m_ornament_hero_model >= 1000)
|
||||
return m_ornament_hero_model;
|
||||
}
|
||||
|
||||
// Item is using a shorthand ID
|
||||
return (m_ornament_hero_model * 100) + material_slot;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::UpdateOrnamentationInfo()
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
|
||||
if (!m_item || !m_item->IsClassCommon())
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto augment = GetOrnamentationAugment();
|
||||
bool ornamentSet = false;
|
||||
|
||||
if (augment) {
|
||||
const auto augment_item = GetOrnamentationAugment()->GetItem();
|
||||
|
||||
if (augment_item) {
|
||||
SetOrnamentIcon(augment_item->Icon);
|
||||
SetOrnamentHeroModel(augment_item->HerosForgeModel);
|
||||
|
||||
if (strlen(augment_item->IDFile) > 2) {
|
||||
SetOrnamentationIDFile(Strings::ToUnsignedInt(&augment_item->IDFile[2]));
|
||||
} else {
|
||||
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||
if (GetOrnamentationAug(ornamentationAugtype))
|
||||
{
|
||||
const ItemData* ornamentItem;
|
||||
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||
if (ornamentItem != nullptr)
|
||||
{
|
||||
SetOrnamentIcon(ornamentItem->Icon);
|
||||
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
|
||||
if (strlen(ornamentItem->IDFile) > 2)
|
||||
{
|
||||
SetOrnamentationIDFile(Strings::ToInt(&ornamentItem->IDFile[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetOrnamentationIDFile(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
ornamentSet = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetOrnamentIcon(0);
|
||||
SetOrnamentHeroModel(0);
|
||||
SetOrnamentationIDFile(0);
|
||||
}
|
||||
|
||||
SetOrnamentIcon(0);
|
||||
SetOrnamentHeroModel(0);
|
||||
SetOrnamentationIDFile(0);
|
||||
|
||||
return false;
|
||||
return ornamentSet;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
|
||||
@@ -716,14 +748,12 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
|
||||
|
||||
bool EQ::ItemInstance::IsAugmented()
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
if (!m_item || !m_item->IsClassCommon())
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||
if (GetAugmentItemID(slot_id)) {
|
||||
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
||||
if (GetAugmentItemID(index))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -832,20 +862,7 @@ std::string EQ::ItemInstance::GetCustomDataString() const {
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomDataString(const std::string& str)
|
||||
{
|
||||
auto components = Strings::Split(str, "^");
|
||||
auto value_count = components.size() / 2;
|
||||
|
||||
for (auto i = 0; i < value_count; i++) {
|
||||
auto identifier = components[i * 2];
|
||||
auto value = components[(i * 2) + 1];
|
||||
|
||||
SetCustomData(identifier, value);
|
||||
}
|
||||
}
|
||||
|
||||
std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) {
|
||||
std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
|
||||
std::map<std::string, std::string>::const_iterator iter = m_custom_data.find(identifier);
|
||||
if (iter != m_custom_data.end()) {
|
||||
return iter->second;
|
||||
@@ -854,33 +871,33 @@ std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, const std::string& value) {
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, std::string value) {
|
||||
DeleteCustomData(identifier);
|
||||
m_custom_data[identifier] = value;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, int value) {
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, int value) {
|
||||
DeleteCustomData(identifier);
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
m_custom_data[identifier] = ss.str();
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, float value) {
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, float value) {
|
||||
DeleteCustomData(identifier);
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
m_custom_data[identifier] = ss.str();
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, bool value) {
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, bool value) {
|
||||
DeleteCustomData(identifier);
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
m_custom_data[identifier] = ss.str();
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::DeleteCustomData(const std::string& identifier) {
|
||||
void EQ::ItemInstance::DeleteCustomData(std::string identifier) {
|
||||
auto iter = m_custom_data.find(identifier);
|
||||
if (iter != m_custom_data.end()) {
|
||||
m_custom_data.erase(iter);
|
||||
@@ -932,9 +949,8 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
|
||||
|
||||
void EQ::ItemInstance::Initialize(SharedDatabase *db) {
|
||||
// if there's no actual item, don't do anything
|
||||
if (!m_item) {
|
||||
if (!m_item)
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize scaling items
|
||||
if (m_item->CharmFileID != 0) {
|
||||
@@ -943,7 +959,7 @@ void EQ::ItemInstance::Initialize(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
// initialize evolving items
|
||||
else if (db && m_item->LoreGroup >= 1000) {
|
||||
else if ((db) && m_item->LoreGroup >= 1000 && m_item->LoreGroup != -1) {
|
||||
// not complete yet
|
||||
}
|
||||
}
|
||||
@@ -1032,6 +1048,29 @@ void EQ::ItemInstance::ScaleItem() {
|
||||
m_scaledItem->CharmFileID = 0; // this stops the client from trying to scale the item itself.
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::EvolveOnAllKills() const {
|
||||
return (m_evolveInfo && m_evolveInfo->AllKills);
|
||||
}
|
||||
|
||||
int8 EQ::ItemInstance::GetMaxEvolveLvl() const {
|
||||
if (m_evolveInfo)
|
||||
return m_evolveInfo->MaxLvl;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 EQ::ItemInstance::GetKillsNeeded(uint8 currentlevel) {
|
||||
uint32 kills = -1; // default to -1 (max uint32 value) because this value is usually divided by, so we don't want to ever return zero.
|
||||
if (m_evolveInfo)
|
||||
if (currentlevel != m_evolveInfo->MaxLvl)
|
||||
kills = m_evolveInfo->LvlKills[currentlevel - 1];
|
||||
|
||||
if (kills == 0)
|
||||
kills = -1;
|
||||
|
||||
return kills;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetTimer(std::string name, uint32 time) {
|
||||
Timer t(time);
|
||||
t.Start(time, false);
|
||||
@@ -1246,7 +1285,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bool augments) const
|
||||
|
||||
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||
{
|
||||
int race = Race::Doug;
|
||||
int race = RACE_DOUG_0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
race = item->BaneDmgRace;
|
||||
@@ -1265,7 +1304,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||
return race;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemBaneDamageBody(uint8 against, bool augments) const
|
||||
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
|
||||
{
|
||||
int64 damage = 0;
|
||||
const auto item = GetItem();
|
||||
@@ -1764,232 +1803,28 @@ int EQ::ItemInstance::RemoveTaskDeliveredItems()
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32 EQ::ItemInstance::GetItemGuildFavor() const
|
||||
{
|
||||
uint32 total = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
return total = item->GuildFavor;
|
||||
}
|
||||
return 0;
|
||||
//
|
||||
// class EvolveInfo
|
||||
//
|
||||
EvolveInfo::EvolveInfo() {
|
||||
// nothing here yet
|
||||
}
|
||||
|
||||
std::vector<uint32> EQ::ItemInstance::GetAugmentIDs() const
|
||||
{
|
||||
std::vector<uint32> augments;
|
||||
|
||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
|
||||
augments.push_back(GetAugment(slot_id) ? GetAugmentItemID(slot_id) : 0);
|
||||
}
|
||||
|
||||
return augments;
|
||||
EvolveInfo::EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10) {
|
||||
FirstItem = first;
|
||||
MaxLvl = max;
|
||||
AllKills = allkills;
|
||||
LvlKills[0] = L2;
|
||||
LvlKills[1] = L3;
|
||||
LvlKills[2] = L4;
|
||||
LvlKills[3] = L5;
|
||||
LvlKills[4] = L6;
|
||||
LvlKills[5] = L7;
|
||||
LvlKills[6] = L8;
|
||||
LvlKills[7] = L9;
|
||||
LvlKills[8] = L10;
|
||||
}
|
||||
|
||||
std::vector<std::string> EQ::ItemInstance::GetAugmentNames() const
|
||||
{
|
||||
std::vector<std::string> augment_names;
|
||||
EvolveInfo::~EvolveInfo() {
|
||||
|
||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
|
||||
const auto augment = GetAugment(slot_id);
|
||||
augment_names.push_back(augment ? augment->GetItem()->Name : "None");
|
||||
}
|
||||
|
||||
return augment_names;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemRegen(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->Regen;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemRegen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemManaRegen(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->ManaRegen;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemManaRegen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemDamageShield(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->DamageShield;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemDamageShield();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemDSMitigation(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->DSMitigation;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemDSMitigation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemHealAmt(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->HealAmt;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemHealAmt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemSpellDamage(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->SpellDmg;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemSpellDamage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemClairvoyance(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->Clairvoyance;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemClairvoyance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemSkillsStat(EQ::skills::SkillType skill, bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->ExtraDmgSkill == skill ? item->ExtraDmgAmt : 0;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemSkillsStat(skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::AddGUIDToMap(uint64 existing_serial_number)
|
||||
{
|
||||
guids.emplace(existing_serial_number);
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::ClearGUIDMap()
|
||||
{
|
||||
guids.clear();
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::TransferOwnership(Database &db, const uint32 to_char_id) const
|
||||
{
|
||||
if (!to_char_id || !IsEvolving()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetEvolveCharID(to_char_id);
|
||||
CharacterEvolvingItemsRepository::UpdateCharID(db, GetEvolveUniqueID(), to_char_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 EQ::ItemInstance::GetAugmentEvolveUniqueID(uint8 augment_index) const
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto item = GetItem(augment_index);
|
||||
if (item) {
|
||||
return item->GetEvolveUniqueID();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetTimer(std::string name, uint32 time) const{
|
||||
Timer t(time);
|
||||
t.Start(time, false);
|
||||
m_timers[name] = t;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetEvolveEquipped(const bool in) const
|
||||
{
|
||||
if (!IsEvolving()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_evolving_details.equipped = in;
|
||||
if (in && !GetTimers().contains("evolve")) {
|
||||
SetTimer("evolve", RuleI(EvolvingItems, DelayUponEquipping));
|
||||
return;
|
||||
}
|
||||
|
||||
if (in) {
|
||||
GetTimers().at("evolve").SetTimer(RuleI(EvolvingItems, DelayUponEquipping));
|
||||
return;
|
||||
}
|
||||
|
||||
GetTimers().at("evolve").Disable();
|
||||
}
|
||||
|
||||
+66
-91
@@ -23,7 +23,6 @@
|
||||
|
||||
#ifndef COMMON_ITEM_INSTANCE_H
|
||||
#define COMMON_ITEM_INSTANCE_H
|
||||
#include "evolving_items.h"
|
||||
|
||||
|
||||
class ItemParse; // Parses item packets
|
||||
@@ -35,7 +34,6 @@ class EvolveInfo; // Stores information about an evolving item family
|
||||
#include "../common/bodytypes.h"
|
||||
#include "../common/deity.h"
|
||||
#include "../common/memory_buffer.h"
|
||||
#include "../common/repositories/character_evolving_items_repository.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@@ -53,11 +51,6 @@ typedef enum {
|
||||
byFlagNotSet //apply action if the flag is NOT set
|
||||
} byFlagSetting;
|
||||
|
||||
enum OrnamentationAugmentTypes {
|
||||
StandardOrnamentation = 20,
|
||||
SpecialOrnamentation = 21
|
||||
};
|
||||
|
||||
class SharedDatabase;
|
||||
|
||||
// ########################################
|
||||
@@ -76,9 +69,9 @@ namespace EQ
|
||||
/////////////////////////
|
||||
|
||||
// Constructors/Destructor
|
||||
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
|
||||
ItemInstance(const ItemData* item, const std::string& guid, int16 charges);
|
||||
|
||||
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
|
||||
ItemInstance(SharedDatabase *db, uint32 item_id, const std::string &guid, int16 charges);
|
||||
|
||||
ItemInstance(ItemInstTypes use_type);
|
||||
|
||||
@@ -86,6 +79,8 @@ namespace EQ
|
||||
|
||||
~ItemInstance();
|
||||
|
||||
inline std::string GetGuid() const { return m_guid; }
|
||||
|
||||
// Query item type
|
||||
bool IsType(item::ItemClass item_class) const;
|
||||
|
||||
@@ -110,8 +105,7 @@ namespace EQ
|
||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||
int8 AvailableAugmentSlot(int32 augment_type) const;
|
||||
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
||||
inline int GetAugmentType() const { return m_item ? m_item->AugType : 0; }
|
||||
inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; }
|
||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||
|
||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||
|
||||
@@ -144,8 +138,7 @@ namespace EQ
|
||||
bool IsAugmented();
|
||||
bool ContainsAugmentByID(uint32 item_id);
|
||||
int CountAugmentByID(uint32 item_id);
|
||||
bool IsOrnamentationAugment(EQ::ItemInstance* augment) const;
|
||||
ItemInstance* GetOrnamentationAugment() const;
|
||||
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
||||
bool UpdateOrnamentationInfo();
|
||||
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
||||
|
||||
@@ -184,13 +177,12 @@ namespace EQ
|
||||
void SetAttuned(bool flag) { m_attuned = flag; }
|
||||
|
||||
std::string GetCustomDataString() const;
|
||||
std::string GetCustomData(const std::string &identifier);
|
||||
void SetCustomDataString(const std::string& str);
|
||||
void SetCustomData(const std::string &identifier, const std::string& value);
|
||||
void SetCustomData(const std::string &identifier, int value);
|
||||
void SetCustomData(const std::string &identifier, float value);
|
||||
void SetCustomData(const std::string &identifier, bool value);
|
||||
void DeleteCustomData(const std::string& identifier);
|
||||
std::string GetCustomData(std::string identifier);
|
||||
void SetCustomData(std::string identifier, std::string value);
|
||||
void SetCustomData(std::string identifier, int value);
|
||||
void SetCustomData(std::string identifier, float value);
|
||||
void SetCustomData(std::string identifier, bool value);
|
||||
void DeleteCustomData(std::string identifier);
|
||||
|
||||
// Allows treatment of this object as though it were a pointer to m_item
|
||||
operator bool() const { return (m_item != nullptr); }
|
||||
@@ -207,9 +199,13 @@ namespace EQ
|
||||
bool IsDroppable(bool recurse = true) const;
|
||||
|
||||
bool IsScaling() const { return m_scaling; }
|
||||
bool IsEvolving() const { return (m_evolveLvl >= 1); }
|
||||
uint32 GetExp() const { return m_exp; }
|
||||
void SetExp(uint32 exp) { m_exp = exp; }
|
||||
void AddExp(uint32 exp) { m_exp += exp; }
|
||||
bool IsActivated() { return m_activated; }
|
||||
void SetActivated(bool activated) { m_activated = activated; }
|
||||
int8 GetEvolveLvl() const { return m_evolveLvl; }
|
||||
void SetScaling(bool v) { m_scaling = v; }
|
||||
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
|
||||
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
|
||||
@@ -224,16 +220,18 @@ namespace EQ
|
||||
|
||||
void Initialize(SharedDatabase *db = nullptr);
|
||||
void ScaleItem();
|
||||
bool EvolveOnAllKills() const;
|
||||
int8 GetMaxEvolveLvl() const;
|
||||
uint32 GetKillsNeeded(uint8 currentlevel);
|
||||
|
||||
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
|
||||
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
|
||||
|
||||
inline int32 GetSerialNumber() const { return m_SerialNumber; }
|
||||
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
|
||||
inline int32 GetSerialNumber() const { return m_serial_number; }
|
||||
inline void SetSerialNumber(int32 id) { m_serial_number = id; }
|
||||
|
||||
std::map<std::string, ::Timer>& GetTimers() const { return m_timers; }
|
||||
std::map<std::string, ::Timer>& GetTimers() { return m_timers; }
|
||||
void SetTimer(std::string name, uint32 time);
|
||||
void SetTimer(std::string name, uint32 time) const;
|
||||
void StopTimer(std::string name);
|
||||
void ClearTimers();
|
||||
|
||||
@@ -261,12 +259,11 @@ namespace EQ
|
||||
// these two are just quick checks
|
||||
int GetItemBaneDamageBody(bool augments = false) const;
|
||||
int GetItemBaneDamageRace(bool augments = false) const;
|
||||
int GetItemBaneDamageBody(uint8 against, bool augments = false) const;
|
||||
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
|
||||
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
|
||||
int GetItemMagical(bool augments = false) const;
|
||||
int GetItemHP(bool augments = false) const;
|
||||
int GetItemMana(bool augments = false) const;
|
||||
int GetItemManaRegen(bool augments = false) const;
|
||||
int GetItemEndur(bool augments = false) const;
|
||||
int GetItemAttack(bool augments = false) const;
|
||||
int GetItemStr(bool augments = false) const;
|
||||
@@ -296,46 +293,6 @@ namespace EQ
|
||||
int GetItemHeroicDR(bool augments = false) const;
|
||||
int GetItemHeroicCorrup(bool augments = false) const;
|
||||
int GetItemHaste(bool augments = false) const;
|
||||
int GetItemRegen(bool augments = false) const;
|
||||
int GetItemDamageShield(bool augments = false) const;
|
||||
int GetItemDSMitigation(bool augments = false) const;
|
||||
int GetItemHealAmt(bool augments = false) const;
|
||||
int GetItemSpellDamage(bool augments = false) const;
|
||||
int GetItemClairvoyance(bool augments = false) const;
|
||||
int GetItemSkillsStat(EQ::skills::SkillType skill, bool augments = false) const;
|
||||
uint32 GetItemGuildFavor() const;
|
||||
std::vector<uint32> GetAugmentIDs() const;
|
||||
std::vector<std::string> GetAugmentNames() const;
|
||||
static void AddGUIDToMap(uint64 existing_serial_number);
|
||||
static void ClearGUIDMap();
|
||||
|
||||
// evolving items stuff
|
||||
CharacterEvolvingItemsRepository::CharacterEvolvingItems &GetEvolvingDetails() const { return m_evolving_details; }
|
||||
|
||||
int8 GetEvolveLvl() const { if (GetItem()) { return GetItem()->EvolvingLevel; } return false; }
|
||||
bool IsEvolving() const { if (GetItem()) { return GetItem()->EvolvingItem; } return false; }
|
||||
int8 GetMaxEvolveLvl() const { if (GetItem()) { return GetItem()->EvolvingMax; } return false; }
|
||||
bool GetEvolveActivated() const { return m_evolving_details.activated ? true : false; }
|
||||
bool GetEvolveEquipped() const { return m_evolving_details.equipped ? true : false; }
|
||||
double GetEvolveProgression() const { return m_evolving_details.progression; }
|
||||
uint64 GetEvolveUniqueID() const { return m_evolving_details.id; }
|
||||
uint32 GetEvolveCharID() const { return m_evolving_details.character_id; }
|
||||
uint32 GetEvolveItemID() const { return m_evolving_details.item_id; }
|
||||
uint32 GetEvolveLoreID() const { if (GetItem()) { return GetItem()->EvolvingID; } return false; }
|
||||
uint64 GetEvolveCurrentAmount() const { return m_evolving_details.current_amount; }
|
||||
uint32 GetEvolveFinalItemID() const { return m_evolving_details.final_item_id; }
|
||||
uint32 GetAugmentEvolveUniqueID(uint8 augment_index) const;
|
||||
void SetEvolveEquipped(const bool in) const;
|
||||
void SetEvolveActivated(const bool in) const { m_evolving_details.activated = in; }
|
||||
void SetEvolveProgression(const double in) const { m_evolving_details.progression = in; }
|
||||
void SetEvolveUniqueID(const uint64 in) const { m_evolving_details.id = in; }
|
||||
void SetEvolveCharID(const uint32 in) const { m_evolving_details.character_id = in; }
|
||||
void SetEvolveItemID(const uint32 in) const { m_evolving_details.item_id = in; }
|
||||
void SetEvolveCurrentAmount(const uint64 in) const { m_evolving_details.current_amount = in; }
|
||||
void SetEvolveAddToCurrentAmount(const uint64 in) const { m_evolving_details.current_amount += in; }
|
||||
void SetEvolveFinalItemID(const uint32 in) const { m_evolving_details.final_item_id = in; }
|
||||
bool TransferOwnership(Database& db, const uint32 to_char_id) const;
|
||||
void CalculateEvolveProgression() const { m_evolving_details.progression = evolving_items_manager.CalculateProgression(GetEvolveCurrentAmount(), GetID()); }
|
||||
|
||||
protected:
|
||||
//////////////////////////
|
||||
@@ -348,32 +305,50 @@ namespace EQ
|
||||
|
||||
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
||||
|
||||
ItemInstTypes m_use_type{ItemInstNormal};// Usage type for item
|
||||
const ItemData * m_item{nullptr}; // Ptr to item data
|
||||
int16 m_charges{0}; // # of charges for chargeable items
|
||||
uint32 m_price{0}; // Bazaar /trader price
|
||||
uint32 m_color{0};
|
||||
uint32 m_merchantslot{0};
|
||||
int16 m_currentslot{0};
|
||||
bool m_attuned{false};
|
||||
int32 m_merchantcount{1};//number avaliable on the merchant, -1=unlimited
|
||||
int32 m_SerialNumber{0}; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||
uint32 m_exp{0};
|
||||
int8 m_evolveLvl{0};
|
||||
ItemData * m_scaledItem{nullptr};
|
||||
bool m_scaling{false};
|
||||
uint32 m_ornamenticon{0};
|
||||
uint32 m_ornamentidfile{0};
|
||||
uint32 m_new_id_file{0};
|
||||
uint32 m_ornament_hero_model{0};
|
||||
uint32 m_recast_timestamp{0};
|
||||
int m_task_delivered_count{0};
|
||||
mutable CharacterEvolvingItemsRepository::CharacterEvolvingItems m_evolving_details{};
|
||||
std::string m_guid;
|
||||
ItemInstTypes m_use_type; // Usage type for item
|
||||
const ItemData* m_item; // Ptr to item data
|
||||
int16 m_charges; // # of charges for chargeable items
|
||||
uint32 m_price; // Bazaar /trader price
|
||||
uint32 m_color;
|
||||
uint32 m_merchantslot;
|
||||
int16 m_currentslot;
|
||||
bool m_attuned;
|
||||
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
||||
uint32 m_serial_number; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||
uint32 m_exp;
|
||||
int8 m_evolveLvl;
|
||||
bool m_activated;
|
||||
ItemData* m_scaledItem;
|
||||
::EvolveInfo* m_evolveInfo;
|
||||
bool m_scaling;
|
||||
uint32 m_ornamenticon;
|
||||
uint32 m_ornamentidfile;
|
||||
uint32 m_new_id_file;
|
||||
uint32 m_ornament_hero_model;
|
||||
uint32 m_recast_timestamp;
|
||||
int m_task_delivered_count = 0;
|
||||
|
||||
// Items inside of this item (augs or contents) {};
|
||||
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
|
||||
std::map<std::string, std::string> m_custom_data {};
|
||||
mutable std::map<std::string, ::Timer> m_timers {};
|
||||
//
|
||||
// Items inside of this item (augs or contents);
|
||||
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
|
||||
std::map<std::string, std::string> m_custom_data;
|
||||
std::map<std::string, ::Timer> m_timers;
|
||||
};
|
||||
}
|
||||
|
||||
class EvolveInfo {
|
||||
public:
|
||||
friend class EQ::ItemInstance;
|
||||
//temporary
|
||||
uint16 LvlKills[9];
|
||||
uint32 FirstItem;
|
||||
uint8 MaxLvl;
|
||||
bool AllKills;
|
||||
|
||||
EvolveInfo();
|
||||
EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10);
|
||||
~EvolveInfo();
|
||||
};
|
||||
|
||||
#endif /*COMMON_ITEM_INSTANCE_H*/
|
||||
|
||||
-24640
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemulator.org)
|
||||
|
||||
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 LANGUAGES_H
|
||||
#define LANGUAGES_H
|
||||
#include "../common/types.h"
|
||||
|
||||
#define LANG_COMMON_TONGUE 0
|
||||
#define LANG_BARBARIAN 1
|
||||
#define LANG_ERUDIAN 2
|
||||
#define LANG_ELVISH 3
|
||||
#define LANG_DARK_ELVISH 4
|
||||
#define LANG_DWARVISH 5
|
||||
#define LANG_TROLL 6
|
||||
#define LANG_OGRE 7
|
||||
#define LANG_GNOMISH 8
|
||||
#define LANG_HALFLING 9
|
||||
#define LANG_THIEVES_CANT 10
|
||||
#define LANG_OLD_ERUDIAN 11
|
||||
#define LANG_ELDER_ELVISH 12
|
||||
#define LANG_FROGLOK 13
|
||||
#define LANG_GOBLIN 14
|
||||
#define LANG_GNOLL 15
|
||||
#define LANG_COMBINE_TONGUE 16
|
||||
#define LANG_ELDER_TEIRDAL 17
|
||||
#define LANG_LIZARDMAN 18
|
||||
#define LANG_ORCISH 19
|
||||
#define LANG_FAERIE 20
|
||||
#define LANG_DRAGON 21
|
||||
#define LANG_ELDER_DRAGON 22
|
||||
#define LANG_DARK_SPEECH 23
|
||||
#define LANG_VAH_SHIR 24
|
||||
#define LANG_ALARAN 25
|
||||
#define LANG_HADAL 26
|
||||
#define LANG_UNKNOWN 27
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef CODE_LOOT_H
|
||||
#define CODE_LOOT_H
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "../common/types.h"
|
||||
|
||||
struct LootItem {
|
||||
uint32 item_id;
|
||||
int16 equip_slot;
|
||||
uint16 charges;
|
||||
uint16 lootslot;
|
||||
uint32 aug_1;
|
||||
uint32 aug_2;
|
||||
uint32 aug_3;
|
||||
uint32 aug_4;
|
||||
uint32 aug_5;
|
||||
uint32 aug_6;
|
||||
bool attuned;
|
||||
std::string custom_data;
|
||||
uint32 ornamenticon{};
|
||||
uint32 ornamentidfile{};
|
||||
uint32 ornament_hero_model{};
|
||||
uint16 trivial_min_level;
|
||||
uint16 trivial_max_level;
|
||||
uint16 npc_min_level;
|
||||
uint16 npc_max_level;
|
||||
};
|
||||
|
||||
typedef std::list<LootItem*> LootItems;
|
||||
|
||||
|
||||
#endif //CODE_LOOT_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user