Compare commits

..

No commits in common. "master" and "v23.6.0" have entirely different histories.

326 changed files with 11325 additions and 15282 deletions

View File

@ -1,5 +1,6 @@
base/ !Makefile
!base/*.json base/*.sql
override/ base/*.zip
repo/ base/db/
cache/ base/maps/
!base/expansion/Makefile

View File

@ -1,127 +1,196 @@
# Build binaries: make cmake, make build
# One time initial setup (or to reset db): make prep, make inject-mariadb, make maps
# Update custom db edits: make inject-custom
# Start up server: make shared, make login, make world, make zone
# in game, stop combat spam #logs set gmsay 79 0
# in game, stop loot spam #logs set gmsay 69 0
NAME := eqemu-server NAME := eqemu-server
.ONESHELL:
.PHONY: prep DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
prep: is-vscode DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
@echo "Preparing build/bin for usage..."
@echo "Prepping folders..." .PHONY: build
@mkdir -p .devcontainer/override build:
@mkdir -p .devcontainer/repo ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@mkdir -p .devcontainer/cache @make -C ../ -f .devcontainer/Makefile build --no-print-directory
@mkdir -p build/bin/logs exit
@mkdir -p build/bin/shared endif
@mkdir -p build/bin/assets cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
@echo "Applying overrides..." .PHONY: cmake
@if [ ! -f .devcontainer/override/eqemu_config.json ]; then cp .devcontainer/base/eqemu_config.json .devcontainer/override/eqemu_config.json; fi cmake:
@if [ -f build/bin/eqemu_config.json ]; then unlink build/bin/eqemu_config.json; fi ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
cd build/bin && ln -s ../../.devcontainer/override/eqemu_config.json eqemu_config.json @make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
@if [ ! -f .devcontainer/override/login.json ]; then cp .devcontainer/base/login.json .devcontainer/override/login.json; fi exit
@if [ -f build/bin/login.json ]; then unlink build/bin/login.json; fi endif
cd build/bin && ln -s ../../.devcontainer/override/login.json login.json @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 ..
@echo "Cloning repositories..." clean:
cd .devcontainer/repo && if [ ! -d "quests" ]; then cd ../../.devcontainer/repo/ && git clone https://github.com/ProjectEQ/projecteqquests.git quests; fi ifneq (,$(findstring .devcontainer,$$PWD))
cd .devcontainer/repo && if [ ! -d "eqemu-definitions" ]; then cd ../../.devcontainer/repo/ && git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi @make -C ../ -f .devcontainer/Makefile clean --no-print-directory
cd .devcontainer/repo && if [ ! -d "maps" ]; then cd ../../ && make maps; fi endif
@if [ -d build/bin/quests ]; then unlink build/bin/quests; fi
cd build/bin && ln -s ../../.devcontainer/repo/quests quests
@if [ -d build/bin/maps ]; then unlink build/bin/maps; fi
cd build/bin && ln -s ../../.devcontainer/repo/maps maps
@if [ -d build/bin/eqemu-definitions ]; then unlink build/bin/eqemu-definitions; fi
cd build/bin && ln -s ../../.devcontainer/repo/eqemu-definitions eqemu-definitions
@mkdir -p build/bin/quests/mods
@echo "Applying base links..."
cp -R -u -p utils/patches .devcontainer/base/
@if [ -d build/bin/assets/patches ]; then unlink build/bin/assets/patches; fi
cd build/bin/assets && ln -s ../../../.devcontainer/base/patches patches
@if [ -d build/bin/lua_modules ]; then unlink build/bin/lua_modules; fi
cd build/bin && ln -s ../../.devcontainer/repo/quests/lua_modules lua_modules
@if [ -d build/bin/mods ]; then unlink build/bin/mods; fi
cd build/bin && ln -s ../../.devcontainer/repo/quests/mods mods
@if [ -d build/bin/plugins ]; then unlink build/bin/plugins; fi
cd build/bin && ln -s ../../.devcontainer/repo/quests/plugins plugins
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
is-vscode:
@if [ -z "$$REMOTE_CONTAINERS" ]; then \
echo "Not running in VS Code devcontainer"; \
exit 1; \
fi
clean: is-vscode
rm -rf build rm -rf build
.PHONY: maps docker-cmake:
maps: is-vscode 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..." @echo "Downloading maps..."
@mkdir -p .devcontainer/repo/maps @mkdir -p base/maps
@cd .devcontainer/repo/maps && wget -nc https://github.com/EQEmu/maps/archive/refs/heads/master.zip @cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
@cd .devcontainer/repo/maps && unzip -o master.zip @cd base/maps && unzip -o master.zip
@cd .devcontainer/repo/maps && mv maps-master/* . @cd base/maps && mv eqemu-maps-master/* .
@cd .devcontainer/repo/maps && rm -rf maps-master @cd base/maps && rm -rf eqemu-maps-master
@echo "Maps downloaded." @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 # Runs tests
.PHONY: test .PHONY: test
test: is-vscode test:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
exit
endif
cd build/bin && ./tests cd build/bin && ./tests
# Runs login binary # Runs login binary
.PHONY: login .PHONY: login
login: is-vscode check-mariadb login:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
exit
endif
cd build/bin && ./loginserver cd build/bin && ./loginserver
.PHONY: hotfix
hotfix: shared
# Runs shared_memory binary # Runs shared_memory binary
.PHONY: shared .PHONY: shared
shared: is-vscode check-mariadb shared:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
exit
endif
cd build/bin && ./shared_memory cd build/bin && ./shared_memory
# Runs zone binary # Runs zone binary
.PHONY: zone .PHONY: zone
zone: is-vscode check-mariadb zone:
@find build/bin/logs/zone/ -type f -name 'zone*.log' -exec rm -f {} + 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 cd build/bin && ./zone
check-mariadb: is-vscode
@if ! sudo service mariadb status | grep -q 'active (running)'; then \
sudo service mariadb start; \
fi
# Runs world binary # Runs world binary
.PHONY: world .PHONY: world
world: is-vscode check-mariadb world:
@find build/bin/logs/ -type f -name 'world*.log' -exec rm -f {} + 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 cd build/bin && ./world
# Runs ucs binary # Runs ucs binary
.PHONY: ucs .PHONY: ucs
ucs: is-vscode check-mariadb ucs:
@find build/bin/logs/ -type f -name 'ucs*.log' -exec rm -f {} + 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 cd build/bin && ./ucs
# Runs queryserv binary # Runs queryserv binary
.PHONY: queryserv .PHONY: queryserv
queryserv: is-vscode check-mariadb queryserv:
@find build/bin/logs/ -type f -name 'query_server*.log' -exec rm -f {} + 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 cd build/bin && ./queryserv
reset-content: valgrind-%:
@echo "Resetting content tables in database peq..." ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql" @make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
exit
valgrind-%: is-vscode endif
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$* cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
# Start mariaDB standalone # Start mariaDB standalone
@ -132,33 +201,30 @@ mariadb:
.PHONY: inject-mariadb .PHONY: inject-mariadb
inject-mariadb: inject-mariadb:
-sudo service mariadb start -sudo service mariadb start
-mkdir -p .devcontainer/cache/db/ -mkdir -p base/db/
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;' -sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
-sudo mariadb -e 'CREATE DATABASE peq;' -sudo mariadb -e 'CREATE DATABASE peq;'
-sudo mariadb -e "CREATE USER IF NOT EXISTS 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';" -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';" -sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
ifeq (,$(wildcard .devcontainer/cache/db/db.sql.zip)) ifeq (,$(wildcard base/db/db.sql.zip))
@echo ".devcontainer/cache/db.sql.zip not found. Downloading database from https://db.eqemu.dev/latest" @echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
wget -nc https://db.eqemu.dev/latest -O .devcontainer/cache/db/db.sql.zip wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
-cd .devcontainer/cache/db && unzip db.sql.zip -cd base/db && unzip db.sql.zip
endif endif
@echo "Sourcing db may take a while, please wait..." @echo "Sourcing db may take a while, please wait..."
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_login.sql"
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_player.sql"
@# deprecated cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_queryserv.sql"
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_state.sql"
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_system.sql"
@echo "MariaDB is now injected." @echo "MariaDB is now injected."
.PHONY: gm-% .PHONY: gm-%
gm-%: is-vscode gm-%:
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';" 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." @echo "Account $* is now a GM. /camp to have it go into effect."
depends: is-vscode depends:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
exit
endif
sudo apt install graphviz pip time sudo apt install graphviz pip time
pip3 install graphviz pip3 install graphviz
mkdir -p build/depends mkdir -p build/depends
@ -175,54 +241,44 @@ depends: is-vscode
@echo "Common..." @echo "Common..."
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
backup: is-vscode backup:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
exit
endif
@mkdir -p build/bin/backup @mkdir -p build/bin/backup
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
restore-%: is-vscode cpu-zone:
@if [ -z "$*" ]; then \
echo "Please provide a backup file to restore from. Example: make restore-backup.sql"; \
exit 1; \
fi
@echo "Restoring from backup $*"
@sudo mariadb --database peq -e "$*"
cpu-zone: is-vscode
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer) ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@echo "This makefile is not intended to be run from the .devcontainer directory." @make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
exit exit
endif endif
@cd build/bin && mkdir -p tmp @cd build/bin && mkdir -p tmp
cd build/bin && CPUPROFILE=prof.out ./zone cd build/bin && CPUPROFILE=prof.out ./zone
pprof-zone: is-vscode pprof-zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer) ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@echo "This makefile is not intended to be run from the .devcontainer directory." @make -C ../ -f .devcontainer/Makefile pprof-zone --no-print-directory
exit exit
endif endif
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
pprof-web-zone:
pprof-gv-zone: is-vscode
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer) ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@echo "This makefile is not intended to be run from the .devcontainer directory." @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 exit
endif endif
cd build/bin && google-pprof --gv zone prof.out > prof.gv cd build/bin && google-pprof --gv zone prof.out > prof.gv
heap-zone:
heap-zone: is-vscode
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer) ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@echo "This makefile is not intended to be run from the .devcontainer directory." @make -C ../ -f .devcontainer/Makefile heap-zone --no-print-directory
exit exit
endif endif
@cd build/bin && mkdir -p tmp @cd build/bin && mkdir -p tmp
cd build/bin && HEAPPROFILE=prof.out ./zone cd build/bin && HEAPPROFILE=prof.out ./zone
.PHONY: pull
pull:
git pull
@if [ ! -d "quests" ]; then git clone https://github.com/rebuildeq/quests.git quests; fi
cd quests && git pull
@if [ ! -d "eqemu-definitions" ]; then git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi
cd eqemu-definitions && git pull

View File

@ -40,41 +40,10 @@
"GitHub.copilot", "GitHub.copilot",
"xackery.make-magic", "xackery.make-magic",
"Gruntfuggly.todo-tree", "Gruntfuggly.todo-tree",
"ms-vscode.cmake-tools", "ms-vscode.cmake-tools"
"sumneko.lua" ]
],
"settings": {
"Lua.runtime.version": "Lua 5.1",
"Lua.workspace.library": [
"/src/repo/eqemu-definitions"
],
"Lua.diagnostics.disable": [
"lowercase-global"
],
"cmake.statusbar.advanced": {
"kit": {
"visibility": "hidden"
},
"debug": {
"visibility": "hidden"
},
"buildTarget": {
"visibility": "compact"
},
"launch": {
"visibility": "hidden"
},
"ctest": {
"visibility": "icon"
}
}
}
} }
}, },
"mounts": [
"source=${localWorkspaceFolder}/.devcontainer/Makefile,target=/src/Makefile,type=bind,consistency=cached"
],
"workspaceFolder": "/src", "workspaceFolder": "/src",
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached" "workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
} }

98
.drone.yml Normal file
View File

@ -0,0 +1,98 @@
---
kind: pipeline
type: docker
name: Build Linux
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
concurrency:
limit: 1
volumes:
- name: cache
host:
path: /var/lib/cache-release
steps:
- name: Build Linux X64
image: akkadius/eqemu-server:v14
environment:
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
commands:
- ./utils/scripts/build/linux-build.sh
volumes:
- name: cache
path: /home/eqemu/.ccache/
---
kind: pipeline
type: exec
name: Build Windows
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
concurrency:
limit: 1
platform:
os: windows
arch: amd64
steps:
- name: Build Windows X64
environment:
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
commands:
- .\utils\scripts\build\windows-build.ps1
---
kind: pipeline
type: docker
name: Publish Artifacts to Github
steps:
- name: Upload Artifacts
image: akkadius/eqemu-build-releaser:v3
environment:
RCLONE_CONFIG_REMOTE_TYPE: ftp
RCLONE_FTP_HOST: drone.akkadius.com
RCLONE_FTP_USER: artifacts
RCLONE_FTP_PASS:
from_secret: RCLONE_FTP_PASS
GH_RELEASE_GITHUB_API_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN
commands:
- ./utils/scripts/build/should-release/should-release
- rclone config create remote ftp env_auth true > /dev/null
- |
rclone copy remote: --include "eqemu-server*.zip" .
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
- |
rclone delete remote: --include "eqemu-server*.zip"
trigger:
branch:
- master
event:
- push
depends_on:
- Build Windows
- Build Linux

View File

@ -1,81 +0,0 @@
name: Build
on:
push:
branches:
- master
pull_request:
jobs:
linux:
name: Linux
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v5
with:
submodules: recursive
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}-ccache
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential ninja-build ccache libmariadb-dev libmariadb-dev-compat libboost-all-dev libperl-dev liblua5.1-0-dev libluajit-5.1-dev zlib1g-dev uuid-dev libssl-dev libsodium-dev libmbedtls-dev
- name: Configure
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DEQEMU_BUILD_TESTS=ON \
-DEQEMU_BUILD_LOGIN=ON \
-DEQEMU_BUILD_LUA=ON \
-DEQEMU_BUILD_PERL=ON \
-DEQEMU_BUILD_CLIENT_FILES=ON
- name: Build
run: cmake --build build --parallel
- name: Test
working-directory: build
run: ./bin/tests
windows:
name: Windows
runs-on: windows-latest
steps:
- name: Checkout source
uses: actions/checkout@v5
with:
submodules: recursive
- name: Enable long paths
run: git config --global core.longpaths true
- name: Setup MSVC environment
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Configure
shell: pwsh
run: |
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
-DCMAKE_BUILD_TYPE=RelWithDebInfo `
-DEQEMU_BUILD_TESTS=ON `
-DEQEMU_BUILD_LOGIN=ON `
-DEQEMU_BUILD_LUA=ON `
-DEQEMU_BUILD_ZLIB=ON `
-DEQEMU_BUILD_CLIENT_FILES=ON
- name: Build
shell: pwsh
run: cmake --build build --config RelWithDebInfo --target ALL_BUILD -- /m
- name: Test
working-directory: build
run: ./bin/RelWithDebInfo/tests.exe

25
.vscode/settings.json vendored
View File

@ -21,6 +21,14 @@
"${workspaceFolder}/dependencies/zlibng" "${workspaceFolder}/dependencies/zlibng"
], ],
"telemetry.enableTelemetry": false, "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.skipConfigureIfCachePresent": true,
"cmake.configureOnOpen": false, "cmake.configureOnOpen": false,
"files.associations": { "files.associations": {
@ -107,5 +115,22 @@
"format": "cpp", "format": "cpp",
"ranges": "cpp", "ranges": "cpp",
"span": "cpp" "span": "cpp"
},
"cmake.statusbar.advanced": {
"kit": {
"visibility": "hidden",
},
"debug": {
"visibility": "hidden",
},
"buildTarget": {
"visibility": "hidden",
},
"launch": {
"visibility": "hidden",
},
"ctest": {
"visibility": "icon",
}
} }
} }

View File

@ -1,283 +1,3 @@
## [23.10.3] 9/16/2025
### Hotfix
* Hotfix crashes occurring in #4987. @Akkadius 2025-09-17
## [23.10.2] 9/16/2025
### Hotfix
* Revert #4996 as it was causing critical issues with spells that needs to be further investigated. @Akkadius 2025-09-17
## [23.10.1] 9/16/2025
### Hotfix
* Fixed Mail Key Bug ([#5015](https://github.com/EQEmu/Server/pull/5015)) @Kinglykrab 2025-09-16
## [23.10.0] 9/15/2025
### Build
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
### Code
* Add #npcedit npc_tint_id Help Message ([#4982](https://github.com/EQEmu/Server/pull/4982)) @Kinglykrab 2025-08-17
* Cleanup #show ip_lookup Message ([#5005](https://github.com/EQEmu/Server/pull/5005)) @Kinglykrab 2025-08-30
* Fix #set race 0 Message ([#5004](https://github.com/EQEmu/Server/pull/5004)) @Kinglykrab 2025-08-30
* Fix Issues with Strings::Commify and Mob::SendStatsWindow ([#4984](https://github.com/EQEmu/Server/pull/4984)) @Kinglykrab 2025-08-17
* Remove Attributions ([#4988](https://github.com/EQEmu/Server/pull/4988)) @KimLS 2025-08-16
* Remove Unused errorname Variable ([#5001](https://github.com/EQEmu/Server/pull/5001)) @Kinglykrab 2025-08-29
### Commands
* Add #find account Subcommand ([#4981](https://github.com/EQEmu/Server/pull/4981)) @Kinglykrab 2025-08-17
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
* Add #task complete Saylink to #task show ([#4985](https://github.com/EQEmu/Server/pull/4985)) @Kinglykrab 2025-08-17
### Constants
* Change Race Changes to Race Namespace ([#5000](https://github.com/EQEmu/Server/pull/5000)) @Kinglykrab 2025-08-30
* Convert SE Defines to SpellEffect Namespace ([#4999](https://github.com/EQEmu/Server/pull/4999)) @Kinglykrab 2025-08-30
### Database
* Add `heal_amount` to `character_stats_record` ([#4986](https://github.com/EQEmu/Server/pull/4986)) @Kinglykrab 2025-08-17
### Fixes
* Fix #show recipe uint16 Cap ([#4978](https://github.com/EQEmu/Server/pull/4978)) @Kinglykrab 2025-08-11
* Fix Race 474 for Titanium ([#4979](https://github.com/EQEmu/Server/pull/4979)) @regneq 2025-08-11
* Fix Recipe Inspect Bug ([#4994](https://github.com/EQEmu/Server/pull/4994)) @Kinglykrab 2025-08-30
* Fix Several Evolving Item Bugs ([#4992](https://github.com/EQEmu/Server/pull/4992)) @neckkola 2025-09-08
* Fix Task Reloading ([#5002](https://github.com/EQEmu/Server/pull/5002)) @Kinglykrab 2025-08-29
### Loginserver
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
### Pets
* Add Pet Constants and Methods ([#4987](https://github.com/EQEmu/Server/pull/4987)) @Kinglykrab 2025-08-17
### Quest API
* Add EVENT_CHARM_START and EVENT_CHARM_END ([#5013](https://github.com/EQEmu/Server/pull/5013)) @Kinglykrab 2025-09-15
* Add GetKeyRing() to Perl/Lua ([#4980](https://github.com/EQEmu/Server/pull/4980)) @Kinglykrab 2025-08-17
* Add GetNPCTintIndex() to Perl/Lua ([#4983](https://github.com/EQEmu/Server/pull/4983)) @Kinglykrab 2025-08-17
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
* Add Identifiers to Get/Modify NPC Stat Methods ([#5012](https://github.com/EQEmu/Server/pull/5012)) @Kinglykrab 2025-09-15
### Repositories
* Convert Character Inspect Messages to Repositories ([#4997](https://github.com/EQEmu/Server/pull/4997)) @Kinglykrab 2025-08-30
* Convert Damage Shield Types to Repositories ([#4995](https://github.com/EQEmu/Server/pull/4995)) @Kinglykrab 2025-08-30
* Convert Item Loading to Repositories ([#4998](https://github.com/EQEmu/Server/pull/4998)) @Kinglykrab 2025-08-30
* Convert Mail Key to Repositories ([#5007](https://github.com/EQEmu/Server/pull/5007)) @Kinglykrab 2025-09-15
* Convert Shared Bank Platinum to Repositories ([#5006](https://github.com/EQEmu/Server/pull/5006)) @Kinglykrab 2025-09-02
* Convert Spell Loading to Repositories ([#4996](https://github.com/EQEmu/Server/pull/4996)) @Kinglykrab 2025-08-30
* Convert Total Time Played to Repositories ([#5008](https://github.com/EQEmu/Server/pull/5008)) @Kinglykrab 2025-09-15
## [23.9.1] 8/2/2025
### Hotfix
* Fix Quest Ownership Edge Case ([#4977](https://github.com/EQEmu/Server/pull/4977)) @Kinglykrab 2025-08-02
## [23.9.0] 8/2/2025
### Bots
* Fix FinishBuffing rule ([#4961](https://github.com/EQEmu/Server/pull/4961)) @nytmyr 2025-07-01
* Fix ^cast resurrects ([#4958](https://github.com/EQEmu/Server/pull/4958)) @nytmyr 2025-06-29
### Build
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
* More Build Speed Improvements ([#4959](https://github.com/EQEmu/Server/pull/4959)) @Akkadius 2025-06-30
### Commands
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
### Database
* Add Indexes to NPC's Spawns Loot ([#4972](https://github.com/EQEmu/Server/pull/4972)) @Akkadius 2025-07-30
### Feature
* Zone Scripting ([#4908](https://github.com/EQEmu/Server/pull/4908)) @Kinglykrab 2025-07-10
### Fixes
* Add a missing Froglok starting area for Titanium Startzone. ([#4962](https://github.com/EQEmu/Server/pull/4962)) @regneq 2025-07-04
* Fix Hero's Forge Ingame and Character Select ([#4966](https://github.com/EQEmu/Server/pull/4966)) @Kinglykrab 2025-07-30
* Show player count on the server list status. ([#4971](https://github.com/EQEmu/Server/pull/4971)) @regneq 2025-07-30
### Loginserver
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
### Performance
* Clear Wearchange Deduplication Cache ([#4960](https://github.com/EQEmu/Server/pull/4960)) @Akkadius 2025-06-30
### Quest API
* Add GetMemberRole() to Perl/Lua ([#4963](https://github.com/EQEmu/Server/pull/4963)) @Barathos 2025-07-10
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
## [23.8.1] 6/28/2025
### Crash Fix
* Fix Possible Crashes with Raid Methods ([#4955](https://github.com/EQEmu/Server/pull/4955)) @Kinglykrab 2025-06-26
### Databuckets
* Revert Caching Changes of #4917 ([#4957](https://github.com/EQEmu/Server/pull/4957)) @Akkadius 2025-06-28
### Fixes
* Fix FindCharacter Using content_db ([#4956](https://github.com/EQEmu/Server/pull/4956)) @Kinglykrab 2025-06-26
* Fix Hero Forge on Character Select ([#4954](https://github.com/EQEmu/Server/pull/4954)) @Kinglykrab 2025-06-26
## [23.8.0] 6/25/2025
### API
* Add wwmarquee <type> <message> ([#4919](https://github.com/EQEmu/Server/pull/4919)) @Akkadius 2025-06-23
### Build
* Significantly Improve Build Times Using Unity Builds ([#4948](https://github.com/EQEmu/Server/pull/4948)) @Akkadius 2025-06-22
### Code
* AdventureManager Global to Singleton Cleanup ([#4931](https://github.com/EQEmu/Server/pull/4931)) @Kinglykrab 2025-06-25
* Cleanup Strings Header ([#4950](https://github.com/EQEmu/Server/pull/4950)) @Akkadius 2025-06-22
* ClientList Global to Singleton Cleanup ([#4942](https://github.com/EQEmu/Server/pull/4942)) @Kinglykrab 2025-06-25
* DatabaseUpdate Global to Singleton Cleanup ([#4943](https://github.com/EQEmu/Server/pull/4943)) @Kinglykrab 2025-06-25
* DiscordManager Global to Singleton Cleanup ([#4926](https://github.com/EQEmu/Server/pull/4926)) @Kinglykrab 2025-06-25
* EQ::Random Global to Singleton Cleanup ([#4936](https://github.com/EQEmu/Server/pull/4936)) @Kinglykrab 2025-06-22
* EQEmuLogSys Global to Singleton Cleanup ([#4925](https://github.com/EQEmu/Server/pull/4925)) @Akkadius 2025-06-25
* EvolvingItemsManager Global to Singleton Cleanup ([#4929](https://github.com/EQEmu/Server/pull/4929)) @Kinglykrab 2025-06-25
* LFGuildManager Global to Singleton Cleanup ([#4927](https://github.com/EQEmu/Server/pull/4927)) @Kinglykrab 2025-06-25
* LoginServerList Global to Singleton Cleanup ([#4941](https://github.com/EQEmu/Server/pull/4941)) @Kinglykrab 2025-06-25
* Optimize PCH Config (Faster Builds) ([#4951](https://github.com/EQEmu/Server/pull/4951)) @Akkadius 2025-06-22
* PCH Cleanup ([#4952](https://github.com/EQEmu/Server/pull/4952)) @Akkadius 2025-06-25
* PathManager Global to Singleton Cleanup ([#4924](https://github.com/EQEmu/Server/pull/4924)) @Akkadius 2025-06-22
* PetitionList Global to Singleton Cleanup ([#4944](https://github.com/EQEmu/Server/pull/4944)) @Kinglykrab 2025-06-25
* PlayerEventLogs Global to Singleton Cleanup ([#4928](https://github.com/EQEmu/Server/pull/4928)) @Kinglykrab 2025-06-25
* QueryServConnection Global to Singleton Cleanup ([#4938](https://github.com/EQEmu/Server/pull/4938)) @Kinglykrab 2025-06-25
* Remove Lua Rule Constants ([#4949](https://github.com/EQEmu/Server/pull/4949)) @Akkadius 2025-06-22
* Remove Regex Compile Bloat ([#4947](https://github.com/EQEmu/Server/pull/4947)) @Akkadius 2025-06-22
* Remove Unused MZoneShutdown Mutex ([#4946](https://github.com/EQEmu/Server/pull/4946)) @Kinglykrab 2025-06-22
* SharedTaskManager Global to Singleton Cleanup ([#4930](https://github.com/EQEmu/Server/pull/4930)) @Kinglykrab 2025-06-25
* SkillCaps Global to Singleton Cleanup ([#4933](https://github.com/EQEmu/Server/pull/4933)) @Kinglykrab 2025-06-22
* TaskManager Global to Singleton Cleanup ([#4945](https://github.com/EQEmu/Server/pull/4945)) @Kinglykrab 2025-06-22
* UCSConnection Global to Singleton Cleanup ([#4937](https://github.com/EQEmu/Server/pull/4937)) @Kinglykrab 2025-06-25
* WebInterfaceList Global to Singleton Cleanup ([#4935](https://github.com/EQEmu/Server/pull/4935)) @Kinglykrab 2025-06-25
* WorldContentServer Global to Singleton Cleanup ([#4939](https://github.com/EQEmu/Server/pull/4939)) @Kinglykrab 2025-06-25
* WorldEventScheduler and ZoneEventScheduler Global to Singleton Cleanup ([#4932](https://github.com/EQEmu/Server/pull/4932)) @Kinglykrab 2025-06-25
* ZSList Global to Singleton Cleanup ([#4940](https://github.com/EQEmu/Server/pull/4940)) @Kinglykrab 2025-06-25
* ZoneStore Global to Singleton Cleanup ([#4934](https://github.com/EQEmu/Server/pull/4934)) @Kinglykrab 2025-06-23
### Corpses
* Add corpse entity variables to DB ([#4911](https://github.com/EQEmu/Server/pull/4911)) @fryguy503 2025-06-25
### Databuckets
* Move Databuckets to Common ([#4918](https://github.com/EQEmu/Server/pull/4918)) @Akkadius 2025-06-16
* Nested Caching ([#4917](https://github.com/EQEmu/Server/pull/4917)) @Akkadius 2025-06-25
### Doors
* Fix door saving for versions ([#4905](https://github.com/EQEmu/Server/pull/4905)) @nytmyr 2025-06-09
### Fixes
* Bulk Send Corpses after Idle State ([#4910](https://github.com/EQEmu/Server/pull/4910)) @Akkadius 2025-06-09
* Fix ClientList Singleton Shortcomings of #4942 @Akkadius 2025-06-25
* Fix breaking changes to Titanium, SoF, SoD patches causes by big bags update ([#4922](https://github.com/EQEmu/Server/pull/4922)) @regneq 2025-06-25
### Logs
* Fix output for tasks in logs ([#4907](https://github.com/EQEmu/Server/pull/4907)) @joligario 2025-06-09
### Performance
* Auto Idle / AFK ([#4903](https://github.com/EQEmu/Server/pull/4903)) @Akkadius 2025-05-22
* Wearchange Packet Send Deduplication ([#4916](https://github.com/EQEmu/Server/pull/4916)) @Akkadius 2025-06-25
### Player Event Logs
* Don't Clear Event Data on ETL Events ([#4913](https://github.com/EQEmu/Server/pull/4913)) @Akkadius 2025-06-25
### Player Events
* Don't Write Empty Data ([#4912](https://github.com/EQEmu/Server/pull/4912)) @Akkadius 2025-06-25
* Zone Fetch Settings from QS if Enabled ([#4915](https://github.com/EQEmu/Server/pull/4915)) @Akkadius 2025-06-25
### Quest API
* Add CompleteTask and UncompleteTask methods to Perl/Lua ([#4921](https://github.com/EQEmu/Server/pull/4921)) @Barathos 2025-06-25
* Lua Client Scoped EnableTitleSets ([#4914](https://github.com/EQEmu/Server/pull/4914)) @fryguy503 2025-06-25
### Quests
* Support Multiple Quest, Plugin, and Lua Module Paths ([#4906](https://github.com/EQEmu/Server/pull/4906)) @Akkadius 2025-06-09
### World API
* Input Validation ([#4904](https://github.com/EQEmu/Server/pull/4904)) @Akkadius 2025-05-22
## [23.7.0] 5/19/2025
### CLI
* Add custom database version output ([#4901](https://github.com/EQEmu/Server/pull/4901)) @joligario 2025-05-18
* Fix MySQL check in database dumper ([#4897](https://github.com/EQEmu/Server/pull/4897)) @joligario 2025-05-16
### Commands
* Add #zonevariable Command ([#4882](https://github.com/EQEmu/Server/pull/4882)) @Kinglykrab 2025-05-15
### Database
* Add Custom Database Migrations for Operators ([#4892](https://github.com/EQEmu/Server/pull/4892)) @Akkadius 2025-05-16
* Remove Transaction Wrapped Character Save ([#4894](https://github.com/EQEmu/Server/pull/4894)) @Akkadius 2025-05-16
### Fixes
* Deadlock on failed #copycharacter commands ([#4887](https://github.com/EQEmu/Server/pull/4887)) @Akkadius 2025-05-16
### Logging
* Auto Update Log Category Names ([#4890](https://github.com/EQEmu/Server/pull/4890)) @Akkadius 2025-05-16
### Netcode
* Resend Logic Adjustments ([#4900](https://github.com/EQEmu/Server/pull/4900)) @Akkadius 2025-05-18
### Player Events
* Add rule to ignore configured GM commands ([#4888](https://github.com/EQEmu/Server/pull/4888)) @Akkadius 2025-05-16
### Rules
* Auto Update Rule Notes from Source ([#4891](https://github.com/EQEmu/Server/pull/4891)) @Akkadius 2025-05-16
### World
* Fix Rarer Reload Deadlock ([#4893](https://github.com/EQEmu/Server/pull/4893)) @Akkadius 2025-05-16
### Zone State
* Load New Spawn2 Data When Present ([#4889](https://github.com/EQEmu/Server/pull/4889)) @Akkadius 2025-05-16
## [23.6.0] 5/14/2025 ## [23.6.0] 5/14/2025
### Bots ### Bots

View File

@ -42,7 +42,6 @@ IF(USE_MAP_MMFS)
ENDIF (USE_MAP_MMFS) ENDIF (USE_MAP_MMFS)
IF(MSVC) IF(MSVC)
add_compile_options(/bigobj)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX) ADD_DEFINITIONS(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING) ADD_DEFINITIONS(-DCRASH_LOGGING)
@ -363,8 +362,6 @@ MESSAGE(STATUS "**************************************************")
#setup server libs and headers #setup server libs and headers
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour) SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
set(FMT_HEADER_ONLY OFF)
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}") INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}") INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}") INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")

View File

@ -1,49 +0,0 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 19,
"patch": 0
},
"configurePresets": [
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_C_COMPILER_LAUNCHER": "ccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache",
"EQEMU_BUILD_LOGIN": "ON",
"EQEMU_BUILD_TESTS": "ON",
"EQEMU_ADD_PROFILER": "ON"
}
},
{
"name": "linux-release",
"displayName": "Linux Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_C_COMPILER_LAUNCHER": "ccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache",
"EQEMU_BUILD_LOGIN": "ON"
}
},
{
"name": "win-msvc",
"displayName": "Windows MSVC (VS 2022)",
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build/{presetName}",
"architecture": { "value": "x64" },
"cacheVariables": {
"CMAKE_CONFIGURATION_TYPES": "Debug;Release",
"EQEMU_BUILD_LOGIN": "ON",
"EQEMU_BUILD_TESTS": "ON"
}
}
]
}

179
README.md
View File

@ -1,150 +1,83 @@
<h1 align="center">EQEmulator Server Platform</h1> # EQEmulator Core Server
| Drone (Linux x64) | Drone (Windows x64) |
<p align="center"> |:---:|:---:|
<img src="https://github.com/user-attachments/assets/11942e15-b512-402d-a619-0543c7f1151e" style="border-radius: 10px"> |[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |
</p>
<p align="center">
<b>EQEmulator - A Fan-Made Project Honoring a Legendary MMORPG</b>
</p>
<p align="center">
<a href="https://github.com/eqemu/server/graphs/contributors"><img src="https://img.shields.io/github/contributors/eqemu/server" alt="Contributors"></a>
<a href="https://discord.gg/QHsm7CD"><img src="https://img.shields.io/discord/212663220849213441?label=Discord&amp;logo=discord&amp;color=7289DA" alt="Discord"></a>
<a href="https://docs.eqemu.io"><img src="https://img.shields.io/badge/docs-MkDocs%20Powered-blueviolet" alt="Docs"></a>
<a href="./LICENSE"><img src="https://img.shields.io/github/license/EQEmu/Server" alt="License"></a>
<a href="https://github.com/eqemu/server/releases"><img src="https://img.shields.io/github/v/release/eqemu/server" alt="Latest Release"></a>
<a href="https://github.com/EQEmu/Server/releases"><img src="https://img.shields.io/github/release-date/EQEmu/Server" alt="Release Date"></a>
<img src="https://img.shields.io/github/downloads/eqemu/server/total.svg" alt="Github All Releases"></a>
<a href="http://drone.akkadius.com/EQEmu/Server"><img src="http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg" alt="Build Status"></a>
<img src="https://img.shields.io/github/issues-pr-closed/eqemu/server" alt="GitHub Issues or Pull Requests">
<img src="https://img.shields.io/docker/pulls/akkadius/eqemu-server" alt="Docker Pulls">
<a href="http://drone.akkadius.com/EQEmu/Server"><img src="http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg" alt="Build Status"></a> <img src="https://jb.gg/badges/official-plastic.svg" alt="Official">
</p>
*** ***
<p align="center"> **EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++**
EQEmulator is a <b>passion-driven</b>, <b>open source server emulator</b> project dedicated to preserving and celebrating the legacy of a groundbreaking classic MMORPG. * MySQL/MariaDB is used as the database engine (over 200+ tables)
</p> * Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events
* Open source database (Project EQ) has content up to expansion OoW (included in server installs)
* Game server environments and databases can be heavily customized to create all new experiences
* Hundreds of Quests/events created and maintained by Project EQ
<p align="center"> ## Server Installs
For over two decades and continuing, EQEmulator has served as a <strong>fan tribute</strong>, providing tools and technology that allow players to explore, customize, and experience the legendary game's iconic gameplay in new ways. This project exists solely out of <strong>deep admiration</strong> for the original developers, artists, designers, and visionaries who created one of the most influential online worlds of all time. | |Windows|Linux|
</p> |:---:|:---:|:---:|
|**Install Count**|![Windows Install Count](http://analytics.akkadius.com/?install_count&windows_count)|![Linux Install Count](http://analytics.akkadius.com/?install_count&linux_count)|
### > Windows
<p align="center"> * [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
We do not claim ownership of the original game or its assets. <strong>All credit and respect belong to the original creators and Daybreak Game Company</strong>, whose work continues to inspire generations of players and developers alike.
</p>
<p align="center"> ### > Debian/Ubuntu/CentOS/Fedora
EQEmulator has for over 20 years and always will be a <strong>fan-based, non-commercial open-source effort</strong> made by players, for players—preserving the legacy of the game while empowering community-driven creativity, learning and joy that the game and its creators has so strongly inspired in us all.
</p>
*** * [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
<h3 align="center"> * You can use curl or wget to kick off the installer (whichever your OS has)
Technical Overview & Reverse Engineering Effort > curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
</h1>
<p align="center">EQEmulator represents <strong>over two decades of collaborative reverse engineering</strong>, building the server from the ground up without access to the original source code. This effort was achieved entirely through <strong>community-driven analysis, network protocol decoding, and in-game behavioral research</strong>.</p> > wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
<h1 align="center"> ## Supported Clients
💡 How We Did It
</h1>
<p align="center">
<img src="https://github.com/user-attachments/assets/b6b48cf7-f64a-4497-9750-71f442a3d132" height="300px">
</p>
<p align="center">
<strong>Reverse Engineering</strong>
Every system, packet, opcode, and game mechanic has been reconstructed through countless hours of live packet sniffing, client disassembly, and in-game experimentation by dedicated contributors over the years.
</p>
<p align="center">
No proprietary code or server sources were ever used.
</p>
<p align="center">
All implementations are the result of clean-room engineering.
</p>
<h1 align="center">
🛠️ Technology Stack
</h1>
<p align="center">
<img src="https://github.com/user-attachments/assets/df5ea809-86c5-439d-a8fa-651fb04ba477" style="border-radius: 10px">
</p>
**C++ Core Engine**
* High-performance networking and gameplay logic built in C++
* Cross-platform support for Linux and Windows
**MySQL / MariaDB Backend**
* Fully structured schema with over 200+ tables
* Supports content customization, expansions, and custom worlds
**Scripting Engine**
* Native support for **Perl** and **Lua** scripting
* Powerfully extendable for quests, NPC behaviors, and custom events
**Open Source Content Database**
* Includes ProjectEQs world data up through *Dragons of Norrath*
* 100% customizable to create entirely new game worlds
<h1 align="center">
🚀 Why It Matters
</h1>
<p align="center">🧬 EQEmulator stands as a <strong>technical preservation project</strong>, ensuring that the magic of classic and custom servers lives on for future generations of players, tinkerers, and game designers.
</p>
> We humbly acknowledge and thank the original developers for creating one of the most influential online experiences in gaming history.
<h1 align="center">
🧑‍💻🖥️ Supported Clients
</h1>
|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear| |Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear|
|:---:|:---:|:---:|:---:|:---:| |:---:|:---:|:---:|:---:|:---:|
|<img src="http://i.imgur.com/hrwDxoM.jpg" height="150">|<img src="http://i.imgur.com/cRDW5tn.png" height="150">|<img src="http://i.imgur.com/V48kuVn.jpg" height="150">|<img src="http://i.imgur.com/IJQ0XMa.jpg" height="150">|<img src="http://i.imgur.com/OMpHkKa.png" height="100">| |<img src="http://i.imgur.com/hrwDxoM.jpg" height="150">|<img src="http://i.imgur.com/cRDW5tn.png" height="150">|<img src="http://i.imgur.com/V48kuVn.jpg" height="150">|<img src="http://i.imgur.com/IJQ0XMa.jpg" height="150">|<img src="http://i.imgur.com/OMpHkKa.png" height="100">|
## 📚 Resources ## Bug Reports <img src="http://i.imgur.com/daf1Vjw.png" height="20">
* Please use the [issue tracker](https://github.com/EQEmu/Server/issues) provided by GitHub to send us bug
reports or feature requests.
* The [EQEmu Forums](http://www.eqemulator.org/forums/) are also a place to submit and get help with bugs.
| Resource | Badges | Link | ## Contributions <img src="http://image.flaticon.com/icons/png/512/25/25231.png" width="20">
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| **EQEmulator Docs** | [![Docs](https://img.shields.io/badge/docs-MkDocs%20Powered-blueviolet)](https://docs.eqemu.io) | [docs.eqemu.io](https://docs.eqemu.io/) |
| **Discord Community**| [![Discord](https://img.shields.io/discord/212663220849213441?label=Discord&logo=discord&color=7289DA)](https://discord.gg/QHsm7CD) | [Join Discord](https://discord.gg/QHsm7CD) |
| **Latest Release** | [![Latest Release](https://img.shields.io/github/v/release/eqemu/server)](https://github.com/eqemu/server/releases) <br> [![Release Date](https://img.shields.io/github/release-date/EQEmu/Server)](https://github.com/EQEmu/Server/releases) <br> [![All Releases](https://img.shields.io/github/downloads/eqemu/server/total.svg)](https://github.com/eqemu/server/releases) | [View Releases](https://github.com/eqemu/server/releases) |
| **License** | [![License](https://img.shields.io/github/license/EQEmu/Server)](./LICENSE) | [View License](./LICENSE) |
| **Build Status** | [![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) | [View Build Status](http://drone.akkadius.com/EQEmu/Server) |
| **Docker Pulls** | [![Docker Pulls](https://img.shields.io/docker/pulls/akkadius/eqemu-server)](https://hub.docker.com/r/akkadius/eqemu-server) | [Docker Hub](https://hub.docker.com/r/akkadius/eqemu-server) |
| **Contributions** | [![GitHub PRs](https://img.shields.io/github/issues-pr-closed/eqemu/server)](https://github.com/eqemu/server/pulls?q=is%3Apr+is%3Aclosed) | [Closed PRs & Issues](https://github.com/eqemu/server/pulls?q=is%3Apr+is%3Aclosed) |
## 🛠️ Getting Started * The preferred way to contribute is to fork the repo and submit a pull request on
GitHub. If you need help with your changes, you can always post on the forums or
try Discord. You can also post unified diffs (`git diff` should do the trick) on the
[Server Code Submissions](http://www.eqemulator.org/forums/forumdisplay.php?f=669)
forum, although pull requests will be much quicker and easier on all parties.
If you want to set up your own EQEmulator server, please refer to the current [server installation guides](https://docs.eqemu.io/#server-installation). We've had 100,000s of players and developers use our guides to set up their own servers, and we hope you will too! ## Contact <img src="http://gamerescape.com/wp-content/uploads/2015/06/discord.png" height="20">
## 🗂️ Related Repositories - Discord Channel: https://discord.gg/QHsm7CD
- **User Discord Channel**: `#general`
- **Developer Discord Channel**: `#eqemucoders`
| Repository | Description | ## Resources
|--------------------|----------------------------------------------------------------------------------| - [EQEmulator Forums](http://www.eqemulator.org/forums)
| [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests) | Official quests and event scripts for ProjectEQ | - [EQEmulator Wiki](https://docs.eqemu.io/)
| [Maps](https://github.com/Akkadius/EQEmuMaps) | EQEmu-compatible zone maps |
| [Installer Resources](https://github.com/Akkadius/EQEmuInstall) | Scripts and assets for setting up EQEmu servers |
| [Zone Utilities](https://github.com/EQEmu/zone-utilities) | Utilities for parsing, rendering, and manipulating EQ zone files |
## Related Repositories
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
* [Maps](https://github.com/Akkadius/EQEmuMaps)
* [Installer Resources](https://github.com/Akkadius/EQEmuInstall)
* [Zone Utilities](https://github.com/EQEmu/zone-utilities) - Various utilities and libraries for parsing, rendering and manipulating EQ Zone files.
## Other License Info
* The server code and utilities are released under **GPLv3**
* We also include some small libraries for convienence that may be under different licensing
* SocketLib - GPL LibXML
* zlib - zlib license
* MariaDB/MySQL - GPL
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
* CPPUnit - GLP StringUtilities - Apache
* LUA - MIT
## Contributors ## Contributors
<a href="https://github.com/EQEmu/server/graphs/contributors"> <a href="https://github.com/EQEmu/server/graphs/contributors">
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" /> <img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
</a> </a>

View File

@ -38,6 +38,13 @@
#include "../../common/skill_caps.h" #include "../../common/skill_caps.h"
#include "../../common/evolving_items.h" #include "../../common/evolving_items.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
PlayerEventLogs player_event_logs;
EvolvingItemsManager evolving_items_manager;
void ExportSpells(SharedDatabase *db); void ExportSpells(SharedDatabase *db);
void ExportSkillCaps(SharedDatabase *db); void ExportSkillCaps(SharedDatabase *db);
void ExportBaseData(SharedDatabase *db); void ExportBaseData(SharedDatabase *db);
@ -46,10 +53,10 @@ void ExportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
RegisterExecutablePlatform(ExePlatformClientExport); RegisterExecutablePlatform(ExePlatformClientExport);
EQEmuLogSys::Instance()->LoadLogSettingsDefaults(); LogSys.LoadLogSettingsDefaults();
set_exception_handler(); set_exception_handler();
PathManager::Instance()->Init(); path.LoadPaths();
LogInfo("Client Files Export Utility"); LogInfo("Client Files Export Utility");
if (!EQEmuConfig::LoadConfig()) { if (!EQEmuConfig::LoadConfig()) {
@ -92,8 +99,8 @@ int main(int argc, char **argv)
content_db.SetMySQL(database); content_db.SetMySQL(database);
} }
EQEmuLogSys::Instance()->SetDatabase(&database) LogSys.SetDatabase(&database)
->SetLogPath(PathManager::Instance()->GetLogPath()) ->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings() ->LoadLogDatabaseSettings()
->StartFileLogs(); ->StartFileLogs();
@ -122,14 +129,14 @@ int main(int argc, char **argv)
ExportBaseData(&content_db); ExportBaseData(&content_db);
ExportDBStrings(&database); ExportDBStrings(&database);
EQEmuLogSys::Instance()->CloseFileLogs(); LogSys.CloseFileLogs();
return 0; return 0;
} }
void ExportSpells(SharedDatabase* db) void ExportSpells(SharedDatabase* db)
{ {
std::ofstream file(fmt::format("{}/export/spells_us.txt", PathManager::Instance()->GetServerPath())); std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
if (!file || !file.is_open()) { if (!file || !file.is_open()) {
LogError("Unable to open export/spells_us.txt to write, skipping."); LogError("Unable to open export/spells_us.txt to write, skipping.");
return; return;
@ -148,7 +155,7 @@ void ExportSpells(SharedDatabase* db)
void ExportSkillCaps(SharedDatabase* db) void ExportSkillCaps(SharedDatabase* db)
{ {
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", PathManager::Instance()->GetServerPath())); std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
if (!file || !file.is_open()) { if (!file || !file.is_open()) {
LogError("Unable to open export/SkillCaps.txt to write, skipping."); LogError("Unable to open export/SkillCaps.txt to write, skipping.");
return; return;
@ -167,7 +174,7 @@ void ExportSkillCaps(SharedDatabase* db)
void ExportBaseData(SharedDatabase *db) void ExportBaseData(SharedDatabase *db)
{ {
std::ofstream file(fmt::format("{}/export/BaseData.txt", PathManager::Instance()->GetServerPath())); std::ofstream file(fmt::format("{}/export/BaseData.txt", path.GetServerPath()));
if (!file || !file.is_open()) { if (!file || !file.is_open()) {
LogError("Unable to open export/BaseData.txt to write, skipping."); LogError("Unable to open export/BaseData.txt to write, skipping.");
return; return;
@ -186,7 +193,7 @@ void ExportBaseData(SharedDatabase *db)
void ExportDBStrings(SharedDatabase *db) void ExportDBStrings(SharedDatabase *db)
{ {
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", PathManager::Instance()->GetServerPath())); std::ofstream file(fmt::format("{}/export/dbstr_us.txt", path.GetServerPath()));
if (!file || !file.is_open()) { if (!file || !file.is_open()) {
LogError("Unable to open export/dbstr_us.txt to write, skipping."); LogError("Unable to open export/dbstr_us.txt to write, skipping.");
return; return;

View File

@ -32,6 +32,13 @@
#include "../../common/events/player_event_logs.h" #include "../../common/events/player_event_logs.h"
#include "../../common/evolving_items.h" #include "../../common/evolving_items.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
PlayerEventLogs player_event_logs;
EvolvingItemsManager evolving_items_manager;
void ImportSpells(SharedDatabase *db); void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db); void ImportSkillCaps(SharedDatabase *db);
void ImportBaseData(SharedDatabase *db); void ImportBaseData(SharedDatabase *db);
@ -39,10 +46,10 @@ void ImportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) { int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientImport); RegisterExecutablePlatform(ExePlatformClientImport);
EQEmuLogSys::Instance()->LoadLogSettingsDefaults(); LogSys.LoadLogSettingsDefaults();
set_exception_handler(); set_exception_handler();
PathManager::Instance()->Init(); path.LoadPaths();
LogInfo("Client Files Import Utility"); LogInfo("Client Files Import Utility");
if(!EQEmuConfig::LoadConfig()) { if(!EQEmuConfig::LoadConfig()) {
@ -85,8 +92,8 @@ int main(int argc, char **argv) {
content_db.SetMySQL(database); content_db.SetMySQL(database);
} }
EQEmuLogSys::Instance()->SetDatabase(&database) LogSys.SetDatabase(&database)
->SetLogPath(PathManager::Instance()->GetLogPath()) ->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings() ->LoadLogDatabaseSettings()
->StartFileLogs(); ->StartFileLogs();
@ -95,7 +102,7 @@ int main(int argc, char **argv) {
ImportBaseData(&content_db); ImportBaseData(&content_db);
ImportDBStrings(&database); ImportDBStrings(&database);
EQEmuLogSys::Instance()->CloseFileLogs(); LogSys.CloseFileLogs();
return 0; return 0;
} }
@ -131,7 +138,7 @@ bool IsStringField(int i) {
void ImportSpells(SharedDatabase *db) { void ImportSpells(SharedDatabase *db) {
LogInfo("Importing Spells"); LogInfo("Importing Spells");
std::string file = fmt::format("{}/import/spells_us.txt", PathManager::Instance()->GetServerPath()); std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r"); FILE *f = fopen(file.c_str(), "r");
if(!f) { if(!f) {
LogError("Unable to open {} to read, skipping.", file); LogError("Unable to open {} to read, skipping.", file);
@ -221,7 +228,7 @@ void ImportSpells(SharedDatabase *db) {
void ImportSkillCaps(SharedDatabase *db) { void ImportSkillCaps(SharedDatabase *db) {
LogInfo("Importing Skill Caps"); LogInfo("Importing Skill Caps");
std::string file = fmt::format("{}/import/SkillCaps.txt", PathManager::Instance()->GetServerPath()); std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r"); FILE *f = fopen(file.c_str(), "r");
if(!f) { if(!f) {
LogError("Unable to open {} to read, skipping.", file); LogError("Unable to open {} to read, skipping.", file);
@ -258,7 +265,7 @@ void ImportBaseData(SharedDatabase *db)
{ {
LogInfo("Importing Base Data"); LogInfo("Importing Base Data");
const std::string& file_name = fmt::format("{}/import/BaseData.txt", PathManager::Instance()->GetServerPath()); const std::string& file_name = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
const auto& file_contents = File::GetContents(file_name); const auto& file_contents = File::GetContents(file_name);
if (!file_contents.error.empty()) { if (!file_contents.error.empty()) {
@ -298,7 +305,7 @@ void ImportBaseData(SharedDatabase *db)
void ImportDBStrings(SharedDatabase *db) { void ImportDBStrings(SharedDatabase *db) {
LogInfo("Importing DB Strings"); LogInfo("Importing DB Strings");
std::string file = fmt::format("{}/import/dbstr_us.txt", PathManager::Instance()->GetServerPath()); std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
FILE *f = fopen(file.c_str(), "r"); FILE *f = fopen(file.c_str(), "r");
if(!f) { if(!f) {
LogError("Unable to open {} to read, skipping.", file); LogError("Unable to open {} to read, skipping.", file);

View File

@ -35,55 +35,60 @@ ENDIF()
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG) IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
MESSAGE(STATUS "Resolving vcpkg dependencies...") MESSAGE(STATUS "Resolving vcpkg dependencies...")
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}) IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg) EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...") MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP} FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
SHOW_PROGRESS SHOW_PROGRESS
STATUS DOWNLOAD_STATUS) STATUS DOWNLOAD_STATUS)
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE) LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
IF(NOT STATUS_CODE EQUAL 0) IF(NOT STATUS_CODE EQUAL 0)
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}") MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
ENDIF() ENDIF()
MESSAGE(STATUS "Extracting files...") MESSAGE(STATUS "Extracting files...")
EXECUTE_PROCESS( EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP} COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
) )
ENDIF() ENDIF()
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake) INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
ENDIF() ENDIF()
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL) IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
MESSAGE(STATUS "Resolving perl dependencies...") #Try to find perl first, (so you can use your active install first)
FIND_PACKAGE(PerlLibs)
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl) IF(NOT PerlLibs_FOUND)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}) MESSAGE(STATUS "Resolving perl dependencies...")
MESSAGE(STATUS "Downloading portable perl...") IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP} EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
SHOW_PROGRESS EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
STATUS DOWNLOAD_STATUS)
MESSAGE(STATUS "Downloading portable perl...")
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE) FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
IF(NOT STATUS_CODE EQUAL 0) SHOW_PROGRESS
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}") STATUS DOWNLOAD_STATUS)
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
IF(NOT STATUS_CODE EQUAL 0)
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
ENDIF()
MESSAGE(STATUS "Extracting files...")
EXECUTE_PROCESS(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
)
ENDIF() ENDIF()
MESSAGE(STATUS "Extracting files...") SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
EXECUTE_PROCESS( SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP} SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
)
ENDIF() ENDIF()
ENDIF()
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
ENDIF()

View File

@ -17,7 +17,6 @@ SET(common_sources
database.cpp database.cpp
database_instances.cpp database_instances.cpp
database/database_update_manifest.cpp database/database_update_manifest.cpp
database/database_update_manifest_custom.cpp
database/database_update_manifest_bots.cpp database/database_update_manifest_bots.cpp
database/database_update.cpp database/database_update.cpp
dbcore.cpp dbcore.cpp
@ -104,9 +103,9 @@ SET(common_sources
net/console_server.cpp net/console_server.cpp
net/console_server_connection.cpp net/console_server_connection.cpp
net/crc32.cpp net/crc32.cpp
net/daybreak_connection.cpp
net/eqstream.cpp net/eqstream.cpp
net/packet.cpp net/packet.cpp
net/reliable_stream_connection.cpp
net/servertalk_client_connection.cpp net/servertalk_client_connection.cpp
net/servertalk_legacy_client_connection.cpp net/servertalk_legacy_client_connection.cpp
net/servertalk_server.cpp net/servertalk_server.cpp
@ -603,6 +602,7 @@ SET(common_headers
ipc_mutex.h ipc_mutex.h
ip_util.h ip_util.h
item_data.h item_data.h
item_fieldlist.h
item_instance.h item_instance.h
json_config.h json_config.h
light_source.h light_source.h
@ -670,13 +670,13 @@ SET(common_headers
net/console_server.h net/console_server.h
net/console_server_connection.h net/console_server_connection.h
net/crc32.h net/crc32.h
net/daybreak_connection.h
net/daybreak_pooling.h
net/daybreak_structs.h
net/dns.h net/dns.h
net/endian.h net/endian.h
net/eqstream.h net/eqstream.h
net/packet.h net/packet.h
net/reliable_stream_connection.h
net/reliable_stream_pooling.h
net/reliable_stream_structs.h
net/servertalk_client_connection.h net/servertalk_client_connection.h
net/servertalk_legacy_client_connection.h net/servertalk_legacy_client_connection.h
net/servertalk_common.h net/servertalk_common.h
@ -742,6 +742,10 @@ SOURCE_GROUP(Net FILES
net/console_server_connection.h net/console_server_connection.h
net/crc32.cpp net/crc32.cpp
net/crc32.h net/crc32.h
net/daybreak_connection.cpp
net/daybreak_connection.h
net/daybreak_pooling.h
net/daybreak_structs.h
net/dns.h net/dns.h
net/endian.h net/endian.h
net/eqmq.cpp net/eqmq.cpp
@ -750,10 +754,6 @@ SOURCE_GROUP(Net FILES
net/eqstream.h net/eqstream.h
net/packet.cpp net/packet.cpp
net/packet.h net/packet.h
net/reliable_stream_connection.cpp
net/reliable_stream_connection.h
net/reliable_stream_pooling.h
net/reliable_stream_structs.h
net/servertalk_client_connection.cpp net/servertalk_client_connection.cpp
net/servertalk_client_connection.h net/servertalk_client_connection.h
net/servertalk_legacy_client_connection.cpp net/servertalk_legacy_client_connection.cpp
@ -840,13 +840,8 @@ 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) SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
ENDIF (UNIX) ENDIF (UNIX)
IF (EQEMU_BUILD_PCH) IF (WIN32 AND EQEMU_BUILD_PCH)
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/std-pch.h) TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
# Avoid PCH/__OPTIMIZE__ mismatch when compiling certain patch sources with -O0
# These files are compiled with -O0 on UNIX (see COMPILE_FLAGS above), which
# disables the __OPTIMIZE__ predefined macro. Disabling PCH for them prevents
# Clang from erroring due to macro state differences between the PCH and TU.
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
ENDIF () ENDIF ()
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -27,7 +27,7 @@ WorldContentService *WorldContentService::SetExpansionContext()
// pull expansion from rules // pull expansion from rules
int expansion = RuleI(Expansion, CurrentExpansion); int expansion = RuleI(Expansion, CurrentExpansion);
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) { if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
WorldContentService::Instance()->SetCurrentExpansion(expansion); content_service.SetCurrentExpansion(expansion);
} }
LogInfo( LogInfo(
@ -41,12 +41,12 @@ WorldContentService *WorldContentService::SetExpansionContext()
std::string WorldContentService::GetCurrentExpansionName() std::string WorldContentService::GetCurrentExpansionName()
{ {
if (WorldContentService::Instance()->GetCurrentExpansion() == Expansion::EXPANSION_ALL) { if (content_service.GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
return "All Expansions"; return "All Expansions";
} }
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) { if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
return Expansion::ExpansionName[WorldContentService::Instance()->GetCurrentExpansion()]; return Expansion::ExpansionName[content_service.GetCurrentExpansion()];
} }
return "Unknown Expansion"; return "Unknown Expansion";
@ -185,7 +185,7 @@ void WorldContentService::ReloadContentFlags()
SetContentFlags(set_content_flags); SetContentFlags(set_content_flags);
LoadStaticGlobalZoneInstances(); LoadStaticGlobalZoneInstances();
ZoneStore::Instance()->LoadZones(*m_content_database); zone_store.LoadZones(*m_content_database);
} }
Database *WorldContentService::GetDatabase() const Database *WorldContentService::GetDatabase() const
@ -291,7 +291,7 @@ WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
// instance_list table entry for lavastorm has version = 1, is_global = 1, never_expires = 1 // 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) WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
{ {
for (const auto &z: ZoneStore::Instance()->GetZones()) { for (const auto &z: zone_store.GetZones()) {
for (auto &i: m_zone_static_instances) { for (auto &i: m_zone_static_instances) {
if ( if (
z.zoneidnumber == zone_id && z.zoneidnumber == zone_id &&

View File

@ -181,12 +181,6 @@ public:
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id); FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
bool IsInPublicStaticInstance(uint32 instance_id); bool IsInPublicStaticInstance(uint32 instance_id);
static WorldContentService* Instance()
{
static WorldContentService instance;
return &instance;
}
private: private:
int current_expansion{}; int current_expansion{};
std::vector<ContentFlagsRepository::ContentFlags> content_flags; std::vector<ContentFlagsRepository::ContentFlags> content_flags;
@ -200,4 +194,6 @@ private:
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances; std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
}; };
extern WorldContentService content_service;
#endif //EQEMU_WORLD_CONTENT_SERVICE_H #endif //EQEMU_WORLD_CONTENT_SERVICE_H

View File

@ -23,12 +23,10 @@ void SendCrashReport(const std::string &crash_report)
{ {
// can configure multiple endpoints if need be // can configure multiple endpoints if need be
std::vector<std::string> endpoints = { std::vector<std::string> endpoints = {
"https://spire.eqemu.dev/api/v1/analytics/server-crash-report", "https://spire.akkadius.com/api/v1/analytics/server-crash-report",
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development // "http://localhost:3010/api/v1/analytics/server-crash-report", // development
}; };
EQEmuLogSys* log = EQEmuLogSys::Instance();
auto config = EQEmuConfig::get(); auto config = EQEmuConfig::get();
for (auto &e: endpoints) { for (auto &e: endpoints) {
uri u(e); uri u(e);
@ -70,12 +68,12 @@ void SendCrashReport(const std::string &crash_report)
p["cpus"] = cpus.size(); p["cpus"] = cpus.size();
p["origination_info"] = ""; p["origination_info"] = "";
if (!log->origination_info.zone_short_name.empty()) { if (!LogSys.origination_info.zone_short_name.empty()) {
p["origination_info"] = fmt::format( p["origination_info"] = fmt::format(
"{} ({}) instance_id [{}]", "{} ({}) instance_id [{}]",
log->origination_info.zone_short_name, LogSys.origination_info.zone_short_name,
log->origination_info.zone_long_name, LogSys.origination_info.zone_long_name,
log->origination_info.instance_id LogSys.origination_info.instance_id
); );
} }
@ -296,7 +294,7 @@ void print_trace()
SendCrashReport(crash_report); SendCrashReport(crash_report);
} }
EQEmuLogSys::Instance()->CloseFileLogs(); LogSys.CloseFileLogs();
exit(1); exit(1);
} }

View File

@ -708,20 +708,6 @@ const std::string Database::GetNPCNameByID(uint32 npc_id)
return e.id ? e.name : std::string(); return e.id ? e.name : std::string();
} }
template<typename InputIterator, typename OutputIterator>
inline auto CleanMobName(InputIterator first, InputIterator last, OutputIterator result)
{
for (; first != last; ++first) {
if (*first == '_') {
*result = ' ';
}
else if (isalpha(*first) || *first == '`') {
*result = *first;
}
}
return result;
}
const std::string Database::GetCleanNPCNameByID(uint32 npc_id) const std::string Database::GetCleanNPCNameByID(uint32 npc_id)
{ {
const auto& e = NpcTypesRepository::FindOne(*this, npc_id); const auto& e = NpcTypesRepository::FindOne(*this, npc_id);
@ -1934,7 +1920,6 @@ bool Database::CopyCharacter(
std::vector<std::string> tables_to_zero_id = { std::vector<std::string> tables_to_zero_id = {
"keyring", "keyring",
"data_buckets", "data_buckets",
"character_evolving_items",
"character_instance_safereturns", "character_instance_safereturns",
"character_expedition_lockouts", "character_expedition_lockouts",
"character_instance_lockouts", "character_instance_lockouts",
@ -1966,12 +1951,6 @@ bool Database::CopyCharacter(
) )
); );
if (!results.Success()) {
LogError("Transaction failed [{}] rolling back", results.ErrorMessage());
TransactionRollback();
return false;
}
std::vector<std::string> columns = {}; std::vector<std::string> columns = {};
int column_count = 0; int column_count = 0;
@ -1990,12 +1969,6 @@ bool Database::CopyCharacter(
) )
); );
if (!results.Success()) {
LogError("Transaction failed [{}] rolling back", results.ErrorMessage());
TransactionRollback();
return false;
}
std::vector<std::vector<std::string>> new_rows; std::vector<std::vector<std::string>> new_rows;
for (auto row : results) { for (auto row : results) {
@ -2063,18 +2036,13 @@ bool Database::CopyCharacter(
LogInfo("Copying table [{}] rows [{}]", table_name, Strings::Commify(rows_copied)); LogInfo("Copying table [{}] rows [{}]", table_name, Strings::Commify(rows_copied));
if (!insert.ErrorMessage().empty()) { if (!insert.ErrorMessage().empty()) {
LogError("Error copying table [{}] [{}]", table_name, insert.ErrorMessage());
TransactionRollback(); TransactionRollback();
return false; return false;
} }
} }
} }
auto r = TransactionCommit(); TransactionCommit();
if (!r.Success()) {
LogError("Transaction failed [{}] rolling back", r.ErrorMessage());
return false;
}
LogInfo( LogInfo(
"Character [{}] copied to [{}] total rows [{}]", "Character [{}] copied to [{}] total rows [{}]",
@ -2244,7 +2212,7 @@ void Database::PurgeCharacterParcels()
pel.event_data = ss.str(); pel.event_data = ss.str();
pel.created_at = std::time(nullptr); pel.created_at = std::time(nullptr);
PlayerEventLogs::Instance()->AddToQueue(pel); player_event_logs.AddToQueue(pel);
ss.str(""); ss.str("");
ss.clear(); ss.clear();

View File

@ -50,7 +50,7 @@ bool DatabaseDumpService::IsMySQLInstalled()
{ {
std::string version_output = GetMySQLVersion(); std::string version_output = GetMySQLVersion();
return version_output.find("mysql") != std::string::npos && (version_output.find("Ver") != std::string::npos || version_output.find("from") != std::string::npos); return version_output.find("mysql") != std::string::npos && version_output.find("Ver") != std::string::npos;
} }
/** /**
@ -204,7 +204,7 @@ void DatabaseDumpService::DatabaseDump()
} }
if (IsDumpOutputToConsole()) { if (IsDumpOutputToConsole()) {
EQEmuLogSys::Instance()->SilenceConsoleLogging(); LogSys.SilenceConsoleLogging();
} }
LogInfo("MySQL installed [{}]", GetMySQLVersion()); LogInfo("MySQL installed [{}]", GetMySQLVersion());
@ -324,7 +324,7 @@ void DatabaseDumpService::DatabaseDump()
} }
if (!IsDumpOutputToConsole()) { if (!IsDumpOutputToConsole()) {
EQEmuLogSys::Instance()->LoadLogSettingsDefaults(); LogSys.LoadLogSettingsDefaults();
} }
if (!pipe_file.empty()) { if (!pipe_file.empty()) {

View File

@ -7,7 +7,6 @@
#include "../http/httplib.h" #include "../http/httplib.h"
#include "database_update_manifest.cpp" #include "database_update_manifest.cpp"
#include "database_update_manifest_custom.cpp"
#include "database_update_manifest_bots.cpp" #include "database_update_manifest_bots.cpp"
#include "database_dump_service.h" #include "database_dump_service.h"
@ -15,7 +14,7 @@ constexpr int BREAK_LENGTH = 70;
DatabaseVersion DatabaseUpdate::GetDatabaseVersions() DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
{ {
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version`, `custom_version` FROM `db_version` LIMIT 1"); auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
if (!results.Success() || !results.RowCount()) { if (!results.Success() || !results.RowCount()) {
LogError("Failed to read from [db_version] table!"); LogError("Failed to read from [db_version] table!");
return DatabaseVersion{}; return DatabaseVersion{};
@ -26,7 +25,6 @@ DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
return DatabaseVersion{ return DatabaseVersion{
.server_database_version = Strings::ToInt(r[0]), .server_database_version = Strings::ToInt(r[0]),
.bots_database_version = Strings::ToInt(r[1]), .bots_database_version = Strings::ToInt(r[1]),
.custom_database_version = Strings::ToInt(r[2]),
}; };
} }
@ -35,7 +33,6 @@ DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
return DatabaseVersion{ return DatabaseVersion{
.server_database_version = CURRENT_BINARY_DATABASE_VERSION, .server_database_version = CURRENT_BINARY_DATABASE_VERSION,
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0), .bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
.custom_database_version = CUSTOM_BINARY_DATABASE_VERSION,
}; };
} }
@ -46,7 +43,6 @@ constexpr int LOOK_BACK_AMOUNT = 10;
// this check will take action // this check will take action
void DatabaseUpdate::CheckDbUpdates() void DatabaseUpdate::CheckDbUpdates()
{ {
InjectCustomVersionColumn();
InjectBotsVersionColumn(); InjectBotsVersionColumn();
auto v = GetDatabaseVersions(); auto v = GetDatabaseVersions();
auto b = GetBinaryDatabaseVersions(); auto b = GetBinaryDatabaseVersions();
@ -63,15 +59,6 @@ void DatabaseUpdate::CheckDbUpdates()
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version)); m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
} }
if (UpdateManifest(manifest_entries_custom, v.custom_database_version, b.custom_database_version)) {
LogInfo(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.custom_database_version,
v.custom_database_version
);
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `custom_version` = {}", b.custom_database_version));
}
if (b.bots_database_version > 0) { if (b.bots_database_version > 0) {
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) { if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
LogInfo( LogInfo(
@ -154,7 +141,7 @@ bool DatabaseUpdate::UpdateManifest(
std::vector<int> missing_migrations = {}; std::vector<int> missing_migrations = {};
if (version_low != version_high) { if (version_low != version_high) {
EQEmuLogSys::Instance()->DisableMySQLErrorLogs(); LogSys.DisableMySQLErrorLogs();
bool force_interactive = false; bool force_interactive = false;
for (int version = version_low + 1; version <= version_high; ++version) { for (int version = version_low + 1; version <= version_high; ++version) {
for (auto &e: entries) { for (auto &e: entries) {
@ -184,7 +171,7 @@ bool DatabaseUpdate::UpdateManifest(
} }
} }
} }
EQEmuLogSys::Instance()->EnableMySQLErrorLogs(); LogSys.EnableMySQLErrorLogs();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH)); LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
if (!missing_migrations.empty() && m_skip_backup) { if (!missing_migrations.empty() && m_skip_backup) {
@ -357,16 +344,6 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
); );
} }
if (b.custom_database_version > 0) {
LogInfo(
"{:>8} | database [{}] binary [{}] {}",
"Custom",
v.custom_database_version,
b.custom_database_version,
(v.custom_database_version == b.custom_database_version) ? "up to date" : "checking updates"
);
}
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config"); LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH)); LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
@ -376,10 +353,7 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
// bots database version is optional, if not enabled then it is always up-to-date // 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; bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version >= b.bots_database_version : true;
// custom database version is optional, if not enabled then it is always up-to-date return server_up_to_date && bots_up_to_date;
bool custom_up_to_date = v.custom_database_version >= b.custom_database_version;
return server_up_to_date && bots_up_to_date && custom_up_to_date;
} }
// checks to see if there are pending updates // checks to see if there are pending updates
@ -399,12 +373,3 @@ void DatabaseUpdate::InjectBotsVersionColumn()
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version"); m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
} }
} }
void DatabaseUpdate::InjectCustomVersionColumn()
{
auto results = m_database->QueryDatabase("SHOW COLUMNS FROM `db_version` LIKE 'custom_version'");
if (!results.Success() || results.RowCount() == 0) {
LogInfo("Adding custom_version column to db_version table");
m_database->QueryDatabase("ALTER TABLE `db_version` ADD COLUMN `custom_version` INT(11) UNSIGNED NOT NULL DEFAULT 0");
}
}

View File

@ -17,7 +17,6 @@ struct ManifestEntry {
struct DatabaseVersion { struct DatabaseVersion {
int server_database_version; int server_database_version;
int bots_database_version; int bots_database_version;
int custom_database_version;
}; };
class DatabaseUpdate { class DatabaseUpdate {
@ -33,20 +32,12 @@ public:
DatabaseUpdate *SetContentDatabase(Database *db); DatabaseUpdate *SetContentDatabase(Database *db);
DatabaseUpdate *SetSkipBackup(bool skip); DatabaseUpdate *SetSkipBackup(bool skip);
bool HasPendingUpdates(); bool HasPendingUpdates();
static DatabaseUpdate* Instance()
{
static DatabaseUpdate instance;
return &instance;
}
private: private:
bool m_skip_backup = false; bool m_skip_backup = false;
Database *m_database; Database *m_database;
Database *m_content_database; Database *m_content_database;
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b); static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
void InjectBotsVersionColumn(); void InjectBotsVersionColumn();
void InjectCustomVersionColumn();
}; };

View File

@ -7109,80 +7109,6 @@ ALTER TABLE `npc_types`
ALTER TABLE `character_data` ALTER TABLE `character_data`
CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`, CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`,
ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`; ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`;
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9324,
.description = "2025_06_11_player_event_logs_table.sql",
.check = "SHOW CREATE TABLE `player_event_logs`",
.condition = "missing",
.match = "COMPRESS",
.sql = R"(
ALTER TABLE player_event_logs ROW_FORMAT=COMPRESSED;
CREATE INDEX idx_event_type_char_id ON player_event_logs (event_type_id, character_id);
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9325,
.description = "2025_06_10_character_corpses_entity_variables.sql",
.check = "SHOW COLUMNS FROM `character_corpses` LIKE 'entity_variables'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_corpses`
ADD COLUMN `entity_variables` TEXT DEFAULT NULL AFTER `rezzable`;
)",
.content_schema_update = false
},
ManifestEntry{
.version = 9326,
.description = "2025_07_27_add_indexes_npc_spawns_loot.sql",
.check = "SHOW INDEX FROM npc_types",
.condition = "missing",
.match = "idx_npc_types_loottable_id",
.sql = R"(
ALTER TABLE npc_types
ADD INDEX idx_npc_types_loottable_id (loottable_id);
ALTER TABLE spawnentry
ADD INDEX idx_spawnentry_spawngroup_id (spawngroupID),
ADD INDEX idx_spawnentry_npc_id (npcID);
ALTER TABLE lootdrop_entries
ADD INDEX idx_lootdrop_entries_lootdrop_id (lootdrop_id),
ADD INDEX idx_lootdrop_entries_item_id (item_id);
ALTER TABLE loottable_entries
ADD INDEX idx_loottable_entries_lootdrop_id (lootdrop_id),
ADD INDEX idx_loottable_entries_loottable_id (loottable_id);
)",
.content_schema_update = true
},
ManifestEntry{
.version = 9327,
.description = "2025_08_13_character_stats_record_heal_amount.sql",
.check = "SHOW COLUMNS FROM `character_stats_record` LIKE 'heal_amount'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_stats_record`
ADD COLUMN `heal_amount` int(11) NULL DEFAULT 0 AFTER `spell_damage`;
)"
},
ManifestEntry{
.version = 9328,
.description = "2025_08_22_character_parcel_updates.sql",
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'evolve_amount'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `character_parcels`
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
ALTER TABLE `character_parcels_containers`
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
)", )",
.content_schema_update = false .content_schema_update = false
}, },

View File

@ -1,55 +0,0 @@
#include "database_update.h"
std::vector<ManifestEntry> manifest_entries_custom = {
ManifestEntry{
.version = 1,
.description = "2025_05_16_new_database_check_test",
.check = "SHOW TABLES LIKE 'new_table'",
.condition = "empty",
.match = "",
.sql = R"(
CREATE TABLE `new_table` (
`id` int NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
)",
.content_schema_update = false,
},
// Used for testing
// ManifestEntry{
// .version = 9229,
// .description = "new_database_check_test",
// .check = "SHOW TABLES LIKE 'new_table'",
// .condition = "empty",
// .match = "",
// .sql = R"(
//CREATE TABLE `new_table` (
// `id` int NOT NULL AUTO_INCREMENT,
// PRIMARY KEY (`id`)
//);
//CREATE TABLE `new_table1` (
// `id` int NOT NULL AUTO_INCREMENT,
// PRIMARY KEY (`id`)
//);
//CREATE TABLE `new_table2` (
// `id` int NOT NULL AUTO_INCREMENT,
// PRIMARY KEY (`id`)
//);
//CREATE TABLE `new_table3` (
// `id` int NOT NULL AUTO_INCREMENT,
// PRIMARY KEY (`id`)
//);
//)",
// }
};
// see struct definitions for what each field does
// struct ManifestEntry {
// int version{}; // database version of the migration
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
// std::string check{}; // query that checks against the condition
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
// };

View File

@ -160,7 +160,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
(uint32) mysql_insert_id(mysql) (uint32) mysql_insert_id(mysql)
); );
if (EQEmuLogSys::Instance()->log_settings[Logs::MySQLQuery].is_category_enabled == 1) { if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
if ((strncasecmp(query, "select", 6) == 0)) { if ((strncasecmp(query, "select", 6) == 0)) {
LogMySQLQuery( LogMySQLQuery(
"{0} -- ({1} row{2} returned) ({3}s)", "{0} -- ({1} row{2} returned) ({3}s)",
@ -189,9 +189,9 @@ void DBcore::TransactionBegin()
QueryDatabase("START TRANSACTION"); QueryDatabase("START TRANSACTION");
} }
MySQLRequestResult DBcore::TransactionCommit() void DBcore::TransactionCommit()
{ {
return QueryDatabase("COMMIT"); QueryDatabase("COMMIT");
} }
void DBcore::TransactionRollback() void DBcore::TransactionRollback()

View File

@ -32,7 +32,7 @@ public:
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true); MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
MySQLRequestResult QueryDatabaseMulti(const std::string &query); MySQLRequestResult QueryDatabaseMulti(const std::string &query);
void TransactionBegin(); void TransactionBegin();
MySQLRequestResult TransactionCommit(); void TransactionCommit();
void TransactionRollback(); void TransactionRollback();
std::string Escape(const std::string& s); std::string Escape(const std::string& s);
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen); uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);

View File

@ -4,6 +4,7 @@
#include <string> #include <string>
#include "../types.h" #include "../types.h"
#include "../http/httplib.h"
#include "../repositories/player_event_logs_repository.h" #include "../repositories/player_event_logs_repository.h"
#include "../events/player_events.h" #include "../events/player_events.h"

View File

@ -26,7 +26,7 @@ void DiscordManager::ProcessMessageQueue()
continue; continue;
} }
auto webhook = EQEmuLogSys::Instance()->GetDiscordWebhooks()[q.first]; auto webhook = LogSys.GetDiscordWebhooks()[q.first];
std::string message; std::string message;
for (auto &m: q.second) { for (auto &m: q.second) {
@ -68,7 +68,7 @@ void DiscordManager::ProcessMessageQueue()
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e) void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
{ {
auto w = PlayerEventLogs::Instance()->GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id); auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
if (!w.empty()) { if (!w.empty()) {
Discord::SendPlayerEventMessage(e, w); Discord::SendPlayerEventMessage(e, w);
} }

View File

@ -13,12 +13,6 @@ public:
void QueueWebhookMessage(uint32 webhook_id, const std::string& message); void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
void ProcessMessageQueue(); void ProcessMessageQueue();
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e); void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
static DiscordManager* Instance()
{
static DiscordManager instance;
return &instance;
}
private: private:
std::mutex webhook_queue_lock{}; std::mutex webhook_queue_lock{};
std::map<uint32, std::vector<std::string>> webhook_message_queue{}; std::map<uint32, std::vector<std::string>> webhook_message_queue{};

View File

@ -451,23 +451,3 @@ bool LDoNTheme::IsValid(uint32 theme_id)
{ {
return ldon_theme_names.find(theme_id) != ldon_theme_names.end(); return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
} }
std::string PetCommand::GetName(uint8 pet_command)
{
return IsValid(pet_command) ? pet_commands[pet_command] : "UNKNOWN PET COMMAND";
}
bool PetCommand::IsValid(uint8 pet_command)
{
return pet_commands.find(pet_command) != pet_commands.end();
}
std::string PetType::GetName(uint8 pet_type)
{
return IsValid(pet_type) ? pet_types[pet_type] : "UNKNOWN PET TYPE";
}
bool PetType::IsValid(uint8 pet_type)
{
return pet_types.find(pet_type) != pet_types.end();
}

View File

@ -792,131 +792,4 @@ namespace BookType {
constexpr uint8 ItemInfo = 2; constexpr uint8 ItemInfo = 2;
} }
namespace PetButton {
constexpr uint8 Sit = 0;
constexpr uint8 Stop = 1;
constexpr uint8 Regroup = 2;
constexpr uint8 Follow = 3;
constexpr uint8 Guard = 4;
constexpr uint8 Taunt = 5;
constexpr uint8 Hold = 6;
constexpr uint8 GreaterHold = 7;
constexpr uint8 Focus = 8;
constexpr uint8 SpellHold = 9;
}
namespace PetButtonState {
constexpr uint8 Off = 0;
constexpr uint8 On = 1;
}
namespace PetCommand {
constexpr uint8 HealthReport = 0; // /pet health or Pet Window
constexpr uint8 Leader = 1; // /pet leader or Pet Window
constexpr uint8 Attack = 2; // /pet attack or Pet Window
constexpr uint8 QAttack = 3; // /pet qattack or Pet Window
constexpr uint8 FollowMe = 4; // /pet follow or Pet Window
constexpr uint8 GuardHere = 5; // /pet guard or Pet Window
constexpr uint8 Sit = 6; // /pet sit or Pet Window
constexpr uint8 SitDown = 7; // /pet sit on
constexpr uint8 StandUp = 8; // /pet sit off
constexpr uint8 Stop = 9; // /pet stop or Pet Window - Not implemented
constexpr uint8 StopOn = 10; // /pet stop on - Not implemented
constexpr uint8 StopOff = 11; // /pet stop off - Not implemented
constexpr uint8 Taunt = 12; // /pet taunt or Pet Window
constexpr uint8 TauntOn = 13; // /pet taunt on
constexpr uint8 TauntOff = 14; // /pet taunt off
constexpr uint8 Hold = 15; // /pet hold or Pet Window, won't add to hate list unless attacking
constexpr uint8 HoldOn = 16; // /pet hold on
constexpr uint8 HoldOff = 17; // /pet hold off
constexpr uint8 GreaterHold = 18; // /pet ghold, will never add to hate list unless told to
constexpr uint8 GreaterHoldOn = 19; // /pet ghold on
constexpr uint8 GreaterHoldOff = 20; // /pet ghold off
constexpr uint8 SpellHold = 21; // /pet no cast or /pet spellhold or Pet Window
constexpr uint8 SpellHoldOn = 22; // /pet spellhold on
constexpr uint8 SpellHoldOff = 23; // /pet spellhold off
constexpr uint8 Focus = 24; // /pet focus or Pet Window
constexpr uint8 FocusOn = 25; // /pet focus on
constexpr uint8 FocusOff = 26; // /pet focus off
constexpr uint8 Feign = 27; // /pet feign
constexpr uint8 BackOff = 28; // /pet back off
constexpr uint8 GetLost = 29; // /pet get lost
constexpr uint8 GuardMe = 30; // Same as /pet follow, but different message in older clients
constexpr uint8 Regroup = 31; // /pet regroup, acts like classic hold
constexpr uint8 RegroupOn = 32; // /pet regroup on
constexpr uint8 RegroupOff = 33; // /pet regroup off
constexpr uint8 Max = 34;
static std::map<uint8, std::string> pet_commands = {
{ PetCommand::HealthReport, "Health Report" },
{ PetCommand::Leader, "Leader" },
{ PetCommand::Attack, "Attack" },
{ PetCommand::QAttack, "QAttack" },
{ PetCommand::FollowMe, "Follow Me" },
{ PetCommand::GuardHere, "Guard Here" },
{ PetCommand::Sit, "Sit" },
{ PetCommand::SitDown, "Sit Down" },
{ PetCommand::StandUp, "Stand Up" },
{ PetCommand::Stop, "Stop" },
{ PetCommand::StopOn, "Stop On" },
{ PetCommand::StopOff, "Stop Off" },
{ PetCommand::Taunt, "Taunt" },
{ PetCommand::TauntOn, "Taunt On" },
{ PetCommand::TauntOff, "Taunt Off" },
{ PetCommand::Hold, "Hold" },
{ PetCommand::HoldOn, "Hold On" },
{ PetCommand::HoldOff, "Hold Off" },
{ PetCommand::GreaterHold, "Greater Hold" },
{ PetCommand::GreaterHoldOn, "Greater Hold On" },
{ PetCommand::GreaterHoldOff, "Greater Hold Off" },
{ PetCommand::SpellHold, "Spell Hold" },
{ PetCommand::SpellHoldOn, "Spell Hold On" },
{ PetCommand::SpellHoldOff, "Spell Hold Off" },
{ PetCommand::Focus, "Focus" },
{ PetCommand::FocusOn, "Focus On" },
{ PetCommand::FocusOff, "Focus Off" },
{ PetCommand::Feign, "Feign" },
{ PetCommand::BackOff, "Back Off" },
{ PetCommand::GetLost, "Get Lost" },
{ PetCommand::GuardMe, "Guard Me" },
{ PetCommand::Regroup, "Regroup" },
{ PetCommand::RegroupOn, "Regroup On" },
{ PetCommand::RegroupOff, "Regroup Off" },
{ PetCommand::Max, "Max" }
};
std::string GetName(uint8 pet_command);
bool IsValid(uint8 pet_command);
}
namespace PetOrder {
constexpr uint8 Follow = 0;
constexpr uint8 Sit = 1;
constexpr uint8 Guard = 2;
constexpr uint8 Feign = 3;
}
namespace PetType {
constexpr uint8 Familiar = 0;
constexpr uint8 Animation = 1;
constexpr uint8 Normal = 2;
constexpr uint8 Charmed = 3;
constexpr uint8 Follow = 4;
constexpr uint8 TargetLock = 5;
constexpr uint8 None = 255;
static std::map<uint8, std::string> pet_types = {
{ PetType::Familiar, "Familiar" },
{ PetType::Animation, "Animation" },
{ PetType::Normal, "Normal" },
{ PetType::Charmed, "Charmed" },
{ PetType::Follow, "Follow" },
{ PetType::TargetLock, "Target Lock" },
{ PetType::None, "None" }
};
std::string GetName(uint8 pet_type);
bool IsValid(uint8 pet_type);
}
#endif /*COMMON_EMU_CONSTANTS_H*/ #endif /*COMMON_EMU_CONSTANTS_H*/

View File

@ -988,8 +988,7 @@ enum StartZoneIndex {
Felwithe, Felwithe,
Akanon, Akanon,
Cabilis, Cabilis,
SharVahl, SharVahl
RatheMtn
}; };
enum FVNoDropFlagRule enum FVNoDropFlagRule

View File

@ -545,13 +545,13 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
uint32 chunksize, used; uint32 chunksize, used;
uint32 length; uint32 length;
if (EQEmuLogSys::Instance()->log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){ if (LogSys.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){
if (p->GetOpcode() != OP_SpecialMesg){ if (p->GetOpcode() != OP_SpecialMesg){
Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size()); Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
} }
} }
if (EQEmuLogSys::Instance()->log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){ if (LogSys.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){
if (p->GetOpcode() != OP_SpecialMesg){ if (p->GetOpcode() != OP_SpecialMesg){
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str()); Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
} }

View File

@ -6,7 +6,7 @@
#include <string> #include <string>
#include "emu_versions.h" #include "emu_versions.h"
#include "eq_packet.h" #include "eq_packet.h"
#include "net/reliable_stream_connection.h" #include "net/daybreak_connection.h"
typedef enum { typedef enum {
ESTABLISHED, ESTABLISHED,
@ -33,18 +33,18 @@ struct EQStreamManagerInterfaceOptions
//Login I had trouble getting to recognize compression at all //Login I had trouble getting to recognize compression at all
//but that might be because it was still a bit buggy when i was testing that. //but that might be because it was still a bit buggy when i was testing that.
if (compressed) { if (compressed) {
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeCompression; daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
} }
else if (encoded) { else if (encoded) {
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeXOR; daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
} }
reliable_stream_options.port = port; daybreak_options.port = port;
} }
int opcode_size; int opcode_size;
bool track_opcode_stats; bool track_opcode_stats;
EQ::Net::ReliableStreamConnectionManagerOptions reliable_stream_options; EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
}; };
class EQStreamManagerInterface class EQStreamManagerInterface
@ -80,7 +80,7 @@ public:
struct Stats struct Stats
{ {
EQ::Net::ReliableStreamConnectionStats ReliableStreamStats; EQ::Net::DaybreakConnectionStats DaybreakStats;
int RecvCount[_maxEmuOpcode]; int RecvCount[_maxEmuOpcode];
int SentCount[_maxEmuOpcode]; int SentCount[_maxEmuOpcode];
}; };

View File

@ -177,21 +177,6 @@ void EQEmuConfig::parse_config()
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString(); SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
LogDir = _root["server"]["directories"].get("logs", "logs/").asString(); LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
auto load_paths = [&](const std::string& key, std::vector<std::string>& target) {
const auto& paths = _root["server"]["directories"][key];
if (paths.isArray()) {
for (const auto& dir : paths) {
if (dir.isString()) {
target.push_back(dir.asString());
}
}
}
};
load_paths("quest_paths", m_quest_directories);
load_paths("plugin_paths", m_plugin_directories);
load_paths("lua_module_paths", m_lua_module_directories);
/** /**
* Logs * Logs
*/ */
@ -436,11 +421,11 @@ void EQEmuConfig::CheckUcsConfigConversion()
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration"); LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
std::string config_file_path = std::filesystem::path{ std::string config_file_path = std::filesystem::path{
PathManager::Instance()->GetServerPath() + "/eqemu_config.json" path.GetServerPath() + "/eqemu_config.json"
}.string(); }.string();
std::string config_file_bak_path = std::filesystem::path{ std::string config_file_bak_path = std::filesystem::path{
PathManager::Instance()->GetServerPath() + "/eqemu_config.ucs-migrate-json.bak" path.GetServerPath() + "/eqemu_config.ucs-migrate-json.bak"
}.string(); }.string();
// copy eqemu_config.json to eqemu_config.json.bak // copy eqemu_config.json to eqemu_config.json.bak

View File

@ -120,22 +120,6 @@ class EQEmuConfig
const std::string &GetUCSHost() const; const std::string &GetUCSHost() const;
uint16 GetUCSPort() const; uint16 GetUCSPort() const;
std::vector<std::string> GetQuestDirectories() const
{
return m_quest_directories;
}
std::vector<std::string> GetPluginsDirectories() const
{
return m_plugin_directories;
}
std::vector<std::string> GetLuaModuleDirectories() const
{
return m_lua_module_directories;
}
// uint16 DynamicCount; // uint16 DynamicCount;
// map<string,uint16> StaticZones; // map<string,uint16> StaticZones;
@ -149,11 +133,6 @@ class EQEmuConfig
Json::Value _root; Json::Value _root;
static std::string ConfigFile; static std::string ConfigFile;
std::vector<std::string> m_quest_directories = {};
std::vector<std::string> m_plugin_directories = {};
std::vector<std::string> m_lua_module_directories = {};
protected:
void parse_config(); void parse_config();
EQEmuConfig() EQEmuConfig()
@ -191,7 +170,7 @@ class EQEmuConfig
std::string file = fmt::format( std::string file = fmt::format(
"{}/{}", "{}/{}",
(file_path.empty() ? PathManager::Instance()->GetServerPath() : file_path), (file_path.empty() ? path.GetServerPath() : file_path),
EQEmuConfig::ConfigFile EQEmuConfig::ConfigFile
); );

View File

@ -537,9 +537,9 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
{ {
EQEmuLogSys::CloseFileLogs(); EQEmuLogSys::CloseFileLogs();
if (!File::Exists(PathManager::Instance()->GetLogPath())) { if (!File::Exists(path.GetLogPath())) {
LogInfo("Logs directory not found, creating [{}]", PathManager::Instance()->GetLogPath()); LogInfo("Logs directory not found, creating [{}]", path.GetLogPath());
File::Makedir(PathManager::Instance()->GetLogPath()); File::Makedir(path.GetLogPath());
} }
/** /**
@ -656,7 +656,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings(bool silent_load)
// If we go through this whole loop and nothing is set to any debug level, there // If we go through this whole loop and nothing is set to any debug level, there
// is no point to create a file or keep anything open // is no point to create a file or keep anything open
if (log_settings[c.log_category_id].log_to_file > 0) { if (log_settings[c.log_category_id].log_to_file > 0) {
m_file_logs_enabled = true; LogSys.m_file_logs_enabled = true;
} }
db_categories.emplace_back(c.log_category_id); db_categories.emplace_back(c.log_category_id);
@ -682,33 +682,14 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings(bool silent_load)
if (is_missing_in_database && !is_deprecated_category) { 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 e = LogsysCategoriesRepository::NewEntity(); auto new_category = LogsysCategoriesRepository::NewEntity();
e.log_category_id = i; new_category.log_category_id = i;
e.log_category_description = Strings::Escape(Logs::LogCategoryName[i]); new_category.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
e.log_to_console = log_settings[i].log_to_console; new_category.log_to_console = log_settings[i].log_to_console;
e.log_to_gmsay = log_settings[i].log_to_gmsay; new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
e.log_to_file = log_settings[i].log_to_file; new_category.log_to_file = log_settings[i].log_to_file;
e.log_to_discord = log_settings[i].log_to_discord; new_category.log_to_discord = log_settings[i].log_to_discord;
db_categories_to_add.emplace_back(e); db_categories_to_add.emplace_back(new_category);
}
// look to see if the category name is different in the database
auto it = std::find_if(
categories.begin(),
categories.end(),
[i](const auto &c) { return c.log_category_id == i; }
);
if (it != categories.end()) {
if (it->log_category_description != Logs::LogCategoryName[i]) {
LogInfo(
"Updating log category [{}] ({}) to new name [{}]",
it->log_category_description,
i,
Logs::LogCategoryName[i]
);
it->log_category_description = Logs::LogCategoryName[i];
LogsysCategoriesRepository::ReplaceOne(*m_database, *it);
}
} }
} }

View File

@ -194,8 +194,8 @@ namespace Logs {
"Web Interface (Deprecated)", "Web Interface (Deprecated)",
"World Server (Deprecated)", "World Server (Deprecated)",
"Zone Server (Deprecated)", "Zone Server (Deprecated)",
"MySQL Error", "QueryErr",
"MySQL Query", "Query",
"Mercenaries", "Mercenaries",
"Quest Debug", "Quest Debug",
"Legacy Packet Logging (Deprecated)", "Legacy Packet Logging (Deprecated)",
@ -211,15 +211,15 @@ namespace Logs {
"Traps", "Traps",
"NPC Roam Box", "NPC Roam Box",
"NPC Scaling", "NPC Scaling",
"Mob Appearance", "MobAppearance",
"Info", "Info",
"Warning", "Warning",
"Critical (Deprecated)", "Critical (Deprecated)",
"Emergency (Deprecated)", "Emergency (Deprecated)",
"Alert (Deprecated)", "Alert (Deprecated)",
"Notice (Deprecated)", "Notice (Deprecated)",
"AI Scan Close", "AI Scan",
"AI Yell For Help", "AI Yell",
"AI CastBeneficial", "AI CastBeneficial",
"AOE Cast", "AOE Cast",
"Entity Management", "Entity Management",
@ -237,7 +237,7 @@ namespace Logs {
"DialogueWindow", "DialogueWindow",
"HTTP", "HTTP",
"Saylink", "Saylink",
"Checksum Verification", "ChecksumVer",
"CombatRecord", "CombatRecord",
"Hate", "Hate",
"Discord", "Discord",
@ -266,6 +266,8 @@ namespace Logs {
}; };
} }
#include "eqemu_logsys_log_aliases.h"
class Database; class Database;
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300; constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
@ -283,12 +285,6 @@ public:
EQEmuLogSys *LoadLogSettingsDefaults(); EQEmuLogSys *LoadLogSettingsDefaults();
EQEmuLogSys *LoadLogDatabaseSettings(bool silent_load = false); EQEmuLogSys *LoadLogDatabaseSettings(bool silent_load = false);
static EQEmuLogSys *Instance()
{
static EQEmuLogSys instance;
return &instance;
}
/** /**
* @param directory_name * @param directory_name
*/ */
@ -354,7 +350,7 @@ public:
/** /**
* Internally used memory reference for all log settings per category * Internally used memory reference for all log settings per category
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults * These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
* Database loaded via EQEmuLogSys::Instance()->SetDatabase(&database)->LoadLogDatabaseSettings(); * Database loaded via LogSys.SetDatabase(&database)->LoadLogDatabaseSettings();
*/ */
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{}; LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
@ -438,7 +434,7 @@ private:
void InjectTablesIfNotExist(); void InjectTablesIfNotExist();
}; };
#include "eqemu_logsys_log_aliases.h" extern EQEmuLogSys LogSys;
/** /**
template<typename... Args> template<typename... Args>
@ -460,7 +456,7 @@ void OutF(
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \ #define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
do { \ do { \
ls->Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \ ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
} while(0) } while(0)
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -716,7 +716,7 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
); );
for (int i = 0; i < h.augment_ids.size(); i++) { for (int i = 0; i < h.augment_ids.size(); i++) {
if (!h.augment_names[i].empty()) { if (!Strings::EqualFold(h.augment_names[i], "None")) {
const uint8 slot_id = (i + 1); const uint8 slot_id = (i + 1);
handin_items_info += fmt::format( handin_items_info += fmt::format(
"Augment {}: {} ({})\n", "Augment {}: {} ({})\n",
@ -741,7 +741,7 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
); );
for (int i = 0; i < r.augment_ids.size(); i++) { for (int i = 0; i < r.augment_ids.size(); i++) {
if (!r.augment_names[i].empty()) { if (!Strings::EqualFold(r.augment_names[i], "None")) {
const uint8 slot_id = (i + 1); const uint8 slot_id = (i + 1);
return_items_info += fmt::format( return_items_info += fmt::format(
"Augment {}: {} ({})\n", "Augment {}: {} ({})\n",

View File

@ -15,9 +15,9 @@ const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1
// general initialization routine // general initialization routine
void PlayerEventLogs::Init() void PlayerEventLogs::Init()
{ {
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000); m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL); m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
m_database_ping_timer.SetTimer(10 * 1000); // 10 seconds
ValidateDatabaseConnection(); ValidateDatabaseConnection();
@ -195,12 +195,10 @@ void PlayerEventLogs::ProcessBatchQueue()
}; };
// Helper to assign ETL table ID // Helper to assign ETL table ID
auto AssignEtlId = [&](
auto AssignEtlId = [&]( PlayerEventLogsRepository::PlayerEventLogs &r,
PlayerEventLogsRepository::PlayerEventLogs& r, PlayerEvent::EventType type
PlayerEvent::EventType type ) {
)
{
if (m_etl_settings.contains(type)) { if (m_etl_settings.contains(type)) {
r.etl_table_id = m_etl_settings.at(type).next_id++; r.etl_table_id = m_etl_settings.at(type).next_id++;
} }
@ -408,6 +406,7 @@ void PlayerEventLogs::ProcessBatchQueue()
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id)); auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
if (it != event_processors.end()) { if (it != event_processors.end()) {
it->second(r); // Call the appropriate lambda it->second(r); // Call the appropriate lambda
r.event_data = "{}"; // Clear event data
} }
else { else {
LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id); LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id);
@ -509,7 +508,7 @@ bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
} }
// ensure there is a matching webhook to begin with // ensure there is a matching webhook to begin with
if (!EQEmuLogSys::Instance()->GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) { if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
return true; return true;
} }
@ -529,27 +528,13 @@ std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_typ
} }
// ensure there is a matching webhook to begin with // ensure there is a matching webhook to begin with
if (!EQEmuLogSys::Instance()->GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) { if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
return EQEmuLogSys::Instance()->GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url; return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
} }
return ""; return "";
} }
void PlayerEventLogs::LoadPlayerEventSettingsFromQS(
const std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> &settings
)
{
for (const auto &e : settings) {
if (e.id >= PlayerEvent::MAX || e.id < 0) {
continue;
}
m_settings[e.id] = e;
}
LogInfo("Applied [{}] player event log settings from QS", settings.size());
}
// GM_COMMAND | [x] Implemented Formatter // GM_COMMAND | [x] Implemented Formatter
// ZONING | [x] Implemented Formatter // ZONING | [x] Implemented Formatter
// AA_GAIN | [x] Implemented Formatter // AA_GAIN | [x] Implemented Formatter
@ -931,10 +916,6 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess // general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
void PlayerEventLogs::Process() void PlayerEventLogs::Process()
{ {
if (m_database_ping_timer.Check()) {
m_database->ping();
}
if (m_process_batch_events_timer.Check() || if (m_process_batch_events_timer.Check() ||
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) { m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
ProcessBatchQueue(); ProcessBatchQueue();

View File

@ -73,11 +73,9 @@ public:
return BuildPlayerEventPacket(c); return BuildPlayerEventPacket(c);
} }
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings * GetSettings() const; [[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
bool IsEventDiscordEnabled(int32_t event_type_id); bool IsEventDiscordEnabled(int32_t event_type_id);
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id); std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
void LoadPlayerEventSettingsFromQS(const std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings>& settings);
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e); static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
@ -96,12 +94,6 @@ public:
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase; std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
}; };
static PlayerEventLogs* Instance()
{
static PlayerEventLogs instance;
return &instance;
}
private: private:
struct EtlSettings { struct EtlSettings {
bool enabled; bool enabled;
@ -121,7 +113,6 @@ private:
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{}; std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
// timers // timers
Timer m_database_ping_timer; // database ping timer
Timer m_process_batch_events_timer; // events processing timer Timer m_process_batch_events_timer; // events processing timer
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
@ -135,4 +126,6 @@ public:
std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;} std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;}
}; };
extern PlayerEventLogs player_event_logs;
#endif //EQEMU_PLAYER_EVENT_LOGS_H #endif //EQEMU_PLAYER_EVENT_LOGS_H

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,8 @@ void EvolvingItemsManager::LoadEvolvingItems() const
results.begin(), results.begin(),
results.end(), results.end(),
std::inserter( std::inserter(
EvolvingItemsManager::Instance()->GetEvolvingItemsCache(), evolving_items_manager.GetEvolvingItemsCache(),
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().end() evolving_items_manager.GetEvolvingItemsCache().end()
), ),
[](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &x) { [](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &x) {
return std::make_pair(x.item_id, x); return std::make_pair(x.item_id, x);
@ -42,13 +42,13 @@ void EvolvingItemsManager::SetContentDatabase(Database *db)
double EvolvingItemsManager::CalculateProgression(const uint64 current_amount, const uint32 item_id) double EvolvingItemsManager::CalculateProgression(const uint64 current_amount, const uint32 item_id)
{ {
if (!EvolvingItemsManager::Instance()->GetEvolvingItemsCache().contains(item_id)) { if (!evolving_items_manager.GetEvolvingItemsCache().contains(item_id)) {
return 0; return 0;
} }
return EvolvingItemsManager::Instance()->GetEvolvingItemsCache().at(item_id).required_amount > 0 return evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount > 0
? static_cast<double>(current_amount) ? static_cast<double>(current_amount)
/ static_cast<double>(EvolvingItemsManager::Instance()->GetEvolvingItemsCache().at(item_id).required_amount) * 100 / static_cast<double>(evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount) * 100
: 0; : 0;
} }
@ -73,11 +73,7 @@ void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_
e.character_id = char_id; e.character_id = char_id;
e.item_id = inst.GetID(); e.item_id = inst.GetID();
e.equipped = inst.GetEvolveEquipped(); e.equipped = inst.GetEvolveEquipped();
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(inst); e.final_item_id = evolving_items_manager.GetFinalItemID(inst);
if (inst.GetEvolveCurrentAmount() > 0) {
e.current_amount = inst.GetEvolveCurrentAmount();
inst.CalculateEvolveProgression();
}
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e); auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
e.id = r.id; e.id = r.id;
@ -100,20 +96,20 @@ uint32 EvolvingItemsManager::GetFinalItemID(const EQ::ItemInstance &inst) const
} }
const auto start_iterator = std::ranges::find_if( const auto start_iterator = std::ranges::find_if(
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cbegin(), evolving_items_manager.GetEvolvingItemsCache().cbegin(),
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(), evolving_items_manager.GetEvolvingItemsCache().cend(),
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) { [&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
return a.second.item_evo_id == inst.GetEvolveLoreID(); return a.second.item_evo_id == inst.GetEvolveLoreID();
} }
); );
if (start_iterator == std::end(EvolvingItemsManager::Instance()->GetEvolvingItemsCache())) { if (start_iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
return 0; return 0;
} }
const auto final_id = std::ranges::max_element( const auto final_id = std::ranges::max_element(
start_iterator, start_iterator,
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(), evolving_items_manager.GetEvolvingItemsCache().cend(),
[&]( [&](
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a, const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a,
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &b const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &b
@ -135,15 +131,15 @@ uint32 EvolvingItemsManager::GetNextEvolveItemID(const EQ::ItemInstance &inst) c
int8 const current_level = inst.GetEvolveLvl(); int8 const current_level = inst.GetEvolveLvl();
const auto iterator = std::ranges::find_if( const auto iterator = std::ranges::find_if(
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cbegin(), evolving_items_manager.GetEvolvingItemsCache().cbegin(),
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(), evolving_items_manager.GetEvolvingItemsCache().cend(),
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) { [&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
return a.second.item_evo_id == inst.GetEvolveLoreID() && return a.second.item_evo_id == inst.GetEvolveLoreID() &&
a.second.item_evolve_level == current_level + 1; a.second.item_evolve_level == current_level + 1;
} }
); );
if (iterator == std::end(EvolvingItemsManager::Instance()->GetEvolvingItemsCache())) { if (iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
return 0; return 0;
} }
@ -259,8 +255,8 @@ EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
return ets; return ets;
} }
auto evolving_details_inst_from = EvolvingItemsManager::Instance()->GetEvolveItemDetails(inst_from.GetID()); auto evolving_details_inst_from = evolving_items_manager.GetEvolveItemDetails(inst_from.GetID());
auto evolving_details_inst_to = EvolvingItemsManager::Instance()->GetEvolveItemDetails(inst_to.GetID()); auto evolving_details_inst_to = evolving_items_manager.GetEvolveItemDetails(inst_to.GetID());
if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) { if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) {
return ets; return ets;
@ -276,10 +272,10 @@ EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
compatibility = 30; compatibility = 30;
} }
xp = EvolvingItemsManager::Instance()->GetTotalEarnedXP(inst_from) * compatibility / 100; xp = evolving_items_manager.GetTotalEarnedXP(inst_from) * compatibility / 100;
auto results = EvolvingItemsManager::Instance()->GetNextItemByXP(inst_to, xp); auto results = evolving_items_manager.GetNextItemByXP(inst_to, xp);
ets.item_from_id = EvolvingItemsManager::Instance()->GetFirstItemInLoreGroup(inst_from.GetEvolveLoreID()); ets.item_from_id = evolving_items_manager.GetFirstItemInLoreGroup(inst_from.GetEvolveLoreID());
ets.item_from_current_amount = results.from_current_amount; ets.item_from_current_amount = results.from_current_amount;
ets.item_to_id = results.new_item_id; ets.item_to_id = results.new_item_id;
ets.item_to_current_amount = results.new_current_amount; ets.item_to_current_amount = results.new_current_amount;

View File

@ -56,15 +56,12 @@ public:
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails>& GetEvolvingItemsCache() { return m_evolving_items_cache; } std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails>& GetEvolvingItemsCache() { return m_evolving_items_cache; }
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id); std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id);
static EvolvingItemsManager* Instance()
{
static EvolvingItemsManager instance;
return &instance;
}
private: private:
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> m_evolving_items_cache; std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> m_evolving_items_cache;
Database * m_db; Database * m_db;
Database * m_content_db; Database * m_content_db;
}; };
extern EvolvingItemsManager evolving_items_manager;
#endif //EVOLVING_H #endif //EVOLVING_H

View File

@ -95,12 +95,12 @@ bool IsOfEqualRace(int r1, int r2)
} }
// TODO: add more values // TODO: add more values
switch (r1) { switch (r1) {
case Race::DarkElf: case DARK_ELF:
if (r2 == Race::NeriakCitizen) { if (r2 == Race::NeriakCitizen) {
return true; return true;
} }
break; break;
case Race::Barbarian: case BARBARIAN:
if (r2 == Race::HalasCitizen) { if (r2 == Race::HalasCitizen) {
return true; return true;
} }
@ -116,49 +116,49 @@ bool IsOfIndiffRace(int r1, int r2)
} }
// TODO: add more values // TODO: add more values
switch (r1) { switch (r1) {
case Race::DarkElf: case DARK_ELF:
case Race::Ogre: case OGRE:
case Race::Troll: case TROLL:
if (r2 == Race::Ogre || r2 == Race::Troll || r2 == Race::DarkElf) { if (r2 == OGRE || r2 == TROLL || r2 == DARK_ELF) {
return true; return true;
} }
break; break;
case Race::Human: case HUMAN:
case Race::Barbarian: case BARBARIAN:
case Race::HalfElf: case HALF_ELF:
case Race::Gnome: case GNOME:
case Race::Halfling: case HALFLING:
case Race::WoodElf: case WOOD_ELF:
if (r2 == Race::Human || if (r2 == HUMAN ||
r2 == Race::Barbarian || r2 == BARBARIAN ||
r2 == Race::Erudite || r2 == ERUDITE ||
r2 == Race::HalfElf || r2 == HALF_ELF ||
r2 == Race::Gnome || r2 == GNOME ||
r2 == Race::Halfling || r2 == HALFLING ||
r2 == Race::Dwarf || r2 == DWARF ||
r2 == Race::HighElf || r2 == HIGH_ELF ||
r2 == Race::WoodElf) { r2 == WOOD_ELF) {
return true; return true;
} }
break; break;
case Race::Erudite: case ERUDITE:
if (r2 == Race::Human || r2 == Race::HalfElf) { if (r2 == HUMAN || r2 == HALF_ELF) {
return true; return true;
} }
break; break;
case Race::Dwarf: case DWARF:
if (r2 == Race::Halfling || r2 == Race::Gnome) { if (r2 == HALFLING || r2 == GNOME) {
return true; return true;
} }
break; break;
case Race::HighElf: case HIGH_ELF:
if (r2 == Race::WoodElf) { if (r2 == WOOD_ELF) {
return true; return true;
} }
break; break;
case Race::VahShir: case VAHSHIR:
return true; return true;
case Race::Iksar: case IKSAR:
return false; return false;
} }
return false; return false;

View File

@ -55,7 +55,7 @@ namespace EQ {
EQ_EXCEPT("IPC Mutex", "Could not create mutex."); EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
} }
#else #else
std::string final_name = fmt::format("{}/{}.lock", PathManager::Instance()->GetSharedMemoryPath(), name); std::string final_name = fmt::format("{}/{}.lock", path.GetSharedMemoryPath(), name);
#ifdef __DARWIN #ifdef __DARWIN
#if __DARWIN_C_LEVEL < 200809L #if __DARWIN_C_LEVEL < 200809L

View File

@ -438,7 +438,7 @@ namespace EQ
//uint32 Unk054 {}; //uint32 Unk054 {};
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
uint8 ItemType {}; // Item Type/Skill (itemClass* from above) 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, SpellEffect::FFItemClass) int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
uint8 Material {}; // Item material type uint8 Material {}; // Item material type
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?) uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
float SellRate {}; // Sell rate float SellRate {}; // Sell rate

206
common/item_fieldlist.h Normal file
View File

@ -0,0 +1,206 @@
/*
These fields must be in the order of how they are serialized!
*/
F(itemclass)
F(name)
F(lore)
F(idfile)
F(id)
F(weight)
F(norent)
F(nodrop)
F(size)
F(slots)
F(price)
F(icon)
F(UNK012)
F(UNK013)
F(benefitflag)
F(tradeskills)
F(cr)
F(dr)
F(pr)
F(mr)
F(fr)
F(astr)
F(asta)
F(aagi)
F(adex)
F(acha)
F(aint)
F(awis)
F(hp)
F(mana)
F(ac)
F(deity)
F(skillmodvalue)
F(UNK033)
F(skillmodmax)
F(skillmodtype)
F(banedmgrace)
F(banedmgamt)
F(banedmgbody)
F(magic)
F(casttime_)
F(reqlevel)
F(bardtype)
F(bardvalue)
F(light)
F(delay)
F(reclevel)
F(recskill)
F(elemdmgtype)
F(elemdmgamt)
F(range)
F(damage)
F(color)
F(classes)
F(races)
F(UNK054)
F(maxcharges)
F(itemtype)
F(material)
F(herosforgemodel)
F(sellrate)
F(UNK059)
F(casttime)
F(elitematerial)
F(procrate)
F(combateffects)
F(shielding)
F(stunresist)
F(strikethrough)
F(extradmgskill)
F(extradmgamt)
F(spellshield)
F(avoidance)
F(accuracy)
F(charmfileid)
F(factionmod1)
F(factionmod2)
F(factionmod3)
F(factionmod4)
F(factionamt1)
F(factionamt2)
F(factionamt3)
F(factionamt4)
F(charmfile)
F(augtype)
F(augslot1type)
F(augslot1visible)
F(augslot2type)
F(augslot2visible)
F(augslot3type)
F(augslot3visible)
F(augslot4type)
F(augslot4visible)
F(augslot5type)
F(augslot5visible)
F(augslot6type)
F(augslot6visible)
F(ldontheme)
F(ldonprice)
F(ldonsold)
F(bagtype)
F(bagslots)
F(bagsize)
F(bagwr)
F(book)
F(booktype)
F(filename)
F(banedmgraceamt)
F(augrestrict)
F(loregroup)
F(pendingloreflag)
F(artifactflag)
F(summonedflag)
F(favor)
F(fvnodrop)
F(endur)
F(dotshielding)
F(attack)
F(regen)
F(manaregen)
F(enduranceregen)
F(haste)
F(damageshield)
F(recastdelay)
F(recasttype)
F(guildfavor)
F(augdistiller)
F(UNK123)
F(UNK124)
F(attuneable)
F(nopet)
F(UNK127)
F(pointtype)
F(potionbelt)
F(potionbeltslots)
F(stacksize)
F(notransfer)
F(stackable)
F(UNK134)
F(clickeffect)
F(clicktype)
F(clicklevel)
F(clicklevel2)
F(proceffect)
F(proctype)
F(proclevel)
F(proclevel2)
F(worneffect)
F(worntype)
F(wornlevel)
F(wornlevel2)
F(focuseffect)
F(focustype)
F(focuslevel)
F(focuslevel2)
F(scrolleffect)
F(scrolltype)
F(scrolllevel)
F(scrolllevel2)
F(bardeffect)
F(bardeffecttype)
F(bardlevel2)
F(bardlevel)
F(questitemflag)
F(svcorruption)
F(purity)
F(evoitem)
F(evoid)
F(evolvinglevel)
F(evomax)
F(backstabdmg)
F(dsmitigation)
F(heroic_str)
F(heroic_int)
F(heroic_wis)
F(heroic_agi)
F(heroic_dex)
F(heroic_sta)
F(heroic_cha)
F(heroic_mr)
F(heroic_fr)
F(heroic_cr)
F(heroic_dr)
F(heroic_pr)
F(heroic_svcorrup)
F(healamt)
F(spelldmg)
F(ldonsellbackrate)
F(scriptfileid)
F(expendablearrow)
F(clairvoyance)
F(clickname)
F(procname)
F(wornname)
F(focusname)
F(scrollname)
F(subtype)

View File

@ -574,7 +574,7 @@ EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
{ {
// Not a Hero Forge item. // Not a Hero Forge item.
if (m_ornament_hero_model == 0) { if (m_ornament_hero_model == 0 || material_slot < 0) {
return 0; return 0;
} }
@ -1799,7 +1799,7 @@ std::vector<std::string> EQ::ItemInstance::GetAugmentNames() const
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) { for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
const auto augment = GetAugment(slot_id); const auto augment = GetAugment(slot_id);
augment_names.push_back(augment ? augment->GetItem()->Name : ""); augment_names.push_back(augment ? augment->GetItem()->Name : "None");
} }
return augment_names; return augment_names;

View File

@ -335,7 +335,7 @@ namespace EQ
void SetEvolveAddToCurrentAmount(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; } void SetEvolveFinalItemID(const uint32 in) const { m_evolving_details.final_item_id = in; }
bool TransferOwnership(Database& db, const uint32 to_char_id) const; bool TransferOwnership(Database& db, const uint32 to_char_id) const;
void CalculateEvolveProgression() const { m_evolving_details.progression = EvolvingItemsManager::Instance()->CalculateProgression(GetEvolveCurrentAmount(), GetID()); } void CalculateEvolveProgression() const { m_evolving_details.progression = evolving_items_manager.CalculateProgression(GetEvolveCurrentAmount(), GetID()); }
protected: protected:
////////////////////////// //////////////////////////

View File

@ -1,4 +1,4 @@
#include "reliable_stream_connection.h" #include "daybreak_connection.h"
#include "../event/event_loop.h" #include "../event/event_loop.h"
#include "../data_verification.h" #include "../data_verification.h"
#include "crc32.h" #include "crc32.h"
@ -12,7 +12,7 @@ constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
// buffer pools // buffer pools
SendBufferPool send_buffer_pool; SendBufferPool send_buffer_pool;
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager() EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
{ {
m_attached = nullptr; m_attached = nullptr;
memset(&m_timer, 0, sizeof(uv_timer_t)); memset(&m_timer, 0, sizeof(uv_timer_t));
@ -21,7 +21,7 @@ EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager()
Attach(EQ::EventLoop::Get().Handle()); Attach(EQ::EventLoop::Get().Handle());
} }
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts) EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
{ {
m_attached = nullptr; m_attached = nullptr;
m_options = opts; m_options = opts;
@ -31,12 +31,12 @@ EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const
Attach(EQ::EventLoop::Get().Handle()); Attach(EQ::EventLoop::Get().Handle());
} }
EQ::Net::ReliableStreamConnectionManager::~ReliableStreamConnectionManager() EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
{ {
Detach(); Detach();
} }
void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop) void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
{ {
if (!m_attached) { if (!m_attached) {
uv_timer_init(loop, &m_timer); uv_timer_init(loop, &m_timer);
@ -45,7 +45,7 @@ void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz); auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz);
uv_timer_start(&m_timer, [](uv_timer_t *handle) { uv_timer_start(&m_timer, [](uv_timer_t *handle) {
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data; DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
c->UpdateDataBudget(); c->UpdateDataBudget();
c->Process(); c->Process();
c->ProcessResend(); c->ProcessResend();
@ -71,7 +71,7 @@ void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
buf->len = 65536; buf->len = 65536;
}, },
[](uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) { [](uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) {
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data; DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
if (nread < 0 || addr == nullptr) { if (nread < 0 || addr == nullptr) {
return; return;
} }
@ -90,7 +90,7 @@ void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
} }
} }
void EQ::Net::ReliableStreamConnectionManager::Detach() void EQ::Net::DaybreakConnectionManager::Detach()
{ {
if (m_attached) { if (m_attached) {
uv_udp_recv_stop(&m_socket); uv_udp_recv_stop(&m_socket);
@ -99,11 +99,11 @@ void EQ::Net::ReliableStreamConnectionManager::Detach()
} }
} }
void EQ::Net::ReliableStreamConnectionManager::Connect(const std::string &addr, int port) void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int port)
{ {
//todo dns resolution //todo dns resolution
auto connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, addr, port)); auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, addr, port));
connection->m_self = connection; connection->m_self = connection;
if (m_on_new_connection) { if (m_on_new_connection) {
@ -113,7 +113,7 @@ void EQ::Net::ReliableStreamConnectionManager::Connect(const std::string &addr,
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection)); m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
} }
void EQ::Net::ReliableStreamConnectionManager::Process() void EQ::Net::DaybreakConnectionManager::Process()
{ {
auto now = Clock::now(); auto now = Clock::now();
auto iter = m_connections.begin(); auto iter = m_connections.begin();
@ -177,7 +177,7 @@ void EQ::Net::ReliableStreamConnectionManager::Process()
} }
} }
void EQ::Net::ReliableStreamConnectionManager::UpdateDataBudget() void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
{ {
auto outgoing_data_rate = m_options.outgoing_data_rate; auto outgoing_data_rate = m_options.outgoing_data_rate;
if (outgoing_data_rate <= 0.0) { if (outgoing_data_rate <= 0.0) {
@ -196,7 +196,7 @@ void EQ::Net::ReliableStreamConnectionManager::UpdateDataBudget()
} }
} }
void EQ::Net::ReliableStreamConnectionManager::ProcessResend() void EQ::Net::DaybreakConnectionManager::ProcessResend()
{ {
auto iter = m_connections.begin(); auto iter = m_connections.begin();
while (iter != m_connections.end()) { while (iter != m_connections.end()) {
@ -217,15 +217,15 @@ void EQ::Net::ReliableStreamConnectionManager::ProcessResend()
} }
} }
void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size) void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
{ {
if (m_options.simulated_in_packet_loss && m_options.simulated_in_packet_loss >= m_rand.Int(0, 100)) { if (m_options.simulated_in_packet_loss && m_options.simulated_in_packet_loss >= m_rand.Int(0, 100)) {
return; return;
} }
if (size < ReliableStreamHeader::size()) { if (size < DaybreakHeader::size()) {
if (m_on_error_message) { if (m_on_error_message) {
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, ReliableStreamHeader::size())); m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, DaybreakHeader::size()));
} }
return; return;
} }
@ -239,9 +239,9 @@ void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &
else { else {
if (data[0] == 0 && data[1] == OP_SessionRequest) { if (data[0] == 0 && data[1] == OP_SessionRequest) {
StaticPacket p((void*)data, size); StaticPacket p((void*)data, size);
auto request = p.GetSerialize<ReliableStreamConnect>(0); auto request = p.GetSerialize<DaybreakConnect>(0);
connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, request, endpoint, port)); connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, request, endpoint, port));
connection->m_self = connection; connection->m_self = connection;
if (m_on_new_connection) { if (m_on_new_connection) {
@ -262,7 +262,7 @@ void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &
} }
} }
std::shared_ptr<EQ::Net::ReliableStreamConnection> EQ::Net::ReliableStreamConnectionManager::FindConnectionByEndpoint(std::string addr, int port) std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
{ {
auto p = std::make_pair(addr, port); auto p = std::make_pair(addr, port);
auto iter = m_connections.find(p); auto iter = m_connections.find(p);
@ -273,9 +273,9 @@ std::shared_ptr<EQ::Net::ReliableStreamConnection> EQ::Net::ReliableStreamConnec
return nullptr; return nullptr;
} }
void EQ::Net::ReliableStreamConnectionManager::SendDisconnect(const std::string &addr, int port) void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr, int port)
{ {
ReliableStreamDisconnect header; DaybreakDisconnect header;
header.zero = 0; header.zero = 0;
header.opcode = OP_OutOfSession; header.opcode = OP_OutOfSession;
header.connect_code = 0; header.connect_code = 0;
@ -300,7 +300,7 @@ void EQ::Net::ReliableStreamConnectionManager::SendDisconnect(const std::string
} }
//new connection made as server //new connection made as server
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port) EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port)
{ {
m_owner = owner; m_owner = owner;
m_last_send = Clock::now(); m_last_send = Clock::now();
@ -327,7 +327,7 @@ EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnec
} }
//new connection made as client //new connection made as client
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port) EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port)
{ {
m_owner = owner; m_owner = owner;
m_last_send = Clock::now(); m_last_send = Clock::now();
@ -349,11 +349,11 @@ EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnec
m_outgoing_budget = owner->m_options.outgoing_data_rate; m_outgoing_budget = owner->m_options.outgoing_data_rate;
} }
EQ::Net::ReliableStreamConnection::~ReliableStreamConnection() EQ::Net::DaybreakConnection::~DaybreakConnection()
{ {
} }
void EQ::Net::ReliableStreamConnection::Close() void EQ::Net::DaybreakConnection::Close()
{ {
if (m_status != StatusDisconnected && m_status != StatusDisconnecting) { if (m_status != StatusDisconnected && m_status != StatusDisconnecting) {
FlushBuffer(); FlushBuffer();
@ -367,17 +367,17 @@ void EQ::Net::ReliableStreamConnection::Close()
ChangeStatus(StatusDisconnecting); ChangeStatus(StatusDisconnecting);
} }
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p) void EQ::Net::DaybreakConnection::QueuePacket(Packet &p)
{ {
QueuePacket(p, 0, true); QueuePacket(p, 0, true);
} }
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream) void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream)
{ {
QueuePacket(p, stream, true); QueuePacket(p, stream, true);
} }
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream, bool reliable) void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliable)
{ {
if (*(char*)p.Data() == 0) { if (*(char*)p.Data() == 0) {
DynamicPacket packet; DynamicPacket packet;
@ -390,21 +390,21 @@ void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream, bool
InternalQueuePacket(p, stream, reliable); InternalQueuePacket(p, stream, reliable);
} }
EQ::Net::ReliableStreamConnectionStats EQ::Net::ReliableStreamConnection::GetStats() EQ::Net::DaybreakConnectionStats EQ::Net::DaybreakConnection::GetStats()
{ {
EQ::Net::ReliableStreamConnectionStats ret = m_stats; EQ::Net::DaybreakConnectionStats ret = m_stats;
ret.datarate_remaining = m_outgoing_budget; ret.datarate_remaining = m_outgoing_budget;
ret.avg_ping = m_rolling_ping; ret.avg_ping = m_rolling_ping;
return ret; return ret;
} }
void EQ::Net::ReliableStreamConnection::ResetStats() void EQ::Net::DaybreakConnection::ResetStats()
{ {
m_stats.Reset(); m_stats.Reset();
} }
void EQ::Net::ReliableStreamConnection::Process() void EQ::Net::DaybreakConnection::Process()
{ {
try { try {
auto now = Clock::now(); auto now = Clock::now();
@ -422,7 +422,7 @@ void EQ::Net::ReliableStreamConnection::Process()
} }
} }
void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p) void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
{ {
m_last_recv = Clock::now(); m_last_recv = Clock::now();
m_stats.recv_packets++; m_stats.recv_packets++;
@ -458,13 +458,13 @@ void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
switch (m_encode_passes[i]) { switch (m_encode_passes[i]) {
case EncodeCompression: case EncodeCompression:
if(temp.GetInt8(0) == 0) if(temp.GetInt8(0) == 0)
Decompress(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size()); Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else else
Decompress(temp, 1, temp.Length() - 1); Decompress(temp, 1, temp.Length() - 1);
break; break;
case EncodeXOR: case EncodeXOR:
if (temp.GetInt8(0) == 0) if (temp.GetInt8(0) == 0)
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size()); Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else else
Decode(temp, 1, temp.Length() - 1); Decode(temp, 1, temp.Length() - 1);
break; break;
@ -483,7 +483,7 @@ void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
switch (m_encode_passes[i]) { switch (m_encode_passes[i]) {
case EncodeXOR: case EncodeXOR:
if (temp.GetInt8(0) == 0) if (temp.GetInt8(0) == 0)
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size()); Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else else
Decode(temp, 1, temp.Length() - 1); Decode(temp, 1, temp.Length() - 1);
break; break;
@ -502,7 +502,7 @@ void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
} }
} }
void EQ::Net::ReliableStreamConnection::ProcessQueue() void EQ::Net::DaybreakConnection::ProcessQueue()
{ {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
auto stream = &m_streams[i]; auto stream = &m_streams[i];
@ -521,7 +521,7 @@ void EQ::Net::ReliableStreamConnection::ProcessQueue()
} }
} }
void EQ::Net::ReliableStreamConnection::RemoveFromQueue(int stream, uint16_t seq) void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
{ {
auto s = &m_streams[stream]; auto s = &m_streams[stream];
auto iter = s->packet_queue.find(seq); auto iter = s->packet_queue.find(seq);
@ -532,7 +532,7 @@ void EQ::Net::ReliableStreamConnection::RemoveFromQueue(int stream, uint16_t seq
} }
} }
void EQ::Net::ReliableStreamConnection::AddToQueue(int stream, uint16_t seq, const Packet &p) void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
{ {
auto s = &m_streams[stream]; auto s = &m_streams[stream];
auto iter = s->packet_queue.find(seq); auto iter = s->packet_queue.find(seq);
@ -544,7 +544,7 @@ void EQ::Net::ReliableStreamConnection::AddToQueue(int stream, uint16_t seq, con
} }
} }
void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p) void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
{ {
if (p.GetInt8(0) == 0) { if (p.GetInt8(0) == 0) {
if (p.Length() < 2) { if (p.Length() < 2) {
@ -628,13 +628,13 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_SessionRequest: case OP_SessionRequest:
{ {
if (m_status == StatusConnected) { if (m_status == StatusConnected) {
auto request = p.GetSerialize<ReliableStreamConnect>(0); auto request = p.GetSerialize<DaybreakConnect>(0);
if (NetworkToHost(request.connect_code) != m_connect_code) { if (NetworkToHost(request.connect_code) != m_connect_code) {
return; return;
} }
ReliableStreamConnectReply reply; DaybreakConnectReply reply;
reply.zero = 0; reply.zero = 0;
reply.opcode = OP_SessionResponse; reply.opcode = OP_SessionResponse;
reply.connect_code = HostToNetwork(m_connect_code); reply.connect_code = HostToNetwork(m_connect_code);
@ -656,13 +656,13 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_SessionResponse: case OP_SessionResponse:
{ {
if (m_status == StatusConnecting) { if (m_status == StatusConnecting) {
auto reply = p.GetSerialize<ReliableStreamConnectReply>(0); auto reply = p.GetSerialize<DaybreakConnectReply>(0);
if (m_connect_code == reply.connect_code) { if (m_connect_code == reply.connect_code) {
m_encode_key = reply.encode_key; m_encode_key = reply.encode_key;
m_crc_bytes = reply.crc_bytes; m_crc_bytes = reply.crc_bytes;
m_encode_passes[0] = (ReliableStreamEncodeType)reply.encode_pass1; m_encode_passes[0] = (DaybreakEncodeType)reply.encode_pass1;
m_encode_passes[1] = (ReliableStreamEncodeType)reply.encode_pass2; m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
m_max_packet_size = reply.max_packet_size; m_max_packet_size = reply.max_packet_size;
ChangeStatus(StatusConnected); ChangeStatus(StatusConnected);
@ -686,7 +686,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
return; return;
} }
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0); auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence); auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Packet; auto stream_id = header.opcode - OP_Packet;
auto stream = &m_streams[stream_id]; auto stream = &m_streams[stream_id];
@ -703,7 +703,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
RemoveFromQueue(stream_id, sequence); RemoveFromQueue(stream_id, sequence);
SendAck(stream_id, stream->sequence_in); SendAck(stream_id, stream->sequence_in);
stream->sequence_in++; stream->sequence_in++;
StaticPacket next((char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size()); StaticPacket next((char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
ProcessDecodedPacket(next); ProcessDecodedPacket(next);
} }
@ -715,7 +715,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_Fragment3: case OP_Fragment3:
case OP_Fragment4: case OP_Fragment4:
{ {
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0); auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence); auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Fragment; auto stream_id = header.opcode - OP_Fragment;
auto stream = &m_streams[stream_id]; auto stream = &m_streams[stream_id];
@ -735,22 +735,22 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
stream->sequence_in++; stream->sequence_in++;
if (stream->fragment_total_bytes == 0) { if (stream->fragment_total_bytes == 0) {
auto fragheader = p.GetSerialize<ReliableStreamReliableFragmentHeader>(0); auto fragheader = p.GetSerialize<DaybreakReliableFragmentHeader>(0);
stream->fragment_total_bytes = NetworkToHost(fragheader.total_size); stream->fragment_total_bytes = NetworkToHost(fragheader.total_size);
stream->fragment_current_bytes = 0; stream->fragment_current_bytes = 0;
stream->fragment_packet.Reserve(stream->fragment_total_bytes); stream->fragment_packet.Reserve(stream->fragment_total_bytes);
stream->fragment_packet.PutData( stream->fragment_packet.PutData(
stream->fragment_current_bytes, stream->fragment_current_bytes,
(char*)p.Data() + ReliableStreamReliableFragmentHeader::size(), p.Length() - ReliableStreamReliableFragmentHeader::size()); (char*)p.Data() + DaybreakReliableFragmentHeader::size(), p.Length() - DaybreakReliableFragmentHeader::size());
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableFragmentHeader::size()); stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableFragmentHeader::size());
} }
else { else {
stream->fragment_packet.PutData( stream->fragment_packet.PutData(
stream->fragment_current_bytes, stream->fragment_current_bytes,
(char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size()); (char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableHeader::size()); stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableHeader::size());
if (stream->fragment_current_bytes >= stream->fragment_total_bytes) { if (stream->fragment_current_bytes >= stream->fragment_total_bytes) {
ProcessDecodedPacket(stream->fragment_packet); ProcessDecodedPacket(stream->fragment_packet);
@ -769,7 +769,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_Ack3: case OP_Ack3:
case OP_Ack4: case OP_Ack4:
{ {
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0); auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence); auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Ack; auto stream_id = header.opcode - OP_Ack;
Ack(stream_id, sequence); Ack(stream_id, sequence);
@ -781,7 +781,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_OutOfOrderAck3: case OP_OutOfOrderAck3:
case OP_OutOfOrderAck4: case OP_OutOfOrderAck4:
{ {
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0); auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence); auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_OutOfOrderAck; auto stream_id = header.opcode - OP_OutOfOrderAck;
OutOfOrderAck(stream_id, sequence); OutOfOrderAck(stream_id, sequence);
@ -815,13 +815,13 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
} }
case OP_SessionStatRequest: case OP_SessionStatRequest:
{ {
auto request = p.GetSerialize<ReliableStreamSessionStatRequest>(0); auto request = p.GetSerialize<DaybreakSessionStatRequest>(0);
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(request.packets_sent); m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(request.packets_sent);
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(request.packets_recv); m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(request.packets_recv);
m_stats.sync_sent_packets = m_stats.sent_packets; m_stats.sync_sent_packets = m_stats.sent_packets;
m_stats.sync_recv_packets = m_stats.recv_packets; m_stats.sync_recv_packets = m_stats.recv_packets;
ReliableStreamSessionStatResponse response; DaybreakSessionStatResponse response;
response.zero = 0; response.zero = 0;
response.opcode = OP_SessionStatResponse; response.opcode = OP_SessionStatResponse;
response.timestamp = request.timestamp; response.timestamp = request.timestamp;
@ -836,7 +836,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
break; break;
} }
case OP_SessionStatResponse: { case OP_SessionStatResponse: {
auto response = p.GetSerialize<ReliableStreamSessionStatResponse>(0); auto response = p.GetSerialize<DaybreakSessionStatResponse>(0);
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(response.server_sent); m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(response.server_sent);
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(response.server_recv); m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(response.server_recv);
m_stats.sync_sent_packets = m_stats.sent_packets; m_stats.sync_sent_packets = m_stats.sent_packets;
@ -858,7 +858,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
} }
} }
bool EQ::Net::ReliableStreamConnection::ValidateCRC(Packet &p) bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
{ {
if (m_crc_bytes == 0U) { if (m_crc_bytes == 0U) {
return true; return true;
@ -892,7 +892,7 @@ bool EQ::Net::ReliableStreamConnection::ValidateCRC(Packet &p)
return false; return false;
} }
void EQ::Net::ReliableStreamConnection::AppendCRC(Packet &p) void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
{ {
if (m_crc_bytes == 0U) { if (m_crc_bytes == 0U) {
return; return;
@ -911,7 +911,7 @@ void EQ::Net::ReliableStreamConnection::AppendCRC(Packet &p)
} }
} }
void EQ::Net::ReliableStreamConnection::ChangeStatus(DbProtocolStatus new_status) void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
{ {
if (m_owner->m_on_connection_state_change) { if (m_owner->m_on_connection_state_change) {
if (auto self = m_self.lock()) { if (auto self = m_self.lock()) {
@ -922,7 +922,7 @@ void EQ::Net::ReliableStreamConnection::ChangeStatus(DbProtocolStatus new_status
m_status = new_status; m_status = new_status;
} }
bool EQ::Net::ReliableStreamConnection::PacketCanBeEncoded(Packet &p) const bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
{ {
if (p.Length() < 2) { if (p.Length() < 2) {
return false; return false;
@ -941,7 +941,7 @@ bool EQ::Net::ReliableStreamConnection::PacketCanBeEncoded(Packet &p) const
return true; return true;
} }
void EQ::Net::ReliableStreamConnection::Decode(Packet &p, size_t offset, size_t length) void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length)
{ {
int key = m_encode_key; int key = m_encode_key;
char *buffer = (char*)p.Data() + offset; char *buffer = (char*)p.Data() + offset;
@ -961,7 +961,7 @@ void EQ::Net::ReliableStreamConnection::Decode(Packet &p, size_t offset, size_t
} }
} }
void EQ::Net::ReliableStreamConnection::Encode(Packet &p, size_t offset, size_t length) void EQ::Net::DaybreakConnection::Encode(Packet &p, size_t offset, size_t length)
{ {
int key = m_encode_key; int key = m_encode_key;
char *buffer = (char*)p.Data() + offset; char *buffer = (char*)p.Data() + offset;
@ -1050,7 +1050,7 @@ uint32_t Deflate(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t out_
} }
} }
void EQ::Net::ReliableStreamConnection::Decompress(Packet &p, size_t offset, size_t length) void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t length)
{ {
if (length < 2) { if (length < 2) {
return; return;
@ -1075,7 +1075,7 @@ void EQ::Net::ReliableStreamConnection::Decompress(Packet &p, size_t offset, siz
p.PutData(offset, new_buffer, new_length); p.PutData(offset, new_buffer, new_length);
} }
void EQ::Net::ReliableStreamConnection::Compress(Packet &p, size_t offset, size_t length) void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t length)
{ {
static thread_local uint8_t new_buffer[2048] = { 0 }; static thread_local uint8_t new_buffer[2048] = { 0 };
uint8_t *buffer = (uint8_t*)p.Data() + offset; uint8_t *buffer = (uint8_t*)p.Data() + offset;
@ -1097,14 +1097,14 @@ void EQ::Net::ReliableStreamConnection::Compress(Packet &p, size_t offset, size_
p.PutData(offset, new_buffer, new_length); p.PutData(offset, new_buffer, new_length);
} }
void EQ::Net::ReliableStreamConnection::ProcessResend() void EQ::Net::DaybreakConnection::ProcessResend()
{ {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
ProcessResend(i); ProcessResend(i);
} }
} }
void EQ::Net::ReliableStreamConnection::ProcessResend(int stream) void EQ::Net::DaybreakConnection::ProcessResend(int stream)
{ {
if (m_status == DbProtocolStatus::StatusDisconnected) { if (m_status == DbProtocolStatus::StatusDisconnected) {
return; return;
@ -1127,37 +1127,16 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - first_packet.first_sent).count(); auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - first_packet.first_sent).count();
if (time_since_first_sent >= m_owner->m_options.resend_timeout) { if (time_since_first_sent >= m_owner->m_options.resend_timeout) {
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
auto first_sent_ms = std::chrono::duration_cast<std::chrono::milliseconds>(first_packet.first_sent.time_since_epoch()).count();
LogNetClient(
"Closing connection for m_endpoint [{}] m_port [{}] time_since_first_sent [{}] >= m_owner->m_options.resend_timeout [{}] now [{}] first_packet.first_sent [{}]",
m_endpoint,
m_port,
time_since_first_sent,
m_owner->m_options.resend_timeout,
now_ms,
first_sent_ms
);
Close(); Close();
return; return;
} }
if (m_last_ack - now > std::chrono::milliseconds(1000)) {
LogNetClient(
"Resetting m_acked_since_last_resend flag for m_endpoint [{}] m_port [{}]",
m_endpoint,
m_port
);
m_acked_since_last_resend = true;
}
// make sure that the first_packet in the list first_sent time is within the resend_delay and now // make sure that the first_packet in the list first_sent time is within the resend_delay and now
// if it is not, then we need to resend all packets in the list // if it is not, then we need to resend all packets in the list
if (time_since_first_sent <= first_packet.resend_delay && !m_acked_since_last_resend) { if (time_since_first_sent <= first_packet.resend_delay && !m_acked_since_last_resend) {
LogNetClientDetail( LogNetClient(
"Not resending packets for m_endpoint [{}] m_port [{}] packets [{}] time_first_sent [{}] resend_delay [{}] m_acked_since_last_resend [{}]", "Not resending packets for stream [{}] packets [{}] time_first_sent [{}] resend_delay [{}] m_acked_since_last_resend [{}]",
m_endpoint, stream,
m_port,
s->sent_packets.size(), s->sent_packets.size(),
time_since_first_sent, time_since_first_sent,
first_packet.resend_delay, first_packet.resend_delay,
@ -1167,16 +1146,15 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
} }
} }
if (EQEmuLogSys::Instance()->IsLogEnabled(Logs::General, Logs::NetClient)) { if (LogSys.IsLogEnabled(Logs::Detail, Logs::Netcode)) {
size_t total_size = 0; size_t total_size = 0;
for (auto &e: s->sent_packets) { for (auto &e: s->sent_packets) {
total_size += e.second.packet.Length(); total_size += e.second.packet.Length();
} }
LogNetClientDetail( LogNetClient(
"Resending packets for m_endpoint [{}] m_port [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]", "Resending packets for stream [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
m_endpoint, stream,
m_port,
s->sent_packets.size(), s->sent_packets.size(),
total_size, total_size,
m_acked_since_last_resend m_acked_since_last_resend
@ -1187,12 +1165,9 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
if (m_resend_packets_sent >= MAX_CLIENT_RECV_PACKETS_PER_WINDOW || if (m_resend_packets_sent >= MAX_CLIENT_RECV_PACKETS_PER_WINDOW ||
m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) { m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) {
LogNetClient( LogNetClient(
"Stopping resend because we hit thresholds for m_endpoint [{}] m_port [{}] m_resend_packets_sent [{}] max [{}] in_queue [{}] m_resend_bytes_sent [{}] max [{}]", "Stopping resend because we hit thresholds m_resend_packets_sent [{}] max [{}] m_resend_bytes_sent [{}] max [{}]",
m_endpoint,
m_port,
m_resend_packets_sent, m_resend_packets_sent,
MAX_CLIENT_RECV_PACKETS_PER_WINDOW, MAX_CLIENT_RECV_PACKETS_PER_WINDOW,
s->sent_packets.size(),
m_resend_bytes_sent, m_resend_bytes_sent,
MAX_CLIENT_RECV_BYTES_PER_WINDOW MAX_CLIENT_RECV_BYTES_PER_WINDOW
); );
@ -1201,7 +1176,7 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
auto &sp = e.second; auto &sp = e.second;
auto &p = sp.packet; auto &p = sp.packet;
if (p.Length() >= ReliableStreamHeader::size()) { if (p.Length() >= DaybreakHeader::size()) {
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) { if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
m_stats.resent_fragments++; m_stats.resent_fragments++;
} }
@ -1229,11 +1204,11 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
} }
m_acked_since_last_resend = false; m_acked_since_last_resend = false;
m_last_ack = now;
} }
void EQ::Net::ReliableStreamConnection::Ack(int stream, uint16_t seq) void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
{ {
auto now = Clock::now(); auto now = Clock::now();
auto s = &m_streams[stream]; auto s = &m_streams[stream];
auto iter = s->sent_packets.begin(); auto iter = s->sent_packets.begin();
@ -1249,17 +1224,15 @@ void EQ::Net::ReliableStreamConnection::Ack(int stream, uint16_t seq)
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3; m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
iter = s->sent_packets.erase(iter); iter = s->sent_packets.erase(iter);
m_acked_since_last_resend = true;
} }
else { else {
++iter; ++iter;
} }
} }
m_acked_since_last_resend = true;
m_last_ack = now;
} }
void EQ::Net::ReliableStreamConnection::OutOfOrderAck(int stream, uint16_t seq) void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
{ {
auto now = Clock::now(); auto now = Clock::now();
auto s = &m_streams[stream]; auto s = &m_streams[stream];
@ -1274,20 +1247,17 @@ void EQ::Net::ReliableStreamConnection::OutOfOrderAck(int stream, uint16_t seq)
s->sent_packets.erase(iter); s->sent_packets.erase(iter);
} }
m_acked_since_last_resend = true;
m_last_ack = now;
} }
void EQ::Net::ReliableStreamConnection::UpdateDataBudget(double budget_add) void EQ::Net::DaybreakConnection::UpdateDataBudget(double budget_add)
{ {
auto outgoing_data_rate = m_owner->m_options.outgoing_data_rate; auto outgoing_data_rate = m_owner->m_options.outgoing_data_rate;
m_outgoing_budget = EQ::ClampUpper(m_outgoing_budget + budget_add, outgoing_data_rate); m_outgoing_budget = EQ::ClampUpper(m_outgoing_budget + budget_add, outgoing_data_rate);
} }
void EQ::Net::ReliableStreamConnection::SendAck(int stream_id, uint16_t seq) void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
{ {
ReliableStreamReliableHeader ack; DaybreakReliableHeader ack;
ack.zero = 0; ack.zero = 0;
ack.opcode = OP_Ack + stream_id; ack.opcode = OP_Ack + stream_id;
ack.sequence = HostToNetwork(seq); ack.sequence = HostToNetwork(seq);
@ -1298,9 +1268,9 @@ void EQ::Net::ReliableStreamConnection::SendAck(int stream_id, uint16_t seq)
InternalBufferedSend(p); InternalBufferedSend(p);
} }
void EQ::Net::ReliableStreamConnection::SendOutOfOrderAck(int stream_id, uint16_t seq) void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
{ {
ReliableStreamReliableHeader ack; DaybreakReliableHeader ack;
ack.zero = 0; ack.zero = 0;
ack.opcode = OP_OutOfOrderAck + stream_id; ack.opcode = OP_OutOfOrderAck + stream_id;
ack.sequence = HostToNetwork(seq); ack.sequence = HostToNetwork(seq);
@ -1311,9 +1281,9 @@ void EQ::Net::ReliableStreamConnection::SendOutOfOrderAck(int stream_id, uint16_
InternalBufferedSend(p); InternalBufferedSend(p);
} }
void EQ::Net::ReliableStreamConnection::SendDisconnect() void EQ::Net::DaybreakConnection::SendDisconnect()
{ {
ReliableStreamDisconnect disconnect; DaybreakDisconnect disconnect;
disconnect.zero = 0; disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect; disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code); disconnect.connect_code = HostToNetwork(m_connect_code);
@ -1322,7 +1292,7 @@ void EQ::Net::ReliableStreamConnection::SendDisconnect()
InternalSend(out); InternalSend(out);
} }
void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p) void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
{ {
if (p.Length() > 0xFFU) { if (p.Length() > 0xFFU) {
FlushBuffer(); FlushBuffer();
@ -1331,7 +1301,7 @@ void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
} }
//we could add this packet to a combined //we could add this packet to a combined
size_t raw_size = ReliableStreamHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length(); size_t raw_size = DaybreakHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
if (raw_size > m_max_packet_size) { if (raw_size > m_max_packet_size) {
FlushBuffer(); FlushBuffer();
} }
@ -1346,9 +1316,9 @@ void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
} }
} }
void EQ::Net::ReliableStreamConnection::SendConnect() void EQ::Net::DaybreakConnection::SendConnect()
{ {
ReliableStreamConnect connect; DaybreakConnect connect;
connect.zero = 0; connect.zero = 0;
connect.opcode = OP_SessionRequest; connect.opcode = OP_SessionRequest;
connect.protocol_version = HostToNetwork(3U); connect.protocol_version = HostToNetwork(3U);
@ -1361,9 +1331,9 @@ void EQ::Net::ReliableStreamConnection::SendConnect()
InternalSend(p); InternalSend(p);
} }
void EQ::Net::ReliableStreamConnection::SendKeepAlive() void EQ::Net::DaybreakConnection::SendKeepAlive()
{ {
ReliableStreamHeader keep_alive; DaybreakHeader keep_alive;
keep_alive.zero = 0; keep_alive.zero = 0;
keep_alive.opcode = OP_KeepAlive; keep_alive.opcode = OP_KeepAlive;
@ -1373,7 +1343,7 @@ void EQ::Net::ReliableStreamConnection::SendKeepAlive()
InternalSend(p); InternalSend(p);
} }
void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) { void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
if (m_owner->m_options.outgoing_data_rate > 0.0) { if (m_owner->m_options.outgoing_data_rate > 0.0) {
auto new_budget = m_outgoing_budget - (p.Length() / 1024.0); auto new_budget = m_outgoing_budget - (p.Length() / 1024.0);
if (new_budget <= 0.0) { if (new_budget <= 0.0) {
@ -1409,14 +1379,14 @@ void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) {
switch (m_encode_passe) { switch (m_encode_passe) {
case EncodeCompression: case EncodeCompression:
if (out.GetInt8(0) == 0) { if (out.GetInt8(0) == 0) {
Compress(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size()); Compress(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
} else { } else {
Compress(out, 1, out.Length() - 1); Compress(out, 1, out.Length() - 1);
} }
break; break;
case EncodeXOR: case EncodeXOR:
if (out.GetInt8(0) == 0) { if (out.GetInt8(0) == 0) {
Encode(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size()); Encode(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
} else { } else {
Encode(out, 1, out.Length() - 1); Encode(out, 1, out.Length() - 1);
} }
@ -1466,7 +1436,7 @@ void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) {
} }
} }
void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable) void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
{ {
if (!reliable) { if (!reliable) {
auto max_raw_size = 0xFFU - m_crc_bytes; auto max_raw_size = 0xFFU - m_crc_bytes;
@ -1480,23 +1450,23 @@ void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int strea
} }
auto stream = &m_streams[stream_id]; auto stream = &m_streams[stream_id];
auto max_raw_size = m_max_packet_size - m_crc_bytes - ReliableStreamReliableHeader::size() - 1; // -1 for compress flag auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
size_t length = p.Length(); size_t length = p.Length();
if (length > max_raw_size) { if (length > max_raw_size) {
ReliableStreamReliableFragmentHeader first_header; DaybreakReliableFragmentHeader first_header;
first_header.reliable.zero = 0; first_header.reliable.zero = 0;
first_header.reliable.opcode = OP_Fragment + stream_id; first_header.reliable.opcode = OP_Fragment + stream_id;
first_header.reliable.sequence = HostToNetwork(stream->sequence_out); first_header.reliable.sequence = HostToNetwork(stream->sequence_out);
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length); first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
size_t used = 0; size_t used = 0;
size_t sublen = m_max_packet_size - m_crc_bytes - ReliableStreamReliableFragmentHeader::size() - 1; // -1 for compress flag size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size() - 1; // -1 for compress flag
DynamicPacket first_packet; DynamicPacket first_packet;
first_packet.PutSerialize(0, first_header); first_packet.PutSerialize(0, first_header);
first_packet.PutData(ReliableStreamReliableFragmentHeader::size(), (char*)p.Data() + used, sublen); first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
used += sublen; used += sublen;
ReliableStreamSentPacket sent; DaybreakSentPacket sent;
sent.packet.PutPacket(0, first_packet); sent.packet.PutPacket(0, first_packet);
sent.last_sent = Clock::now(); sent.last_sent = Clock::now();
sent.first_sent = Clock::now(); sent.first_sent = Clock::now();
@ -1513,22 +1483,22 @@ void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int strea
while (used < length) { while (used < length) {
auto left = length - used; auto left = length - used;
DynamicPacket packet; DynamicPacket packet;
ReliableStreamReliableHeader header; DaybreakReliableHeader header;
header.zero = 0; header.zero = 0;
header.opcode = OP_Fragment + stream_id; header.opcode = OP_Fragment + stream_id;
header.sequence = HostToNetwork(stream->sequence_out); header.sequence = HostToNetwork(stream->sequence_out);
packet.PutSerialize(0, header); packet.PutSerialize(0, header);
if (left > max_raw_size) { if (left > max_raw_size) {
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, max_raw_size); packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
used += max_raw_size; used += max_raw_size;
} }
else { else {
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, left); packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, left);
used += left; used += left;
} }
ReliableStreamSentPacket sent; DaybreakSentPacket sent;
sent.packet.PutPacket(0, packet); sent.packet.PutPacket(0, packet);
sent.last_sent = Clock::now(); sent.last_sent = Clock::now();
sent.first_sent = Clock::now(); sent.first_sent = Clock::now();
@ -1545,14 +1515,14 @@ void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int strea
} }
else { else {
DynamicPacket packet; DynamicPacket packet;
ReliableStreamReliableHeader header; DaybreakReliableHeader header;
header.zero = 0; header.zero = 0;
header.opcode = OP_Packet + stream_id; header.opcode = OP_Packet + stream_id;
header.sequence = HostToNetwork(stream->sequence_out); header.sequence = HostToNetwork(stream->sequence_out);
packet.PutSerialize(0, header); packet.PutSerialize(0, header);
packet.PutPacket(ReliableStreamReliableHeader::size(), p); packet.PutPacket(DaybreakReliableHeader::size(), p);
ReliableStreamSentPacket sent; DaybreakSentPacket sent;
sent.packet.PutPacket(0, packet); sent.packet.PutPacket(0, packet);
sent.last_sent = Clock::now(); sent.last_sent = Clock::now();
sent.first_sent = Clock::now(); sent.first_sent = Clock::now();
@ -1568,7 +1538,7 @@ void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int strea
} }
} }
void EQ::Net::ReliableStreamConnection::FlushBuffer() void EQ::Net::DaybreakConnection::FlushBuffer()
{ {
if (m_buffered_packets.empty()) { if (m_buffered_packets.empty()) {
return; return;
@ -1595,7 +1565,7 @@ void EQ::Net::ReliableStreamConnection::FlushBuffer()
m_buffered_packets_length = 0; m_buffered_packets_length = 0;
} }
EQ::Net::SequenceOrder EQ::Net::ReliableStreamConnection::CompareSequence(uint16_t expected, uint16_t actual) const EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t expected, uint16_t actual) const
{ {
int diff = (int)actual - (int)expected; int diff = (int)actual - (int)expected;

View File

@ -2,8 +2,8 @@
#include "../random.h" #include "../random.h"
#include "packet.h" #include "packet.h"
#include "reliable_stream_structs.h" #include "daybreak_structs.h"
#include "reliable_stream_pooling.h" #include "daybreak_pooling.h"
#include <uv.h> #include <uv.h>
#include <chrono> #include <chrono>
#include <functional> #include <functional>
@ -16,7 +16,7 @@ namespace EQ
{ {
namespace Net namespace Net
{ {
enum ReliableStreamProtocolOpcode enum DaybreakProtocolOpcode
{ {
OP_Padding = 0x00, OP_Padding = 0x00,
OP_SessionRequest = 0x01, OP_SessionRequest = 0x01,
@ -55,7 +55,7 @@ namespace EQ
StatusDisconnected StatusDisconnected
}; };
enum ReliableStreamEncodeType enum DaybreakEncodeType
{ {
EncodeNone = 0, EncodeNone = 0,
EncodeCompression = 1, EncodeCompression = 1,
@ -72,9 +72,9 @@ namespace EQ
typedef std::chrono::steady_clock::time_point Timestamp; typedef std::chrono::steady_clock::time_point Timestamp;
typedef std::chrono::steady_clock Clock; typedef std::chrono::steady_clock Clock;
struct ReliableStreamConnectionStats struct DaybreakConnectionStats
{ {
ReliableStreamConnectionStats() { DaybreakConnectionStats() {
recv_bytes = 0; recv_bytes = 0;
sent_bytes = 0; sent_bytes = 0;
recv_packets = 0; recv_packets = 0;
@ -134,14 +134,14 @@ namespace EQ
uint64_t bytes_before_encode; uint64_t bytes_before_encode;
}; };
class ReliableStreamConnectionManager; class DaybreakConnectionManager;
class ReliableStreamConnection; class DaybreakConnection;
class ReliableStreamConnection class DaybreakConnection
{ {
public: public:
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port); DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port); DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
~ReliableStreamConnection(); ~DaybreakConnection();
const std::string& RemoteEndpoint() const { return m_endpoint; } const std::string& RemoteEndpoint() const { return m_endpoint; }
int RemotePort() const { return m_port; } int RemotePort() const { return m_port; }
@ -151,23 +151,23 @@ namespace EQ
void QueuePacket(Packet &p, int stream); void QueuePacket(Packet &p, int stream);
void QueuePacket(Packet &p, int stream, bool reliable); void QueuePacket(Packet &p, int stream, bool reliable);
ReliableStreamConnectionStats GetStats(); DaybreakConnectionStats GetStats();
void ResetStats(); void ResetStats();
size_t GetRollingPing() const { return m_rolling_ping; } size_t GetRollingPing() const { return m_rolling_ping; }
DbProtocolStatus GetStatus() const { return m_status; } DbProtocolStatus GetStatus() const { return m_status; }
const ReliableStreamEncodeType* GetEncodePasses() const { return m_encode_passes; } const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
const ReliableStreamConnectionManager* GetManager() const { return m_owner; } const DaybreakConnectionManager* GetManager() const { return m_owner; }
ReliableStreamConnectionManager* GetManager() { return m_owner; } DaybreakConnectionManager* GetManager() { return m_owner; }
private: private:
ReliableStreamConnectionManager *m_owner; DaybreakConnectionManager *m_owner;
std::string m_endpoint; std::string m_endpoint;
int m_port; int m_port;
uint32_t m_connect_code; uint32_t m_connect_code;
uint32_t m_encode_key; uint32_t m_encode_key;
uint32_t m_max_packet_size; uint32_t m_max_packet_size;
uint32_t m_crc_bytes; uint32_t m_crc_bytes;
ReliableStreamEncodeType m_encode_passes[2]; DaybreakEncodeType m_encode_passes[2];
Timestamp m_last_send; Timestamp m_last_send;
Timestamp m_last_recv; Timestamp m_last_recv;
@ -176,7 +176,7 @@ namespace EQ
std::list<DynamicPacket> m_buffered_packets; std::list<DynamicPacket> m_buffered_packets;
size_t m_buffered_packets_length; size_t m_buffered_packets_length;
std::unique_ptr<char[]> m_combined; std::unique_ptr<char[]> m_combined;
ReliableStreamConnectionStats m_stats; DaybreakConnectionStats m_stats;
Timestamp m_last_session_stats; Timestamp m_last_session_stats;
size_t m_rolling_ping; size_t m_rolling_ping;
Timestamp m_close_time; Timestamp m_close_time;
@ -186,9 +186,8 @@ namespace EQ
size_t m_resend_packets_sent = 0; size_t m_resend_packets_sent = 0;
size_t m_resend_bytes_sent = 0; size_t m_resend_bytes_sent = 0;
bool m_acked_since_last_resend = false; bool m_acked_since_last_resend = false;
Timestamp m_last_ack;
struct ReliableStreamSentPacket struct DaybreakSentPacket
{ {
DynamicPacket packet; DynamicPacket packet;
Timestamp last_sent; Timestamp last_sent;
@ -197,9 +196,9 @@ namespace EQ
size_t resend_delay; size_t resend_delay;
}; };
struct ReliableStream struct DaybreakStream
{ {
ReliableStream() { DaybreakStream() {
sequence_in = 0; sequence_in = 0;
sequence_out = 0; sequence_out = 0;
fragment_current_bytes = 0; fragment_current_bytes = 0;
@ -214,11 +213,11 @@ namespace EQ
uint32_t fragment_current_bytes; uint32_t fragment_current_bytes;
uint32_t fragment_total_bytes; uint32_t fragment_total_bytes;
std::map<uint16_t, ReliableStreamSentPacket> sent_packets; std::map<uint16_t, DaybreakSentPacket> sent_packets;
}; };
ReliableStream m_streams[4]; DaybreakStream m_streams[4];
std::weak_ptr<ReliableStreamConnection> m_self; std::weak_ptr<DaybreakConnection> m_self;
void Process(); void Process();
void ProcessPacket(Packet &p); void ProcessPacket(Packet &p);
@ -251,12 +250,12 @@ namespace EQ
void FlushBuffer(); void FlushBuffer();
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const; SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
friend class ReliableStreamConnectionManager; friend class DaybreakConnectionManager;
}; };
struct ReliableStreamConnectionManagerOptions struct DaybreakConnectionManagerOptions
{ {
ReliableStreamConnectionManagerOptions() { DaybreakConnectionManagerOptions() {
max_connection_count = 0; max_connection_count = 0;
keepalive_delay_ms = 9000; keepalive_delay_ms = 9000;
resend_delay_ms = 30; resend_delay_ms = 30;
@ -268,8 +267,8 @@ namespace EQ
connect_stale_ms = 5000; connect_stale_ms = 5000;
crc_length = 2; crc_length = 2;
max_packet_size = 512; max_packet_size = 512;
encode_passes[0] = ReliableStreamEncodeType::EncodeNone; encode_passes[0] = DaybreakEncodeType::EncodeNone;
encode_passes[1] = ReliableStreamEncodeType::EncodeNone; encode_passes[1] = DaybreakEncodeType::EncodeNone;
port = 0; port = 0;
hold_size = 512; hold_size = 512;
hold_length_ms = 50; hold_length_ms = 50;
@ -299,28 +298,28 @@ namespace EQ
double tic_rate_hertz; double tic_rate_hertz;
size_t resend_timeout; size_t resend_timeout;
size_t connection_close_time; size_t connection_close_time;
ReliableStreamEncodeType encode_passes[2]; DaybreakEncodeType encode_passes[2];
int port; int port;
double outgoing_data_rate; double outgoing_data_rate;
}; };
class ReliableStreamConnectionManager class DaybreakConnectionManager
{ {
public: public:
ReliableStreamConnectionManager(); DaybreakConnectionManager();
ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts); DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts);
~ReliableStreamConnectionManager(); ~DaybreakConnectionManager();
void Connect(const std::string &addr, int port); void Connect(const std::string &addr, int port);
void Process(); void Process();
void UpdateDataBudget(); void UpdateDataBudget();
void ProcessResend(); void ProcessResend();
void OnNewConnection(std::function<void(std::shared_ptr<ReliableStreamConnection>)> func) { m_on_new_connection = func; } void OnNewConnection(std::function<void(std::shared_ptr<DaybreakConnection>)> func) { m_on_new_connection = func; }
void OnConnectionStateChange(std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; } void OnConnectionStateChange(std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
void OnPacketRecv(std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet &)> func) { m_on_packet_recv = func; } void OnPacketRecv(std::function<void(std::shared_ptr<DaybreakConnection>, const Packet &)> func) { m_on_packet_recv = func; }
void OnErrorMessage(std::function<void(const std::string&)> func) { m_on_error_message = func; } void OnErrorMessage(std::function<void(const std::string&)> func) { m_on_error_message = func; }
ReliableStreamConnectionManagerOptions& GetOptions() { return m_options; } DaybreakConnectionManagerOptions& GetOptions() { return m_options; }
private: private:
void Attach(uv_loop_t *loop); void Attach(uv_loop_t *loop);
void Detach(); void Detach();
@ -329,18 +328,18 @@ namespace EQ
uv_timer_t m_timer; uv_timer_t m_timer;
uv_udp_t m_socket; uv_udp_t m_socket;
uv_loop_t *m_attached; uv_loop_t *m_attached;
ReliableStreamConnectionManagerOptions m_options; DaybreakConnectionManagerOptions m_options;
std::function<void(std::shared_ptr<ReliableStreamConnection>)> m_on_new_connection; std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change; std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet&)> m_on_packet_recv; std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
std::function<void(const std::string&)> m_on_error_message; std::function<void(const std::string&)> m_on_error_message;
std::map<std::pair<std::string, int>, std::shared_ptr<ReliableStreamConnection>> m_connections; std::map<std::pair<std::string, int>, std::shared_ptr<DaybreakConnection>> m_connections;
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size); void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
std::shared_ptr<ReliableStreamConnection> FindConnectionByEndpoint(std::string addr, int port); std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
void SendDisconnect(const std::string &addr, int port); void SendDisconnect(const std::string &addr, int port);
friend class ReliableStreamConnection; friend class DaybreakConnection;
}; };
} }
} }

View File

@ -8,7 +8,7 @@ namespace EQ
{ {
namespace Net namespace Net
{ {
struct ReliableStreamHeader struct DaybreakHeader
{ {
static size_t size() { return 2; } static size_t size() { return 2; }
uint8_t zero; uint8_t zero;
@ -22,7 +22,7 @@ namespace EQ
} }
}; };
struct ReliableStreamConnect struct DaybreakConnect
{ {
static size_t size() { return 14; } static size_t size() { return 14; }
uint8_t zero; uint8_t zero;
@ -42,7 +42,7 @@ namespace EQ
} }
}; };
struct ReliableStreamConnectReply struct DaybreakConnectReply
{ {
static size_t size() { return 17; } static size_t size() { return 17; }
uint8_t zero; uint8_t zero;
@ -68,7 +68,7 @@ namespace EQ
} }
}; };
struct ReliableStreamDisconnect struct DaybreakDisconnect
{ {
static size_t size() { return 8; } static size_t size() { return 8; }
uint8_t zero; uint8_t zero;
@ -84,7 +84,7 @@ namespace EQ
} }
}; };
struct ReliableStreamReliableHeader struct DaybreakReliableHeader
{ {
static size_t size() { return 4; } static size_t size() { return 4; }
uint8_t zero; uint8_t zero;
@ -100,10 +100,10 @@ namespace EQ
} }
}; };
struct ReliableStreamReliableFragmentHeader struct DaybreakReliableFragmentHeader
{ {
static size_t size() { return 4 + ReliableStreamReliableHeader::size(); } static size_t size() { return 4 + DaybreakReliableHeader::size(); }
ReliableStreamReliableHeader reliable; DaybreakReliableHeader reliable;
uint32_t total_size; uint32_t total_size;
template <class Archive> template <class Archive>
@ -114,7 +114,7 @@ namespace EQ
} }
}; };
struct ReliableStreamSessionStatRequest struct DaybreakSessionStatRequest
{ {
static size_t size() { return 40; } static size_t size() { return 40; }
uint8_t zero; uint8_t zero;
@ -144,7 +144,7 @@ namespace EQ
} }
}; };
struct ReliableStreamSessionStatResponse struct DaybreakSessionStatResponse
{ {
static size_t size() { return 40; } static size_t size() { return 40; }
uint8_t zero; uint8_t zero;

View File

@ -1,11 +1,11 @@
#include "eqstream.h" #include "eqstream.h"
#include "../eqemu_logsys.h" #include "../eqemu_logsys.h"
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_reliable_stream(options.reliable_stream_options) EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
{ {
m_reliable_stream.OnNewConnection(std::bind(&EQStreamManager::ReliableStreamNewConnection, this, std::placeholders::_1)); m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
m_reliable_stream.OnConnectionStateChange(std::bind(&EQStreamManager::ReliableStreamConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_reliable_stream.OnPacketRecv(std::bind(&EQStreamManager::ReliableStreamPacketRecv, this, std::placeholders::_1, std::placeholders::_2)); m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
} }
EQ::Net::EQStreamManager::~EQStreamManager() EQ::Net::EQStreamManager::~EQStreamManager()
@ -15,11 +15,11 @@ EQ::Net::EQStreamManager::~EQStreamManager()
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options) void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
{ {
m_options = options; m_options = options;
auto &opts = m_reliable_stream.GetOptions(); auto &opts = m_daybreak.GetOptions();
opts = options.reliable_stream_options; opts = options.daybreak_options;
} }
void EQ::Net::EQStreamManager::ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection) void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
{ {
std::shared_ptr<EQStream> stream(new EQStream(this, connection)); std::shared_ptr<EQStream> stream(new EQStream(this, connection));
m_streams.emplace(std::make_pair(connection, stream)); m_streams.emplace(std::make_pair(connection, stream));
@ -28,7 +28,7 @@ void EQ::Net::EQStreamManager::ReliableStreamNewConnection(std::shared_ptr<Relia
} }
} }
void EQ::Net::EQStreamManager::ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to) void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
{ {
auto iter = m_streams.find(connection); auto iter = m_streams.find(connection);
if (iter != m_streams.end()) { if (iter != m_streams.end()) {
@ -42,7 +42,7 @@ void EQ::Net::EQStreamManager::ReliableStreamConnectionStateChange(std::shared_p
} }
} }
void EQ::Net::EQStreamManager::ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p) void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
{ {
auto iter = m_streams.find(connection); auto iter = m_streams.find(connection);
if (iter != m_streams.end()) { if (iter != m_streams.end()) {
@ -53,7 +53,7 @@ void EQ::Net::EQStreamManager::ReliableStreamPacketRecv(std::shared_ptr<Reliable
} }
} }
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<ReliableStreamConnection> connection) EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<DaybreakConnection> connection)
{ {
m_owner = owner; m_owner = owner;
m_connection = connection; m_connection = connection;
@ -71,7 +71,7 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
OpcodeManager::EmuToName(p->GetOpcode()), OpcodeManager::EmuToName(p->GetOpcode()),
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()), (*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
p->Size(), p->Size(),
(EQEmuLogSys::Instance()->IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "") (LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
); );
if (m_opcode_manager && *m_opcode_manager) { if (m_opcode_manager && *m_opcode_manager) {
@ -235,7 +235,7 @@ EQStreamState EQ::Net::EQStream::GetState() {
EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
{ {
Stats ret; Stats ret;
ret.ReliableStreamStats = m_connection->GetStats(); ret.DaybreakStats = m_connection->GetStats();
for (int i = 0; i < _maxEmuOpcode; ++i) { for (int i = 0; i < _maxEmuOpcode; ++i) {
ret.RecvCount[i] = 0; ret.RecvCount[i] = 0;

View File

@ -3,7 +3,7 @@
#include "../eq_packet.h" #include "../eq_packet.h"
#include "../eq_stream_intf.h" #include "../eq_stream_intf.h"
#include "../opcodemgr.h" #include "../opcodemgr.h"
#include "reliable_stream_connection.h" #include "daybreak_connection.h"
#include <vector> #include <vector>
#include <deque> #include <deque>
#include <unordered_map> #include <unordered_map>
@ -23,21 +23,21 @@ namespace EQ
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; } void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; } void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
private: private:
ReliableStreamConnectionManager m_reliable_stream; DaybreakConnectionManager m_daybreak;
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection; std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change; std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
std::map<std::shared_ptr<ReliableStreamConnection>, std::shared_ptr<EQStream>> m_streams; std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
void ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection); void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
void ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to); void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
void ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p); void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
friend class EQStream; friend class EQStream;
}; };
class EQStream : public EQStreamInterface class EQStream : public EQStreamInterface
{ {
public: public:
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<ReliableStreamConnection> connection); EQStream(EQStreamManagerInterface *parent, std::shared_ptr<DaybreakConnection> connection);
~EQStream(); ~EQStream();
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true); virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
@ -67,7 +67,7 @@ namespace EQ
virtual EQStreamManagerInterface* GetManager() const; virtual EQStreamManagerInterface* GetManager() const;
private: private:
EQStreamManagerInterface *m_owner; EQStreamManagerInterface *m_owner;
std::shared_ptr<ReliableStreamConnection> m_connection; std::shared_ptr<DaybreakConnection> m_connection;
OpcodeManager **m_opcode_manager; OpcodeManager **m_opcode_manager;
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue; std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
std::unordered_map<int, int> m_packet_recv_count; std::unordered_map<int, int> m_packet_recv_count;

View File

@ -319,7 +319,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
size_t message_len = length; size_t message_len = length;
EQ::Net::StaticPacket packet(&data[0], message_len); EQ::Net::StaticPacket packet(&data[0], message_len);
const auto is_detail_enabled = EQEmuLogSys::Instance()->IsLogEnabled(Logs::Detail, Logs::PacketServerToServer); const auto is_detail_enabled = LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
if (opcode != ServerOP_KeepAlive || is_detail_enabled) { if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
LogPacketServerToServer( LogPacketServerToServer(
"[{:#06x}] Size [{}] {}", "[{:#06x}] Size [{}] {}",

View File

@ -78,7 +78,7 @@ namespace RoF
{ {
//create our opcode manager if we havent already //create our opcode manager if we havent already
if (opcodes == nullptr) { if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//load up the opcode manager. //load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches... //TODO: figure out how to support shared memory with multiple patches...
@ -117,7 +117,7 @@ namespace RoF
//we need to go to every stream and replace it's manager. //we need to go to every stream and replace it's manager.
if (opcodes != nullptr) { if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
if (!opcodes->ReloadOpcodes(opfile.c_str())) { if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name); LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return; return;

View File

@ -81,7 +81,7 @@ namespace RoF2
//create our opcode manager if we havent already //create our opcode manager if we havent already
if (opcodes == nullptr) { if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//load up the opcode manager. //load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches... //TODO: figure out how to support shared memory with multiple patches...
@ -123,7 +123,7 @@ namespace RoF2
//we need to go to every stream and replace it's manager. //we need to go to every stream and replace it's manager.
if (opcodes != nullptr) { if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
if (!opcodes->ReloadOpcodes(opfile.c_str())) { if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name); LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return; return;
@ -6481,7 +6481,7 @@ namespace RoF2
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0); hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber()); hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0; hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
if (item->EvolvingItem && packet_type != ItemPacketParcel && packet_type != ItemPacketMerchant) { if (item->EvolvingItem) {
hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword
hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
} }
@ -6500,7 +6500,6 @@ namespace RoF2
if (item->EvolvingItem > 0) { if (item->EvolvingItem > 0) {
RoF2::structs::EvolvingItem_Struct evotop; RoF2::structs::EvolvingItem_Struct evotop;
inst->CalculateEvolveProgression();
evotop.final_item_id = inst->GetEvolveFinalItemID(); evotop.final_item_id = inst->GetEvolveFinalItemID();
evotop.evolve_level = item->EvolvingLevel; evotop.evolve_level = item->EvolvingLevel;

View File

@ -72,7 +72,7 @@ namespace SoD
{ {
//create our opcode manager if we havent already //create our opcode manager if we havent already
if (opcodes == nullptr) { if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//load up the opcode manager. //load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches... //TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager(); opcodes = new RegularOpcodeManager();
@ -113,7 +113,7 @@ namespace SoD
//we need to go to every stream and replace it's manager. //we need to go to every stream and replace it's manager.
if (opcodes != nullptr) { if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
if (!opcodes->ReloadOpcodes(opfile.c_str())) { if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name); LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return; return;
@ -3966,12 +3966,12 @@ namespace SoD
SoDSlot = serverSlot - 2; SoDSlot = serverSlot - 2;
} }
else if (serverSlot <= EQ::invbag::GENERAL_BAGS_END && serverSlot >= EQ::invbag::GENERAL_BAGS_BEGIN) { else if (serverSlot <= EQ::invbag::GENERAL_BAGS_8_END && serverSlot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
SoDSlot = serverSlot - (EQ::invbag::GENERAL_BAGS_BEGIN - invbag::GENERAL_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((serverSlot - EQ::invbag::GENERAL_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT));; SoDSlot = serverSlot + 11;
} }
else if (serverSlot <= EQ::invbag::CURSOR_BAG_END && serverSlot >= EQ::invbag::CURSOR_BAG_BEGIN) { else if (serverSlot <= EQ::invbag::CURSOR_BAG_END && serverSlot >= EQ::invbag::CURSOR_BAG_BEGIN) {
SoDSlot = serverSlot - (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN); SoDSlot = serverSlot - 9;
} }
else if (serverSlot <= EQ::invslot::TRIBUTE_END && serverSlot >= EQ::invslot::TRIBUTE_BEGIN) { else if (serverSlot <= EQ::invslot::TRIBUTE_END && serverSlot >= EQ::invslot::TRIBUTE_BEGIN) {
@ -3991,7 +3991,7 @@ namespace SoD
} }
else if (serverSlot <= EQ::invbag::BANK_BAGS_END && serverSlot >= EQ::invbag::BANK_BAGS_BEGIN) { else if (serverSlot <= EQ::invbag::BANK_BAGS_END && serverSlot >= EQ::invbag::BANK_BAGS_BEGIN) {
SoDSlot = serverSlot - (EQ::invbag::BANK_BAGS_BEGIN - invbag::BANK_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((serverSlot - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT));; SoDSlot = serverSlot + 1;
} }
else if (serverSlot <= EQ::invslot::SHARED_BANK_END && serverSlot >= EQ::invslot::SHARED_BANK_BEGIN) { else if (serverSlot <= EQ::invslot::SHARED_BANK_END && serverSlot >= EQ::invslot::SHARED_BANK_BEGIN) {
@ -3999,7 +3999,7 @@ namespace SoD
} }
else if (serverSlot <= EQ::invbag::SHARED_BANK_BAGS_END && serverSlot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) { else if (serverSlot <= EQ::invbag::SHARED_BANK_BAGS_END && serverSlot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
SoDSlot = serverSlot - (EQ::invbag::SHARED_BANK_BAGS_BEGIN - invbag::SHARED_BANK_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((serverSlot - EQ::invbag::SHARED_BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); SoDSlot = serverSlot + 1;
} }
else if (serverSlot <= EQ::invslot::TRADE_END && serverSlot >= EQ::invslot::TRADE_BEGIN) { else if (serverSlot <= EQ::invslot::TRADE_END && serverSlot >= EQ::invslot::TRADE_BEGIN) {
@ -4007,7 +4007,7 @@ namespace SoD
} }
else if (serverSlot <= EQ::invbag::TRADE_BAGS_END && serverSlot >= EQ::invbag::TRADE_BAGS_BEGIN) { else if (serverSlot <= EQ::invbag::TRADE_BAGS_END && serverSlot >= EQ::invbag::TRADE_BAGS_BEGIN) {
SoDSlot = serverSlot - (EQ::invbag::TRADE_BAGS_BEGIN - invbag::TRADE_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((serverSlot - EQ::invbag::TRADE_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); SoDSlot = serverSlot;
} }
else if (serverSlot <= EQ::invslot::WORLD_END && serverSlot >= EQ::invslot::WORLD_BEGIN) { else if (serverSlot <= EQ::invslot::WORLD_END && serverSlot >= EQ::invslot::WORLD_BEGIN) {
@ -4049,11 +4049,11 @@ namespace SoD
} }
else if (sod_slot <= invbag::GENERAL_BAGS_END && sod_slot >= invbag::GENERAL_BAGS_BEGIN) { else if (sod_slot <= invbag::GENERAL_BAGS_END && sod_slot >= invbag::GENERAL_BAGS_BEGIN) {
server_slot = sod_slot + (EQ::invbag::GENERAL_BAGS_BEGIN - invbag::GENERAL_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sod_slot - invbag::GENERAL_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = sod_slot - 11;
} }
else if (sod_slot <= invbag::CURSOR_BAG_END && sod_slot >= invbag::CURSOR_BAG_BEGIN) { else if (sod_slot <= invbag::CURSOR_BAG_END && sod_slot >= invbag::CURSOR_BAG_BEGIN) {
server_slot = sod_slot + (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN); server_slot = sod_slot + 9;
} }
else if (sod_slot <= invslot::TRIBUTE_END && sod_slot >= invslot::TRIBUTE_BEGIN) { else if (sod_slot <= invslot::TRIBUTE_END && sod_slot >= invslot::TRIBUTE_BEGIN) {
@ -4073,7 +4073,7 @@ namespace SoD
} }
else if (sod_slot <= invbag::BANK_BAGS_END && sod_slot >= invbag::BANK_BAGS_BEGIN) { else if (sod_slot <= invbag::BANK_BAGS_END && sod_slot >= invbag::BANK_BAGS_BEGIN) {
server_slot = sod_slot + (EQ::invbag::BANK_BAGS_BEGIN - invbag::BANK_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sod_slot - invbag::BANK_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = sod_slot - 1;
} }
else if (sod_slot <= invslot::SHARED_BANK_END && sod_slot >= invslot::SHARED_BANK_BEGIN) { else if (sod_slot <= invslot::SHARED_BANK_END && sod_slot >= invslot::SHARED_BANK_BEGIN) {
@ -4081,7 +4081,7 @@ namespace SoD
} }
else if (sod_slot <= invbag::SHARED_BANK_BAGS_END && sod_slot >= invbag::SHARED_BANK_BAGS_BEGIN) { else if (sod_slot <= invbag::SHARED_BANK_BAGS_END && sod_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
server_slot = sod_slot + (EQ::invbag::SHARED_BANK_BAGS_BEGIN - invbag::SHARED_BANK_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sod_slot - invbag::SHARED_BANK_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = sod_slot - 1;
} }
else if (sod_slot <= invslot::TRADE_END && sod_slot >= invslot::TRADE_BEGIN) { else if (sod_slot <= invslot::TRADE_END && sod_slot >= invslot::TRADE_BEGIN) {
@ -4089,7 +4089,7 @@ namespace SoD
} }
else if (sod_slot <= invbag::TRADE_BAGS_END && sod_slot >= invbag::TRADE_BAGS_BEGIN) { else if (sod_slot <= invbag::TRADE_BAGS_END && sod_slot >= invbag::TRADE_BAGS_BEGIN) {
server_slot = sod_slot + (EQ::invbag::TRADE_BAGS_BEGIN - invbag::TRADE_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sod_slot - invbag::TRADE_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = sod_slot;
} }
else if (sod_slot <= invslot::WORLD_END && sod_slot >= invslot::WORLD_BEGIN) { else if (sod_slot <= invslot::WORLD_END && sod_slot >= invslot::WORLD_BEGIN) {

View File

@ -71,7 +71,7 @@ namespace SoF
{ {
//create our opcode manager if we havent already //create our opcode manager if we havent already
if (opcodes == nullptr) { if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//load up the opcode manager. //load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches... //TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager(); opcodes = new RegularOpcodeManager();
@ -110,7 +110,7 @@ namespace SoF
//we need to go to every stream and replace it's manager. //we need to go to every stream and replace it's manager.
if (opcodes != nullptr) { if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
if (!opcodes->ReloadOpcodes(opfile.c_str())) { if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name); LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return; return;
@ -3355,12 +3355,12 @@ namespace SoF
sof_slot = server_slot - 2; sof_slot = server_slot - 2;
} }
else if (server_slot <= EQ::invbag::GENERAL_BAGS_END && server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) { else if (server_slot <= EQ::invbag::GENERAL_BAGS_8_END && server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
sof_slot = server_slot - (EQ::invbag::GENERAL_BAGS_BEGIN - invbag::GENERAL_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::GENERAL_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT));; sof_slot = server_slot + 11;
} }
else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) { else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) {
sof_slot = server_slot - (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN); sof_slot = server_slot - 9;
} }
else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) { else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) {
@ -3380,7 +3380,7 @@ namespace SoF
} }
else if (server_slot <= EQ::invbag::BANK_BAGS_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) { else if (server_slot <= EQ::invbag::BANK_BAGS_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
sof_slot = server_slot - (EQ::invbag::BANK_BAGS_BEGIN - invbag::BANK_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); sof_slot = server_slot + 1;
} }
else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) { else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
@ -3388,7 +3388,7 @@ namespace SoF
} }
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END && server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) { else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END && server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
sof_slot = server_slot - (EQ::invbag::SHARED_BANK_BAGS_BEGIN - invbag::SHARED_BANK_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::SHARED_BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); sof_slot = server_slot + 1;
} }
else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) { else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) {
@ -3396,7 +3396,7 @@ namespace SoF
} }
else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) { else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) {
sof_slot = server_slot - (EQ::invbag::TRADE_BAGS_BEGIN - invbag::TRADE_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::TRADE_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); sof_slot = server_slot;
} }
else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) { else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) {
@ -3442,11 +3442,11 @@ namespace SoF
} }
else if (sof_slot <= invbag::GENERAL_BAGS_END && sof_slot >= invbag::GENERAL_BAGS_BEGIN) { else if (sof_slot <= invbag::GENERAL_BAGS_END && sof_slot >= invbag::GENERAL_BAGS_BEGIN) {
server_slot = sof_slot + (EQ::invbag::GENERAL_BAGS_BEGIN - invbag::GENERAL_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sof_slot - invbag::GENERAL_BAGS_BEGIN) / invbag::SLOT_COUNT));; server_slot = sof_slot - 11;
} }
else if (sof_slot <= invbag::CURSOR_BAG_END && sof_slot >= invbag::CURSOR_BAG_BEGIN) { else if (sof_slot <= invbag::CURSOR_BAG_END && sof_slot >= invbag::CURSOR_BAG_BEGIN) {
server_slot = sof_slot + (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN); server_slot = sof_slot + 9;
} }
else if (sof_slot <= invslot::TRIBUTE_END && sof_slot >= invslot::TRIBUTE_BEGIN) { else if (sof_slot <= invslot::TRIBUTE_END && sof_slot >= invslot::TRIBUTE_BEGIN) {
@ -3466,7 +3466,7 @@ namespace SoF
} }
else if (sof_slot <= invbag::BANK_BAGS_END && sof_slot >= invbag::BANK_BAGS_BEGIN) { else if (sof_slot <= invbag::BANK_BAGS_END && sof_slot >= invbag::BANK_BAGS_BEGIN) {
server_slot = sof_slot + (EQ::invbag::BANK_BAGS_BEGIN - invbag::BANK_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sof_slot - invbag::BANK_BAGS_BEGIN) / invbag::SLOT_COUNT));; server_slot = sof_slot - 1;
} }
else if (sof_slot <= invslot::SHARED_BANK_END && sof_slot >= invslot::SHARED_BANK_BEGIN) { else if (sof_slot <= invslot::SHARED_BANK_END && sof_slot >= invslot::SHARED_BANK_BEGIN) {
@ -3474,7 +3474,7 @@ namespace SoF
} }
else if (sof_slot <= invbag::SHARED_BANK_BAGS_END && sof_slot >= invbag::SHARED_BANK_BAGS_BEGIN) { else if (sof_slot <= invbag::SHARED_BANK_BAGS_END && sof_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
server_slot = sof_slot + (EQ::invbag::SHARED_BANK_BAGS_BEGIN - invbag::SHARED_BANK_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sof_slot - invbag::SHARED_BANK_BAGS_BEGIN) / invbag::SLOT_COUNT));; server_slot = sof_slot - 1;
} }
else if (sof_slot <= invslot::TRADE_END && sof_slot >= invslot::TRADE_BEGIN) { else if (sof_slot <= invslot::TRADE_END && sof_slot >= invslot::TRADE_BEGIN) {
@ -3482,7 +3482,7 @@ namespace SoF
} }
else if (sof_slot <= invbag::TRADE_BAGS_END && sof_slot >= invbag::TRADE_BAGS_BEGIN) { else if (sof_slot <= invbag::TRADE_BAGS_END && sof_slot >= invbag::TRADE_BAGS_BEGIN) {
server_slot = sof_slot + (EQ::invbag::TRADE_BAGS_BEGIN - invbag::TRADE_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((sof_slot - invbag::TRADE_BAGS_BEGIN) / invbag::SLOT_COUNT));; server_slot = sof_slot;
} }
else if (sof_slot <= invslot::WORLD_END && sof_slot >= invslot::WORLD_BEGIN) { else if (sof_slot <= invslot::WORLD_END && sof_slot >= invslot::WORLD_BEGIN) {

View File

@ -73,7 +73,7 @@ namespace Titanium
auto Config = EQEmuConfig::get(); auto Config = EQEmuConfig::get();
//create our opcode manager if we havent already //create our opcode manager if we havent already
if (opcodes == nullptr) { if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//load up the opcode manager. //load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches... //TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager(); opcodes = new RegularOpcodeManager();
@ -114,7 +114,7 @@ namespace Titanium
//we need to go to every stream and replace it's manager. //we need to go to every stream and replace it's manager.
if (opcodes != nullptr) { if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
if (!opcodes->ReloadOpcodes(opfile.c_str())) { if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name); LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return; return;
@ -1059,7 +1059,7 @@ namespace Titanium
OUT(spawnid); OUT(spawnid);
OUT_str(charname); OUT_str(charname);
if (emu->race > 474) if (emu->race > 473)
eq->race = 1; eq->race = 1;
else else
OUT(race); OUT(race);
@ -1840,7 +1840,7 @@ namespace Titanium
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr; emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq->Race[char_index] = emu_cse->Race; eq->Race[char_index] = emu_cse->Race;
if (eq->Race[char_index] > 474) if (eq->Race[char_index] > 473)
eq->Race[char_index] = 1; eq->Race[char_index] = 1;
for (int index = 0; index < EQ::textures::materialCount; ++index) { for (int index = 0; index < EQ::textures::materialCount; ++index) {
@ -2421,7 +2421,7 @@ namespace Titanium
strcpy(eq->title, emu->title); strcpy(eq->title, emu->title);
// eq->unknown0274 = emu->unknown0274; // eq->unknown0274 = emu->unknown0274;
eq->helm = emu->helm; eq->helm = emu->helm;
if (emu->race > 474) if (emu->race > 473)
eq->race = 1; eq->race = 1;
else else
eq->race = emu->race; eq->race = emu->race;
@ -3596,12 +3596,12 @@ namespace Titanium
else if (server_slot == (EQ::invslot::POSSESSIONS_COUNT + EQ::invslot::slotAmmo)) { else if (server_slot == (EQ::invslot::POSSESSIONS_COUNT + EQ::invslot::slotAmmo)) {
titanium_slot = server_slot - 4; titanium_slot = server_slot - 4;
} }
else if (server_slot <= EQ::invbag::GENERAL_BAGS_END && else if (server_slot <= EQ::invbag::GENERAL_BAGS_8_END &&
server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) { server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
titanium_slot = server_slot - (EQ::invbag::GENERAL_BAGS_BEGIN - invbag::GENERAL_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::GENERAL_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) { else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) {
titanium_slot = server_slot - (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN); titanium_slot = server_slot - 20;
} }
else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) { else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) {
titanium_slot = server_slot; titanium_slot = server_slot;
@ -3616,21 +3616,21 @@ namespace Titanium
else if (server_slot <= EQ::invslot::BANK_END && server_slot >= EQ::invslot::BANK_BEGIN) { else if (server_slot <= EQ::invslot::BANK_END && server_slot >= EQ::invslot::BANK_BEGIN) {
titanium_slot = server_slot; titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invbag::BANK_BAGS_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) { else if (server_slot <= EQ::invbag::BANK_BAGS_16_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
titanium_slot = server_slot - (EQ::invbag::BANK_BAGS_BEGIN - invbag::BANK_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) { else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
titanium_slot = server_slot; titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END && else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END &&
server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) { server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
titanium_slot = server_slot - (EQ::invbag::SHARED_BANK_BAGS_BEGIN - invbag::SHARED_BANK_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::SHARED_BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) { else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) {
titanium_slot = server_slot; titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) { else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) {
titanium_slot = server_slot - (EQ::invbag::TRADE_BAGS_BEGIN - invbag::TRADE_BAGS_BEGIN) - ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((server_slot - EQ::invbag::TRADE_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT)); titanium_slot = server_slot;
} }
else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) { else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) {
titanium_slot = server_slot; titanium_slot = server_slot;
@ -3687,10 +3687,10 @@ namespace Titanium
server_slot = titanium_slot + 4; server_slot = titanium_slot + 4;
} }
else if (titanium_slot <= invbag::GENERAL_BAGS_END && titanium_slot >= invbag::GENERAL_BAGS_BEGIN) { else if (titanium_slot <= invbag::GENERAL_BAGS_END && titanium_slot >= invbag::GENERAL_BAGS_BEGIN) {
server_slot = titanium_slot + (EQ::invbag::GENERAL_BAGS_BEGIN - invbag::GENERAL_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((titanium_slot - invbag::GENERAL_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = titanium_slot;
} }
else if (titanium_slot <= invbag::CURSOR_BAG_END && titanium_slot >= invbag::CURSOR_BAG_BEGIN) { else if (titanium_slot <= invbag::CURSOR_BAG_END && titanium_slot >= invbag::CURSOR_BAG_BEGIN) {
server_slot = titanium_slot + (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN); server_slot = titanium_slot + 20;
} }
else if (titanium_slot <= invslot::TRIBUTE_END && titanium_slot >= invslot::TRIBUTE_BEGIN) { else if (titanium_slot <= invslot::TRIBUTE_END && titanium_slot >= invslot::TRIBUTE_BEGIN) {
server_slot = titanium_slot; server_slot = titanium_slot;
@ -3705,19 +3705,19 @@ namespace Titanium
server_slot = titanium_slot; server_slot = titanium_slot;
} }
else if (titanium_slot <= invbag::BANK_BAGS_END && titanium_slot >= invbag::BANK_BAGS_BEGIN) { else if (titanium_slot <= invbag::BANK_BAGS_END && titanium_slot >= invbag::BANK_BAGS_BEGIN) {
server_slot = titanium_slot + (EQ::invbag::BANK_BAGS_BEGIN - invbag::BANK_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((titanium_slot - invbag::BANK_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = titanium_slot;
} }
else if (titanium_slot <= invslot::SHARED_BANK_END && titanium_slot >= invslot::SHARED_BANK_BEGIN) { else if (titanium_slot <= invslot::SHARED_BANK_END && titanium_slot >= invslot::SHARED_BANK_BEGIN) {
server_slot = titanium_slot; server_slot = titanium_slot;
} }
else if (titanium_slot <= invbag::SHARED_BANK_BAGS_END && titanium_slot >= invbag::SHARED_BANK_BAGS_BEGIN) { else if (titanium_slot <= invbag::SHARED_BANK_BAGS_END && titanium_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
server_slot = titanium_slot + (EQ::invbag::SHARED_BANK_BAGS_BEGIN - invbag::SHARED_BANK_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((titanium_slot - invbag::SHARED_BANK_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = titanium_slot;
} }
else if (titanium_slot <= invslot::TRADE_END && titanium_slot >= invslot::TRADE_BEGIN) { else if (titanium_slot <= invslot::TRADE_END && titanium_slot >= invslot::TRADE_BEGIN) {
server_slot = titanium_slot; server_slot = titanium_slot;
} }
else if (titanium_slot <= invbag::TRADE_BAGS_END && titanium_slot >= invbag::TRADE_BAGS_BEGIN) { else if (titanium_slot <= invbag::TRADE_BAGS_END && titanium_slot >= invbag::TRADE_BAGS_BEGIN) {
server_slot = titanium_slot + (EQ::invbag::TRADE_BAGS_BEGIN - invbag::TRADE_BAGS_BEGIN) + ((EQ::invbag::SLOT_COUNT - invbag::SLOT_COUNT) * ((titanium_slot - invbag::TRADE_BAGS_BEGIN) / invbag::SLOT_COUNT)); server_slot = titanium_slot;
} }
else if (titanium_slot <= invslot::WORLD_END && titanium_slot >= invslot::WORLD_BEGIN) { else if (titanium_slot <= invslot::WORLD_END && titanium_slot >= invslot::WORLD_BEGIN) {
server_slot = titanium_slot; server_slot = titanium_slot;

View File

@ -76,7 +76,7 @@ namespace UF
{ {
//create our opcode manager if we havent already //create our opcode manager if we havent already
if (opcodes == nullptr) { if (opcodes == nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
//load up the opcode manager. //load up the opcode manager.
//TODO: figure out how to support shared memory with multiple patches... //TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager(); opcodes = new RegularOpcodeManager();
@ -117,7 +117,7 @@ namespace UF
//we need to go to every stream and replace it's manager. //we need to go to every stream and replace it's manager.
if (opcodes != nullptr) { if (opcodes != nullptr) {
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name); std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
if (!opcodes->ReloadOpcodes(opfile.c_str())) { if (!opcodes->ReloadOpcodes(opfile.c_str())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name); LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return; return;

View File

@ -8,7 +8,7 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
void PathManager::Init() void PathManager::LoadPaths()
{ {
m_server_path = File::FindEqemuConfigPath(); m_server_path = File::FindEqemuConfigPath();
@ -48,23 +48,10 @@ void PathManager::Init()
return dir; return dir;
}; };
auto load_many_paths_fallback = [&](const std::vector<std::string>& dirs, const std::string& fallback, std::vector<std::string>& target) {
target.clear();
if (!dirs.empty()) {
for (const auto& path : dirs) {
target.push_back(resolve_path(path));
}
} else {
target.push_back(resolve_path(fallback));
}
};
load_many_paths_fallback(c->GetQuestDirectories(), c->QuestDir, m_quests_paths);
load_many_paths_fallback(c->GetPluginsDirectories(), c->PluginDir, m_plugin_paths);
load_many_paths_fallback(c->GetLuaModuleDirectories(), c->LuaModuleDir, m_lua_module_paths);
// resolve all paths
m_maps_path = resolve_path(c->MapDir, {"maps", "Maps"}); m_maps_path = resolve_path(c->MapDir, {"maps", "Maps"});
m_quests_path = resolve_path(c->QuestDir);
m_plugins_path = resolve_path(c->PluginDir);
m_lua_modules_path = resolve_path(c->LuaModuleDir);
m_lua_mods_path = resolve_path("mods"); m_lua_mods_path = resolve_path("mods");
m_patch_path = resolve_path(c->PatchDir); m_patch_path = resolve_path(c->PatchDir);
m_opcode_path = resolve_path(c->OpcodeDir); m_opcode_path = resolve_path(c->OpcodeDir);
@ -75,10 +62,13 @@ void PathManager::Init()
std::vector<std::pair<std::string, std::string>> paths = { std::vector<std::pair<std::string, std::string>> paths = {
{"server", m_server_path}, {"server", m_server_path},
{"logs", m_log_path}, {"logs", m_log_path},
{"maps", m_maps_path},
{"lua mods", m_lua_mods_path}, {"lua mods", m_lua_mods_path},
{"lua_modules", m_lua_modules_path},
{"maps", m_maps_path},
{"patches", m_patch_path}, {"patches", m_patch_path},
{"opcode", m_opcode_path}, {"opcode", m_opcode_path},
{"plugins", m_plugins_path},
{"quests", m_quests_path},
{"shared_memory", m_shared_memory_path} {"shared_memory", m_shared_memory_path}
}; };
@ -93,17 +83,6 @@ void PathManager::Init()
LogInfo("{:>{}} > [{:<{}}]", name, name_width, in_path, path_width); LogInfo("{:>{}} > [{:<{}}]", name, name_width, in_path, path_width);
} }
} }
auto log_paths = [&](const std::string& label, const std::vector<std::string>& paths) {
if (!paths.empty()) {
LogInfo("{:>{}} > [{:<{}}]", label, name_width - 1, Strings::Join(paths, ";"), path_width);
}
};
log_paths("quests", m_quests_paths);
log_paths("plugins", m_plugin_paths);
log_paths("lua_modules", m_lua_module_paths);
LogInfo("{}", Strings::Repeat("-", break_length)); LogInfo("{}", Strings::Repeat("-", break_length));
} }
@ -117,26 +96,21 @@ const std::string &PathManager::GetMapsPath() const
return m_maps_path; return m_maps_path;
} }
const std::string &PathManager::GetQuestsPath() const
{
return m_quests_path;
}
const std::string &PathManager::GetPluginsPath() const
{
return m_plugins_path;
}
const std::string &PathManager::GetSharedMemoryPath() const const std::string &PathManager::GetSharedMemoryPath() const
{ {
return m_shared_memory_path; return m_shared_memory_path;
} }
std::vector<std::string> PathManager::GetQuestPaths() const
{
return m_quests_paths;
}
std::vector<std::string> PathManager::GetPluginPaths() const
{
return m_plugin_paths;
}
std::vector<std::string> PathManager::GetLuaModulePaths() const
{
return m_lua_module_paths;
}
const std::string &PathManager::GetLogPath() const const std::string &PathManager::GetLogPath() const
{ {
return m_log_path; return m_log_path;
@ -152,6 +126,11 @@ const std::string &PathManager::GetOpcodePath() const
return m_opcode_path; return m_opcode_path;
} }
const std::string &PathManager::GetLuaModulesPath() const
{
return m_lua_modules_path;
}
const std::string &PathManager::GetLuaModsPath() const const std::string &PathManager::GetLuaModsPath() const
{ {
return m_lua_mods_path; return m_lua_mods_path;

View File

@ -3,17 +3,10 @@
#include <string> #include <string>
#include <vector>
class PathManager { class PathManager {
public: public:
void Init(); void LoadPaths();
static PathManager *Instance()
{
static PathManager instance;
return &instance;
}
[[nodiscard]] const std::string &GetLogPath() const; [[nodiscard]] const std::string &GetLogPath() const;
[[nodiscard]] const std::string &GetLuaModsPath() const; [[nodiscard]] const std::string &GetLuaModsPath() const;
@ -21,27 +14,24 @@ public:
[[nodiscard]] const std::string &GetMapsPath() const; [[nodiscard]] const std::string &GetMapsPath() const;
[[nodiscard]] const std::string &GetPatchPath() const; [[nodiscard]] const std::string &GetPatchPath() const;
[[nodiscard]] const std::string &GetOpcodePath() const; [[nodiscard]] const std::string &GetOpcodePath() const;
[[nodiscard]] const std::string &GetPluginsPath() const;
[[nodiscard]] const std::string &GetQuestsPath() const;
[[nodiscard]] const std::string &GetServerPath() const; [[nodiscard]] const std::string &GetServerPath() const;
[[nodiscard]] const std::string &GetSharedMemoryPath() const; [[nodiscard]] const std::string &GetSharedMemoryPath() const;
[[nodiscard]] std::vector<std::string> GetQuestPaths() const;
[[nodiscard]] std::vector<std::string> GetPluginPaths() const;
[[nodiscard]] std::vector<std::string> GetLuaModulePaths() const;
private: private:
std::string m_log_path; std::string m_log_path;
std::string m_lua_mods_path; std::string m_lua_mods_path;
std::string m_maps_path; std::string m_lua_modules_path;
std::string m_patch_path; std::string m_maps_path;
std::string m_opcode_path; std::string m_patch_path;
std::string m_quests_path; std::string m_opcode_path;
std::vector<std::string> m_quests_paths; std::string m_plugins_path;
std::vector<std::string> m_plugin_paths; std::string m_quests_path;
std::vector<std::string> m_lua_module_paths; std::string m_server_path;
std::string m_shared_memory_path;
private:
std::string m_server_path;
std::string m_shared_memory_path;
}; };
extern PathManager path;
#endif //EQEMU_PATH_MANAGER_H #endif //EQEMU_PATH_MANAGER_H

View File

@ -1,9 +0,0 @@
#pragma once
#include "../types.h"
#include "../database.h"
#include "../strings.h"
#include "../eqemu_logsys.h"
#include "../eqemu_logsys_log_aliases.h"
#include "../features.h"
#include "../global_define.h"

34
common/pch/pch.h Normal file
View File

@ -0,0 +1,34 @@
// types
#include <limits>
#include <string>
#include <cctype>
#include <sstream>
// containers
#include <iterator>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <list>
#include <vector>
// utilities
#include <iostream>
#include <cassert>
#include <cmath>
#include <memory>
#include <functional>
#include <algorithm>
#include <utility>
#include <tuple>
#include <fstream>
#include <cstdio>
// fmt
#include <fmt/format.h>
// lua
#include "lua.hpp"
#include <luabind/luabind.hpp>
#include <luabind/object.hpp>

View File

@ -1,14 +0,0 @@
#pragma once
// Lightweight, widely used
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <memory>
#include <limits>
#include <cstdint>
#include <cassert>
// fmt
#include <fmt/format.h>

View File

@ -1,7 +1,6 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include "process.h" #include "process.h"
#include <fmt/format.h>
std::string Process::execute(const std::string &cmd) std::string Process::execute(const std::string &cmd)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,103 @@
#include "../common/types.h" #include "../common/types.h"
#include <string> #include <string>
namespace Gender {
constexpr uint8 Male = 0;
constexpr uint8 Female = 1;
constexpr uint8 Neuter = 2;
}
//theres a big list straight from the client below.
#define HUMAN 1
#define BARBARIAN 2
#define ERUDITE 3
#define WOOD_ELF 4
#define HIGH_ELF 5
#define DARK_ELF 6
#define HALF_ELF 7
#define DWARF 8
#define TROLL 9
#define OGRE 10
#define HALFLING 11
#define GNOME 12
#define WEREWOLF 14
#define WOLF 42
#define BEAR 43
#define SKELETON 60
#define TIGER 63
#define ELEMENTAL 75
#define ALLIGATOR 91
#define OGGOK_CITIZEN 93
#define EYE_OF_ZOMM 108
#define WOLF_ELEMENTAL 120
#define INVISIBLE_MAN 127
#define IKSAR 128
#define VAHSHIR 130
#define CONTROLLED_BOAT 141
#define MINOR_ILL_OBJ 142
#define TREE 143
#define IKSAR_SKELETON 161
#define FROGLOK 330
// TODO: check all clients for (BYTE) usage of '/who all' class and remove FROGLOK2, if possible (330 - 74 = 256 .. WORD->BYTE conversion loss...)
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
#define FAIRY 473
#define DRAKKIN 522 // 32768
#define EMU_RACE_NPC 131069 // was 65533
#define EMU_RACE_PET 131070 // was 65534
#define EMU_RACE_UNKNOWN 131071 // was 65535
// player race values
#define PLAYER_RACE_UNKNOWN 0
#define PLAYER_RACE_HUMAN 1
#define PLAYER_RACE_BARBARIAN 2
#define PLAYER_RACE_ERUDITE 3
#define PLAYER_RACE_WOOD_ELF 4
#define PLAYER_RACE_HIGH_ELF 5
#define PLAYER_RACE_DARK_ELF 6
#define PLAYER_RACE_HALF_ELF 7
#define PLAYER_RACE_DWARF 8
#define PLAYER_RACE_TROLL 9
#define PLAYER_RACE_OGRE 10
#define PLAYER_RACE_HALFLING 11
#define PLAYER_RACE_GNOME 12
#define PLAYER_RACE_IKSAR 13
#define PLAYER_RACE_VAHSHIR 14
#define PLAYER_RACE_FROGLOK 15
#define PLAYER_RACE_DRAKKIN 16
#define PLAYER_RACE_COUNT 16
#define PLAYER_RACE_EMU_NPC 17
#define PLAYER_RACE_EMU_PET 18
#define PLAYER_RACE_EMU_COUNT 19
// player race bits
#define PLAYER_RACE_UNKNOWN_BIT 0
#define PLAYER_RACE_HUMAN_BIT 1
#define PLAYER_RACE_BARBARIAN_BIT 2
#define PLAYER_RACE_ERUDITE_BIT 4
#define PLAYER_RACE_WOOD_ELF_BIT 8
#define PLAYER_RACE_HIGH_ELF_BIT 16
#define PLAYER_RACE_DARK_ELF_BIT 32
#define PLAYER_RACE_HALF_ELF_BIT 64
#define PLAYER_RACE_DWARF_BIT 128
#define PLAYER_RACE_TROLL_BIT 256
#define PLAYER_RACE_OGRE_BIT 512
#define PLAYER_RACE_HALFLING_BIT 1024
#define PLAYER_RACE_GNOME_BIT 2048
#define PLAYER_RACE_IKSAR_BIT 4096
#define PLAYER_RACE_VAHSHIR_BIT 8192
#define PLAYER_RACE_FROGLOK_BIT 16384
#define PLAYER_RACE_DRAKKIN_BIT 32768
#define PLAYER_RACE_ALL_MASK 65535
const char* GetRaceIDName(uint16 race_id); const char* GetRaceIDName(uint16 race_id);
const char* GetPlayerRaceName(uint32 player_race_value);
const char* GetGenderName(uint32 gender_id); const char* GetGenderName(uint32 gender_id);
bool IsPlayerRace(uint16 race_id); bool IsPlayerRace(uint16 race_id);
@ -31,13 +127,25 @@ uint32 GetPlayerRaceValue(uint16 race_id);
uint16 GetPlayerRaceBit(uint16 race_id); uint16 GetPlayerRaceBit(uint16 race_id);
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value); uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
float GetRaceGenderDefaultHeight(int race, int gender); float GetRaceGenderDefaultHeight(int race, int gender);
namespace Gender { // player race-/gender-based model feature validators
constexpr uint8 Male = 0; namespace PlayerAppearance
constexpr uint8 Female = 1; {
constexpr uint8 Neuter = 2; bool IsValidBeard(uint16 race_id, uint8 gender_id, uint8 beard_value, bool use_luclin = true);
bool IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8 beard_color_value, bool use_luclin = true);
bool IsValidDetail(uint16 race_id, uint8 gender_id, uint32 detail_value, bool use_luclin = true);
bool IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 eye_color_value, bool use_luclin = true);
bool IsValidFace(uint16 race_id, uint8 gender_id, uint8 face_value, bool use_luclin = true);
bool IsValidHair(uint16 race_id, uint8 gender_id, uint8 hair_value, bool use_luclin = true);
bool IsValidHairColor(uint16 race_id, uint8 gender_id, uint8 hair_color_value, bool use_luclin = true);
bool IsValidHead(uint16 race_id, uint8 gender_id, uint8 head_value, bool use_luclin = true);
bool IsValidHeritage(uint16 race_id, uint8 gender_id, uint32 heritage_value, bool use_luclin = true);
bool IsValidTattoo(uint16 race_id, uint8 gender_id, uint32 tattoo_value, bool use_luclin = true);
bool IsValidTexture(uint16 race_id, uint8 gender_id, uint8 texture_value, bool use_luclin = true);
bool IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_value, bool use_luclin = true);
} }
namespace Race { namespace Race {
@ -776,92 +884,8 @@ namespace Race {
constexpr uint16 Pegasus3 = 732; constexpr uint16 Pegasus3 = 732;
constexpr uint16 InteractiveObject = 2250; constexpr uint16 InteractiveObject = 2250;
constexpr uint16 Node = 2254; constexpr uint16 Node = 2254;
}
namespace RaceBitmask { constexpr uint16 ALL_RACES_BITMASK = 65535;
constexpr uint16 Unknown = 0;
constexpr uint16 Human = 1;
constexpr uint16 Barbarian = 2;
constexpr uint16 Erudite = 4;
constexpr uint16 WoodElf = 8;
constexpr uint16 HighElf = 16;
constexpr uint16 DarkElf = 32;
constexpr uint16 HalfElf = 64;
constexpr uint16 Dwarf = 128;
constexpr uint16 Troll = 256;
constexpr uint16 Ogre = 512;
constexpr uint16 Halfling = 1024;
constexpr uint16 Gnome = 2048;
constexpr uint16 Iksar = 4096;
constexpr uint16 VahShir = 8192;
constexpr uint16 Froglok = 16384;
constexpr uint16 Drakkin = 32768;
constexpr uint16 All = 65535;
}
namespace RaceIndex {
constexpr uint16 Human = 1;
constexpr uint16 Barbarian = 2;
constexpr uint16 Erudite = 3;
constexpr uint16 WoodElf = 4;
constexpr uint16 HighElf = 5;
constexpr uint16 DarkElf = 6;
constexpr uint16 HalfElf = 7;
constexpr uint16 Dwarf = 8;
constexpr uint16 Troll = 9;
constexpr uint16 Ogre = 10;
constexpr uint16 Halfling = 11;
constexpr uint16 Gnome = 12;
constexpr uint16 Iksar = 13;
constexpr uint16 VahShir = 14;
constexpr uint16 Froglok = 15;
constexpr uint16 Drakkin = 16;
}
namespace RaceAppearance {
bool IsValidBeard(uint16 race_id, uint8 gender_id, uint8 beard_value, bool use_luclin = true);
bool IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8 beard_color_value, bool use_luclin = true);
bool IsValidDetail(uint16 race_id, uint8 gender_id, uint32 detail_value, bool use_luclin = true);
bool IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 eye_color_value, bool use_luclin = true);
bool IsValidFace(uint16 race_id, uint8 gender_id, uint8 face_value, bool use_luclin = true);
bool IsValidHair(uint16 race_id, uint8 gender_id, uint8 hair_value, bool use_luclin = true);
bool IsValidHairColor(uint16 race_id, uint8 gender_id, uint8 hair_color_value, bool use_luclin = true);
bool IsValidHeritage(uint16 race_id, uint8 gender_id, uint32 heritage_value, bool use_luclin = true);
bool IsValidTattoo(uint16 race_id, uint8 gender_id, uint32 tattoo_value, bool use_luclin = true);
bool IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_value, bool use_luclin = true);
constexpr int HumanMale = (Race::Human << 8) | Gender::Male;
constexpr int HumanFemale = (Race::Human << 8) | Gender::Female;
constexpr int BarbarianMale = (Race::Barbarian << 8) | Gender::Male;
constexpr int BarbarianFemale = (Race::Barbarian << 8) | Gender::Female;
constexpr int EruditeMale = (Race::Erudite << 8) | Gender::Male;
constexpr int EruditeFemale = (Race::Erudite << 8) | Gender::Female;
constexpr int WoodElfMale = (Race::WoodElf << 8) | Gender::Male;
constexpr int WoodElfFemale = (Race::WoodElf << 8) | Gender::Female;
constexpr int HighElfMale = (Race::HighElf << 8) | Gender::Male;
constexpr int HighElfFemale = (Race::HighElf << 8) | Gender::Female;
constexpr int DarkElfMale = (Race::DarkElf << 8) | Gender::Male;
constexpr int DarkElfFemale = (Race::DarkElf << 8) | Gender::Female;
constexpr int HalfElfMale = (Race::HalfElf << 8) | Gender::Male;
constexpr int HalfElfFemale = (Race::HalfElf << 8) | Gender::Female;
constexpr int DwarfMale = (Race::Dwarf << 8) | Gender::Male;
constexpr int DwarfFemale = (Race::Dwarf << 8) | Gender::Female;
constexpr int TrollMale = (Race::Troll << 8) | Gender::Male;
constexpr int TrollFemale = (Race::Troll << 8) | Gender::Female;
constexpr int OgreMale = (Race::Ogre << 8) | Gender::Male;
constexpr int OgreFemale = (Race::Ogre << 8) | Gender::Female;
constexpr int HalflingMale = (Race::Halfling << 8) | Gender::Male;
constexpr int HalflingFemale = (Race::Halfling << 8) | Gender::Female;
constexpr int GnomeMale = (Race::Gnome << 8) | Gender::Male;
constexpr int GnomeFemale = (Race::Gnome << 8) | Gender::Female;
constexpr int IksarMale = (Race::Iksar << 8) | Gender::Male;
constexpr int IksarFemale = (Race::Iksar << 8) | Gender::Female;
constexpr int VahShirMale = (Race::VahShir << 8) | Gender::Male;
constexpr int VahShirFemale = (Race::VahShir << 8) | Gender::Female;
constexpr int FroglokMale = (Race::Froglok2 << 8) | Gender::Male;
constexpr int FroglokFemale = (Race::Froglok2 << 8) | Gender::Female;
constexpr int DrakkinMale = (Race::Drakkin << 8) | Gender::Male;
constexpr int DrakkinFemale = (Race::Drakkin << 8) | Gender::Female;
} }
#endif #endif

View File

@ -116,12 +116,6 @@ namespace EQ {
Reseed(); Reseed();
} }
static Random* Instance()
{
static Random instance;
return &instance;
}
private: private:
#ifndef BIASED_INT_DIST #ifndef BIASED_INT_DIST
typedef std::uniform_int_distribution<int>::param_type int_param_t; typedef std::uniform_int_distribution<int>::param_type int_param_t;

View File

@ -70,7 +70,6 @@ public:
uint32_t gm_exp; uint32_t gm_exp;
uint32_t killed_by; uint32_t killed_by;
uint8_t rezzable; uint8_t rezzable;
std::string entity_variables;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@ -132,7 +131,6 @@ public:
"gm_exp", "gm_exp",
"killed_by", "killed_by",
"rezzable", "rezzable",
"entity_variables",
}; };
} }
@ -190,7 +188,6 @@ public:
"gm_exp", "gm_exp",
"killed_by", "killed_by",
"rezzable", "rezzable",
"entity_variables",
}; };
} }
@ -282,7 +279,6 @@ public:
e.gm_exp = 0; e.gm_exp = 0;
e.killed_by = 0; e.killed_by = 0;
e.rezzable = 0; e.rezzable = 0;
e.entity_variables = "";
return e; return e;
} }
@ -370,7 +366,6 @@ public:
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0; e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0; e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0; e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.entity_variables = row[51] ? row[51] : "";
return e; return e;
} }
@ -454,7 +449,6 @@ public:
v.push_back(columns[48] + " = " + std::to_string(e.gm_exp)); v.push_back(columns[48] + " = " + std::to_string(e.gm_exp));
v.push_back(columns[49] + " = " + std::to_string(e.killed_by)); v.push_back(columns[49] + " = " + std::to_string(e.killed_by));
v.push_back(columns[50] + " = " + std::to_string(e.rezzable)); v.push_back(columns[50] + " = " + std::to_string(e.rezzable));
v.push_back(columns[51] + " = '" + Strings::Escape(e.entity_variables) + "'");
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -527,7 +521,6 @@ public:
v.push_back(std::to_string(e.gm_exp)); v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by)); v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable)); v.push_back(std::to_string(e.rezzable));
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -608,7 +601,6 @@ public:
v.push_back(std::to_string(e.gm_exp)); v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by)); v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable)); v.push_back(std::to_string(e.rezzable));
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@ -693,7 +685,6 @@ public:
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0; e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0; e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0; e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.entity_variables = row[51] ? row[51] : "";
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -769,7 +760,6 @@ public:
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0; e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0; e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0; e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.entity_variables = row[51] ? row[51] : "";
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -895,7 +885,6 @@ public:
v.push_back(std::to_string(e.gm_exp)); v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by)); v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable)); v.push_back(std::to_string(e.rezzable));
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -969,7 +958,6 @@ public:
v.push_back(std::to_string(e.gm_exp)); v.push_back(std::to_string(e.gm_exp));
v.push_back(std::to_string(e.killed_by)); v.push_back(std::to_string(e.killed_by));
v.push_back(std::to_string(e.rezzable)); v.push_back(std::to_string(e.rezzable));
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }

View File

@ -30,7 +30,6 @@ public:
uint32_t aug_slot_5; uint32_t aug_slot_5;
uint32_t aug_slot_6; uint32_t aug_slot_6;
uint32_t quantity; uint32_t quantity;
uint32_t evolve_amount;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
@ -52,7 +51,6 @@ public:
"aug_slot_5", "aug_slot_5",
"aug_slot_6", "aug_slot_6",
"quantity", "quantity",
"evolve_amount",
}; };
} }
@ -70,7 +68,6 @@ public:
"aug_slot_5", "aug_slot_5",
"aug_slot_6", "aug_slot_6",
"quantity", "quantity",
"evolve_amount",
}; };
} }
@ -111,18 +108,17 @@ public:
{ {
CharacterParcelsContainers e{}; CharacterParcelsContainers e{};
e.id = 0; e.id = 0;
e.parcels_id = 0; e.parcels_id = 0;
e.slot_id = 0; e.slot_id = 0;
e.item_id = 0; e.item_id = 0;
e.aug_slot_1 = 0; e.aug_slot_1 = 0;
e.aug_slot_2 = 0; e.aug_slot_2 = 0;
e.aug_slot_3 = 0; e.aug_slot_3 = 0;
e.aug_slot_4 = 0; e.aug_slot_4 = 0;
e.aug_slot_5 = 0; e.aug_slot_5 = 0;
e.aug_slot_6 = 0; e.aug_slot_6 = 0;
e.quantity = 0; e.quantity = 0;
e.evolve_amount = 0;
return e; return e;
} }
@ -159,18 +155,17 @@ public:
if (results.RowCount() == 1) { if (results.RowCount() == 1) {
CharacterParcelsContainers e{}; CharacterParcelsContainers e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0; e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0; e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0; e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0; e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0; e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0; e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0; e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0; e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0; e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0; e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0; e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
return e; return e;
} }
@ -214,7 +209,6 @@ public:
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5)); v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6)); v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
v.push_back(columns[10] + " = " + std::to_string(e.quantity)); v.push_back(columns[10] + " = " + std::to_string(e.quantity));
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -247,7 +241,6 @@ public:
v.push_back(std::to_string(e.aug_slot_5)); v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -288,7 +281,6 @@ public:
v.push_back(std::to_string(e.aug_slot_5)); v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@ -322,18 +314,17 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcelsContainers e{}; CharacterParcelsContainers e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0; e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0; e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0; e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0; e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0; e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0; e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0; e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0; e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0; e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0; e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0; e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -358,18 +349,17 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcelsContainers e{}; CharacterParcelsContainers e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0; e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0; e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0; e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0; e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0; e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0; e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0; e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0; e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0; e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0; e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0; e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -455,7 +445,6 @@ public:
v.push_back(std::to_string(e.aug_slot_5)); v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -489,7 +478,6 @@ public:
v.push_back(std::to_string(e.aug_slot_5)); v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }

View File

@ -30,7 +30,6 @@ public:
uint32_t aug_slot_6; uint32_t aug_slot_6;
uint32_t slot_id; uint32_t slot_id;
uint32_t quantity; uint32_t quantity;
uint32_t evolve_amount;
std::string from_name; std::string from_name;
std::string note; std::string note;
time_t sent_date; time_t sent_date;
@ -55,7 +54,6 @@ public:
"aug_slot_6", "aug_slot_6",
"slot_id", "slot_id",
"quantity", "quantity",
"evolve_amount",
"from_name", "from_name",
"note", "note",
"sent_date", "sent_date",
@ -76,7 +74,6 @@ public:
"aug_slot_6", "aug_slot_6",
"slot_id", "slot_id",
"quantity", "quantity",
"evolve_amount",
"from_name", "from_name",
"note", "note",
"UNIX_TIMESTAMP(sent_date)", "UNIX_TIMESTAMP(sent_date)",
@ -120,21 +117,20 @@ public:
{ {
CharacterParcels e{}; CharacterParcels e{};
e.id = 0; e.id = 0;
e.char_id = 0; e.char_id = 0;
e.item_id = 0; e.item_id = 0;
e.aug_slot_1 = 0; e.aug_slot_1 = 0;
e.aug_slot_2 = 0; e.aug_slot_2 = 0;
e.aug_slot_3 = 0; e.aug_slot_3 = 0;
e.aug_slot_4 = 0; e.aug_slot_4 = 0;
e.aug_slot_5 = 0; e.aug_slot_5 = 0;
e.aug_slot_6 = 0; e.aug_slot_6 = 0;
e.slot_id = 0; e.slot_id = 0;
e.quantity = 0; e.quantity = 0;
e.evolve_amount = 0; e.from_name = "";
e.from_name = ""; e.note = "";
e.note = ""; e.sent_date = 0;
e.sent_date = 0;
return e; return e;
} }
@ -171,21 +167,20 @@ public:
if (results.RowCount() == 1) { if (results.RowCount() == 1) {
CharacterParcels e{}; CharacterParcels e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0; e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0; e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0; e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0; e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0; e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0; e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0; e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0; e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0; e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0; e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0; e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0; e.from_name = row[11] ? row[11] : "";
e.from_name = row[12] ? row[12] : ""; e.note = row[12] ? row[12] : "";
e.note = row[13] ? row[13] : ""; e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
return e; return e;
} }
@ -229,10 +224,9 @@ public:
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_6)); v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_6));
v.push_back(columns[9] + " = " + std::to_string(e.slot_id)); v.push_back(columns[9] + " = " + std::to_string(e.slot_id));
v.push_back(columns[10] + " = " + std::to_string(e.quantity)); v.push_back(columns[10] + " = " + std::to_string(e.quantity));
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount)); v.push_back(columns[11] + " = '" + Strings::Escape(e.from_name) + "'");
v.push_back(columns[12] + " = '" + Strings::Escape(e.from_name) + "'"); v.push_back(columns[12] + " = '" + Strings::Escape(e.note) + "'");
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'"); v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
v.push_back(columns[14] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -265,7 +259,6 @@ public:
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id)); v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
v.push_back("'" + Strings::Escape(e.from_name) + "'"); v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'"); v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
@ -309,7 +302,6 @@ public:
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id)); v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
v.push_back("'" + Strings::Escape(e.from_name) + "'"); v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'"); v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
@ -346,21 +338,20 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcels e{}; CharacterParcels e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0; e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0; e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0; e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0; e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0; e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0; e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0; e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0; e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0; e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0; e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0; e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0; e.from_name = row[11] ? row[11] : "";
e.from_name = row[12] ? row[12] : ""; e.note = row[12] ? row[12] : "";
e.note = row[13] ? row[13] : ""; e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -385,21 +376,20 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcels e{}; CharacterParcels e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0; e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0; e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0; e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0; e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0; e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0; e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0; e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0; e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0; e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0; e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0; e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0; e.from_name = row[11] ? row[11] : "";
e.from_name = row[12] ? row[12] : ""; e.note = row[12] ? row[12] : "";
e.note = row[13] ? row[13] : ""; e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -485,7 +475,6 @@ public:
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id)); v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
v.push_back("'" + Strings::Escape(e.from_name) + "'"); v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'"); v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
@ -522,7 +511,6 @@ public:
v.push_back(std::to_string(e.aug_slot_6)); v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id)); v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity)); v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
v.push_back("'" + Strings::Escape(e.from_name) + "'"); v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'"); v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")"); v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");

View File

@ -70,7 +70,6 @@ public:
int32_t endurance_regen; int32_t endurance_regen;
int32_t shielding; int32_t shielding;
int32_t spell_damage; int32_t spell_damage;
int32_t heal_amount;
int32_t spell_shielding; int32_t spell_shielding;
int32_t strikethrough; int32_t strikethrough;
int32_t stun_resist; int32_t stun_resist;
@ -155,7 +154,6 @@ public:
"endurance_regen", "endurance_regen",
"shielding", "shielding",
"spell_damage", "spell_damage",
"heal_amount",
"spell_shielding", "spell_shielding",
"strikethrough", "strikethrough",
"stun_resist", "stun_resist",
@ -236,7 +234,6 @@ public:
"endurance_regen", "endurance_regen",
"shielding", "shielding",
"spell_damage", "spell_damage",
"heal_amount",
"spell_shielding", "spell_shielding",
"strikethrough", "strikethrough",
"stun_resist", "stun_resist",
@ -351,7 +348,6 @@ public:
e.endurance_regen = 0; e.endurance_regen = 0;
e.shielding = 0; e.shielding = 0;
e.spell_damage = 0; e.spell_damage = 0;
e.heal_amount = 0;
e.spell_shielding = 0; e.spell_shielding = 0;
e.strikethrough = 0; e.strikethrough = 0;
e.stun_resist = 0; e.stun_resist = 0;
@ -462,30 +458,29 @@ public:
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0; e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0; e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0; e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0; e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0; e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0; e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0; e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0; e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0; e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0; e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0; e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0; e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0; e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0; e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0; e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0; e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0; e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0; e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0; e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0; e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0; e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0; e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0; e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0; e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0; e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10); e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
return e; return e;
} }
@ -570,30 +565,29 @@ public:
v.push_back(columns[48] + " = " + std::to_string(e.endurance_regen)); v.push_back(columns[48] + " = " + std::to_string(e.endurance_regen));
v.push_back(columns[49] + " = " + std::to_string(e.shielding)); v.push_back(columns[49] + " = " + std::to_string(e.shielding));
v.push_back(columns[50] + " = " + std::to_string(e.spell_damage)); v.push_back(columns[50] + " = " + std::to_string(e.spell_damage));
v.push_back(columns[51] + " = " + std::to_string(e.heal_amount)); v.push_back(columns[51] + " = " + std::to_string(e.spell_shielding));
v.push_back(columns[52] + " = " + std::to_string(e.spell_shielding)); v.push_back(columns[52] + " = " + std::to_string(e.strikethrough));
v.push_back(columns[53] + " = " + std::to_string(e.strikethrough)); v.push_back(columns[53] + " = " + std::to_string(e.stun_resist));
v.push_back(columns[54] + " = " + std::to_string(e.stun_resist)); v.push_back(columns[54] + " = " + std::to_string(e.backstab));
v.push_back(columns[55] + " = " + std::to_string(e.backstab)); v.push_back(columns[55] + " = " + std::to_string(e.wind));
v.push_back(columns[56] + " = " + std::to_string(e.wind)); v.push_back(columns[56] + " = " + std::to_string(e.brass));
v.push_back(columns[57] + " = " + std::to_string(e.brass)); v.push_back(columns[57] + " = " + std::to_string(e.string));
v.push_back(columns[58] + " = " + std::to_string(e.string)); v.push_back(columns[58] + " = " + std::to_string(e.percussion));
v.push_back(columns[59] + " = " + std::to_string(e.percussion)); v.push_back(columns[59] + " = " + std::to_string(e.singing));
v.push_back(columns[60] + " = " + std::to_string(e.singing)); v.push_back(columns[60] + " = " + std::to_string(e.baking));
v.push_back(columns[61] + " = " + std::to_string(e.baking)); v.push_back(columns[61] + " = " + std::to_string(e.alchemy));
v.push_back(columns[62] + " = " + std::to_string(e.alchemy)); v.push_back(columns[62] + " = " + std::to_string(e.tailoring));
v.push_back(columns[63] + " = " + std::to_string(e.tailoring)); v.push_back(columns[63] + " = " + std::to_string(e.blacksmithing));
v.push_back(columns[64] + " = " + std::to_string(e.blacksmithing)); v.push_back(columns[64] + " = " + std::to_string(e.fletching));
v.push_back(columns[65] + " = " + std::to_string(e.fletching)); v.push_back(columns[65] + " = " + std::to_string(e.brewing));
v.push_back(columns[66] + " = " + std::to_string(e.brewing)); v.push_back(columns[66] + " = " + std::to_string(e.jewelry));
v.push_back(columns[67] + " = " + std::to_string(e.jewelry)); v.push_back(columns[67] + " = " + std::to_string(e.pottery));
v.push_back(columns[68] + " = " + std::to_string(e.pottery)); v.push_back(columns[68] + " = " + std::to_string(e.research));
v.push_back(columns[69] + " = " + std::to_string(e.research)); v.push_back(columns[69] + " = " + std::to_string(e.alcohol));
v.push_back(columns[70] + " = " + std::to_string(e.alcohol)); v.push_back(columns[70] + " = " + std::to_string(e.fishing));
v.push_back(columns[71] + " = " + std::to_string(e.fishing)); v.push_back(columns[71] + " = " + std::to_string(e.tinkering));
v.push_back(columns[72] + " = " + std::to_string(e.tinkering)); v.push_back(columns[72] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")"); v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
v.push_back(columns[74] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -666,7 +660,6 @@ public:
v.push_back(std::to_string(e.endurance_regen)); v.push_back(std::to_string(e.endurance_regen));
v.push_back(std::to_string(e.shielding)); v.push_back(std::to_string(e.shielding));
v.push_back(std::to_string(e.spell_damage)); v.push_back(std::to_string(e.spell_damage));
v.push_back(std::to_string(e.heal_amount));
v.push_back(std::to_string(e.spell_shielding)); v.push_back(std::to_string(e.spell_shielding));
v.push_back(std::to_string(e.strikethrough)); v.push_back(std::to_string(e.strikethrough));
v.push_back(std::to_string(e.stun_resist)); v.push_back(std::to_string(e.stun_resist));
@ -770,7 +763,6 @@ public:
v.push_back(std::to_string(e.endurance_regen)); v.push_back(std::to_string(e.endurance_regen));
v.push_back(std::to_string(e.shielding)); v.push_back(std::to_string(e.shielding));
v.push_back(std::to_string(e.spell_damage)); v.push_back(std::to_string(e.spell_damage));
v.push_back(std::to_string(e.heal_amount));
v.push_back(std::to_string(e.spell_shielding)); v.push_back(std::to_string(e.spell_shielding));
v.push_back(std::to_string(e.strikethrough)); v.push_back(std::to_string(e.strikethrough));
v.push_back(std::to_string(e.stun_resist)); v.push_back(std::to_string(e.stun_resist));
@ -878,30 +870,29 @@ public:
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0; e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0; e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0; e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0; e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0; e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0; e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0; e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0; e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0; e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0; e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0; e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0; e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0; e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0; e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0; e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0; e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0; e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0; e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0; e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0; e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0; e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0; e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0; e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0; e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0; e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10); e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -977,30 +968,29 @@ public:
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0; e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0; e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0; e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0; e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0; e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0; e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0; e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0; e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0; e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0; e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0; e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0; e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0; e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0; e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0; e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0; e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0; e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0; e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0; e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0; e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0; e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0; e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0; e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0; e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0; e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10); e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -1126,7 +1116,6 @@ public:
v.push_back(std::to_string(e.endurance_regen)); v.push_back(std::to_string(e.endurance_regen));
v.push_back(std::to_string(e.shielding)); v.push_back(std::to_string(e.shielding));
v.push_back(std::to_string(e.spell_damage)); v.push_back(std::to_string(e.spell_damage));
v.push_back(std::to_string(e.heal_amount));
v.push_back(std::to_string(e.spell_shielding)); v.push_back(std::to_string(e.spell_shielding));
v.push_back(std::to_string(e.strikethrough)); v.push_back(std::to_string(e.strikethrough));
v.push_back(std::to_string(e.stun_resist)); v.push_back(std::to_string(e.stun_resist));
@ -1223,7 +1212,6 @@ public:
v.push_back(std::to_string(e.endurance_regen)); v.push_back(std::to_string(e.endurance_regen));
v.push_back(std::to_string(e.shielding)); v.push_back(std::to_string(e.shielding));
v.push_back(std::to_string(e.spell_damage)); v.push_back(std::to_string(e.spell_damage));
v.push_back(std::to_string(e.heal_amount));
v.push_back(std::to_string(e.spell_shielding)); v.push_back(std::to_string(e.spell_shielding));
v.push_back(std::to_string(e.strikethrough)); v.push_back(std::to_string(e.strikethrough));
v.push_back(std::to_string(e.stun_resist)); v.push_back(std::to_string(e.stun_resist));

View File

@ -15,7 +15,7 @@
#include "../../database.h" #include "../../database.h"
#include "../../strings.h" #include "../../strings.h"
#include <ctime> #include <ctime>
#include <cereal/cereal.hpp>
class BasePlayerEventLogSettingsRepository { class BasePlayerEventLogSettingsRepository {
public: public:
struct PlayerEventLogSettings { struct PlayerEventLogSettings {
@ -25,20 +25,6 @@ public:
int32_t retention_days; int32_t retention_days;
int32_t discord_webhook_id; int32_t discord_webhook_id;
uint8_t etl_enabled; uint8_t etl_enabled;
// cereal
template<class Archive>
void serialize(Archive &ar)
{
ar(
CEREAL_NVP(id),
CEREAL_NVP(event_name),
CEREAL_NVP(event_enabled),
CEREAL_NVP(retention_days),
CEREAL_NVP(discord_webhook_id),
CEREAL_NVP(etl_enabled)
);
}
}; };
static std::string PrimaryKey() static std::string PrimaryKey()

View File

@ -231,21 +231,6 @@ public:
return UpdateOne(db, corpse); return UpdateOne(db, corpse);
} }
static int UpdateEntityVariables(Database& db, uint32 corpse_id, const std::string& json_string)
{
auto results = db.QueryDatabase(
fmt::format(
"UPDATE `{}` SET `entity_variables` = '{}' WHERE `{}` = {}",
TableName(),
Strings::Escape(json_string),
PrimaryKey(),
corpse_id
)
);
return results.Success() ? results.RowsAffected() : 0;
}
}; };
#endif //EQEMU_CHARACTER_CORPSES_REPOSITORY_H #endif //EQEMU_CHARACTER_CORPSES_REPOSITORY_H

View File

@ -167,46 +167,6 @@ public:
return zone_player_counts; return zone_player_counts;
} }
static std::vector<uint32_t> GetCharacterIDsByAccountID(
Database& db,
uint32_t account_id
)
{
std::vector<uint32_t> character_ids;
auto query = fmt::format(
"SELECT id FROM character_data WHERE account_id = {} AND deleted_at IS NULL",
account_id
);
auto results = db.QueryDatabase(query);
if (results.Success()) {
for (auto row : results) {
if (row[0]) {
character_ids.push_back(static_cast<uint32_t>(std::stoul(row[0])));
}
}
}
return character_ids;
}
static uint32_t GetTotalTimePlayed(Database& db, uint32_t account_id)
{
auto query = fmt::format(
"SELECT SUM(time_played) FROM `character_data` WHERE `account_id` = {}",
account_id
);
auto results = db.QueryDatabase(query);
if (!results.Success()) {
return 0;
}
auto row = results.begin();
return Strings::ToUnsignedInt(row[0]);
}
}; };
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H #endif //EQEMU_CHARACTER_DATA_REPOSITORY_H

View File

@ -49,7 +49,6 @@ public:
// these are the base definitions for command_subsettings and can be over-ridden by the database // these are the base definitions for command_subsettings and can be over-ridden by the database
std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = { std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = {
{.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"}, {.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"},
{.parent_command = "find", .sub_command = "account", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaccount"},
{.parent_command = "find", .sub_command = "body_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbodytype"}, {.parent_command = "find", .sub_command = "body_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbodytype"},
{.parent_command = "find", .sub_command = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"}, {.parent_command = "find", .sub_command = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"},
{.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"}, {.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"},
@ -143,7 +142,6 @@ public:
{.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"}, {.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"},
{.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"}, {.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"},
{.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"}, {.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"},
{.parent_command = "show", .sub_command = "keyring", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showkeyring"},
{.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"}, {.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"},
{.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"}, {.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"},
{.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"}, {.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"},

View File

@ -14,7 +14,7 @@ namespace ContentFilterCriteria {
table_prefix = table_prefix + "."; table_prefix = table_prefix + ".";
} }
int current_expansion_filter_criteria = WorldContentService::Instance()->GetCurrentExpansion(); int current_expansion_filter_criteria = content_service.GetCurrentExpansion();
if (current_expansion_filter_criteria == Expansion::EXPANSION_ALL) { if (current_expansion_filter_criteria == Expansion::EXPANSION_ALL) {
current_expansion_filter_criteria = Expansion::EXPANSION_FILTER_MAX; current_expansion_filter_criteria = Expansion::EXPANSION_FILTER_MAX;
} }
@ -33,8 +33,8 @@ namespace ContentFilterCriteria {
table_prefix table_prefix
); );
std::vector<std::string> flags_disabled = WorldContentService::Instance()->GetContentFlagsDisabled(); std::vector<std::string> flags_disabled = content_service.GetContentFlagsDisabled();
std::vector<std::string> flags_enabled = WorldContentService::Instance()->GetContentFlagsEnabled(); std::vector<std::string> flags_enabled = content_service.GetContentFlagsEnabled();
std::string flags_in_filter_enabled; std::string flags_in_filter_enabled;
std::string flags_in_filter_disabled; std::string flags_in_filter_disabled;
if (!flags_enabled.empty()) { if (!flags_enabled.empty()) {

View File

@ -43,47 +43,6 @@ public:
* method and encapsulate filters there * method and encapsulate filters there
*/ */
template<typename T1, typename T2, typename T3, typename T4>
static std::vector<std::string> join_tuple(
const std::string &glue,
const std::pair<char, char> &encapsulation,
const std::vector<std::tuple<T1, T2, T3, T4>> &src
)
{
if (src.empty()) {
return {};
}
std::vector<std::string> output;
for (const std::tuple<T1, T2, T3, T4> &src_iter: src) {
output.emplace_back(
fmt::format(
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
encapsulation.first,
std::get<0>(src_iter),
encapsulation.second,
glue,
encapsulation.first,
std::get<1>(src_iter),
encapsulation.second,
glue,
encapsulation.first,
std::get<2>(src_iter),
encapsulation.second,
glue,
encapsulation.first,
std::get<3>(src_iter),
encapsulation.second
)
);
}
return output;
}
// Custom extended repository methods here // Custom extended repository methods here
static std::vector<std::string> GetRuleNames(Database &db, int rule_set_id) static std::vector<std::string> GetRuleNames(Database &db, int rule_set_id)
{ {
@ -128,28 +87,12 @@ public:
return v; return v;
} }
template<typename T>
static std::string
ImplodePair(const std::string &glue, const std::pair<char, char> &encapsulation, const std::vector<T> &src)
{
if (src.empty()) {
return {};
}
std::ostringstream oss;
for (const T &src_iter: src) {
oss << encapsulation.first << src_iter << encapsulation.second << glue;
}
std::string output(oss.str());
output.resize(output.size() - glue.size());
return output;
}
static bool DeleteOrphanedRules(Database& db, std::vector<std::string>& v) static bool DeleteOrphanedRules(Database& db, std::vector<std::string>& v)
{ {
const auto query = fmt::format( const auto query = fmt::format(
"DELETE FROM {} WHERE rule_name IN ({})", "DELETE FROM {} WHERE rule_name IN ({})",
TableName(), TableName(),
ImplodePair(",", std::pair<char, char>('\'', '\''), v) Strings::ImplodePair(",", std::pair<char, char>('\'', '\''), v)
); );
return db.QueryDatabase(query).Success(); return db.QueryDatabase(query).Success();
@ -160,7 +103,7 @@ public:
const auto query = fmt::format( const auto query = fmt::format(
"REPLACE INTO {} (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES {}", "REPLACE INTO {} (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES {}",
TableName(), TableName(),
ImplodePair( Strings::ImplodePair(
",", ",",
std::pair<char, char>('(', ')'), std::pair<char, char>('(', ')'),
join_tuple(",", std::pair<char, char>('\'', '\''), v) join_tuple(",", std::pair<char, char>('\'', '\''), v)

View File

@ -502,19 +502,6 @@ bool RuleManager::UpdateInjectedRules(Database *db, const std::string &rule_set_
} }
} }
// update rules in the database where the description is different
for (auto &e : RuleValuesRepository::All(*db)) {
auto i = rule_data.find(e.rule_name);
if (i != rule_data.end()) {
// if notes are different, update them
if (i->second.second != nullptr && *i->second.second != e.notes) {
LogInfo("Updating rule [{}] notes to [{}]", i->first, *i->second.second);
e.notes = *i->second.second;
RuleValuesRepository::ReplaceOne(*db, e);
}
}
}
if (injected_rule_entries.size()) { if (injected_rule_entries.size()) {
if (!RuleValuesRepository::InjectRules(*db, injected_rule_entries)) { if (!RuleValuesRepository::InjectRules(*db, injected_rule_entries)) {
return false; return false;

View File

@ -233,12 +233,6 @@ RULE_BOOL(Character, SneakAlwaysSucceedOver100, false, "When sneak skill is over
RULE_INT(Character, BandolierSwapDelay, 0, "Bandolier swap delay in milliseconds, default is 0") RULE_INT(Character, BandolierSwapDelay, 0, "Bandolier swap delay in milliseconds, default is 0")
RULE_BOOL(Character, EnableHackedFastCampForGM, false, "Enables hacked fast camp for GM clients, if the GM doesn't have a hacked client they'll camp like normal") RULE_BOOL(Character, EnableHackedFastCampForGM, false, "Enables hacked fast camp for GM clients, if the GM doesn't have a hacked client they'll camp like normal")
RULE_BOOL(Character, AlwaysAllowNameChange, false, "Enable this option to allow /changename to work without enabling a name change via scripts.") RULE_BOOL(Character, AlwaysAllowNameChange, false, "Enable this option to allow /changename to work without enabling a name change via scripts.")
RULE_BOOL(Character, EnableAutoAFK, false, "Enable or disable the auto AFK feature, cuts down on packet spam")
RULE_BOOL(Character, AutoIdleFilterPackets, true, "Enable or disable filtering packets when auto AFK is enabled, heavily cuts down on packet spam in zones with lots of players")
RULE_INT(Character, SecondsBeforeIdleCombatZone, 600, "Seconds before a player is considered idle in combat zones (600 = 10 minutes)")
RULE_INT(Character, SecondsBeforeIdleNonCombatZone, 60, "Seconds before a player is considered idle in non-combat zones (60 = 1 minute)")
RULE_INT(Character, SecondsBeforeAFKCombatZone, 1800, "Seconds before a player is considered AFK in combat zones (1800 = 30 minutes)")
RULE_INT(Character, SecondsBeforeAFKNonCombatZone, 600, "Seconds before a player is considered AFK in non-combat zones (600 = 10 minutes)")
RULE_CATEGORY_END() RULE_CATEGORY_END()
RULE_CATEGORY(Mercs) RULE_CATEGORY(Mercs)
@ -619,7 +613,7 @@ RULE_INT(Combat, SneakPullAssistRange, 400, "Modified range of assist for sneak
RULE_BOOL(Combat, Classic2HBAnimation, false, "2HB will use the 2 hand piercing animation instead of the overhead slashing animation") RULE_BOOL(Combat, Classic2HBAnimation, false, "2HB will use the 2 hand piercing animation instead of the overhead slashing animation")
RULE_BOOL(Combat, ArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption") RULE_BOOL(Combat, ArcheryConsumesAmmo, true, "Set to false to disable Archery Ammo Consumption")
RULE_BOOL(Combat, ThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption") RULE_BOOL(Combat, ThrowingConsumesAmmo, true, "Set to false to disable Throwing Ammo Consumption")
RULE_BOOL(Combat, UseLiveRiposteMechanics, false, "Set to true to disable SPA 173 SpellEffect::RiposteChance from making those with the effect on them immune to enrage, can longer riposte from a riposte.") RULE_BOOL(Combat, UseLiveRiposteMechanics, false, "Set to true to disable SPA 173 SE_RiposteChance from making those with the effect on them immune to enrage, can longer riposte from a riposte.")
RULE_INT(Combat, FrontalStunImmunityClasses, 0, "Bitmask for Classes than have frontal stun immunity, No Races (0) by default.") RULE_INT(Combat, FrontalStunImmunityClasses, 0, "Bitmask for Classes than have frontal stun immunity, No Races (0) by default.")
RULE_BOOL(Combat, NPCsUseFrontalStunImmunityClasses, false, "Enable or disable NPCs using frontal stun immunity Classes from Combat:FrontalStunImmunityClasses, false by default.") RULE_BOOL(Combat, NPCsUseFrontalStunImmunityClasses, false, "Enable or disable NPCs using frontal stun immunity Classes from Combat:FrontalStunImmunityClasses, false by default.")
RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have frontal stun immunity, Ogre (512) only by default.") RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have frontal stun immunity, Ogre (512) only by default.")
@ -1079,7 +1073,6 @@ RULE_CATEGORY(Logging)
RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...") RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...")
RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output") RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output")
RULE_BOOL(Logging, PlayerEventsQSProcess, false, "Have query server process player events instead of world. Useful when wanting to use a dedicated server and database for processing player events on separate disk") RULE_BOOL(Logging, PlayerEventsQSProcess, false, "Have query server process player events instead of world. Useful when wanting to use a dedicated server and database for processing player events on separate disk")
RULE_STRING(Logging, PlayerEventsIgnoreGMCommands, "help,show", "This is a comma delimited list of commands to ignore when recording GM command player events.")
RULE_INT(Logging, BatchPlayerEventProcessIntervalSeconds, 5, "This is the interval in which player events are processed in world or qs") RULE_INT(Logging, BatchPlayerEventProcessIntervalSeconds, 5, "This is the interval in which player events are processed in world or qs")
RULE_INT(Logging, BatchPlayerEventProcessChunkSize, 10000, "This is the cap of events that can be inserted into the queue before a force flush. This is to keep from hitting MySQL max_allowed_packet and killing the connection") RULE_INT(Logging, BatchPlayerEventProcessChunkSize, 10000, "This is the cap of events that can be inserted into the queue before a force flush. This is to keep from hitting MySQL max_allowed_packet and killing the connection")
RULE_CATEGORY_END() RULE_CATEGORY_END()

View File

@ -273,9 +273,8 @@
#define ServerOP_WWTaskUpdate 0x4758 #define ServerOP_WWTaskUpdate 0x4758
// player events // player events
#define ServerOP_QSSendQuery 0x5000 #define ServerOP_QSSendQuery 0x5000
#define ServerOP_PlayerEvent 0x5100 #define ServerOP_PlayerEvent 0x5100
#define ServerOP_SendPlayerEventSettings 0x5101
enum { enum {
CZUpdateType_Character, CZUpdateType_Character,
@ -1779,7 +1778,6 @@ struct BazaarPurchaseMessaging_Struct {
uint32 id; uint32 id;
}; };
#pragma pack() #pragma pack()
#endif #endif

View File

@ -48,7 +48,7 @@ enum class SharedTaskRequestGroupType {
struct ServerSharedTaskRequest_Struct { struct ServerSharedTaskRequest_Struct {
uint32 requested_character_id; uint32 requested_character_id;
uint32 requested_task_id; uint32 requested_task_id;
uint32 requested_npc_entity_id; // original task logic passthrough uint32 requested_npc_type_id; // original task logic passthrough
uint32 accept_time; uint32 accept_time;
}; };

View File

@ -51,10 +51,19 @@
#include "repositories/inventory_repository.h" #include "repositories/inventory_repository.h"
#include "repositories/books_repository.h" #include "repositories/books_repository.h"
#include "repositories/sharedbank_repository.h" #include "repositories/sharedbank_repository.h"
#include "repositories/character_inspect_messages_repository.h"
#include "repositories/spells_new_repository.h" namespace ItemField
#include "repositories/damageshieldtypes_repository.h" {
#include "repositories/items_repository.h" enum {
source = 0,
#define F(x) x,
#include "item_fieldlist.h"
#undef F
updated,
minstatus,
comment,
};
}
SharedDatabase::SharedDatabase() SharedDatabase::SharedDatabase()
: Database() : Database()
@ -122,41 +131,66 @@ bool SharedDatabase::SetGMFlymode(uint32 account_id, uint8 flymode)
return a.id > 0; return a.id > 0;
} }
void SharedDatabase::SetMailKey(uint32 character_id, uint32 ip_address, uint32 mail_key) uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
uint32 EntitledTime = 0;
const std::string query = StringFormat("SELECT `time_played` FROM `character_data` WHERE `account_id` = %u", AccountID);
auto results = QueryDatabase(query);
for (auto& row = results.begin(); row != results.end(); ++row) {
EntitledTime += Strings::ToUnsignedInt(row[0]);
}
return EntitledTime;
}
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
{ {
std::string full_mail_key; char mail_key[17];
if (RuleB(Chat, EnableMailKeyIPVerification)) { if (RuleB(Chat, EnableMailKeyIPVerification) == true) {
full_mail_key = fmt::format("{:08X}{:08X}", ip_address, mail_key); sprintf(mail_key, "%08X%08X", IPAddress, MailKey);
} else { }
full_mail_key = fmt::format("{:08X}", mail_key); else {
sprintf(mail_key, "%08X", MailKey);
} }
auto e = CharacterDataRepository::FindOne(*this, character_id); const std::string query = StringFormat(
if (!e.id) { "UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
LogError("Failed to find character_id [{}] when setting mailkey", character_id); mail_key, CharID
return; );
}
e.mailkey = full_mail_key; const auto results = QueryDatabase(query);
if (!results.Success()) {
if (!CharacterDataRepository::UpdateOne(*this, e)) { LogError("SharedDatabase::SetMailKey({}, {}) : {}", CharID, mail_key, results.ErrorMessage().c_str());
LogError("Failed to set mailkey to [{}] for character_id [{}]", full_mail_key, character_id);
} }
} }
SharedDatabase::MailKeys SharedDatabase::GetMailKey(uint32 character_id) SharedDatabase::MailKeys SharedDatabase::GetMailKey(int character_id)
{ {
auto e = CharacterDataRepository::FindOne(*this, character_id); const std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", character_id);
auto results = QueryDatabase(query);
if (!e.id) { if (!results.Success()) {
return MailKeys{ }; return MailKeys{};
} }
return MailKeys{ if (!results.RowCount()) {
.mail_key = e.mailkey.substr(8), Log(Logs::General,
.mail_key_full = e.mailkey Logs::ClientLogin,
}; "Error: Mailkey for character id [%i] does not exist or could not be found",
character_id
);
return MailKeys{};
}
auto &row = results.begin();
if (row != results.end()) {
std::string mail_key = row[0];
return MailKeys{
.mail_key = mail_key.substr(8),
.mail_key_full = mail_key
};
}
return MailKeys{};
} }
bool SharedDatabase::SaveCursor( bool SharedDatabase::SaveCursor(
@ -423,20 +457,27 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id)
); );
} }
int32 SharedDatabase::GetSharedPlatinum(uint32 account_id) int32 SharedDatabase::GetSharedPlatinum(uint32 account_id)
{ {
const auto& e = AccountRepository::FindOne(*this, account_id); const auto query = fmt::format("SELECT sharedplat FROM account WHERE id = {}", account_id);
auto results = QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return 0;
}
return e.sharedplat; auto row = results.begin();
return Strings::ToInt(row[0]);
} }
bool SharedDatabase::AddSharedPlatinum(uint32 account_id, int amount) bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
{ const std::string query = StringFormat("UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id);
auto e = AccountRepository::FindOne(*this, account_id); const auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
e.sharedplat += amount; return true;
return AccountRepository::UpdateOne(*this, e);
} }
bool SharedDatabase::SetStartingItems( bool SharedDatabase::SetStartingItems(
@ -783,7 +824,7 @@ bool SharedDatabase::GetInventory(Client *c)
e.character_id = char_id; e.character_id = char_id;
e.item_id = item_id; e.item_id = item_id;
e.equipped = inst->GetEvolveEquipped(); e.equipped = inst->GetEvolveEquipped();
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(*inst); e.final_item_id = evolving_items_manager.GetFinalItemID(*inst);
auto r = CharacterEvolvingItemsRepository::InsertOne(*this, e); auto r = CharacterEvolvingItemsRepository::InsertOne(*this, e);
e.id = r.id; e.id = r.id;
@ -903,10 +944,27 @@ void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
); );
} }
void SharedDatabase::GetItemsCount(int32& item_count, uint32& max_id) void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
{ {
max_id = ItemsRepository::GetMaxId(*this); item_count = -1;
item_count = ItemsRepository::Count(*this); max_id = 0;
const std::string query = "SELECT MAX(id), count(*) FROM items";
auto results = QueryDatabase(query);
if (!results.Success()) {
return;
}
if (results.RowCount() == 0)
return;
auto& row = results.begin();
if (row[0])
max_id = Strings::ToUnsignedInt(row[0]);
if (row[1])
item_count = Strings::ToUnsignedInt(row[1]);
} }
bool SharedDatabase::LoadItems(const std::string &prefix) { bool SharedDatabase::LoadItems(const std::string &prefix) {
@ -916,7 +974,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
const auto Config = EQEmuConfig::get(); const auto Config = EQEmuConfig::get();
EQ::IPCMutex mutex("items"); EQ::IPCMutex mutex("items");
mutex.Lock(); mutex.Lock();
std::string file_name = fmt::format("{}/{}{}", PathManager::Instance()->GetSharedMemoryPath(), prefix, std::string("items")); std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("items"));
items_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name); items_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
items_hash = std::make_unique<EQ::FixedMemoryHashSet<EQ::ItemData>>(static_cast<uint8*>(items_mmf->Get()), items_mmf->Size()); items_hash = std::make_unique<EQ::FixedMemoryHashSet<EQ::ItemData>>(static_cast<uint8*>(items_mmf->Get()), items_mmf->Size());
mutex.Unlock(); mutex.Unlock();
@ -936,14 +994,14 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
std::string variable_buffer; std::string variable_buffer;
bool disable_attuneable = RuleB(Items, DisableAttuneable); bool disable_attuneable = RuleB(Items, DisableAttuneable);
bool disable_bard_focus_effects = RuleB(Items, DisableBardFocusEffects); bool disable_bard_focus_effects = RuleB(Items, DisableBardFocusEffects);
bool disable_lore = RuleB(Items, DisableLore); bool disable_lore = RuleB(Items, DisableLore);
bool disable_no_drop = RuleB(Items, DisableNoDrop); bool disable_no_drop = RuleB(Items, DisableNoDrop);
bool disable_no_pet = RuleB(Items, DisableNoPet); bool disable_no_pet = RuleB(Items, DisableNoPet);
bool disable_no_rent = RuleB(Items, DisableNoRent); bool disable_no_rent = RuleB(Items, DisableNoRent);
bool disable_no_transfer = RuleB(Items, DisableNoTransfer); bool disable_no_transfer = RuleB(Items, DisableNoTransfer);
bool disable_potion_belt = RuleB(Items, DisablePotionBelt); bool disable_potion_belt = RuleB(Items, DisablePotionBelt);
bool disable_spell_focus_effects = RuleB(Items, DisableSpellFocusEffects); bool disable_spell_focus_effects = RuleB(Items, DisableSpellFocusEffects);
// Old Variable Code // Old Variable Code
@ -974,204 +1032,206 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
EQ::ItemData item; EQ::ItemData item;
const auto& l = ItemsRepository::All(*this); const std::string query = "SELECT source,"
#define F(x) "`"#x"`,"
if (l.empty()) { #include "item_fieldlist.h"
#undef F
"updated, minstatus, comment FROM items ORDER BY id";
auto results = QueryDatabase(query);
if (!results.Success()) {
return; return;
} }
for (const auto& e : l) { for (auto& row = results.begin(); row != results.end(); ++row) {
memset(&item, 0, sizeof(EQ::ItemData)); memset(&item, 0, sizeof(EQ::ItemData));
// Unique Identifier // Unique Identifier
item.ID = e.id; item.ID = Strings::ToUnsignedInt(row[ItemField::id]);
// Minimum Status // Minimum Status
item.MinStatus = static_cast<uint8>(e.minstatus); item.MinStatus = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::minstatus]));
// Name, Lore, and Comment // Name, Lore, and Comment
strn0cpy(item.Name, e.Name.c_str(), sizeof(item.Name)); strn0cpy(item.Name, row[ItemField::name], sizeof(item.Name));
strn0cpy(item.Lore, e.lore.c_str(), sizeof(item.Lore)); strn0cpy(item.Lore, row[ItemField::lore], sizeof(item.Lore));
strn0cpy(item.Comment, e.comment.c_str(), sizeof(item.Comment)); strn0cpy(item.Comment, row[ItemField::comment], sizeof(item.Comment));
// Flags // Flags
item.ArtifactFlag = e.artifactflag; item.ArtifactFlag = Strings::ToBool(row[ItemField::artifactflag]);
item.Attuneable = !disable_attuneable && e.attuneable; item.Attuneable = !disable_attuneable && Strings::ToBool(row[ItemField::attuneable]);
item.BenefitFlag = e.benefitflag; item.BenefitFlag = Strings::ToBool(row[ItemField::benefitflag]);
item.FVNoDrop = e.fvnodrop; item.FVNoDrop = Strings::ToBool(row[ItemField::fvnodrop]);
item.Magic = e.magic; item.Magic = Strings::ToBool(row[ItemField::magic]);
item.NoDrop = disable_no_drop ? std::numeric_limits<uint8>::max() : e.nodrop; item.NoDrop = disable_no_drop ? static_cast<uint8>(255) : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::nodrop]));
item.NoPet = !disable_no_pet && e.nopet; item.NoPet = !disable_no_pet && Strings::ToBool(row[ItemField::nopet]);
item.NoRent = disable_no_rent ? std::numeric_limits<uint8>::max() : e.norent; item.NoRent = disable_no_rent ? static_cast<uint8>(255) : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::norent]));
item.NoTransfer = !disable_no_transfer && e.notransfer; item.NoTransfer = !disable_no_transfer && Strings::ToBool(row[ItemField::notransfer]);
item.PendingLoreFlag = e.pendingloreflag; item.PendingLoreFlag = Strings::ToBool(row[ItemField::pendingloreflag]);
item.QuestItemFlag = e.questitemflag; item.QuestItemFlag = Strings::ToBool(row[ItemField::questitemflag]);
item.Stackable = e.stackable; item.Stackable = Strings::ToBool(row[ItemField::stackable]);
item.Tradeskills = e.tradeskills; item.Tradeskills = Strings::ToBool(row[ItemField::tradeskills]);
item.SummonedFlag = e.summonedflag; item.SummonedFlag = Strings::ToBool(row[ItemField::summonedflag]);
// Lore // Lore
item.LoreGroup = disable_lore ? 0 : e.loregroup; item.LoreGroup = disable_lore ? 0 : Strings::ToInt(row[ItemField::loregroup]);
item.LoreFlag = !disable_lore && item.LoreGroup != 0; item.LoreFlag = !disable_lore && item.LoreGroup != 0;
// Type // Type
item.AugType = e.augtype; item.AugType = Strings::ToUnsignedInt(row[ItemField::augtype]);
item.ItemType = static_cast<uint8>(e.itemtype); item.ItemType = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::itemtype]));
item.SubType = e.subtype; item.SubType = Strings::ToInt(row[ItemField::subtype]);
// Miscellaneous // Miscellaneous
item.ExpendableArrow = e.expendablearrow; item.ExpendableArrow = static_cast<uint16>(Strings::ToUnsignedInt(row[ItemField::expendablearrow]));
item.Light = EQ::Clamp(e.light, -128, 127); item.Light = static_cast<int8>(Strings::ToInt(row[ItemField::light]));
item.MaxCharges = e.maxcharges; item.MaxCharges = static_cast<int16>(Strings::ToInt(row[ItemField::maxcharges]));
item.Size = static_cast<uint8>(e.size); item.Size = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::size]));
item.StackSize = e.stacksize; item.StackSize = static_cast<int16>(Strings::ToInt(row[ItemField::stacksize]));
item.Weight = e.weight; item.Weight = Strings::ToInt(row[ItemField::weight]);
// Potion Belt // Potion Belt
item.PotionBelt = !disable_potion_belt && e.potionbelt; item.PotionBelt = !disable_potion_belt && Strings::ToBool(row[ItemField::potionbelt]);
item.PotionBeltSlots = disable_potion_belt ? 0 : static_cast<uint8>(e.potionbeltslots); item.PotionBeltSlots = disable_potion_belt ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::potionbeltslots]));
// Merchant // Merchant
item.Favor = e.favor; item.Favor = Strings::ToUnsignedInt(row[ItemField::favor]);
item.GuildFavor = e.guildfavor; item.GuildFavor = Strings::ToUnsignedInt(row[ItemField::guildfavor]);
item.Price = e.price; item.Price = Strings::ToUnsignedInt(row[ItemField::price]);
item.SellRate = e.sellrate; item.SellRate = Strings::ToFloat(row[ItemField::sellrate]);
// Display // Display
item.Color = e.color; item.Color = Strings::ToUnsignedInt(row[ItemField::color]);
item.EliteMaterial = e.elitematerial; item.EliteMaterial = Strings::ToUnsignedInt(row[ItemField::elitematerial]);
item.HerosForgeModel = e.herosforgemodel; item.HerosForgeModel = Strings::ToUnsignedInt(row[ItemField::herosforgemodel]);
item.Icon = e.icon; item.Icon = Strings::ToUnsignedInt(row[ItemField::icon]);
strn0cpy(item.IDFile, e.idfile.c_str(), sizeof(item.IDFile)); strn0cpy(item.IDFile, row[ItemField::idfile], sizeof(item.IDFile));
item.Material = e.material; item.Material = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::material]));
// Resists // Resists
item.CR = EQ::Clamp(e.cr, -128, 127); item.CR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::cr]), -128, 127));
item.DR = EQ::Clamp(e.dr, -128, 127); item.DR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::dr]), -128, 127));
item.FR = EQ::Clamp(e.fr, -128, 127); item.FR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::fr]), -128, 127));
item.MR = EQ::Clamp(e.mr, -128, 127); item.MR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::mr]), -128, 127));
item.PR = EQ::Clamp(e.pr, -128, 127); item.PR = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::pr]), -128, 127));
item.SVCorruption = EQ::Clamp(e.svcorruption, -128, 127); item.SVCorruption = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::svcorruption]), -128, 127));
// Heroic Resists // Heroic Resists
item.HeroicCR = e.heroic_cr; item.HeroicCR = Strings::ToInt(row[ItemField::heroic_cr]);
item.HeroicDR = e.heroic_dr; item.HeroicDR = Strings::ToInt(row[ItemField::heroic_dr]);
item.HeroicFR = e.heroic_fr; item.HeroicFR = Strings::ToInt(row[ItemField::heroic_fr]);
item.HeroicMR = e.heroic_mr; item.HeroicMR = Strings::ToInt(row[ItemField::heroic_mr]);
item.HeroicPR = e.heroic_pr; item.HeroicPR = Strings::ToInt(row[ItemField::heroic_pr]);
item.HeroicSVCorrup = e.heroic_svcorrup; item.HeroicSVCorrup = Strings::ToInt(row[ItemField::heroic_svcorrup]);
// Stats // Stats
item.AAgi = EQ::Clamp(e.aagi, -128, 127); item.AAgi = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::aagi]), -128, 127));
item.ACha = EQ::Clamp(e.acha, -128, 127); item.ACha = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::acha]), -128, 127));
item.ADex = EQ::Clamp(e.adex, -128, 127); item.ADex = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::adex]), -128, 127));
item.AInt = EQ::Clamp(e.aint, -128, 127); item.AInt = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::aint]), -128, 127));
item.ASta = EQ::Clamp(e.asta, -128, 127); item.ASta = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::asta]), -128, 127));
item.AStr = EQ::Clamp(e.astr, -128, 127); item.AStr = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::astr]), -128, 127));
item.AWis = EQ::Clamp(e.awis, -128, 127); item.AWis = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::awis]), -128, 127));
// Heroic Stats // Heroic Stats
item.HeroicAgi = e.heroic_agi; item.HeroicAgi = Strings::ToInt(row[ItemField::heroic_agi]);
item.HeroicCha = e.heroic_cha; item.HeroicCha = Strings::ToInt(row[ItemField::heroic_cha]);
item.HeroicDex = e.heroic_dex; item.HeroicDex = Strings::ToInt(row[ItemField::heroic_dex]);
item.HeroicInt = e.heroic_int; item.HeroicInt = Strings::ToInt(row[ItemField::heroic_int]);
item.HeroicSta = e.heroic_sta; item.HeroicSta = Strings::ToInt(row[ItemField::heroic_sta]);
item.HeroicStr = e.heroic_str; item.HeroicStr = Strings::ToInt(row[ItemField::heroic_str]);
item.HeroicWis = e.heroic_wis; item.HeroicWis = Strings::ToInt(row[ItemField::heroic_wis]);
// Health, Mana, and Endurance // Health, Mana, and Endurance
item.HP = e.hp; item.HP = Strings::ToInt(row[ItemField::hp]);
item.Regen = e.regen; item.Regen = Strings::ToInt(row[ItemField::regen]);
item.Mana = e.mana; item.Mana = Strings::ToInt(row[ItemField::mana]);
item.ManaRegen = e.manaregen; item.ManaRegen = Strings::ToInt(row[ItemField::manaregen]);
item.Endur = e.endur; item.Endur = Strings::ToInt(row[ItemField::endur]);
item.EnduranceRegen = e.enduranceregen; item.EnduranceRegen = Strings::ToInt(row[ItemField::enduranceregen]);
// Bane Damage // Bane Damage
item.BaneDmgAmt = e.banedmgamt; item.BaneDmgAmt = Strings::ToInt(row[ItemField::banedmgamt]);
item.BaneDmgBody = e.banedmgbody; item.BaneDmgBody = Strings::ToUnsignedInt(row[ItemField::banedmgbody]);
item.BaneDmgRace = e.banedmgrace; item.BaneDmgRace = Strings::ToUnsignedInt(row[ItemField::banedmgrace]);
item.BaneDmgRaceAmt = e.banedmgraceamt; item.BaneDmgRaceAmt = Strings::ToUnsignedInt(row[ItemField::banedmgraceamt]);
// Elemental Damage // Elemental Damage
item.ElemDmgType = static_cast<uint8>(e.elemdmgtype); item.ElemDmgType = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::elemdmgtype]));
item.ElemDmgAmt = static_cast<uint8>(e.elemdmgamt); item.ElemDmgAmt = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::elemdmgamt]));
// Combat // Combat
item.BackstabDmg = e.backstabdmg; item.BackstabDmg = Strings::ToUnsignedInt(row[ItemField::backstabdmg]);
item.Damage = e.damage; item.Damage = Strings::ToUnsignedInt(row[ItemField::damage]);
item.Delay = static_cast<uint8>(e.delay); item.Delay = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::delay]));
item.Range = static_cast<uint8>(e.range_); item.Range = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::range]));
// Combat Stats // Combat Stats
item.AC = e.ac; item.AC = Strings::ToInt(row[ItemField::ac]);
item.Accuracy = EQ::Clamp(e.accuracy, -128, 127); item.Accuracy = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::accuracy]), -128, 127));
item.Attack = e.attack; item.Attack = Strings::ToInt(row[ItemField::attack]);
item.Avoidance = EQ::Clamp(e.avoidance, -128, 127); item.Avoidance = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::avoidance]), -128, 127));
item.Clairvoyance = e.clairvoyance; item.Clairvoyance = Strings::ToUnsignedInt(row[ItemField::clairvoyance]);
item.CombatEffects = Strings::IsNumber(e.combateffects) ? static_cast<int8>(EQ::Clamp(Strings::ToInt(e.combateffects), -128, 127)) : 0; item.CombatEffects = Strings::IsNumber(row[ItemField::combateffects]) ? static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::combateffects]), -128, 127)) : 0;
item.DamageShield = e.damageshield; item.DamageShield = Strings::ToInt(row[ItemField::damageshield]);
item.DotShielding = e.dotshielding; item.DotShielding = Strings::ToInt(row[ItemField::dotshielding]);
item.DSMitigation = e.dsmitigation; item.DSMitigation = Strings::ToUnsignedInt(row[ItemField::dsmitigation]);
item.Haste = e.haste; item.Haste = Strings::ToInt(row[ItemField::haste]);
item.HealAmt = e.healamt; item.HealAmt = Strings::ToInt(row[ItemField::healamt]);
item.Purity = e.purity; item.Purity = Strings::ToUnsignedInt(row[ItemField::purity]);
item.Shielding = EQ::Clamp(e.shielding, -128, 127); item.Shielding = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::shielding]), -128, 127));
item.SpellDmg = e.spelldmg; item.SpellDmg = Strings::ToInt(row[ItemField::spelldmg]);
item.SpellShield = EQ::Clamp(e.spellshield, -128, 127); item.SpellShield = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::spellshield]), -128, 127));
item.StrikeThrough = EQ::Clamp(e.strikethrough, -128, 127); item.StrikeThrough = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::strikethrough]), -128, 127));
item.StunResist = EQ::Clamp(e.stunresist, -128, 127); item.StunResist = static_cast<int8>(EQ::Clamp(Strings::ToInt(row[ItemField::stunresist]), -128, 127));
// Restrictions // Restrictions
item.AugRestrict = e.augrestrict; item.AugRestrict = Strings::ToUnsignedInt(row[ItemField::augrestrict]);
item.Classes = e.classes; item.Classes = Strings::ToUnsignedInt(row[ItemField::classes]);
item.Deity = e.deity; item.Deity = Strings::ToUnsignedInt(row[ItemField::deity]);
item.ItemClass = static_cast<uint8>(e.itemclass); item.ItemClass = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::itemclass]));
item.Races = e.races; item.Races = Strings::ToUnsignedInt(row[ItemField::races]);
item.RecLevel = static_cast<uint8>(e.reclevel); item.RecLevel = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::reclevel]));
item.RecSkill = static_cast<uint8>(e.recskill); item.RecSkill = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::recskill]));
item.ReqLevel = static_cast<uint8>(e.reqlevel); item.ReqLevel = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::reqlevel]));
item.Slots = e.slots; item.Slots = Strings::ToUnsignedInt(row[ItemField::slots]);
// Skill Modifier // Skill Modifier
item.SkillModValue = e.skillmodvalue; item.SkillModValue = Strings::ToInt(row[ItemField::skillmodvalue]);
item.SkillModMax = e.skillmodmax; item.SkillModMax = Strings::ToInt(row[ItemField::skillmodmax]);
item.SkillModType = e.skillmodtype; item.SkillModType = Strings::ToUnsignedInt(row[ItemField::skillmodtype]);
// Extra Damage Skill // Extra Damage Skill
item.ExtraDmgSkill = e.extradmgskill; item.ExtraDmgSkill = Strings::ToInt(row[ItemField::extradmgskill]);
item.ExtraDmgAmt = e.extradmgamt; item.ExtraDmgAmt = Strings::ToInt(row[ItemField::extradmgamt]);
// Bard // Bard
item.BardType = e.bardtype; item.BardType = Strings::ToUnsignedInt(row[ItemField::bardtype]);
item.BardValue = e.bardvalue; item.BardValue = Strings::ToInt(row[ItemField::bardvalue]);
// Faction // Faction
item.FactionAmt1 = e.factionamt1; item.FactionAmt1 = Strings::ToInt(row[ItemField::factionamt1]);
item.FactionMod1 = e.factionmod1; item.FactionMod1 = Strings::ToInt(row[ItemField::factionmod1]);
item.FactionAmt2 = e.factionamt2; item.FactionAmt2 = Strings::ToInt(row[ItemField::factionamt2]);
item.FactionMod2 = e.factionmod2; item.FactionMod2 = Strings::ToInt(row[ItemField::factionmod2]);
item.FactionAmt3 = e.factionamt3; item.FactionAmt3 = Strings::ToInt(row[ItemField::factionamt3]);
item.FactionMod3 = e.factionmod3; item.FactionMod3 = Strings::ToInt(row[ItemField::factionmod3]);
item.FactionAmt4 = e.factionamt4; item.FactionAmt4 = Strings::ToInt(row[ItemField::factionamt4]);
item.FactionMod4 = e.factionmod4; item.FactionMod4 = Strings::ToInt(row[ItemField::factionmod4]);
// Augment Distiller // Augment
item.AugDistiller = e.augdistiller; item.AugDistiller = Strings::ToUnsignedInt(row[ItemField::augdistiller]);
item.AugSlotType[0] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot1type]));
// Augment Slots item.AugSlotVisible[0] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot1visible]));
item.AugSlotType[0] = static_cast<uint8>(e.augslot1type); item.AugSlotType[1] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot2type]));
item.AugSlotVisible[0] = static_cast<uint8>(e.augslot1visible); item.AugSlotVisible[1] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot2visible]));
item.AugSlotType[1] = static_cast<uint8>(e.augslot2type); item.AugSlotType[2] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot3type]));
item.AugSlotVisible[1] = static_cast<uint8>(e.augslot2visible); item.AugSlotVisible[2] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot3visible]));
item.AugSlotType[2] = static_cast<uint8>(e.augslot3type); item.AugSlotType[3] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot4type]));
item.AugSlotVisible[2] = static_cast<uint8>(e.augslot3visible); item.AugSlotVisible[3] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot4visible]));
item.AugSlotType[3] = static_cast<uint8>(e.augslot4type); item.AugSlotType[4] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot5type]));
item.AugSlotVisible[3] = static_cast<uint8>(e.augslot4visible); item.AugSlotVisible[4] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot5visible]));
item.AugSlotType[4] = static_cast<uint8>(e.augslot5type); item.AugSlotType[5] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot6type]));
item.AugSlotVisible[4] = static_cast<uint8>(e.augslot5visible); item.AugSlotVisible[5] = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::augslot6visible]));
item.AugSlotType[5] = static_cast<uint8>(e.augslot6type);
item.AugSlotVisible[5] = static_cast<uint8>(e.augslot6visible);
// Augment Unknowns // Augment Unknowns
for (uint8 i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) { for (uint8 i = EQ::invaug::SOCKET_BEGIN; i <= EQ::invaug::SOCKET_END; i++) {
@ -1179,79 +1239,79 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
} }
// LDoN // LDoN
item.LDoNTheme = e.ldontheme; item.LDoNTheme = Strings::ToUnsignedInt(row[ItemField::ldontheme]);
item.LDoNPrice = e.ldonprice; item.LDoNPrice = Strings::ToUnsignedInt(row[ItemField::ldonprice]);
item.LDoNSellBackRate = e.ldonsellbackrate; item.LDoNSellBackRate = Strings::ToUnsignedInt(row[ItemField::ldonsellbackrate]);
item.LDoNSold = e.ldonsold; item.LDoNSold = Strings::ToUnsignedInt(row[ItemField::ldonsold]);
item.PointType = e.pointtype; item.PointType = Strings::ToUnsignedInt(row[ItemField::pointtype]);
// Bag // Bag
item.BagSize = static_cast<uint8>(e.bagsize); item.BagSize = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bagsize]));
item.BagSlots = EQ::Clamp(e.bagslots, 0, static_cast<int>(EQ::invbag::SLOT_COUNT)); item.BagSlots = static_cast<uint8>(EQ::Clamp(Strings::ToInt(row[ItemField::bagslots]), 0, static_cast<int>(EQ::invbag::SLOT_COUNT)));
item.BagType = static_cast<uint8>(e.bagtype); item.BagType = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bagtype]));
item.BagWR = EQ::Clamp(e.bagwr, 0, 100); item.BagWR = static_cast<uint8>(EQ::Clamp(Strings::ToInt(row[ItemField::bagwr]), 0, 100));
// Bard Effect // Bard Effect
item.Bard.Effect = disable_bard_focus_effects ? 0 : e.bardeffect; item.Bard.Effect = disable_bard_focus_effects ? 0 : Strings::ToInt(row[ItemField::bardeffect]);
item.Bard.Type = disable_bard_focus_effects ? 0 : static_cast<uint8>(e.bardtype); item.Bard.Type = disable_bard_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bardtype]));
item.Bard.Level = disable_bard_focus_effects ? 0 : static_cast<uint8>(e.bardlevel); item.Bard.Level = disable_bard_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bardlevel]));
item.Bard.Level2 = disable_bard_focus_effects ? 0 : static_cast<uint8>(e.bardlevel2); item.Bard.Level2 = disable_bard_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::bardlevel2]));
// Book // Book
item.Book = static_cast<uint8>(e.book); item.Book = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::book]));
item.BookType = e.booktype; item.BookType = Strings::ToUnsignedInt(row[ItemField::booktype]);
// Click Effect // Click Effect
item.CastTime = e.casttime; item.CastTime = Strings::ToUnsignedInt(row[ItemField::casttime]);
item.CastTime_ = e.casttime_; item.CastTime_ = Strings::ToInt(row[ItemField::casttime_]);
item.Click.Effect = e.clickeffect; item.Click.Effect = Strings::ToInt(row[ItemField::clickeffect]);
item.Click.Type = static_cast<uint8>(e.clicktype); item.Click.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::clicktype]));
item.Click.Level = static_cast<uint8>(e.clicklevel); item.Click.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::clicklevel]));
item.Click.Level2 = static_cast<uint8>(e.clicklevel2); item.Click.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::clicklevel2]));
strn0cpy(item.ClickName, e.clickname.c_str(), sizeof(item.ClickName)); strn0cpy(item.ClickName, row[ItemField::clickname], sizeof(item.ClickName));
item.RecastDelay = e.recastdelay; item.RecastDelay = Strings::ToUnsignedInt(row[ItemField::recastdelay]);
item.RecastType = e.recasttype; item.RecastType = Strings::ToInt(row[ItemField::recasttype]);
// Focus Effect // Focus Effect
item.Focus.Effect = disable_spell_focus_effects ? 0 : e.focuseffect; item.Focus.Effect = disable_spell_focus_effects ? 0 : Strings::ToInt(row[ItemField::focuseffect]);
item.Focus.Type = disable_spell_focus_effects ? 0 : static_cast<uint8>(e.focustype); item.Focus.Type = disable_spell_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::focustype]));
item.Focus.Level = disable_spell_focus_effects ? 0 : static_cast<uint8>(e.focuslevel); item.Focus.Level = disable_spell_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::focuslevel]));
item.Focus.Level2 = disable_spell_focus_effects ? 0 : static_cast<uint8>(e.focuslevel2); item.Focus.Level2 = disable_spell_focus_effects ? 0 : static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::focuslevel2]));
strn0cpy(item.FocusName, disable_spell_focus_effects ? "" : e.focusname.c_str(), sizeof(item.FocusName)); strn0cpy(item.FocusName, disable_spell_focus_effects ? "" : row[ItemField::focusname], sizeof(item.FocusName));
// Proc Effect // Proc Effect
item.Proc.Effect = e.proceffect; item.Proc.Effect = Strings::ToInt(row[ItemField::proceffect]);
item.Proc.Type = static_cast<uint8>(e.proctype); item.Proc.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::proctype]));
item.Proc.Level = static_cast<uint8>(e.proclevel); item.Proc.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::proclevel]));
item.Proc.Level2 = static_cast<uint8>(e.proclevel2); item.Proc.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::proclevel2]));
strn0cpy(item.ProcName, e.procname.c_str(), sizeof(item.ProcName)); strn0cpy(item.ProcName, row[ItemField::procname], sizeof(item.ProcName));
item.ProcRate = e.procrate; item.ProcRate = Strings::ToInt(row[ItemField::procrate]);
// Scroll Effect // Scroll Effect
item.Scroll.Effect = e.scrolleffect; item.Scroll.Effect = Strings::ToInt(row[ItemField::scrolleffect]);
item.Scroll.Type = static_cast<uint8>(e.scrolltype); item.Scroll.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::scrolltype]));
item.Scroll.Level = static_cast<uint8>(e.scrolllevel); item.Scroll.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::scrolllevel]));
item.Scroll.Level2 = static_cast<uint8>(e.scrolllevel2); item.Scroll.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::scrolllevel2]));
strn0cpy(item.ScrollName, e.scrollname.c_str(), sizeof(item.ScrollName)); strn0cpy(item.ScrollName, row[ItemField::scrollname], sizeof(item.ScrollName));
// Worn Effect // Worn Effect
item.Worn.Effect = e.worneffect; item.Worn.Effect = Strings::ToInt(row[ItemField::worneffect]);
item.Worn.Type = static_cast<uint8>(e.worntype); item.Worn.Type = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::worntype]));
item.Worn.Level = static_cast<uint8>(e.wornlevel); item.Worn.Level = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::wornlevel]));
item.Worn.Level2 = static_cast<uint8>(e.wornlevel2); item.Worn.Level2 = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::wornlevel2]));
strn0cpy(item.WornName, e.wornname.c_str(), sizeof(item.WornName)); strn0cpy(item.WornName, row[ItemField::wornname], sizeof(item.WornName));
// Evolving Item // Evolving Item
item.EvolvingID = e.evoid; item.EvolvingID = Strings::ToUnsignedInt(row[ItemField::evoid]);
item.EvolvingItem = static_cast<uint8>(e.evoitem); item.EvolvingItem = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::evoitem]));
item.EvolvingLevel = static_cast<uint8>(e.evolvinglevel); item.EvolvingLevel = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::evolvinglevel]));
item.EvolvingMax = static_cast<uint8>(e.evomax); item.EvolvingMax = static_cast<uint8>(Strings::ToUnsignedInt(row[ItemField::evomax]));
// Scripting // Scripting
item.CharmFileID = Strings::IsNumber(e.charmfileid) ? Strings::ToUnsignedInt(e.charmfileid) : 0; item.CharmFileID = Strings::IsNumber(row[ItemField::charmfileid]) ? Strings::ToUnsignedInt(row[ItemField::charmfileid]) : 0;
strn0cpy(item.CharmFile, e.charmfile.c_str(), sizeof(item.CharmFile)); strn0cpy(item.CharmFile, row[ItemField::charmfile], sizeof(item.CharmFile));
strn0cpy(item.Filename, e.filename.c_str(), sizeof(item.Filename)); strn0cpy(item.Filename, row[ItemField::filename], sizeof(item.Filename));
item.ScriptFileID = e.scriptfileid; item.ScriptFileID = Strings::ToUnsignedInt(row[ItemField::scriptfileid]);
try { try {
hash.insert(item.ID, item); hash.insert(item.ID, item);
@ -1484,60 +1544,12 @@ bool SharedDatabase::GetCommandSettings(std::map<std::string, std::pair<uint8, s
return true; return true;
} }
template<typename T1, typename T2>
inline std::vector<std::string> join_pair(
const std::string &glue,
const std::pair<char, char> &encapsulation,
const std::vector<std::pair<T1, T2>> &src
)
{
if (src.empty()) {
return {};
}
std::vector<std::string> output;
for (const std::pair<T1, T2> &src_iter: src) {
output.emplace_back(
fmt::format(
"{}{}{}{}{}{}{}",
encapsulation.first,
src_iter.first,
encapsulation.second,
glue,
encapsulation.first,
src_iter.second,
encapsulation.second
)
);
}
return output;
}
template<typename T>
inline std::string
ImplodePair(const std::string &glue, const std::pair<char, char> &encapsulation, const std::vector<T> &src)
{
if (src.empty()) {
return {};
}
std::ostringstream oss;
for (const T &src_iter: src) {
oss << encapsulation.first << src_iter << encapsulation.second << glue;
}
std::string output(oss.str());
output.resize(output.size() - glue.size());
return output;
}
bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected) bool SharedDatabase::UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected)
{ {
if (injected.size()) { if (injected.size()) {
const std::string query = fmt::format( const std::string query = fmt::format(
"REPLACE INTO `command_settings`(`command`, `access`) VALUES {}", "REPLACE INTO `command_settings`(`command`, `access`) VALUES {}",
ImplodePair( Strings::ImplodePair(
",", ",",
std::pair<char, char>('(', ')'), std::pair<char, char>('(', ')'),
join_pair(",", std::pair<char, char>('\'', '\''), injected) join_pair(",", std::pair<char, char>('\'', '\''), injected)
@ -1564,7 +1576,7 @@ bool SharedDatabase::UpdateOrphanedCommandSettings(const std::vector<std::string
if (orphaned.size()) { if (orphaned.size()) {
std::string query = fmt::format( std::string query = fmt::format(
"DELETE FROM `command_settings` WHERE `command` IN ({})", "DELETE FROM `command_settings` WHERE `command` IN ({})",
ImplodePair(",", std::pair<char, char>('\'', '\''), orphaned) Strings::ImplodePair(",", std::pair<char, char>('\'', '\''), orphaned)
); );
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
@ -1574,7 +1586,7 @@ bool SharedDatabase::UpdateOrphanedCommandSettings(const std::vector<std::string
query = fmt::format( query = fmt::format(
"DELETE FROM `command_subsettings` WHERE `parent_command` IN ({})", "DELETE FROM `command_subsettings` WHERE `parent_command` IN ({})",
ImplodePair(",", std::pair<char, char>('\'', '\''), orphaned) Strings::ImplodePair(",", std::pair<char, char>('\'', '\''), orphaned)
); );
auto results_two = QueryDatabase(query); auto results_two = QueryDatabase(query);
@ -1613,17 +1625,20 @@ bool SharedDatabase::GetCommandSubSettings(std::vector<CommandSubsettingsReposit
return true; return true;
} }
void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* s) void SharedDatabase::LoadDamageShieldTypes(SPDat_Spell_Struct* sp, int32 iMaxSpellID) {
{ const std::string query = StringFormat("SELECT `spellid`, `type` FROM `damageshieldtypes` WHERE `spellid` > 0 "
const auto& l = DamageshieldtypesRepository::All(*this); "AND `spellid` <= %i", iMaxSpellID);
auto results = QueryDatabase(query);
if (!results.Success()) {
return;
}
if (l.empty()) { for(auto& row = results.begin(); row != results.end(); ++row) {
return; const int spellID = Strings::ToInt(row[0]);
} if((spellID > 0) && (spellID <= iMaxSpellID))
sp[spellID].damage_shield_type = Strings::ToUnsignedInt(row[1]);
}
for (const auto& e : l) {
s[e.spellid].damage_shield_type = e.type;
}
} }
const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) { const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) {
@ -1650,7 +1665,7 @@ bool SharedDatabase::LoadSpells(const std::string &prefix, int32 *records, const
EQ::IPCMutex mutex("spells"); EQ::IPCMutex mutex("spells");
mutex.Lock(); mutex.Lock();
std::string file_name = fmt::format("{}/{}{}", PathManager::Instance()->GetSharedMemoryPath(), prefix, std::string("spells")); std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("spells"));
spells_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name); spells_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
LogInfo("Loading [{}]", file_name); LogInfo("Loading [{}]", file_name);
*records = *static_cast<uint32*>(spells_mmf->Get()); *records = *static_cast<uint32*>(spells_mmf->Get());
@ -1840,32 +1855,21 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
sp[tempid].damage_shield_type = 0; sp[tempid].damage_shield_type = 0;
} }
LoadDamageShieldTypes(sp); LoadDamageShieldTypes(sp, max_spells);
} }
void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* s) void SharedDatabase::LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message) {
{ const std::string query = StringFormat("SELECT `inspect_message` FROM `character_inspect_messages` WHERE `id` = %u LIMIT 1", character_id);
const auto& e = CharacterInspectMessagesRepository::FindOne(*this, character_id); auto results = QueryDatabase(query);
memset(message, '\0', sizeof(InspectMessage_Struct));
memset(s, '\0', sizeof(InspectMessage_Struct)); for (auto& row = results.begin(); row != results.end(); ++row) {
memcpy(message, row[0], sizeof(InspectMessage_Struct));
if (!e.id) {
return;
} }
memcpy(s, e.inspect_message.c_str(), sizeof(InspectMessage_Struct));
} }
void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* s) void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message) {
{ const std::string query = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message) VALUES (%u, '%s')", character_id, Strings::Escape(message->text).c_str());
auto e = CharacterInspectMessagesRepository::NewEntity(); auto results = QueryDatabase(query);
e.id = character_id;
e.inspect_message = s->text;
if (!CharacterInspectMessagesRepository::ReplaceOne(*this, e)) {
LogError("Failed to save character inspect message of [{}] for character_id [{}]", s->text, character_id);
}
} }
uint32 SharedDatabase::GetSpellsCount() uint32 SharedDatabase::GetSpellsCount()
@ -1886,7 +1890,18 @@ uint32 SharedDatabase::GetSpellsCount()
uint32 SharedDatabase::GetItemsCount() uint32 SharedDatabase::GetItemsCount()
{ {
return ItemsRepository::Count(*this); auto results = QueryDatabase("SELECT count(*) FROM items");
if (!results.Success() || !results.RowCount()) {
return 0;
}
auto& row = results.begin();
if (row[0]) {
return Strings::ToUnsignedInt(row[0]);
}
return 0;
} }
void SharedDatabase::SetSharedItemsCount(uint32 shared_items_count) void SharedDatabase::SetSharedItemsCount(uint32 shared_items_count)

View File

@ -76,20 +76,21 @@ public:
uint8 GetGMSpeed(uint32 account_id); uint8 GetGMSpeed(uint32 account_id);
bool SetHideMe(uint32 account_id, uint8 hideme); bool SetHideMe(uint32 account_id, uint8 hideme);
int DeleteStalePlayerCorpses(); int DeleteStalePlayerCorpses();
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* s); void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct *message);
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* s); void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct *message);
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings); bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected); bool UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned); bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings); bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
bool SetGMInvul(uint32 account_id, bool gminvul); bool SetGMInvul(uint32 account_id, bool gminvul);
bool SetGMFlymode(uint32 account_id, uint8 flymode); bool SetGMFlymode(uint32 account_id, uint8 flymode);
void SetMailKey(uint32 character_id, uint32 ip_address, uint32 mail_key); void SetMailKey(int CharID, int IPAddress, int MailKey);
struct MailKeys { struct MailKeys {
std::string mail_key; std::string mail_key;
std::string mail_key_full; std::string mail_key_full;
}; };
MailKeys GetMailKey(uint32 character_id); MailKeys GetMailKey(int character_id);
bool SaveCursor( bool SaveCursor(
uint32 char_id, uint32 char_id,
std::list<EQ::ItemInstance *>::const_iterator &start, std::list<EQ::ItemInstance *>::const_iterator &start,
@ -103,7 +104,7 @@ public:
bool VerifyInventory(uint32 account_id, int16 slot_id, const EQ::ItemInstance *inst); bool VerifyInventory(uint32 account_id, int16 slot_id, const EQ::ItemInstance *inst);
bool GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is_charid); bool GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is_charid);
int32 GetSharedPlatinum(uint32 account_id); int32 GetSharedPlatinum(uint32 account_id);
bool AddSharedPlatinum(uint32 account_id, int amount); bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
bool GetInventory(Client* c); bool GetInventory(Client* c);
bool GetInventory(uint32 account_id, char *name, EQ::InventoryProfile *inv); // deprecated bool GetInventory(uint32 account_id, char *name, EQ::InventoryProfile *inv); // deprecated
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id); std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
@ -157,7 +158,7 @@ public:
); );
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0); EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);
void GetItemsCount(int32& item_count, uint32& max_id); void GetItemsCount(int32 &item_count, uint32 &max_id);
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id); void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
bool LoadItems(const std::string &prefix); bool LoadItems(const std::string &prefix);
const EQ::ItemData *IterateItems(uint32 *id) const; const EQ::ItemData *IterateItems(uint32 *id) const;
@ -172,7 +173,7 @@ public:
int GetMaxSpellID(); int GetMaxSpellID();
bool LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp); bool LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp);
void LoadSpells(void *data, int max_spells); void LoadSpells(void *data, int max_spells);
void LoadDamageShieldTypes(SPDat_Spell_Struct* s); void LoadDamageShieldTypes(SPDat_Spell_Struct *sp, int32 iMaxSpellID);
uint32 GetSharedSpellsCount() { return m_shared_spells_count; } uint32 GetSharedSpellsCount() { return m_shared_spells_count; }
uint32 GetSpellsCount(); uint32 GetSpellsCount();

View File

@ -16,16 +16,12 @@ public:
static int32_t GetSkillCapMaxLevel(uint8 class_id, EQ::skills::SkillType skill_id); static int32_t GetSkillCapMaxLevel(uint8 class_id, EQ::skills::SkillType skill_id);
SkillCaps *SetContentDatabase(Database *db); SkillCaps *SetContentDatabase(Database *db);
static SkillCaps* Instance()
{
static SkillCaps instance;
return &instance;
}
private: private:
Database *m_content_database{}; Database *m_content_database{};
std::map<uint64, SkillCapsRepository::SkillCaps> m_skill_caps = {}; std::map<uint64, SkillCapsRepository::SkillCaps> m_skill_caps = {};
}; };
extern SkillCaps skill_caps;
#endif //CODE_SKILL_CAPS_H #endif //CODE_SKILL_CAPS_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -358,7 +358,6 @@ bool RequiresStackCheck(uint16 spell_type) {
case BotSpellTypes::CompleteHeal: case BotSpellTypes::CompleteHeal:
case BotSpellTypes::PetCompleteHeals: case BotSpellTypes::PetCompleteHeals:
case BotSpellTypes::GroupCompleteHeals: case BotSpellTypes::GroupCompleteHeals:
case BotSpellTypes::Resurrect:
return false; return false;
default: default:
return true; return true;

View File

@ -34,7 +34,6 @@
*/ */
#include "strings.h" #include "strings.h"
#include <cereal/external/rapidjson/document.h>
#include <fmt/format.h> #include <fmt/format.h>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
@ -42,7 +41,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <sstream>
#include <random> #include <random>
#include <string> #include <string>
@ -51,12 +49,6 @@
#include "strings_legacy.cpp" // legacy c functions #include "strings_legacy.cpp" // legacy c functions
#include "strings_misc.cpp" // anything non "Strings" scoped #include "strings_misc.cpp" // anything non "Strings" scoped
#ifdef _WINDOWS
#include <ctype.h>
#include <functional>
#include <algorithm>
#endif
std::string Strings::Random(size_t length) std::string Strings::Random(size_t length)
{ {
static auto &chrs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static auto &chrs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
@ -313,12 +305,6 @@ std::string Strings::Commify(const std::string &number)
auto string_length = static_cast<int>(number.length()); auto string_length = static_cast<int>(number.length());
if (string_length == 3) {
return number;
} else if (string_length == 4 && number.starts_with("-")) {
return number;
}
int i = 0; int i = 0;
for (i = string_length - 3; i >= 0; i -= 3) { for (i = string_length - 3; i >= 0; i -= 3) {
if (i > 0) { if (i > 0) {
@ -715,18 +701,6 @@ std::string &Strings::Trim(std::string &str, const std::string &chars)
return LTrim(RTrim(str, chars), chars); return LTrim(RTrim(str, chars), chars);
} }
const std::string NUM_TO_ENGLISH_X[] = {
"", "One ", "Two ", "Three ", "Four ",
"Five ", "Six ", "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ",
"Twelve ", "Thirteen ", "Fourteen ", "Fifteen ",
"Sixteen ", "Seventeen ", "Eighteen ", "Nineteen "
};
const std::string NUM_TO_ENGLISH_Y[] = {
"", "", "Twenty ", "Thirty ", "Forty ",
"Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "
};
// Function to convert single digit or two digit number into words // Function to convert single digit or two digit number into words
std::string Strings::ConvertToDigit(int n, const std::string& suffix) std::string Strings::ConvertToDigit(int n, const std::string& suffix)
{ {

View File

@ -36,19 +36,53 @@
#define _STRINGUTIL_H_ #define _STRINGUTIL_H_
#include <charconv> #include <charconv>
#include <cstring> #include <sstream>
#include <string.h>
#include <string_view> #include <string_view>
#include <string>
#include <vector> #include <vector>
#include <cstdarg> #include <cstdarg>
#include <tuple>
#include <type_traits> #include <type_traits>
#ifdef _WIN32 #include <fmt/format.h>
#include <cereal/external/rapidjson/document.h>
#ifndef _WIN32
// this doesn't appear to affect linux-based systems..need feedback for _WIN64
#endif
#ifdef _WINDOWS
#include <ctype.h> #include <ctype.h>
#include <functional>
#include <algorithm>
#endif #endif
#include "types.h" #include "types.h"
namespace detail {
// template magic to check if std::from_chars floating point functions exist
template <typename T, typename = void>
struct has_from_chars_float : std::false_type { };
// basically it "uses" this template if they do exist because reasons
template <typename T>
struct has_from_chars_float < T,
std::void_t<decltype(std::from_chars(std::declval<const char *>(), std::declval<const char *>(),
std::declval<T &>()))>> : std::true_type { };
}; // namespace detail
namespace EQ {
// lame -- older GCC's didn't define this, clang's libc++ however does, even though they lack FP support
#if defined(__GNUC__) && (__GNUC__ < 11) && !defined(__clang__)
enum class chars_format {
scientific = 1, fixed = 2, hex = 4, general = fixed | scientific
};
#else
using chars_format = std::chars_format;
#endif
}; // namespace EQ
class Strings { class Strings {
public: public:
static bool Contains(std::vector<std::string> container, const std::string& element); static bool Contains(std::vector<std::string> container, const std::string& element);
@ -99,6 +133,61 @@ public:
static bool BeginsWith(const std::string& subject, const std::string& search); static bool BeginsWith(const std::string& subject, const std::string& search);
static bool EndsWith(const std::string& subject, const std::string& search); static bool EndsWith(const std::string& subject, const std::string& search);
static std::string ZoneTime(const uint8 hours, const uint8 minutes); static std::string ZoneTime(const uint8 hours, const uint8 minutes);
template<typename T>
static std::string
ImplodePair(const std::string &glue, const std::pair<char, char> &encapsulation, const std::vector<T> &src)
{
if (src.empty()) {
return {};
}
std::ostringstream oss;
for (const T &src_iter: src) {
oss << encapsulation.first << src_iter << encapsulation.second << glue;
}
std::string output(oss.str());
output.resize(output.size() - glue.size());
return output;
}
// basic string_view overloads that just use std stuff since they work!
template <typename T>
std::enable_if_t<std::is_floating_point_v<T> && detail::has_from_chars_float<T>::value, std::from_chars_result>
static from_chars(std::string_view str, T& value, EQ::chars_format fmt = EQ::chars_format::general)
{
return std::from_chars(str.data(), str.data() + str.size(), value, fmt);
}
template <typename T>
std::enable_if_t<std::is_integral_v<T>, std::from_chars_result>
static from_chars(std::string_view str, T& value, int base = 10)
{
return std::from_chars(str.data(), str.data() + str.size(), value, base);
}
// fallback versions of floating point in case they're not implemented
// TODO: add error handling ...
// This does have to allocate since from_chars doesn't need a null terminated string and neither does string_view
template <typename T>
std::enable_if_t<std::is_floating_point_v<T> && !detail::has_from_chars_float<T>::value && std::is_same_v<T, float>, std::from_chars_result>
static from_chars(std::string_view str, T& value, EQ::chars_format fmt = EQ::chars_format::general)
{
std::from_chars_result res{};
std::string tmp_str(str.data(), str.size());
value = strtof(tmp_str.data(), nullptr);
return res;
}
template <typename T>
std::enable_if_t<std::is_floating_point_v<T> && !detail::has_from_chars_float<T>::value && std::is_same_v<T, double>, std::from_chars_result>
static from_chars(std::string_view str, T& value, EQ::chars_format fmt = EQ::chars_format::general)
{
std::from_chars_result res{};
std::string tmp_str(str.data(), str.size());
value = strtod(tmp_str.data(), nullptr);
return res;
}
static std::string Slugify(const std::string &input, const std::string &separator = "-"); static std::string Slugify(const std::string &input, const std::string &separator = "-");
static bool IsValidJson(const std::string& json); static bool IsValidJson(const std::string& json);
}; };
@ -110,6 +199,93 @@ const std::string vStringFormat(const char *format, va_list args);
// Used for grid nodes, as NPC names remove numerals. // Used for grid nodes, as NPC names remove numerals.
// But general purpose // But general purpose
const std::string NUM_TO_ENGLISH_X[] = {
"", "One ", "Two ", "Three ", "Four ",
"Five ", "Six ", "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ",
"Twelve ", "Thirteen ", "Fourteen ", "Fifteen ",
"Sixteen ", "Seventeen ", "Eighteen ", "Nineteen "
};
const std::string NUM_TO_ENGLISH_Y[] = {
"", "", "Twenty ", "Thirty ", "Forty ",
"Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "
};
// _WIN32 builds require that #include<fmt/format.h> be included in whatever code file the invocation is made from (no header files)
template<typename T1, typename T2>
std::vector<std::string> join_pair(
const std::string &glue,
const std::pair<char, char> &encapsulation,
const std::vector<std::pair<T1, T2>> &src
)
{
if (src.empty()) {
return {};
}
std::vector<std::string> output;
for (const std::pair<T1, T2> &src_iter: src) {
output.emplace_back(
fmt::format(
"{}{}{}{}{}{}{}",
encapsulation.first,
src_iter.first,
encapsulation.second,
glue,
encapsulation.first,
src_iter.second,
encapsulation.second
)
);
}
return output;
}
// _WIN32 builds require that #include<fmt/format.h> be included in whatever code file the invocation is made from (no header files)
template<typename T1, typename T2, typename T3, typename T4>
std::vector<std::string> join_tuple(
const std::string &glue,
const std::pair<char, char> &encapsulation,
const std::vector<std::tuple<T1, T2, T3, T4>> &src
)
{
if (src.empty()) {
return {};
}
std::vector<std::string> output;
for (const std::tuple<T1, T2, T3, T4> &src_iter: src) {
output.emplace_back(
fmt::format(
"{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}",
encapsulation.first,
std::get<0>(src_iter),
encapsulation.second,
glue,
encapsulation.first,
std::get<1>(src_iter),
encapsulation.second,
glue,
encapsulation.first,
std::get<2>(src_iter),
encapsulation.second,
glue,
encapsulation.first,
std::get<3>(src_iter),
encapsulation.second
)
);
}
return output;
}
// misc functions // misc functions
std::string SanitizeWorldServerName(std::string server_long_name); std::string SanitizeWorldServerName(std::string server_long_name);
std::vector<std::string> GetBadWords(); std::vector<std::string> GetBadWords();
@ -134,4 +310,18 @@ std::string FormatName(const std::string &char_name);
bool IsAllowedWorldServerCharacterList(char c); bool IsAllowedWorldServerCharacterList(char c);
void SanitizeWorldServerName(char *name); void SanitizeWorldServerName(char *name);
template<typename InputIterator, typename OutputIterator>
auto CleanMobName(InputIterator first, InputIterator last, OutputIterator result)
{
for (; first != last; ++first) {
if (*first == '_') {
*result = ' ';
}
else if (isalpha(*first) || *first == '`') {
*result = *first;
}
}
return result;
}
#endif #endif

View File

@ -25,7 +25,7 @@
// Build variables // Build variables
// these get injected during the build pipeline // these get injected during the build pipeline
#define CURRENT_VERSION "23.10.3-dev" // always append -dev to the current version for custom-builds #define CURRENT_VERSION "23.6.0-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0" #define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__ #define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__ #define COMPILE_TIME __TIME__
@ -42,9 +42,8 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/ */
#define CURRENT_BINARY_DATABASE_VERSION 9328 #define CURRENT_BINARY_DATABASE_VERSION 9323
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
#define CUSTOM_BINARY_DATABASE_VERSION 0
#endif #endif

View File

@ -104,39 +104,36 @@ public:
uint8 GetZoneIdleWhenEmpty(uint32 zone_id, int version = 0); uint8 GetZoneIdleWhenEmpty(uint32 zone_id, int version = 0);
uint32 GetZoneSecondsBeforeIdle(uint32 zone_id, int version = 0); uint32 GetZoneSecondsBeforeIdle(uint32 zone_id, int version = 0);
static ZoneStore* Instance()
{
static ZoneStore instance;
return &instance;
}
private: private:
std::vector<ZoneRepository::Zone> m_zones; std::vector<ZoneRepository::Zone> m_zones;
}; };
extern ZoneStore zone_store;
/** /**
* Global helpers * Global helpers
*/ */
inline uint32 ZoneID(const char *in_zone_name) { return ZoneStore::Instance()->GetZoneID(in_zone_name); } inline uint32 ZoneID(const char *in_zone_name) { return zone_store.GetZoneID(in_zone_name); }
inline uint32 ZoneID(const std::string& zone_name) { return ZoneStore::Instance()->GetZoneID(zone_name); } inline uint32 ZoneID(const std::string& zone_name) { return zone_store.GetZoneID(zone_name); }
inline const char *ZoneName(uint32 zone_id, bool error_unknown = false) inline const char *ZoneName(uint32 zone_id, bool error_unknown = false)
{ {
return ZoneStore::Instance()->GetZoneName( return zone_store.GetZoneName(
zone_id, zone_id,
error_unknown error_unknown
); );
} }
inline const char *ZoneLongName(uint32 zone_id, bool error_unknown = false) inline const char *ZoneLongName(uint32 zone_id, bool error_unknown = false)
{ {
return ZoneStore::Instance()->GetZoneLongName( return zone_store.GetZoneLongName(
zone_id, zone_id,
error_unknown error_unknown
); );
} }
inline ZoneRepository::Zone *GetZone(uint32 zone_id, int version = 0) { return ZoneStore::Instance()->GetZone(zone_id, version); }; inline ZoneRepository::Zone *GetZone(uint32 zone_id, int version = 0) { return zone_store.GetZone(zone_id, version); };
inline ZoneRepository::Zone *GetZone(const char *in_zone_name) { return ZoneStore::Instance()->GetZone(in_zone_name); }; inline ZoneRepository::Zone *GetZone(const char *in_zone_name) { return zone_store.GetZone(in_zone_name); };
inline ZoneRepository::Zone *GetZone(const char *in_zone_name, int version = 0) inline ZoneRepository::Zone *GetZone(const char *in_zone_name, int version = 0)
{ {
return ZoneStore::Instance()->GetZone( return zone_store.GetZone(
ZoneID( ZoneID(
in_zone_name in_zone_name
), version ), version
@ -144,7 +141,7 @@ inline ZoneRepository::Zone *GetZone(const char *in_zone_name, int version = 0)
}; };
inline ZoneRepository::Zone *GetZoneVersionWithFallback(uint32 zone_id, int version = 0) inline ZoneRepository::Zone *GetZoneVersionWithFallback(uint32 zone_id, int version = 0)
{ {
return ZoneStore::Instance()->GetZoneWithFallback( return zone_store.GetZoneWithFallback(
zone_id, zone_id,
version version
); );

View File

@ -33,16 +33,19 @@
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
EQEmuLogSys LogSys;
PathManager path;
bool RunLoops = false; bool RunLoops = false;
void CatchSignal(int sig_num); void CatchSignal(int sig_num);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
RegisterExecutablePlatform(ExePlatformLaunch); RegisterExecutablePlatform(ExePlatformLaunch);
EQEmuLogSys::Instance()->LoadLogSettingsDefaults(); LogSys.LoadLogSettingsDefaults();
set_exception_handler(); set_exception_handler();
PathManager::Instance()->Init(); path.LoadPaths();
std::string launcher_name; std::string launcher_name;
if(argc == 2) { if(argc == 2) {
@ -166,7 +169,7 @@ int main(int argc, char *argv[]) {
delete zone->second; delete zone->second;
} }
EQEmuLogSys::Instance()->CloseFileLogs(); LogSys.CloseFileLogs();
return 0; return 0;
} }

View File

@ -33,7 +33,7 @@ EverQuest::EverQuest(const std::string &host, int port, const std::string &user,
} }
else { else {
m_host = addr; m_host = addr;
m_login_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager()); m_login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
m_login_connection_manager->OnNewConnection(std::bind(&EverQuest::LoginOnNewConnection, this, std::placeholders::_1)); m_login_connection_manager->OnNewConnection(std::bind(&EverQuest::LoginOnNewConnection, this, std::placeholders::_1));
m_login_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::LoginOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); m_login_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::LoginOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
@ -48,13 +48,13 @@ EverQuest::~EverQuest()
{ {
} }
void EverQuest::LoginOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) void EverQuest::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
{ {
m_login_connection = connection; m_login_connection = connection;
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting..."); Log.OutF(Logs::General, Logs::Headless_Client, "Connecting...");
} }
void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
{ {
if (to == EQ::Net::StatusConnected) { if (to == EQ::Net::StatusConnected) {
Log.OutF(Logs::General, Logs::Headless_Client, "Login connected."); Log.OutF(Logs::General, Logs::Headless_Client, "Login connected.");
@ -70,14 +70,14 @@ void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::Rel
} }
} }
void EverQuest::LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) void EverQuest::LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
{ {
if (to == EQ::Net::StatusDisconnected) { if (to == EQ::Net::StatusDisconnected) {
m_login_connection.reset(); m_login_connection.reset();
} }
} }
void EverQuest::LoginOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet & p) void EverQuest::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
{ {
auto opcode = p.GetUInt16(0); auto opcode = p.GetUInt16(0);
switch (opcode) { switch (opcode) {
@ -251,20 +251,20 @@ void EverQuest::LoginDisableReconnect()
void EverQuest::ConnectToWorld() void EverQuest::ConnectToWorld()
{ {
m_world_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager()); m_world_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
m_world_connection_manager->OnNewConnection(std::bind(&EverQuest::WorldOnNewConnection, this, std::placeholders::_1)); m_world_connection_manager->OnNewConnection(std::bind(&EverQuest::WorldOnNewConnection, this, std::placeholders::_1));
m_world_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::WorldOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); m_world_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::WorldOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_world_connection_manager->OnPacketRecv(std::bind(&EverQuest::WorldOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2)); m_world_connection_manager->OnPacketRecv(std::bind(&EverQuest::WorldOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
m_world_connection_manager->Connect(m_host, 9000); m_world_connection_manager->Connect(m_host, 9000);
} }
void EverQuest::WorldOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) void EverQuest::WorldOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
{ {
m_world_connection = connection; m_world_connection = connection;
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting to world..."); Log.OutF(Logs::General, Logs::Headless_Client, "Connecting to world...");
} }
void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
{ {
if (to == EQ::Net::StatusConnected) { if (to == EQ::Net::StatusConnected) {
Log.OutF(Logs::General, Logs::Headless_Client, "World connected."); Log.OutF(Logs::General, Logs::Headless_Client, "World connected.");
@ -278,14 +278,14 @@ void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::Rel
} }
} }
void EverQuest::WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) void EverQuest::WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
{ {
if (to == EQ::Net::StatusDisconnected) { if (to == EQ::Net::StatusDisconnected) {
m_world_connection.reset(); m_world_connection.reset();
} }
} }
void EverQuest::WorldOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet & p) void EverQuest::WorldOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
{ {
auto opcode = p.GetUInt16(0); auto opcode = p.GetUInt16(0);
switch (opcode) { switch (opcode) {

26
hc/eq.h
View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys.h"
#include "../common/net/reliable_stream_connection.h" #include "../common/net/daybreak_connection.h"
#include "../common/event/timer.h" #include "../common/event/timer.h"
#include <openssl/des.h> #include <openssl/des.h>
#include <string> #include <string>
@ -26,10 +26,10 @@ public:
private: private:
//Login //Login
void LoginOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection); void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
void LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); void LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
void LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); void LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p); void LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
void LoginSendSessionReady(); void LoginSendSessionReady();
void LoginSendLogin(); void LoginSendLogin();
@ -41,25 +41,25 @@ private:
void LoginDisableReconnect(); void LoginDisableReconnect();
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_login_connection_manager; std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_login_connection_manager;
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_login_connection; std::shared_ptr<EQ::Net::DaybreakConnection> m_login_connection;
std::map<uint32_t, WorldServer> m_world_servers; std::map<uint32_t, WorldServer> m_world_servers;
//World //World
void ConnectToWorld(); void ConnectToWorld();
void WorldOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection); void WorldOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
void WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); void WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
void WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); void WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
void WorldOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p); void WorldOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
void WorldSendClientAuth(); void WorldSendClientAuth();
void WorldSendEnterWorld(const std::string &character); void WorldSendEnterWorld(const std::string &character);
void WorldProcessCharacterSelect(const EQ::Net::Packet &p); void WorldProcessCharacterSelect(const EQ::Net::Packet &p);
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_world_connection_manager; std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_world_connection_manager;
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_world_connection; std::shared_ptr<EQ::Net::DaybreakConnection> m_world_connection;
//Variables //Variables
std::string m_host; std::string m_host;

View File

@ -26,7 +26,7 @@ LoginConnection::LoginConnection(const std::string &username, const std::string
m_host_port = host_port; m_host_port = host_port;
m_server = server; m_server = server;
m_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager()); m_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
m_connection_manager->OnNewConnection(std::bind(&LoginConnection::OnNewConnection, this, std::placeholders::_1)); m_connection_manager->OnNewConnection(std::bind(&LoginConnection::OnNewConnection, this, std::placeholders::_1));
m_connection_manager->OnConnectionStateChange(std::bind(&LoginConnection::OnStatusChangeActive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); m_connection_manager->OnConnectionStateChange(std::bind(&LoginConnection::OnStatusChangeActive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
@ -39,13 +39,13 @@ LoginConnection::~LoginConnection()
{ {
} }
void LoginConnection::OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) void LoginConnection::OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
{ {
m_connection = connection; m_connection = connection;
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting..."); Log.OutF(Logs::General, Logs::Headless_Client, "Connecting...");
} }
void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
{ {
if (to == EQ::Net::StatusConnected) { if (to == EQ::Net::StatusConnected) {
Log.OutF(Logs::General, Logs::Headless_Client, "Login connected."); Log.OutF(Logs::General, Logs::Headless_Client, "Login connected.");
@ -61,7 +61,7 @@ void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStre
} }
} }
void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
{ {
if (to == EQ::Net::StatusDisconnected) { if (to == EQ::Net::StatusDisconnected) {
m_key.clear(); m_key.clear();
@ -70,7 +70,7 @@ void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableSt
} }
} }
void LoginConnection::OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p) void LoginConnection::OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
{ {
auto opcode = p.GetUInt16(0); auto opcode = p.GetUInt16(0);
switch (opcode) { switch (opcode) {

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