mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b3f9f356d | ||
|
|
e42dc2e1d2 | ||
|
|
c611a25385 | ||
|
|
f74efcaa5f | ||
|
|
eb4e7d694c | ||
|
|
ecc0d4b5c0 | ||
|
|
8175ae6187 | ||
|
|
e8f4ffd628 | ||
|
|
0447618f7e | ||
|
|
e71ce001ff |
11
.devcontainer/.gitignore
vendored
11
.devcontainer/.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
!Makefile
|
||||
base/*.sql
|
||||
base/*.zip
|
||||
base/db/
|
||||
base/maps/
|
||||
!base/expansion/Makefile
|
||||
base/
|
||||
!base/*.json
|
||||
override/
|
||||
repo/
|
||||
cache/
|
||||
|
||||
@ -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
|
||||
.ONESHELL:
|
||||
|
||||
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
|
||||
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
|
||||
|
||||
.PHONY: cmake
|
||||
cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
mkdir -p build$$BUILD_SUFFIX
|
||||
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_TESTS=ON \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
|
||||
|
||||
clean:
|
||||
ifneq (,$(findstring .devcontainer,$$PWD))
|
||||
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
|
||||
endif
|
||||
rm -rf build
|
||||
|
||||
docker-cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARGS} make cmake
|
||||
|
||||
docker-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARGS} make build
|
||||
|
||||
# Build image if it doesn't exist
|
||||
docker-image-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.dev -t ${NAME} .
|
||||
endif
|
||||
|
||||
docker-arm-cmake: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-build: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-image-build:
|
||||
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
|
||||
endif
|
||||
|
||||
docker-clean: clean
|
||||
|
||||
.PHONY: prep
|
||||
prep:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
|
||||
exit
|
||||
endif
|
||||
prep: is-vscode
|
||||
@echo "Preparing build/bin for usage..."
|
||||
mkdir -p build/bin/assets/patches
|
||||
cp -R -u -p .devcontainer/base/eqemu_config.json build/bin/eqemu_config.json
|
||||
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
|
||||
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
|
||||
mkdir -p build/bin/assets
|
||||
cp -R -u -p utils/patches build/bin/assets/
|
||||
-unlink build/bin/lua_modules
|
||||
cd build/bin && ln -s quests/lua_modules lua_modules
|
||||
-unlink build/bin/mods
|
||||
cd build/bin && ln -s quests/mods mods
|
||||
-unlink build/bin/maps
|
||||
cd build/bin && ln -s ../../base/maps maps
|
||||
mkdir -p build/bin/logs
|
||||
mkdir -p build/bin/shared
|
||||
|
||||
@echo "Prepping folders..."
|
||||
@mkdir -p .devcontainer/override
|
||||
@mkdir -p .devcontainer/repo
|
||||
@mkdir -p .devcontainer/cache
|
||||
@mkdir -p build/bin/logs
|
||||
@mkdir -p build/bin/shared
|
||||
@mkdir -p build/bin/assets
|
||||
|
||||
@echo "Applying overrides..."
|
||||
@if [ ! -f .devcontainer/override/eqemu_config.json ]; then cp .devcontainer/base/eqemu_config.json .devcontainer/override/eqemu_config.json; fi
|
||||
@if [ -f build/bin/eqemu_config.json ]; then unlink build/bin/eqemu_config.json; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/override/eqemu_config.json eqemu_config.json
|
||||
@if [ ! -f .devcontainer/override/login.json ]; then cp .devcontainer/base/login.json .devcontainer/override/login.json; fi
|
||||
@if [ -f build/bin/login.json ]; then unlink build/bin/login.json; fi
|
||||
cd build/bin && ln -s ../../.devcontainer/override/login.json login.json
|
||||
|
||||
@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."
|
||||
|
||||
maps:
|
||||
@echo "Downloading maps..."
|
||||
@mkdir -p base/maps
|
||||
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
|
||||
@cd base/maps && unzip -o master.zip
|
||||
@cd base/maps && mv eqemu-maps-master/* .
|
||||
@cd base/maps && rm -rf eqemu-maps-master
|
||||
@echo "Maps downloaded."
|
||||
is-vscode:
|
||||
@if [ -z "$$REMOTE_CONTAINERS" ]; then \
|
||||
echo "Not running in VS Code devcontainer"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
quests:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
|
||||
clean: is-vscode
|
||||
rm -rf build
|
||||
|
||||
.PHONY: maps
|
||||
maps: is-vscode
|
||||
@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
|
||||
.PHONY: test
|
||||
test:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
|
||||
exit
|
||||
endif
|
||||
test: is-vscode
|
||||
cd build/bin && ./tests
|
||||
|
||||
# Runs login binary
|
||||
.PHONY: login
|
||||
login:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
|
||||
exit
|
||||
endif
|
||||
login: is-vscode check-mariadb
|
||||
cd build/bin && ./loginserver
|
||||
|
||||
.PHONY: hotfix
|
||||
hotfix: shared
|
||||
|
||||
# Runs shared_memory binary
|
||||
.PHONY: shared
|
||||
shared:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
|
||||
exit
|
||||
endif
|
||||
shared: is-vscode check-mariadb
|
||||
cd build/bin && ./shared_memory
|
||||
|
||||
# Runs zone binary
|
||||
.PHONY: zone
|
||||
zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/zone/zone*.log
|
||||
zone: is-vscode check-mariadb
|
||||
@find build/bin/logs/zone/ -type f -name 'zone*.log' -exec rm -f {} +
|
||||
cd build/bin && ./zone
|
||||
|
||||
check-mariadb: is-vscode
|
||||
@if ! sudo service mariadb status | grep -q 'active (running)'; then \
|
||||
sudo service mariadb start; \
|
||||
fi
|
||||
|
||||
# Runs world binary
|
||||
.PHONY: world
|
||||
world:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/world*.log
|
||||
world: is-vscode check-mariadb
|
||||
@find build/bin/logs/ -type f -name 'world*.log' -exec rm -f {} +
|
||||
cd build/bin && ./world
|
||||
|
||||
# Runs ucs binary
|
||||
.PHONY: ucs
|
||||
ucs:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/ucs*.log
|
||||
ucs: is-vscode check-mariadb
|
||||
@find build/bin/logs/ -type f -name 'ucs*.log' -exec rm -f {} +
|
||||
cd build/bin && ./ucs
|
||||
|
||||
# Runs queryserv binary
|
||||
.PHONY: queryserv
|
||||
queryserv:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/query_server*.log
|
||||
queryserv: is-vscode check-mariadb
|
||||
@find build/bin/logs/ -type f -name 'query_server*.log' -exec rm -f {} +
|
||||
cd build/bin && ./queryserv
|
||||
|
||||
valgrind-%:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
|
||||
exit
|
||||
endif
|
||||
reset-content:
|
||||
@echo "Resetting content tables in database peq..."
|
||||
cd .devcontainer/cache/db/peq-dump && sudo mariadb --database peq -e "source create_tables_content.sql"
|
||||
|
||||
valgrind-%: is-vscode
|
||||
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
|
||||
|
||||
# Start mariaDB standalone
|
||||
@ -201,30 +132,33 @@ mariadb:
|
||||
.PHONY: inject-mariadb
|
||||
inject-mariadb:
|
||||
-sudo service mariadb start
|
||||
-mkdir -p base/db/
|
||||
-mkdir -p .devcontainer/cache/db/
|
||||
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
|
||||
-sudo mariadb -e 'CREATE DATABASE peq;'
|
||||
-sudo mariadb -e "CREATE USER 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
||||
-sudo mariadb -e "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';"
|
||||
ifeq (,$(wildcard base/db/db.sql.zip))
|
||||
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
|
||||
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
|
||||
-cd base/db && unzip db.sql.zip
|
||||
ifeq (,$(wildcard .devcontainer/cache/db/db.sql.zip))
|
||||
@echo ".devcontainer/cache/db.sql.zip not found. Downloading database from https://db.eqemu.dev/latest"
|
||||
wget -nc https://db.eqemu.dev/latest -O .devcontainer/cache/db/db.sql.zip
|
||||
-cd .devcontainer/cache/db && unzip db.sql.zip
|
||||
endif
|
||||
@echo "Sourcing db may take a while, please wait..."
|
||||
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
|
||||
|
||||
@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."
|
||||
|
||||
.PHONY: gm-%
|
||||
gm-%:
|
||||
gm-%: is-vscode
|
||||
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
|
||||
@echo "Account $* is now a GM. /camp to have it go into effect."
|
||||
|
||||
depends:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
|
||||
exit
|
||||
endif
|
||||
depends: is-vscode
|
||||
sudo apt install graphviz pip time
|
||||
pip3 install graphviz
|
||||
mkdir -p build/depends
|
||||
@ -241,44 +175,54 @@ endif
|
||||
@echo "Common..."
|
||||
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
|
||||
|
||||
backup:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
|
||||
exit
|
||||
endif
|
||||
backup: is-vscode
|
||||
@mkdir -p build/bin/backup
|
||||
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)
|
||||
@make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
|
||||
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && CPUPROFILE=prof.out ./zone
|
||||
|
||||
pprof-zone:
|
||||
pprof-zone: is-vscode
|
||||
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
|
||||
endif
|
||||
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
|
||||
pprof-web-zone:
|
||||
|
||||
pprof-gv-zone: is-vscode
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-web-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --web zone prof.out
|
||||
pprof-gv-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-gv-zone --no-print-directory
|
||||
@echo "This makefile is not intended to be run from the .devcontainer directory."
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --gv zone prof.out > prof.gv
|
||||
heap-zone:
|
||||
|
||||
heap-zone: is-vscode
|
||||
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
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && HEAPPROFILE=prof.out ./zone
|
||||
|
||||
|
||||
.PHONY: pull
|
||||
pull:
|
||||
git pull
|
||||
@if [ ! -d "quests" ]; then git clone https://github.com/rebuildeq/quests.git quests; fi
|
||||
cd quests && git pull
|
||||
@if [ ! -d "eqemu-definitions" ]; then git clone https://github.com/xackery/eqemu-definitions.git eqemu-definitions; fi
|
||||
cd eqemu-definitions && git pull
|
||||
@ -40,10 +40,41 @@
|
||||
"GitHub.copilot",
|
||||
"xackery.make-magic",
|
||||
"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",
|
||||
"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 libmariadb-dev libmariadb-dev-compat libboost-all-dev libperl-dev liblua5.1-0-dev libluajit-5.1-dev zlib1g-dev uuid-dev libssl-dev libsodium-dev libmbedtls-dev
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -S . -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DEQEMU_BUILD_TESTS=ON \
|
||||
-DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_LUA=ON \
|
||||
-DEQEMU_BUILD_PERL=ON \
|
||||
-DEQEMU_BUILD_CLIENT_FILES=ON
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build --parallel
|
||||
|
||||
- name: Test
|
||||
working-directory: build
|
||||
run: ./bin/tests
|
||||
|
||||
windows:
|
||||
name: Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Enable long paths
|
||||
run: git config --global core.longpaths true
|
||||
|
||||
- name: Setup MSVC environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: Configure
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 `
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo `
|
||||
-DEQEMU_BUILD_TESTS=ON `
|
||||
-DEQEMU_BUILD_LOGIN=ON `
|
||||
-DEQEMU_BUILD_LUA=ON `
|
||||
-DEQEMU_BUILD_ZLIB=ON `
|
||||
-DEQEMU_BUILD_CLIENT_FILES=ON
|
||||
|
||||
- name: Build
|
||||
shell: pwsh
|
||||
run: cmake --build build --config RelWithDebInfo --target ALL_BUILD -- /m
|
||||
|
||||
- name: Test
|
||||
working-directory: build
|
||||
run: ./bin/RelWithDebInfo/tests.exe
|
||||
25
.vscode/settings.json
vendored
25
.vscode/settings.json
vendored
@ -21,14 +21,6 @@
|
||||
"${workspaceFolder}/dependencies/zlibng"
|
||||
],
|
||||
"telemetry.enableTelemetry": false,
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"cmake.configureArgs": [
|
||||
"-DEQEMU_BUILD_LOGIN=ON",
|
||||
"-DEQEMU_BUILD_TESTS=ON",
|
||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
|
||||
"-DEQEMU_ADD_PROFILER=ON",
|
||||
"Ninja"
|
||||
],
|
||||
"cmake.skipConfigureIfCachePresent": true,
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
@ -115,22 +107,5 @@
|
||||
"format": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp"
|
||||
},
|
||||
"cmake.statusbar.advanced": {
|
||||
"kit": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"debug": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"buildTarget": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"launch": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"ctest": {
|
||||
"visibility": "icon",
|
||||
}
|
||||
}
|
||||
}
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,3 +1,15 @@
|
||||
## [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
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -35,60 +35,55 @@ ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
||||
MESSAGE(STATUS "Resolving vcpkg dependencies...")
|
||||
|
||||
|
||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
|
||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
|
||||
|
||||
|
||||
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
|
||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_STATUS)
|
||||
|
||||
|
||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
||||
IF(NOT STATUS_CODE EQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
|
||||
ENDIF()
|
||||
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
|
||||
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
|
||||
ENDIF()
|
||||
|
||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
||||
#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}
|
||||
)
|
||||
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()
|
||||
|
||||
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)
|
||||
|
||||
MESSAGE(STATUS "Extracting files...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
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()
|
||||
|
||||
@ -842,6 +842,11 @@ ENDIF (UNIX)
|
||||
|
||||
IF (EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/std-pch.h)
|
||||
# Avoid PCH/__OPTIMIZE__ mismatch when compiling certain patch sources with -O0
|
||||
# These files are compiled with -O0 on UNIX (see COMPILE_FLAGS above), which
|
||||
# disables the __OPTIMIZE__ predefined macro. Disabling PCH for them prevents
|
||||
# Clang from erroring due to macro state differences between the PCH and TU.
|
||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
@ -23,7 +23,7 @@ void SendCrashReport(const std::string &crash_report)
|
||||
{
|
||||
// can configure multiple endpoints if need be
|
||||
std::vector<std::string> endpoints = {
|
||||
"https://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
"https://spire.eqemu.dev/api/v1/analytics/server-crash-report",
|
||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||
};
|
||||
|
||||
|
||||
@ -7173,26 +7173,6 @@ ADD COLUMN `heal_amount` int(11) NULL DEFAULT 0 AFTER `spell_damage`;
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9328,
|
||||
.description = "2025_08_27_spells_new_column_names.sql",
|
||||
.check = "SHOW COLUMNS FROM `spells_new` LIKE 'feedbackable'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `spells_new`
|
||||
CHANGE COLUMN `field160` `feedbackable` int(11) NOT NULL DEFAULT 0 AFTER `npc_no_los`,
|
||||
CHANGE COLUMN `field198` `no_detrimental_spell_aggro` int(11) NOT NULL DEFAULT 0 AFTER `not_extendable`,
|
||||
CHANGE COLUMN `field209` `no_resist` int(11) NULL DEFAULT 0 AFTER `rank`,
|
||||
CHANGE COLUMN `field217` `override_crit_chance` int(11) NULL DEFAULT 0 AFTER `field216`,
|
||||
CHANGE COLUMN `field220` `no_heal_damage_item_mod` int(11) NULL DEFAULT 0 AFTER `maxtargets`,
|
||||
CHANGE COLUMN `field221` `caster_requirement_id` int(11) NULL DEFAULT 0 AFTER `no_heal_damage_item_mod`,
|
||||
CHANGE COLUMN `field222` `spell_class` int(11) NULL DEFAULT 0 AFTER `caster_requirement_id`,
|
||||
CHANGE COLUMN `field223` `spell_subclass` int(11) NULL DEFAULT 0 AFTER `spell_class`,
|
||||
CHANGE COLUMN `field232` `no_remove` int(11) NOT NULL DEFAULT 0 AFTER `min_range`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9329,
|
||||
.description = "2025_08_22_character_parcel_updates.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'evolve_amount'",
|
||||
.condition = "empty",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1630,9 +1630,16 @@ const EvolveInfo* SharedDatabase::GetEvolveInfo(uint32 loregroup) {
|
||||
return nullptr; // nothing here for now... database and/or sharemem pulls later
|
||||
}
|
||||
|
||||
int SharedDatabase::GetMaxSpellID()
|
||||
{
|
||||
return SpellsNewRepository::GetMaxId(*this);
|
||||
int SharedDatabase::GetMaxSpellID() {
|
||||
const std::string query = "SELECT MAX(id) FROM spells_new";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto& row = results.begin();
|
||||
|
||||
return Strings::ToInt(row[0]);
|
||||
}
|
||||
|
||||
bool SharedDatabase::LoadSpells(const std::string &prefix, int32 *records, const SPDat_Spell_Struct **sp) {
|
||||
@ -1664,247 +1671,173 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
*static_cast<uint32*>(data) = max_spells;
|
||||
SPDat_Spell_Struct *sp = reinterpret_cast<SPDat_Spell_Struct*>(static_cast<char*>(data) + sizeof(uint32));
|
||||
|
||||
const auto& l = SpellsNewRepository::All(*this);
|
||||
const std::string query = "SELECT * FROM spells_new ORDER BY id ASC";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (l.empty()) {
|
||||
if(results.ColumnCount() <= SPELL_LOAD_FIELD_COUNT) {
|
||||
LogSpells("Fatal error loading spells: Spell field count < SPELL_LOAD_FIELD_COUNT([{}])", SPELL_LOAD_FIELD_COUNT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (e.id >= max_spells) {
|
||||
int counter = 0;
|
||||
|
||||
for (auto& row = results.begin(); row != results.end(); ++row) {
|
||||
const int tempid = Strings::ToInt(row[0]);
|
||||
if(tempid >= max_spells) {
|
||||
LogSpells("Non fatal error: spell.id >= max_spells, ignoring");
|
||||
continue;
|
||||
}
|
||||
|
||||
sp[e.id].id = e.id;
|
||||
++counter;
|
||||
sp[tempid].id = tempid;
|
||||
strn0cpy(sp[tempid].name, row[1], sizeof(sp[tempid].name));
|
||||
strn0cpy(sp[tempid].player_1, row[2], sizeof(sp[tempid].player_1));
|
||||
strn0cpy(sp[tempid].teleport_zone, row[3], sizeof(sp[tempid].teleport_zone));
|
||||
strn0cpy(sp[tempid].you_cast, row[4], sizeof(sp[tempid].you_cast));
|
||||
strn0cpy(sp[tempid].other_casts, row[5], sizeof(sp[tempid].other_casts));
|
||||
strn0cpy(sp[tempid].cast_on_you, row[6], sizeof(sp[tempid].cast_on_you));
|
||||
strn0cpy(sp[tempid].cast_on_other, row[7], sizeof(sp[tempid].cast_on_other));
|
||||
strn0cpy(sp[tempid].spell_fades, row[8], sizeof(sp[tempid].spell_fades));
|
||||
|
||||
strn0cpy(sp[e.id].name, e.name.c_str(), sizeof(sp[e.id].name));
|
||||
strn0cpy(sp[e.id].player_1, e.player_1.c_str(), sizeof(sp[e.id].player_1));
|
||||
strn0cpy(sp[e.id].teleport_zone, e.teleport_zone.c_str(), sizeof(sp[e.id].teleport_zone));
|
||||
strn0cpy(sp[e.id].you_cast, e.you_cast.c_str(), sizeof(sp[e.id].you_cast));
|
||||
strn0cpy(sp[e.id].other_casts, e.other_casts.c_str(), sizeof(sp[e.id].other_casts));
|
||||
strn0cpy(sp[e.id].cast_on_you, e.cast_on_you.c_str(), sizeof(sp[e.id].cast_on_you));
|
||||
strn0cpy(sp[e.id].cast_on_other, e.cast_on_other.c_str(), sizeof(sp[e.id].cast_on_other));
|
||||
strn0cpy(sp[e.id].spell_fades, e.spell_fades.c_str(), sizeof(sp[e.id].spell_fades));
|
||||
sp[tempid].range = Strings::ToFloat(row[9]);
|
||||
sp[tempid].aoe_range = Strings::ToFloat(row[10]);
|
||||
sp[tempid].push_back = Strings::ToFloat(row[11]);
|
||||
sp[tempid].push_up = Strings::ToFloat(row[12]);
|
||||
sp[tempid].cast_time=Strings::ToUnsignedInt(row[13]);
|
||||
sp[tempid].recovery_time=Strings::ToUnsignedInt(row[14]);
|
||||
sp[tempid].recast_time=Strings::ToUnsignedInt(row[15]);
|
||||
sp[tempid].buff_duration_formula=Strings::ToUnsignedInt(row[16]);
|
||||
sp[tempid].buff_duration=Strings::ToUnsignedInt(row[17]);
|
||||
sp[tempid].aoe_duration=Strings::ToUnsignedInt(row[18]);
|
||||
sp[tempid].mana=Strings::ToInt(row[19]);
|
||||
|
||||
sp[e.id].range = e.range_;
|
||||
sp[e.id].aoe_range = e.aoerange;
|
||||
sp[e.id].push_back = e.pushback;
|
||||
sp[e.id].push_up = e.pushup;
|
||||
sp[e.id].cast_time = e.cast_time;
|
||||
sp[e.id].recovery_time = e.recovery_time;
|
||||
sp[e.id].recast_time = e.recast_time;
|
||||
sp[e.id].buff_duration_formula = e.buffdurationformula;
|
||||
sp[e.id].buff_duration = e.buffduration;
|
||||
sp[e.id].aoe_duration = e.AEDuration;
|
||||
sp[e.id].mana = e.mana;
|
||||
int y=0;
|
||||
for(y=0; y< EFFECT_COUNT;y++)
|
||||
sp[tempid].base_value[y]=Strings::ToInt(row[20+y]); // effect_base_value
|
||||
|
||||
sp[e.id].base_value[0] = e.effect_base_value1;
|
||||
sp[e.id].base_value[1] = e.effect_base_value2;
|
||||
sp[e.id].base_value[2] = e.effect_base_value3;
|
||||
sp[e.id].base_value[3] = e.effect_base_value4;
|
||||
sp[e.id].base_value[4] = e.effect_base_value5;
|
||||
sp[e.id].base_value[5] = e.effect_base_value6;
|
||||
sp[e.id].base_value[6] = e.effect_base_value7;
|
||||
sp[e.id].base_value[7] = e.effect_base_value8;
|
||||
sp[e.id].base_value[8] = e.effect_base_value9;
|
||||
sp[e.id].base_value[9] = e.effect_base_value10;
|
||||
sp[e.id].base_value[10] = e.effect_base_value11;
|
||||
sp[e.id].base_value[11] = e.effect_base_value12;
|
||||
for(y=0; y < EFFECT_COUNT; y++)
|
||||
sp[tempid].limit_value[y]=Strings::ToInt(row[32+y]); // effect_limit_value
|
||||
|
||||
sp[e.id].limit_value[0] = e.effect_limit_value1;
|
||||
sp[e.id].limit_value[1] = e.effect_limit_value2;
|
||||
sp[e.id].limit_value[2] = e.effect_limit_value3;
|
||||
sp[e.id].limit_value[3] = e.effect_limit_value4;
|
||||
sp[e.id].limit_value[4] = e.effect_limit_value5;
|
||||
sp[e.id].limit_value[5] = e.effect_limit_value6;
|
||||
sp[e.id].limit_value[6] = e.effect_limit_value7;
|
||||
sp[e.id].limit_value[7] = e.effect_limit_value8;
|
||||
sp[e.id].limit_value[8] = e.effect_limit_value9;
|
||||
sp[e.id].limit_value[9] = e.effect_limit_value10;
|
||||
sp[e.id].limit_value[10] = e.effect_limit_value11;
|
||||
sp[e.id].limit_value[11] = e.effect_limit_value12;
|
||||
for(y=0; y< EFFECT_COUNT;y++)
|
||||
sp[tempid].max_value[y]=Strings::ToInt(row[44+y]);
|
||||
|
||||
sp[e.id].max_value[0] = e.max1;
|
||||
sp[e.id].max_value[1] = e.max2;
|
||||
sp[e.id].max_value[2] = e.max3;
|
||||
sp[e.id].max_value[3] = e.max4;
|
||||
sp[e.id].max_value[4] = e.max5;
|
||||
sp[e.id].max_value[5] = e.max6;
|
||||
sp[e.id].max_value[6] = e.max7;
|
||||
sp[e.id].max_value[7] = e.max8;
|
||||
sp[e.id].max_value[8] = e.max9;
|
||||
sp[e.id].max_value[9] = e.max10;
|
||||
sp[e.id].max_value[10] = e.max11;
|
||||
sp[e.id].max_value[11] = e.max12;
|
||||
for(y=0; y< 4;y++)
|
||||
sp[tempid].component[y]=Strings::ToInt(row[58+y]);
|
||||
|
||||
sp[e.id].component[0] = e.components1;
|
||||
sp[e.id].component[1] = e.components2;
|
||||
sp[e.id].component[2] = e.components3;
|
||||
sp[e.id].component[3] = e.components4;
|
||||
for(y=0; y< 4;y++)
|
||||
sp[tempid].component_count[y]=Strings::ToInt(row[62+y]);
|
||||
|
||||
sp[e.id].component_count[0] = e.component_counts1;
|
||||
sp[e.id].component_count[1] = e.component_counts2;
|
||||
sp[e.id].component_count[2] = e.component_counts3;
|
||||
sp[e.id].component_count[3] = e.component_counts4;
|
||||
for(y=0; y< 4;y++)
|
||||
sp[tempid].no_expend_reagent[y]=Strings::ToInt(row[66+y]);
|
||||
|
||||
sp[e.id].no_expend_reagent[0] = e.NoexpendReagent1;
|
||||
sp[e.id].no_expend_reagent[1] = e.NoexpendReagent2;
|
||||
sp[e.id].no_expend_reagent[2] = e.NoexpendReagent3;
|
||||
sp[e.id].no_expend_reagent[3] = e.NoexpendReagent4;
|
||||
for(y=0; y< EFFECT_COUNT;y++)
|
||||
sp[tempid].formula[y]=Strings::ToUnsignedInt(row[70+y]);
|
||||
|
||||
sp[e.id].formula[0] = e.formula1;
|
||||
sp[e.id].formula[1] = e.formula2;
|
||||
sp[e.id].formula[2] = e.formula3;
|
||||
sp[e.id].formula[3] = e.formula4;
|
||||
sp[e.id].formula[4] = e.formula5;
|
||||
sp[e.id].formula[5] = e.formula6;
|
||||
sp[e.id].formula[6] = e.formula7;
|
||||
sp[e.id].formula[7] = e.formula8;
|
||||
sp[e.id].formula[8] = e.formula9;
|
||||
sp[e.id].formula[9] = e.formula10;
|
||||
sp[e.id].formula[10] = e.formula11;
|
||||
sp[e.id].formula[11] = e.formula12;
|
||||
sp[tempid].good_effect=Strings::ToInt(row[83]);
|
||||
sp[tempid].activated=Strings::ToInt(row[84]);
|
||||
sp[tempid].resist_type=Strings::ToInt(row[85]);
|
||||
|
||||
sp[e.id].good_effect = e.goodEffect;
|
||||
sp[e.id].activated = e.Activated;
|
||||
sp[e.id].resist_type = e.resisttype;
|
||||
for(y=0; y< EFFECT_COUNT;y++)
|
||||
sp[tempid].effect_id[y]=Strings::ToInt(row[86+y]);
|
||||
|
||||
sp[e.id].effect_id[0] = e.effectid1;
|
||||
sp[e.id].effect_id[1] = e.effectid2;
|
||||
sp[e.id].effect_id[2] = e.effectid3;
|
||||
sp[e.id].effect_id[3] = e.effectid4;
|
||||
sp[e.id].effect_id[4] = e.effectid5;
|
||||
sp[e.id].effect_id[5] = e.effectid6;
|
||||
sp[e.id].effect_id[6] = e.effectid7;
|
||||
sp[e.id].effect_id[7] = e.effectid8;
|
||||
sp[e.id].effect_id[8] = e.effectid9;
|
||||
sp[e.id].effect_id[9] = e.effectid10;
|
||||
sp[e.id].effect_id[10] = e.effectid11;
|
||||
sp[e.id].effect_id[11] = e.effectid12;
|
||||
sp[tempid].target_type = static_cast<SpellTargetType>(Strings::ToInt(row[98]));
|
||||
sp[tempid].base_difficulty=Strings::ToInt(row[99]);
|
||||
|
||||
sp[e.id].target_type = static_cast<SpellTargetType>(e.targettype);
|
||||
int tmp_skill = Strings::ToInt(row[100]);
|
||||
|
||||
sp[e.id].base_difficulty = e.basediff;
|
||||
if (tmp_skill < 0 || tmp_skill > EQ::skills::HIGHEST_SKILL)
|
||||
sp[tempid].skill = EQ::skills::SkillBegging; /* not much better we can do. */ // can probably be changed to client-based 'SkillNone' once activated
|
||||
else
|
||||
sp[tempid].skill = static_cast<EQ::skills::SkillType>(tmp_skill);
|
||||
|
||||
sp[e.id].skill = (
|
||||
EQ::ValueWithin(e.skill, 0, EQ::skills::HIGHEST_SKILL) ?
|
||||
static_cast<EQ::skills::SkillType>(e.skill) :
|
||||
EQ::skills::SkillBegging
|
||||
);
|
||||
sp[tempid].zone_type=Strings::ToInt(row[101]);
|
||||
sp[tempid].environment_type=Strings::ToInt(row[102]);
|
||||
sp[tempid].time_of_day=Strings::ToInt(row[103]);
|
||||
|
||||
sp[e.id].zone_type = e.zonetype;
|
||||
sp[e.id].environment_type = e.EnvironmentType;
|
||||
sp[e.id].time_of_day = e.TimeOfDay;
|
||||
for(y=0; y < Class::PLAYER_CLASS_COUNT;y++)
|
||||
sp[tempid].classes[y]=Strings::ToInt(row[104+y]);
|
||||
|
||||
sp[e.id].classes[0] = e.classes1;
|
||||
sp[e.id].classes[1] = e.classes2;
|
||||
sp[e.id].classes[2] = e.classes3;
|
||||
sp[e.id].classes[3] = e.classes4;
|
||||
sp[e.id].classes[4] = e.classes5;
|
||||
sp[e.id].classes[5] = e.classes6;
|
||||
sp[e.id].classes[6] = e.classes7;
|
||||
sp[e.id].classes[7] = e.classes8;
|
||||
sp[e.id].classes[8] = e.classes9;
|
||||
sp[e.id].classes[9] = e.classes10;
|
||||
sp[e.id].classes[10] = e.classes11;
|
||||
sp[e.id].classes[11] = e.classes12;
|
||||
sp[e.id].classes[12] = e.classes13;
|
||||
sp[e.id].classes[13] = e.classes14;
|
||||
sp[e.id].classes[14] = e.classes15;
|
||||
sp[e.id].classes[15] = e.classes16;
|
||||
sp[tempid].casting_animation=Strings::ToInt(row[120]);
|
||||
sp[tempid].spell_affect_index=Strings::ToInt(row[123]);
|
||||
sp[tempid].disallow_sit=Strings::ToInt(row[124]);
|
||||
sp[tempid].deity_agnostic=Strings::ToInt(row[125]);
|
||||
|
||||
sp[e.id].casting_animation = e.CastingAnim;
|
||||
sp[e.id].spell_affect_index = e.SpellAffectIndex;
|
||||
sp[e.id].disallow_sit = e.disallow_sit;
|
||||
for (y = 0; y < 16; y++)
|
||||
sp[tempid].deities[y]=Strings::ToInt(row[126+y]);
|
||||
|
||||
sp[e.id].deity_agnostic = e.deities0; // Agnostic
|
||||
sp[e.id].deities[0] = e.deities1; // Bertoxxulous
|
||||
sp[e.id].deities[1] = e.deities2; // Brell Serilis
|
||||
sp[e.id].deities[2] = e.deities3; // Cazic Thule
|
||||
sp[e.id].deities[3] = e.deities4; // Erollsi Marr
|
||||
sp[e.id].deities[4] = e.deities5; // Bristlebane
|
||||
sp[e.id].deities[5] = e.deities6; // Innoruuk
|
||||
sp[e.id].deities[6] = e.deities7; // Karana
|
||||
sp[e.id].deities[7] = e.deities8; // Mithaniel Marr
|
||||
sp[e.id].deities[8] = e.deities9; // Prexius
|
||||
sp[e.id].deities[9] = e.deities10; // Quellious
|
||||
sp[e.id].deities[10] = e.deities11; // Rallos Zek
|
||||
sp[e.id].deities[11] = e.deities12; // Rodcet Nife
|
||||
sp[e.id].deities[12] = e.deities13; // Solusek Ro
|
||||
sp[e.id].deities[13] = e.deities14; // The Tribunal
|
||||
sp[e.id].deities[14] = e.deities15; // Tunare
|
||||
sp[e.id].deities[15] = e.deities16; // Veeshan
|
||||
sp[tempid].new_icon=Strings::ToInt(row[144]);
|
||||
sp[tempid].uninterruptable=Strings::ToBool(row[146]);
|
||||
sp[tempid].resist_difficulty=Strings::ToInt(row[147]);
|
||||
sp[tempid].unstackable_dot = Strings::ToBool(row[148]);
|
||||
sp[tempid].recourse_link = Strings::ToUnsignedInt(row[150]);
|
||||
sp[tempid].no_partial_resist = Strings::ToBool(row[151]);
|
||||
|
||||
sp[e.id].new_icon = e.new_icon;
|
||||
sp[e.id].uninterruptable = e.uninterruptable;
|
||||
sp[e.id].resist_difficulty = e.ResistDiff;
|
||||
sp[e.id].unstackable_dot = e.dot_stacking_exempt;
|
||||
sp[e.id].recourse_link = e.RecourseLink;
|
||||
sp[e.id].no_partial_resist = e.no_partial_resist;
|
||||
sp[e.id].short_buff_box = e.short_buff_box;
|
||||
sp[e.id].description_id = e.descnum;
|
||||
sp[e.id].type_description_id = e.typedescnum;
|
||||
sp[e.id].effect_description_id = e.effectdescnum;
|
||||
sp[e.id].npc_no_los = e.npc_no_los;
|
||||
sp[e.id].feedbackable = e.feedbackable;
|
||||
sp[e.id].reflectable = e.reflectable;
|
||||
sp[e.id].bonus_hate = e.bonushate;
|
||||
sp[e.id].ldon_trap = e.ldon_trap;
|
||||
sp[e.id].endurance_cost = e.EndurCost;
|
||||
sp[e.id].timer_id = e.EndurTimerIndex;
|
||||
sp[e.id].is_discipline = e.IsDiscipline;
|
||||
sp[e.id].hate_added = e.HateAdded;
|
||||
sp[e.id].endurance_upkeep = e.EndurUpkeep;
|
||||
sp[e.id].hit_number_type = e.numhits;
|
||||
sp[e.id].hit_number = e.numhitstype;
|
||||
sp[e.id].pvp_resist_base = e.pvpresistbase;
|
||||
sp[e.id].pvp_resist_per_level = e.pvpresistcalc;
|
||||
sp[e.id].pvp_resist_cap = e.pvpresistcap;
|
||||
sp[e.id].spell_category = e.spell_category;
|
||||
sp[e.id].pvp_duration = e.pvp_duration;
|
||||
sp[e.id].pvp_duration_cap = e.pvp_duration_cap;
|
||||
sp[e.id].pcnpc_only_flag = e.pcnpc_only_flag;
|
||||
sp[e.id].cast_not_standing = e.cast_not_standing;
|
||||
sp[e.id].can_mgb = e.can_mgb;
|
||||
sp[e.id].dispel_flag = e.nodispell;
|
||||
sp[e.id].min_resist = e.MinResist;
|
||||
sp[e.id].max_resist = e.MaxResist;
|
||||
sp[e.id].viral_targets = e.viral_targets;
|
||||
sp[e.id].viral_timer = e.viral_timer;
|
||||
sp[e.id].nimbus_effect = e.nimbuseffect;
|
||||
sp[e.id].directional_start = e.ConeStartAngle;
|
||||
sp[e.id].directional_end = e.ConeStopAngle;
|
||||
sp[e.id].sneak = e.sneaking;
|
||||
sp[e.id].not_focusable = e.not_extendable;
|
||||
sp[tempid].short_buff_box = Strings::ToInt(row[154]);
|
||||
sp[tempid].description_id = Strings::ToInt(row[155]);
|
||||
sp[tempid].type_description_id = Strings::ToInt(row[156]);
|
||||
sp[tempid].effect_description_id = Strings::ToInt(row[157]);
|
||||
|
||||
sp[e.id].no_detrimental_spell_aggro = e.no_detrimental_spell_aggro;
|
||||
sp[tempid].npc_no_los = Strings::ToBool(row[159]);
|
||||
sp[tempid].feedbackable = Strings::ToBool(row[160]);
|
||||
sp[tempid].reflectable = Strings::ToBool(row[161]);
|
||||
sp[tempid].bonus_hate=Strings::ToInt(row[162]);
|
||||
|
||||
sp[e.id].suspendable = e.suspendable;
|
||||
sp[e.id].viral_range = e.viral_range;
|
||||
sp[e.id].song_cap = e.songcap;
|
||||
sp[e.id].no_block = e.no_block;
|
||||
sp[e.id].spell_group = e.spellgroup;
|
||||
sp[e.id].rank = e.rank_;
|
||||
sp[e.id].no_resist = e.no_resist;
|
||||
sp[e.id].cast_restriction = e.CastRestriction;
|
||||
sp[e.id].allow_rest = e.allowrest;
|
||||
sp[e.id].can_cast_in_combat = e.InCombat;
|
||||
sp[e.id].can_cast_out_of_combat = e.OutofCombat;
|
||||
sp[e.id].override_crit_chance = e.override_crit_chance;
|
||||
sp[e.id].aoe_max_targets = e.aemaxtargets;
|
||||
sp[e.id].no_heal_damage_item_mod = e.no_heal_damage_item_mod;
|
||||
sp[e.id].caster_requirement_id = e.caster_requirement_id;
|
||||
sp[e.id].spell_class = e.spell_class;
|
||||
sp[e.id].spell_subclass = e.spell_subclass;
|
||||
sp[e.id].persist_death = e.persistdeath;
|
||||
sp[e.id].min_distance = e.min_dist;
|
||||
sp[e.id].min_distance_mod = e.min_dist_mod;
|
||||
sp[e.id].max_distance = e.max_dist;
|
||||
sp[e.id].max_distance_mod = e.max_dist_mod;
|
||||
sp[e.id].min_range = e.min_range;
|
||||
sp[e.id].no_remove = e.no_remove;
|
||||
sp[e.id].damage_shield_type = 0;
|
||||
sp[tempid].ldon_trap = Strings::ToBool(row[165]);
|
||||
sp[tempid].endurance_cost= Strings::ToInt(row[166]);
|
||||
sp[tempid].timer_id= Strings::ToInt(row[167]);
|
||||
sp[tempid].is_discipline = Strings::ToBool(row[168]);
|
||||
sp[tempid].hate_added= Strings::ToInt(row[173]);
|
||||
sp[tempid].endurance_upkeep=Strings::ToInt(row[174]);
|
||||
sp[tempid].hit_number_type = Strings::ToInt(row[175]);
|
||||
sp[tempid].hit_number = Strings::ToInt(row[176]);
|
||||
sp[tempid].pvp_resist_base= Strings::ToInt(row[177]);
|
||||
sp[tempid].pvp_resist_per_level= Strings::ToInt(row[178]);
|
||||
sp[tempid].pvp_resist_cap= Strings::ToInt(row[179]);
|
||||
sp[tempid].spell_category= Strings::ToInt(row[180]);
|
||||
sp[tempid].pvp_duration = Strings::ToInt(row[181]);
|
||||
sp[tempid].pvp_duration_cap = Strings::ToInt(row[182]);
|
||||
sp[tempid].pcnpc_only_flag= Strings::ToInt(row[183]);
|
||||
sp[tempid].cast_not_standing = Strings::ToInt(row[184]) != 0;
|
||||
sp[tempid].can_mgb= Strings::ToBool(row[185]);
|
||||
sp[tempid].dispel_flag = Strings::ToInt(row[186]);
|
||||
sp[tempid].min_resist = Strings::ToInt(row[189]);
|
||||
sp[tempid].max_resist = Strings::ToInt(row[190]);
|
||||
sp[tempid].viral_targets = Strings::ToInt(row[191]);
|
||||
sp[tempid].viral_timer = Strings::ToInt(row[192]);
|
||||
sp[tempid].nimbus_effect = Strings::ToInt(row[193]);
|
||||
sp[tempid].directional_start = Strings::ToFloat(row[194]);
|
||||
sp[tempid].directional_end = Strings::ToFloat(row[195]);
|
||||
sp[tempid].sneak = Strings::ToBool(row[196]);
|
||||
sp[tempid].not_focusable = Strings::ToBool(row[197]);
|
||||
sp[tempid].no_detrimental_spell_aggro = Strings::ToBool(row[198]);
|
||||
sp[tempid].suspendable = Strings::ToBool(row[200]);
|
||||
sp[tempid].viral_range = Strings::ToInt(row[201]);
|
||||
sp[tempid].song_cap = Strings::ToInt(row[202]);
|
||||
sp[tempid].no_block = Strings::ToInt(row[205]);
|
||||
sp[tempid].spell_group=Strings::ToInt(row[207]);
|
||||
sp[tempid].rank = Strings::ToInt(row[208]);
|
||||
sp[tempid].no_resist=Strings::ToInt(row[209]);
|
||||
sp[tempid].cast_restriction = Strings::ToInt(row[211]);
|
||||
sp[tempid].allow_rest = Strings::ToBool(row[212]);
|
||||
sp[tempid].can_cast_in_combat = Strings::ToBool(row[213]);
|
||||
sp[tempid].can_cast_out_of_combat = Strings::ToBool(row[214]);
|
||||
sp[tempid].override_crit_chance = Strings::ToInt(row[217]);
|
||||
sp[tempid].aoe_max_targets = Strings::ToInt(row[218]);
|
||||
sp[tempid].no_heal_damage_item_mod = Strings::ToInt(row[219]);
|
||||
sp[tempid].caster_requirement_id = Strings::ToInt(row[220]);
|
||||
sp[tempid].spell_class = Strings::ToInt(row[221]);
|
||||
sp[tempid].spell_subclass = Strings::ToInt(row[222]);
|
||||
sp[tempid].persist_death = Strings::ToBool(row[224]);
|
||||
sp[tempid].min_distance = Strings::ToFloat(row[227]);
|
||||
sp[tempid].min_distance_mod = Strings::ToFloat(row[228]);
|
||||
sp[tempid].max_distance = Strings::ToFloat(row[229]);
|
||||
sp[tempid].max_distance_mod = Strings::ToFloat(row[230]);
|
||||
sp[tempid].min_range = Strings::ToFloat(row[231]);
|
||||
sp[tempid].no_remove = Strings::ToBool(row[232]);
|
||||
sp[tempid].damage_shield_type = 0;
|
||||
}
|
||||
|
||||
LoadDamageShieldTypes(sp);
|
||||
@ -1937,7 +1870,18 @@ void SharedDatabase::SaveCharacterInspectMessage(uint32 character_id, const Insp
|
||||
|
||||
uint32 SharedDatabase::GetSpellsCount()
|
||||
{
|
||||
return SpellsNewRepository::Count(*this);
|
||||
auto results = QueryDatabase("SELECT count(*) FROM spells_new");
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto& row = results.begin();
|
||||
|
||||
if (row[0]) {
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 SharedDatabase::GetItemsCount()
|
||||
|
||||
@ -1600,6 +1600,7 @@ namespace SpellEffect {
|
||||
// number. note that the id field is counted as 0, this way the numbers
|
||||
// here match the numbers given to sep in the loading function net.cpp
|
||||
//
|
||||
#define SPELL_LOAD_FIELD_COUNT 236
|
||||
|
||||
struct SPDat_Spell_Struct
|
||||
{
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "23.10.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "23.10.3-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9329
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9328
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||
#define CUSTOM_BINARY_DATABASE_VERSION 0
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "23.10.1",
|
||||
"version": "23.10.3",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
@ -35,4 +35,4 @@ IF(UNIX)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
ENDIF(UNIX)
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ../../Bin)
|
||||
SET(LIBRARY_OUTPUT_PATH ../../bin)
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
module should-release
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.5
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/google/go-github/v41 v41.0.0
|
||||
@ -11,5 +9,5 @@ require (
|
||||
|
||||
require (
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
)
|
||||
|
||||
@ -10,8 +10,8 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
||||
@ -1019,8 +1019,16 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
break;
|
||||
}
|
||||
|
||||
std::string ucs_addr = config->GetUCSHost();
|
||||
if (cle && cle->IsLocalClient()) {
|
||||
const char* local_addr = config->LocalAddress.c_str();
|
||||
if (local_addr[0]) {
|
||||
ucs_addr = local_addr;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||
config->GetUCSHost(),
|
||||
ucs_addr,
|
||||
config->GetUCSPort(),
|
||||
config->ShortName,
|
||||
GetCharName(),
|
||||
@ -1046,7 +1054,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||
config->GetUCSHost(),
|
||||
ucs_addr,
|
||||
config->GetUCSPort(),
|
||||
config->ShortName,
|
||||
GetCharName(),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -854,6 +854,66 @@ struct DataBucketCache
|
||||
uint32_t bucket_expires;
|
||||
};
|
||||
|
||||
// Defines based on the RoF2 Client
|
||||
#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window
|
||||
#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window
|
||||
#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window
|
||||
#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window
|
||||
#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window
|
||||
#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window
|
||||
#define PET_SIT 6 // 0x06 - /pet sit or Pet Window
|
||||
#define PET_SITDOWN 7 // 0x07 - /pet sit on
|
||||
#define PET_STANDUP 8 // 0x08 - /pet sit off
|
||||
#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented
|
||||
#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented
|
||||
#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented
|
||||
#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window
|
||||
#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on
|
||||
#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off
|
||||
#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window, won't add to hate list unless attacking
|
||||
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
|
||||
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
|
||||
#define PET_GHOLD 18 // 0x12 - /pet ghold, will never add to hate list unless told to
|
||||
#define PET_GHOLD_ON 19 // 0x13 - /pet ghold on
|
||||
#define PET_GHOLD_OFF 20 // 0x14 - /pet ghold off
|
||||
#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window
|
||||
#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on
|
||||
#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off
|
||||
#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window
|
||||
#define PET_FOCUS_ON 25 // 0x19 - /pet focus on
|
||||
#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off
|
||||
#define PET_FEIGN 27 // 0x1b - /pet feign
|
||||
#define PET_BACKOFF 28 // 0x1c - /pet back off
|
||||
#define PET_GETLOST 29 // 0x1d - /pet get lost
|
||||
#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client /pet target in modern clients but doesn't send packet
|
||||
#define PET_REGROUP 31 // 0x1f - /pet regroup, acts like classic hold. Stops attack and moves back to guard/you but doesn't clear hate list
|
||||
#define PET_REGROUP_ON 32 // 0x20 - /pet regroup on, turns on regroup
|
||||
#define PET_REGROUP_OFF 33 // 0x21 - /pet regroup off, turns off regroup
|
||||
#define PET_MAXCOMMANDS PET_REGROUP_OFF + 1
|
||||
|
||||
// can change the state of these buttons with a packet
|
||||
#define PET_BUTTON_SIT 0
|
||||
#define PET_BUTTON_STOP 1
|
||||
#define PET_BUTTON_REGROUP 2
|
||||
#define PET_BUTTON_FOLLOW 3
|
||||
#define PET_BUTTON_GUARD 4
|
||||
#define PET_BUTTON_TAUNT 5
|
||||
#define PET_BUTTON_HOLD 6
|
||||
#define PET_BUTTON_GHOLD 7
|
||||
#define PET_BUTTON_FOCUS 8
|
||||
#define PET_BUTTON_SPELLHOLD 9
|
||||
|
||||
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard, SPO_FeignDeath };
|
||||
|
||||
typedef enum {
|
||||
petFamiliar, //only listens to /pet get lost
|
||||
petAnimation, //does not listen to any commands
|
||||
petOther,
|
||||
petCharmed,
|
||||
petNPCFollow,
|
||||
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||
petNone = 0xFF // not a pet
|
||||
} PetTypeOld;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -4607,26 +4607,32 @@ void Client::SummonItemIntoInventory(
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_arrow = inst->GetItem()->ItemType == EQ::item::ItemTypeArrow;
|
||||
const int16 slot_id = m_inv.FindFreeSlot(
|
||||
inst->IsClassBag(),
|
||||
true,
|
||||
inst->GetItem()->Size,
|
||||
is_arrow
|
||||
);
|
||||
// Try stacking first if the item is stackable, then fall back to finding a free slot
|
||||
if (!PutItemInInventoryWithStacking(inst)) {
|
||||
// PutItemInInventoryWithStacking failed, fall back to original behavior
|
||||
const bool is_arrow = inst->GetItem()->ItemType == EQ::item::ItemTypeArrow;
|
||||
const int16 slot_id = m_inv.FindFreeSlot(
|
||||
inst->IsClassBag(),
|
||||
true,
|
||||
inst->GetItem()->Size,
|
||||
is_arrow
|
||||
);
|
||||
|
||||
SummonItem(
|
||||
item_id,
|
||||
charges,
|
||||
aug1,
|
||||
aug2,
|
||||
aug3,
|
||||
aug4,
|
||||
aug5,
|
||||
aug6,
|
||||
is_attuned,
|
||||
slot_id
|
||||
);
|
||||
SummonItem(
|
||||
item_id,
|
||||
charges,
|
||||
aug1,
|
||||
aug2,
|
||||
aug3,
|
||||
aug4,
|
||||
aug5,
|
||||
aug6,
|
||||
is_attuned,
|
||||
slot_id
|
||||
);
|
||||
}
|
||||
|
||||
safe_delete(inst);
|
||||
}
|
||||
|
||||
bool Client::HasItemOnCorpse(uint32 item_id)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user