mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 11:31:30 +00:00
Compare commits
133 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c057308da | ||
|
|
0bc0ee609a | ||
|
|
c84df0d5ba | ||
|
|
9b3f9f356d | ||
|
|
e42dc2e1d2 | ||
|
|
c611a25385 | ||
|
|
f74efcaa5f | ||
|
|
eb4e7d694c | ||
|
|
ecc0d4b5c0 | ||
|
|
8175ae6187 | ||
|
|
e8f4ffd628 | ||
|
|
0447618f7e | ||
|
|
e71ce001ff | ||
|
|
1575a2af40 | ||
|
|
4b69df646c | ||
|
|
044b9c1420 | ||
|
|
0bbb5b90e7 | ||
|
|
6506ad5b51 | ||
|
|
dcaa0ecdaa | ||
|
|
9b143132be | ||
|
|
231bf8b4ec | ||
|
|
dee58f9a91 | ||
|
|
1eb89edbbd | ||
|
|
e015d0d67e | ||
|
|
ba78394ce9 | ||
|
|
060f6e377d | ||
|
|
92c8b0e585 | ||
|
|
33df8ea665 | ||
|
|
9668074d94 | ||
|
|
822a5dcac4 | ||
|
|
0c65a4febe | ||
|
|
02f66de679 | ||
|
|
145111f11e | ||
|
|
a4e47d9180 | ||
|
|
207ee2daa0 | ||
|
|
1fe5d9fa4f | ||
|
|
ed3f6c2a40 | ||
|
|
adb3196ca5 | ||
|
|
e13b133ac8 | ||
|
|
d475428157 | ||
|
|
00b66ce432 | ||
|
|
4d12dd5c43 | ||
|
|
c4f408bffc | ||
|
|
d876c6df2a | ||
|
|
d142e1ca81 | ||
|
|
d9f4d49ef4 | ||
|
|
0a1df5bbb6 | ||
|
|
41f3d7ff31 | ||
|
|
0afef19d26 | ||
|
|
e9be2d76c3 | ||
|
|
ffa813b92c | ||
|
|
909de47acd | ||
|
|
73a5f11e17 | ||
|
|
9544e100c3 | ||
|
|
f3232cdc3a | ||
|
|
b8884d6572 | ||
|
|
323a0c0b27 | ||
|
|
ab45d4358d | ||
|
|
f7775c7a75 | ||
|
|
659a960401 | ||
|
|
07d484597d | ||
|
|
fc470d5f83 | ||
|
|
585ed3bd25 | ||
|
|
2eb291a461 | ||
|
|
a1421af214 | ||
|
|
13aad6229f | ||
|
|
76d46ceaf0 | ||
|
|
389047c4e2 | ||
|
|
2c6d405b2c | ||
|
|
50ae0f8351 | ||
|
|
dc261bb203 | ||
|
|
643ee56433 | ||
|
|
c0bb32ed12 | ||
|
|
c99bda3f47 | ||
|
|
967a13e692 | ||
|
|
f304f9cc61 | ||
|
|
004e2ca63f | ||
|
|
128732e05d | ||
|
|
1e6a4dac78 | ||
|
|
654764685a | ||
|
|
c5ab35e4af | ||
|
|
947795f1d1 | ||
|
|
1153c9ab96 | ||
|
|
2128b45313 | ||
|
|
4f7ff2d6f2 | ||
|
|
b5f1e99d3b | ||
|
|
83918ce020 | ||
|
|
f3aaeff0a9 | ||
|
|
98eff43346 | ||
|
|
46b43a990f | ||
|
|
ea96cbf885 | ||
|
|
de07870c99 | ||
|
|
b3b228c26c | ||
|
|
27b5c80c3c | ||
|
|
fb4d003e19 | ||
|
|
f025e5741b | ||
|
|
c3f2708f1b | ||
|
|
2e760d6397 | ||
|
|
bac892b582 | ||
|
|
4005b68383 | ||
|
|
5ac9dd04e4 | ||
|
|
f0c041e8b3 | ||
|
|
2f4a5b56dd | ||
|
|
940f97c9ae | ||
|
|
f8ee664b27 | ||
|
|
df86ad371b | ||
|
|
e846bb86b6 | ||
|
|
3e6a3e2168 | ||
|
|
2aebf1a78a | ||
|
|
1be7e56b86 | ||
|
|
a0ff9d67a1 | ||
|
|
befee1c729 | ||
|
|
3d70063a68 | ||
|
|
4e28bcf85e | ||
|
|
687d10960a | ||
|
|
567d46c3d6 | ||
|
|
53cc2de459 | ||
|
|
cb866cba31 | ||
|
|
e2162c08da | ||
|
|
e657953b8f | ||
|
|
eb366e67b7 | ||
|
|
5b728a42f7 | ||
|
|
a1d414d64c | ||
|
|
907029ed76 | ||
|
|
894f22fba0 | ||
|
|
7ec09d7e0f | ||
|
|
c82266790a | ||
|
|
ec31fddbae | ||
|
|
fb49ce2404 | ||
|
|
276b7e238a | ||
|
|
c7a463420b | ||
|
|
a56bb52808 | ||
|
|
0bbdb58679 |
11
.devcontainer/.gitignore
vendored
11
.devcontainer/.gitignore
vendored
@ -1,6 +1,5 @@
|
|||||||
!Makefile
|
base/
|
||||||
base/*.sql
|
!base/*.json
|
||||||
base/*.zip
|
override/
|
||||||
base/db/
|
repo/
|
||||||
base/maps/
|
cache/
|
||||||
!base/expansion/Makefile
|
|
||||||
|
|||||||
@ -1,196 +1,127 @@
|
|||||||
|
# Build binaries: make cmake, make build
|
||||||
|
# One time initial setup (or to reset db): make prep, make inject-mariadb, make maps
|
||||||
|
# Update custom db edits: make inject-custom
|
||||||
|
# Start up server: make shared, make login, make world, make zone
|
||||||
|
# in game, stop combat spam #logs set gmsay 79 0
|
||||||
|
# in game, stop loot spam #logs set gmsay 69 0
|
||||||
NAME := eqemu-server
|
NAME := eqemu-server
|
||||||
.ONESHELL:
|
|
||||||
|
|
||||||
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
|
|
||||||
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
|
|
||||||
|
|
||||||
.PHONY: build
|
|
||||||
build:
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
|
|
||||||
|
|
||||||
.PHONY: cmake
|
|
||||||
cmake:
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@echo "working directory: $$PWD"
|
|
||||||
mkdir -p build$$BUILD_SUFFIX
|
|
||||||
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
|
|
||||||
-DEQEMU_BUILD_TESTS=ON \
|
|
||||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
|
|
||||||
|
|
||||||
clean:
|
|
||||||
ifneq (,$(findstring .devcontainer,$$PWD))
|
|
||||||
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
|
|
||||||
endif
|
|
||||||
rm -rf build
|
|
||||||
|
|
||||||
docker-cmake:
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@echo "working directory: $$PWD"
|
|
||||||
git submodule update --init --recursive
|
|
||||||
docker run ${DOCKER_ARGS} make cmake
|
|
||||||
|
|
||||||
docker-build:
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
docker run ${DOCKER_ARGS} make build
|
|
||||||
|
|
||||||
# Build image if it doesn't exist
|
|
||||||
docker-image-build:
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
|
|
||||||
@echo "Docker image not found. Building..."
|
|
||||||
docker build -f Dockerfile.debian.dev -t ${NAME} .
|
|
||||||
endif
|
|
||||||
|
|
||||||
docker-arm-cmake: docker-arm-image-build
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
git submodule update --init --recursive
|
|
||||||
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
|
|
||||||
|
|
||||||
docker-arm-build: docker-arm-image-build
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
|
|
||||||
|
|
||||||
docker-arm-image-build:
|
|
||||||
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
|
|
||||||
@echo "Docker image not found. Building..."
|
|
||||||
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
|
|
||||||
endif
|
|
||||||
|
|
||||||
docker-clean: clean
|
|
||||||
|
|
||||||
.PHONY: prep
|
.PHONY: prep
|
||||||
prep:
|
prep: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@echo "Preparing build/bin for usage..."
|
@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
|
@echo "Prepping folders..."
|
||||||
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
|
@mkdir -p .devcontainer/override
|
||||||
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
|
@mkdir -p .devcontainer/repo
|
||||||
mkdir -p build/bin/assets
|
@mkdir -p .devcontainer/cache
|
||||||
cp -R -u -p utils/patches build/bin/assets/
|
@mkdir -p build/bin/logs
|
||||||
-unlink build/bin/lua_modules
|
@mkdir -p build/bin/shared
|
||||||
cd build/bin && ln -s quests/lua_modules lua_modules
|
@mkdir -p build/bin/assets
|
||||||
-unlink build/bin/mods
|
|
||||||
cd build/bin && ln -s quests/mods mods
|
@echo "Applying overrides..."
|
||||||
-unlink build/bin/maps
|
@if [ ! -f .devcontainer/override/eqemu_config.json ]; then cp .devcontainer/base/eqemu_config.json .devcontainer/override/eqemu_config.json; fi
|
||||||
cd build/bin && ln -s ../../base/maps maps
|
@if [ -f build/bin/eqemu_config.json ]; then unlink build/bin/eqemu_config.json; fi
|
||||||
mkdir -p build/bin/logs
|
cd build/bin && ln -s ../../.devcontainer/override/eqemu_config.json eqemu_config.json
|
||||||
mkdir -p build/bin/shared
|
@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
|
||||||
|
|
||||||
|
@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."
|
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
|
||||||
|
|
||||||
maps:
|
is-vscode:
|
||||||
@echo "Downloading maps..."
|
@if [ -z "$$REMOTE_CONTAINERS" ]; then \
|
||||||
@mkdir -p base/maps
|
echo "Not running in VS Code devcontainer"; \
|
||||||
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
|
exit 1; \
|
||||||
@cd base/maps && unzip -o master.zip
|
fi
|
||||||
@cd base/maps && mv eqemu-maps-master/* .
|
|
||||||
@cd base/maps && rm -rf eqemu-maps-master
|
|
||||||
@echo "Maps downloaded."
|
|
||||||
|
|
||||||
quests:
|
clean: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
rm -rf build
|
||||||
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
|
|
||||||
exit
|
.PHONY: maps
|
||||||
endif
|
maps: is-vscode
|
||||||
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
|
@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
|
||||||
|
@echo "Maps downloaded."
|
||||||
|
|
||||||
# Runs tests
|
# Runs tests
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
cd build/bin && ./tests
|
cd build/bin && ./tests
|
||||||
|
|
||||||
# Runs login binary
|
# Runs login binary
|
||||||
.PHONY: login
|
.PHONY: login
|
||||||
login:
|
login: is-vscode check-mariadb
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
cd build/bin && ./loginserver
|
cd build/bin && ./loginserver
|
||||||
|
|
||||||
|
.PHONY: hotfix
|
||||||
|
hotfix: shared
|
||||||
|
|
||||||
# Runs shared_memory binary
|
# Runs shared_memory binary
|
||||||
.PHONY: shared
|
.PHONY: shared
|
||||||
shared:
|
shared: is-vscode check-mariadb
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
cd build/bin && ./shared_memory
|
cd build/bin && ./shared_memory
|
||||||
|
|
||||||
# Runs zone binary
|
# Runs zone binary
|
||||||
.PHONY: zone
|
.PHONY: zone
|
||||||
zone:
|
zone: is-vscode check-mariadb
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
@find build/bin/logs/zone/ -type f -name 'zone*.log' -exec rm -f {} +
|
||||||
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@-rm build/bin/logs/zone/zone*.log
|
|
||||||
cd build/bin && ./zone
|
cd build/bin && ./zone
|
||||||
|
|
||||||
|
check-mariadb: is-vscode
|
||||||
|
@if ! sudo service mariadb status | grep -q 'active (running)'; then \
|
||||||
|
sudo service mariadb start; \
|
||||||
|
fi
|
||||||
|
|
||||||
# Runs world binary
|
# Runs world binary
|
||||||
.PHONY: world
|
.PHONY: world
|
||||||
world:
|
world: is-vscode check-mariadb
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
@find build/bin/logs/ -type f -name 'world*.log' -exec rm -f {} +
|
||||||
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@-rm build/bin/logs/world*.log
|
|
||||||
cd build/bin && ./world
|
cd build/bin && ./world
|
||||||
|
|
||||||
# Runs ucs binary
|
# Runs ucs binary
|
||||||
.PHONY: ucs
|
.PHONY: ucs
|
||||||
ucs:
|
ucs: is-vscode check-mariadb
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
@find build/bin/logs/ -type f -name 'ucs*.log' -exec rm -f {} +
|
||||||
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@-rm build/bin/logs/ucs*.log
|
|
||||||
cd build/bin && ./ucs
|
cd build/bin && ./ucs
|
||||||
|
|
||||||
# Runs queryserv binary
|
# Runs queryserv binary
|
||||||
.PHONY: queryserv
|
.PHONY: queryserv
|
||||||
queryserv:
|
queryserv: is-vscode check-mariadb
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
@find build/bin/logs/ -type f -name 'query_server*.log' -exec rm -f {} +
|
||||||
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@-rm build/bin/logs/query_server*.log
|
|
||||||
cd build/bin && ./queryserv
|
cd build/bin && ./queryserv
|
||||||
|
|
||||||
valgrind-%:
|
reset-content:
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
@echo "Resetting content tables in database peq..."
|
||||||
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
|
cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
|
||||||
exit
|
|
||||||
endif
|
valgrind-%: is-vscode
|
||||||
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
|
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
|
||||||
|
|
||||||
# Start mariaDB standalone
|
# Start mariaDB standalone
|
||||||
@ -201,30 +132,33 @@ mariadb:
|
|||||||
.PHONY: inject-mariadb
|
.PHONY: inject-mariadb
|
||||||
inject-mariadb:
|
inject-mariadb:
|
||||||
-sudo service mariadb start
|
-sudo service mariadb start
|
||||||
-mkdir -p base/db/
|
-mkdir -p .devcontainer/cache/db/
|
||||||
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
|
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
|
||||||
-sudo mariadb -e 'CREATE DATABASE peq;'
|
-sudo mariadb -e 'CREATE DATABASE peq;'
|
||||||
-sudo mariadb -e "CREATE USER 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
-sudo mariadb -e "CREATE USER IF NOT EXISTS 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
||||||
-sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
|
-sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
|
||||||
ifeq (,$(wildcard base/db/db.sql.zip))
|
ifeq (,$(wildcard .devcontainer/cache/db/db.sql.zip))
|
||||||
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
|
@echo ".devcontainer/cache/db.sql.zip not found. Downloading database from https://db.eqemu.dev/latest"
|
||||||
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
|
wget -nc https://db.eqemu.dev/latest -O .devcontainer/cache/db/db.sql.zip
|
||||||
-cd base/db && unzip db.sql.zip
|
-cd .devcontainer/cache/db && unzip db.sql.zip
|
||||||
endif
|
endif
|
||||||
@echo "Sourcing db may take a while, please wait..."
|
@echo "Sourcing db may take a while, please wait..."
|
||||||
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
|
|
||||||
|
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
|
||||||
|
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_login.sql"
|
||||||
|
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_player.sql"
|
||||||
|
@# deprecated cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_queryserv.sql"
|
||||||
|
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_state.sql"
|
||||||
|
@cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_system.sql"
|
||||||
|
|
||||||
@echo "MariaDB is now injected."
|
@echo "MariaDB is now injected."
|
||||||
|
|
||||||
.PHONY: gm-%
|
.PHONY: gm-%
|
||||||
gm-%:
|
gm-%: is-vscode
|
||||||
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
|
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
|
||||||
@echo "Account $* is now a GM. /camp to have it go into effect."
|
@echo "Account $* is now a GM. /camp to have it go into effect."
|
||||||
|
|
||||||
depends:
|
depends: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
sudo apt install graphviz pip time
|
sudo apt install graphviz pip time
|
||||||
pip3 install graphviz
|
pip3 install graphviz
|
||||||
mkdir -p build/depends
|
mkdir -p build/depends
|
||||||
@ -241,44 +175,54 @@ endif
|
|||||||
@echo "Common..."
|
@echo "Common..."
|
||||||
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
|
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
|
||||||
|
|
||||||
backup:
|
backup: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
@mkdir -p build/bin/backup
|
@mkdir -p build/bin/backup
|
||||||
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
|
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
|
||||||
|
|
||||||
cpu-zone:
|
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
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||||
@make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
|
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||||
exit
|
exit
|
||||||
endif
|
endif
|
||||||
@cd build/bin && mkdir -p tmp
|
@cd build/bin && mkdir -p tmp
|
||||||
cd build/bin && CPUPROFILE=prof.out ./zone
|
cd build/bin && CPUPROFILE=prof.out ./zone
|
||||||
|
|
||||||
pprof-zone:
|
pprof-zone: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||||
@make -C ../ -f .devcontainer/Makefile pprof-zone --no-print-directory
|
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||||
exit
|
exit
|
||||||
endif
|
endif
|
||||||
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
|
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
|
||||||
pprof-web-zone:
|
|
||||||
|
pprof-gv-zone: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||||
@make -C ../ -f .devcontainer/Makefile pprof-web-zone --no-print-directory
|
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||||
exit
|
|
||||||
endif
|
|
||||||
cd build/bin && google-pprof --web zone prof.out
|
|
||||||
pprof-gv-zone:
|
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
|
||||||
@make -C ../ -f .devcontainer/Makefile pprof-gv-zone --no-print-directory
|
|
||||||
exit
|
exit
|
||||||
endif
|
endif
|
||||||
cd build/bin && google-pprof --gv zone prof.out > prof.gv
|
cd build/bin && google-pprof --gv zone prof.out > prof.gv
|
||||||
heap-zone:
|
|
||||||
|
heap-zone: is-vscode
|
||||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||||
@make -C ../ -f .devcontainer/Makefile heap-zone --no-print-directory
|
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||||
exit
|
exit
|
||||||
endif
|
endif
|
||||||
@cd build/bin && mkdir -p tmp
|
@cd build/bin && mkdir -p tmp
|
||||||
cd build/bin && HEAPPROFILE=prof.out ./zone
|
cd build/bin && HEAPPROFILE=prof.out ./zone
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: pull
|
||||||
|
pull:
|
||||||
|
git pull
|
||||||
|
@if [ ! -d "quests" ]; then git clone https://github.com/rebuildeq/quests.git quests; fi
|
||||||
|
cd quests && git pull
|
||||||
|
@if [ ! -d "eqemu-definitions" ]; then git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi
|
||||||
|
cd eqemu-definitions && git pull
|
||||||
@ -40,10 +40,41 @@
|
|||||||
"GitHub.copilot",
|
"GitHub.copilot",
|
||||||
"xackery.make-magic",
|
"xackery.make-magic",
|
||||||
"Gruntfuggly.todo-tree",
|
"Gruntfuggly.todo-tree",
|
||||||
"ms-vscode.cmake-tools"
|
"ms-vscode.cmake-tools",
|
||||||
]
|
"sumneko.lua"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"Lua.runtime.version": "Lua 5.1",
|
||||||
|
"Lua.workspace.library": [
|
||||||
|
"/src/repo/eqemu-definitions"
|
||||||
|
],
|
||||||
|
"Lua.diagnostics.disable": [
|
||||||
|
"lowercase-global"
|
||||||
|
],
|
||||||
|
"cmake.statusbar.advanced": {
|
||||||
|
"kit": {
|
||||||
|
"visibility": "hidden"
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"visibility": "hidden"
|
||||||
|
},
|
||||||
|
"buildTarget": {
|
||||||
|
"visibility": "compact"
|
||||||
|
},
|
||||||
|
"launch": {
|
||||||
|
"visibility": "hidden"
|
||||||
|
},
|
||||||
|
"ctest": {
|
||||||
|
"visibility": "icon"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mounts": [
|
||||||
|
"source=${localWorkspaceFolder}/.devcontainer/Makefile,target=/src/Makefile,type=bind,consistency=cached"
|
||||||
|
],
|
||||||
|
|
||||||
"workspaceFolder": "/src",
|
"workspaceFolder": "/src",
|
||||||
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
|
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
|
||||||
}
|
}
|
||||||
98
.drone.yml
98
.drone.yml
@ -1,98 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: Build Linux
|
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
|
||||||
concurrency:
|
|
||||||
limit: 1
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
host:
|
|
||||||
path: /var/lib/cache-release
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Build Linux X64
|
|
||||||
image: akkadius/eqemu-server:v14
|
|
||||||
environment:
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
|
||||||
RCLONE_FTP_HOST: drone.akkadius.com
|
|
||||||
RCLONE_FTP_USER: artifacts
|
|
||||||
RCLONE_FTP_PASS:
|
|
||||||
from_secret: RCLONE_FTP_PASS
|
|
||||||
commands:
|
|
||||||
- ./utils/scripts/build/linux-build.sh
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
path: /home/eqemu/.ccache/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
kind: pipeline
|
|
||||||
type: exec
|
|
||||||
name: Build Windows
|
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
|
||||||
concurrency:
|
|
||||||
limit: 1
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: windows
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Build Windows X64
|
|
||||||
environment:
|
|
||||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
|
||||||
RCLONE_FTP_HOST: drone.akkadius.com
|
|
||||||
RCLONE_FTP_USER: artifacts
|
|
||||||
RCLONE_FTP_PASS:
|
|
||||||
from_secret: RCLONE_FTP_PASS
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
commands:
|
|
||||||
- .\utils\scripts\build\windows-build.ps1
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: Publish Artifacts to Github
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Upload Artifacts
|
|
||||||
image: akkadius/eqemu-build-releaser:v3
|
|
||||||
environment:
|
|
||||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
|
||||||
RCLONE_FTP_HOST: drone.akkadius.com
|
|
||||||
RCLONE_FTP_USER: artifacts
|
|
||||||
RCLONE_FTP_PASS:
|
|
||||||
from_secret: RCLONE_FTP_PASS
|
|
||||||
GH_RELEASE_GITHUB_API_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
commands:
|
|
||||||
- ./utils/scripts/build/should-release/should-release
|
|
||||||
- rclone config create remote ftp env_auth true > /dev/null
|
|
||||||
- |
|
|
||||||
rclone copy remote: --include "eqemu-server*.zip" .
|
|
||||||
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
|
|
||||||
- |
|
|
||||||
rclone delete remote: --include "eqemu-server*.zip"
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- Build Windows
|
|
||||||
- Build Linux
|
|
||||||
|
|
||||||
|
|
||||||
81
.github/workflows/build.yaml
vendored
Normal file
81
.github/workflows/build.yaml
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
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 uuid-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
|
||||||
18
.gitmodules
vendored
18
.gitmodules
vendored
@ -1,18 +1,6 @@
|
|||||||
[submodule "submodules/glm"]
|
|
||||||
path = submodules/glm
|
|
||||||
url = https://github.com/g-truc/glm.git
|
|
||||||
[submodule "submodules/fmt"]
|
|
||||||
path = submodules/fmt
|
|
||||||
url = https://github.com/fmtlib/fmt.git
|
|
||||||
[submodule "submodules/libuv"]
|
|
||||||
path = submodules/libuv
|
|
||||||
url = https://github.com/libuv/libuv.git
|
|
||||||
[submodule "submodules/cereal"]
|
|
||||||
path = submodules/cereal
|
|
||||||
url = https://github.com/USCiLab/cereal.git
|
|
||||||
[submodule "submodules/websocketpp"]
|
[submodule "submodules/websocketpp"]
|
||||||
path = submodules/websocketpp
|
path = submodules/websocketpp
|
||||||
url = https://github.com/zaphoyd/websocketpp.git
|
url = https://github.com/zaphoyd/websocketpp.git
|
||||||
[submodule "submodules/recastnavigation"]
|
[submodule "submodules/vcpkg"]
|
||||||
path = submodules/recastnavigation
|
path = submodules/vcpkg
|
||||||
url = https://github.com/EQEmu/recastnavigation.git
|
url = https://github.com/microsoft/vcpkg.git
|
||||||
|
|||||||
25
.vscode/settings.json
vendored
25
.vscode/settings.json
vendored
@ -21,14 +21,6 @@
|
|||||||
"${workspaceFolder}/dependencies/zlibng"
|
"${workspaceFolder}/dependencies/zlibng"
|
||||||
],
|
],
|
||||||
"telemetry.enableTelemetry": false,
|
"telemetry.enableTelemetry": false,
|
||||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
|
||||||
"cmake.configureArgs": [
|
|
||||||
"-DEQEMU_BUILD_LOGIN=ON",
|
|
||||||
"-DEQEMU_BUILD_TESTS=ON",
|
|
||||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
|
|
||||||
"-DEQEMU_ADD_PROFILER=ON",
|
|
||||||
"Ninja"
|
|
||||||
],
|
|
||||||
"cmake.skipConfigureIfCachePresent": true,
|
"cmake.skipConfigureIfCachePresent": true,
|
||||||
"cmake.configureOnOpen": false,
|
"cmake.configureOnOpen": false,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
@ -115,22 +107,5 @@
|
|||||||
"format": "cpp",
|
"format": "cpp",
|
||||||
"ranges": "cpp",
|
"ranges": "cpp",
|
||||||
"span": "cpp"
|
"span": "cpp"
|
||||||
},
|
|
||||||
"cmake.statusbar.advanced": {
|
|
||||||
"kit": {
|
|
||||||
"visibility": "hidden",
|
|
||||||
},
|
|
||||||
"debug": {
|
|
||||||
"visibility": "hidden",
|
|
||||||
},
|
|
||||||
"buildTarget": {
|
|
||||||
"visibility": "hidden",
|
|
||||||
},
|
|
||||||
"launch": {
|
|
||||||
"visibility": "hidden",
|
|
||||||
},
|
|
||||||
"ctest": {
|
|
||||||
"visibility": "icon",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
21
BUILD.md
21
BUILD.md
@ -4,46 +4,35 @@ This guide is far from exhaustive, you should expect to have some experience wit
|
|||||||
|
|
||||||
### CMake
|
### CMake
|
||||||
|
|
||||||
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source.
|
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.20 or higher to build from source.
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
The following libraries are required to build from source:
|
The following libraries are required to build from source:
|
||||||
- [boost](https://www.boost.org/ "boost")
|
- uuid (unix)
|
||||||
- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead)
|
|
||||||
- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb")
|
|
||||||
|
|
||||||
The following libraries are not strictly required but in many cased recommended.
|
The following libraries are not strictly required but in many cased recommended.
|
||||||
- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client)
|
|
||||||
- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver)
|
|
||||||
- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting)
|
|
||||||
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
|
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
|
||||||
|
|
||||||
##### Windows
|
##### Windows
|
||||||
For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies.
|
|
||||||
|
|
||||||
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
|
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
|
||||||
|
|
||||||
You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake.
|
|
||||||
|
|
||||||
##### Linux
|
##### Linux
|
||||||
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
|
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
|
||||||
|
|
||||||
sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev
|
sudo apt-get install libperl-dev uuid-dev
|
||||||
|
|
||||||
### Running CMake
|
### Running CMake
|
||||||
|
|
||||||
##### Windows
|
##### Windows
|
||||||
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
|
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
|
||||||
|
|
||||||
Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg.
|
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
|
cmake -G "Visual Studio 15 2022 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
||||||
|
|
||||||
##### Linux
|
##### Linux
|
||||||
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
Similarly to Windows running CMake on Linux is simple it just uses a different generator.
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
|||||||
280
CHANGELOG.md
280
CHANGELOG.md
@ -1,3 +1,283 @@
|
|||||||
|
## [23.10.3] 9/16/2025
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Hotfix crashes occurring in #4987. @Akkadius 2025-09-17
|
||||||
|
|
||||||
|
## [23.10.2] 9/16/2025
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Revert #4996 as it was causing critical issues with spells that needs to be further investigated. @Akkadius 2025-09-17
|
||||||
|
|
||||||
|
## [23.10.1] 9/16/2025
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
* Fixed Mail Key Bug ([#5015](https://github.com/EQEmu/Server/pull/5015)) @Kinglykrab 2025-09-16
|
||||||
|
|
||||||
|
## [23.10.0] 9/15/2025
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Add #npcedit npc_tint_id Help Message ([#4982](https://github.com/EQEmu/Server/pull/4982)) @Kinglykrab 2025-08-17
|
||||||
|
* Cleanup #show ip_lookup Message ([#5005](https://github.com/EQEmu/Server/pull/5005)) @Kinglykrab 2025-08-30
|
||||||
|
* Fix #set race 0 Message ([#5004](https://github.com/EQEmu/Server/pull/5004)) @Kinglykrab 2025-08-30
|
||||||
|
* Fix Issues with Strings::Commify and Mob::SendStatsWindow ([#4984](https://github.com/EQEmu/Server/pull/4984)) @Kinglykrab 2025-08-17
|
||||||
|
* Remove Attributions ([#4988](https://github.com/EQEmu/Server/pull/4988)) @KimLS 2025-08-16
|
||||||
|
* Remove Unused errorname Variable ([#5001](https://github.com/EQEmu/Server/pull/5001)) @Kinglykrab 2025-08-29
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #find account Subcommand ([#4981](https://github.com/EQEmu/Server/pull/4981)) @Kinglykrab 2025-08-17
|
||||||
|
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
|
||||||
|
* Add #task complete Saylink to #task show ([#4985](https://github.com/EQEmu/Server/pull/4985)) @Kinglykrab 2025-08-17
|
||||||
|
|
||||||
|
### Constants
|
||||||
|
|
||||||
|
* Change Race Changes to Race Namespace ([#5000](https://github.com/EQEmu/Server/pull/5000)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert SE Defines to SpellEffect Namespace ([#4999](https://github.com/EQEmu/Server/pull/4999)) @Kinglykrab 2025-08-30
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Add `heal_amount` to `character_stats_record` ([#4986](https://github.com/EQEmu/Server/pull/4986)) @Kinglykrab 2025-08-17
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix #show recipe uint16 Cap ([#4978](https://github.com/EQEmu/Server/pull/4978)) @Kinglykrab 2025-08-11
|
||||||
|
* Fix Race 474 for Titanium ([#4979](https://github.com/EQEmu/Server/pull/4979)) @regneq 2025-08-11
|
||||||
|
* Fix Recipe Inspect Bug ([#4994](https://github.com/EQEmu/Server/pull/4994)) @Kinglykrab 2025-08-30
|
||||||
|
* Fix Several Evolving Item Bugs ([#4992](https://github.com/EQEmu/Server/pull/4992)) @neckkola 2025-09-08
|
||||||
|
* Fix Task Reloading ([#5002](https://github.com/EQEmu/Server/pull/5002)) @Kinglykrab 2025-08-29
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
|
||||||
|
|
||||||
|
### Pets
|
||||||
|
|
||||||
|
* Add Pet Constants and Methods ([#4987](https://github.com/EQEmu/Server/pull/4987)) @Kinglykrab 2025-08-17
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add EVENT_CHARM_START and EVENT_CHARM_END ([#5013](https://github.com/EQEmu/Server/pull/5013)) @Kinglykrab 2025-09-15
|
||||||
|
* Add GetKeyRing() to Perl/Lua ([#4980](https://github.com/EQEmu/Server/pull/4980)) @Kinglykrab 2025-08-17
|
||||||
|
* Add GetNPCTintIndex() to Perl/Lua ([#4983](https://github.com/EQEmu/Server/pull/4983)) @Kinglykrab 2025-08-17
|
||||||
|
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
|
||||||
|
* Add Identifiers to Get/Modify NPC Stat Methods ([#5012](https://github.com/EQEmu/Server/pull/5012)) @Kinglykrab 2025-09-15
|
||||||
|
|
||||||
|
### Repositories
|
||||||
|
|
||||||
|
* Convert Character Inspect Messages to Repositories ([#4997](https://github.com/EQEmu/Server/pull/4997)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Damage Shield Types to Repositories ([#4995](https://github.com/EQEmu/Server/pull/4995)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Item Loading to Repositories ([#4998](https://github.com/EQEmu/Server/pull/4998)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Mail Key to Repositories ([#5007](https://github.com/EQEmu/Server/pull/5007)) @Kinglykrab 2025-09-15
|
||||||
|
* Convert Shared Bank Platinum to Repositories ([#5006](https://github.com/EQEmu/Server/pull/5006)) @Kinglykrab 2025-09-02
|
||||||
|
* Convert Spell Loading to Repositories ([#4996](https://github.com/EQEmu/Server/pull/4996)) @Kinglykrab 2025-08-30
|
||||||
|
* Convert Total Time Played to Repositories ([#5008](https://github.com/EQEmu/Server/pull/5008)) @Kinglykrab 2025-09-15
|
||||||
|
|
||||||
|
## [23.9.1] 8/2/2025
|
||||||
|
|
||||||
|
### Hotfix
|
||||||
|
|
||||||
|
* Fix Quest Ownership Edge Case ([#4977](https://github.com/EQEmu/Server/pull/4977)) @Kinglykrab 2025-08-02
|
||||||
|
|
||||||
|
## [23.9.0] 8/2/2025
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Fix FinishBuffing rule ([#4961](https://github.com/EQEmu/Server/pull/4961)) @nytmyr 2025-07-01
|
||||||
|
* Fix ^cast resurrects ([#4958](https://github.com/EQEmu/Server/pull/4958)) @nytmyr 2025-06-29
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
|
||||||
|
* More Build Speed Improvements ([#4959](https://github.com/EQEmu/Server/pull/4959)) @Akkadius 2025-06-30
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Add Indexes to NPC's Spawns Loot ([#4972](https://github.com/EQEmu/Server/pull/4972)) @Akkadius 2025-07-30
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Zone Scripting ([#4908](https://github.com/EQEmu/Server/pull/4908)) @Kinglykrab 2025-07-10
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add a missing Froglok starting area for Titanium Startzone. ([#4962](https://github.com/EQEmu/Server/pull/4962)) @regneq 2025-07-04
|
||||||
|
* Fix Hero's Forge Ingame and Character Select ([#4966](https://github.com/EQEmu/Server/pull/4966)) @Kinglykrab 2025-07-30
|
||||||
|
* Show player count on the server list status. ([#4971](https://github.com/EQEmu/Server/pull/4971)) @regneq 2025-07-30
|
||||||
|
|
||||||
|
### Loginserver
|
||||||
|
|
||||||
|
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Clear Wearchange Deduplication Cache ([#4960](https://github.com/EQEmu/Server/pull/4960)) @Akkadius 2025-06-30
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add GetMemberRole() to Perl/Lua ([#4963](https://github.com/EQEmu/Server/pull/4963)) @Barathos 2025-07-10
|
||||||
|
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
|
||||||
|
|
||||||
|
## [23.8.1] 6/28/2025
|
||||||
|
|
||||||
|
### Crash Fix
|
||||||
|
|
||||||
|
* Fix Possible Crashes with Raid Methods ([#4955](https://github.com/EQEmu/Server/pull/4955)) @Kinglykrab 2025-06-26
|
||||||
|
|
||||||
|
### Databuckets
|
||||||
|
|
||||||
|
* Revert Caching Changes of #4917 ([#4957](https://github.com/EQEmu/Server/pull/4957)) @Akkadius 2025-06-28
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Fix FindCharacter Using content_db ([#4956](https://github.com/EQEmu/Server/pull/4956)) @Kinglykrab 2025-06-26
|
||||||
|
* Fix Hero Forge on Character Select ([#4954](https://github.com/EQEmu/Server/pull/4954)) @Kinglykrab 2025-06-26
|
||||||
|
|
||||||
|
## [23.8.0] 6/25/2025
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
* Add wwmarquee <type> <message> ([#4919](https://github.com/EQEmu/Server/pull/4919)) @Akkadius 2025-06-23
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
* Significantly Improve Build Times Using Unity Builds ([#4948](https://github.com/EQEmu/Server/pull/4948)) @Akkadius 2025-06-22
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* AdventureManager Global to Singleton Cleanup ([#4931](https://github.com/EQEmu/Server/pull/4931)) @Kinglykrab 2025-06-25
|
||||||
|
* Cleanup Strings Header ([#4950](https://github.com/EQEmu/Server/pull/4950)) @Akkadius 2025-06-22
|
||||||
|
* ClientList Global to Singleton Cleanup ([#4942](https://github.com/EQEmu/Server/pull/4942)) @Kinglykrab 2025-06-25
|
||||||
|
* DatabaseUpdate Global to Singleton Cleanup ([#4943](https://github.com/EQEmu/Server/pull/4943)) @Kinglykrab 2025-06-25
|
||||||
|
* DiscordManager Global to Singleton Cleanup ([#4926](https://github.com/EQEmu/Server/pull/4926)) @Kinglykrab 2025-06-25
|
||||||
|
* EQ::Random Global to Singleton Cleanup ([#4936](https://github.com/EQEmu/Server/pull/4936)) @Kinglykrab 2025-06-22
|
||||||
|
* EQEmuLogSys Global to Singleton Cleanup ([#4925](https://github.com/EQEmu/Server/pull/4925)) @Akkadius 2025-06-25
|
||||||
|
* EvolvingItemsManager Global to Singleton Cleanup ([#4929](https://github.com/EQEmu/Server/pull/4929)) @Kinglykrab 2025-06-25
|
||||||
|
* LFGuildManager Global to Singleton Cleanup ([#4927](https://github.com/EQEmu/Server/pull/4927)) @Kinglykrab 2025-06-25
|
||||||
|
* LoginServerList Global to Singleton Cleanup ([#4941](https://github.com/EQEmu/Server/pull/4941)) @Kinglykrab 2025-06-25
|
||||||
|
* Optimize PCH Config (Faster Builds) ([#4951](https://github.com/EQEmu/Server/pull/4951)) @Akkadius 2025-06-22
|
||||||
|
* PCH Cleanup ([#4952](https://github.com/EQEmu/Server/pull/4952)) @Akkadius 2025-06-25
|
||||||
|
* PathManager Global to Singleton Cleanup ([#4924](https://github.com/EQEmu/Server/pull/4924)) @Akkadius 2025-06-22
|
||||||
|
* PetitionList Global to Singleton Cleanup ([#4944](https://github.com/EQEmu/Server/pull/4944)) @Kinglykrab 2025-06-25
|
||||||
|
* PlayerEventLogs Global to Singleton Cleanup ([#4928](https://github.com/EQEmu/Server/pull/4928)) @Kinglykrab 2025-06-25
|
||||||
|
* QueryServConnection Global to Singleton Cleanup ([#4938](https://github.com/EQEmu/Server/pull/4938)) @Kinglykrab 2025-06-25
|
||||||
|
* Remove Lua Rule Constants ([#4949](https://github.com/EQEmu/Server/pull/4949)) @Akkadius 2025-06-22
|
||||||
|
* Remove Regex Compile Bloat ([#4947](https://github.com/EQEmu/Server/pull/4947)) @Akkadius 2025-06-22
|
||||||
|
* Remove Unused MZoneShutdown Mutex ([#4946](https://github.com/EQEmu/Server/pull/4946)) @Kinglykrab 2025-06-22
|
||||||
|
* SharedTaskManager Global to Singleton Cleanup ([#4930](https://github.com/EQEmu/Server/pull/4930)) @Kinglykrab 2025-06-25
|
||||||
|
* SkillCaps Global to Singleton Cleanup ([#4933](https://github.com/EQEmu/Server/pull/4933)) @Kinglykrab 2025-06-22
|
||||||
|
* TaskManager Global to Singleton Cleanup ([#4945](https://github.com/EQEmu/Server/pull/4945)) @Kinglykrab 2025-06-22
|
||||||
|
* UCSConnection Global to Singleton Cleanup ([#4937](https://github.com/EQEmu/Server/pull/4937)) @Kinglykrab 2025-06-25
|
||||||
|
* WebInterfaceList Global to Singleton Cleanup ([#4935](https://github.com/EQEmu/Server/pull/4935)) @Kinglykrab 2025-06-25
|
||||||
|
* WorldContentServer Global to Singleton Cleanup ([#4939](https://github.com/EQEmu/Server/pull/4939)) @Kinglykrab 2025-06-25
|
||||||
|
* WorldEventScheduler and ZoneEventScheduler Global to Singleton Cleanup ([#4932](https://github.com/EQEmu/Server/pull/4932)) @Kinglykrab 2025-06-25
|
||||||
|
* ZSList Global to Singleton Cleanup ([#4940](https://github.com/EQEmu/Server/pull/4940)) @Kinglykrab 2025-06-25
|
||||||
|
* ZoneStore Global to Singleton Cleanup ([#4934](https://github.com/EQEmu/Server/pull/4934)) @Kinglykrab 2025-06-23
|
||||||
|
|
||||||
|
### Corpses
|
||||||
|
|
||||||
|
* Add corpse entity variables to DB ([#4911](https://github.com/EQEmu/Server/pull/4911)) @fryguy503 2025-06-25
|
||||||
|
|
||||||
|
### Databuckets
|
||||||
|
|
||||||
|
* Move Databuckets to Common ([#4918](https://github.com/EQEmu/Server/pull/4918)) @Akkadius 2025-06-16
|
||||||
|
* Nested Caching ([#4917](https://github.com/EQEmu/Server/pull/4917)) @Akkadius 2025-06-25
|
||||||
|
|
||||||
|
### Doors
|
||||||
|
|
||||||
|
* Fix door saving for versions ([#4905](https://github.com/EQEmu/Server/pull/4905)) @nytmyr 2025-06-09
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Bulk Send Corpses after Idle State ([#4910](https://github.com/EQEmu/Server/pull/4910)) @Akkadius 2025-06-09
|
||||||
|
* Fix ClientList Singleton Shortcomings of #4942 @Akkadius 2025-06-25
|
||||||
|
* Fix breaking changes to Titanium, SoF, SoD patches causes by big bags update ([#4922](https://github.com/EQEmu/Server/pull/4922)) @regneq 2025-06-25
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
* Fix output for tasks in logs ([#4907](https://github.com/EQEmu/Server/pull/4907)) @joligario 2025-06-09
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
|
||||||
|
* Auto Idle / AFK ([#4903](https://github.com/EQEmu/Server/pull/4903)) @Akkadius 2025-05-22
|
||||||
|
* Wearchange Packet Send Deduplication ([#4916](https://github.com/EQEmu/Server/pull/4916)) @Akkadius 2025-06-25
|
||||||
|
|
||||||
|
### Player Event Logs
|
||||||
|
|
||||||
|
* Don't Clear Event Data on ETL Events ([#4913](https://github.com/EQEmu/Server/pull/4913)) @Akkadius 2025-06-25
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Don't Write Empty Data ([#4912](https://github.com/EQEmu/Server/pull/4912)) @Akkadius 2025-06-25
|
||||||
|
* Zone Fetch Settings from QS if Enabled ([#4915](https://github.com/EQEmu/Server/pull/4915)) @Akkadius 2025-06-25
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add CompleteTask and UncompleteTask methods to Perl/Lua ([#4921](https://github.com/EQEmu/Server/pull/4921)) @Barathos 2025-06-25
|
||||||
|
* Lua Client Scoped EnableTitleSets ([#4914](https://github.com/EQEmu/Server/pull/4914)) @fryguy503 2025-06-25
|
||||||
|
|
||||||
|
### Quests
|
||||||
|
|
||||||
|
* Support Multiple Quest, Plugin, and Lua Module Paths ([#4906](https://github.com/EQEmu/Server/pull/4906)) @Akkadius 2025-06-09
|
||||||
|
|
||||||
|
### World API
|
||||||
|
|
||||||
|
* Input Validation ([#4904](https://github.com/EQEmu/Server/pull/4904)) @Akkadius 2025-05-22
|
||||||
|
|
||||||
|
## [23.7.0] 5/19/2025
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
* Add custom database version output ([#4901](https://github.com/EQEmu/Server/pull/4901)) @joligario 2025-05-18
|
||||||
|
* Fix MySQL check in database dumper ([#4897](https://github.com/EQEmu/Server/pull/4897)) @joligario 2025-05-16
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #zonevariable Command ([#4882](https://github.com/EQEmu/Server/pull/4882)) @Kinglykrab 2025-05-15
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Add Custom Database Migrations for Operators ([#4892](https://github.com/EQEmu/Server/pull/4892)) @Akkadius 2025-05-16
|
||||||
|
* Remove Transaction Wrapped Character Save ([#4894](https://github.com/EQEmu/Server/pull/4894)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Deadlock on failed #copycharacter commands ([#4887](https://github.com/EQEmu/Server/pull/4887)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
* Auto Update Log Category Names ([#4890](https://github.com/EQEmu/Server/pull/4890)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
|
### Netcode
|
||||||
|
|
||||||
|
* Resend Logic Adjustments ([#4900](https://github.com/EQEmu/Server/pull/4900)) @Akkadius 2025-05-18
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Add rule to ignore configured GM commands ([#4888](https://github.com/EQEmu/Server/pull/4888)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Auto Update Rule Notes from Source ([#4891](https://github.com/EQEmu/Server/pull/4891)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
|
### World
|
||||||
|
|
||||||
|
* Fix Rarer Reload Deadlock ([#4893](https://github.com/EQEmu/Server/pull/4893)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
|
### Zone State
|
||||||
|
|
||||||
|
* Load New Spawn2 Data When Present ([#4889](https://github.com/EQEmu/Server/pull/4889)) @Akkadius 2025-05-16
|
||||||
|
|
||||||
## [23.6.0] 5/14/2025
|
## [23.6.0] 5/14/2025
|
||||||
|
|
||||||
### Bots
|
### Bots
|
||||||
|
|||||||
605
CMakeLists.txt
605
CMakeLists.txt
@ -1,487 +1,180 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
IF(POLICY CMP0074)
|
if(NOT CMAKE_TOOLCHAIN_FILE)
|
||||||
CMAKE_POLICY(SET CMP0074 NEW)
|
if(DEFINED ENV{VCPKG_ROOT})
|
||||||
ENDIF()
|
message(STATUS "Using vcpkg from VCPKG_ROOT")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE
|
||||||
|
"$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
|
||||||
|
CACHE FILEPATH "Vcpkg toolchain file"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS "Using vcpkg submodule")
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/submodules/vcpkg/scripts/buildsystems/vcpkg.cmake"
|
||||||
|
CACHE FILEPATH "Vcpkg toolchain file"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
PROJECT(EQEmu)
|
project(EQEmu
|
||||||
|
VERSION 24.10.3
|
||||||
|
LANGUAGES CXX
|
||||||
|
)
|
||||||
|
|
||||||
IF(NOT CMAKE_BUILD_TYPE)
|
#explicitly set CMP0167 for Find Boost
|
||||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
if(POLICY CMP0167)
|
||||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
cmake_policy(SET CMP0167 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
SET(CMAKE_CXX_STANDARD 20)
|
if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Build type")
|
||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
endif()
|
||||||
|
|
||||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
OPTION(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
IF (EQEMU_BUILD_STATIC)
|
option(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON)
|
||||||
SET(BUILD_SHARED_LIBS OFF)
|
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
|
||||||
MESSAGE(STATUS "Building with static linking")
|
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
|
||||||
IF (UNIX)
|
|
||||||
SET(PERL_LIBRARY "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/libperl.so")
|
|
||||||
SET(PERL_INCLUDE_PATH "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/")
|
|
||||||
SET(PERL_EXECUTABLE "/opt/eqemu-perl/bin/perl")
|
|
||||||
ENDIF ()
|
|
||||||
ENDIF (EQEMU_BUILD_STATIC)
|
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
add_compile_options(/bigobj)
|
||||||
|
add_compile_definitions(_CRT_SECURE_NO_WARNINGS NOMINMAX CRASH_LOGGING _HAS_AUTO_PTR_ETC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
|
|
||||||
# Requires libgoogle-perftools-dev google-perftools packages for linux (debian)
|
option(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
||||||
IF(EQEMU_ADD_PROFILER)
|
if(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-as-needed,-lprofiler,--as-needed")
|
add_compile_options(/W0 /wd4005 /wd4996 /nologo /Os)
|
||||||
ENDIF(EQEMU_ADD_PROFILER)
|
endif()
|
||||||
|
else()
|
||||||
IF(USE_MAP_MMFS)
|
add_compile_definitions(HAS_UNION_SEMUN)
|
||||||
ADD_DEFINITIONS(-DUSE_MAP_MMFS)
|
endif()
|
||||||
ENDIF (USE_MAP_MMFS)
|
|
||||||
|
|
||||||
IF(MSVC)
|
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
|
||||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
|
||||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
|
||||||
|
|
||||||
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
|
||||||
IF(EQEMU_DISABLE_MSVC_WARNINGS)
|
|
||||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
|
||||||
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
|
|
||||||
ELSE(MSVC)
|
|
||||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
|
||||||
ENDIF(MSVC)
|
|
||||||
|
|
||||||
#FreeBSD support
|
#FreeBSD support
|
||||||
IF(UNIX)
|
if(UNIX)
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||||
ADD_DEFINITIONS(-DFREEBSD)
|
add_compile_definitions(FREEBSD)
|
||||||
ADD_DEFINITIONS(-D_GLIBCXX_USE_C99)
|
add_compile_definitions(_GLIBCXX_USE_C99)
|
||||||
SET(FREEBSD TRUE)
|
set(FREEBSD TRUE)
|
||||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
endif()
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
ADD_DEFINITIONS(-DDARWIN)
|
add_compile_definitions(DARWIN)
|
||||||
SET(DARWIN TRUE)
|
set(DARWIN TRUE)
|
||||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
endif()
|
||||||
ENDIF(UNIX)
|
endif()
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
find_package(Boost REQUIRED COMPONENTS dynamic_bitset foreach tuple)
|
||||||
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
find_package(cereal CONFIG REQUIRED)
|
||||||
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
find_package(fmt CONFIG REQUIRED)
|
||||||
|
find_package(glm CONFIG REQUIRED)
|
||||||
|
find_package(unofficial-libmariadb CONFIG REQUIRED)
|
||||||
|
find_package(libuv CONFIG REQUIRED)
|
||||||
|
find_package(OpenSSL REQUIRED)
|
||||||
|
find_package(recastnavigation CONFIG REQUIRED)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
find_package(LuaJit REQUIRED)
|
||||||
|
find_package(unofficial-sodium CONFIG REQUIRED)
|
||||||
|
find_package(PerlLibs)
|
||||||
|
|
||||||
#MSVC can fetch dependencies automatically.
|
message(STATUS "**************************************************")
|
||||||
IF(MSVC)
|
message(STATUS "* Library Detection *")
|
||||||
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
|
message(STATUS "**************************************************")
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#Find everything we need
|
if(MARIADB_FOUND)
|
||||||
FIND_PACKAGE(Boost REQUIRED)
|
message(STATUS "* MariaDB: FOUND *")
|
||||||
FIND_PACKAGE(MySQL)
|
else()
|
||||||
FIND_PACKAGE(MariaDB)
|
message(STATUS "* MariaDB: MISSING *")
|
||||||
FIND_PACKAGE(ZLIB)
|
endif()
|
||||||
FIND_PACKAGE(OpenSSL)
|
|
||||||
FIND_PACKAGE(Lua51)
|
|
||||||
FIND_PACKAGE(LuaJit)
|
|
||||||
FIND_PACKAGE(PerlLibs)
|
|
||||||
FIND_PACKAGE(Sodium)
|
|
||||||
FIND_PACKAGE(mbedTLS)
|
|
||||||
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
if(ZLIB_FOUND)
|
||||||
MESSAGE(STATUS "* Library Detection *")
|
message(STATUS "* ZLIB: FOUND *")
|
||||||
MESSAGE(STATUS "**************************************************")
|
else()
|
||||||
|
message(STATUS "* ZLIB: MISSING *")
|
||||||
|
endif()
|
||||||
|
|
||||||
IF(MYSQL_FOUND)
|
if(LuaJit_FOUND)
|
||||||
MESSAGE(STATUS "* MySQL: FOUND *")
|
message(STATUS "* LuaJIT: FOUND *")
|
||||||
ELSE()
|
else()
|
||||||
MESSAGE(STATUS "* MySQL: MISSING *")
|
message(STATUS "* LuaJIT: MISSING *")
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
IF(MARIADB_FOUND)
|
if(PerlLibs_FOUND)
|
||||||
MESSAGE(STATUS "* MariaDB: FOUND *")
|
message(STATUS "* Perl: FOUND *")
|
||||||
ELSE()
|
else()
|
||||||
MESSAGE(STATUS "* MariaDB: MISSING *")
|
message(STATUS "* Perl: MISSING *")
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
IF(ZLIB_FOUND)
|
if(OpenSSL_FOUND)
|
||||||
MESSAGE(STATUS "* ZLIB: FOUND *")
|
message(STATUS "* OpenSSL: FOUND *")
|
||||||
ELSE()
|
else()
|
||||||
MESSAGE(STATUS "* ZLIB: MISSING *")
|
message(STATUS "* OpenSSL: MISSING *")
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
IF(Lua51_FOUND)
|
message(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
|
||||||
MESSAGE(STATUS "* Lua: FOUND *")
|
message(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
|
||||||
ELSE()
|
message(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
|
||||||
MESSAGE(STATUS "* Lua: MISSING *")
|
message(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
|
||||||
ENDIF()
|
message(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
|
||||||
|
message(STATUS "PERL_VERSION: ${PERL_VERSION}")
|
||||||
IF(LuaJit_FOUND)
|
message(STATUS "**************************************************")
|
||||||
MESSAGE(STATUS "* LuaJIT: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* LuaJIT: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(PerlLibs_FOUND)
|
|
||||||
MESSAGE(STATUS "* Perl: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* Perl: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(SODIUM_FOUND)
|
|
||||||
MESSAGE(STATUS "* libsodium: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* libsodium: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(OpenSSL_FOUND)
|
|
||||||
MESSAGE(STATUS "* OpenSSL: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* OpenSSL: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(MBEDTLS_FOUND)
|
|
||||||
MESSAGE(STATUS "* mbedTLS: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
|
|
||||||
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
|
|
||||||
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
|
|
||||||
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
|
|
||||||
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
|
|
||||||
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
|
|
||||||
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
|
|
||||||
#options
|
#options
|
||||||
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
|
option(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
option(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
||||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
option(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||||
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
option(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
|
||||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
|
||||||
OPTION(EQEMU_PREFER_LUA "Build with normal Lua even if LuaJIT is found." OFF)
|
|
||||||
|
|
||||||
#PRNG options
|
if(PerlLibs_FOUND)
|
||||||
OPTION(EQEMU_ADDITIVE_LFIB_PRNG "Use Additive LFib for PRNG." OFF)
|
option(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||||
MARK_AS_ADVANCED(EQEMU_ADDITIVE_LFIB_PRNG)
|
|
||||||
OPTION(EQEMU_BIASED_INT_DIST "Use biased int dist instead of uniform." OFF)
|
|
||||||
MARK_AS_ADVANCED(EQEMU_BIASED_INT_DIST)
|
|
||||||
SET(EQEMU_CUSTOM_PRNG_ENGINE "" CACHE STRING "Custom random engine. (ex. std::default_random_engine)")
|
|
||||||
MARK_AS_ADVANCED(EQEMU_CUSTOM_PRNG_ENGINE)
|
|
||||||
|
|
||||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
if(EQEMU_BUILD_PERL)
|
||||||
OPTION(EQEMU_SFMT19937 "Use GCC's extention for SIMD Fast MT19937." OFF)
|
set(PERL_LIBRARY_TYPE " Perl")
|
||||||
MARK_AS_ADVANCED(EQEMU_SFMT19937)
|
else()
|
||||||
ENDIF()
|
set(PERL_LIBRARY_TYPE " Missing")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(PERL_LIBRARY_TYPE "Disabled")
|
||||||
|
endif()
|
||||||
|
|
||||||
IF(EQEMU_ADDITIVE_LFIB_PRNG)
|
message(STATUS "")
|
||||||
ADD_DEFINITIONS(-DUSE_ADDITIVE_LFIB_PRNG)
|
message(STATUS "**************************************************")
|
||||||
IF(EQEMU_SFMT19937)
|
message(STATUS "* Library Usage *")
|
||||||
MESSAGE(STATUS "SFMT19937 and ADDITITVE_LFIB_PRNG both set, SFMT19937 ignored.")
|
message(STATUS "**************************************************")
|
||||||
SET(EQEMU_SFMT19937 OFF)
|
message(STATUS "* Database: MariaDB *")
|
||||||
ENDIF()
|
message(STATUS "* TLS: OpenSSL *")
|
||||||
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
|
message(STATUS "* Lua: LuaJIT *")
|
||||||
MESSAGE(STATUS "CUSTOM_PRNG_ENGINE and ADDITITVE_LFIB_PRNG both set, CUSTOM_PRNG_ENGINE ignored.")
|
message(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
|
||||||
SET(EQEMU_CUSTOM_PRNG_ENGINE "")
|
message(STATUS "* zlib: ZLIB *")
|
||||||
ENDIF()
|
message(STATUS "**************************************************")
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(EQEMU_SFMT19937)
|
|
||||||
ADD_DEFINITIONS(-DUSE_SFMT19937)
|
|
||||||
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
|
|
||||||
MESSAGE(STATUS "CUSTOM_PRNG_ENGINE and SFMT19937 both set, CUSTOM_PRNG_ENGINE ignored.")
|
|
||||||
SET(EQEMU_CUSTOM_PRNG_ENGINE "")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(NOT EQEMU_CUSTOM_PRNG_ENGINE STREQUAL "")
|
option(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||||
ADD_DEFINITIONS(-DUSE_CUSTOM_PRNG_ENGINE=${EQEMU_CUSTOM_PRNG_ENGINE})
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(EQEMU_BIASED_INT_DIST)
|
if(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_CLIENT_FILES)
|
||||||
ADD_DEFINITIONS(-DBIASED_INT_DIST)
|
add_subdirectory(common)
|
||||||
ENDIF()
|
add_subdirectory(libs)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "No targets were selected to build, we must build at least one target.")
|
||||||
|
endif()
|
||||||
|
|
||||||
IF(EQEMU_COMMANDS_LOGGING)
|
if(EQEMU_BUILD_SERVER)
|
||||||
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
add_subdirectory(shared_memory)
|
||||||
ENDIF(EQEMU_COMMANDS_LOGGING)
|
add_subdirectory(world)
|
||||||
|
add_subdirectory(zone)
|
||||||
|
add_subdirectory(ucs)
|
||||||
|
add_subdirectory(queryserv)
|
||||||
|
add_subdirectory(eqlaunch)
|
||||||
|
endif()
|
||||||
|
|
||||||
#database
|
if(EQEMU_BUILD_LOGIN)
|
||||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
add_subdirectory(loginserver)
|
||||||
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
|
endif()
|
||||||
MySQL
|
|
||||||
MariaDB"
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
|
if(EQEMU_BUILD_TESTS)
|
||||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
add_subdirectory(tests)
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
endif()
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
|
||||||
ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB")
|
|
||||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB")
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(MariaDB_FOUND)
|
|
||||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
|
||||||
ELSEIF(MySQL_FOUND)
|
|
||||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#security
|
if(EQEMU_BUILD_CLIENT_FILES)
|
||||||
#prefer openssl to mbedtls (arbitrary)
|
add_subdirectory(client_files)
|
||||||
IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
|
endif()
|
||||||
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
|
|
||||||
OpenSSL
|
|
||||||
mbedTLS"
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
|
|
||||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
|
||||||
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
|
|
||||||
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
|
|
||||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS")
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(OpenSSL_FOUND)
|
|
||||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
|
||||||
IF(${OPENSSL_VERSION} VERSION_GREATER_EQUAL "1.1.1")
|
|
||||||
ADD_DEFINITIONS(-DCPPHTTPLIB_OPENSSL_SUPPORT)
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(MBEDTLS_FOUND)
|
|
||||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
|
||||||
ELSE()
|
|
||||||
SET(TLS_LIBRARY_TYPE "Disabled")
|
|
||||||
SET(TLS_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(SODIUM_FOUND)
|
|
||||||
SET(SODIUM_LIBRARY_TYPE "Libsodium")
|
|
||||||
SET(SODIUM_LIBRARY_ENABLED ON)
|
|
||||||
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
|
|
||||||
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
|
|
||||||
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
|
||||||
ELSE()
|
|
||||||
SET(SODIUM_LIBRARY_TYPE " Disabled")
|
|
||||||
SET(SODIUM_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(LUAJIT_FOUND AND NOT (EQEMU_PREFER_LUA AND Lua51_FOUND))
|
|
||||||
SET(LUA_LIBRARY_TYPE " LuaJIT")
|
|
||||||
SET(LUA_LIBRARY_ENABLED ON)
|
|
||||||
SET(LUA_LIBRARY_LIBS ${LUAJIT_LIBRARY} luabind)
|
|
||||||
SET(LUA_LIBRARY_INCLUDE ${LUAJIT_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
|
||||||
ELSEIF(Lua51_FOUND )
|
|
||||||
SET(LUA_LIBRARY_TYPE " Lua 5.1")
|
|
||||||
SET(LUA_LIBRARY_ENABLED ON)
|
|
||||||
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
|
|
||||||
SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
|
||||||
ELSE()
|
|
||||||
SET(LUA_LIBRARY_TYPE "Disabled")
|
|
||||||
SET(LUA_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(PerlLibs_FOUND)
|
|
||||||
SET(PERL_LIBRARY_TYPE " Perl")
|
|
||||||
SET(PERL_LIBRARY_ENABLED ON)
|
|
||||||
SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY})
|
|
||||||
SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH})
|
|
||||||
ELSE()
|
|
||||||
SET(PERL_LIBRARY_TYPE "Disabled")
|
|
||||||
SET(PERL_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#use zlib if exists
|
|
||||||
IF(ZLIB_FOUND)
|
|
||||||
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON)
|
|
||||||
IF(EQEMU_BUILD_ZLIB)
|
|
||||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
|
||||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
|
||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng")
|
|
||||||
ELSE()
|
|
||||||
SET(ZLIB_LIBRARY_TYPE " zlib")
|
|
||||||
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
|
|
||||||
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
|
||||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
|
||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (EQEMU_BUILD_STATIC)
|
|
||||||
SET(ZLIB_LIBRARY_LIBS libz.a)
|
|
||||||
ENDIF(EQEMU_BUILD_STATIC)
|
|
||||||
|
|
||||||
MESSAGE(STATUS "")
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
MESSAGE(STATUS "* Library Usage *")
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
|
|
||||||
#setup server libs and headers
|
|
||||||
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
|
||||||
|
|
||||||
# silence obnoxious deprecation message
|
|
||||||
ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
|
|
||||||
|
|
||||||
IF(TLS_LIBRARY_ENABLED)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(SODIUM_LIBRARY_ENABLED)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(LUA_LIBRARY_ENABLED)
|
|
||||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LUA)
|
|
||||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
|
||||||
SET(ZONE_LIBS ${LUA_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
|
|
||||||
|
|
||||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
|
||||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
|
||||||
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(PERL_LIBRARY_ENABLED)
|
|
||||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
|
||||||
IF(EQEMU_BUILD_PERL)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
|
||||||
ADD_DEFINITIONS(-DEMBPERL)
|
|
||||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
|
||||||
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
|
||||||
IF (UNIX AND EQEMU_BUILD_STATIC)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
|
|
||||||
ENDIF ()
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} "ws2_32" "psapi" "iphlpapi" "userenv")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(UNIX)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${CMAKE_DL_LIBS} "z" "m" "pthread")
|
|
||||||
IF(NOT DARWIN)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} "rt")
|
|
||||||
ENDIF()
|
|
||||||
# Freebsd provides uuids in the C library
|
|
||||||
IF(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(ZONE_LIBS ${ZONE_LIBS} ${SERVER_LIBS})
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
|
||||||
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
|
|
||||||
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
|
||||||
ADD_SUBDIRECTORY(common)
|
|
||||||
ADD_SUBDIRECTORY(libs)
|
|
||||||
ADD_SUBDIRECTORY(submodules/fmt)
|
|
||||||
ADD_SUBDIRECTORY(submodules/libuv)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_ZLIB)
|
|
||||||
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
|
|
||||||
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
|
|
||||||
ADD_SUBDIRECTORY(libs/zlibng)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
|
|
||||||
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
|
|
||||||
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
|
|
||||||
ADD_SUBDIRECTORY(submodules/recastnavigation)
|
|
||||||
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_SERVER)
|
|
||||||
ADD_SUBDIRECTORY(shared_memory)
|
|
||||||
ADD_SUBDIRECTORY(world)
|
|
||||||
ADD_SUBDIRECTORY(zone)
|
|
||||||
ADD_SUBDIRECTORY(ucs)
|
|
||||||
ADD_SUBDIRECTORY(queryserv)
|
|
||||||
ADD_SUBDIRECTORY(eqlaunch)
|
|
||||||
ENDIF(EQEMU_BUILD_SERVER)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LOGIN)
|
|
||||||
ADD_SUBDIRECTORY(loginserver)
|
|
||||||
ENDIF(EQEMU_BUILD_LOGIN)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_HC)
|
|
||||||
ADD_SUBDIRECTORY(hc)
|
|
||||||
ENDIF(EQEMU_BUILD_HC)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_TESTS)
|
|
||||||
ADD_SUBDIRECTORY(tests)
|
|
||||||
ENDIF(EQEMU_BUILD_TESTS)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_CLIENT_FILES)
|
|
||||||
ADD_SUBDIRECTORY(client_files)
|
|
||||||
ENDIF(EQEMU_BUILD_CLIENT_FILES)
|
|
||||||
|
|||||||
49
CMakePresets.json
Normal file
49
CMakePresets.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"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
179
README.md
@ -1,83 +1,150 @@
|
|||||||
# EQEmulator Core Server
|
<h1 align="center">EQEmulator Server Platform</h1>
|
||||||
| Drone (Linux x64) | Drone (Windows x64) |
|
|
||||||
|:---:|:---:|
|
<p align="center">
|
||||||
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
<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&logo=discord&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 is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++**
|
<p align="center">
|
||||||
* MySQL/MariaDB is used as the database engine (over 200+ tables)
|
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.
|
||||||
* Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events
|
</p>
|
||||||
* 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
|
|
||||||
|
|
||||||
## Server Installs
|
<p align="center">
|
||||||
| |Windows|Linux|
|
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>
|
||||||
|**Install Count**|||
|
|
||||||
### > Windows
|
|
||||||
|
|
||||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-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>
|
||||||
|
|
||||||
### > Debian/Ubuntu/CentOS/Fedora
|
<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>
|
||||||
|
|
||||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
|
***
|
||||||
|
|
||||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
<h3 align="center">
|
||||||
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
Technical Overview & Reverse Engineering Effort
|
||||||
|
</h1>
|
||||||
|
|
||||||
> 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
|
<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>
|
||||||
|
|
||||||
## Supported Clients
|
<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 ProjectEQ’s world data up through *Dragons of Norrath*
|
||||||
|
* 100% customizable to create entirely new game worlds
|
||||||
|
|
||||||
|
<h1 align="center">
|
||||||
|
🚀 Why It Matters
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p align="center">🧬 EQEmulator stands as a <strong>technical preservation project</strong>, ensuring that the magic of classic and custom servers lives on for future generations of players, tinkerers, and game designers.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
> We humbly acknowledge and thank the original developers for creating one of the most influential online experiences in gaming history.
|
||||||
|
|
||||||
|
<h1 align="center">
|
||||||
|
🧑💻🖥️ Supported Clients
|
||||||
|
</h1>
|
||||||
|
|
||||||
|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear|
|
|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear|
|
||||||
|:---:|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|:---:|
|
||||||
|<img src="http://i.imgur.com/hrwDxoM.jpg" height="150">|<img src="http://i.imgur.com/cRDW5tn.png" height="150">|<img src="http://i.imgur.com/V48kuVn.jpg" height="150">|<img src="http://i.imgur.com/IJQ0XMa.jpg" height="150">|<img src="http://i.imgur.com/OMpHkKa.png" height="100">|
|
|<img src="http://i.imgur.com/hrwDxoM.jpg" height="150">|<img src="http://i.imgur.com/cRDW5tn.png" height="150">|<img src="http://i.imgur.com/V48kuVn.jpg" height="150">|<img src="http://i.imgur.com/IJQ0XMa.jpg" height="150">|<img src="http://i.imgur.com/OMpHkKa.png" height="100">|
|
||||||
|
|
||||||
## Bug Reports <img src="http://i.imgur.com/daf1Vjw.png" height="20">
|
## 📚 Resources
|
||||||
* 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.
|
|
||||||
|
|
||||||
## Contributions <img src="http://image.flaticon.com/icons/png/512/25/25231.png" width="20">
|
| Resource | Badges | Link |
|
||||||
|
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
|
||||||
|
| **EQEmulator Docs** | [](https://docs.eqemu.io) | [docs.eqemu.io](https://docs.eqemu.io/) |
|
||||||
|
| **Discord Community**| [](https://discord.gg/QHsm7CD) | [Join Discord](https://discord.gg/QHsm7CD) |
|
||||||
|
| **Latest Release** | [](https://github.com/eqemu/server/releases) <br> [](https://github.com/EQEmu/Server/releases) <br> [](https://github.com/eqemu/server/releases) | [View Releases](https://github.com/eqemu/server/releases) |
|
||||||
|
| **License** | [](./LICENSE) | [View License](./LICENSE) |
|
||||||
|
| **Build Status** | [](http://drone.akkadius.com/EQEmu/Server) | [View Build Status](http://drone.akkadius.com/EQEmu/Server) |
|
||||||
|
| **Docker Pulls** | [](https://hub.docker.com/r/akkadius/eqemu-server) | [Docker Hub](https://hub.docker.com/r/akkadius/eqemu-server) |
|
||||||
|
| **Contributions** | [](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) |
|
||||||
|
|
||||||
* The preferred way to contribute is to fork the repo and submit a pull request on
|
## 🛠️ Getting Started
|
||||||
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.
|
|
||||||
|
|
||||||
## Contact <img src="http://gamerescape.com/wp-content/uploads/2015/06/discord.png" height="20">
|
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!
|
||||||
|
|
||||||
- Discord Channel: https://discord.gg/QHsm7CD
|
## 🗂️ Related Repositories
|
||||||
- **User Discord Channel**: `#general`
|
|
||||||
- **Developer Discord Channel**: `#eqemucoders`
|
|
||||||
|
|
||||||
## Resources
|
| Repository | Description |
|
||||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
|--------------------|----------------------------------------------------------------------------------|
|
||||||
- [EQEmulator Wiki](https://docs.eqemu.io/)
|
| [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 |
|
||||||
|
|
||||||
## Related Repositories
|
|
||||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
|
||||||
* [Maps](https://github.com/Akkadius/EQEmuMaps)
|
|
||||||
* [Installer Resources](https://github.com/Akkadius/EQEmuInstall)
|
|
||||||
* [Zone Utilities](https://github.com/EQEmu/zone-utilities) - Various utilities and libraries for parsing, rendering and manipulating EQ Zone files.
|
|
||||||
|
|
||||||
## Other License Info
|
|
||||||
|
|
||||||
* The server code and utilities are released under **GPLv3**
|
|
||||||
* We also include some small libraries for convienence that may be under different licensing
|
|
||||||
* SocketLib - GPL LibXML
|
|
||||||
* zlib - zlib license
|
|
||||||
* MariaDB/MySQL - GPL
|
|
||||||
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
|
|
||||||
* CPPUnit - GLP StringUtilities - Apache
|
|
||||||
* LUA - MIT
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
<a href="https://github.com/EQEmu/server/graphs/contributors">
|
<a href="https://github.com/EQEmu/server/graphs/contributors">
|
||||||
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
|
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
add_subdirectory(import)
|
add_subdirectory(import)
|
||||||
add_subdirectory(export)
|
add_subdirectory(export)
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
SET(export_sources
|
set(export_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(export_headers
|
set(export_headers
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
|
add_executable(export_client_files ${export_sources} ${export_headers})
|
||||||
|
|
||||||
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
install(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(export_client_files ${SERVER_LIBS})
|
target_link_libraries(export_client_files common)
|
||||||
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||||
|
|||||||
@ -38,13 +38,6 @@
|
|||||||
#include "../../common/skill_caps.h"
|
#include "../../common/skill_caps.h"
|
||||||
#include "../../common/evolving_items.h"
|
#include "../../common/evolving_items.h"
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
|
||||||
WorldContentService content_service;
|
|
||||||
ZoneStore zone_store;
|
|
||||||
PathManager path;
|
|
||||||
PlayerEventLogs player_event_logs;
|
|
||||||
EvolvingItemsManager evolving_items_manager;
|
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase *db);
|
void ExportSpells(SharedDatabase *db);
|
||||||
void ExportSkillCaps(SharedDatabase *db);
|
void ExportSkillCaps(SharedDatabase *db);
|
||||||
void ExportBaseData(SharedDatabase *db);
|
void ExportBaseData(SharedDatabase *db);
|
||||||
@ -53,10 +46,10 @@ void ExportDBStrings(SharedDatabase *db);
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
RegisterExecutablePlatform(ExePlatformClientExport);
|
RegisterExecutablePlatform(ExePlatformClientExport);
|
||||||
LogSys.LoadLogSettingsDefaults();
|
EQEmuLogSys::Instance()->LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
path.LoadPaths();
|
PathManager::Instance()->Init();
|
||||||
|
|
||||||
LogInfo("Client Files Export Utility");
|
LogInfo("Client Files Export Utility");
|
||||||
if (!EQEmuConfig::LoadConfig()) {
|
if (!EQEmuConfig::LoadConfig()) {
|
||||||
@ -99,8 +92,8 @@ int main(int argc, char **argv)
|
|||||||
content_db.SetMySQL(database);
|
content_db.SetMySQL(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
EQEmuLogSys::Instance()->SetDatabase(&database)
|
||||||
->SetLogPath(path.GetLogPath())
|
->SetLogPath(PathManager::Instance()->GetLogPath())
|
||||||
->LoadLogDatabaseSettings()
|
->LoadLogDatabaseSettings()
|
||||||
->StartFileLogs();
|
->StartFileLogs();
|
||||||
|
|
||||||
@ -129,14 +122,14 @@ int main(int argc, char **argv)
|
|||||||
ExportBaseData(&content_db);
|
ExportBaseData(&content_db);
|
||||||
ExportDBStrings(&database);
|
ExportDBStrings(&database);
|
||||||
|
|
||||||
LogSys.CloseFileLogs();
|
EQEmuLogSys::Instance()->CloseFileLogs();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase* db)
|
void ExportSpells(SharedDatabase* db)
|
||||||
{
|
{
|
||||||
std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
|
std::ofstream file(fmt::format("{}/export/spells_us.txt", PathManager::Instance()->GetServerPath()));
|
||||||
if (!file || !file.is_open()) {
|
if (!file || !file.is_open()) {
|
||||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@ -155,7 +148,7 @@ void ExportSpells(SharedDatabase* db)
|
|||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase* db)
|
void ExportSkillCaps(SharedDatabase* db)
|
||||||
{
|
{
|
||||||
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", PathManager::Instance()->GetServerPath()));
|
||||||
if (!file || !file.is_open()) {
|
if (!file || !file.is_open()) {
|
||||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@ -174,7 +167,7 @@ void ExportSkillCaps(SharedDatabase* db)
|
|||||||
|
|
||||||
void ExportBaseData(SharedDatabase *db)
|
void ExportBaseData(SharedDatabase *db)
|
||||||
{
|
{
|
||||||
std::ofstream file(fmt::format("{}/export/BaseData.txt", path.GetServerPath()));
|
std::ofstream file(fmt::format("{}/export/BaseData.txt", PathManager::Instance()->GetServerPath()));
|
||||||
if (!file || !file.is_open()) {
|
if (!file || !file.is_open()) {
|
||||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@ -193,7 +186,7 @@ void ExportBaseData(SharedDatabase *db)
|
|||||||
|
|
||||||
void ExportDBStrings(SharedDatabase *db)
|
void ExportDBStrings(SharedDatabase *db)
|
||||||
{
|
{
|
||||||
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", path.GetServerPath()));
|
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", PathManager::Instance()->GetServerPath()));
|
||||||
if (!file || !file.is_open()) {
|
if (!file || !file.is_open()) {
|
||||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
SET(import_sources
|
set(import_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(import_headers
|
set(import_headers
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
|
add_executable(import_client_files ${import_sources} ${import_headers})
|
||||||
|
|
||||||
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
install(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(import_client_files ${SERVER_LIBS})
|
target_link_libraries(import_client_files common)
|
||||||
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||||
|
|||||||
@ -32,13 +32,6 @@
|
|||||||
#include "../../common/events/player_event_logs.h"
|
#include "../../common/events/player_event_logs.h"
|
||||||
#include "../../common/evolving_items.h"
|
#include "../../common/evolving_items.h"
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
|
||||||
WorldContentService content_service;
|
|
||||||
ZoneStore zone_store;
|
|
||||||
PathManager path;
|
|
||||||
PlayerEventLogs player_event_logs;
|
|
||||||
EvolvingItemsManager evolving_items_manager;
|
|
||||||
|
|
||||||
void ImportSpells(SharedDatabase *db);
|
void ImportSpells(SharedDatabase *db);
|
||||||
void ImportSkillCaps(SharedDatabase *db);
|
void ImportSkillCaps(SharedDatabase *db);
|
||||||
void ImportBaseData(SharedDatabase *db);
|
void ImportBaseData(SharedDatabase *db);
|
||||||
@ -46,10 +39,10 @@ void ImportDBStrings(SharedDatabase *db);
|
|||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
RegisterExecutablePlatform(ExePlatformClientImport);
|
RegisterExecutablePlatform(ExePlatformClientImport);
|
||||||
LogSys.LoadLogSettingsDefaults();
|
EQEmuLogSys::Instance()->LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
path.LoadPaths();
|
PathManager::Instance()->Init();
|
||||||
|
|
||||||
LogInfo("Client Files Import Utility");
|
LogInfo("Client Files Import Utility");
|
||||||
if(!EQEmuConfig::LoadConfig()) {
|
if(!EQEmuConfig::LoadConfig()) {
|
||||||
@ -92,8 +85,8 @@ int main(int argc, char **argv) {
|
|||||||
content_db.SetMySQL(database);
|
content_db.SetMySQL(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
EQEmuLogSys::Instance()->SetDatabase(&database)
|
||||||
->SetLogPath(path.GetLogPath())
|
->SetLogPath(PathManager::Instance()->GetLogPath())
|
||||||
->LoadLogDatabaseSettings()
|
->LoadLogDatabaseSettings()
|
||||||
->StartFileLogs();
|
->StartFileLogs();
|
||||||
|
|
||||||
@ -102,7 +95,7 @@ int main(int argc, char **argv) {
|
|||||||
ImportBaseData(&content_db);
|
ImportBaseData(&content_db);
|
||||||
ImportDBStrings(&database);
|
ImportDBStrings(&database);
|
||||||
|
|
||||||
LogSys.CloseFileLogs();
|
EQEmuLogSys::Instance()->CloseFileLogs();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -138,7 +131,7 @@ bool IsStringField(int i) {
|
|||||||
|
|
||||||
void ImportSpells(SharedDatabase *db) {
|
void ImportSpells(SharedDatabase *db) {
|
||||||
LogInfo("Importing Spells");
|
LogInfo("Importing Spells");
|
||||||
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
|
std::string file = fmt::format("{}/import/spells_us.txt", PathManager::Instance()->GetServerPath());
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
FILE *f = fopen(file.c_str(), "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open {} to read, skipping.", file);
|
||||||
@ -228,7 +221,7 @@ void ImportSpells(SharedDatabase *db) {
|
|||||||
void ImportSkillCaps(SharedDatabase *db) {
|
void ImportSkillCaps(SharedDatabase *db) {
|
||||||
LogInfo("Importing Skill Caps");
|
LogInfo("Importing Skill Caps");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
|
std::string file = fmt::format("{}/import/SkillCaps.txt", PathManager::Instance()->GetServerPath());
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
FILE *f = fopen(file.c_str(), "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open {} to read, skipping.", file);
|
||||||
@ -265,7 +258,7 @@ void ImportBaseData(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Importing Base Data");
|
LogInfo("Importing Base Data");
|
||||||
|
|
||||||
const std::string& file_name = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
const std::string& file_name = fmt::format("{}/import/BaseData.txt", PathManager::Instance()->GetServerPath());
|
||||||
|
|
||||||
const auto& file_contents = File::GetContents(file_name);
|
const auto& file_contents = File::GetContents(file_name);
|
||||||
if (!file_contents.error.empty()) {
|
if (!file_contents.error.empty()) {
|
||||||
@ -305,7 +298,7 @@ void ImportBaseData(SharedDatabase *db)
|
|||||||
void ImportDBStrings(SharedDatabase *db) {
|
void ImportDBStrings(SharedDatabase *db) {
|
||||||
LogInfo("Importing DB Strings");
|
LogInfo("Importing DB Strings");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
|
std::string file = fmt::format("{}/import/dbstr_us.txt", PathManager::Instance()->GetServerPath());
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
FILE *f = fopen(file.c_str(), "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open {} to read, skipping.", file);
|
||||||
|
|||||||
@ -1,94 +0,0 @@
|
|||||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON)
|
|
||||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
|
||||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
|
||||||
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-x86")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-x64")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64")
|
|
||||||
|
|
||||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64})
|
|
||||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64})
|
|
||||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP})
|
|
||||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR})
|
|
||||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP})
|
|
||||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR})
|
|
||||||
ELSE()
|
|
||||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86})
|
|
||||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86})
|
|
||||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP})
|
|
||||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR})
|
|
||||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP})
|
|
||||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR})
|
|
||||||
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}
|
|
||||||
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)
|
|
||||||
#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()
|
|
||||||
|
|
||||||
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()
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
||||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
|
||||||
# Modified from the FindLua51 that comes with CMake
|
|
||||||
|
|
||||||
#[=======================================================================[.rst:
|
|
||||||
FindLua51
|
|
||||||
---------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Locate Lua51 library This module defines
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
LUA51_FOUND, if false, do not try to link to Lua
|
|
||||||
LUA_LIBRARIES
|
|
||||||
LUA_INCLUDE_DIR, where to find lua.h
|
|
||||||
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note that the expected include convention is
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
#include "lua.h"
|
|
||||||
|
|
||||||
and not
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
#include <lua/lua.h>
|
|
||||||
|
|
||||||
This is because, the lua location is not standardized and may exist in
|
|
||||||
locations other than lua/
|
|
||||||
#]=======================================================================]
|
|
||||||
|
|
||||||
find_path(LUA_INCLUDE_DIR lua.h
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw # Fink
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt/csw # Blastwave
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(LUA_LIBRARY
|
|
||||||
NAMES lua51 lua5.1 lua-5.1 lua
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATH_SUFFIXES lib
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw
|
|
||||||
/opt/local
|
|
||||||
/opt/csw
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LUA_LIBRARY)
|
|
||||||
# include the math library for Unix
|
|
||||||
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
|
|
||||||
find_library(LUA_MATH_LIBRARY m)
|
|
||||||
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
|
||||||
# For Windows and Mac, don't need to explicitly include the math library
|
|
||||||
else()
|
|
||||||
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
|
||||||
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
|
||||||
|
|
||||||
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
|
||||||
unset(lua_version_str)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
|
||||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
|
||||||
VERSION_VAR LUA_VERSION_STRING)
|
|
||||||
|
|
||||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
|
||||||
|
|
||||||
@ -88,4 +88,3 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJit
|
|||||||
VERSION_VAR LUAJIT_VERSION_STRING)
|
VERSION_VAR LUAJIT_VERSION_STRING)
|
||||||
|
|
||||||
mark_as_advanced(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
|
mark_as_advanced(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
|
||||||
|
|
||||||
|
|||||||
@ -1,87 +0,0 @@
|
|||||||
# - Find mariadbclient
|
|
||||||
#
|
|
||||||
# -*- cmake -*-
|
|
||||||
#
|
|
||||||
# Find the native MariaDB includes and library
|
|
||||||
#
|
|
||||||
# MariaDB_INCLUDE_DIR - where to find mysql.h, etc.
|
|
||||||
# MariaDB_LIBRARIES - List of libraries when using MariaDB.
|
|
||||||
# MariaDB_FOUND - True if MariaDB found.
|
|
||||||
# The following can be used as a hint as to where to search:
|
|
||||||
# MARIADB_ROOT
|
|
||||||
|
|
||||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
|
||||||
# Already in cache, be silent
|
|
||||||
SET(MariaDB_FIND_QUIETLY TRUE)
|
|
||||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
|
||||||
|
|
||||||
# Include dir
|
|
||||||
IF(MARIADB_ROOT)
|
|
||||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
|
||||||
NAMES mariadb_version.h
|
|
||||||
PATHS ${MARIADB_ROOT}/include
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_SYSTEM_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
|
||||||
NAMES mariadb_version.h
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ELSE(MARIADB_ROOT)
|
|
||||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
|
||||||
NAMES mariadb_version.h
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ENDIF(MARIADB_ROOT)
|
|
||||||
|
|
||||||
# Library
|
|
||||||
SET(MariaDB_NAMES libmariadb)
|
|
||||||
IF(MARIADB_ROOT)
|
|
||||||
FIND_LIBRARY(MariaDB_LIBRARY
|
|
||||||
NAMES ${MariaDB_NAMES}
|
|
||||||
PATHS ${MARIADB_ROOT}/lib
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_SYSTEM_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(MariaDB_LIBRARY
|
|
||||||
NAMES ${MariaDB_NAMES}
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ELSE(MARIADB_ROOT)
|
|
||||||
FIND_LIBRARY(MariaDB_LIBRARY
|
|
||||||
NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient
|
|
||||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ENDIF(MARIADB_ROOT)
|
|
||||||
|
|
||||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
|
||||||
SET(MariaDB_FOUND TRUE)
|
|
||||||
SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY})
|
|
||||||
ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
|
||||||
SET(MariaDB_FOUND FALSE)
|
|
||||||
SET(MariaDB_LIBRARIES)
|
|
||||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
|
||||||
|
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR)
|
|
||||||
|
|
||||||
IF(MariaDB_FOUND)
|
|
||||||
SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} )
|
|
||||||
SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} )
|
|
||||||
SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} )
|
|
||||||
ELSE(MariaDB_FOUND)
|
|
||||||
SET( MariaDB_LIBRARIES )
|
|
||||||
ENDIF(MariaDB_FOUND)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
|
||||||
MariaDB_LIBRARY_DEBUG
|
|
||||||
MariaDB_LIBRARY_RELEASE
|
|
||||||
MariaDB_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
# - Find mysqlclient
|
|
||||||
#
|
|
||||||
# -*- cmake -*-
|
|
||||||
#
|
|
||||||
# Find the native MySQL includes and library
|
|
||||||
#
|
|
||||||
# MySQL_INCLUDE_DIR - where to find mysql.h, etc.
|
|
||||||
# MySQL_LIBRARIES - List of libraries when using MySQL.
|
|
||||||
# MySQL_FOUND - True if MySQL found.
|
|
||||||
# The following can be used as a hint as to where to search:
|
|
||||||
# MYSQL_ROOT
|
|
||||||
|
|
||||||
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARIES)
|
|
||||||
# Already in cache, be silent
|
|
||||||
SET(MySQL_FIND_QUIETLY TRUE)
|
|
||||||
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARIES)
|
|
||||||
|
|
||||||
# Include dir
|
|
||||||
IF(MYSQL_ROOT)
|
|
||||||
FIND_PATH(MySQL_INCLUDE_DIR
|
|
||||||
NAMES mysql.h
|
|
||||||
PATHS ${MYSQL_ROOT}/include
|
|
||||||
PATH_SUFFIXES mysql
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_SYSTEM_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
FIND_PATH(MySQL_INCLUDE_DIR
|
|
||||||
NAMES mysql.h
|
|
||||||
PATH_SUFFIXES mysql
|
|
||||||
)
|
|
||||||
ELSE(MYSQL_ROOT)
|
|
||||||
FIND_PATH(MySQL_INCLUDE_DIR
|
|
||||||
NAMES mysql.h
|
|
||||||
PATH_SUFFIXES mysql
|
|
||||||
)
|
|
||||||
ENDIF(MYSQL_ROOT)
|
|
||||||
|
|
||||||
# Library
|
|
||||||
SET(MySQL_NAMES libmysql)
|
|
||||||
IF(MYSQL_ROOT)
|
|
||||||
FIND_LIBRARY(MySQL_LIBRARY
|
|
||||||
NAMES ${MySQL_NAMES}
|
|
||||||
PATHS ${MYSQL_ROOT}/lib
|
|
||||||
PATH_SUFFIXES mysql
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_SYSTEM_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(MySQL_LIBRARY
|
|
||||||
NAMES ${MySQL_NAMES}
|
|
||||||
PATH_SUFFIXES mysql
|
|
||||||
)
|
|
||||||
ELSE(MYSQL_ROOT)
|
|
||||||
FIND_LIBRARY(MySQL_LIBRARY
|
|
||||||
NAMES ${MySQL_NAMES} mysqlclient_r mysqlclient
|
|
||||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
|
||||||
PATH_SUFFIXES mysql
|
|
||||||
)
|
|
||||||
ENDIF(MYSQL_ROOT)
|
|
||||||
|
|
||||||
IF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
|
|
||||||
SET(MySQL_FOUND TRUE)
|
|
||||||
SET( MySQL_LIBRARIES ${MySQL_LIBRARY} )
|
|
||||||
ELSE (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
|
|
||||||
SET(MySQL_FOUND FALSE)
|
|
||||||
SET( MySQL_LIBRARIES )
|
|
||||||
ENDIF (MySQL_INCLUDE_DIR AND MySQL_LIBRARY)
|
|
||||||
|
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set MySQL_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MySQL DEFAULT_MSG MySQL_LIBRARY MySQL_INCLUDE_DIR)
|
|
||||||
|
|
||||||
IF(MySQL_FOUND)
|
|
||||||
SET( MySQL_LIBRARY_RELEASE ${MySQL_LIBRARY} )
|
|
||||||
SET( MySQL_LIBRARY_DEBUG ${MySQL_LIBRARY} )
|
|
||||||
SET( MySQL_LIBRARIES ${MySQL_LIBRARY_RELEASE} ${MySQL_LIBRARY_DEBUG} )
|
|
||||||
ELSE(MySQL_FOUND)
|
|
||||||
SET( MySQL_LIBRARIES )
|
|
||||||
ENDIF(MySQL_FOUND)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
|
||||||
MySQL_LIBRARY_DEBUG
|
|
||||||
MySQL_LIBRARY_RELEASE
|
|
||||||
MySQL_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
if (NOT MSVC)
|
|
||||||
include(FindPkgConfig)
|
|
||||||
pkg_check_modules(PC_SODIUM "libsodium")
|
|
||||||
if (NOT PC_SODIUM_FOUND)
|
|
||||||
pkg_check_modules(PC_SODIUM "sodium")
|
|
||||||
endif (NOT PC_SODIUM_FOUND)
|
|
||||||
if (PC_SODIUM_FOUND)
|
|
||||||
set(SODIUM_INCLUDE_HINTS ${PC_SODIUM_INCLUDE_DIRS} ${PC_SODIUM_INCLUDE_DIRS}/*)
|
|
||||||
set(SODIUM_LIBRARY_HINTS ${PC_SODIUM_LIBRARY_DIRS} ${PC_SODIUM_LIBRARY_DIRS}/*)
|
|
||||||
endif()
|
|
||||||
endif (NOT MSVC)
|
|
||||||
|
|
||||||
# some libraries install the headers is a subdirectory of the include dir
|
|
||||||
# returned by pkg-config, so use a wildcard match to improve chances of finding
|
|
||||||
# headers and libraries.
|
|
||||||
find_path(
|
|
||||||
SODIUM_INCLUDE_DIRS
|
|
||||||
NAMES sodium.h
|
|
||||||
HINTS ${SODIUM_INCLUDE_HINTS}
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(
|
|
||||||
SODIUM_LIBRARIES
|
|
||||||
NAMES libsodium sodium
|
|
||||||
HINTS ${SODIUM_LIBRARY_HINTS}
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(SODIUM DEFAULT_MSG SODIUM_LIBRARIES SODIUM_INCLUDE_DIRS)
|
|
||||||
mark_as_advanced(SODIUM_FOUND SODIUM_LIBRARIES SODIUM_INCLUDE_DIRS)
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
# - Try to find mbedTLS
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# Read-Only variables
|
|
||||||
# MBEDTLS_FOUND - system has mbedTLS
|
|
||||||
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
|
|
||||||
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
|
|
||||||
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
|
|
||||||
# MBEDTLS_LIBRARY - path to mbedTLS library
|
|
||||||
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
|
|
||||||
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
|
|
||||||
#
|
|
||||||
# Hint
|
|
||||||
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.
|
|
||||||
|
|
||||||
SET(_MBEDTLS_ROOT_HINTS
|
|
||||||
${MBEDTLS_ROOT_DIR}
|
|
||||||
ENV MBEDTLS_ROOT_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
|
|
||||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
|
||||||
PATHS ${_MBEDTLS_ROOT_PATHS}
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_PATH(MBEDTLS_INCLUDE_DIR
|
|
||||||
NAMES mbedtls/version.h
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES include
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
|
|
||||||
# Already in cache, be silent
|
|
||||||
SET(MBEDTLS_FIND_QUIETLY TRUE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
FIND_LIBRARY(MBEDTLS_LIBRARY
|
|
||||||
NAMES mbedtls libmbedtls
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES library
|
|
||||||
)
|
|
||||||
FIND_LIBRARY(MBEDX509_LIBRARY
|
|
||||||
NAMES mbedx509 libmbedx509
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES library
|
|
||||||
)
|
|
||||||
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
|
|
||||||
NAMES mbedcrypto libmbedcrypto
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES library
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
|
|
||||||
SET(MBEDTLS_FOUND TRUE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(MBEDTLS_FOUND)
|
|
||||||
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
|
|
||||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
|
|
||||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
|
|
||||||
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
|
|
||||||
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
|
|
||||||
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
|
|
||||||
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
|
|
||||||
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
|
|
||||||
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
|
|
||||||
|
|
||||||
IF(NOT MBEDTLS_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Found mbedTLS:")
|
|
||||||
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
|
|
||||||
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
|
|
||||||
IF (MBEDTLSMATCH)
|
|
||||||
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
|
|
||||||
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
|
|
||||||
ENDIF(MBEDTLSMATCH)
|
|
||||||
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
|
|
||||||
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
|
|
||||||
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
|
|
||||||
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
|
|
||||||
ELSE(MBEDTLS_FOUND)
|
|
||||||
IF(MBEDTLS_FIND_REQUIRED)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
|
|
||||||
ENDIF(MBEDTLS_FIND_REQUIRED)
|
|
||||||
ENDIF(MBEDTLS_FOUND)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
|
||||||
MBEDTLS_INCLUDE_DIR
|
|
||||||
MBEDTLS_LIBRARY_DIR
|
|
||||||
MBEDTLS_LIBRARIES
|
|
||||||
MBEDTLS_LIBRARY
|
|
||||||
MBEDX509_LIBRARY
|
|
||||||
MBEDCRYPTO_LIBRARY
|
|
||||||
)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/classes.h"
|
#include "../common/classes.h"
|
||||||
#include "data_verification.h"
|
#include "data_verification.h"
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include "eqemu_command_handler.h"
|
#include "eqemu_command_handler.h"
|
||||||
#include "terminal_color.hpp"
|
#include "terminal_color.hpp"
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
|
|||||||
@ -27,7 +27,7 @@ WorldContentService *WorldContentService::SetExpansionContext()
|
|||||||
// pull expansion from rules
|
// pull expansion from rules
|
||||||
int expansion = RuleI(Expansion, CurrentExpansion);
|
int expansion = RuleI(Expansion, CurrentExpansion);
|
||||||
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
||||||
content_service.SetCurrentExpansion(expansion);
|
WorldContentService::Instance()->SetCurrentExpansion(expansion);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(
|
LogInfo(
|
||||||
@ -41,12 +41,12 @@ WorldContentService *WorldContentService::SetExpansionContext()
|
|||||||
|
|
||||||
std::string WorldContentService::GetCurrentExpansionName()
|
std::string WorldContentService::GetCurrentExpansionName()
|
||||||
{
|
{
|
||||||
if (content_service.GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
|
if (WorldContentService::Instance()->GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
|
||||||
return "All Expansions";
|
return "All Expansions";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
|
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
|
||||||
return Expansion::ExpansionName[content_service.GetCurrentExpansion()];
|
return Expansion::ExpansionName[WorldContentService::Instance()->GetCurrentExpansion()];
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Unknown Expansion";
|
return "Unknown Expansion";
|
||||||
@ -185,7 +185,7 @@ void WorldContentService::ReloadContentFlags()
|
|||||||
|
|
||||||
SetContentFlags(set_content_flags);
|
SetContentFlags(set_content_flags);
|
||||||
LoadStaticGlobalZoneInstances();
|
LoadStaticGlobalZoneInstances();
|
||||||
zone_store.LoadZones(*m_content_database);
|
ZoneStore::Instance()->LoadZones(*m_content_database);
|
||||||
}
|
}
|
||||||
|
|
||||||
Database *WorldContentService::GetDatabase() const
|
Database *WorldContentService::GetDatabase() const
|
||||||
@ -291,7 +291,7 @@ WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
|
|||||||
// instance_list table entry for lavastorm has version = 1, is_global = 1, never_expires = 1
|
// instance_list table entry for lavastorm has version = 1, is_global = 1, never_expires = 1
|
||||||
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
|
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
|
||||||
{
|
{
|
||||||
for (const auto &z: zone_store.GetZones()) {
|
for (const auto &z: ZoneStore::Instance()->GetZones()) {
|
||||||
for (auto &i: m_zone_static_instances) {
|
for (auto &i: m_zone_static_instances) {
|
||||||
if (
|
if (
|
||||||
z.zoneidnumber == zone_id &&
|
z.zoneidnumber == zone_id &&
|
||||||
|
|||||||
@ -181,6 +181,12 @@ public:
|
|||||||
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
|
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
|
||||||
bool IsInPublicStaticInstance(uint32 instance_id);
|
bool IsInPublicStaticInstance(uint32 instance_id);
|
||||||
|
|
||||||
|
static WorldContentService* Instance()
|
||||||
|
{
|
||||||
|
static WorldContentService instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int current_expansion{};
|
int current_expansion{};
|
||||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||||
@ -194,6 +200,4 @@ private:
|
|||||||
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
|
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WorldContentService content_service;
|
|
||||||
|
|
||||||
#endif //EQEMU_WORLD_CONTENT_SERVICE_H
|
#endif //EQEMU_WORLD_CONTENT_SERVICE_H
|
||||||
|
|||||||
@ -23,10 +23,12 @@ void SendCrashReport(const std::string &crash_report)
|
|||||||
{
|
{
|
||||||
// can configure multiple endpoints if need be
|
// can configure multiple endpoints if need be
|
||||||
std::vector<std::string> endpoints = {
|
std::vector<std::string> endpoints = {
|
||||||
"https://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
"https://spire.eqemu.dev/api/v1/analytics/server-crash-report",
|
||||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EQEmuLogSys* log = EQEmuLogSys::Instance();
|
||||||
|
|
||||||
auto config = EQEmuConfig::get();
|
auto config = EQEmuConfig::get();
|
||||||
for (auto &e: endpoints) {
|
for (auto &e: endpoints) {
|
||||||
uri u(e);
|
uri u(e);
|
||||||
@ -68,12 +70,12 @@ void SendCrashReport(const std::string &crash_report)
|
|||||||
p["cpus"] = cpus.size();
|
p["cpus"] = cpus.size();
|
||||||
p["origination_info"] = "";
|
p["origination_info"] = "";
|
||||||
|
|
||||||
if (!LogSys.origination_info.zone_short_name.empty()) {
|
if (!log->origination_info.zone_short_name.empty()) {
|
||||||
p["origination_info"] = fmt::format(
|
p["origination_info"] = fmt::format(
|
||||||
"{} ({}) instance_id [{}]",
|
"{} ({}) instance_id [{}]",
|
||||||
LogSys.origination_info.zone_short_name,
|
log->origination_info.zone_short_name,
|
||||||
LogSys.origination_info.zone_long_name,
|
log->origination_info.zone_long_name,
|
||||||
LogSys.origination_info.instance_id
|
log->origination_info.instance_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +296,7 @@ void print_trace()
|
|||||||
SendCrashReport(crash_report);
|
SendCrashReport(crash_report);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.CloseFileLogs();
|
EQEmuLogSys::Instance()->CloseFileLogs();
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,15 @@
|
|||||||
#include "data_bucket.h"
|
#include "../common/data_bucket.h"
|
||||||
#include "zonedb.h"
|
#include "database.h"
|
||||||
#include "mob.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "worldserver.h"
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include "../common/json/json.hpp"
|
#include "../common/json/json.hpp"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
const std::string NESTED_KEY_DELIMITER = ".";
|
||||||
const std::string NESTED_KEY_DELIMITER = ".";
|
std::vector<DataBucketsRepository::DataBuckets> g_data_bucket_cache = {};
|
||||||
|
|
||||||
std::vector<DataBucketsRepository::DataBuckets> g_data_bucket_cache = {};
|
void DataBucket::SetData(SharedDatabase* database, const std::string &bucket_key, const std::string &bucket_value, std::string expires_time)
|
||||||
|
|
||||||
void DataBucket::SetData(const std::string &bucket_key, const std::string &bucket_value, std::string expires_time)
|
|
||||||
{
|
{
|
||||||
auto k = DataBucketKey{
|
auto k = DataBucketKey{
|
||||||
.key = bucket_key,
|
.key = bucket_key,
|
||||||
@ -22,10 +17,10 @@ void DataBucket::SetData(const std::string &bucket_key, const std::string &bucke
|
|||||||
.expires = expires_time,
|
.expires = expires_time,
|
||||||
};
|
};
|
||||||
|
|
||||||
DataBucket::SetData(k);
|
DataBucket::SetData(database, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataBucket::SetData(const DataBucketKey &k_)
|
void DataBucket::SetData(SharedDatabase *database, const DataBucketKey &k_)
|
||||||
{
|
{
|
||||||
DataBucketKey k = k_; // copy the key so we can modify it
|
DataBucketKey k = k_; // copy the key so we can modify it
|
||||||
bool is_nested = k.key.find(NESTED_KEY_DELIMITER) != std::string::npos;
|
bool is_nested = k.key.find(NESTED_KEY_DELIMITER) != std::string::npos;
|
||||||
@ -34,7 +29,7 @@ void DataBucket::SetData(const DataBucketKey &k_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto b = DataBucketsRepository::NewEntity();
|
auto b = DataBucketsRepository::NewEntity();
|
||||||
auto r = GetData(k, true);
|
auto r = GetData(database, k, true);
|
||||||
// if we have an entry, use it
|
// if we have an entry, use it
|
||||||
if (r.id > 0) {
|
if (r.id > 0) {
|
||||||
b = r;
|
b = r;
|
||||||
@ -144,10 +139,10 @@ void DataBucket::SetData(const DataBucketKey &k_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBucketsRepository::UpdateOne(database, b);
|
DataBucketsRepository::UpdateOne(*database, b);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
b = DataBucketsRepository::InsertOne(database, b);
|
b = DataBucketsRepository::InsertOne(*database, b);
|
||||||
|
|
||||||
// add to cache if it doesn't exist
|
// add to cache if it doesn't exist
|
||||||
if (CanCache(k) && !ExistsInCache(b)) {
|
if (CanCache(k) && !ExistsInCache(b)) {
|
||||||
@ -157,9 +152,9 @@ void DataBucket::SetData(const DataBucketKey &k_)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataBucket::GetData(const std::string &bucket_key)
|
std::string DataBucket::GetData(SharedDatabase* database, const std::string &bucket_key)
|
||||||
{
|
{
|
||||||
return GetData(DataBucketKey{.key = bucket_key}).value;
|
return GetData(database, DataBucketKey{.key = bucket_key}).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBucketsRepository::DataBuckets DataBucket::ExtractNestedValue(
|
DataBucketsRepository::DataBuckets DataBucket::ExtractNestedValue(
|
||||||
@ -209,7 +204,7 @@ DataBucketsRepository::DataBuckets DataBucket::ExtractNestedValue(
|
|||||||
// if the bucket doesn't exist, it will be added to the cache as a miss
|
// if the bucket doesn't exist, it will be added to the cache as a miss
|
||||||
// if ignore_misses_cache is true, the bucket will not be added to the cache as a miss
|
// if ignore_misses_cache is true, the bucket will not be added to the cache as a miss
|
||||||
// the only place we should be ignoring the misses cache is on the initial read during SetData
|
// the only place we should be ignoring the misses cache is on the initial read during SetData
|
||||||
DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k_, bool ignore_misses_cache)
|
DataBucketsRepository::DataBuckets DataBucket::GetData(SharedDatabase* database, const DataBucketKey &k_, bool ignore_misses_cache)
|
||||||
{
|
{
|
||||||
DataBucketKey k = k_; // Copy the key so we can modify it
|
DataBucketKey k = k_; // Copy the key so we can modify it
|
||||||
|
|
||||||
@ -239,7 +234,7 @@ DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k_,
|
|||||||
if (CheckBucketMatch(e, k)) {
|
if (CheckBucketMatch(e, k)) {
|
||||||
if (e.expires > 0 && e.expires < std::time(nullptr)) {
|
if (e.expires > 0 && e.expires < std::time(nullptr)) {
|
||||||
LogDataBuckets("Attempted to read expired key [{}] removing from cache", e.key_);
|
LogDataBuckets("Attempted to read expired key [{}] removing from cache", e.key_);
|
||||||
DeleteData(k);
|
DeleteData(database, k);
|
||||||
return DataBucketsRepository::NewEntity();
|
return DataBucketsRepository::NewEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +251,7 @@ DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k_,
|
|||||||
|
|
||||||
// Fetch the value from the database
|
// Fetch the value from the database
|
||||||
auto r = DataBucketsRepository::GetWhere(
|
auto r = DataBucketsRepository::GetWhere(
|
||||||
database,
|
*database,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
" {} `key` = '{}' LIMIT 1",
|
" {} `key` = '{}' LIMIT 1",
|
||||||
DataBucket::GetScopedDbFilters(k),
|
DataBucket::GetScopedDbFilters(k),
|
||||||
@ -305,7 +300,7 @@ DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k_,
|
|||||||
|
|
||||||
// If the entry has expired, delete it
|
// If the entry has expired, delete it
|
||||||
if (bucket.expires > 0 && bucket.expires < static_cast<long long>(std::time(nullptr))) {
|
if (bucket.expires > 0 && bucket.expires < static_cast<long long>(std::time(nullptr))) {
|
||||||
DeleteData(k);
|
DeleteData(database, k);
|
||||||
return DataBucketsRepository::NewEntity();
|
return DataBucketsRepository::NewEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,43 +327,22 @@ DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k_,
|
|||||||
return bucket;
|
return bucket;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataBucket::GetDataExpires(const std::string &bucket_key)
|
std::string DataBucket::GetDataExpires(SharedDatabase* database, const std::string &bucket_key)
|
||||||
{
|
{
|
||||||
return GetDataExpires(DataBucketKey{.key = bucket_key});
|
return GetDataExpires(database, DataBucketKey{.key = bucket_key});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataBucket::GetDataRemaining(const std::string &bucket_key)
|
std::string DataBucket::GetDataRemaining(SharedDatabase* database, const std::string &bucket_key)
|
||||||
{
|
{
|
||||||
return GetDataRemaining(DataBucketKey{.key = bucket_key});
|
return GetDataRemaining(database, DataBucketKey{.key = bucket_key});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DataBucket::DeleteData(const std::string &bucket_key)
|
bool DataBucket::DeleteData(SharedDatabase* database, const std::string &bucket_key)
|
||||||
{
|
{
|
||||||
return DeleteData(DataBucketKey{.key = bucket_key});
|
return DeleteData(database, DataBucketKey{.key = bucket_key});
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDataBuckets bulk loads all data buckets for a mob
|
bool DataBucket::DeleteData(SharedDatabase* database, const DataBucketKey &k)
|
||||||
bool DataBucket::GetDataBuckets(Mob *mob)
|
|
||||||
{
|
|
||||||
const uint32 id = mob->GetMobTypeIdentifier();
|
|
||||||
|
|
||||||
if (!id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mob->IsBot()) {
|
|
||||||
BulkLoadEntitiesToCache(DataBucketLoadType::Bot, {id});
|
|
||||||
}
|
|
||||||
else if (mob->IsClient()) {
|
|
||||||
uint32 account_id = mob->CastToClient()->AccountID();
|
|
||||||
BulkLoadEntitiesToCache(DataBucketLoadType::Account, {account_id});
|
|
||||||
BulkLoadEntitiesToCache(DataBucketLoadType::Client, {id});
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DataBucket::DeleteData(const DataBucketKey &k)
|
|
||||||
{
|
{
|
||||||
bool is_nested_key = k.key.find(NESTED_KEY_DELIMITER) != std::string::npos;
|
bool is_nested_key = k.key.find(NESTED_KEY_DELIMITER) != std::string::npos;
|
||||||
|
|
||||||
@ -390,7 +364,7 @@ bool DataBucket::DeleteData(const DataBucketKey &k)
|
|||||||
|
|
||||||
// Regular key deletion, no nesting involved
|
// Regular key deletion, no nesting involved
|
||||||
return DataBucketsRepository::DeleteWhere(
|
return DataBucketsRepository::DeleteWhere(
|
||||||
database,
|
*database,
|
||||||
fmt::format("{} `key` = '{}'", DataBucket::GetScopedDbFilters(k), k.key)
|
fmt::format("{} `key` = '{}'", DataBucket::GetScopedDbFilters(k), k.key)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -400,7 +374,7 @@ bool DataBucket::DeleteData(const DataBucketKey &k)
|
|||||||
DataBucketKey top_level_k = k;
|
DataBucketKey top_level_k = k;
|
||||||
top_level_k.key = top_level_key;
|
top_level_k.key = top_level_key;
|
||||||
|
|
||||||
auto r = GetData(top_level_k);
|
auto r = GetData(database, top_level_k);
|
||||||
if (r.id == 0 || r.value.empty() || !Strings::IsValidJson(r.value)) {
|
if (r.id == 0 || r.value.empty() || !Strings::IsValidJson(r.value)) {
|
||||||
LogDataBuckets("Attempted to delete nested key [{}] but parent key [{}] does not exist or is invalid JSON", k.key, top_level_key);
|
LogDataBuckets("Attempted to delete nested key [{}] but parent key [{}] does not exist or is invalid JSON", k.key, top_level_key);
|
||||||
return false;
|
return false;
|
||||||
@ -460,14 +434,14 @@ bool DataBucket::DeleteData(const DataBucketKey &k)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return DataBucketsRepository::DeleteWhere(
|
return DataBucketsRepository::DeleteWhere(
|
||||||
database,
|
*database,
|
||||||
fmt::format("{} `key` = '{}'", DataBucket::GetScopedDbFilters(k), top_level_key)
|
fmt::format("{} `key` = '{}'", DataBucket::GetScopedDbFilters(k), top_level_key)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, update the existing JSON without the deleted key
|
// Otherwise, update the existing JSON without the deleted key
|
||||||
r.value = json_value.dump();
|
r.value = json_value.dump();
|
||||||
DataBucketsRepository::UpdateOne(database, r);
|
DataBucketsRepository::UpdateOne(*database, r);
|
||||||
|
|
||||||
// Update cache
|
// Update cache
|
||||||
if (CanCache(k)) {
|
if (CanCache(k)) {
|
||||||
@ -482,7 +456,7 @@ bool DataBucket::DeleteData(const DataBucketKey &k)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataBucket::GetDataExpires(const DataBucketKey &k)
|
std::string DataBucket::GetDataExpires(SharedDatabase* database, const DataBucketKey &k)
|
||||||
{
|
{
|
||||||
LogDataBuckets(
|
LogDataBuckets(
|
||||||
"Getting bucket expiration key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}]",
|
"Getting bucket expiration key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}]",
|
||||||
@ -493,7 +467,7 @@ std::string DataBucket::GetDataExpires(const DataBucketKey &k)
|
|||||||
k.npc_id
|
k.npc_id
|
||||||
);
|
);
|
||||||
|
|
||||||
auto r = GetData(k);
|
auto r = GetData(database, k);
|
||||||
if (r.id == 0) {
|
if (r.id == 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -501,7 +475,7 @@ std::string DataBucket::GetDataExpires(const DataBucketKey &k)
|
|||||||
return std::to_string(r.expires);
|
return std::to_string(r.expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DataBucket::GetDataRemaining(const DataBucketKey &k)
|
std::string DataBucket::GetDataRemaining(SharedDatabase* database, const DataBucketKey &k)
|
||||||
{
|
{
|
||||||
LogDataBuckets(
|
LogDataBuckets(
|
||||||
"Getting bucket remaining key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}] bot_id [{}] zone_id [{}] instance_id [{}]",
|
"Getting bucket remaining key [{}] bot_id [{}] account_id [{}] character_id [{}] npc_id [{}] bot_id [{}] zone_id [{}] instance_id [{}]",
|
||||||
@ -515,7 +489,7 @@ std::string DataBucket::GetDataRemaining(const DataBucketKey &k)
|
|||||||
k.instance_id
|
k.instance_id
|
||||||
);
|
);
|
||||||
|
|
||||||
auto r = GetData(k);
|
auto r = GetData(database, k);
|
||||||
if (r.id == 0) {
|
if (r.id == 0) {
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
@ -581,10 +555,10 @@ bool DataBucket::CheckBucketMatch(const DataBucketsRepository::DataBuckets &dbe,
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataBucket::LoadZoneCache(uint16 zone_id, uint16 instance_id)
|
void DataBucket::LoadZoneCache(SharedDatabase* database, uint16 zone_id, uint16 instance_id)
|
||||||
{
|
{
|
||||||
const auto &l = DataBucketsRepository::GetWhere(
|
const auto &l = DataBucketsRepository::GetWhere(
|
||||||
database,
|
*database,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"zone_id = {} AND instance_id = {} AND (`expires` > {} OR `expires` = 0)",
|
"zone_id = {} AND instance_id = {} AND (`expires` > {} OR `expires` = 0)",
|
||||||
zone_id,
|
zone_id,
|
||||||
@ -624,7 +598,7 @@ void DataBucket::LoadZoneCache(uint16 zone_id, uint16 instance_id)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataBucket::BulkLoadEntitiesToCache(DataBucketLoadType::Type t, std::vector<uint32> ids)
|
void DataBucket::BulkLoadEntitiesToCache(SharedDatabase* database, DataBucketLoadType::Type t, std::vector<uint32> ids)
|
||||||
{
|
{
|
||||||
if (ids.empty()) {
|
if (ids.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -669,7 +643,7 @@ void DataBucket::BulkLoadEntitiesToCache(DataBucketLoadType::Type t, std::vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto &l = DataBucketsRepository::GetWhere(
|
const auto &l = DataBucketsRepository::GetWhere(
|
||||||
database,
|
*database,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} IN ({}) AND (`expires` > {} OR `expires` = 0)",
|
"{} IN ({}) AND (`expires` > {} OR `expires` = 0)",
|
||||||
column,
|
column,
|
||||||
@ -2,11 +2,10 @@
|
|||||||
#define EQEMU_DATABUCKET_H
|
#define EQEMU_DATABUCKET_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../common/types.h"
|
#include "types.h"
|
||||||
#include "../common/repositories/data_buckets_repository.h"
|
#include "repositories/data_buckets_repository.h"
|
||||||
#include "mob.h"
|
#include "json/json_archive_single_line.h"
|
||||||
#include "../common/json/json_archive_single_line.h"
|
#include "shareddb.h"
|
||||||
#include "../common/servertalk.h"
|
|
||||||
|
|
||||||
struct DataBucketKey {
|
struct DataBucketKey {
|
||||||
std::string key;
|
std::string key;
|
||||||
@ -40,28 +39,26 @@ namespace DataBucketLoadType {
|
|||||||
class DataBucket {
|
class DataBucket {
|
||||||
public:
|
public:
|
||||||
// non-scoped bucket methods (for global buckets)
|
// non-scoped bucket methods (for global buckets)
|
||||||
static void SetData(const std::string &bucket_key, const std::string &bucket_value, std::string expires_time = "");
|
static void SetData(SharedDatabase *database, const std::string &bucket_key, const std::string &bucket_value, std::string expires_time = "");
|
||||||
static bool DeleteData(const std::string &bucket_key);
|
static bool DeleteData(SharedDatabase *database, const std::string &bucket_key);
|
||||||
static std::string GetData(const std::string &bucket_key);
|
static std::string GetData(SharedDatabase *database, const std::string &bucket_key);
|
||||||
static std::string GetDataExpires(const std::string &bucket_key);
|
static std::string GetDataExpires(SharedDatabase *database, const std::string &bucket_key);
|
||||||
static std::string GetDataRemaining(const std::string &bucket_key);
|
static std::string GetDataRemaining(SharedDatabase *database, const std::string &bucket_key);
|
||||||
|
|
||||||
static bool GetDataBuckets(Mob *mob);
|
|
||||||
|
|
||||||
// scoped bucket methods
|
// scoped bucket methods
|
||||||
static void SetData(const DataBucketKey &k_);
|
static void SetData(SharedDatabase *database, const DataBucketKey &k_);
|
||||||
static bool DeleteData(const DataBucketKey &k);
|
static bool DeleteData(SharedDatabase *database, const DataBucketKey &k);
|
||||||
static DataBucketsRepository::DataBuckets GetData(const DataBucketKey &k_, bool ignore_misses_cache = false);
|
static DataBucketsRepository::DataBuckets GetData(SharedDatabase *database, const DataBucketKey &k_, bool ignore_misses_cache = false);
|
||||||
static std::string GetDataExpires(const DataBucketKey &k);
|
static std::string GetDataExpires(SharedDatabase *database, const DataBucketKey &k);
|
||||||
static std::string GetDataRemaining(const DataBucketKey &k);
|
static std::string GetDataRemaining(SharedDatabase *database, const DataBucketKey &k);
|
||||||
static std::string GetScopedDbFilters(const DataBucketKey &k);
|
static std::string GetScopedDbFilters(const DataBucketKey &k);
|
||||||
|
|
||||||
// bucket repository versus key matching
|
// bucket repository versus key matching
|
||||||
static bool CheckBucketMatch(const DataBucketsRepository::DataBuckets &dbe, const DataBucketKey &k);
|
static bool CheckBucketMatch(const DataBucketsRepository::DataBuckets &dbe, const DataBucketKey &k);
|
||||||
static bool ExistsInCache(const DataBucketsRepository::DataBuckets &entry);
|
static bool ExistsInCache(const DataBucketsRepository::DataBuckets &entry);
|
||||||
|
|
||||||
static void LoadZoneCache(uint16 zone_id, uint16 instance_id);
|
static void LoadZoneCache(SharedDatabase* database, uint16 zone_id, uint16 instance_id);
|
||||||
static void BulkLoadEntitiesToCache(DataBucketLoadType::Type t, std::vector<uint32> ids);
|
static void BulkLoadEntitiesToCache(SharedDatabase* database, DataBucketLoadType::Type t, std::vector<uint32> ids);
|
||||||
static void DeleteCachedBuckets(DataBucketLoadType::Type type, uint32 id, uint32 secondary_id = 0);
|
static void DeleteCachedBuckets(DataBucketLoadType::Type type, uint32 id, uint32 secondary_id = 0);
|
||||||
|
|
||||||
static void DeleteFromMissesCache(DataBucketsRepository::DataBuckets e);
|
static void DeleteFromMissesCache(DataBucketsRepository::DataBuckets e);
|
||||||
@ -708,6 +708,20 @@ const std::string Database::GetNPCNameByID(uint32 npc_id)
|
|||||||
return e.id ? e.name : std::string();
|
return e.id ? e.name : std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename InputIterator, typename OutputIterator>
|
||||||
|
inline auto CleanMobName(InputIterator first, InputIterator last, OutputIterator result)
|
||||||
|
{
|
||||||
|
for (; first != last; ++first) {
|
||||||
|
if (*first == '_') {
|
||||||
|
*result = ' ';
|
||||||
|
}
|
||||||
|
else if (isalpha(*first) || *first == '`') {
|
||||||
|
*result = *first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string Database::GetCleanNPCNameByID(uint32 npc_id)
|
const std::string Database::GetCleanNPCNameByID(uint32 npc_id)
|
||||||
{
|
{
|
||||||
const auto& e = NpcTypesRepository::FindOne(*this, npc_id);
|
const auto& e = NpcTypesRepository::FindOne(*this, npc_id);
|
||||||
@ -1920,6 +1934,7 @@ bool Database::CopyCharacter(
|
|||||||
std::vector<std::string> tables_to_zero_id = {
|
std::vector<std::string> tables_to_zero_id = {
|
||||||
"keyring",
|
"keyring",
|
||||||
"data_buckets",
|
"data_buckets",
|
||||||
|
"character_evolving_items",
|
||||||
"character_instance_safereturns",
|
"character_instance_safereturns",
|
||||||
"character_expedition_lockouts",
|
"character_expedition_lockouts",
|
||||||
"character_instance_lockouts",
|
"character_instance_lockouts",
|
||||||
@ -1951,6 +1966,12 @@ bool Database::CopyCharacter(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
LogError("Transaction failed [{}] rolling back", results.ErrorMessage());
|
||||||
|
TransactionRollback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> columns = {};
|
std::vector<std::string> columns = {};
|
||||||
int column_count = 0;
|
int column_count = 0;
|
||||||
|
|
||||||
@ -1969,6 +1990,12 @@ bool Database::CopyCharacter(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
LogError("Transaction failed [{}] rolling back", results.ErrorMessage());
|
||||||
|
TransactionRollback();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::vector<std::string>> new_rows;
|
std::vector<std::vector<std::string>> new_rows;
|
||||||
|
|
||||||
for (auto row : results) {
|
for (auto row : results) {
|
||||||
@ -2036,13 +2063,18 @@ bool Database::CopyCharacter(
|
|||||||
LogInfo("Copying table [{}] rows [{}]", table_name, Strings::Commify(rows_copied));
|
LogInfo("Copying table [{}] rows [{}]", table_name, Strings::Commify(rows_copied));
|
||||||
|
|
||||||
if (!insert.ErrorMessage().empty()) {
|
if (!insert.ErrorMessage().empty()) {
|
||||||
|
LogError("Error copying table [{}] [{}]", table_name, insert.ErrorMessage());
|
||||||
TransactionRollback();
|
TransactionRollback();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionCommit();
|
auto r = TransactionCommit();
|
||||||
|
if (!r.Success()) {
|
||||||
|
LogError("Transaction failed [{}] rolling back", r.ErrorMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LogInfo(
|
LogInfo(
|
||||||
"Character [{}] copied to [{}] total rows [{}]",
|
"Character [{}] copied to [{}] total rows [{}]",
|
||||||
@ -2212,7 +2244,7 @@ void Database::PurgeCharacterParcels()
|
|||||||
pel.event_data = ss.str();
|
pel.event_data = ss.str();
|
||||||
pel.created_at = std::time(nullptr);
|
pel.created_at = std::time(nullptr);
|
||||||
|
|
||||||
player_event_logs.AddToQueue(pel);
|
PlayerEventLogs::Instance()->AddToQueue(pel);
|
||||||
|
|
||||||
ss.str("");
|
ss.str("");
|
||||||
ss.clear();
|
ss.clear();
|
||||||
|
|||||||
@ -50,7 +50,7 @@ bool DatabaseDumpService::IsMySQLInstalled()
|
|||||||
{
|
{
|
||||||
std::string version_output = GetMySQLVersion();
|
std::string version_output = GetMySQLVersion();
|
||||||
|
|
||||||
return version_output.find("mysql") != std::string::npos && version_output.find("Ver") != std::string::npos;
|
return version_output.find("mysql") != std::string::npos && (version_output.find("Ver") != std::string::npos || version_output.find("from") != std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,7 +204,7 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IsDumpOutputToConsole()) {
|
if (IsDumpOutputToConsole()) {
|
||||||
LogSys.SilenceConsoleLogging();
|
EQEmuLogSys::Instance()->SilenceConsoleLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("MySQL installed [{}]", GetMySQLVersion());
|
LogInfo("MySQL installed [{}]", GetMySQLVersion());
|
||||||
@ -324,7 +324,7 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IsDumpOutputToConsole()) {
|
if (!IsDumpOutputToConsole()) {
|
||||||
LogSys.LoadLogSettingsDefaults();
|
EQEmuLogSys::Instance()->LoadLogSettingsDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pipe_file.empty()) {
|
if (!pipe_file.empty()) {
|
||||||
|
|||||||
@ -5,16 +5,16 @@
|
|||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../http/httplib.h"
|
#include "../http/httplib.h"
|
||||||
|
|
||||||
#include "database_update_manifest.cpp"
|
|
||||||
#include "database_update_manifest_bots.cpp"
|
|
||||||
#include "database_dump_service.h"
|
#include "database_dump_service.h"
|
||||||
|
#include "database_update_manifest.h"
|
||||||
|
#include "database_update_manifest_custom.h"
|
||||||
|
#include "database_update_manifest_bots.h"
|
||||||
|
|
||||||
constexpr int BREAK_LENGTH = 70;
|
constexpr int BREAK_LENGTH = 70;
|
||||||
|
|
||||||
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
||||||
{
|
{
|
||||||
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
|
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version`, `custom_version` FROM `db_version` LIMIT 1");
|
||||||
if (!results.Success() || !results.RowCount()) {
|
if (!results.Success() || !results.RowCount()) {
|
||||||
LogError("Failed to read from [db_version] table!");
|
LogError("Failed to read from [db_version] table!");
|
||||||
return DatabaseVersion{};
|
return DatabaseVersion{};
|
||||||
@ -25,6 +25,7 @@ DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
|||||||
return DatabaseVersion{
|
return DatabaseVersion{
|
||||||
.server_database_version = Strings::ToInt(r[0]),
|
.server_database_version = Strings::ToInt(r[0]),
|
||||||
.bots_database_version = Strings::ToInt(r[1]),
|
.bots_database_version = Strings::ToInt(r[1]),
|
||||||
|
.custom_database_version = Strings::ToInt(r[2]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
|
|||||||
return DatabaseVersion{
|
return DatabaseVersion{
|
||||||
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
|
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
|
||||||
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
|
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
|
||||||
|
.custom_database_version = CUSTOM_BINARY_DATABASE_VERSION,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,6 +45,7 @@ constexpr int LOOK_BACK_AMOUNT = 10;
|
|||||||
// this check will take action
|
// this check will take action
|
||||||
void DatabaseUpdate::CheckDbUpdates()
|
void DatabaseUpdate::CheckDbUpdates()
|
||||||
{
|
{
|
||||||
|
InjectCustomVersionColumn();
|
||||||
InjectBotsVersionColumn();
|
InjectBotsVersionColumn();
|
||||||
auto v = GetDatabaseVersions();
|
auto v = GetDatabaseVersions();
|
||||||
auto b = GetBinaryDatabaseVersions();
|
auto b = GetBinaryDatabaseVersions();
|
||||||
@ -59,6 +62,15 @@ void DatabaseUpdate::CheckDbUpdates()
|
|||||||
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
|
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UpdateManifest(manifest_entries_custom, v.custom_database_version, b.custom_database_version)) {
|
||||||
|
LogInfo(
|
||||||
|
"Updates ran successfully, setting database version to [{}] from [{}]",
|
||||||
|
b.custom_database_version,
|
||||||
|
v.custom_database_version
|
||||||
|
);
|
||||||
|
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `custom_version` = {}", b.custom_database_version));
|
||||||
|
}
|
||||||
|
|
||||||
if (b.bots_database_version > 0) {
|
if (b.bots_database_version > 0) {
|
||||||
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
|
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
|
||||||
LogInfo(
|
LogInfo(
|
||||||
@ -141,7 +153,7 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
std::vector<int> missing_migrations = {};
|
std::vector<int> missing_migrations = {};
|
||||||
if (version_low != version_high) {
|
if (version_low != version_high) {
|
||||||
|
|
||||||
LogSys.DisableMySQLErrorLogs();
|
EQEmuLogSys::Instance()->DisableMySQLErrorLogs();
|
||||||
bool force_interactive = false;
|
bool force_interactive = false;
|
||||||
for (int version = version_low + 1; version <= version_high; ++version) {
|
for (int version = version_low + 1; version <= version_high; ++version) {
|
||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
@ -171,7 +183,7 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogSys.EnableMySQLErrorLogs();
|
EQEmuLogSys::Instance()->EnableMySQLErrorLogs();
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|
||||||
if (!missing_migrations.empty() && m_skip_backup) {
|
if (!missing_migrations.empty() && m_skip_backup) {
|
||||||
@ -344,6 +356,16 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b.custom_database_version > 0) {
|
||||||
|
LogInfo(
|
||||||
|
"{:>8} | database [{}] binary [{}] {}",
|
||||||
|
"Custom",
|
||||||
|
v.custom_database_version,
|
||||||
|
b.custom_database_version,
|
||||||
|
(v.custom_database_version == b.custom_database_version) ? "up to date" : "checking updates"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
|
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
|
||||||
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
@ -353,7 +375,10 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
|||||||
// bots database version is optional, if not enabled then it is always up-to-date
|
// bots database version is optional, if not enabled then it is always up-to-date
|
||||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version >= b.bots_database_version : true;
|
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version >= b.bots_database_version : true;
|
||||||
|
|
||||||
return server_up_to_date && bots_up_to_date;
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks to see if there are pending updates
|
// checks to see if there are pending updates
|
||||||
@ -373,3 +398,12 @@ void DatabaseUpdate::InjectBotsVersionColumn()
|
|||||||
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
|
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseUpdate::InjectCustomVersionColumn()
|
||||||
|
{
|
||||||
|
auto results = m_database->QueryDatabase("SHOW COLUMNS FROM `db_version` LIKE 'custom_version'");
|
||||||
|
if (!results.Success() || results.RowCount() == 0) {
|
||||||
|
LogInfo("Adding custom_version column to db_version table");
|
||||||
|
m_database->QueryDatabase("ALTER TABLE `db_version` ADD COLUMN `custom_version` INT(11) UNSIGNED NOT NULL DEFAULT 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ struct ManifestEntry {
|
|||||||
struct DatabaseVersion {
|
struct DatabaseVersion {
|
||||||
int server_database_version;
|
int server_database_version;
|
||||||
int bots_database_version;
|
int bots_database_version;
|
||||||
|
int custom_database_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DatabaseUpdate {
|
class DatabaseUpdate {
|
||||||
@ -32,12 +33,20 @@ public:
|
|||||||
DatabaseUpdate *SetContentDatabase(Database *db);
|
DatabaseUpdate *SetContentDatabase(Database *db);
|
||||||
DatabaseUpdate *SetSkipBackup(bool skip);
|
DatabaseUpdate *SetSkipBackup(bool skip);
|
||||||
bool HasPendingUpdates();
|
bool HasPendingUpdates();
|
||||||
|
|
||||||
|
static DatabaseUpdate* Instance()
|
||||||
|
{
|
||||||
|
static DatabaseUpdate instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_skip_backup = false;
|
bool m_skip_backup = false;
|
||||||
Database *m_database;
|
Database *m_database;
|
||||||
Database *m_content_database;
|
Database *m_content_database;
|
||||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
||||||
void InjectBotsVersionColumn();
|
void InjectBotsVersionColumn();
|
||||||
|
void InjectCustomVersionColumn();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "database_update.h"
|
#pragma once
|
||||||
|
|
||||||
std::vector<ManifestEntry> manifest_entries = {
|
std::vector<ManifestEntry> manifest_entries = {
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
@ -7109,6 +7109,80 @@ ALTER TABLE `npc_types`
|
|||||||
ALTER TABLE `character_data`
|
ALTER TABLE `character_data`
|
||||||
CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`,
|
CHANGE COLUMN `firstlogon` `ingame` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`,
|
||||||
ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`;
|
ADD COLUMN `first_login` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `xtargets`;
|
||||||
|
)",
|
||||||
|
.content_schema_update = false
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9324,
|
||||||
|
.description = "2025_06_11_player_event_logs_table.sql",
|
||||||
|
.check = "SHOW CREATE TABLE `player_event_logs`",
|
||||||
|
.condition = "missing",
|
||||||
|
.match = "COMPRESS",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE player_event_logs ROW_FORMAT=COMPRESSED;
|
||||||
|
CREATE INDEX idx_event_type_char_id ON player_event_logs (event_type_id, character_id);
|
||||||
|
)",
|
||||||
|
.content_schema_update = false
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9325,
|
||||||
|
.description = "2025_06_10_character_corpses_entity_variables.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `character_corpses` LIKE 'entity_variables'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `character_corpses`
|
||||||
|
ADD COLUMN `entity_variables` TEXT DEFAULT NULL AFTER `rezzable`;
|
||||||
|
)",
|
||||||
|
.content_schema_update = false
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9326,
|
||||||
|
.description = "2025_07_27_add_indexes_npc_spawns_loot.sql",
|
||||||
|
.check = "SHOW INDEX FROM npc_types",
|
||||||
|
.condition = "missing",
|
||||||
|
.match = "idx_npc_types_loottable_id",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE npc_types
|
||||||
|
ADD INDEX idx_npc_types_loottable_id (loottable_id);
|
||||||
|
|
||||||
|
ALTER TABLE spawnentry
|
||||||
|
ADD INDEX idx_spawnentry_spawngroup_id (spawngroupID),
|
||||||
|
ADD INDEX idx_spawnentry_npc_id (npcID);
|
||||||
|
|
||||||
|
ALTER TABLE lootdrop_entries
|
||||||
|
ADD INDEX idx_lootdrop_entries_lootdrop_id (lootdrop_id),
|
||||||
|
ADD INDEX idx_lootdrop_entries_item_id (item_id);
|
||||||
|
|
||||||
|
ALTER TABLE loottable_entries
|
||||||
|
ADD INDEX idx_loottable_entries_lootdrop_id (lootdrop_id),
|
||||||
|
ADD INDEX idx_loottable_entries_loottable_id (loottable_id);
|
||||||
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9327,
|
||||||
|
.description = "2025_08_13_character_stats_record_heal_amount.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `character_stats_record` LIKE 'heal_amount'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `character_stats_record`
|
||||||
|
ADD COLUMN `heal_amount` int(11) NULL DEFAULT 0 AFTER `spell_damage`;
|
||||||
|
)"
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9328,
|
||||||
|
.description = "2025_08_22_character_parcel_updates.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'evolve_amount'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `character_parcels`
|
||||||
|
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
|
||||||
|
|
||||||
|
ALTER TABLE `character_parcels_containers`
|
||||||
|
ADD COLUMN `evolve_amount` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `quantity`;
|
||||||
)",
|
)",
|
||||||
.content_schema_update = false
|
.content_schema_update = false
|
||||||
},
|
},
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "database_update.h"
|
#pragma once
|
||||||
|
|
||||||
std::vector<ManifestEntry> bot_manifest_entries = {
|
std::vector<ManifestEntry> bot_manifest_entries = {
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
55
common/database/database_update_manifest_custom.h
Normal file
55
common/database/database_update_manifest_custom.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
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
|
||||||
|
// };
|
||||||
@ -160,7 +160,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
(uint32) mysql_insert_id(mysql)
|
(uint32) mysql_insert_id(mysql)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
if (EQEmuLogSys::Instance()->log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||||
if ((strncasecmp(query, "select", 6) == 0)) {
|
if ((strncasecmp(query, "select", 6) == 0)) {
|
||||||
LogMySQLQuery(
|
LogMySQLQuery(
|
||||||
"{0} -- ({1} row{2} returned) ({3}s)",
|
"{0} -- ({1} row{2} returned) ({3}s)",
|
||||||
@ -189,9 +189,9 @@ void DBcore::TransactionBegin()
|
|||||||
QueryDatabase("START TRANSACTION");
|
QueryDatabase("START TRANSACTION");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::TransactionCommit()
|
MySQLRequestResult DBcore::TransactionCommit()
|
||||||
{
|
{
|
||||||
QueryDatabase("COMMIT");
|
return QueryDatabase("COMMIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::TransactionRollback()
|
void DBcore::TransactionRollback()
|
||||||
@ -258,9 +258,17 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (pCompress) {
|
if (pCompress) {
|
||||||
flags |= CLIENT_COMPRESS;
|
flags |= CLIENT_COMPRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo: we need to revisit this ssl handling later
|
||||||
|
//the whole connect code is ancient and tls is starting to come as a default requirement for many db setups
|
||||||
if (pSSL) {
|
if (pSSL) {
|
||||||
flags |= CLIENT_SSL;
|
flags |= CLIENT_SSL;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
int off = 0;
|
||||||
|
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &off);
|
||||||
|
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &off);
|
||||||
|
}
|
||||||
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
||||||
pStatus = Connected;
|
pStatus = Connected;
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ public:
|
|||||||
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
||||||
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
||||||
void TransactionBegin();
|
void TransactionBegin();
|
||||||
void TransactionCommit();
|
MySQLRequestResult TransactionCommit();
|
||||||
void TransactionRollback();
|
void TransactionRollback();
|
||||||
std::string Escape(const std::string& s);
|
std::string Escape(const std::string& s);
|
||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "../http/httplib.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
#include "../repositories/player_event_logs_repository.h"
|
||||||
#include "../events/player_events.h"
|
#include "../events/player_events.h"
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto webhook = LogSys.GetDiscordWebhooks()[q.first];
|
auto webhook = EQEmuLogSys::Instance()->GetDiscordWebhooks()[q.first];
|
||||||
std::string message;
|
std::string message;
|
||||||
|
|
||||||
for (auto &m: q.second) {
|
for (auto &m: q.second) {
|
||||||
@ -68,7 +68,7 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
|
|
||||||
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
|
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
|
||||||
{
|
{
|
||||||
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
|
auto w = PlayerEventLogs::Instance()->GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
|
||||||
if (!w.empty()) {
|
if (!w.empty()) {
|
||||||
Discord::SendPlayerEventMessage(e, w);
|
Discord::SendPlayerEventMessage(e, w);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,12 @@ public:
|
|||||||
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
||||||
void ProcessMessageQueue();
|
void ProcessMessageQueue();
|
||||||
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
||||||
|
|
||||||
|
static DiscordManager* Instance()
|
||||||
|
{
|
||||||
|
static DiscordManager instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::mutex webhook_queue_lock{};
|
std::mutex webhook_queue_lock{};
|
||||||
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
#include "util/uuid.h"
|
#include "util/uuid.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include <cereal/types/chrono.hpp>
|
#include <cereal/types/chrono.hpp>
|
||||||
|
|
||||||
DzLockout::DzLockout(std::string uuid, std::string expedition, std::string event, uint64_t expire_time, uint32_t duration)
|
DzLockout::DzLockout(std::string uuid, std::string expedition, std::string event, uint64_t expire_time, uint32_t duration)
|
||||||
|
|||||||
@ -451,3 +451,23 @@ bool LDoNTheme::IsValid(uint32 theme_id)
|
|||||||
{
|
{
|
||||||
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
|
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PetCommand::GetName(uint8 pet_command)
|
||||||
|
{
|
||||||
|
return IsValid(pet_command) ? pet_commands[pet_command] : "UNKNOWN PET COMMAND";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetCommand::IsValid(uint8 pet_command)
|
||||||
|
{
|
||||||
|
return pet_commands.find(pet_command) != pet_commands.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PetType::GetName(uint8 pet_type)
|
||||||
|
{
|
||||||
|
return IsValid(pet_type) ? pet_types[pet_type] : "UNKNOWN PET TYPE";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PetType::IsValid(uint8 pet_type)
|
||||||
|
{
|
||||||
|
return pet_types.find(pet_type) != pet_types.end();
|
||||||
|
}
|
||||||
|
|||||||
@ -792,4 +792,131 @@ namespace BookType {
|
|||||||
constexpr uint8 ItemInfo = 2;
|
constexpr uint8 ItemInfo = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace PetButton {
|
||||||
|
constexpr uint8 Sit = 0;
|
||||||
|
constexpr uint8 Stop = 1;
|
||||||
|
constexpr uint8 Regroup = 2;
|
||||||
|
constexpr uint8 Follow = 3;
|
||||||
|
constexpr uint8 Guard = 4;
|
||||||
|
constexpr uint8 Taunt = 5;
|
||||||
|
constexpr uint8 Hold = 6;
|
||||||
|
constexpr uint8 GreaterHold = 7;
|
||||||
|
constexpr uint8 Focus = 8;
|
||||||
|
constexpr uint8 SpellHold = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PetButtonState {
|
||||||
|
constexpr uint8 Off = 0;
|
||||||
|
constexpr uint8 On = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PetCommand {
|
||||||
|
constexpr uint8 HealthReport = 0; // /pet health or Pet Window
|
||||||
|
constexpr uint8 Leader = 1; // /pet leader or Pet Window
|
||||||
|
constexpr uint8 Attack = 2; // /pet attack or Pet Window
|
||||||
|
constexpr uint8 QAttack = 3; // /pet qattack or Pet Window
|
||||||
|
constexpr uint8 FollowMe = 4; // /pet follow or Pet Window
|
||||||
|
constexpr uint8 GuardHere = 5; // /pet guard or Pet Window
|
||||||
|
constexpr uint8 Sit = 6; // /pet sit or Pet Window
|
||||||
|
constexpr uint8 SitDown = 7; // /pet sit on
|
||||||
|
constexpr uint8 StandUp = 8; // /pet sit off
|
||||||
|
constexpr uint8 Stop = 9; // /pet stop or Pet Window - Not implemented
|
||||||
|
constexpr uint8 StopOn = 10; // /pet stop on - Not implemented
|
||||||
|
constexpr uint8 StopOff = 11; // /pet stop off - Not implemented
|
||||||
|
constexpr uint8 Taunt = 12; // /pet taunt or Pet Window
|
||||||
|
constexpr uint8 TauntOn = 13; // /pet taunt on
|
||||||
|
constexpr uint8 TauntOff = 14; // /pet taunt off
|
||||||
|
constexpr uint8 Hold = 15; // /pet hold or Pet Window, won't add to hate list unless attacking
|
||||||
|
constexpr uint8 HoldOn = 16; // /pet hold on
|
||||||
|
constexpr uint8 HoldOff = 17; // /pet hold off
|
||||||
|
constexpr uint8 GreaterHold = 18; // /pet ghold, will never add to hate list unless told to
|
||||||
|
constexpr uint8 GreaterHoldOn = 19; // /pet ghold on
|
||||||
|
constexpr uint8 GreaterHoldOff = 20; // /pet ghold off
|
||||||
|
constexpr uint8 SpellHold = 21; // /pet no cast or /pet spellhold or Pet Window
|
||||||
|
constexpr uint8 SpellHoldOn = 22; // /pet spellhold on
|
||||||
|
constexpr uint8 SpellHoldOff = 23; // /pet spellhold off
|
||||||
|
constexpr uint8 Focus = 24; // /pet focus or Pet Window
|
||||||
|
constexpr uint8 FocusOn = 25; // /pet focus on
|
||||||
|
constexpr uint8 FocusOff = 26; // /pet focus off
|
||||||
|
constexpr uint8 Feign = 27; // /pet feign
|
||||||
|
constexpr uint8 BackOff = 28; // /pet back off
|
||||||
|
constexpr uint8 GetLost = 29; // /pet get lost
|
||||||
|
constexpr uint8 GuardMe = 30; // Same as /pet follow, but different message in older clients
|
||||||
|
constexpr uint8 Regroup = 31; // /pet regroup, acts like classic hold
|
||||||
|
constexpr uint8 RegroupOn = 32; // /pet regroup on
|
||||||
|
constexpr uint8 RegroupOff = 33; // /pet regroup off
|
||||||
|
constexpr uint8 Max = 34;
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> pet_commands = {
|
||||||
|
{ PetCommand::HealthReport, "Health Report" },
|
||||||
|
{ PetCommand::Leader, "Leader" },
|
||||||
|
{ PetCommand::Attack, "Attack" },
|
||||||
|
{ PetCommand::QAttack, "QAttack" },
|
||||||
|
{ PetCommand::FollowMe, "Follow Me" },
|
||||||
|
{ PetCommand::GuardHere, "Guard Here" },
|
||||||
|
{ PetCommand::Sit, "Sit" },
|
||||||
|
{ PetCommand::SitDown, "Sit Down" },
|
||||||
|
{ PetCommand::StandUp, "Stand Up" },
|
||||||
|
{ PetCommand::Stop, "Stop" },
|
||||||
|
{ PetCommand::StopOn, "Stop On" },
|
||||||
|
{ PetCommand::StopOff, "Stop Off" },
|
||||||
|
{ PetCommand::Taunt, "Taunt" },
|
||||||
|
{ PetCommand::TauntOn, "Taunt On" },
|
||||||
|
{ PetCommand::TauntOff, "Taunt Off" },
|
||||||
|
{ PetCommand::Hold, "Hold" },
|
||||||
|
{ PetCommand::HoldOn, "Hold On" },
|
||||||
|
{ PetCommand::HoldOff, "Hold Off" },
|
||||||
|
{ PetCommand::GreaterHold, "Greater Hold" },
|
||||||
|
{ PetCommand::GreaterHoldOn, "Greater Hold On" },
|
||||||
|
{ PetCommand::GreaterHoldOff, "Greater Hold Off" },
|
||||||
|
{ PetCommand::SpellHold, "Spell Hold" },
|
||||||
|
{ PetCommand::SpellHoldOn, "Spell Hold On" },
|
||||||
|
{ PetCommand::SpellHoldOff, "Spell Hold Off" },
|
||||||
|
{ PetCommand::Focus, "Focus" },
|
||||||
|
{ PetCommand::FocusOn, "Focus On" },
|
||||||
|
{ PetCommand::FocusOff, "Focus Off" },
|
||||||
|
{ PetCommand::Feign, "Feign" },
|
||||||
|
{ PetCommand::BackOff, "Back Off" },
|
||||||
|
{ PetCommand::GetLost, "Get Lost" },
|
||||||
|
{ PetCommand::GuardMe, "Guard Me" },
|
||||||
|
{ PetCommand::Regroup, "Regroup" },
|
||||||
|
{ PetCommand::RegroupOn, "Regroup On" },
|
||||||
|
{ PetCommand::RegroupOff, "Regroup Off" },
|
||||||
|
{ PetCommand::Max, "Max" }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetName(uint8 pet_command);
|
||||||
|
bool IsValid(uint8 pet_command);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PetOrder {
|
||||||
|
constexpr uint8 Follow = 0;
|
||||||
|
constexpr uint8 Sit = 1;
|
||||||
|
constexpr uint8 Guard = 2;
|
||||||
|
constexpr uint8 Feign = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PetType {
|
||||||
|
constexpr uint8 Familiar = 0;
|
||||||
|
constexpr uint8 Animation = 1;
|
||||||
|
constexpr uint8 Normal = 2;
|
||||||
|
constexpr uint8 Charmed = 3;
|
||||||
|
constexpr uint8 Follow = 4;
|
||||||
|
constexpr uint8 TargetLock = 5;
|
||||||
|
constexpr uint8 None = 255;
|
||||||
|
|
||||||
|
static std::map<uint8, std::string> pet_types = {
|
||||||
|
{ PetType::Familiar, "Familiar" },
|
||||||
|
{ PetType::Animation, "Animation" },
|
||||||
|
{ PetType::Normal, "Normal" },
|
||||||
|
{ PetType::Charmed, "Charmed" },
|
||||||
|
{ PetType::Follow, "Follow" },
|
||||||
|
{ PetType::TargetLock, "Target Lock" },
|
||||||
|
{ PetType::None, "None" }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetName(uint8 pet_type);
|
||||||
|
bool IsValid(uint8 pet_type);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||||
|
|||||||
@ -988,7 +988,8 @@ enum StartZoneIndex {
|
|||||||
Felwithe,
|
Felwithe,
|
||||||
Akanon,
|
Akanon,
|
||||||
Cabilis,
|
Cabilis,
|
||||||
SharVahl
|
SharVahl,
|
||||||
|
RatheMtn
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FVNoDropFlagRule
|
enum FVNoDropFlagRule
|
||||||
|
|||||||
@ -23,9 +23,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "../cereal/include/cereal/archives/binary.hpp"
|
#include <cereal/archives/binary.hpp>
|
||||||
#include "../cereal/include/cereal/types/string.hpp"
|
#include <cereal/types/string.hpp>
|
||||||
#include "../cereal/include/cereal/types/vector.hpp"
|
#include <cereal/types/vector.hpp>
|
||||||
#include "../common/version.h"
|
#include "../common/version.h"
|
||||||
#include "emu_constants.h"
|
#include "emu_constants.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|||||||
@ -545,13 +545,13 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
|||||||
uint32 chunksize, used;
|
uint32 chunksize, used;
|
||||||
uint32 length;
|
uint32 length;
|
||||||
|
|
||||||
if (LogSys.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){
|
if (EQEmuLogSys::Instance()->log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){
|
||||||
if (p->GetOpcode() != OP_SpecialMesg){
|
if (p->GetOpcode() != OP_SpecialMesg){
|
||||||
Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
Log(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogSys.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){
|
if (EQEmuLogSys::Instance()->log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){
|
||||||
if (p->GetOpcode() != OP_SpecialMesg){
|
if (p->GetOpcode() != OP_SpecialMesg){
|
||||||
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "emu_versions.h"
|
#include "emu_versions.h"
|
||||||
#include "eq_packet.h"
|
#include "eq_packet.h"
|
||||||
#include "net/daybreak_connection.h"
|
#include "net/reliable_stream_connection.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESTABLISHED,
|
ESTABLISHED,
|
||||||
@ -33,18 +33,18 @@ struct EQStreamManagerInterfaceOptions
|
|||||||
//Login I had trouble getting to recognize compression at all
|
//Login I had trouble getting to recognize compression at all
|
||||||
//but that might be because it was still a bit buggy when i was testing that.
|
//but that might be because it was still a bit buggy when i was testing that.
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||||
}
|
}
|
||||||
else if (encoded) {
|
else if (encoded) {
|
||||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
daybreak_options.port = port;
|
reliable_stream_options.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
int opcode_size;
|
int opcode_size;
|
||||||
bool track_opcode_stats;
|
bool track_opcode_stats;
|
||||||
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
EQ::Net::ReliableStreamConnectionManagerOptions reliable_stream_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EQStreamManagerInterface
|
class EQStreamManagerInterface
|
||||||
@ -80,7 +80,7 @@ public:
|
|||||||
|
|
||||||
struct Stats
|
struct Stats
|
||||||
{
|
{
|
||||||
EQ::Net::DaybreakConnectionStats DaybreakStats;
|
EQ::Net::ReliableStreamConnectionStats ReliableStreamStats;
|
||||||
int RecvCount[_maxEmuOpcode];
|
int RecvCount[_maxEmuOpcode];
|
||||||
int SentCount[_maxEmuOpcode];
|
int SentCount[_maxEmuOpcode];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -177,6 +177,21 @@ void EQEmuConfig::parse_config()
|
|||||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||||
|
|
||||||
|
auto load_paths = [&](const std::string& key, std::vector<std::string>& target) {
|
||||||
|
const auto& paths = _root["server"]["directories"][key];
|
||||||
|
if (paths.isArray()) {
|
||||||
|
for (const auto& dir : paths) {
|
||||||
|
if (dir.isString()) {
|
||||||
|
target.push_back(dir.asString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
load_paths("quest_paths", m_quest_directories);
|
||||||
|
load_paths("plugin_paths", m_plugin_directories);
|
||||||
|
load_paths("lua_module_paths", m_lua_module_directories);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs
|
* Logs
|
||||||
*/
|
*/
|
||||||
@ -421,11 +436,11 @@ void EQEmuConfig::CheckUcsConfigConversion()
|
|||||||
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
|
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
|
||||||
|
|
||||||
std::string config_file_path = std::filesystem::path{
|
std::string config_file_path = std::filesystem::path{
|
||||||
path.GetServerPath() + "/eqemu_config.json"
|
PathManager::Instance()->GetServerPath() + "/eqemu_config.json"
|
||||||
}.string();
|
}.string();
|
||||||
|
|
||||||
std::string config_file_bak_path = std::filesystem::path{
|
std::string config_file_bak_path = std::filesystem::path{
|
||||||
path.GetServerPath() + "/eqemu_config.ucs-migrate-json.bak"
|
PathManager::Instance()->GetServerPath() + "/eqemu_config.ucs-migrate-json.bak"
|
||||||
}.string();
|
}.string();
|
||||||
|
|
||||||
// copy eqemu_config.json to eqemu_config.json.bak
|
// copy eqemu_config.json to eqemu_config.json.bak
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
#include "path_manager.h"
|
#include "path_manager.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
struct LoginConfig {
|
struct LoginConfig {
|
||||||
std::string LoginHost;
|
std::string LoginHost;
|
||||||
@ -120,6 +121,22 @@ class EQEmuConfig
|
|||||||
const std::string &GetUCSHost() const;
|
const std::string &GetUCSHost() const;
|
||||||
uint16 GetUCSPort() const;
|
uint16 GetUCSPort() const;
|
||||||
|
|
||||||
|
std::vector<std::string> GetQuestDirectories() const
|
||||||
|
{
|
||||||
|
return m_quest_directories;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> GetPluginsDirectories() const
|
||||||
|
{
|
||||||
|
return m_plugin_directories;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> GetLuaModuleDirectories() const
|
||||||
|
{
|
||||||
|
return m_lua_module_directories;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// uint16 DynamicCount;
|
// uint16 DynamicCount;
|
||||||
|
|
||||||
// map<string,uint16> StaticZones;
|
// map<string,uint16> StaticZones;
|
||||||
@ -133,6 +150,11 @@ class EQEmuConfig
|
|||||||
Json::Value _root;
|
Json::Value _root;
|
||||||
static std::string ConfigFile;
|
static std::string ConfigFile;
|
||||||
|
|
||||||
|
std::vector<std::string> m_quest_directories = {};
|
||||||
|
std::vector<std::string> m_plugin_directories = {};
|
||||||
|
std::vector<std::string> m_lua_module_directories = {};
|
||||||
|
|
||||||
|
protected:
|
||||||
void parse_config();
|
void parse_config();
|
||||||
|
|
||||||
EQEmuConfig()
|
EQEmuConfig()
|
||||||
@ -170,7 +192,7 @@ class EQEmuConfig
|
|||||||
|
|
||||||
std::string file = fmt::format(
|
std::string file = fmt::format(
|
||||||
"{}/{}",
|
"{}/{}",
|
||||||
(file_path.empty() ? path.GetServerPath() : file_path),
|
(file_path.empty() ? PathManager::Instance()->GetServerPath() : file_path),
|
||||||
EQEmuConfig::ConfigFile
|
EQEmuConfig::ConfigFile
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -537,9 +537,9 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
{
|
{
|
||||||
EQEmuLogSys::CloseFileLogs();
|
EQEmuLogSys::CloseFileLogs();
|
||||||
|
|
||||||
if (!File::Exists(path.GetLogPath())) {
|
if (!File::Exists(PathManager::Instance()->GetLogPath())) {
|
||||||
LogInfo("Logs directory not found, creating [{}]", path.GetLogPath());
|
LogInfo("Logs directory not found, creating [{}]", PathManager::Instance()->GetLogPath());
|
||||||
File::Makedir(path.GetLogPath());
|
File::Makedir(PathManager::Instance()->GetLogPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -656,7 +656,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings(bool silent_load)
|
|||||||
// If we go through this whole loop and nothing is set to any debug level, there
|
// If we go through this whole loop and nothing is set to any debug level, there
|
||||||
// is no point to create a file or keep anything open
|
// is no point to create a file or keep anything open
|
||||||
if (log_settings[c.log_category_id].log_to_file > 0) {
|
if (log_settings[c.log_category_id].log_to_file > 0) {
|
||||||
LogSys.m_file_logs_enabled = true;
|
m_file_logs_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
db_categories.emplace_back(c.log_category_id);
|
db_categories.emplace_back(c.log_category_id);
|
||||||
@ -682,14 +682,33 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings(bool silent_load)
|
|||||||
if (is_missing_in_database && !is_deprecated_category) {
|
if (is_missing_in_database && !is_deprecated_category) {
|
||||||
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
|
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
|
||||||
|
|
||||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
auto e = LogsysCategoriesRepository::NewEntity();
|
||||||
new_category.log_category_id = i;
|
e.log_category_id = i;
|
||||||
new_category.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
|
e.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
|
||||||
new_category.log_to_console = log_settings[i].log_to_console;
|
e.log_to_console = log_settings[i].log_to_console;
|
||||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
e.log_to_gmsay = log_settings[i].log_to_gmsay;
|
||||||
new_category.log_to_file = log_settings[i].log_to_file;
|
e.log_to_file = log_settings[i].log_to_file;
|
||||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
e.log_to_discord = log_settings[i].log_to_discord;
|
||||||
db_categories_to_add.emplace_back(new_category);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace Logs {
|
namespace Logs {
|
||||||
@ -194,8 +195,8 @@ namespace Logs {
|
|||||||
"Web Interface (Deprecated)",
|
"Web Interface (Deprecated)",
|
||||||
"World Server (Deprecated)",
|
"World Server (Deprecated)",
|
||||||
"Zone Server (Deprecated)",
|
"Zone Server (Deprecated)",
|
||||||
"QueryErr",
|
"MySQL Error",
|
||||||
"Query",
|
"MySQL Query",
|
||||||
"Mercenaries",
|
"Mercenaries",
|
||||||
"Quest Debug",
|
"Quest Debug",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Legacy Packet Logging (Deprecated)",
|
||||||
@ -211,15 +212,15 @@ namespace Logs {
|
|||||||
"Traps",
|
"Traps",
|
||||||
"NPC Roam Box",
|
"NPC Roam Box",
|
||||||
"NPC Scaling",
|
"NPC Scaling",
|
||||||
"MobAppearance",
|
"Mob Appearance",
|
||||||
"Info",
|
"Info",
|
||||||
"Warning",
|
"Warning",
|
||||||
"Critical (Deprecated)",
|
"Critical (Deprecated)",
|
||||||
"Emergency (Deprecated)",
|
"Emergency (Deprecated)",
|
||||||
"Alert (Deprecated)",
|
"Alert (Deprecated)",
|
||||||
"Notice (Deprecated)",
|
"Notice (Deprecated)",
|
||||||
"AI Scan",
|
"AI Scan Close",
|
||||||
"AI Yell",
|
"AI Yell For Help",
|
||||||
"AI CastBeneficial",
|
"AI CastBeneficial",
|
||||||
"AOE Cast",
|
"AOE Cast",
|
||||||
"Entity Management",
|
"Entity Management",
|
||||||
@ -237,7 +238,7 @@ namespace Logs {
|
|||||||
"DialogueWindow",
|
"DialogueWindow",
|
||||||
"HTTP",
|
"HTTP",
|
||||||
"Saylink",
|
"Saylink",
|
||||||
"ChecksumVer",
|
"Checksum Verification",
|
||||||
"CombatRecord",
|
"CombatRecord",
|
||||||
"Hate",
|
"Hate",
|
||||||
"Discord",
|
"Discord",
|
||||||
@ -266,8 +267,6 @@ namespace Logs {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "eqemu_logsys_log_aliases.h"
|
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
|
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
|
||||||
@ -285,6 +284,12 @@ public:
|
|||||||
EQEmuLogSys *LoadLogSettingsDefaults();
|
EQEmuLogSys *LoadLogSettingsDefaults();
|
||||||
EQEmuLogSys *LoadLogDatabaseSettings(bool silent_load = false);
|
EQEmuLogSys *LoadLogDatabaseSettings(bool silent_load = false);
|
||||||
|
|
||||||
|
static EQEmuLogSys *Instance()
|
||||||
|
{
|
||||||
|
static EQEmuLogSys instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param directory_name
|
* @param directory_name
|
||||||
*/
|
*/
|
||||||
@ -350,7 +355,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Internally used memory reference for all log settings per category
|
* Internally used memory reference for all log settings per category
|
||||||
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
||||||
* Database loaded via LogSys.SetDatabase(&database)->LoadLogDatabaseSettings();
|
* Database loaded via EQEmuLogSys::Instance()->SetDatabase(&database)->LoadLogDatabaseSettings();
|
||||||
*/
|
*/
|
||||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||||
|
|
||||||
@ -434,7 +439,7 @@ private:
|
|||||||
void InjectTablesIfNotExist();
|
void InjectTablesIfNotExist();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EQEmuLogSys LogSys;
|
#include "eqemu_logsys_log_aliases.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@ -456,7 +461,7 @@ void OutF(
|
|||||||
|
|
||||||
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
|
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
|
||||||
do { \
|
do { \
|
||||||
ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
|
ls->Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
|||||||
#include "../json/json_archive_single_line.h"
|
#include "../json/json_archive_single_line.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include <cereal/archives/json.hpp>
|
#include <cereal/archives/json.hpp>
|
||||||
#include <cereal/types/vector.hpp>
|
#include <cereal/types/vector.hpp>
|
||||||
|
|
||||||
@ -716,7 +717,7 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (int i = 0; i < h.augment_ids.size(); i++) {
|
for (int i = 0; i < h.augment_ids.size(); i++) {
|
||||||
if (!Strings::EqualFold(h.augment_names[i], "None")) {
|
if (!h.augment_names[i].empty()) {
|
||||||
const uint8 slot_id = (i + 1);
|
const uint8 slot_id = (i + 1);
|
||||||
handin_items_info += fmt::format(
|
handin_items_info += fmt::format(
|
||||||
"Augment {}: {} ({})\n",
|
"Augment {}: {} ({})\n",
|
||||||
@ -741,7 +742,7 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (int i = 0; i < r.augment_ids.size(); i++) {
|
for (int i = 0; i < r.augment_ids.size(); i++) {
|
||||||
if (!Strings::EqualFold(r.augment_names[i], "None")) {
|
if (!r.augment_names[i].empty()) {
|
||||||
const uint8 slot_id = (i + 1);
|
const uint8 slot_id = (i + 1);
|
||||||
return_items_info += fmt::format(
|
return_items_info += fmt::format(
|
||||||
"Augment {}: {} ({})\n",
|
"Augment {}: {} ({})\n",
|
||||||
|
|||||||
@ -15,9 +15,9 @@ const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1
|
|||||||
// general initialization routine
|
// general initialization routine
|
||||||
void PlayerEventLogs::Init()
|
void PlayerEventLogs::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
||||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
||||||
|
m_database_ping_timer.SetTimer(10 * 1000); // 10 seconds
|
||||||
|
|
||||||
ValidateDatabaseConnection();
|
ValidateDatabaseConnection();
|
||||||
|
|
||||||
@ -195,10 +195,12 @@ void PlayerEventLogs::ProcessBatchQueue()
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper to assign ETL table ID
|
// Helper to assign ETL table ID
|
||||||
auto AssignEtlId = [&](
|
|
||||||
PlayerEventLogsRepository::PlayerEventLogs &r,
|
auto AssignEtlId = [&](
|
||||||
PlayerEvent::EventType type
|
PlayerEventLogsRepository::PlayerEventLogs& r,
|
||||||
) {
|
PlayerEvent::EventType type
|
||||||
|
)
|
||||||
|
{
|
||||||
if (m_etl_settings.contains(type)) {
|
if (m_etl_settings.contains(type)) {
|
||||||
r.etl_table_id = m_etl_settings.at(type).next_id++;
|
r.etl_table_id = m_etl_settings.at(type).next_id++;
|
||||||
}
|
}
|
||||||
@ -406,7 +408,6 @@ void PlayerEventLogs::ProcessBatchQueue()
|
|||||||
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
|
auto it = event_processors.find(static_cast<PlayerEvent::EventType>(r.event_type_id));
|
||||||
if (it != event_processors.end()) {
|
if (it != event_processors.end()) {
|
||||||
it->second(r); // Call the appropriate lambda
|
it->second(r); // Call the appropriate lambda
|
||||||
r.event_data = "{}"; // Clear event data
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id);
|
LogPlayerEventsDetail("Non-Implemented ETL routing [{}]", r.event_type_id);
|
||||||
@ -508,7 +509,7 @@ bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure there is a matching webhook to begin with
|
// ensure there is a matching webhook to begin with
|
||||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
if (!EQEmuLogSys::Instance()->GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,13 +529,27 @@ std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure there is a matching webhook to begin with
|
// ensure there is a matching webhook to begin with
|
||||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
if (!EQEmuLogSys::Instance()->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 EQEmuLogSys::Instance()->GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerEventLogs::LoadPlayerEventSettingsFromQS(
|
||||||
|
const std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> &settings
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (const auto &e : settings) {
|
||||||
|
if (e.id >= PlayerEvent::MAX || e.id < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_settings[e.id] = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo("Applied [{}] player event log settings from QS", settings.size());
|
||||||
|
}
|
||||||
|
|
||||||
// GM_COMMAND | [x] Implemented Formatter
|
// GM_COMMAND | [x] Implemented Formatter
|
||||||
// ZONING | [x] Implemented Formatter
|
// ZONING | [x] Implemented Formatter
|
||||||
// AA_GAIN | [x] Implemented Formatter
|
// AA_GAIN | [x] Implemented Formatter
|
||||||
@ -916,6 +931,10 @@ std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::Playe
|
|||||||
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
||||||
void PlayerEventLogs::Process()
|
void PlayerEventLogs::Process()
|
||||||
{
|
{
|
||||||
|
if (m_database_ping_timer.Check()) {
|
||||||
|
m_database->ping();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_process_batch_events_timer.Check() ||
|
if (m_process_batch_events_timer.Check() ||
|
||||||
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
||||||
ProcessBatchQueue();
|
ProcessBatchQueue();
|
||||||
|
|||||||
@ -73,9 +73,11 @@ public:
|
|||||||
return BuildPlayerEventPacket(c);
|
return BuildPlayerEventPacket(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
|
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings * GetSettings() const;
|
||||||
bool IsEventDiscordEnabled(int32_t event_type_id);
|
bool IsEventDiscordEnabled(int32_t event_type_id);
|
||||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
||||||
|
|
||||||
|
void LoadPlayerEventSettingsFromQS(const std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings>& settings);
|
||||||
|
|
||||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
||||||
|
|
||||||
@ -94,6 +96,12 @@ public:
|
|||||||
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
|
std::vector<PlayerEventAaPurchaseRepository::PlayerEventAaPurchase> aa_purchase;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PlayerEventLogs* Instance()
|
||||||
|
{
|
||||||
|
static PlayerEventLogs instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct EtlSettings {
|
struct EtlSettings {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
@ -113,6 +121,7 @@ private:
|
|||||||
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
|
std::map<PlayerEvent::EventType, EtlSettings> m_etl_settings{};
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
|
Timer m_database_ping_timer; // database ping timer
|
||||||
Timer m_process_batch_events_timer; // events processing timer
|
Timer m_process_batch_events_timer; // events processing timer
|
||||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
||||||
|
|
||||||
@ -126,6 +135,4 @@ public:
|
|||||||
std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;}
|
std::map<PlayerEvent::EventType, EtlSettings> &GetEtlSettings() { return m_etl_settings;}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PlayerEventLogs player_event_logs;
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -21,8 +21,8 @@ void EvolvingItemsManager::LoadEvolvingItems() const
|
|||||||
results.begin(),
|
results.begin(),
|
||||||
results.end(),
|
results.end(),
|
||||||
std::inserter(
|
std::inserter(
|
||||||
evolving_items_manager.GetEvolvingItemsCache(),
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache(),
|
||||||
evolving_items_manager.GetEvolvingItemsCache().end()
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().end()
|
||||||
),
|
),
|
||||||
[](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &x) {
|
[](const ItemsEvolvingDetailsRepository::ItemsEvolvingDetails &x) {
|
||||||
return std::make_pair(x.item_id, x);
|
return std::make_pair(x.item_id, x);
|
||||||
@ -42,13 +42,13 @@ void EvolvingItemsManager::SetContentDatabase(Database *db)
|
|||||||
|
|
||||||
double EvolvingItemsManager::CalculateProgression(const uint64 current_amount, const uint32 item_id)
|
double EvolvingItemsManager::CalculateProgression(const uint64 current_amount, const uint32 item_id)
|
||||||
{
|
{
|
||||||
if (!evolving_items_manager.GetEvolvingItemsCache().contains(item_id)) {
|
if (!EvolvingItemsManager::Instance()->GetEvolvingItemsCache().contains(item_id)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount > 0
|
return EvolvingItemsManager::Instance()->GetEvolvingItemsCache().at(item_id).required_amount > 0
|
||||||
? static_cast<double>(current_amount)
|
? static_cast<double>(current_amount)
|
||||||
/ static_cast<double>(evolving_items_manager.GetEvolvingItemsCache().at(item_id).required_amount) * 100
|
/ static_cast<double>(EvolvingItemsManager::Instance()->GetEvolvingItemsCache().at(item_id).required_amount) * 100
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,11 @@ void EvolvingItemsManager::DoLootChecks(const uint32 char_id, const uint16 slot_
|
|||||||
e.character_id = char_id;
|
e.character_id = char_id;
|
||||||
e.item_id = inst.GetID();
|
e.item_id = inst.GetID();
|
||||||
e.equipped = inst.GetEvolveEquipped();
|
e.equipped = inst.GetEvolveEquipped();
|
||||||
e.final_item_id = evolving_items_manager.GetFinalItemID(inst);
|
e.final_item_id = EvolvingItemsManager::Instance()->GetFinalItemID(inst);
|
||||||
|
if (inst.GetEvolveCurrentAmount() > 0) {
|
||||||
|
e.current_amount = inst.GetEvolveCurrentAmount();
|
||||||
|
inst.CalculateEvolveProgression();
|
||||||
|
}
|
||||||
|
|
||||||
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
auto r = CharacterEvolvingItemsRepository::InsertOne(*m_db, e);
|
||||||
e.id = r.id;
|
e.id = r.id;
|
||||||
@ -96,20 +100,20 @@ uint32 EvolvingItemsManager::GetFinalItemID(const EQ::ItemInstance &inst) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto start_iterator = std::ranges::find_if(
|
const auto start_iterator = std::ranges::find_if(
|
||||||
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cbegin(),
|
||||||
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(),
|
||||||
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
||||||
return a.second.item_evo_id == inst.GetEvolveLoreID();
|
return a.second.item_evo_id == inst.GetEvolveLoreID();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (start_iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
|
if (start_iterator == std::end(EvolvingItemsManager::Instance()->GetEvolvingItemsCache())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto final_id = std::ranges::max_element(
|
const auto final_id = std::ranges::max_element(
|
||||||
start_iterator,
|
start_iterator,
|
||||||
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(),
|
||||||
[&](
|
[&](
|
||||||
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a,
|
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a,
|
||||||
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &b
|
const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &b
|
||||||
@ -131,15 +135,15 @@ uint32 EvolvingItemsManager::GetNextEvolveItemID(const EQ::ItemInstance &inst) c
|
|||||||
int8 const current_level = inst.GetEvolveLvl();
|
int8 const current_level = inst.GetEvolveLvl();
|
||||||
|
|
||||||
const auto iterator = std::ranges::find_if(
|
const auto iterator = std::ranges::find_if(
|
||||||
evolving_items_manager.GetEvolvingItemsCache().cbegin(),
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cbegin(),
|
||||||
evolving_items_manager.GetEvolvingItemsCache().cend(),
|
EvolvingItemsManager::Instance()->GetEvolvingItemsCache().cend(),
|
||||||
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
[&](const std::pair<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> &a) {
|
||||||
return a.second.item_evo_id == inst.GetEvolveLoreID() &&
|
return a.second.item_evo_id == inst.GetEvolveLoreID() &&
|
||||||
a.second.item_evolve_level == current_level + 1;
|
a.second.item_evolve_level == current_level + 1;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (iterator == std::end(evolving_items_manager.GetEvolvingItemsCache())) {
|
if (iterator == std::end(EvolvingItemsManager::Instance()->GetEvolvingItemsCache())) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,8 +259,8 @@ EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
|
|||||||
return ets;
|
return ets;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evolving_details_inst_from = evolving_items_manager.GetEvolveItemDetails(inst_from.GetID());
|
auto evolving_details_inst_from = EvolvingItemsManager::Instance()->GetEvolveItemDetails(inst_from.GetID());
|
||||||
auto evolving_details_inst_to = evolving_items_manager.GetEvolveItemDetails(inst_to.GetID());
|
auto evolving_details_inst_to = EvolvingItemsManager::Instance()->GetEvolveItemDetails(inst_to.GetID());
|
||||||
|
|
||||||
if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) {
|
if (!evolving_details_inst_from.id || !evolving_details_inst_to.id) {
|
||||||
return ets;
|
return ets;
|
||||||
@ -272,10 +276,10 @@ EvolveTransfer EvolvingItemsManager::DetermineTransferResults(
|
|||||||
compatibility = 30;
|
compatibility = 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
xp = evolving_items_manager.GetTotalEarnedXP(inst_from) * compatibility / 100;
|
xp = EvolvingItemsManager::Instance()->GetTotalEarnedXP(inst_from) * compatibility / 100;
|
||||||
auto results = evolving_items_manager.GetNextItemByXP(inst_to, xp);
|
auto results = EvolvingItemsManager::Instance()->GetNextItemByXP(inst_to, xp);
|
||||||
|
|
||||||
ets.item_from_id = evolving_items_manager.GetFirstItemInLoreGroup(inst_from.GetEvolveLoreID());
|
ets.item_from_id = EvolvingItemsManager::Instance()->GetFirstItemInLoreGroup(inst_from.GetEvolveLoreID());
|
||||||
ets.item_from_current_amount = results.from_current_amount;
|
ets.item_from_current_amount = results.from_current_amount;
|
||||||
ets.item_to_id = results.new_item_id;
|
ets.item_to_id = results.new_item_id;
|
||||||
ets.item_to_current_amount = results.new_current_amount;
|
ets.item_to_current_amount = results.new_current_amount;
|
||||||
|
|||||||
@ -56,12 +56,15 @@ public:
|
|||||||
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails>& GetEvolvingItemsCache() { return m_evolving_items_cache; }
|
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails>& GetEvolvingItemsCache() { return m_evolving_items_cache; }
|
||||||
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id);
|
std::vector<ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> GetEvolveIDItems(uint32 evolve_id);
|
||||||
|
|
||||||
|
static EvolvingItemsManager* Instance()
|
||||||
|
{
|
||||||
|
static EvolvingItemsManager instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> m_evolving_items_cache;
|
std::map<uint32, ItemsEvolvingDetailsRepository::ItemsEvolvingDetails> m_evolving_items_cache;
|
||||||
Database * m_db;
|
Database * m_db;
|
||||||
Database * m_content_db;
|
Database * m_content_db;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EvolvingItemsManager evolving_items_manager;
|
|
||||||
|
|
||||||
#endif //EVOLVING_H
|
#endif //EVOLVING_H
|
||||||
|
|||||||
@ -95,12 +95,12 @@ bool IsOfEqualRace(int r1, int r2)
|
|||||||
}
|
}
|
||||||
// TODO: add more values
|
// TODO: add more values
|
||||||
switch (r1) {
|
switch (r1) {
|
||||||
case DARK_ELF:
|
case Race::DarkElf:
|
||||||
if (r2 == Race::NeriakCitizen) {
|
if (r2 == Race::NeriakCitizen) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BARBARIAN:
|
case Race::Barbarian:
|
||||||
if (r2 == Race::HalasCitizen) {
|
if (r2 == Race::HalasCitizen) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -116,49 +116,49 @@ bool IsOfIndiffRace(int r1, int r2)
|
|||||||
}
|
}
|
||||||
// TODO: add more values
|
// TODO: add more values
|
||||||
switch (r1) {
|
switch (r1) {
|
||||||
case DARK_ELF:
|
case Race::DarkElf:
|
||||||
case OGRE:
|
case Race::Ogre:
|
||||||
case TROLL:
|
case Race::Troll:
|
||||||
if (r2 == OGRE || r2 == TROLL || r2 == DARK_ELF) {
|
if (r2 == Race::Ogre || r2 == Race::Troll || r2 == Race::DarkElf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HUMAN:
|
case Race::Human:
|
||||||
case BARBARIAN:
|
case Race::Barbarian:
|
||||||
case HALF_ELF:
|
case Race::HalfElf:
|
||||||
case GNOME:
|
case Race::Gnome:
|
||||||
case HALFLING:
|
case Race::Halfling:
|
||||||
case WOOD_ELF:
|
case Race::WoodElf:
|
||||||
if (r2 == HUMAN ||
|
if (r2 == Race::Human ||
|
||||||
r2 == BARBARIAN ||
|
r2 == Race::Barbarian ||
|
||||||
r2 == ERUDITE ||
|
r2 == Race::Erudite ||
|
||||||
r2 == HALF_ELF ||
|
r2 == Race::HalfElf ||
|
||||||
r2 == GNOME ||
|
r2 == Race::Gnome ||
|
||||||
r2 == HALFLING ||
|
r2 == Race::Halfling ||
|
||||||
r2 == DWARF ||
|
r2 == Race::Dwarf ||
|
||||||
r2 == HIGH_ELF ||
|
r2 == Race::HighElf ||
|
||||||
r2 == WOOD_ELF) {
|
r2 == Race::WoodElf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ERUDITE:
|
case Race::Erudite:
|
||||||
if (r2 == HUMAN || r2 == HALF_ELF) {
|
if (r2 == Race::Human || r2 == Race::HalfElf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DWARF:
|
case Race::Dwarf:
|
||||||
if (r2 == HALFLING || r2 == GNOME) {
|
if (r2 == Race::Halfling || r2 == Race::Gnome) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIGH_ELF:
|
case Race::HighElf:
|
||||||
if (r2 == WOOD_ELF) {
|
if (r2 == Race::WoodElf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VAHSHIR:
|
case Race::VahShir:
|
||||||
return true;
|
return true;
|
||||||
case IKSAR:
|
case Race::Iksar:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -36,6 +36,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "ip_util.h"
|
#include "ip_util.h"
|
||||||
|
|||||||
@ -55,7 +55,7 @@ namespace EQ {
|
|||||||
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
|
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::string final_name = fmt::format("{}/{}.lock", path.GetSharedMemoryPath(), name);
|
std::string final_name = fmt::format("{}/{}.lock", PathManager::Instance()->GetSharedMemoryPath(), name);
|
||||||
|
|
||||||
#ifdef __DARWIN
|
#ifdef __DARWIN
|
||||||
#if __DARWIN_C_LEVEL < 200809L
|
#if __DARWIN_C_LEVEL < 200809L
|
||||||
|
|||||||
@ -438,7 +438,7 @@ namespace EQ
|
|||||||
//uint32 Unk054 {};
|
//uint32 Unk054 {};
|
||||||
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
|
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
|
||||||
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
|
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
|
||||||
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SpellEffect::FFItemClass)
|
||||||
uint8 Material {}; // Item material type
|
uint8 Material {}; // Item material type
|
||||||
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
|
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
|
||||||
float SellRate {}; // Sell rate
|
float SellRate {}; // Sell rate
|
||||||
|
|||||||
@ -1,206 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
@ -574,7 +574,7 @@ EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
|
|||||||
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
|
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
|
||||||
{
|
{
|
||||||
// Not a Hero Forge item.
|
// Not a Hero Forge item.
|
||||||
if (m_ornament_hero_model == 0 || material_slot < 0) {
|
if (m_ornament_hero_model == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1799,7 +1799,7 @@ std::vector<std::string> EQ::ItemInstance::GetAugmentNames() const
|
|||||||
|
|
||||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
|
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; slot_id++) {
|
||||||
const auto augment = GetAugment(slot_id);
|
const auto augment = GetAugment(slot_id);
|
||||||
augment_names.push_back(augment ? augment->GetItem()->Name : "None");
|
augment_names.push_back(augment ? augment->GetItem()->Name : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
return augment_names;
|
return augment_names;
|
||||||
|
|||||||
@ -335,7 +335,7 @@ namespace EQ
|
|||||||
void SetEvolveAddToCurrentAmount(const uint64 in) const { m_evolving_details.current_amount += in; }
|
void SetEvolveAddToCurrentAmount(const uint64 in) const { m_evolving_details.current_amount += in; }
|
||||||
void SetEvolveFinalItemID(const uint32 in) const { m_evolving_details.final_item_id = in; }
|
void SetEvolveFinalItemID(const uint32 in) const { m_evolving_details.final_item_id = in; }
|
||||||
bool TransferOwnership(Database& db, const uint32 to_char_id) const;
|
bool TransferOwnership(Database& db, const uint32 to_char_id) const;
|
||||||
void CalculateEvolveProgression() const { m_evolving_details.progression = evolving_items_manager.CalculateProgression(GetEvolveCurrentAmount(), GetID()); }
|
void CalculateEvolveProgression() const { m_evolving_details.progression = EvolvingItemsManager::Instance()->CalculateProgression(GetEvolveCurrentAmount(), GetID()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "console_server.h"
|
#include "console_server.h"
|
||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
|
EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "../servertalk.h"
|
#include "../servertalk.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent, std::shared_ptr<TCPConnection> connection)
|
EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent, std::shared_ptr<TCPConnection> connection)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
#include "eqstream.h"
|
#include "eqstream.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
|
|
||||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
|
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_reliable_stream(options.reliable_stream_options)
|
||||||
{
|
{
|
||||||
m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
|
m_reliable_stream.OnNewConnection(std::bind(&EQStreamManager::ReliableStreamNewConnection, this, std::placeholders::_1));
|
||||||
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
m_reliable_stream.OnConnectionStateChange(std::bind(&EQStreamManager::ReliableStreamConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
m_reliable_stream.OnPacketRecv(std::bind(&EQStreamManager::ReliableStreamPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::EQStreamManager::~EQStreamManager()
|
EQ::Net::EQStreamManager::~EQStreamManager()
|
||||||
@ -15,11 +15,11 @@ EQ::Net::EQStreamManager::~EQStreamManager()
|
|||||||
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
|
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
|
||||||
{
|
{
|
||||||
m_options = options;
|
m_options = options;
|
||||||
auto &opts = m_daybreak.GetOptions();
|
auto &opts = m_reliable_stream.GetOptions();
|
||||||
opts = options.daybreak_options;
|
opts = options.reliable_stream_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
void EQ::Net::EQStreamManager::ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection)
|
||||||
{
|
{
|
||||||
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
||||||
m_streams.emplace(std::make_pair(connection, stream));
|
m_streams.emplace(std::make_pair(connection, stream));
|
||||||
@ -28,7 +28,7 @@ void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakCon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
void EQ::Net::EQStreamManager::ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||||
{
|
{
|
||||||
auto iter = m_streams.find(connection);
|
auto iter = m_streams.find(connection);
|
||||||
if (iter != m_streams.end()) {
|
if (iter != m_streams.end()) {
|
||||||
@ -42,7 +42,7 @@ void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<Day
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
|
void EQ::Net::EQStreamManager::ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p)
|
||||||
{
|
{
|
||||||
auto iter = m_streams.find(connection);
|
auto iter = m_streams.find(connection);
|
||||||
if (iter != m_streams.end()) {
|
if (iter != m_streams.end()) {
|
||||||
@ -53,7 +53,7 @@ void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<DaybreakConnection> connection)
|
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<ReliableStreamConnection> connection)
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_connection = connection;
|
m_connection = connection;
|
||||||
@ -71,7 +71,7 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
|
|||||||
OpcodeManager::EmuToName(p->GetOpcode()),
|
OpcodeManager::EmuToName(p->GetOpcode()),
|
||||||
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
|
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
|
||||||
p->Size(),
|
p->Size(),
|
||||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
|
(EQEmuLogSys::Instance()->IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
|
||||||
);
|
);
|
||||||
|
|
||||||
if (m_opcode_manager && *m_opcode_manager) {
|
if (m_opcode_manager && *m_opcode_manager) {
|
||||||
@ -235,7 +235,7 @@ EQStreamState EQ::Net::EQStream::GetState() {
|
|||||||
EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
|
EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
|
||||||
{
|
{
|
||||||
Stats ret;
|
Stats ret;
|
||||||
ret.DaybreakStats = m_connection->GetStats();
|
ret.ReliableStreamStats = m_connection->GetStats();
|
||||||
|
|
||||||
for (int i = 0; i < _maxEmuOpcode; ++i) {
|
for (int i = 0; i < _maxEmuOpcode; ++i) {
|
||||||
ret.RecvCount[i] = 0;
|
ret.RecvCount[i] = 0;
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
#include "../eq_packet.h"
|
#include "../eq_packet.h"
|
||||||
#include "../eq_stream_intf.h"
|
#include "../eq_stream_intf.h"
|
||||||
#include "../opcodemgr.h"
|
#include "../opcodemgr.h"
|
||||||
#include "daybreak_connection.h"
|
#include "reliable_stream_connection.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -23,21 +23,21 @@ namespace EQ
|
|||||||
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
|
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
|
||||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||||
private:
|
private:
|
||||||
DaybreakConnectionManager m_daybreak;
|
ReliableStreamConnectionManager m_reliable_stream;
|
||||||
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
|
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
|
||||||
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||||
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
|
std::map<std::shared_ptr<ReliableStreamConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||||
|
|
||||||
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
void ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection);
|
||||||
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
void ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||||
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
|
void ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p);
|
||||||
friend class EQStream;
|
friend class EQStream;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EQStream : public EQStreamInterface
|
class EQStream : public EQStreamInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<DaybreakConnection> connection);
|
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<ReliableStreamConnection> connection);
|
||||||
~EQStream();
|
~EQStream();
|
||||||
|
|
||||||
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
|
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
|
||||||
@ -67,7 +67,7 @@ namespace EQ
|
|||||||
virtual EQStreamManagerInterface* GetManager() const;
|
virtual EQStreamManagerInterface* GetManager() const;
|
||||||
private:
|
private:
|
||||||
EQStreamManagerInterface *m_owner;
|
EQStreamManagerInterface *m_owner;
|
||||||
std::shared_ptr<DaybreakConnection> m_connection;
|
std::shared_ptr<ReliableStreamConnection> m_connection;
|
||||||
OpcodeManager **m_opcode_manager;
|
OpcodeManager **m_opcode_manager;
|
||||||
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
||||||
std::unordered_map<int, int> m_packet_recv_count;
|
std::unordered_map<int, int> m_packet_recv_count;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "endian.h"
|
#include "endian.h"
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
void EQ::Net::Packet::PutInt8(size_t offset, int8_t value)
|
void EQ::Net::Packet::PutInt8(size_t offset, int8_t value)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
#include "daybreak_connection.h"
|
#include "reliable_stream_connection.h"
|
||||||
#include "../event/event_loop.h"
|
#include "../event/event_loop.h"
|
||||||
#include "../data_verification.h"
|
#include "../data_verification.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
// observed client receive window is 300 packets, 140KB
|
// observed client receive window is 300 packets, 140KB
|
||||||
constexpr size_t MAX_CLIENT_RECV_PACKETS_PER_WINDOW = 300;
|
constexpr size_t MAX_CLIENT_RECV_PACKETS_PER_WINDOW = 300;
|
||||||
@ -12,7 +13,7 @@ constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
|
|||||||
// buffer pools
|
// buffer pools
|
||||||
SendBufferPool send_buffer_pool;
|
SendBufferPool send_buffer_pool;
|
||||||
|
|
||||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager()
|
||||||
{
|
{
|
||||||
m_attached = nullptr;
|
m_attached = nullptr;
|
||||||
memset(&m_timer, 0, sizeof(uv_timer_t));
|
memset(&m_timer, 0, sizeof(uv_timer_t));
|
||||||
@ -21,7 +22,7 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
|||||||
Attach(EQ::EventLoop::Get().Handle());
|
Attach(EQ::EventLoop::Get().Handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
|
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts)
|
||||||
{
|
{
|
||||||
m_attached = nullptr;
|
m_attached = nullptr;
|
||||||
m_options = opts;
|
m_options = opts;
|
||||||
@ -31,12 +32,12 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConn
|
|||||||
Attach(EQ::EventLoop::Get().Handle());
|
Attach(EQ::EventLoop::Get().Handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
|
EQ::Net::ReliableStreamConnectionManager::~ReliableStreamConnectionManager()
|
||||||
{
|
{
|
||||||
Detach();
|
Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
|
||||||
{
|
{
|
||||||
if (!m_attached) {
|
if (!m_attached) {
|
||||||
uv_timer_init(loop, &m_timer);
|
uv_timer_init(loop, &m_timer);
|
||||||
@ -45,7 +46,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
|||||||
auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz);
|
auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz);
|
||||||
|
|
||||||
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
|
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
|
||||||
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
|
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
|
||||||
c->UpdateDataBudget();
|
c->UpdateDataBudget();
|
||||||
c->Process();
|
c->Process();
|
||||||
c->ProcessResend();
|
c->ProcessResend();
|
||||||
@ -71,7 +72,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
|||||||
buf->len = 65536;
|
buf->len = 65536;
|
||||||
},
|
},
|
||||||
[](uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) {
|
[](uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) {
|
||||||
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
|
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
|
||||||
if (nread < 0 || addr == nullptr) {
|
if (nread < 0 || addr == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -90,7 +91,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::Detach()
|
void EQ::Net::ReliableStreamConnectionManager::Detach()
|
||||||
{
|
{
|
||||||
if (m_attached) {
|
if (m_attached) {
|
||||||
uv_udp_recv_stop(&m_socket);
|
uv_udp_recv_stop(&m_socket);
|
||||||
@ -99,11 +100,11 @@ void EQ::Net::DaybreakConnectionManager::Detach()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int port)
|
void EQ::Net::ReliableStreamConnectionManager::Connect(const std::string &addr, int port)
|
||||||
{
|
{
|
||||||
//todo dns resolution
|
//todo dns resolution
|
||||||
|
|
||||||
auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, addr, port));
|
auto connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, addr, port));
|
||||||
connection->m_self = connection;
|
connection->m_self = connection;
|
||||||
|
|
||||||
if (m_on_new_connection) {
|
if (m_on_new_connection) {
|
||||||
@ -113,7 +114,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
|
|||||||
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
|
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::Process()
|
void EQ::Net::ReliableStreamConnectionManager::Process()
|
||||||
{
|
{
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
auto iter = m_connections.begin();
|
auto iter = m_connections.begin();
|
||||||
@ -177,7 +178,7 @@ void EQ::Net::DaybreakConnectionManager::Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
|
void EQ::Net::ReliableStreamConnectionManager::UpdateDataBudget()
|
||||||
{
|
{
|
||||||
auto outgoing_data_rate = m_options.outgoing_data_rate;
|
auto outgoing_data_rate = m_options.outgoing_data_rate;
|
||||||
if (outgoing_data_rate <= 0.0) {
|
if (outgoing_data_rate <= 0.0) {
|
||||||
@ -196,7 +197,7 @@ void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
void EQ::Net::ReliableStreamConnectionManager::ProcessResend()
|
||||||
{
|
{
|
||||||
auto iter = m_connections.begin();
|
auto iter = m_connections.begin();
|
||||||
while (iter != m_connections.end()) {
|
while (iter != m_connections.end()) {
|
||||||
@ -217,15 +218,15 @@ void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
|
void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
|
||||||
{
|
{
|
||||||
if (m_options.simulated_in_packet_loss && m_options.simulated_in_packet_loss >= m_rand.Int(0, 100)) {
|
if (m_options.simulated_in_packet_loss && m_options.simulated_in_packet_loss >= m_rand.Int(0, 100)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < DaybreakHeader::size()) {
|
if (size < ReliableStreamHeader::size()) {
|
||||||
if (m_on_error_message) {
|
if (m_on_error_message) {
|
||||||
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, DaybreakHeader::size()));
|
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, ReliableStreamHeader::size()));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -239,9 +240,9 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
|||||||
else {
|
else {
|
||||||
if (data[0] == 0 && data[1] == OP_SessionRequest) {
|
if (data[0] == 0 && data[1] == OP_SessionRequest) {
|
||||||
StaticPacket p((void*)data, size);
|
StaticPacket p((void*)data, size);
|
||||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
auto request = p.GetSerialize<ReliableStreamConnect>(0);
|
||||||
|
|
||||||
connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, request, endpoint, port));
|
connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, request, endpoint, port));
|
||||||
connection->m_self = connection;
|
connection->m_self = connection;
|
||||||
|
|
||||||
if (m_on_new_connection) {
|
if (m_on_new_connection) {
|
||||||
@ -262,7 +263,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
|
std::shared_ptr<EQ::Net::ReliableStreamConnection> EQ::Net::ReliableStreamConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
|
||||||
{
|
{
|
||||||
auto p = std::make_pair(addr, port);
|
auto p = std::make_pair(addr, port);
|
||||||
auto iter = m_connections.find(p);
|
auto iter = m_connections.find(p);
|
||||||
@ -273,9 +274,9 @@ std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr, int port)
|
void EQ::Net::ReliableStreamConnectionManager::SendDisconnect(const std::string &addr, int port)
|
||||||
{
|
{
|
||||||
DaybreakDisconnect header;
|
ReliableStreamDisconnect header;
|
||||||
header.zero = 0;
|
header.zero = 0;
|
||||||
header.opcode = OP_OutOfSession;
|
header.opcode = OP_OutOfSession;
|
||||||
header.connect_code = 0;
|
header.connect_code = 0;
|
||||||
@ -300,7 +301,7 @@ void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
//new connection made as server
|
//new connection made as server
|
||||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port)
|
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port)
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_last_send = Clock::now();
|
m_last_send = Clock::now();
|
||||||
@ -327,7 +328,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
|||||||
}
|
}
|
||||||
|
|
||||||
//new connection made as client
|
//new connection made as client
|
||||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port)
|
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port)
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
m_last_send = Clock::now();
|
m_last_send = Clock::now();
|
||||||
@ -349,11 +350,11 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
|||||||
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnection::~DaybreakConnection()
|
EQ::Net::ReliableStreamConnection::~ReliableStreamConnection()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Close()
|
void EQ::Net::ReliableStreamConnection::Close()
|
||||||
{
|
{
|
||||||
if (m_status != StatusDisconnected && m_status != StatusDisconnecting) {
|
if (m_status != StatusDisconnected && m_status != StatusDisconnecting) {
|
||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
@ -367,17 +368,17 @@ void EQ::Net::DaybreakConnection::Close()
|
|||||||
ChangeStatus(StatusDisconnecting);
|
ChangeStatus(StatusDisconnecting);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p)
|
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p)
|
||||||
{
|
{
|
||||||
QueuePacket(p, 0, true);
|
QueuePacket(p, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream)
|
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream)
|
||||||
{
|
{
|
||||||
QueuePacket(p, stream, true);
|
QueuePacket(p, stream, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliable)
|
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream, bool reliable)
|
||||||
{
|
{
|
||||||
if (*(char*)p.Data() == 0) {
|
if (*(char*)p.Data() == 0) {
|
||||||
DynamicPacket packet;
|
DynamicPacket packet;
|
||||||
@ -390,21 +391,21 @@ void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliab
|
|||||||
InternalQueuePacket(p, stream, reliable);
|
InternalQueuePacket(p, stream, reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnectionStats EQ::Net::DaybreakConnection::GetStats()
|
EQ::Net::ReliableStreamConnectionStats EQ::Net::ReliableStreamConnection::GetStats()
|
||||||
{
|
{
|
||||||
EQ::Net::DaybreakConnectionStats ret = m_stats;
|
EQ::Net::ReliableStreamConnectionStats ret = m_stats;
|
||||||
ret.datarate_remaining = m_outgoing_budget;
|
ret.datarate_remaining = m_outgoing_budget;
|
||||||
ret.avg_ping = m_rolling_ping;
|
ret.avg_ping = m_rolling_ping;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ResetStats()
|
void EQ::Net::ReliableStreamConnection::ResetStats()
|
||||||
{
|
{
|
||||||
m_stats.Reset();
|
m_stats.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Process()
|
void EQ::Net::ReliableStreamConnection::Process()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
@ -422,7 +423,7 @@ void EQ::Net::DaybreakConnection::Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
|
||||||
{
|
{
|
||||||
m_last_recv = Clock::now();
|
m_last_recv = Clock::now();
|
||||||
m_stats.recv_packets++;
|
m_stats.recv_packets++;
|
||||||
@ -458,13 +459,13 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
switch (m_encode_passes[i]) {
|
switch (m_encode_passes[i]) {
|
||||||
case EncodeCompression:
|
case EncodeCompression:
|
||||||
if(temp.GetInt8(0) == 0)
|
if(temp.GetInt8(0) == 0)
|
||||||
Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
Decompress(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||||
else
|
else
|
||||||
Decompress(temp, 1, temp.Length() - 1);
|
Decompress(temp, 1, temp.Length() - 1);
|
||||||
break;
|
break;
|
||||||
case EncodeXOR:
|
case EncodeXOR:
|
||||||
if (temp.GetInt8(0) == 0)
|
if (temp.GetInt8(0) == 0)
|
||||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||||
else
|
else
|
||||||
Decode(temp, 1, temp.Length() - 1);
|
Decode(temp, 1, temp.Length() - 1);
|
||||||
break;
|
break;
|
||||||
@ -483,7 +484,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
switch (m_encode_passes[i]) {
|
switch (m_encode_passes[i]) {
|
||||||
case EncodeXOR:
|
case EncodeXOR:
|
||||||
if (temp.GetInt8(0) == 0)
|
if (temp.GetInt8(0) == 0)
|
||||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||||
else
|
else
|
||||||
Decode(temp, 1, temp.Length() - 1);
|
Decode(temp, 1, temp.Length() - 1);
|
||||||
break;
|
break;
|
||||||
@ -502,7 +503,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessQueue()
|
void EQ::Net::ReliableStreamConnection::ProcessQueue()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
auto stream = &m_streams[i];
|
auto stream = &m_streams[i];
|
||||||
@ -521,7 +522,7 @@ void EQ::Net::DaybreakConnection::ProcessQueue()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
void EQ::Net::ReliableStreamConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||||
{
|
{
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
auto iter = s->packet_queue.find(seq);
|
auto iter = s->packet_queue.find(seq);
|
||||||
@ -532,7 +533,7 @@ void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
|
void EQ::Net::ReliableStreamConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
|
||||||
{
|
{
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
auto iter = s->packet_queue.find(seq);
|
auto iter = s->packet_queue.find(seq);
|
||||||
@ -544,7 +545,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
|
||||||
{
|
{
|
||||||
if (p.GetInt8(0) == 0) {
|
if (p.GetInt8(0) == 0) {
|
||||||
if (p.Length() < 2) {
|
if (p.Length() < 2) {
|
||||||
@ -628,13 +629,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
case OP_SessionRequest:
|
case OP_SessionRequest:
|
||||||
{
|
{
|
||||||
if (m_status == StatusConnected) {
|
if (m_status == StatusConnected) {
|
||||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
auto request = p.GetSerialize<ReliableStreamConnect>(0);
|
||||||
|
|
||||||
if (NetworkToHost(request.connect_code) != m_connect_code) {
|
if (NetworkToHost(request.connect_code) != m_connect_code) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DaybreakConnectReply reply;
|
ReliableStreamConnectReply reply;
|
||||||
reply.zero = 0;
|
reply.zero = 0;
|
||||||
reply.opcode = OP_SessionResponse;
|
reply.opcode = OP_SessionResponse;
|
||||||
reply.connect_code = HostToNetwork(m_connect_code);
|
reply.connect_code = HostToNetwork(m_connect_code);
|
||||||
@ -656,13 +657,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
case OP_SessionResponse:
|
case OP_SessionResponse:
|
||||||
{
|
{
|
||||||
if (m_status == StatusConnecting) {
|
if (m_status == StatusConnecting) {
|
||||||
auto reply = p.GetSerialize<DaybreakConnectReply>(0);
|
auto reply = p.GetSerialize<ReliableStreamConnectReply>(0);
|
||||||
|
|
||||||
if (m_connect_code == reply.connect_code) {
|
if (m_connect_code == reply.connect_code) {
|
||||||
m_encode_key = reply.encode_key;
|
m_encode_key = reply.encode_key;
|
||||||
m_crc_bytes = reply.crc_bytes;
|
m_crc_bytes = reply.crc_bytes;
|
||||||
m_encode_passes[0] = (DaybreakEncodeType)reply.encode_pass1;
|
m_encode_passes[0] = (ReliableStreamEncodeType)reply.encode_pass1;
|
||||||
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
m_encode_passes[1] = (ReliableStreamEncodeType)reply.encode_pass2;
|
||||||
m_max_packet_size = reply.max_packet_size;
|
m_max_packet_size = reply.max_packet_size;
|
||||||
ChangeStatus(StatusConnected);
|
ChangeStatus(StatusConnected);
|
||||||
|
|
||||||
@ -686,7 +687,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||||
auto sequence = NetworkToHost(header.sequence);
|
auto sequence = NetworkToHost(header.sequence);
|
||||||
auto stream_id = header.opcode - OP_Packet;
|
auto stream_id = header.opcode - OP_Packet;
|
||||||
auto stream = &m_streams[stream_id];
|
auto stream = &m_streams[stream_id];
|
||||||
@ -703,7 +704,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
RemoveFromQueue(stream_id, sequence);
|
RemoveFromQueue(stream_id, sequence);
|
||||||
SendAck(stream_id, stream->sequence_in);
|
SendAck(stream_id, stream->sequence_in);
|
||||||
stream->sequence_in++;
|
stream->sequence_in++;
|
||||||
StaticPacket next((char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
|
StaticPacket next((char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size());
|
||||||
ProcessDecodedPacket(next);
|
ProcessDecodedPacket(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,7 +716,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
case OP_Fragment3:
|
case OP_Fragment3:
|
||||||
case OP_Fragment4:
|
case OP_Fragment4:
|
||||||
{
|
{
|
||||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||||
auto sequence = NetworkToHost(header.sequence);
|
auto sequence = NetworkToHost(header.sequence);
|
||||||
auto stream_id = header.opcode - OP_Fragment;
|
auto stream_id = header.opcode - OP_Fragment;
|
||||||
auto stream = &m_streams[stream_id];
|
auto stream = &m_streams[stream_id];
|
||||||
@ -735,22 +736,22 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
stream->sequence_in++;
|
stream->sequence_in++;
|
||||||
|
|
||||||
if (stream->fragment_total_bytes == 0) {
|
if (stream->fragment_total_bytes == 0) {
|
||||||
auto fragheader = p.GetSerialize<DaybreakReliableFragmentHeader>(0);
|
auto fragheader = p.GetSerialize<ReliableStreamReliableFragmentHeader>(0);
|
||||||
stream->fragment_total_bytes = NetworkToHost(fragheader.total_size);
|
stream->fragment_total_bytes = NetworkToHost(fragheader.total_size);
|
||||||
stream->fragment_current_bytes = 0;
|
stream->fragment_current_bytes = 0;
|
||||||
stream->fragment_packet.Reserve(stream->fragment_total_bytes);
|
stream->fragment_packet.Reserve(stream->fragment_total_bytes);
|
||||||
stream->fragment_packet.PutData(
|
stream->fragment_packet.PutData(
|
||||||
stream->fragment_current_bytes,
|
stream->fragment_current_bytes,
|
||||||
(char*)p.Data() + DaybreakReliableFragmentHeader::size(), p.Length() - DaybreakReliableFragmentHeader::size());
|
(char*)p.Data() + ReliableStreamReliableFragmentHeader::size(), p.Length() - ReliableStreamReliableFragmentHeader::size());
|
||||||
|
|
||||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableFragmentHeader::size());
|
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableFragmentHeader::size());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stream->fragment_packet.PutData(
|
stream->fragment_packet.PutData(
|
||||||
stream->fragment_current_bytes,
|
stream->fragment_current_bytes,
|
||||||
(char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
|
(char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size());
|
||||||
|
|
||||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableHeader::size());
|
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableHeader::size());
|
||||||
|
|
||||||
if (stream->fragment_current_bytes >= stream->fragment_total_bytes) {
|
if (stream->fragment_current_bytes >= stream->fragment_total_bytes) {
|
||||||
ProcessDecodedPacket(stream->fragment_packet);
|
ProcessDecodedPacket(stream->fragment_packet);
|
||||||
@ -769,7 +770,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
case OP_Ack3:
|
case OP_Ack3:
|
||||||
case OP_Ack4:
|
case OP_Ack4:
|
||||||
{
|
{
|
||||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||||
auto sequence = NetworkToHost(header.sequence);
|
auto sequence = NetworkToHost(header.sequence);
|
||||||
auto stream_id = header.opcode - OP_Ack;
|
auto stream_id = header.opcode - OP_Ack;
|
||||||
Ack(stream_id, sequence);
|
Ack(stream_id, sequence);
|
||||||
@ -781,7 +782,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
case OP_OutOfOrderAck3:
|
case OP_OutOfOrderAck3:
|
||||||
case OP_OutOfOrderAck4:
|
case OP_OutOfOrderAck4:
|
||||||
{
|
{
|
||||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||||
auto sequence = NetworkToHost(header.sequence);
|
auto sequence = NetworkToHost(header.sequence);
|
||||||
auto stream_id = header.opcode - OP_OutOfOrderAck;
|
auto stream_id = header.opcode - OP_OutOfOrderAck;
|
||||||
OutOfOrderAck(stream_id, sequence);
|
OutOfOrderAck(stream_id, sequence);
|
||||||
@ -815,13 +816,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
}
|
}
|
||||||
case OP_SessionStatRequest:
|
case OP_SessionStatRequest:
|
||||||
{
|
{
|
||||||
auto request = p.GetSerialize<DaybreakSessionStatRequest>(0);
|
auto request = p.GetSerialize<ReliableStreamSessionStatRequest>(0);
|
||||||
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(request.packets_sent);
|
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(request.packets_sent);
|
||||||
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(request.packets_recv);
|
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(request.packets_recv);
|
||||||
m_stats.sync_sent_packets = m_stats.sent_packets;
|
m_stats.sync_sent_packets = m_stats.sent_packets;
|
||||||
m_stats.sync_recv_packets = m_stats.recv_packets;
|
m_stats.sync_recv_packets = m_stats.recv_packets;
|
||||||
|
|
||||||
DaybreakSessionStatResponse response;
|
ReliableStreamSessionStatResponse response;
|
||||||
response.zero = 0;
|
response.zero = 0;
|
||||||
response.opcode = OP_SessionStatResponse;
|
response.opcode = OP_SessionStatResponse;
|
||||||
response.timestamp = request.timestamp;
|
response.timestamp = request.timestamp;
|
||||||
@ -836,7 +837,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_SessionStatResponse: {
|
case OP_SessionStatResponse: {
|
||||||
auto response = p.GetSerialize<DaybreakSessionStatResponse>(0);
|
auto response = p.GetSerialize<ReliableStreamSessionStatResponse>(0);
|
||||||
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(response.server_sent);
|
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(response.server_sent);
|
||||||
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(response.server_recv);
|
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(response.server_recv);
|
||||||
m_stats.sync_sent_packets = m_stats.sent_packets;
|
m_stats.sync_sent_packets = m_stats.sent_packets;
|
||||||
@ -858,7 +859,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
bool EQ::Net::ReliableStreamConnection::ValidateCRC(Packet &p)
|
||||||
{
|
{
|
||||||
if (m_crc_bytes == 0U) {
|
if (m_crc_bytes == 0U) {
|
||||||
return true;
|
return true;
|
||||||
@ -892,7 +893,7 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
|
void EQ::Net::ReliableStreamConnection::AppendCRC(Packet &p)
|
||||||
{
|
{
|
||||||
if (m_crc_bytes == 0U) {
|
if (m_crc_bytes == 0U) {
|
||||||
return;
|
return;
|
||||||
@ -911,7 +912,7 @@ void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
|
void EQ::Net::ReliableStreamConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||||
{
|
{
|
||||||
if (m_owner->m_on_connection_state_change) {
|
if (m_owner->m_on_connection_state_change) {
|
||||||
if (auto self = m_self.lock()) {
|
if (auto self = m_self.lock()) {
|
||||||
@ -922,7 +923,7 @@ void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
|
|||||||
m_status = new_status;
|
m_status = new_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
|
bool EQ::Net::ReliableStreamConnection::PacketCanBeEncoded(Packet &p) const
|
||||||
{
|
{
|
||||||
if (p.Length() < 2) {
|
if (p.Length() < 2) {
|
||||||
return false;
|
return false;
|
||||||
@ -941,7 +942,7 @@ bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length)
|
void EQ::Net::ReliableStreamConnection::Decode(Packet &p, size_t offset, size_t length)
|
||||||
{
|
{
|
||||||
int key = m_encode_key;
|
int key = m_encode_key;
|
||||||
char *buffer = (char*)p.Data() + offset;
|
char *buffer = (char*)p.Data() + offset;
|
||||||
@ -961,7 +962,7 @@ void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Encode(Packet &p, size_t offset, size_t length)
|
void EQ::Net::ReliableStreamConnection::Encode(Packet &p, size_t offset, size_t length)
|
||||||
{
|
{
|
||||||
int key = m_encode_key;
|
int key = m_encode_key;
|
||||||
char *buffer = (char*)p.Data() + offset;
|
char *buffer = (char*)p.Data() + offset;
|
||||||
@ -1050,7 +1051,7 @@ uint32_t Deflate(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t out_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t length)
|
void EQ::Net::ReliableStreamConnection::Decompress(Packet &p, size_t offset, size_t length)
|
||||||
{
|
{
|
||||||
if (length < 2) {
|
if (length < 2) {
|
||||||
return;
|
return;
|
||||||
@ -1075,7 +1076,7 @@ void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t le
|
|||||||
p.PutData(offset, new_buffer, new_length);
|
p.PutData(offset, new_buffer, new_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t length)
|
void EQ::Net::ReliableStreamConnection::Compress(Packet &p, size_t offset, size_t length)
|
||||||
{
|
{
|
||||||
static thread_local uint8_t new_buffer[2048] = { 0 };
|
static thread_local uint8_t new_buffer[2048] = { 0 };
|
||||||
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
||||||
@ -1097,14 +1098,14 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
|
|||||||
p.PutData(offset, new_buffer, new_length);
|
p.PutData(offset, new_buffer, new_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessResend()
|
void EQ::Net::ReliableStreamConnection::ProcessResend()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
ProcessResend(i);
|
ProcessResend(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
|
||||||
{
|
{
|
||||||
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
||||||
return;
|
return;
|
||||||
@ -1127,16 +1128,37 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - first_packet.first_sent).count();
|
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - first_packet.first_sent).count();
|
||||||
|
|
||||||
if (time_since_first_sent >= m_owner->m_options.resend_timeout) {
|
if (time_since_first_sent >= m_owner->m_options.resend_timeout) {
|
||||||
|
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
|
||||||
|
auto first_sent_ms = std::chrono::duration_cast<std::chrono::milliseconds>(first_packet.first_sent.time_since_epoch()).count();
|
||||||
|
LogNetClient(
|
||||||
|
"Closing connection for m_endpoint [{}] m_port [{}] time_since_first_sent [{}] >= m_owner->m_options.resend_timeout [{}] now [{}] first_packet.first_sent [{}]",
|
||||||
|
m_endpoint,
|
||||||
|
m_port,
|
||||||
|
time_since_first_sent,
|
||||||
|
m_owner->m_options.resend_timeout,
|
||||||
|
now_ms,
|
||||||
|
first_sent_ms
|
||||||
|
);
|
||||||
Close();
|
Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_last_ack - now > std::chrono::milliseconds(1000)) {
|
||||||
|
LogNetClient(
|
||||||
|
"Resetting m_acked_since_last_resend flag for m_endpoint [{}] m_port [{}]",
|
||||||
|
m_endpoint,
|
||||||
|
m_port
|
||||||
|
);
|
||||||
|
m_acked_since_last_resend = true;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure that the first_packet in the list first_sent time is within the resend_delay and now
|
// make sure that the first_packet in the list first_sent time is within the resend_delay and now
|
||||||
// if it is not, then we need to resend all packets in the list
|
// if it is not, then we need to resend all packets in the list
|
||||||
if (time_since_first_sent <= first_packet.resend_delay && !m_acked_since_last_resend) {
|
if (time_since_first_sent <= first_packet.resend_delay && !m_acked_since_last_resend) {
|
||||||
LogNetClient(
|
LogNetClientDetail(
|
||||||
"Not resending packets for stream [{}] packets [{}] time_first_sent [{}] resend_delay [{}] m_acked_since_last_resend [{}]",
|
"Not resending packets for m_endpoint [{}] m_port [{}] packets [{}] time_first_sent [{}] resend_delay [{}] m_acked_since_last_resend [{}]",
|
||||||
stream,
|
m_endpoint,
|
||||||
|
m_port,
|
||||||
s->sent_packets.size(),
|
s->sent_packets.size(),
|
||||||
time_since_first_sent,
|
time_since_first_sent,
|
||||||
first_packet.resend_delay,
|
first_packet.resend_delay,
|
||||||
@ -1146,15 +1168,16 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Netcode)) {
|
if (EQEmuLogSys::Instance()->IsLogEnabled(Logs::General, Logs::NetClient)) {
|
||||||
size_t total_size = 0;
|
size_t total_size = 0;
|
||||||
for (auto &e: s->sent_packets) {
|
for (auto &e: s->sent_packets) {
|
||||||
total_size += e.second.packet.Length();
|
total_size += e.second.packet.Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetClient(
|
LogNetClientDetail(
|
||||||
"Resending packets for stream [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
|
"Resending packets for m_endpoint [{}] m_port [{}] packet count [{}] total packet size [{}] m_acked_since_last_resend [{}]",
|
||||||
stream,
|
m_endpoint,
|
||||||
|
m_port,
|
||||||
s->sent_packets.size(),
|
s->sent_packets.size(),
|
||||||
total_size,
|
total_size,
|
||||||
m_acked_since_last_resend
|
m_acked_since_last_resend
|
||||||
@ -1165,9 +1188,12 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
if (m_resend_packets_sent >= MAX_CLIENT_RECV_PACKETS_PER_WINDOW ||
|
if (m_resend_packets_sent >= MAX_CLIENT_RECV_PACKETS_PER_WINDOW ||
|
||||||
m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) {
|
m_resend_bytes_sent >= MAX_CLIENT_RECV_BYTES_PER_WINDOW) {
|
||||||
LogNetClient(
|
LogNetClient(
|
||||||
"Stopping resend because we hit thresholds m_resend_packets_sent [{}] max [{}] m_resend_bytes_sent [{}] max [{}]",
|
"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,
|
||||||
m_resend_packets_sent,
|
m_resend_packets_sent,
|
||||||
MAX_CLIENT_RECV_PACKETS_PER_WINDOW,
|
MAX_CLIENT_RECV_PACKETS_PER_WINDOW,
|
||||||
|
s->sent_packets.size(),
|
||||||
m_resend_bytes_sent,
|
m_resend_bytes_sent,
|
||||||
MAX_CLIENT_RECV_BYTES_PER_WINDOW
|
MAX_CLIENT_RECV_BYTES_PER_WINDOW
|
||||||
);
|
);
|
||||||
@ -1176,7 +1202,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
|
|
||||||
auto &sp = e.second;
|
auto &sp = e.second;
|
||||||
auto &p = sp.packet;
|
auto &p = sp.packet;
|
||||||
if (p.Length() >= DaybreakHeader::size()) {
|
if (p.Length() >= ReliableStreamHeader::size()) {
|
||||||
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
||||||
m_stats.resent_fragments++;
|
m_stats.resent_fragments++;
|
||||||
}
|
}
|
||||||
@ -1204,11 +1230,11 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_acked_since_last_resend = false;
|
m_acked_since_last_resend = false;
|
||||||
|
m_last_ack = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
void EQ::Net::ReliableStreamConnection::Ack(int stream, uint16_t seq)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
auto iter = s->sent_packets.begin();
|
auto iter = s->sent_packets.begin();
|
||||||
@ -1224,15 +1250,17 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
|||||||
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
||||||
|
|
||||||
iter = s->sent_packets.erase(iter);
|
iter = s->sent_packets.erase(iter);
|
||||||
m_acked_since_last_resend = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_acked_since_last_resend = true;
|
||||||
|
m_last_ack = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
void EQ::Net::ReliableStreamConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||||
{
|
{
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
@ -1247,17 +1275,20 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
|||||||
|
|
||||||
s->sent_packets.erase(iter);
|
s->sent_packets.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_acked_since_last_resend = true;
|
||||||
|
m_last_ack = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::UpdateDataBudget(double budget_add)
|
void EQ::Net::ReliableStreamConnection::UpdateDataBudget(double budget_add)
|
||||||
{
|
{
|
||||||
auto outgoing_data_rate = m_owner->m_options.outgoing_data_rate;
|
auto outgoing_data_rate = m_owner->m_options.outgoing_data_rate;
|
||||||
m_outgoing_budget = EQ::ClampUpper(m_outgoing_budget + budget_add, outgoing_data_rate);
|
m_outgoing_budget = EQ::ClampUpper(m_outgoing_budget + budget_add, outgoing_data_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
void EQ::Net::ReliableStreamConnection::SendAck(int stream_id, uint16_t seq)
|
||||||
{
|
{
|
||||||
DaybreakReliableHeader ack;
|
ReliableStreamReliableHeader ack;
|
||||||
ack.zero = 0;
|
ack.zero = 0;
|
||||||
ack.opcode = OP_Ack + stream_id;
|
ack.opcode = OP_Ack + stream_id;
|
||||||
ack.sequence = HostToNetwork(seq);
|
ack.sequence = HostToNetwork(seq);
|
||||||
@ -1268,9 +1299,9 @@ void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
|||||||
InternalBufferedSend(p);
|
InternalBufferedSend(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
void EQ::Net::ReliableStreamConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||||
{
|
{
|
||||||
DaybreakReliableHeader ack;
|
ReliableStreamReliableHeader ack;
|
||||||
ack.zero = 0;
|
ack.zero = 0;
|
||||||
ack.opcode = OP_OutOfOrderAck + stream_id;
|
ack.opcode = OP_OutOfOrderAck + stream_id;
|
||||||
ack.sequence = HostToNetwork(seq);
|
ack.sequence = HostToNetwork(seq);
|
||||||
@ -1281,9 +1312,9 @@ void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
|||||||
InternalBufferedSend(p);
|
InternalBufferedSend(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::SendDisconnect()
|
void EQ::Net::ReliableStreamConnection::SendDisconnect()
|
||||||
{
|
{
|
||||||
DaybreakDisconnect disconnect;
|
ReliableStreamDisconnect disconnect;
|
||||||
disconnect.zero = 0;
|
disconnect.zero = 0;
|
||||||
disconnect.opcode = OP_SessionDisconnect;
|
disconnect.opcode = OP_SessionDisconnect;
|
||||||
disconnect.connect_code = HostToNetwork(m_connect_code);
|
disconnect.connect_code = HostToNetwork(m_connect_code);
|
||||||
@ -1292,7 +1323,7 @@ void EQ::Net::DaybreakConnection::SendDisconnect()
|
|||||||
InternalSend(out);
|
InternalSend(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
|
||||||
{
|
{
|
||||||
if (p.Length() > 0xFFU) {
|
if (p.Length() > 0xFFU) {
|
||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
@ -1301,7 +1332,7 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//we could add this packet to a combined
|
//we could add this packet to a combined
|
||||||
size_t raw_size = DaybreakHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
|
size_t raw_size = ReliableStreamHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
|
||||||
if (raw_size > m_max_packet_size) {
|
if (raw_size > m_max_packet_size) {
|
||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
}
|
}
|
||||||
@ -1316,9 +1347,9 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::SendConnect()
|
void EQ::Net::ReliableStreamConnection::SendConnect()
|
||||||
{
|
{
|
||||||
DaybreakConnect connect;
|
ReliableStreamConnect connect;
|
||||||
connect.zero = 0;
|
connect.zero = 0;
|
||||||
connect.opcode = OP_SessionRequest;
|
connect.opcode = OP_SessionRequest;
|
||||||
connect.protocol_version = HostToNetwork(3U);
|
connect.protocol_version = HostToNetwork(3U);
|
||||||
@ -1331,9 +1362,9 @@ void EQ::Net::DaybreakConnection::SendConnect()
|
|||||||
InternalSend(p);
|
InternalSend(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::SendKeepAlive()
|
void EQ::Net::ReliableStreamConnection::SendKeepAlive()
|
||||||
{
|
{
|
||||||
DaybreakHeader keep_alive;
|
ReliableStreamHeader keep_alive;
|
||||||
keep_alive.zero = 0;
|
keep_alive.zero = 0;
|
||||||
keep_alive.opcode = OP_KeepAlive;
|
keep_alive.opcode = OP_KeepAlive;
|
||||||
|
|
||||||
@ -1343,7 +1374,7 @@ void EQ::Net::DaybreakConnection::SendKeepAlive()
|
|||||||
InternalSend(p);
|
InternalSend(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) {
|
||||||
if (m_owner->m_options.outgoing_data_rate > 0.0) {
|
if (m_owner->m_options.outgoing_data_rate > 0.0) {
|
||||||
auto new_budget = m_outgoing_budget - (p.Length() / 1024.0);
|
auto new_budget = m_outgoing_budget - (p.Length() / 1024.0);
|
||||||
if (new_budget <= 0.0) {
|
if (new_budget <= 0.0) {
|
||||||
@ -1379,14 +1410,14 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
|||||||
switch (m_encode_passe) {
|
switch (m_encode_passe) {
|
||||||
case EncodeCompression:
|
case EncodeCompression:
|
||||||
if (out.GetInt8(0) == 0) {
|
if (out.GetInt8(0) == 0) {
|
||||||
Compress(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
Compress(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
|
||||||
} else {
|
} else {
|
||||||
Compress(out, 1, out.Length() - 1);
|
Compress(out, 1, out.Length() - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EncodeXOR:
|
case EncodeXOR:
|
||||||
if (out.GetInt8(0) == 0) {
|
if (out.GetInt8(0) == 0) {
|
||||||
Encode(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
Encode(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
|
||||||
} else {
|
} else {
|
||||||
Encode(out, 1, out.Length() - 1);
|
Encode(out, 1, out.Length() - 1);
|
||||||
}
|
}
|
||||||
@ -1436,7 +1467,7 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
||||||
{
|
{
|
||||||
if (!reliable) {
|
if (!reliable) {
|
||||||
auto max_raw_size = 0xFFU - m_crc_bytes;
|
auto max_raw_size = 0xFFU - m_crc_bytes;
|
||||||
@ -1450,23 +1481,23 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto stream = &m_streams[stream_id];
|
auto stream = &m_streams[stream_id];
|
||||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
|
auto max_raw_size = m_max_packet_size - m_crc_bytes - ReliableStreamReliableHeader::size() - 1; // -1 for compress flag
|
||||||
size_t length = p.Length();
|
size_t length = p.Length();
|
||||||
if (length > max_raw_size) {
|
if (length > max_raw_size) {
|
||||||
DaybreakReliableFragmentHeader first_header;
|
ReliableStreamReliableFragmentHeader first_header;
|
||||||
first_header.reliable.zero = 0;
|
first_header.reliable.zero = 0;
|
||||||
first_header.reliable.opcode = OP_Fragment + stream_id;
|
first_header.reliable.opcode = OP_Fragment + stream_id;
|
||||||
first_header.reliable.sequence = HostToNetwork(stream->sequence_out);
|
first_header.reliable.sequence = HostToNetwork(stream->sequence_out);
|
||||||
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
|
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
|
||||||
|
|
||||||
size_t used = 0;
|
size_t used = 0;
|
||||||
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size() - 1; // -1 for compress flag
|
size_t sublen = m_max_packet_size - m_crc_bytes - ReliableStreamReliableFragmentHeader::size() - 1; // -1 for compress flag
|
||||||
DynamicPacket first_packet;
|
DynamicPacket first_packet;
|
||||||
first_packet.PutSerialize(0, first_header);
|
first_packet.PutSerialize(0, first_header);
|
||||||
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
first_packet.PutData(ReliableStreamReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
||||||
used += sublen;
|
used += sublen;
|
||||||
|
|
||||||
DaybreakSentPacket sent;
|
ReliableStreamSentPacket sent;
|
||||||
sent.packet.PutPacket(0, first_packet);
|
sent.packet.PutPacket(0, first_packet);
|
||||||
sent.last_sent = Clock::now();
|
sent.last_sent = Clock::now();
|
||||||
sent.first_sent = Clock::now();
|
sent.first_sent = Clock::now();
|
||||||
@ -1483,22 +1514,22 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
while (used < length) {
|
while (used < length) {
|
||||||
auto left = length - used;
|
auto left = length - used;
|
||||||
DynamicPacket packet;
|
DynamicPacket packet;
|
||||||
DaybreakReliableHeader header;
|
ReliableStreamReliableHeader header;
|
||||||
header.zero = 0;
|
header.zero = 0;
|
||||||
header.opcode = OP_Fragment + stream_id;
|
header.opcode = OP_Fragment + stream_id;
|
||||||
header.sequence = HostToNetwork(stream->sequence_out);
|
header.sequence = HostToNetwork(stream->sequence_out);
|
||||||
packet.PutSerialize(0, header);
|
packet.PutSerialize(0, header);
|
||||||
|
|
||||||
if (left > max_raw_size) {
|
if (left > max_raw_size) {
|
||||||
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
|
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
|
||||||
used += max_raw_size;
|
used += max_raw_size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, left);
|
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, left);
|
||||||
used += left;
|
used += left;
|
||||||
}
|
}
|
||||||
|
|
||||||
DaybreakSentPacket sent;
|
ReliableStreamSentPacket sent;
|
||||||
sent.packet.PutPacket(0, packet);
|
sent.packet.PutPacket(0, packet);
|
||||||
sent.last_sent = Clock::now();
|
sent.last_sent = Clock::now();
|
||||||
sent.first_sent = Clock::now();
|
sent.first_sent = Clock::now();
|
||||||
@ -1515,14 +1546,14 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DynamicPacket packet;
|
DynamicPacket packet;
|
||||||
DaybreakReliableHeader header;
|
ReliableStreamReliableHeader header;
|
||||||
header.zero = 0;
|
header.zero = 0;
|
||||||
header.opcode = OP_Packet + stream_id;
|
header.opcode = OP_Packet + stream_id;
|
||||||
header.sequence = HostToNetwork(stream->sequence_out);
|
header.sequence = HostToNetwork(stream->sequence_out);
|
||||||
packet.PutSerialize(0, header);
|
packet.PutSerialize(0, header);
|
||||||
packet.PutPacket(DaybreakReliableHeader::size(), p);
|
packet.PutPacket(ReliableStreamReliableHeader::size(), p);
|
||||||
|
|
||||||
DaybreakSentPacket sent;
|
ReliableStreamSentPacket sent;
|
||||||
sent.packet.PutPacket(0, packet);
|
sent.packet.PutPacket(0, packet);
|
||||||
sent.last_sent = Clock::now();
|
sent.last_sent = Clock::now();
|
||||||
sent.first_sent = Clock::now();
|
sent.first_sent = Clock::now();
|
||||||
@ -1538,7 +1569,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::FlushBuffer()
|
void EQ::Net::ReliableStreamConnection::FlushBuffer()
|
||||||
{
|
{
|
||||||
if (m_buffered_packets.empty()) {
|
if (m_buffered_packets.empty()) {
|
||||||
return;
|
return;
|
||||||
@ -1565,7 +1596,7 @@ void EQ::Net::DaybreakConnection::FlushBuffer()
|
|||||||
m_buffered_packets_length = 0;
|
m_buffered_packets_length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t expected, uint16_t actual) const
|
EQ::Net::SequenceOrder EQ::Net::ReliableStreamConnection::CompareSequence(uint16_t expected, uint16_t actual) const
|
||||||
{
|
{
|
||||||
int diff = (int)actual - (int)expected;
|
int diff = (int)actual - (int)expected;
|
||||||
|
|
||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include "../random.h"
|
#include "../random.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "daybreak_structs.h"
|
#include "reliable_stream_structs.h"
|
||||||
#include "daybreak_pooling.h"
|
#include "reliable_stream_pooling.h"
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -16,7 +16,7 @@ namespace EQ
|
|||||||
{
|
{
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
enum DaybreakProtocolOpcode
|
enum ReliableStreamProtocolOpcode
|
||||||
{
|
{
|
||||||
OP_Padding = 0x00,
|
OP_Padding = 0x00,
|
||||||
OP_SessionRequest = 0x01,
|
OP_SessionRequest = 0x01,
|
||||||
@ -55,7 +55,7 @@ namespace EQ
|
|||||||
StatusDisconnected
|
StatusDisconnected
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DaybreakEncodeType
|
enum ReliableStreamEncodeType
|
||||||
{
|
{
|
||||||
EncodeNone = 0,
|
EncodeNone = 0,
|
||||||
EncodeCompression = 1,
|
EncodeCompression = 1,
|
||||||
@ -72,9 +72,9 @@ namespace EQ
|
|||||||
typedef std::chrono::steady_clock::time_point Timestamp;
|
typedef std::chrono::steady_clock::time_point Timestamp;
|
||||||
typedef std::chrono::steady_clock Clock;
|
typedef std::chrono::steady_clock Clock;
|
||||||
|
|
||||||
struct DaybreakConnectionStats
|
struct ReliableStreamConnectionStats
|
||||||
{
|
{
|
||||||
DaybreakConnectionStats() {
|
ReliableStreamConnectionStats() {
|
||||||
recv_bytes = 0;
|
recv_bytes = 0;
|
||||||
sent_bytes = 0;
|
sent_bytes = 0;
|
||||||
recv_packets = 0;
|
recv_packets = 0;
|
||||||
@ -134,14 +134,14 @@ namespace EQ
|
|||||||
uint64_t bytes_before_encode;
|
uint64_t bytes_before_encode;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DaybreakConnectionManager;
|
class ReliableStreamConnectionManager;
|
||||||
class DaybreakConnection;
|
class ReliableStreamConnection;
|
||||||
class DaybreakConnection
|
class ReliableStreamConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
|
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port);
|
||||||
DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
|
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port);
|
||||||
~DaybreakConnection();
|
~ReliableStreamConnection();
|
||||||
|
|
||||||
const std::string& RemoteEndpoint() const { return m_endpoint; }
|
const std::string& RemoteEndpoint() const { return m_endpoint; }
|
||||||
int RemotePort() const { return m_port; }
|
int RemotePort() const { return m_port; }
|
||||||
@ -151,23 +151,23 @@ namespace EQ
|
|||||||
void QueuePacket(Packet &p, int stream);
|
void QueuePacket(Packet &p, int stream);
|
||||||
void QueuePacket(Packet &p, int stream, bool reliable);
|
void QueuePacket(Packet &p, int stream, bool reliable);
|
||||||
|
|
||||||
DaybreakConnectionStats GetStats();
|
ReliableStreamConnectionStats GetStats();
|
||||||
void ResetStats();
|
void ResetStats();
|
||||||
size_t GetRollingPing() const { return m_rolling_ping; }
|
size_t GetRollingPing() const { return m_rolling_ping; }
|
||||||
DbProtocolStatus GetStatus() const { return m_status; }
|
DbProtocolStatus GetStatus() const { return m_status; }
|
||||||
|
|
||||||
const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
const ReliableStreamEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||||
const DaybreakConnectionManager* GetManager() const { return m_owner; }
|
const ReliableStreamConnectionManager* GetManager() const { return m_owner; }
|
||||||
DaybreakConnectionManager* GetManager() { return m_owner; }
|
ReliableStreamConnectionManager* GetManager() { return m_owner; }
|
||||||
private:
|
private:
|
||||||
DaybreakConnectionManager *m_owner;
|
ReliableStreamConnectionManager *m_owner;
|
||||||
std::string m_endpoint;
|
std::string m_endpoint;
|
||||||
int m_port;
|
int m_port;
|
||||||
uint32_t m_connect_code;
|
uint32_t m_connect_code;
|
||||||
uint32_t m_encode_key;
|
uint32_t m_encode_key;
|
||||||
uint32_t m_max_packet_size;
|
uint32_t m_max_packet_size;
|
||||||
uint32_t m_crc_bytes;
|
uint32_t m_crc_bytes;
|
||||||
DaybreakEncodeType m_encode_passes[2];
|
ReliableStreamEncodeType m_encode_passes[2];
|
||||||
|
|
||||||
Timestamp m_last_send;
|
Timestamp m_last_send;
|
||||||
Timestamp m_last_recv;
|
Timestamp m_last_recv;
|
||||||
@ -176,7 +176,7 @@ namespace EQ
|
|||||||
std::list<DynamicPacket> m_buffered_packets;
|
std::list<DynamicPacket> m_buffered_packets;
|
||||||
size_t m_buffered_packets_length;
|
size_t m_buffered_packets_length;
|
||||||
std::unique_ptr<char[]> m_combined;
|
std::unique_ptr<char[]> m_combined;
|
||||||
DaybreakConnectionStats m_stats;
|
ReliableStreamConnectionStats m_stats;
|
||||||
Timestamp m_last_session_stats;
|
Timestamp m_last_session_stats;
|
||||||
size_t m_rolling_ping;
|
size_t m_rolling_ping;
|
||||||
Timestamp m_close_time;
|
Timestamp m_close_time;
|
||||||
@ -186,8 +186,9 @@ namespace EQ
|
|||||||
size_t m_resend_packets_sent = 0;
|
size_t m_resend_packets_sent = 0;
|
||||||
size_t m_resend_bytes_sent = 0;
|
size_t m_resend_bytes_sent = 0;
|
||||||
bool m_acked_since_last_resend = false;
|
bool m_acked_since_last_resend = false;
|
||||||
|
Timestamp m_last_ack;
|
||||||
|
|
||||||
struct DaybreakSentPacket
|
struct ReliableStreamSentPacket
|
||||||
{
|
{
|
||||||
DynamicPacket packet;
|
DynamicPacket packet;
|
||||||
Timestamp last_sent;
|
Timestamp last_sent;
|
||||||
@ -196,9 +197,9 @@ namespace EQ
|
|||||||
size_t resend_delay;
|
size_t resend_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakStream
|
struct ReliableStream
|
||||||
{
|
{
|
||||||
DaybreakStream() {
|
ReliableStream() {
|
||||||
sequence_in = 0;
|
sequence_in = 0;
|
||||||
sequence_out = 0;
|
sequence_out = 0;
|
||||||
fragment_current_bytes = 0;
|
fragment_current_bytes = 0;
|
||||||
@ -213,11 +214,11 @@ namespace EQ
|
|||||||
uint32_t fragment_current_bytes;
|
uint32_t fragment_current_bytes;
|
||||||
uint32_t fragment_total_bytes;
|
uint32_t fragment_total_bytes;
|
||||||
|
|
||||||
std::map<uint16_t, DaybreakSentPacket> sent_packets;
|
std::map<uint16_t, ReliableStreamSentPacket> sent_packets;
|
||||||
};
|
};
|
||||||
|
|
||||||
DaybreakStream m_streams[4];
|
ReliableStream m_streams[4];
|
||||||
std::weak_ptr<DaybreakConnection> m_self;
|
std::weak_ptr<ReliableStreamConnection> m_self;
|
||||||
|
|
||||||
void Process();
|
void Process();
|
||||||
void ProcessPacket(Packet &p);
|
void ProcessPacket(Packet &p);
|
||||||
@ -250,12 +251,12 @@ namespace EQ
|
|||||||
void FlushBuffer();
|
void FlushBuffer();
|
||||||
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
|
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
|
||||||
|
|
||||||
friend class DaybreakConnectionManager;
|
friend class ReliableStreamConnectionManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakConnectionManagerOptions
|
struct ReliableStreamConnectionManagerOptions
|
||||||
{
|
{
|
||||||
DaybreakConnectionManagerOptions() {
|
ReliableStreamConnectionManagerOptions() {
|
||||||
max_connection_count = 0;
|
max_connection_count = 0;
|
||||||
keepalive_delay_ms = 9000;
|
keepalive_delay_ms = 9000;
|
||||||
resend_delay_ms = 30;
|
resend_delay_ms = 30;
|
||||||
@ -267,8 +268,8 @@ namespace EQ
|
|||||||
connect_stale_ms = 5000;
|
connect_stale_ms = 5000;
|
||||||
crc_length = 2;
|
crc_length = 2;
|
||||||
max_packet_size = 512;
|
max_packet_size = 512;
|
||||||
encode_passes[0] = DaybreakEncodeType::EncodeNone;
|
encode_passes[0] = ReliableStreamEncodeType::EncodeNone;
|
||||||
encode_passes[1] = DaybreakEncodeType::EncodeNone;
|
encode_passes[1] = ReliableStreamEncodeType::EncodeNone;
|
||||||
port = 0;
|
port = 0;
|
||||||
hold_size = 512;
|
hold_size = 512;
|
||||||
hold_length_ms = 50;
|
hold_length_ms = 50;
|
||||||
@ -298,28 +299,28 @@ namespace EQ
|
|||||||
double tic_rate_hertz;
|
double tic_rate_hertz;
|
||||||
size_t resend_timeout;
|
size_t resend_timeout;
|
||||||
size_t connection_close_time;
|
size_t connection_close_time;
|
||||||
DaybreakEncodeType encode_passes[2];
|
ReliableStreamEncodeType encode_passes[2];
|
||||||
int port;
|
int port;
|
||||||
double outgoing_data_rate;
|
double outgoing_data_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DaybreakConnectionManager
|
class ReliableStreamConnectionManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DaybreakConnectionManager();
|
ReliableStreamConnectionManager();
|
||||||
DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts);
|
ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts);
|
||||||
~DaybreakConnectionManager();
|
~ReliableStreamConnectionManager();
|
||||||
|
|
||||||
void Connect(const std::string &addr, int port);
|
void Connect(const std::string &addr, int port);
|
||||||
void Process();
|
void Process();
|
||||||
void UpdateDataBudget();
|
void UpdateDataBudget();
|
||||||
void ProcessResend();
|
void ProcessResend();
|
||||||
void OnNewConnection(std::function<void(std::shared_ptr<DaybreakConnection>)> func) { m_on_new_connection = func; }
|
void OnNewConnection(std::function<void(std::shared_ptr<ReliableStreamConnection>)> 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 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<DaybreakConnection>, const Packet &)> func) { m_on_packet_recv = func; }
|
void OnPacketRecv(std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet &)> func) { m_on_packet_recv = func; }
|
||||||
void OnErrorMessage(std::function<void(const std::string&)> func) { m_on_error_message = func; }
|
void OnErrorMessage(std::function<void(const std::string&)> func) { m_on_error_message = func; }
|
||||||
|
|
||||||
DaybreakConnectionManagerOptions& GetOptions() { return m_options; }
|
ReliableStreamConnectionManagerOptions& GetOptions() { return m_options; }
|
||||||
private:
|
private:
|
||||||
void Attach(uv_loop_t *loop);
|
void Attach(uv_loop_t *loop);
|
||||||
void Detach();
|
void Detach();
|
||||||
@ -328,18 +329,18 @@ namespace EQ
|
|||||||
uv_timer_t m_timer;
|
uv_timer_t m_timer;
|
||||||
uv_udp_t m_socket;
|
uv_udp_t m_socket;
|
||||||
uv_loop_t *m_attached;
|
uv_loop_t *m_attached;
|
||||||
DaybreakConnectionManagerOptions m_options;
|
ReliableStreamConnectionManagerOptions m_options;
|
||||||
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
|
std::function<void(std::shared_ptr<ReliableStreamConnection>)> m_on_new_connection;
|
||||||
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||||
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
|
std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet&)> m_on_packet_recv;
|
||||||
std::function<void(const std::string&)> m_on_error_message;
|
std::function<void(const std::string&)> m_on_error_message;
|
||||||
std::map<std::pair<std::string, int>, std::shared_ptr<DaybreakConnection>> m_connections;
|
std::map<std::pair<std::string, int>, std::shared_ptr<ReliableStreamConnection>> m_connections;
|
||||||
|
|
||||||
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
|
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
|
||||||
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
|
std::shared_ptr<ReliableStreamConnection> FindConnectionByEndpoint(std::string addr, int port);
|
||||||
void SendDisconnect(const std::string &addr, int port);
|
void SendDisconnect(const std::string &addr, int port);
|
||||||
|
|
||||||
friend class DaybreakConnection;
|
friend class ReliableStreamConnection;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,7 +8,7 @@ namespace EQ
|
|||||||
{
|
{
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
struct DaybreakHeader
|
struct ReliableStreamHeader
|
||||||
{
|
{
|
||||||
static size_t size() { return 2; }
|
static size_t size() { return 2; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -22,7 +22,7 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakConnect
|
struct ReliableStreamConnect
|
||||||
{
|
{
|
||||||
static size_t size() { return 14; }
|
static size_t size() { return 14; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -42,7 +42,7 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakConnectReply
|
struct ReliableStreamConnectReply
|
||||||
{
|
{
|
||||||
static size_t size() { return 17; }
|
static size_t size() { return 17; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -68,7 +68,7 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakDisconnect
|
struct ReliableStreamDisconnect
|
||||||
{
|
{
|
||||||
static size_t size() { return 8; }
|
static size_t size() { return 8; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -84,7 +84,7 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakReliableHeader
|
struct ReliableStreamReliableHeader
|
||||||
{
|
{
|
||||||
static size_t size() { return 4; }
|
static size_t size() { return 4; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -100,10 +100,10 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakReliableFragmentHeader
|
struct ReliableStreamReliableFragmentHeader
|
||||||
{
|
{
|
||||||
static size_t size() { return 4 + DaybreakReliableHeader::size(); }
|
static size_t size() { return 4 + ReliableStreamReliableHeader::size(); }
|
||||||
DaybreakReliableHeader reliable;
|
ReliableStreamReliableHeader reliable;
|
||||||
uint32_t total_size;
|
uint32_t total_size;
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
@ -114,7 +114,7 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakSessionStatRequest
|
struct ReliableStreamSessionStatRequest
|
||||||
{
|
{
|
||||||
static size_t size() { return 40; }
|
static size_t size() { return 40; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -144,7 +144,7 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakSessionStatResponse
|
struct ReliableStreamSessionStatResponse
|
||||||
{
|
{
|
||||||
static size_t size() { return 40; }
|
static size_t size() { return 40; }
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
@ -319,7 +319,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
|||||||
size_t message_len = length;
|
size_t message_len = length;
|
||||||
EQ::Net::StaticPacket packet(&data[0], message_len);
|
EQ::Net::StaticPacket packet(&data[0], message_len);
|
||||||
|
|
||||||
const auto is_detail_enabled = LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
|
const auto is_detail_enabled = EQEmuLogSys::Instance()->IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
|
||||||
if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
|
if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
|
||||||
LogPacketServerToServer(
|
LogPacketServerToServer(
|
||||||
"[{:#06x}] Size [{}] {}",
|
"[{:#06x}] Size [{}] {}",
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "../event/event_loop.h"
|
#include "../event/event_loop.h"
|
||||||
#include "../event/timer.h"
|
#include "../event/timer.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "../util/uuid.h"
|
#include "../util/uuid.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
struct EQ::Net::WebsocketServerConnection::Impl {
|
struct EQ::Net::WebsocketServerConnection::Impl {
|
||||||
WebsocketServer *parent;
|
WebsocketServer *parent;
|
||||||
|
|||||||
@ -78,7 +78,7 @@ namespace RoF
|
|||||||
{
|
{
|
||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
|
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
@ -117,7 +117,7 @@ namespace RoF
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -81,7 +81,7 @@ namespace RoF2
|
|||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
|
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
|
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
@ -123,7 +123,7 @@ namespace RoF2
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
@ -6481,7 +6481,7 @@ namespace RoF2
|
|||||||
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
hdr.scaled_value = (inst->IsScaling() ? (inst->GetExp() / 100) : 0);
|
||||||
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
hdr.instance_id = (inst->GetMerchantSlot() ? inst->GetMerchantSlot() : inst->GetSerialNumber());
|
||||||
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
|
hdr.parcel_item_id = packet_type == ItemPacketParcel ? inst->GetID() : 0;
|
||||||
if (item->EvolvingItem) {
|
if (item->EvolvingItem && packet_type != ItemPacketParcel && packet_type != ItemPacketMerchant) {
|
||||||
hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword
|
hdr.instance_id = inst->GetEvolveUniqueID() & 0xFFFFFFFF; //lower dword
|
||||||
hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
|
hdr.parcel_item_id = inst->GetEvolveUniqueID() >> 32; //upper dword
|
||||||
}
|
}
|
||||||
@ -6500,6 +6500,7 @@ namespace RoF2
|
|||||||
|
|
||||||
if (item->EvolvingItem > 0) {
|
if (item->EvolvingItem > 0) {
|
||||||
RoF2::structs::EvolvingItem_Struct evotop;
|
RoF2::structs::EvolvingItem_Struct evotop;
|
||||||
|
inst->CalculateEvolveProgression();
|
||||||
|
|
||||||
evotop.final_item_id = inst->GetEvolveFinalItemID();
|
evotop.final_item_id = inst->GetEvolveFinalItemID();
|
||||||
evotop.evolve_level = item->EvolvingLevel;
|
evotop.evolve_level = item->EvolvingLevel;
|
||||||
|
|||||||
@ -72,7 +72,7 @@ namespace SoD
|
|||||||
{
|
{
|
||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
opcodes = new RegularOpcodeManager();
|
opcodes = new RegularOpcodeManager();
|
||||||
@ -113,7 +113,7 @@ namespace SoD
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
@ -3966,12 +3966,12 @@ namespace SoD
|
|||||||
SoDSlot = serverSlot - 2;
|
SoDSlot = serverSlot - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invbag::GENERAL_BAGS_8_END && serverSlot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
|
else if (serverSlot <= EQ::invbag::GENERAL_BAGS_END && serverSlot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
|
||||||
SoDSlot = serverSlot + 11;
|
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::CURSOR_BAG_END && serverSlot >= EQ::invbag::CURSOR_BAG_BEGIN) {
|
else if (serverSlot <= EQ::invbag::CURSOR_BAG_END && serverSlot >= EQ::invbag::CURSOR_BAG_BEGIN) {
|
||||||
SoDSlot = serverSlot - 9;
|
SoDSlot = serverSlot - (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invslot::TRIBUTE_END && serverSlot >= EQ::invslot::TRIBUTE_BEGIN) {
|
else if (serverSlot <= EQ::invslot::TRIBUTE_END && serverSlot >= EQ::invslot::TRIBUTE_BEGIN) {
|
||||||
@ -3991,7 +3991,7 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invbag::BANK_BAGS_END && serverSlot >= EQ::invbag::BANK_BAGS_BEGIN) {
|
else if (serverSlot <= EQ::invbag::BANK_BAGS_END && serverSlot >= EQ::invbag::BANK_BAGS_BEGIN) {
|
||||||
SoDSlot = serverSlot + 1;
|
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));;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invslot::SHARED_BANK_END && serverSlot >= EQ::invslot::SHARED_BANK_BEGIN) {
|
else if (serverSlot <= EQ::invslot::SHARED_BANK_END && serverSlot >= EQ::invslot::SHARED_BANK_BEGIN) {
|
||||||
@ -3999,7 +3999,7 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invbag::SHARED_BANK_BAGS_END && serverSlot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
|
else if (serverSlot <= EQ::invbag::SHARED_BANK_BAGS_END && serverSlot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
|
||||||
SoDSlot = serverSlot + 1;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invslot::TRADE_END && serverSlot >= EQ::invslot::TRADE_BEGIN) {
|
else if (serverSlot <= EQ::invslot::TRADE_END && serverSlot >= EQ::invslot::TRADE_BEGIN) {
|
||||||
@ -4007,7 +4007,7 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invbag::TRADE_BAGS_END && serverSlot >= EQ::invbag::TRADE_BAGS_BEGIN) {
|
else if (serverSlot <= EQ::invbag::TRADE_BAGS_END && serverSlot >= EQ::invbag::TRADE_BAGS_BEGIN) {
|
||||||
SoDSlot = serverSlot;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (serverSlot <= EQ::invslot::WORLD_END && serverSlot >= EQ::invslot::WORLD_BEGIN) {
|
else if (serverSlot <= EQ::invslot::WORLD_END && serverSlot >= EQ::invslot::WORLD_BEGIN) {
|
||||||
@ -4049,11 +4049,11 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invbag::GENERAL_BAGS_END && sod_slot >= invbag::GENERAL_BAGS_BEGIN) {
|
else if (sod_slot <= invbag::GENERAL_BAGS_END && sod_slot >= invbag::GENERAL_BAGS_BEGIN) {
|
||||||
server_slot = sod_slot - 11;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invbag::CURSOR_BAG_END && sod_slot >= invbag::CURSOR_BAG_BEGIN) {
|
else if (sod_slot <= invbag::CURSOR_BAG_END && sod_slot >= invbag::CURSOR_BAG_BEGIN) {
|
||||||
server_slot = sod_slot + 9;
|
server_slot = sod_slot + (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invslot::TRIBUTE_END && sod_slot >= invslot::TRIBUTE_BEGIN) {
|
else if (sod_slot <= invslot::TRIBUTE_END && sod_slot >= invslot::TRIBUTE_BEGIN) {
|
||||||
@ -4073,7 +4073,7 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invbag::BANK_BAGS_END && sod_slot >= invbag::BANK_BAGS_BEGIN) {
|
else if (sod_slot <= invbag::BANK_BAGS_END && sod_slot >= invbag::BANK_BAGS_BEGIN) {
|
||||||
server_slot = sod_slot - 1;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invslot::SHARED_BANK_END && sod_slot >= invslot::SHARED_BANK_BEGIN) {
|
else if (sod_slot <= invslot::SHARED_BANK_END && sod_slot >= invslot::SHARED_BANK_BEGIN) {
|
||||||
@ -4081,7 +4081,7 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invbag::SHARED_BANK_BAGS_END && sod_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
|
else if (sod_slot <= invbag::SHARED_BANK_BAGS_END && sod_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
|
||||||
server_slot = sod_slot - 1;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invslot::TRADE_END && sod_slot >= invslot::TRADE_BEGIN) {
|
else if (sod_slot <= invslot::TRADE_END && sod_slot >= invslot::TRADE_BEGIN) {
|
||||||
@ -4089,7 +4089,7 @@ namespace SoD
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invbag::TRADE_BAGS_END && sod_slot >= invbag::TRADE_BAGS_BEGIN) {
|
else if (sod_slot <= invbag::TRADE_BAGS_END && sod_slot >= invbag::TRADE_BAGS_BEGIN) {
|
||||||
server_slot = sod_slot;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sod_slot <= invslot::WORLD_END && sod_slot >= invslot::WORLD_BEGIN) {
|
else if (sod_slot <= invslot::WORLD_END && sod_slot >= invslot::WORLD_BEGIN) {
|
||||||
|
|||||||
@ -71,7 +71,7 @@ namespace SoF
|
|||||||
{
|
{
|
||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
opcodes = new RegularOpcodeManager();
|
opcodes = new RegularOpcodeManager();
|
||||||
@ -110,7 +110,7 @@ namespace SoF
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
@ -3355,12 +3355,12 @@ namespace SoF
|
|||||||
sof_slot = server_slot - 2;
|
sof_slot = server_slot - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invbag::GENERAL_BAGS_8_END && server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
|
else if (server_slot <= EQ::invbag::GENERAL_BAGS_END && server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
|
||||||
sof_slot = server_slot + 11;
|
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::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) {
|
else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) {
|
||||||
sof_slot = server_slot - 9;
|
sof_slot = server_slot - (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) {
|
else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) {
|
||||||
@ -3380,7 +3380,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invbag::BANK_BAGS_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
|
else if (server_slot <= EQ::invbag::BANK_BAGS_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
|
||||||
sof_slot = server_slot + 1;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
|
else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
|
||||||
@ -3388,7 +3388,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END && server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
|
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END && server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
|
||||||
sof_slot = server_slot + 1;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) {
|
else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) {
|
||||||
@ -3396,7 +3396,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) {
|
else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) {
|
||||||
sof_slot = server_slot;
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) {
|
else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) {
|
||||||
@ -3442,11 +3442,11 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invbag::GENERAL_BAGS_END && sof_slot >= invbag::GENERAL_BAGS_BEGIN) {
|
else if (sof_slot <= invbag::GENERAL_BAGS_END && sof_slot >= invbag::GENERAL_BAGS_BEGIN) {
|
||||||
server_slot = sof_slot - 11;
|
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));;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invbag::CURSOR_BAG_END && sof_slot >= invbag::CURSOR_BAG_BEGIN) {
|
else if (sof_slot <= invbag::CURSOR_BAG_END && sof_slot >= invbag::CURSOR_BAG_BEGIN) {
|
||||||
server_slot = sof_slot + 9;
|
server_slot = sof_slot + (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invslot::TRIBUTE_END && sof_slot >= invslot::TRIBUTE_BEGIN) {
|
else if (sof_slot <= invslot::TRIBUTE_END && sof_slot >= invslot::TRIBUTE_BEGIN) {
|
||||||
@ -3466,7 +3466,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invbag::BANK_BAGS_END && sof_slot >= invbag::BANK_BAGS_BEGIN) {
|
else if (sof_slot <= invbag::BANK_BAGS_END && sof_slot >= invbag::BANK_BAGS_BEGIN) {
|
||||||
server_slot = sof_slot - 1;
|
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));;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invslot::SHARED_BANK_END && sof_slot >= invslot::SHARED_BANK_BEGIN) {
|
else if (sof_slot <= invslot::SHARED_BANK_END && sof_slot >= invslot::SHARED_BANK_BEGIN) {
|
||||||
@ -3474,7 +3474,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invbag::SHARED_BANK_BAGS_END && sof_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
|
else if (sof_slot <= invbag::SHARED_BANK_BAGS_END && sof_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
|
||||||
server_slot = sof_slot - 1;
|
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));;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invslot::TRADE_END && sof_slot >= invslot::TRADE_BEGIN) {
|
else if (sof_slot <= invslot::TRADE_END && sof_slot >= invslot::TRADE_BEGIN) {
|
||||||
@ -3482,7 +3482,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invbag::TRADE_BAGS_END && sof_slot >= invbag::TRADE_BAGS_BEGIN) {
|
else if (sof_slot <= invbag::TRADE_BAGS_END && sof_slot >= invbag::TRADE_BAGS_BEGIN) {
|
||||||
server_slot = sof_slot;
|
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));;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sof_slot <= invslot::WORLD_END && sof_slot >= invslot::WORLD_BEGIN) {
|
else if (sof_slot <= invslot::WORLD_END && sof_slot >= invslot::WORLD_BEGIN) {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ namespace Titanium
|
|||||||
auto Config = EQEmuConfig::get();
|
auto Config = EQEmuConfig::get();
|
||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
opcodes = new RegularOpcodeManager();
|
opcodes = new RegularOpcodeManager();
|
||||||
@ -114,7 +114,7 @@ namespace Titanium
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
@ -1059,7 +1059,7 @@ namespace Titanium
|
|||||||
OUT(spawnid);
|
OUT(spawnid);
|
||||||
OUT_str(charname);
|
OUT_str(charname);
|
||||||
|
|
||||||
if (emu->race > 473)
|
if (emu->race > 474)
|
||||||
eq->race = 1;
|
eq->race = 1;
|
||||||
else
|
else
|
||||||
OUT(race);
|
OUT(race);
|
||||||
@ -1840,7 +1840,7 @@ namespace Titanium
|
|||||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||||
|
|
||||||
eq->Race[char_index] = emu_cse->Race;
|
eq->Race[char_index] = emu_cse->Race;
|
||||||
if (eq->Race[char_index] > 473)
|
if (eq->Race[char_index] > 474)
|
||||||
eq->Race[char_index] = 1;
|
eq->Race[char_index] = 1;
|
||||||
|
|
||||||
for (int index = 0; index < EQ::textures::materialCount; ++index) {
|
for (int index = 0; index < EQ::textures::materialCount; ++index) {
|
||||||
@ -2421,7 +2421,7 @@ namespace Titanium
|
|||||||
strcpy(eq->title, emu->title);
|
strcpy(eq->title, emu->title);
|
||||||
// eq->unknown0274 = emu->unknown0274;
|
// eq->unknown0274 = emu->unknown0274;
|
||||||
eq->helm = emu->helm;
|
eq->helm = emu->helm;
|
||||||
if (emu->race > 473)
|
if (emu->race > 474)
|
||||||
eq->race = 1;
|
eq->race = 1;
|
||||||
else
|
else
|
||||||
eq->race = emu->race;
|
eq->race = emu->race;
|
||||||
@ -3596,12 +3596,12 @@ namespace Titanium
|
|||||||
else if (server_slot == (EQ::invslot::POSSESSIONS_COUNT + EQ::invslot::slotAmmo)) {
|
else if (server_slot == (EQ::invslot::POSSESSIONS_COUNT + EQ::invslot::slotAmmo)) {
|
||||||
titanium_slot = server_slot - 4;
|
titanium_slot = server_slot - 4;
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invbag::GENERAL_BAGS_8_END &&
|
else if (server_slot <= EQ::invbag::GENERAL_BAGS_END &&
|
||||||
server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
|
server_slot >= EQ::invbag::GENERAL_BAGS_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) {
|
else if (server_slot <= EQ::invbag::CURSOR_BAG_END && server_slot >= EQ::invbag::CURSOR_BAG_BEGIN) {
|
||||||
titanium_slot = server_slot - 20;
|
titanium_slot = server_slot - (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN);
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) {
|
else if (server_slot <= EQ::invslot::TRIBUTE_END && server_slot >= EQ::invslot::TRIBUTE_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
titanium_slot = server_slot;
|
||||||
@ -3616,21 +3616,21 @@ namespace Titanium
|
|||||||
else if (server_slot <= EQ::invslot::BANK_END && server_slot >= EQ::invslot::BANK_BEGIN) {
|
else if (server_slot <= EQ::invslot::BANK_END && server_slot >= EQ::invslot::BANK_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
titanium_slot = server_slot;
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invbag::BANK_BAGS_16_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
|
else if (server_slot <= EQ::invbag::BANK_BAGS_END && server_slot >= EQ::invbag::BANK_BAGS_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
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::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
|
else if (server_slot <= EQ::invslot::SHARED_BANK_END && server_slot >= EQ::invslot::SHARED_BANK_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
titanium_slot = server_slot;
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END &&
|
else if (server_slot <= EQ::invbag::SHARED_BANK_BAGS_END &&
|
||||||
server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
|
server_slot >= EQ::invbag::SHARED_BANK_BAGS_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) {
|
else if (server_slot <= EQ::invslot::TRADE_END && server_slot >= EQ::invslot::TRADE_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
titanium_slot = server_slot;
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) {
|
else if (server_slot <= EQ::invbag::TRADE_BAGS_END && server_slot >= EQ::invbag::TRADE_BAGS_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) {
|
else if (server_slot <= EQ::invslot::WORLD_END && server_slot >= EQ::invslot::WORLD_BEGIN) {
|
||||||
titanium_slot = server_slot;
|
titanium_slot = server_slot;
|
||||||
@ -3687,10 +3687,10 @@ namespace Titanium
|
|||||||
server_slot = titanium_slot + 4;
|
server_slot = titanium_slot + 4;
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invbag::GENERAL_BAGS_END && titanium_slot >= invbag::GENERAL_BAGS_BEGIN) {
|
else if (titanium_slot <= invbag::GENERAL_BAGS_END && titanium_slot >= invbag::GENERAL_BAGS_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invbag::CURSOR_BAG_END && titanium_slot >= invbag::CURSOR_BAG_BEGIN) {
|
else if (titanium_slot <= invbag::CURSOR_BAG_END && titanium_slot >= invbag::CURSOR_BAG_BEGIN) {
|
||||||
server_slot = titanium_slot + 20;
|
server_slot = titanium_slot + (EQ::invbag::CURSOR_BAG_BEGIN - invbag::CURSOR_BAG_BEGIN);
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invslot::TRIBUTE_END && titanium_slot >= invslot::TRIBUTE_BEGIN) {
|
else if (titanium_slot <= invslot::TRIBUTE_END && titanium_slot >= invslot::TRIBUTE_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
server_slot = titanium_slot;
|
||||||
@ -3705,19 +3705,19 @@ namespace Titanium
|
|||||||
server_slot = titanium_slot;
|
server_slot = titanium_slot;
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invbag::BANK_BAGS_END && titanium_slot >= invbag::BANK_BAGS_BEGIN) {
|
else if (titanium_slot <= invbag::BANK_BAGS_END && titanium_slot >= invbag::BANK_BAGS_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invslot::SHARED_BANK_END && titanium_slot >= invslot::SHARED_BANK_BEGIN) {
|
else if (titanium_slot <= invslot::SHARED_BANK_END && titanium_slot >= invslot::SHARED_BANK_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
server_slot = titanium_slot;
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invbag::SHARED_BANK_BAGS_END && titanium_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
|
else if (titanium_slot <= invbag::SHARED_BANK_BAGS_END && titanium_slot >= invbag::SHARED_BANK_BAGS_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invslot::TRADE_END && titanium_slot >= invslot::TRADE_BEGIN) {
|
else if (titanium_slot <= invslot::TRADE_END && titanium_slot >= invslot::TRADE_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
server_slot = titanium_slot;
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invbag::TRADE_BAGS_END && titanium_slot >= invbag::TRADE_BAGS_BEGIN) {
|
else if (titanium_slot <= invbag::TRADE_BAGS_END && titanium_slot >= invbag::TRADE_BAGS_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
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));
|
||||||
}
|
}
|
||||||
else if (titanium_slot <= invslot::WORLD_END && titanium_slot >= invslot::WORLD_BEGIN) {
|
else if (titanium_slot <= invslot::WORLD_END && titanium_slot >= invslot::WORLD_BEGIN) {
|
||||||
server_slot = titanium_slot;
|
server_slot = titanium_slot;
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
#include "../raid.h"
|
#include "../raid.h"
|
||||||
#include "../guilds.h"
|
#include "../guilds.h"
|
||||||
//#include "../repositories/trader_repository.h"
|
//#include "../repositories/trader_repository.h"
|
||||||
#include "../cereal/include/cereal/types/vector.hpp"
|
#include <cereal/types/vector.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -76,7 +76,7 @@ namespace UF
|
|||||||
{
|
{
|
||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
opcodes = new RegularOpcodeManager();
|
opcodes = new RegularOpcodeManager();
|
||||||
@ -117,7 +117,7 @@ namespace UF
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
std::string opfile = fmt::format("{}/patch_{}.conf", PathManager::Instance()->GetPatchPath(), name);
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
void PathManager::LoadPaths()
|
void PathManager::Init()
|
||||||
{
|
{
|
||||||
m_server_path = File::FindEqemuConfigPath();
|
m_server_path = File::FindEqemuConfigPath();
|
||||||
|
|
||||||
@ -48,10 +48,23 @@ void PathManager::LoadPaths()
|
|||||||
return dir;
|
return dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto load_many_paths_fallback = [&](const std::vector<std::string>& dirs, const std::string& fallback, std::vector<std::string>& target) {
|
||||||
|
target.clear();
|
||||||
|
if (!dirs.empty()) {
|
||||||
|
for (const auto& path : dirs) {
|
||||||
|
target.push_back(resolve_path(path));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
target.push_back(resolve_path(fallback));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
load_many_paths_fallback(c->GetQuestDirectories(), c->QuestDir, m_quests_paths);
|
||||||
|
load_many_paths_fallback(c->GetPluginsDirectories(), c->PluginDir, m_plugin_paths);
|
||||||
|
load_many_paths_fallback(c->GetLuaModuleDirectories(), c->LuaModuleDir, m_lua_module_paths);
|
||||||
|
|
||||||
|
// resolve all paths
|
||||||
m_maps_path = resolve_path(c->MapDir, {"maps", "Maps"});
|
m_maps_path = resolve_path(c->MapDir, {"maps", "Maps"});
|
||||||
m_quests_path = resolve_path(c->QuestDir);
|
|
||||||
m_plugins_path = resolve_path(c->PluginDir);
|
|
||||||
m_lua_modules_path = resolve_path(c->LuaModuleDir);
|
|
||||||
m_lua_mods_path = resolve_path("mods");
|
m_lua_mods_path = resolve_path("mods");
|
||||||
m_patch_path = resolve_path(c->PatchDir);
|
m_patch_path = resolve_path(c->PatchDir);
|
||||||
m_opcode_path = resolve_path(c->OpcodeDir);
|
m_opcode_path = resolve_path(c->OpcodeDir);
|
||||||
@ -62,13 +75,10 @@ void PathManager::LoadPaths()
|
|||||||
std::vector<std::pair<std::string, std::string>> paths = {
|
std::vector<std::pair<std::string, std::string>> paths = {
|
||||||
{"server", m_server_path},
|
{"server", m_server_path},
|
||||||
{"logs", m_log_path},
|
{"logs", m_log_path},
|
||||||
{"lua mods", m_lua_mods_path},
|
|
||||||
{"lua_modules", m_lua_modules_path},
|
|
||||||
{"maps", m_maps_path},
|
{"maps", m_maps_path},
|
||||||
|
{"lua mods", m_lua_mods_path},
|
||||||
{"patches", m_patch_path},
|
{"patches", m_patch_path},
|
||||||
{"opcode", m_opcode_path},
|
{"opcode", m_opcode_path},
|
||||||
{"plugins", m_plugins_path},
|
|
||||||
{"quests", m_quests_path},
|
|
||||||
{"shared_memory", m_shared_memory_path}
|
{"shared_memory", m_shared_memory_path}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,6 +93,17 @@ void PathManager::LoadPaths()
|
|||||||
LogInfo("{:>{}} > [{:<{}}]", name, name_width, in_path, path_width);
|
LogInfo("{:>{}} > [{:<{}}]", name, name_width, in_path, path_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto log_paths = [&](const std::string& label, const std::vector<std::string>& paths) {
|
||||||
|
if (!paths.empty()) {
|
||||||
|
LogInfo("{:>{}} > [{:<{}}]", label, name_width - 1, Strings::Join(paths, ";"), path_width);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
log_paths("quests", m_quests_paths);
|
||||||
|
log_paths("plugins", m_plugin_paths);
|
||||||
|
log_paths("lua_modules", m_lua_module_paths);
|
||||||
|
|
||||||
LogInfo("{}", Strings::Repeat("-", break_length));
|
LogInfo("{}", Strings::Repeat("-", break_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,21 +117,26 @@ const std::string &PathManager::GetMapsPath() const
|
|||||||
return m_maps_path;
|
return m_maps_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &PathManager::GetQuestsPath() const
|
|
||||||
{
|
|
||||||
return m_quests_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &PathManager::GetPluginsPath() const
|
|
||||||
{
|
|
||||||
return m_plugins_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &PathManager::GetSharedMemoryPath() const
|
const std::string &PathManager::GetSharedMemoryPath() const
|
||||||
{
|
{
|
||||||
return m_shared_memory_path;
|
return m_shared_memory_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PathManager::GetQuestPaths() const
|
||||||
|
{
|
||||||
|
return m_quests_paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PathManager::GetPluginPaths() const
|
||||||
|
{
|
||||||
|
return m_plugin_paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> PathManager::GetLuaModulePaths() const
|
||||||
|
{
|
||||||
|
return m_lua_module_paths;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string &PathManager::GetLogPath() const
|
const std::string &PathManager::GetLogPath() const
|
||||||
{
|
{
|
||||||
return m_log_path;
|
return m_log_path;
|
||||||
@ -126,11 +152,6 @@ const std::string &PathManager::GetOpcodePath() const
|
|||||||
return m_opcode_path;
|
return m_opcode_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &PathManager::GetLuaModulesPath() const
|
|
||||||
{
|
|
||||||
return m_lua_modules_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &PathManager::GetLuaModsPath() const
|
const std::string &PathManager::GetLuaModsPath() const
|
||||||
{
|
{
|
||||||
return m_lua_mods_path;
|
return m_lua_mods_path;
|
||||||
|
|||||||
@ -3,10 +3,17 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class PathManager {
|
class PathManager {
|
||||||
public:
|
public:
|
||||||
void LoadPaths();
|
void Init();
|
||||||
|
|
||||||
|
static PathManager *Instance()
|
||||||
|
{
|
||||||
|
static PathManager instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] const std::string &GetLogPath() const;
|
[[nodiscard]] const std::string &GetLogPath() const;
|
||||||
[[nodiscard]] const std::string &GetLuaModsPath() const;
|
[[nodiscard]] const std::string &GetLuaModsPath() const;
|
||||||
@ -14,24 +21,27 @@ public:
|
|||||||
[[nodiscard]] const std::string &GetMapsPath() const;
|
[[nodiscard]] const std::string &GetMapsPath() const;
|
||||||
[[nodiscard]] const std::string &GetPatchPath() const;
|
[[nodiscard]] const std::string &GetPatchPath() const;
|
||||||
[[nodiscard]] const std::string &GetOpcodePath() const;
|
[[nodiscard]] const std::string &GetOpcodePath() const;
|
||||||
[[nodiscard]] const std::string &GetPluginsPath() const;
|
|
||||||
[[nodiscard]] const std::string &GetQuestsPath() const;
|
|
||||||
[[nodiscard]] const std::string &GetServerPath() const;
|
[[nodiscard]] const std::string &GetServerPath() const;
|
||||||
[[nodiscard]] const std::string &GetSharedMemoryPath() const;
|
[[nodiscard]] const std::string &GetSharedMemoryPath() const;
|
||||||
|
[[nodiscard]] std::vector<std::string> GetQuestPaths() const;
|
||||||
|
[[nodiscard]] std::vector<std::string> GetPluginPaths() const;
|
||||||
|
[[nodiscard]] std::vector<std::string> GetLuaModulePaths() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_log_path;
|
std::string m_log_path;
|
||||||
std::string m_lua_mods_path;
|
std::string m_lua_mods_path;
|
||||||
std::string m_lua_modules_path;
|
std::string m_maps_path;
|
||||||
std::string m_maps_path;
|
std::string m_patch_path;
|
||||||
std::string m_patch_path;
|
std::string m_opcode_path;
|
||||||
std::string m_opcode_path;
|
std::string m_quests_path;
|
||||||
std::string m_plugins_path;
|
std::vector<std::string> m_quests_paths;
|
||||||
std::string m_quests_path;
|
std::vector<std::string> m_plugin_paths;
|
||||||
std::string m_server_path;
|
std::vector<std::string> m_lua_module_paths;
|
||||||
std::string m_shared_memory_path;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_server_path;
|
||||||
|
std::string m_shared_memory_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern PathManager path;
|
|
||||||
|
|
||||||
#endif //EQEMU_PATH_MANAGER_H
|
#endif //EQEMU_PATH_MANAGER_H
|
||||||
|
|||||||
9
common/pch/app-pch.h
Normal file
9
common/pch/app-pch.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#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"
|
||||||
@ -1,34 +0,0 @@
|
|||||||
// 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>
|
|
||||||
14
common/pch/std-pch.h
Normal file
14
common/pch/std-pch.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#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>
|
||||||
@ -1,6 +1,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
std::string Process::execute(const std::string &cmd)
|
std::string Process::execute(const std::string &cmd)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/ranges.h>
|
||||||
|
|
||||||
class DBcore;
|
class DBcore;
|
||||||
|
|
||||||
|
|||||||
3779
common/races.cpp
3779
common/races.cpp
File diff suppressed because it is too large
Load Diff
202
common/races.h
202
common/races.h
@ -21,103 +21,7 @@
|
|||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Gender {
|
|
||||||
constexpr uint8 Male = 0;
|
|
||||||
constexpr uint8 Female = 1;
|
|
||||||
constexpr uint8 Neuter = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//theres a big list straight from the client below.
|
|
||||||
|
|
||||||
#define HUMAN 1
|
|
||||||
#define BARBARIAN 2
|
|
||||||
#define ERUDITE 3
|
|
||||||
#define WOOD_ELF 4
|
|
||||||
#define HIGH_ELF 5
|
|
||||||
#define DARK_ELF 6
|
|
||||||
#define HALF_ELF 7
|
|
||||||
#define DWARF 8
|
|
||||||
#define TROLL 9
|
|
||||||
#define OGRE 10
|
|
||||||
#define HALFLING 11
|
|
||||||
#define GNOME 12
|
|
||||||
#define WEREWOLF 14
|
|
||||||
#define WOLF 42
|
|
||||||
#define BEAR 43
|
|
||||||
#define SKELETON 60
|
|
||||||
#define TIGER 63
|
|
||||||
#define ELEMENTAL 75
|
|
||||||
#define ALLIGATOR 91
|
|
||||||
#define OGGOK_CITIZEN 93
|
|
||||||
#define EYE_OF_ZOMM 108
|
|
||||||
#define WOLF_ELEMENTAL 120
|
|
||||||
#define INVISIBLE_MAN 127
|
|
||||||
#define IKSAR 128
|
|
||||||
#define VAHSHIR 130
|
|
||||||
#define CONTROLLED_BOAT 141
|
|
||||||
#define MINOR_ILL_OBJ 142
|
|
||||||
#define TREE 143
|
|
||||||
#define IKSAR_SKELETON 161
|
|
||||||
#define FROGLOK 330
|
|
||||||
// TODO: check all clients for (BYTE) usage of '/who all' class and remove FROGLOK2, if possible (330 - 74 = 256 .. WORD->BYTE conversion loss...)
|
|
||||||
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks
|
|
||||||
#define FAIRY 473
|
|
||||||
#define DRAKKIN 522 // 32768
|
|
||||||
#define EMU_RACE_NPC 131069 // was 65533
|
|
||||||
#define EMU_RACE_PET 131070 // was 65534
|
|
||||||
#define EMU_RACE_UNKNOWN 131071 // was 65535
|
|
||||||
|
|
||||||
|
|
||||||
// player race values
|
|
||||||
#define PLAYER_RACE_UNKNOWN 0
|
|
||||||
#define PLAYER_RACE_HUMAN 1
|
|
||||||
#define PLAYER_RACE_BARBARIAN 2
|
|
||||||
#define PLAYER_RACE_ERUDITE 3
|
|
||||||
#define PLAYER_RACE_WOOD_ELF 4
|
|
||||||
#define PLAYER_RACE_HIGH_ELF 5
|
|
||||||
#define PLAYER_RACE_DARK_ELF 6
|
|
||||||
#define PLAYER_RACE_HALF_ELF 7
|
|
||||||
#define PLAYER_RACE_DWARF 8
|
|
||||||
#define PLAYER_RACE_TROLL 9
|
|
||||||
#define PLAYER_RACE_OGRE 10
|
|
||||||
#define PLAYER_RACE_HALFLING 11
|
|
||||||
#define PLAYER_RACE_GNOME 12
|
|
||||||
#define PLAYER_RACE_IKSAR 13
|
|
||||||
#define PLAYER_RACE_VAHSHIR 14
|
|
||||||
#define PLAYER_RACE_FROGLOK 15
|
|
||||||
#define PLAYER_RACE_DRAKKIN 16
|
|
||||||
|
|
||||||
#define PLAYER_RACE_COUNT 16
|
|
||||||
|
|
||||||
|
|
||||||
#define PLAYER_RACE_EMU_NPC 17
|
|
||||||
#define PLAYER_RACE_EMU_PET 18
|
|
||||||
#define PLAYER_RACE_EMU_COUNT 19
|
|
||||||
|
|
||||||
|
|
||||||
// player race bits
|
|
||||||
#define PLAYER_RACE_UNKNOWN_BIT 0
|
|
||||||
#define PLAYER_RACE_HUMAN_BIT 1
|
|
||||||
#define PLAYER_RACE_BARBARIAN_BIT 2
|
|
||||||
#define PLAYER_RACE_ERUDITE_BIT 4
|
|
||||||
#define PLAYER_RACE_WOOD_ELF_BIT 8
|
|
||||||
#define PLAYER_RACE_HIGH_ELF_BIT 16
|
|
||||||
#define PLAYER_RACE_DARK_ELF_BIT 32
|
|
||||||
#define PLAYER_RACE_HALF_ELF_BIT 64
|
|
||||||
#define PLAYER_RACE_DWARF_BIT 128
|
|
||||||
#define PLAYER_RACE_TROLL_BIT 256
|
|
||||||
#define PLAYER_RACE_OGRE_BIT 512
|
|
||||||
#define PLAYER_RACE_HALFLING_BIT 1024
|
|
||||||
#define PLAYER_RACE_GNOME_BIT 2048
|
|
||||||
#define PLAYER_RACE_IKSAR_BIT 4096
|
|
||||||
#define PLAYER_RACE_VAHSHIR_BIT 8192
|
|
||||||
#define PLAYER_RACE_FROGLOK_BIT 16384
|
|
||||||
#define PLAYER_RACE_DRAKKIN_BIT 32768
|
|
||||||
|
|
||||||
#define PLAYER_RACE_ALL_MASK 65535
|
|
||||||
|
|
||||||
const char* GetRaceIDName(uint16 race_id);
|
const char* GetRaceIDName(uint16 race_id);
|
||||||
const char* GetPlayerRaceName(uint32 player_race_value);
|
|
||||||
const char* GetGenderName(uint32 gender_id);
|
const char* GetGenderName(uint32 gender_id);
|
||||||
|
|
||||||
bool IsPlayerRace(uint16 race_id);
|
bool IsPlayerRace(uint16 race_id);
|
||||||
@ -127,25 +31,13 @@ uint32 GetPlayerRaceValue(uint16 race_id);
|
|||||||
uint16 GetPlayerRaceBit(uint16 race_id);
|
uint16 GetPlayerRaceBit(uint16 race_id);
|
||||||
|
|
||||||
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
|
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
|
||||||
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
|
|
||||||
|
|
||||||
float GetRaceGenderDefaultHeight(int race, int gender);
|
float GetRaceGenderDefaultHeight(int race, int gender);
|
||||||
|
|
||||||
// player race-/gender-based model feature validators
|
namespace Gender {
|
||||||
namespace PlayerAppearance
|
constexpr uint8 Male = 0;
|
||||||
{
|
constexpr uint8 Female = 1;
|
||||||
bool IsValidBeard(uint16 race_id, uint8 gender_id, uint8 beard_value, bool use_luclin = true);
|
constexpr uint8 Neuter = 2;
|
||||||
bool IsValidBeardColor(uint16 race_id, uint8 gender_id, uint8 beard_color_value, bool use_luclin = true);
|
|
||||||
bool IsValidDetail(uint16 race_id, uint8 gender_id, uint32 detail_value, bool use_luclin = true);
|
|
||||||
bool IsValidEyeColor(uint16 race_id, uint8 gender_id, uint8 eye_color_value, bool use_luclin = true);
|
|
||||||
bool IsValidFace(uint16 race_id, uint8 gender_id, uint8 face_value, bool use_luclin = true);
|
|
||||||
bool IsValidHair(uint16 race_id, uint8 gender_id, uint8 hair_value, bool use_luclin = true);
|
|
||||||
bool IsValidHairColor(uint16 race_id, uint8 gender_id, uint8 hair_color_value, bool use_luclin = true);
|
|
||||||
bool IsValidHead(uint16 race_id, uint8 gender_id, uint8 head_value, bool use_luclin = true);
|
|
||||||
bool IsValidHeritage(uint16 race_id, uint8 gender_id, uint32 heritage_value, bool use_luclin = true);
|
|
||||||
bool IsValidTattoo(uint16 race_id, uint8 gender_id, uint32 tattoo_value, bool use_luclin = true);
|
|
||||||
bool IsValidTexture(uint16 race_id, uint8 gender_id, uint8 texture_value, bool use_luclin = true);
|
|
||||||
bool IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_value, bool use_luclin = true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Race {
|
namespace Race {
|
||||||
@ -884,8 +776,92 @@ namespace Race {
|
|||||||
constexpr uint16 Pegasus3 = 732;
|
constexpr uint16 Pegasus3 = 732;
|
||||||
constexpr uint16 InteractiveObject = 2250;
|
constexpr uint16 InteractiveObject = 2250;
|
||||||
constexpr uint16 Node = 2254;
|
constexpr uint16 Node = 2254;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr uint16 ALL_RACES_BITMASK = 65535;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -116,6 +116,12 @@ namespace EQ {
|
|||||||
Reseed();
|
Reseed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Random* Instance()
|
||||||
|
{
|
||||||
|
static Random instance;
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifndef BIASED_INT_DIST
|
#ifndef BIASED_INT_DIST
|
||||||
typedef std::uniform_int_distribution<int>::param_type int_param_t;
|
typedef std::uniform_int_distribution<int>::param_type int_param_t;
|
||||||
|
|||||||
@ -70,6 +70,7 @@ public:
|
|||||||
uint32_t gm_exp;
|
uint32_t gm_exp;
|
||||||
uint32_t killed_by;
|
uint32_t killed_by;
|
||||||
uint8_t rezzable;
|
uint8_t rezzable;
|
||||||
|
std::string entity_variables;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@ -131,6 +132,7 @@ public:
|
|||||||
"gm_exp",
|
"gm_exp",
|
||||||
"killed_by",
|
"killed_by",
|
||||||
"rezzable",
|
"rezzable",
|
||||||
|
"entity_variables",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,6 +190,7 @@ public:
|
|||||||
"gm_exp",
|
"gm_exp",
|
||||||
"killed_by",
|
"killed_by",
|
||||||
"rezzable",
|
"rezzable",
|
||||||
|
"entity_variables",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +282,7 @@ public:
|
|||||||
e.gm_exp = 0;
|
e.gm_exp = 0;
|
||||||
e.killed_by = 0;
|
e.killed_by = 0;
|
||||||
e.rezzable = 0;
|
e.rezzable = 0;
|
||||||
|
e.entity_variables = "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -366,6 +370,7 @@ public:
|
|||||||
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
|
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
|
||||||
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
|
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
|
||||||
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
||||||
|
e.entity_variables = row[51] ? row[51] : "";
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -449,6 +454,7 @@ public:
|
|||||||
v.push_back(columns[48] + " = " + std::to_string(e.gm_exp));
|
v.push_back(columns[48] + " = " + std::to_string(e.gm_exp));
|
||||||
v.push_back(columns[49] + " = " + std::to_string(e.killed_by));
|
v.push_back(columns[49] + " = " + std::to_string(e.killed_by));
|
||||||
v.push_back(columns[50] + " = " + std::to_string(e.rezzable));
|
v.push_back(columns[50] + " = " + std::to_string(e.rezzable));
|
||||||
|
v.push_back(columns[51] + " = '" + Strings::Escape(e.entity_variables) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -521,6 +527,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.gm_exp));
|
v.push_back(std::to_string(e.gm_exp));
|
||||||
v.push_back(std::to_string(e.killed_by));
|
v.push_back(std::to_string(e.killed_by));
|
||||||
v.push_back(std::to_string(e.rezzable));
|
v.push_back(std::to_string(e.rezzable));
|
||||||
|
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -601,6 +608,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.gm_exp));
|
v.push_back(std::to_string(e.gm_exp));
|
||||||
v.push_back(std::to_string(e.killed_by));
|
v.push_back(std::to_string(e.killed_by));
|
||||||
v.push_back(std::to_string(e.rezzable));
|
v.push_back(std::to_string(e.rezzable));
|
||||||
|
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@ -685,6 +693,7 @@ public:
|
|||||||
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
|
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
|
||||||
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
|
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
|
||||||
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
||||||
|
e.entity_variables = row[51] ? row[51] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -760,6 +769,7 @@ public:
|
|||||||
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
|
e.gm_exp = row[48] ? static_cast<uint32_t>(strtoul(row[48], nullptr, 10)) : 0;
|
||||||
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
|
e.killed_by = row[49] ? static_cast<uint32_t>(strtoul(row[49], nullptr, 10)) : 0;
|
||||||
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
e.rezzable = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
|
||||||
|
e.entity_variables = row[51] ? row[51] : "";
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -885,6 +895,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.gm_exp));
|
v.push_back(std::to_string(e.gm_exp));
|
||||||
v.push_back(std::to_string(e.killed_by));
|
v.push_back(std::to_string(e.killed_by));
|
||||||
v.push_back(std::to_string(e.rezzable));
|
v.push_back(std::to_string(e.rezzable));
|
||||||
|
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -958,6 +969,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.gm_exp));
|
v.push_back(std::to_string(e.gm_exp));
|
||||||
v.push_back(std::to_string(e.killed_by));
|
v.push_back(std::to_string(e.killed_by));
|
||||||
v.push_back(std::to_string(e.rezzable));
|
v.push_back(std::to_string(e.rezzable));
|
||||||
|
v.push_back("'" + Strings::Escape(e.entity_variables) + "'");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ public:
|
|||||||
uint32_t aug_slot_5;
|
uint32_t aug_slot_5;
|
||||||
uint32_t aug_slot_6;
|
uint32_t aug_slot_6;
|
||||||
uint32_t quantity;
|
uint32_t quantity;
|
||||||
|
uint32_t evolve_amount;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@ -51,6 +52,7 @@ public:
|
|||||||
"aug_slot_5",
|
"aug_slot_5",
|
||||||
"aug_slot_6",
|
"aug_slot_6",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"evolve_amount",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ public:
|
|||||||
"aug_slot_5",
|
"aug_slot_5",
|
||||||
"aug_slot_6",
|
"aug_slot_6",
|
||||||
"quantity",
|
"quantity",
|
||||||
|
"evolve_amount",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,17 +111,18 @@ public:
|
|||||||
{
|
{
|
||||||
CharacterParcelsContainers e{};
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
e.id = 0;
|
e.id = 0;
|
||||||
e.parcels_id = 0;
|
e.parcels_id = 0;
|
||||||
e.slot_id = 0;
|
e.slot_id = 0;
|
||||||
e.item_id = 0;
|
e.item_id = 0;
|
||||||
e.aug_slot_1 = 0;
|
e.aug_slot_1 = 0;
|
||||||
e.aug_slot_2 = 0;
|
e.aug_slot_2 = 0;
|
||||||
e.aug_slot_3 = 0;
|
e.aug_slot_3 = 0;
|
||||||
e.aug_slot_4 = 0;
|
e.aug_slot_4 = 0;
|
||||||
e.aug_slot_5 = 0;
|
e.aug_slot_5 = 0;
|
||||||
e.aug_slot_6 = 0;
|
e.aug_slot_6 = 0;
|
||||||
e.quantity = 0;
|
e.quantity = 0;
|
||||||
|
e.evolve_amount = 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -155,17 +159,18 @@ public:
|
|||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1) {
|
||||||
CharacterParcelsContainers e{};
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@ -209,6 +214,7 @@ public:
|
|||||||
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
|
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
|
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
|
||||||
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
|
||||||
|
v.push_back(columns[11] + " = " + std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -241,6 +247,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -281,6 +288,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@ -314,17 +322,18 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
CharacterParcelsContainers e{};
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -349,17 +358,18 @@ public:
|
|||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
CharacterParcelsContainers e{};
|
CharacterParcelsContainers e{};
|
||||||
|
|
||||||
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||||
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
|
||||||
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
|
||||||
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
|
||||||
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
|
||||||
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
|
||||||
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
|
||||||
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
|
||||||
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
|
||||||
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
|
||||||
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
|
||||||
|
e.evolve_amount = row[11] ? static_cast<uint32_t>(strtoul(row[11], nullptr, 10)) : 0;
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@ -445,6 +455,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@ -478,6 +489,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.aug_slot_5));
|
v.push_back(std::to_string(e.aug_slot_5));
|
||||||
v.push_back(std::to_string(e.aug_slot_6));
|
v.push_back(std::to_string(e.aug_slot_6));
|
||||||
v.push_back(std::to_string(e.quantity));
|
v.push_back(std::to_string(e.quantity));
|
||||||
|
v.push_back(std::to_string(e.evolve_amount));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user