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/
!base/*.json
override/
repo/
cache/
!Makefile
base/*.sql
base/*.zip
base/db/
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
.ONESHELL:
.PHONY: prep
prep: is-vscode
@echo "Preparing build/bin for usage..."
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
@echo "Prepping folders..."
@mkdir -p .devcontainer/override
@mkdir -p .devcontainer/repo
@mkdir -p .devcontainer/cache
@mkdir -p build/bin/logs
@mkdir -p build/bin/shared
@mkdir -p build/bin/assets
.PHONY: build
build:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
exit
endif
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
@echo "Applying overrides..."
@if [ ! -f .devcontainer/override/eqemu_config.json ]; then cp .devcontainer/base/eqemu_config.json .devcontainer/override/eqemu_config.json; fi
@if [ -f build/bin/eqemu_config.json ]; then unlink build/bin/eqemu_config.json; fi
cd build/bin && ln -s ../../.devcontainer/override/eqemu_config.json eqemu_config.json
@if [ ! -f .devcontainer/override/login.json ]; then cp .devcontainer/base/login.json .devcontainer/override/login.json; fi
@if [ -f build/bin/login.json ]; then unlink build/bin/login.json; fi
cd build/bin && ln -s ../../.devcontainer/override/login.json login.json
.PHONY: cmake
cmake:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
exit
endif
@echo "working directory: $$PWD"
mkdir -p build$$BUILD_SUFFIX
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
-DEQEMU_BUILD_TESTS=ON \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
@echo "Cloning repositories..."
cd .devcontainer/repo && if [ ! -d "quests" ]; then cd ../../.devcontainer/repo/ && git clone https://github.com/ProjectEQ/projecteqquests.git quests; fi
cd .devcontainer/repo && if [ ! -d "eqemu-definitions" ]; then cd ../../.devcontainer/repo/ && git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi
cd .devcontainer/repo && if [ ! -d "maps" ]; then cd ../../ && make maps; fi
@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
clean:
ifneq (,$(findstring .devcontainer,$$PWD))
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
endif
rm -rf build
.PHONY: maps
maps: is-vscode
docker-cmake:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
exit
endif
@echo "working directory: $$PWD"
git submodule update --init --recursive
docker run ${DOCKER_ARGS} make cmake
docker-build:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
exit
endif
docker run ${DOCKER_ARGS} make build
# Build image if it doesn't exist
docker-image-build:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
exit
endif
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
@echo "Docker image not found. Building..."
docker build -f Dockerfile.debian.dev -t ${NAME} .
endif
docker-arm-cmake: docker-arm-image-build
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
exit
endif
git submodule update --init --recursive
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
docker-arm-build: docker-arm-image-build
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
exit
endif
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
docker-arm-image-build:
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
@echo "Docker image not found. Building..."
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
endif
docker-clean: clean
.PHONY: prep
prep:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
exit
endif
@echo "Preparing build/bin for usage..."
mkdir -p build/bin/assets/patches
cp -R -u -p .devcontainer/base/eqemu_config.json build/bin/eqemu_config.json
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
mkdir -p build/bin/assets
cp -R -u -p utils/patches build/bin/assets/
-unlink build/bin/lua_modules
cd build/bin && ln -s quests/lua_modules lua_modules
-unlink build/bin/mods
cd build/bin && ln -s quests/mods mods
-unlink build/bin/maps
cd build/bin && ln -s ../../base/maps maps
mkdir -p build/bin/logs
mkdir -p build/bin/shared
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
maps:
@echo "Downloading maps..."
@mkdir -p .devcontainer/repo/maps
@cd .devcontainer/repo/maps && wget -nc https://github.com/EQEmu/maps/archive/refs/heads/master.zip
@cd .devcontainer/repo/maps && unzip -o master.zip
@cd .devcontainer/repo/maps && mv maps-master/* .
@cd .devcontainer/repo/maps && rm -rf maps-master
@mkdir -p base/maps
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
@cd base/maps && unzip -o master.zip
@cd base/maps && mv eqemu-maps-master/* .
@cd base/maps && rm -rf eqemu-maps-master
@echo "Maps downloaded."
quests:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
exit
endif
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
# Runs tests
.PHONY: test
test: is-vscode
test:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
exit
endif
cd build/bin && ./tests
# Runs login binary
.PHONY: login
login: 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
.PHONY: hotfix
hotfix: shared
# Runs shared_memory binary
.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
# Runs zone binary
.PHONY: zone
zone: is-vscode check-mariadb
@find build/bin/logs/zone/ -type f -name 'zone*.log' -exec rm -f {} +
zone:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
exit
endif
@-rm build/bin/logs/zone/zone*.log
cd build/bin && ./zone
check-mariadb: is-vscode
@if ! sudo service mariadb status | grep -q 'active (running)'; then \
sudo service mariadb start; \
fi
# Runs world binary
.PHONY: world
world: is-vscode check-mariadb
@find build/bin/logs/ -type f -name 'world*.log' -exec rm -f {} +
world:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
exit
endif
@-rm build/bin/logs/world*.log
cd build/bin && ./world
# Runs ucs binary
.PHONY: ucs
ucs: is-vscode check-mariadb
@find build/bin/logs/ -type f -name 'ucs*.log' -exec rm -f {} +
ucs:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
exit
endif
@-rm build/bin/logs/ucs*.log
cd build/bin && ./ucs
# Runs queryserv binary
.PHONY: queryserv
queryserv: is-vscode check-mariadb
@find build/bin/logs/ -type f -name 'query_server*.log' -exec rm -f {} +
queryserv:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
exit
endif
@-rm build/bin/logs/query_server*.log
cd build/bin && ./queryserv
reset-content:
@echo "Resetting content tables in database peq..."
cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
valgrind-%: is-vscode
valgrind-%:
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
exit
endif
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
# Start mariaDB standalone
@ -132,33 +201,30 @@ mariadb:
.PHONY: inject-mariadb
inject-mariadb:
-sudo service mariadb start
-mkdir -p .devcontainer/cache/db/
-mkdir -p base/db/
-sudo mariadb -e 'DROP DATABASE IF EXISTS 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';"
ifeq (,$(wildcard .devcontainer/cache/db/db.sql.zip))
@echo ".devcontainer/cache/db.sql.zip not found. Downloading database from https://db.eqemu.dev/latest"
wget -nc https://db.eqemu.dev/latest -O .devcontainer/cache/db/db.sql.zip
-cd .devcontainer/cache/db && unzip db.sql.zip
ifeq (,$(wildcard base/db/db.sql.zip))
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
-cd base/db && unzip db.sql.zip
endif
@echo "Sourcing db may take a while, please wait..."
@cd .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"
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
@echo "MariaDB is now injected."
.PHONY: gm-%
gm-%: is-vscode
gm-%:
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
@echo "Account $* is now a GM. /camp to have it go into effect."
depends: 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
pip3 install graphviz
mkdir -p build/depends
@ -175,54 +241,44 @@ depends: is-vscode
@echo "Common..."
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
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
restore-%: is-vscode
@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
cpu-zone:
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
endif
@cd build/bin && mkdir -p tmp
cd build/bin && CPUPROFILE=prof.out ./zone
pprof-zone: is-vscode
pprof-zone:
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
endif
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
pprof-gv-zone: is-vscode
pprof-web-zone:
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
endif
cd build/bin && google-pprof --gv zone prof.out > prof.gv
heap-zone: is-vscode
heap-zone:
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
endif
@cd build/bin && mkdir -p tmp
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",
"xackery.make-magic",
"Gruntfuggly.todo-tree",
"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"
}
}
}
"ms-vscode.cmake-tools"
]
}
},
"mounts": [
"source=${localWorkspaceFolder}/.devcontainer/Makefile,target=/src/Makefile,type=bind,consistency=cached"
],
"workspaceFolder": "/src",
"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"
],
"telemetry.enableTelemetry": false,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.configureArgs": [
"-DEQEMU_BUILD_LOGIN=ON",
"-DEQEMU_BUILD_TESTS=ON",
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
"-DEQEMU_ADD_PROFILER=ON",
"Ninja"
],
"cmake.skipConfigureIfCachePresent": true,
"cmake.configureOnOpen": false,
"files.associations": {
@ -107,5 +115,22 @@
"format": "cpp",
"ranges": "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
### Bots

View File

@ -42,7 +42,6 @@ IF(USE_MAP_MMFS)
ENDIF (USE_MAP_MMFS)
IF(MSVC)
add_compile_options(/bigobj)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
ADD_DEFINITIONS(-DNOMINMAX)
ADD_DEFINITIONS(-DCRASH_LOGGING)
@ -363,8 +362,6 @@ MESSAGE(STATUS "**************************************************")
#setup server libs and headers
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 "${ZLIB_LIBRARY_INCLUDE}")
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>
<p align="center">
<img src="https://github.com/user-attachments/assets/11942e15-b512-402d-a619-0543c7f1151e" style="border-radius: 10px">
</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>
# EQEmulator Core Server
| Drone (Linux x64) | Drone (Windows x64) |
|:---:|:---:|
|[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |
***
<p align="center">
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.
</p>
**EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++**
* MySQL/MariaDB is used as the database engine (over 200+ tables)
* 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">
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.
</p>
## Server Installs
| |Windows|Linux|
|:---:|:---:|:---:|
|**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">
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>
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
<p align="center">
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>
### > Debian/Ubuntu/CentOS/Fedora
***
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
<h3 align="center">
Technical Overview & Reverse Engineering Effort
</h1>
* You can use curl or wget to kick off the installer (whichever your OS has)
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
<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">
💡 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>
## Supported Clients
|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">|
## 📚 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 |
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| **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) |
## Contributions <img src="http://image.flaticon.com/icons/png/512/25/25231.png" width="20">
## 🛠️ 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 |
|--------------------|----------------------------------------------------------------------------------|
| [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests) | Official quests and event scripts for ProjectEQ |
| [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 |
## Resources
- [EQEmulator Forums](http://www.eqemulator.org/forums)
- [EQEmulator Wiki](https://docs.eqemu.io/)
## 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
<a href="https://github.com/EQEmu/server/graphs/contributors">
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
</a>

View File

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

View File

@ -32,6 +32,13 @@
#include "../../common/events/player_event_logs.h"
#include "../../common/evolving_items.h"
EQEmuLogSys LogSys;
WorldContentService content_service;
ZoneStore zone_store;
PathManager path;
PlayerEventLogs player_event_logs;
EvolvingItemsManager evolving_items_manager;
void ImportSpells(SharedDatabase *db);
void ImportSkillCaps(SharedDatabase *db);
void ImportBaseData(SharedDatabase *db);
@ -39,10 +46,10 @@ void ImportDBStrings(SharedDatabase *db);
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformClientImport);
EQEmuLogSys::Instance()->LoadLogSettingsDefaults();
LogSys.LoadLogSettingsDefaults();
set_exception_handler();
PathManager::Instance()->Init();
path.LoadPaths();
LogInfo("Client Files Import Utility");
if(!EQEmuConfig::LoadConfig()) {
@ -85,8 +92,8 @@ int main(int argc, char **argv) {
content_db.SetMySQL(database);
}
EQEmuLogSys::Instance()->SetDatabase(&database)
->SetLogPath(PathManager::Instance()->GetLogPath())
LogSys.SetDatabase(&database)
->SetLogPath(path.GetLogPath())
->LoadLogDatabaseSettings()
->StartFileLogs();
@ -95,7 +102,7 @@ int main(int argc, char **argv) {
ImportBaseData(&content_db);
ImportDBStrings(&database);
EQEmuLogSys::Instance()->CloseFileLogs();
LogSys.CloseFileLogs();
return 0;
}
@ -131,7 +138,7 @@ bool IsStringField(int i) {
void ImportSpells(SharedDatabase *db) {
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");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
@ -221,7 +228,7 @@ void ImportSpells(SharedDatabase *db) {
void ImportSkillCaps(SharedDatabase *db) {
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");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);
@ -258,7 +265,7 @@ void ImportBaseData(SharedDatabase *db)
{
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);
if (!file_contents.error.empty()) {
@ -298,7 +305,7 @@ void ImportBaseData(SharedDatabase *db)
void ImportDBStrings(SharedDatabase *db) {
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");
if(!f) {
LogError("Unable to open {} to read, skipping.", file);

View File

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

View File

@ -17,7 +17,6 @@ SET(common_sources
database.cpp
database_instances.cpp
database/database_update_manifest.cpp
database/database_update_manifest_custom.cpp
database/database_update_manifest_bots.cpp
database/database_update.cpp
dbcore.cpp
@ -104,9 +103,9 @@ SET(common_sources
net/console_server.cpp
net/console_server_connection.cpp
net/crc32.cpp
net/daybreak_connection.cpp
net/eqstream.cpp
net/packet.cpp
net/reliable_stream_connection.cpp
net/servertalk_client_connection.cpp
net/servertalk_legacy_client_connection.cpp
net/servertalk_server.cpp
@ -603,6 +602,7 @@ SET(common_headers
ipc_mutex.h
ip_util.h
item_data.h
item_fieldlist.h
item_instance.h
json_config.h
light_source.h
@ -670,13 +670,13 @@ SET(common_headers
net/console_server.h
net/console_server_connection.h
net/crc32.h
net/daybreak_connection.h
net/daybreak_pooling.h
net/daybreak_structs.h
net/dns.h
net/endian.h
net/eqstream.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_legacy_client_connection.h
net/servertalk_common.h
@ -742,6 +742,10 @@ SOURCE_GROUP(Net FILES
net/console_server_connection.h
net/crc32.cpp
net/crc32.h
net/daybreak_connection.cpp
net/daybreak_connection.h
net/daybreak_pooling.h
net/daybreak_structs.h
net/dns.h
net/endian.h
net/eqmq.cpp
@ -750,10 +754,6 @@ SOURCE_GROUP(Net FILES
net/eqstream.h
net/packet.cpp
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.h
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)
ENDIF (UNIX)
IF (EQEMU_BUILD_PCH)
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/std-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)
IF (WIN32 AND EQEMU_BUILD_PCH)
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
ENDIF ()
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

View File

@ -27,7 +27,7 @@ WorldContentService *WorldContentService::SetExpansionContext()
// pull expansion from rules
int expansion = RuleI(Expansion, CurrentExpansion);
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
WorldContentService::Instance()->SetCurrentExpansion(expansion);
content_service.SetCurrentExpansion(expansion);
}
LogInfo(
@ -41,12 +41,12 @@ WorldContentService *WorldContentService::SetExpansionContext()
std::string WorldContentService::GetCurrentExpansionName()
{
if (WorldContentService::Instance()->GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
if (content_service.GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
return "All Expansions";
}
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
return Expansion::ExpansionName[WorldContentService::Instance()->GetCurrentExpansion()];
return Expansion::ExpansionName[content_service.GetCurrentExpansion()];
}
return "Unknown Expansion";
@ -185,7 +185,7 @@ void WorldContentService::ReloadContentFlags()
SetContentFlags(set_content_flags);
LoadStaticGlobalZoneInstances();
ZoneStore::Instance()->LoadZones(*m_content_database);
zone_store.LoadZones(*m_content_database);
}
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
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) {
if (
z.zoneidnumber == zone_id &&

View File

@ -181,12 +181,6 @@ public:
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
bool IsInPublicStaticInstance(uint32 instance_id);
static WorldContentService* Instance()
{
static WorldContentService instance;
return &instance;
}
private:
int current_expansion{};
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
@ -200,4 +194,6 @@ private:
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
};
extern WorldContentService content_service;
#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
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
};
EQEmuLogSys* log = EQEmuLogSys::Instance();
auto config = EQEmuConfig::get();
for (auto &e: endpoints) {
uri u(e);
@ -70,12 +68,12 @@ void SendCrashReport(const std::string &crash_report)
p["cpus"] = cpus.size();
p["origination_info"] = "";
if (!log->origination_info.zone_short_name.empty()) {
if (!LogSys.origination_info.zone_short_name.empty()) {
p["origination_info"] = fmt::format(
"{} ({}) instance_id [{}]",
log->origination_info.zone_short_name,
log->origination_info.zone_long_name,
log->origination_info.instance_id
LogSys.origination_info.zone_short_name,
LogSys.origination_info.zone_long_name,
LogSys.origination_info.instance_id
);
}
@ -296,7 +294,7 @@ void print_trace()
SendCrashReport(crash_report);
}
EQEmuLogSys::Instance()->CloseFileLogs();
LogSys.CloseFileLogs();
exit(1);
}

View File

@ -708,20 +708,6 @@ const std::string Database::GetNPCNameByID(uint32 npc_id)
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 auto& e = NpcTypesRepository::FindOne(*this, npc_id);
@ -1934,7 +1920,6 @@ bool Database::CopyCharacter(
std::vector<std::string> tables_to_zero_id = {
"keyring",
"data_buckets",
"character_evolving_items",
"character_instance_safereturns",
"character_expedition_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 = {};
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;
for (auto row : results) {
@ -2063,18 +2036,13 @@ bool Database::CopyCharacter(
LogInfo("Copying table [{}] rows [{}]", table_name, Strings::Commify(rows_copied));
if (!insert.ErrorMessage().empty()) {
LogError("Error copying table [{}] [{}]", table_name, insert.ErrorMessage());
TransactionRollback();
return false;
}
}
}
auto r = TransactionCommit();
if (!r.Success()) {
LogError("Transaction failed [{}] rolling back", r.ErrorMessage());
return false;
}
TransactionCommit();
LogInfo(
"Character [{}] copied to [{}] total rows [{}]",
@ -2244,7 +2212,7 @@ void Database::PurgeCharacterParcels()
pel.event_data = ss.str();
pel.created_at = std::time(nullptr);
PlayerEventLogs::Instance()->AddToQueue(pel);
player_event_logs.AddToQueue(pel);
ss.str("");
ss.clear();

View File

@ -50,7 +50,7 @@ bool DatabaseDumpService::IsMySQLInstalled()
{
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()) {
EQEmuLogSys::Instance()->SilenceConsoleLogging();
LogSys.SilenceConsoleLogging();
}
LogInfo("MySQL installed [{}]", GetMySQLVersion());
@ -324,7 +324,7 @@ void DatabaseDumpService::DatabaseDump()
}
if (!IsDumpOutputToConsole()) {
EQEmuLogSys::Instance()->LoadLogSettingsDefaults();
LogSys.LoadLogSettingsDefaults();
}
if (!pipe_file.empty()) {

View File

@ -7,7 +7,6 @@
#include "../http/httplib.h"
#include "database_update_manifest.cpp"
#include "database_update_manifest_custom.cpp"
#include "database_update_manifest_bots.cpp"
#include "database_dump_service.h"
@ -15,7 +14,7 @@ constexpr int BREAK_LENGTH = 70;
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()) {
LogError("Failed to read from [db_version] table!");
return DatabaseVersion{};
@ -26,7 +25,6 @@ DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
return DatabaseVersion{
.server_database_version = Strings::ToInt(r[0]),
.bots_database_version = Strings::ToInt(r[1]),
.custom_database_version = Strings::ToInt(r[2]),
};
}
@ -35,7 +33,6 @@ DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
return DatabaseVersion{
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
.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
void DatabaseUpdate::CheckDbUpdates()
{
InjectCustomVersionColumn();
InjectBotsVersionColumn();
auto v = GetDatabaseVersions();
auto b = GetBinaryDatabaseVersions();
@ -63,15 +59,6 @@ void DatabaseUpdate::CheckDbUpdates()
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 (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
LogInfo(
@ -154,7 +141,7 @@ bool DatabaseUpdate::UpdateManifest(
std::vector<int> missing_migrations = {};
if (version_low != version_high) {
EQEmuLogSys::Instance()->DisableMySQLErrorLogs();
LogSys.DisableMySQLErrorLogs();
bool force_interactive = false;
for (int version = version_low + 1; version <= version_high; ++version) {
for (auto &e: entries) {
@ -184,7 +171,7 @@ bool DatabaseUpdate::UpdateManifest(
}
}
}
EQEmuLogSys::Instance()->EnableMySQLErrorLogs();
LogSys.EnableMySQLErrorLogs();
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
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("{}", 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
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
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;
return server_up_to_date && bots_up_to_date;
}
// 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");
}
}
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 {
int server_database_version;
int bots_database_version;
int custom_database_version;
};
class DatabaseUpdate {
@ -33,20 +32,12 @@ public:
DatabaseUpdate *SetContentDatabase(Database *db);
DatabaseUpdate *SetSkipBackup(bool skip);
bool HasPendingUpdates();
static DatabaseUpdate* Instance()
{
static DatabaseUpdate instance;
return &instance;
}
private:
bool m_skip_backup = false;
Database *m_database;
Database *m_content_database;
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
void InjectBotsVersionColumn();
void InjectCustomVersionColumn();
};

View File

@ -7109,80 +7109,6 @@ ALTER TABLE `npc_types`
ALTER TABLE `character_data`
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`;
)",
.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
},

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)
);
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)) {
LogMySQLQuery(
"{0} -- ({1} row{2} returned) ({3}s)",
@ -189,9 +189,9 @@ void DBcore::TransactionBegin()
QueryDatabase("START TRANSACTION");
}
MySQLRequestResult DBcore::TransactionCommit()
void DBcore::TransactionCommit()
{
return QueryDatabase("COMMIT");
QueryDatabase("COMMIT");
}
void DBcore::TransactionRollback()

View File

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

View File

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

View File

@ -26,7 +26,7 @@ void DiscordManager::ProcessMessageQueue()
continue;
}
auto webhook = EQEmuLogSys::Instance()->GetDiscordWebhooks()[q.first];
auto webhook = LogSys.GetDiscordWebhooks()[q.first];
std::string message;
for (auto &m: q.second) {
@ -68,7 +68,7 @@ void DiscordManager::ProcessMessageQueue()
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()) {
Discord::SendPlayerEventMessage(e, w);
}

View File

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

View File

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

View File

@ -545,13 +545,13 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
uint32 chunksize, used;
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){
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){
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 "emu_versions.h"
#include "eq_packet.h"
#include "net/reliable_stream_connection.h"
#include "net/daybreak_connection.h"
typedef enum {
ESTABLISHED,
@ -33,18 +33,18 @@ struct EQStreamManagerInterfaceOptions
//Login I had trouble getting to recognize compression at all
//but that might be because it was still a bit buggy when i was testing that.
if (compressed) {
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeCompression;
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
}
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;
bool track_opcode_stats;
EQ::Net::ReliableStreamConnectionManagerOptions reliable_stream_options;
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
};
class EQStreamManagerInterface
@ -80,7 +80,7 @@ public:
struct Stats
{
EQ::Net::ReliableStreamConnectionStats ReliableStreamStats;
EQ::Net::DaybreakConnectionStats DaybreakStats;
int RecvCount[_maxEmuOpcode];
int SentCount[_maxEmuOpcode];
};

View File

@ -177,21 +177,6 @@ void EQEmuConfig::parse_config()
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").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
*/
@ -436,11 +421,11 @@ void EQEmuConfig::CheckUcsConfigConversion()
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
std::string config_file_path = std::filesystem::path{
PathManager::Instance()->GetServerPath() + "/eqemu_config.json"
path.GetServerPath() + "/eqemu_config.json"
}.string();
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();
// copy eqemu_config.json to eqemu_config.json.bak

View File

@ -120,22 +120,6 @@ class EQEmuConfig
const std::string &GetUCSHost() 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;
// map<string,uint16> StaticZones;
@ -149,11 +133,6 @@ class EQEmuConfig
Json::Value _root;
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();
EQEmuConfig()
@ -191,7 +170,7 @@ class EQEmuConfig
std::string file = fmt::format(
"{}/{}",
(file_path.empty() ? PathManager::Instance()->GetServerPath() : file_path),
(file_path.empty() ? path.GetServerPath() : file_path),
EQEmuConfig::ConfigFile
);

View File

@ -537,9 +537,9 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
{
EQEmuLogSys::CloseFileLogs();
if (!File::Exists(PathManager::Instance()->GetLogPath())) {
LogInfo("Logs directory not found, creating [{}]", PathManager::Instance()->GetLogPath());
File::Makedir(PathManager::Instance()->GetLogPath());
if (!File::Exists(path.GetLogPath())) {
LogInfo("Logs directory not found, creating [{}]", path.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
// is no point to create a file or keep anything open
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);
@ -682,33 +682,14 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings(bool silent_load)
if (is_missing_in_database && !is_deprecated_category) {
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
auto e = LogsysCategoriesRepository::NewEntity();
e.log_category_id = i;
e.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
e.log_to_console = log_settings[i].log_to_console;
e.log_to_gmsay = log_settings[i].log_to_gmsay;
e.log_to_file = log_settings[i].log_to_file;
e.log_to_discord = log_settings[i].log_to_discord;
db_categories_to_add.emplace_back(e);
}
// 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);
}
auto new_category = LogsysCategoriesRepository::NewEntity();
new_category.log_category_id = i;
new_category.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
new_category.log_to_console = log_settings[i].log_to_console;
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
new_category.log_to_file = log_settings[i].log_to_file;
new_category.log_to_discord = log_settings[i].log_to_discord;
db_categories_to_add.emplace_back(new_category);
}
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -716,7 +716,7 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
);
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);
handin_items_info += fmt::format(
"Augment {}: {} ({})\n",
@ -741,7 +741,7 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
);
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);
return_items_info += fmt::format(
"Augment {}: {} ({})\n",

View File

@ -15,9 +15,9 @@ const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1
// general initialization routine
void PlayerEventLogs::Init()
{
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
m_database_ping_timer.SetTimer(10 * 1000); // 10 seconds
ValidateDatabaseConnection();
@ -195,12 +195,10 @@ void PlayerEventLogs::ProcessBatchQueue()
};
// Helper to assign ETL table ID
auto AssignEtlId = [&](
PlayerEventLogsRepository::PlayerEventLogs& r,
PlayerEvent::EventType type
)
{
auto AssignEtlId = [&](
PlayerEventLogsRepository::PlayerEventLogs &r,
PlayerEvent::EventType type
) {
if (m_etl_settings.contains(type)) {
r.etl_table_id = m_etl_settings.at(type).next_id++;
}
@ -408,6 +406,7 @@ void PlayerEventLogs::ProcessBatchQueue()
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
if (it != event_processors.end()) {
it->second(r); // Call the appropriate lambda
r.event_data = "{}"; // Clear event data
}
else {
LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id);
@ -509,7 +508,7 @@ bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
}
// 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;
}
@ -529,27 +528,13 @@ std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_typ
}
// ensure there is a matching webhook to begin with
if (!EQEmuLogSys::Instance()->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;
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
}
return "";
}
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
// ZONING | [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
void PlayerEventLogs::Process()
{
if (m_database_ping_timer.Check()) {
m_database->ping();
}
if (m_process_batch_events_timer.Check() ||
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
ProcessBatchQueue();

View File

@ -73,11 +73,9 @@ public:
return BuildPlayerEventPacket(c);
}
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings * GetSettings() const;
bool IsEventDiscordEnabled(int32_t event_type_id);
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
void LoadPlayerEventSettingsFromQS(const std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings>& settings);
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
bool IsEventDiscordEnabled(int32_t event_type_id);
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
@ -96,12 +94,6 @@ public:
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
};
static PlayerEventLogs* Instance()
{
static PlayerEventLogs instance;
return &instance;
}
private:
struct EtlSettings {
bool enabled;
@ -121,7 +113,6 @@ private:
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
// timers
Timer m_database_ping_timer; // database ping timer
Timer m_process_batch_events_timer; // events processing timer
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;}
};
extern PlayerEventLogs player_event_logs;
#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.end(),
std::inserter(
EvolvingItemsManager::Instance()->GetEvolvingItemsCache(),
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().end()
evolving_items_manager.GetEvolvingItemsCache(),
evolving_items_manager.GetEvolvingItemsCache().end()
),
[](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &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)
{
if (!EvolvingItemsManager::Instance()->GetEvolvingItemsCache().contains(item_id)) {
if (!evolving_items_manager.GetEvolvingItemsCache().contains(item_id)) {
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>(EvolvingItemsManager::Instance()->GetEvolvingItemsCache().at(item_id).required_amount) * 100
/ static_cast<double>(evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount) * 100
: 0;
}
@ -73,11 +73,7 @@ void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_
e.character_id = char_id;
e.item_id = inst.GetID();
e.equipped = inst.GetEvolveEquipped();
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(inst);
if (inst.GetEvolveCurrentAmount() > 0) {
e.current_amount = inst.GetEvolveCurrentAmount();
inst.CalculateEvolveProgression();
}
e.final_item_id = evolving_items_manager.GetFinalItemID(inst);
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
e.id = r.id;
@ -100,20 +96,20 @@ uint32 EvolvingItemsManager::GetFinalItemID(const EQ::ItemInstance &inst) const
}
const auto start_iterator = std::ranges::find_if(
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cbegin(),
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(),
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
evolving_items_manager.GetEvolvingItemsCache().cend(),
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
return a.second.item_evo_id == inst.GetEvolveLoreID();
}
);
if (start_iterator == std::end(EvolvingItemsManager::Instance()->GetEvolvingItemsCache())) {
if (start_iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
return 0;
}
const auto final_id = std::ranges::max_element(
start_iterator,
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(),
evolving_items_manager.GetEvolvingItemsCache().cend(),
[&](
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a,
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();
const auto iterator = std::ranges::find_if(
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cbegin(),
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(),
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
evolving_items_manager.GetEvolvingItemsCache().cend(),
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
return a.second.item_evo_id == inst.GetEvolveLoreID() &&
a.second.item_evolve_level == current_level + 1;
}
);
if (iterator == std::end(EvolvingItemsManager::Instance()->GetEvolvingItemsCache())) {
if (iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
return 0;
}
@ -259,8 +255,8 @@ EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
return ets;
}
auto evolving_details_inst_from = EvolvingItemsManager::Instance()->GetEvolveItemDetails(inst_from.GetID());
auto evolving_details_inst_to = EvolvingItemsManager::Instance()->GetEvolveItemDetails(inst_to.GetID());
auto evolving_details_inst_from = evolving_items_manager.GetEvolveItemDetails(inst_from.GetID());
auto evolving_details_inst_to = evolving_items_manager.GetEvolveItemDetails(inst_to.GetID());
if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) {
return ets;
@ -276,10 +272,10 @@ EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
compatibility = 30;
}
xp = EvolvingItemsManager::Instance()->GetTotalEarnedXP(inst_from) * compatibility / 100;
auto results = EvolvingItemsManager::Instance()->GetNextItemByXP(inst_to, xp);
xp = evolving_items_manager.GetTotalEarnedXP(inst_from) * compatibility / 100;
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_to_id = results.new_item_id;
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::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id);
static EvolvingItemsManager* Instance()
{
static EvolvingItemsManager instance;
return &instance;
}
private:
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> m_evolving_items_cache;
Database * m_db;
Database * m_content_db;
};
extern EvolvingItemsManager evolving_items_manager;
#endif //EVOLVING_H

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
#include "reliable_stream_connection.h"
#include "daybreak_connection.h"
#include "../event/event_loop.h"
#include "../data_verification.h"
#include "crc32.h"
@ -12,7 +12,7 @@ constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
// buffer pools
SendBufferPool send_buffer_pool;
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager()
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
{
m_attached = nullptr;
memset(&m_timer, 0, sizeof(uv_timer_t));
@ -21,7 +21,7 @@ EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager()
Attach(EQ::EventLoop::Get().Handle());
}
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts)
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
{
m_attached = nullptr;
m_options = opts;
@ -31,12 +31,12 @@ EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const
Attach(EQ::EventLoop::Get().Handle());
}
EQ::Net::ReliableStreamConnectionManager::~ReliableStreamConnectionManager()
EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
{
Detach();
}
void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
{
if (!m_attached) {
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);
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
c->UpdateDataBudget();
c->Process();
c->ProcessResend();
@ -71,7 +71,7 @@ void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
buf->len = 65536;
},
[](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) {
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) {
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
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;
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));
}
void EQ::Net::ReliableStreamConnectionManager::Process()
void EQ::Net::DaybreakConnectionManager::Process()
{
auto now = Clock::now();
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;
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();
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)) {
return;
}
if (size < ReliableStreamHeader::size()) {
if (size < DaybreakHeader::size()) {
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;
}
@ -239,9 +239,9 @@ void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &
else {
if (data[0] == 0 && data[1] == OP_SessionRequest) {
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;
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 iter = m_connections.find(p);
@ -273,9 +273,9 @@ std::shared_ptr<EQ::Net::ReliableStreamConnection> EQ::Net::ReliableStreamConnec
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.opcode = OP_OutOfSession;
header.connect_code = 0;
@ -300,7 +300,7 @@ void EQ::Net::ReliableStreamConnectionManager::SendDisconnect(const std::string
}
//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_last_send = Clock::now();
@ -327,7 +327,7 @@ EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnec
}
//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_last_send = Clock::now();
@ -349,11 +349,11 @@ EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnec
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) {
FlushBuffer();
@ -367,17 +367,17 @@ void EQ::Net::ReliableStreamConnection::Close()
ChangeStatus(StatusDisconnecting);
}
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p)
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p)
{
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);
}
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) {
DynamicPacket packet;
@ -390,21 +390,21 @@ void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream, bool
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.avg_ping = m_rolling_ping;
return ret;
}
void EQ::Net::ReliableStreamConnection::ResetStats()
void EQ::Net::DaybreakConnection::ResetStats()
{
m_stats.Reset();
}
void EQ::Net::ReliableStreamConnection::Process()
void EQ::Net::DaybreakConnection::Process()
{
try {
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_stats.recv_packets++;
@ -458,13 +458,13 @@ void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
switch (m_encode_passes[i]) {
case EncodeCompression:
if(temp.GetInt8(0) == 0)
Decompress(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else
Decompress(temp, 1, temp.Length() - 1);
break;
case EncodeXOR:
if (temp.GetInt8(0) == 0)
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else
Decode(temp, 1, temp.Length() - 1);
break;
@ -483,7 +483,7 @@ void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
switch (m_encode_passes[i]) {
case EncodeXOR:
if (temp.GetInt8(0) == 0)
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
else
Decode(temp, 1, temp.Length() - 1);
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) {
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 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 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.Length() < 2) {
@ -628,13 +628,13 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_SessionRequest:
{
if (m_status == StatusConnected) {
auto request = p.GetSerialize<ReliableStreamConnect>(0);
auto request = p.GetSerialize<DaybreakConnect>(0);
if (NetworkToHost(request.connect_code) != m_connect_code) {
return;
}
ReliableStreamConnectReply reply;
DaybreakConnectReply reply;
reply.zero = 0;
reply.opcode = OP_SessionResponse;
reply.connect_code = HostToNetwork(m_connect_code);
@ -656,13 +656,13 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_SessionResponse:
{
if (m_status == StatusConnecting) {
auto reply = p.GetSerialize<ReliableStreamConnectReply>(0);
auto reply = p.GetSerialize<DaybreakConnectReply>(0);
if (m_connect_code == reply.connect_code) {
m_encode_key = reply.encode_key;
m_crc_bytes = reply.crc_bytes;
m_encode_passes[0] = (ReliableStreamEncodeType)reply.encode_pass1;
m_encode_passes[1] = (ReliableStreamEncodeType)reply.encode_pass2;
m_encode_passes[0] = (DaybreakEncodeType)reply.encode_pass1;
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
m_max_packet_size = reply.max_packet_size;
ChangeStatus(StatusConnected);
@ -686,7 +686,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
return;
}
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Packet;
auto stream = &m_streams[stream_id];
@ -703,7 +703,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
RemoveFromQueue(stream_id, sequence);
SendAck(stream_id, 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);
}
@ -715,7 +715,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_Fragment3:
case OP_Fragment4:
{
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Fragment;
auto stream = &m_streams[stream_id];
@ -735,22 +735,22 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
stream->sequence_in++;
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_current_bytes = 0;
stream->fragment_packet.Reserve(stream->fragment_total_bytes);
stream->fragment_packet.PutData(
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 {
stream->fragment_packet.PutData(
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) {
ProcessDecodedPacket(stream->fragment_packet);
@ -769,7 +769,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_Ack3:
case OP_Ack4:
{
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Ack;
Ack(stream_id, sequence);
@ -781,7 +781,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
case OP_OutOfOrderAck3:
case OP_OutOfOrderAck4:
{
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_OutOfOrderAck;
OutOfOrderAck(stream_id, sequence);
@ -815,13 +815,13 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
}
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_recv_packets = EQ::Net::NetworkToHost(request.packets_recv);
m_stats.sync_sent_packets = m_stats.sent_packets;
m_stats.sync_recv_packets = m_stats.recv_packets;
ReliableStreamSessionStatResponse response;
DaybreakSessionStatResponse response;
response.zero = 0;
response.opcode = OP_SessionStatResponse;
response.timestamp = request.timestamp;
@ -836,7 +836,7 @@ void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
break;
}
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_recv_packets = EQ::Net::NetworkToHost(response.server_recv);
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) {
return true;
@ -892,7 +892,7 @@ bool EQ::Net::ReliableStreamConnection::ValidateCRC(Packet &p)
return false;
}
void EQ::Net::ReliableStreamConnection::AppendCRC(Packet &p)
void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
{
if (m_crc_bytes == 0U) {
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 (auto self = m_self.lock()) {
@ -922,7 +922,7 @@ void EQ::Net::ReliableStreamConnection::ChangeStatus(DbProtocolStatus 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) {
return false;
@ -941,7 +941,7 @@ bool EQ::Net::ReliableStreamConnection::PacketCanBeEncoded(Packet &p) const
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;
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;
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) {
return;
@ -1075,7 +1075,7 @@ void EQ::Net::ReliableStreamConnection::Decompress(Packet &p, size_t offset, siz
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 };
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);
}
void EQ::Net::ReliableStreamConnection::ProcessResend()
void EQ::Net::DaybreakConnection::ProcessResend()
{
for (int i = 0; i < 4; ++i) {
ProcessResend(i);
}
}
void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
{
if (m_status == DbProtocolStatus::StatusDisconnected) {
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();
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();
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
// 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) {
LogNetClientDetail(
"Not resending packets for m_endpoint [{}] m_port [{}] packets [{}] time_first_sent [{}] resend_delay [{}] m_acked_since_last_resend [{}]",
m_endpoint,
m_port,
LogNetClient(
"Not resending packets for stream [{}] packets [{}] time_first_sent [{}] resend_delay [{}] m_acked_since_last_resend [{}]",
stream,
s->sent_packets.size(),
time_since_first_sent,
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;
for (auto &e: s->sent_packets) {
total_size += e.second.packet.Length();
}
LogNetClientDetail(
"Resending packets for m_endpoint [{}] m_port [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
m_endpoint,
m_port,
LogNetClient(
"Resending packets for stream [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
stream,
s->sent_packets.size(),
total_size,
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 ||
m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) {
LogNetClient(
"Stopping resend because we hit thresholds for m_endpoint [{}] m_port [{}] m_resend_packets_sent [{}] max [{}] in_queue [{}] m_resend_bytes_sent [{}] max [{}]",
m_endpoint,
m_port,
"Stopping resend because we hit thresholds m_resend_packets_sent [{}] max [{}] m_resend_bytes_sent [{}] max [{}]",
m_resend_packets_sent,
MAX_CLIENT_RECV_PACKETS_PER_WINDOW,
s->sent_packets.size(),
m_resend_bytes_sent,
MAX_CLIENT_RECV_BYTES_PER_WINDOW
);
@ -1201,7 +1176,7 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
auto &sp = e.second;
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) {
m_stats.resent_fragments++;
}
@ -1229,11 +1204,11 @@ void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
}
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 s = &m_streams[stream];
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;
iter = s->sent_packets.erase(iter);
m_acked_since_last_resend = true;
}
else {
++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 s = &m_streams[stream];
@ -1274,20 +1247,17 @@ void EQ::Net::ReliableStreamConnection::OutOfOrderAck(int stream, uint16_t seq)
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;
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.opcode = OP_Ack + stream_id;
ack.sequence = HostToNetwork(seq);
@ -1298,9 +1268,9 @@ void EQ::Net::ReliableStreamConnection::SendAck(int stream_id, uint16_t seq)
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.opcode = OP_OutOfOrderAck + stream_id;
ack.sequence = HostToNetwork(seq);
@ -1311,9 +1281,9 @@ void EQ::Net::ReliableStreamConnection::SendOutOfOrderAck(int stream_id, uint16_
InternalBufferedSend(p);
}
void EQ::Net::ReliableStreamConnection::SendDisconnect()
void EQ::Net::DaybreakConnection::SendDisconnect()
{
ReliableStreamDisconnect disconnect;
DaybreakDisconnect disconnect;
disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code);
@ -1322,7 +1292,7 @@ void EQ::Net::ReliableStreamConnection::SendDisconnect()
InternalSend(out);
}
void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
{
if (p.Length() > 0xFFU) {
FlushBuffer();
@ -1331,7 +1301,7 @@ void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
}
//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) {
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.opcode = OP_SessionRequest;
connect.protocol_version = HostToNetwork(3U);
@ -1361,9 +1331,9 @@ void EQ::Net::ReliableStreamConnection::SendConnect()
InternalSend(p);
}
void EQ::Net::ReliableStreamConnection::SendKeepAlive()
void EQ::Net::DaybreakConnection::SendKeepAlive()
{
ReliableStreamHeader keep_alive;
DaybreakHeader keep_alive;
keep_alive.zero = 0;
keep_alive.opcode = OP_KeepAlive;
@ -1373,7 +1343,7 @@ void EQ::Net::ReliableStreamConnection::SendKeepAlive()
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) {
auto new_budget = m_outgoing_budget - (p.Length() / 1024.0);
if (new_budget <= 0.0) {
@ -1409,14 +1379,14 @@ void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) {
switch (m_encode_passe) {
case EncodeCompression:
if (out.GetInt8(0) == 0) {
Compress(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
Compress(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
} else {
Compress(out, 1, out.Length() - 1);
}
break;
case EncodeXOR:
if (out.GetInt8(0) == 0) {
Encode(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
Encode(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
} else {
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) {
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 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();
if (length > max_raw_size) {
ReliableStreamReliableFragmentHeader first_header;
DaybreakReliableFragmentHeader first_header;
first_header.reliable.zero = 0;
first_header.reliable.opcode = OP_Fragment + stream_id;
first_header.reliable.sequence = HostToNetwork(stream->sequence_out);
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
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;
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;
ReliableStreamSentPacket sent;
DaybreakSentPacket sent;
sent.packet.PutPacket(0, first_packet);
sent.last_sent = Clock::now();
sent.first_sent = Clock::now();
@ -1513,22 +1483,22 @@ void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int strea
while (used < length) {
auto left = length - used;
DynamicPacket packet;
ReliableStreamReliableHeader header;
DaybreakReliableHeader header;
header.zero = 0;
header.opcode = OP_Fragment + stream_id;
header.sequence = HostToNetwork(stream->sequence_out);
packet.PutSerialize(0, header);
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;
}
else {
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, left);
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, left);
used += left;
}
ReliableStreamSentPacket sent;
DaybreakSentPacket sent;
sent.packet.PutPacket(0, packet);
sent.last_sent = Clock::now();
sent.first_sent = Clock::now();
@ -1545,14 +1515,14 @@ void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int strea
}
else {
DynamicPacket packet;
ReliableStreamReliableHeader header;
DaybreakReliableHeader header;
header.zero = 0;
header.opcode = OP_Packet + stream_id;
header.sequence = HostToNetwork(stream->sequence_out);
packet.PutSerialize(0, header);
packet.PutPacket(ReliableStreamReliableHeader::size(), p);
packet.PutPacket(DaybreakReliableHeader::size(), p);
ReliableStreamSentPacket sent;
DaybreakSentPacket sent;
sent.packet.PutPacket(0, packet);
sent.last_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()) {
return;
@ -1595,7 +1565,7 @@ void EQ::Net::ReliableStreamConnection::FlushBuffer()
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;

View File

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

View File

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

View File

@ -1,11 +1,11 @@
#include "eqstream.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_reliable_stream.OnConnectionStateChange(std::bind(&EQStreamManager::ReliableStreamConnectionStateChange, 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.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
}
EQ::Net::EQStreamManager::~EQStreamManager()
@ -15,11 +15,11 @@ EQ::Net::EQStreamManager::~EQStreamManager()
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
{
m_options = options;
auto &opts = m_reliable_stream.GetOptions();
opts = options.reliable_stream_options;
auto &opts = m_daybreak.GetOptions();
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));
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);
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);
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_connection = connection;
@ -71,7 +71,7 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
OpcodeManager::EmuToName(p->GetOpcode()),
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
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) {
@ -235,7 +235,7 @@ EQStreamState EQ::Net::EQStream::GetState() {
EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
{
Stats ret;
ret.ReliableStreamStats = m_connection->GetStats();
ret.DaybreakStats = m_connection->GetStats();
for (int i = 0; i < _maxEmuOpcode; ++i) {
ret.RecvCount[i] = 0;

View File

@ -3,7 +3,7 @@
#include "../eq_packet.h"
#include "../eq_stream_intf.h"
#include "../opcodemgr.h"
#include "reliable_stream_connection.h"
#include "daybreak_connection.h"
#include <vector>
#include <deque>
#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 OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
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>, 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 ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
void ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p);
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
friend class EQStream;
};
class EQStream : public EQStreamInterface
{
public:
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<ReliableStreamConnection> connection);
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<DaybreakConnection> connection);
~EQStream();
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
@ -67,7 +67,7 @@ namespace EQ
virtual EQStreamManagerInterface* GetManager() const;
private:
EQStreamManagerInterface *m_owner;
std::shared_ptr<ReliableStreamConnection> m_connection;
std::shared_ptr<DaybreakConnection> m_connection;
OpcodeManager **m_opcode_manager;
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
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;
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) {
LogPacketServerToServer(
"[{:#06x}] Size [{}] {}",

View File

@ -78,7 +78,7 @@ namespace RoF
{
//create our opcode manager if we havent already
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.
//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.
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())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;

View File

@ -81,7 +81,7 @@ namespace RoF2
//create our opcode manager if we havent already
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.
//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.
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())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@ -6481,7 +6481,7 @@ namespace RoF2
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
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.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
}
@ -6500,7 +6500,6 @@ namespace RoF2
if (item->EvolvingItem > 0) {
RoF2::structs::EvolvingItem_Struct evotop;
inst->CalculateEvolveProgression();
evotop.final_item_id = inst->GetEvolveFinalItemID();
evotop.evolve_level = item->EvolvingLevel;

View File

@ -72,7 +72,7 @@ namespace SoD
{
//create our opcode manager if we havent already
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.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@ -113,7 +113,7 @@ namespace SoD
//we need to go to every stream and replace it's manager.
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())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@ -3966,12 +3966,12 @@ namespace SoD
SoDSlot = serverSlot - 2;
}
else if (serverSlot <= EQ::invbag::GENERAL_BAGS_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));;
else if (serverSlot <= EQ::invbag::GENERAL_BAGS_8_END && serverSlot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
SoDSlot = serverSlot + 11;
}
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) {
@ -3991,7 +3991,7 @@ namespace SoD
}
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) {
@ -3999,7 +3999,7 @@ namespace SoD
}
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) {
@ -4007,7 +4007,7 @@ namespace SoD
}
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) {
@ -4049,11 +4049,11 @@ namespace SoD
}
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) {
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) {
@ -4073,7 +4073,7 @@ namespace SoD
}
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) {
@ -4081,7 +4081,7 @@ namespace SoD
}
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) {
@ -4089,7 +4089,7 @@ namespace SoD
}
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) {

View File

@ -71,7 +71,7 @@ namespace SoF
{
//create our opcode manager if we havent already
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.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@ -110,7 +110,7 @@ namespace SoF
//we need to go to every stream and replace it's manager.
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())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@ -3355,12 +3355,12 @@ namespace SoF
sof_slot = server_slot - 2;
}
else if (server_slot <= EQ::invbag::GENERAL_BAGS_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));;
else if (server_slot <= EQ::invbag::GENERAL_BAGS_8_END && server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
sof_slot = server_slot + 11;
}
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) {
@ -3380,7 +3380,7 @@ namespace SoF
}
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) {
@ -3388,7 +3388,7 @@ namespace SoF
}
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) {
@ -3396,7 +3396,7 @@ namespace SoF
}
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) {
@ -3442,11 +3442,11 @@ namespace SoF
}
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) {
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) {
@ -3466,7 +3466,7 @@ namespace SoF
}
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) {
@ -3474,7 +3474,7 @@ namespace SoF
}
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) {
@ -3482,7 +3482,7 @@ namespace SoF
}
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) {

View File

@ -73,7 +73,7 @@ namespace Titanium
auto Config = EQEmuConfig::get();
//create our opcode manager if we havent already
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.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@ -114,7 +114,7 @@ namespace Titanium
//we need to go to every stream and replace it's manager.
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())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;
@ -1059,7 +1059,7 @@ namespace Titanium
OUT(spawnid);
OUT_str(charname);
if (emu->race > 474)
if (emu->race > 473)
eq->race = 1;
else
OUT(race);
@ -1840,7 +1840,7 @@ namespace Titanium
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
eq->Race[char_index] = emu_cse->Race;
if (eq->Race[char_index] > 474)
if (eq->Race[char_index] > 473)
eq->Race[char_index] = 1;
for (int index = 0; index < EQ::textures::materialCount; ++index) {
@ -2421,7 +2421,7 @@ namespace Titanium
strcpy(eq->title, emu->title);
// eq->unknown0274 = emu->unknown0274;
eq->helm = emu->helm;
if (emu->race > 474)
if (emu->race > 473)
eq->race = 1;
else
eq->race = emu->race;
@ -3596,12 +3596,12 @@ namespace Titanium
else if (server_slot == (EQ::invslot::POSSESSIONS_COUNT + EQ::invslot::slotAmmo)) {
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) {
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) {
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) {
titanium_slot = server_slot;
@ -3616,21 +3616,21 @@ namespace Titanium
else if (server_slot <= EQ::invslot::BANK_END && server_slot >= EQ::invslot::BANK_BEGIN) {
titanium_slot = server_slot;
}
else if (server_slot <= EQ::invbag::BANK_BAGS_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));
else if (server_slot <= EQ::invbag::BANK_BAGS_16_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
titanium_slot = server_slot;
}
else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
titanium_slot = server_slot;
}
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END &&
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) {
titanium_slot = server_slot;
}
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) {
titanium_slot = server_slot;
@ -3687,10 +3687,10 @@ namespace Titanium
server_slot = titanium_slot + 4;
}
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) {
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) {
server_slot = titanium_slot;
@ -3705,19 +3705,19 @@ namespace Titanium
server_slot = titanium_slot;
}
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) {
server_slot = titanium_slot;
}
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) {
server_slot = titanium_slot;
}
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) {
server_slot = titanium_slot;

View File

@ -76,7 +76,7 @@ namespace UF
{
//create our opcode manager if we havent already
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.
//TODO: figure out how to support shared memory with multiple patches...
opcodes = new RegularOpcodeManager();
@ -117,7 +117,7 @@ namespace UF
//we need to go to every stream and replace it's manager.
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())) {
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
return;

View File

@ -8,7 +8,7 @@
namespace fs = std::filesystem;
void PathManager::Init()
void PathManager::LoadPaths()
{
m_server_path = File::FindEqemuConfigPath();
@ -48,23 +48,10 @@ void PathManager::Init()
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_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_patch_path = resolve_path(c->PatchDir);
m_opcode_path = resolve_path(c->OpcodeDir);
@ -75,10 +62,13 @@ void PathManager::Init()
std::vector<std::pair<std::string, std::string>> paths = {
{"server", m_server_path},
{"logs", m_log_path},
{"maps", m_maps_path},
{"lua mods", m_lua_mods_path},
{"lua_modules", m_lua_modules_path},
{"maps", m_maps_path},
{"patches", m_patch_path},
{"opcode", m_opcode_path},
{"plugins", m_plugins_path},
{"quests", m_quests_path},
{"shared_memory", m_shared_memory_path}
};
@ -93,17 +83,6 @@ void PathManager::Init()
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));
}
@ -117,26 +96,21 @@ const std::string &PathManager::GetMapsPath() const
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
{
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
{
return m_log_path;
@ -152,6 +126,11 @@ const std::string &PathManager::GetOpcodePath() const
return m_opcode_path;
}
const std::string &PathManager::GetLuaModulesPath() const
{
return m_lua_modules_path;
}
const std::string &PathManager::GetLuaModsPath() const
{
return m_lua_mods_path;

View File

@ -3,17 +3,10 @@
#include <string>
#include <vector>
class PathManager {
public:
void Init();
static PathManager *Instance()
{
static PathManager instance;
return &instance;
}
void LoadPaths();
[[nodiscard]] const std::string &GetLogPath() const;
[[nodiscard]] const std::string &GetLuaModsPath() const;
@ -21,27 +14,24 @@ public:
[[nodiscard]] const std::string &GetMapsPath() const;
[[nodiscard]] const std::string &GetPatchPath() 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 &GetSharedMemoryPath() const;
[[nodiscard]] std::vector<std::string> GetQuestPaths() const;
[[nodiscard]] std::vector<std::string> GetPluginPaths() const;
[[nodiscard]] std::vector<std::string> GetLuaModulePaths() const;
private:
std::string m_log_path;
std::string m_lua_mods_path;
std::string m_maps_path;
std::string m_patch_path;
std::string m_opcode_path;
std::string m_quests_path;
std::vector<std::string> m_quests_paths;
std::vector<std::string> m_plugin_paths;
std::vector<std::string> m_lua_module_paths;
private:
std::string m_server_path;
std::string m_shared_memory_path;
std::string m_log_path;
std::string m_lua_mods_path;
std::string m_lua_modules_path;
std::string m_maps_path;
std::string m_patch_path;
std::string m_opcode_path;
std::string m_plugins_path;
std::string m_quests_path;
std::string m_server_path;
std::string m_shared_memory_path;
};
extern PathManager path;
#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 <memory>
#include "process.h"
#include <fmt/format.h>
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 <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* GetPlayerRaceName(uint32 player_race_value);
const char* GetGenderName(uint32 gender_id);
bool IsPlayerRace(uint16 race_id);
@ -31,13 +127,25 @@ uint32 GetPlayerRaceValue(uint16 race_id);
uint16 GetPlayerRaceBit(uint16 race_id);
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
float GetRaceGenderDefaultHeight(int race, int gender);
namespace Gender {
constexpr uint8 Male = 0;
constexpr uint8 Female = 1;
constexpr uint8 Neuter = 2;
// player race-/gender-based model feature validators
namespace PlayerAppearance
{
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 {
@ -776,92 +884,8 @@ namespace Race {
constexpr uint16 Pegasus3 = 732;
constexpr uint16 InteractiveObject = 2250;
constexpr uint16 Node = 2254;
}
namespace RaceBitmask {
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;
constexpr uint16 ALL_RACES_BITMASK = 65535;
}
#endif

View File

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

View File

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

View File

@ -30,7 +30,6 @@ public:
uint32_t aug_slot_5;
uint32_t aug_slot_6;
uint32_t quantity;
uint32_t evolve_amount;
};
static std::string PrimaryKey()
@ -52,7 +51,6 @@ public:
"aug_slot_5",
"aug_slot_6",
"quantity",
"evolve_amount",
};
}
@ -70,7 +68,6 @@ public:
"aug_slot_5",
"aug_slot_6",
"quantity",
"evolve_amount",
};
}
@ -111,18 +108,17 @@ public:
{
CharacterParcelsContainers e{};
e.id = 0;
e.parcels_id = 0;
e.slot_id = 0;
e.item_id = 0;
e.aug_slot_1 = 0;
e.aug_slot_2 = 0;
e.aug_slot_3 = 0;
e.aug_slot_4 = 0;
e.aug_slot_5 = 0;
e.aug_slot_6 = 0;
e.quantity = 0;
e.evolve_amount = 0;
e.id = 0;
e.parcels_id = 0;
e.slot_id = 0;
e.item_id = 0;
e.aug_slot_1 = 0;
e.aug_slot_2 = 0;
e.aug_slot_3 = 0;
e.aug_slot_4 = 0;
e.aug_slot_5 = 0;
e.aug_slot_6 = 0;
e.quantity = 0;
return e;
}
@ -159,18 +155,17 @@ public:
if (results.RowCount() == 1) {
CharacterParcelsContainers e{};
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.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.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_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_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.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.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.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.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_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_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.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
return e;
}
@ -214,7 +209,6 @@ public:
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[10] + " = " + std::to_string(e.quantity));
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
auto results = db.QueryDatabase(
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_6));
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
auto results = db.QueryDatabase(
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_6));
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@ -322,18 +314,17 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcelsContainers e{};
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.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.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_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_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.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.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.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.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_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_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.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
all_entries.push_back(e);
}
@ -358,18 +349,17 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcelsContainers e{};
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.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.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_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_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.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.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.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.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_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_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.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
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_6));
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
auto results = db.QueryDatabase(
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_6));
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.evolve_amount));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}

View File

@ -30,7 +30,6 @@ public:
uint32_t aug_slot_6;
uint32_t slot_id;
uint32_t quantity;
uint32_t evolve_amount;
std::string from_name;
std::string note;
time_t sent_date;
@ -55,7 +54,6 @@ public:
"aug_slot_6",
"slot_id",
"quantity",
"evolve_amount",
"from_name",
"note",
"sent_date",
@ -76,7 +74,6 @@ public:
"aug_slot_6",
"slot_id",
"quantity",
"evolve_amount",
"from_name",
"note",
"UNIX_TIMESTAMP(sent_date)",
@ -120,21 +117,20 @@ public:
{
CharacterParcels e{};
e.id = 0;
e.char_id = 0;
e.item_id = 0;
e.aug_slot_1 = 0;
e.aug_slot_2 = 0;
e.aug_slot_3 = 0;
e.aug_slot_4 = 0;
e.aug_slot_5 = 0;
e.aug_slot_6 = 0;
e.slot_id = 0;
e.quantity = 0;
e.evolve_amount = 0;
e.from_name = "";
e.note = "";
e.sent_date = 0;
e.id = 0;
e.char_id = 0;
e.item_id = 0;
e.aug_slot_1 = 0;
e.aug_slot_2 = 0;
e.aug_slot_3 = 0;
e.aug_slot_4 = 0;
e.aug_slot_5 = 0;
e.aug_slot_6 = 0;
e.slot_id = 0;
e.quantity = 0;
e.from_name = "";
e.note = "";
e.sent_date = 0;
return e;
}
@ -171,21 +167,20 @@ public:
if (results.RowCount() == 1) {
CharacterParcels e{};
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.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_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_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_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.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[12] ? row[12] : "";
e.note = row[13] ? row[13] : "";
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
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.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_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_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_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.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.from_name = row[11] ? row[11] : "";
e.note = row[12] ? row[12] : "";
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
return e;
}
@ -229,10 +224,9 @@ public:
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[10] + " = " + std::to_string(e.quantity));
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
v.push_back(columns[12] + " = '" + Strings::Escape(e.from_name) + "'");
v.push_back(columns[13] + " = '" + Strings::Escape(e.note) + "'");
v.push_back(columns[14] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
v.push_back(columns[11] + " = '" + Strings::Escape(e.from_name) + "'");
v.push_back(columns[12] + " = '" + Strings::Escape(e.note) + "'");
v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -265,7 +259,6 @@ public:
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.quantity));
v.push_back(std::to_string(e.evolve_amount));
v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'");
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.slot_id));
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.note) + "'");
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) {
CharacterParcels e{};
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.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_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_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_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.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[12] ? row[12] : "";
e.note = row[13] ? row[13] : "";
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
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.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_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_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_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.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.from_name = row[11] ? row[11] : "";
e.note = row[12] ? row[12] : "";
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@ -385,21 +376,20 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcels e{};
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.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_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_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_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.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[12] ? row[12] : "";
e.note = row[13] ? row[13] : "";
e.sent_date = strtoll(row[14] ? row[14] : "-1", nullptr, 10);
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.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_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_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_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.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.from_name = row[11] ? row[11] : "";
e.note = row[12] ? row[12] : "";
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
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.slot_id));
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.note) + "'");
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.slot_id));
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.note) + "'");
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 shielding;
int32_t spell_damage;
int32_t heal_amount;
int32_t spell_shielding;
int32_t strikethrough;
int32_t stun_resist;
@ -155,7 +154,6 @@ public:
"endurance_regen",
"shielding",
"spell_damage",
"heal_amount",
"spell_shielding",
"strikethrough",
"stun_resist",
@ -236,7 +234,6 @@ public:
"endurance_regen",
"shielding",
"spell_damage",
"heal_amount",
"spell_shielding",
"strikethrough",
"stun_resist",
@ -351,7 +348,6 @@ public:
e.endurance_regen = 0;
e.shielding = 0;
e.spell_damage = 0;
e.heal_amount = 0;
e.spell_shielding = 0;
e.strikethrough = 0;
e.stun_resist = 0;
@ -462,30 +458,29 @@ public:
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.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[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[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.backstab = 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[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.string = 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[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.baking = 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[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.blacksmithing = 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[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.jewelry = 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[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.alcohol = 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[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
return e;
}
@ -570,30 +565,29 @@ public:
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[50] + " = " + std::to_string(e.spell_damage));
v.push_back(columns[51] + " = " + std::to_string(e.heal_amount));
v.push_back(columns[52] + " = " + std::to_string(e.spell_shielding));
v.push_back(columns[53] + " = " + std::to_string(e.strikethrough));
v.push_back(columns[54] + " = " + std::to_string(e.stun_resist));
v.push_back(columns[55] + " = " + std::to_string(e.backstab));
v.push_back(columns[56] + " = " + std::to_string(e.wind));
v.push_back(columns[57] + " = " + std::to_string(e.brass));
v.push_back(columns[58] + " = " + std::to_string(e.string));
v.push_back(columns[59] + " = " + std::to_string(e.percussion));
v.push_back(columns[60] + " = " + std::to_string(e.singing));
v.push_back(columns[61] + " = " + std::to_string(e.baking));
v.push_back(columns[62] + " = " + std::to_string(e.alchemy));
v.push_back(columns[63] + " = " + std::to_string(e.tailoring));
v.push_back(columns[64] + " = " + std::to_string(e.blacksmithing));
v.push_back(columns[65] + " = " + std::to_string(e.fletching));
v.push_back(columns[66] + " = " + std::to_string(e.brewing));
v.push_back(columns[67] + " = " + std::to_string(e.jewelry));
v.push_back(columns[68] + " = " + std::to_string(e.pottery));
v.push_back(columns[69] + " = " + std::to_string(e.research));
v.push_back(columns[70] + " = " + std::to_string(e.alcohol));
v.push_back(columns[71] + " = " + std::to_string(e.fishing));
v.push_back(columns[72] + " = " + std::to_string(e.tinkering));
v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
v.push_back(columns[74] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
v.push_back(columns[51] + " = " + 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.stun_resist));
v.push_back(columns[54] + " = " + std::to_string(e.backstab));
v.push_back(columns[55] + " = " + std::to_string(e.wind));
v.push_back(columns[56] + " = " + std::to_string(e.brass));
v.push_back(columns[57] + " = " + std::to_string(e.string));
v.push_back(columns[58] + " = " + std::to_string(e.percussion));
v.push_back(columns[59] + " = " + std::to_string(e.singing));
v.push_back(columns[60] + " = " + std::to_string(e.baking));
v.push_back(columns[61] + " = " + std::to_string(e.alchemy));
v.push_back(columns[62] + " = " + std::to_string(e.tailoring));
v.push_back(columns[63] + " = " + std::to_string(e.blacksmithing));
v.push_back(columns[64] + " = " + std::to_string(e.fletching));
v.push_back(columns[65] + " = " + std::to_string(e.brewing));
v.push_back(columns[66] + " = " + std::to_string(e.jewelry));
v.push_back(columns[67] + " = " + std::to_string(e.pottery));
v.push_back(columns[68] + " = " + std::to_string(e.research));
v.push_back(columns[69] + " = " + std::to_string(e.alcohol));
v.push_back(columns[70] + " = " + std::to_string(e.fishing));
v.push_back(columns[71] + " = " + 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.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@ -666,7 +660,6 @@ public:
v.push_back(std::to_string(e.endurance_regen));
v.push_back(std::to_string(e.shielding));
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.strikethrough));
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.shielding));
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.strikethrough));
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.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.heal_amount = 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[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[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.wind = 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[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.percussion = 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[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.alchemy = 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[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.fletching = 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[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.pottery = 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[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.fishing = 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[73] ? row[73] : "-1", nullptr, 10);
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@ -977,30 +968,29 @@ public:
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.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[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[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.backstab = 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[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.string = 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[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.baking = 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[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.blacksmithing = 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[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.jewelry = 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[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.alcohol = 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[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
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.shielding));
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.strikethrough));
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.shielding));
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.strikethrough));
v.push_back(std::to_string(e.stun_resist));

View File

@ -15,7 +15,7 @@
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
#include <cereal/cereal.hpp>
class BasePlayerEventLogSettingsRepository {
public:
struct PlayerEventLogSettings {
@ -25,20 +25,6 @@ public:
int32_t retention_days;
int32_t discord_webhook_id;
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()

View File

@ -231,21 +231,6 @@ public:
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

View File

@ -167,46 +167,6 @@ public:
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

View File

@ -49,7 +49,6 @@ public:
// these are the base definitions for command_subsettings and can be over-ridden by the database
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 = "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 = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"},
{.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 = "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 = "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 = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"},
{.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 + ".";
}
int current_expansion_filter_criteria = WorldContentService::Instance()->GetCurrentExpansion();
int current_expansion_filter_criteria = content_service.GetCurrentExpansion();
if (current_expansion_filter_criteria == Expansion::EXPANSION_ALL) {
current_expansion_filter_criteria = Expansion::EXPANSION_FILTER_MAX;
}
@ -33,8 +33,8 @@ namespace ContentFilterCriteria {
table_prefix
);
std::vector<std::string> flags_disabled = WorldContentService::Instance()->GetContentFlagsDisabled();
std::vector<std::string> flags_enabled = WorldContentService::Instance()->GetContentFlagsEnabled();
std::vector<std::string> flags_disabled = content_service.GetContentFlagsDisabled();
std::vector<std::string> flags_enabled = content_service.GetContentFlagsEnabled();
std::string flags_in_filter_enabled;
std::string flags_in_filter_disabled;
if (!flags_enabled.empty()) {

View File

@ -43,47 +43,6 @@ public:
* 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
static std::vector<std::string> GetRuleNames(Database &db, int rule_set_id)
{
@ -128,28 +87,12 @@ public:
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)
{
const auto query = fmt::format(
"DELETE FROM {} WHERE rule_name IN ({})",
TableName(),
ImplodePair(",", std::pair<char, char>('\'', '\''), v)
Strings::ImplodePair(",", std::pair<char, char>('\'', '\''), v)
);
return db.QueryDatabase(query).Success();
@ -160,7 +103,7 @@ public:
const auto query = fmt::format(
"REPLACE INTO {} (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES {}",
TableName(),
ImplodePair(
Strings::ImplodePair(
",",
std::pair<char, char>('(', ')'),
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 (!RuleValuesRepository::InjectRules(*db, injected_rule_entries)) {
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_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, 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(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, 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, 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_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.")
@ -1079,7 +1073,6 @@ RULE_CATEGORY(Logging)
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, 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, 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()

View File

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

View File

@ -48,7 +48,7 @@ enum class SharedTaskRequestGroupType {
struct ServerSharedTaskRequest_Struct {
uint32 requested_character_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;
};

View File

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

View File

@ -76,20 +76,21 @@ public:
uint8 GetGMSpeed(uint32 account_id);
bool SetHideMe(uint32 account_id, uint8 hideme);
int DeleteStalePlayerCorpses();
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* s);
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* s);
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct *message);
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 UpdateInjectedCommandSettings(const std::vector<std::pair<std::string, uint8>> &injected);
bool UpdateOrphanedCommandSettings(const std::vector<std::string> &orphaned);
bool GetCommandSubSettings(std::vector<CommandSubsettingsRepository::CommandSubsettings> &command_subsettings);
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
bool SetGMInvul(uint32 account_id, bool gminvul);
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 {
std::string mail_key;
std::string mail_key_full;
};
MailKeys GetMailKey(uint32 character_id);
MailKeys GetMailKey(int character_id);
bool SaveCursor(
uint32 char_id,
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 GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is_charid);
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(uint32 account_id, char *name, EQ::InventoryProfile *inv); // deprecated
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
@ -157,7 +158,7 @@ public:
);
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);
bool LoadItems(const std::string &prefix);
const EQ::ItemData *IterateItems(uint32 *id) const;
@ -172,7 +173,7 @@ public:
int GetMaxSpellID();
bool LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp);
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 GetSpellsCount();

View File

@ -16,16 +16,12 @@ public:
static int32_t GetSkillCapMaxLevel(uint8 class_id, EQ::skills::SkillType skill_id);
SkillCaps *SetContentDatabase(Database *db);
static SkillCaps* Instance()
{
static SkillCaps instance;
return &instance;
}
private:
Database *m_content_database{};
std::map<uint64, SkillCapsRepository::SkillCaps> m_skill_caps = {};
};
extern SkillCaps skill_caps;
#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::PetCompleteHeals:
case BotSpellTypes::GroupCompleteHeals:
case BotSpellTypes::Resurrect:
return false;
default:
return true;

View File

@ -34,7 +34,6 @@
*/
#include "strings.h"
#include <cereal/external/rapidjson/document.h>
#include <fmt/format.h>
#include <algorithm>
#include <cctype>
@ -42,7 +41,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <random>
#include <string>
@ -51,12 +49,6 @@
#include "strings_legacy.cpp" // legacy c functions
#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)
{
static auto &chrs = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
@ -313,12 +305,6 @@ std::string Strings::Commify(const std::string &number)
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;
for (i = string_length - 3; i >= 0; i -= 3) {
if (i > 0) {
@ -715,18 +701,6 @@ std::string &Strings::Trim(std::string &str, const std::string &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
std::string Strings::ConvertToDigit(int n, const std::string& suffix)
{

View File

@ -36,19 +36,53 @@
#define _STRINGUTIL_H_
#include <charconv>
#include <cstring>
#include <sstream>
#include <string.h>
#include <string_view>
#include <string>
#include <vector>
#include <cstdarg>
#include <tuple>
#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 <functional>
#include <algorithm>
#endif
#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 {
public:
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 EndsWith(const std::string& subject, const std::string& search);
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 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.
// 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
std::string SanitizeWorldServerName(std::string server_long_name);
std::vector<std::string> GetBadWords();
@ -134,4 +310,18 @@ std::string FormatName(const std::string &char_name);
bool IsAllowedWorldServerCharacterList(char c);
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

View File

@ -25,7 +25,7 @@
// Build variables
// 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 COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
@ -42,9 +42,8 @@
* 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 CUSTOM_BINARY_DATABASE_VERSION 0
#endif

View File

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

View File

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

View File

@ -33,7 +33,7 @@ EverQuest::EverQuest(const std::string &host, int port, const std::string &user,
}
else {
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->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;
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) {
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) {
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);
switch (opcode) {
@ -251,20 +251,20 @@ void EverQuest::LoginDisableReconnect()
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->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->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;
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) {
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) {
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);
switch (opcode) {

26
hc/eq.h
View File

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

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