mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-23 21:32:28 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2434bab697 | |||
| 7a5a755033 |
@@ -1,6 +0,0 @@
|
||||
!Makefile
|
||||
base/*.sql
|
||||
base/*.zip
|
||||
base/db/
|
||||
base/maps/
|
||||
!base/expansion/Makefile
|
||||
@@ -1,9 +0,0 @@
|
||||
# This is a "dev" image for running eqemu in development, also for dev containers
|
||||
ARG USERNAME=user-name-goes-here
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
FROM --platform=linux/arm64 mcr.microsoft.com/devcontainers/base:debian
|
||||
RUN sudo apt update && sudo apt install -y --no-install-recommends build-essential libtool cmake curl debconf-utils git libluabind-dev libsodium-dev liblua5.2-0 liblua5.2-dev libmariadb-dev libssl-dev minizip make mariadb-client locales nano open-vm-tools unzip uuid-dev iputils-ping wget libcurl4-openssl-dev gdb libyaml-cpp-dev ccache ninja-build pv mariadb-server libperl-dev libjson-perl libio-stringy-perl liblua5.1-dev libluabind-dev libboost-dev mariadb-server valgrind telnet libgoogle-perftools-dev google-perftools
|
||||
|
||||
USER $USERNAME
|
||||
@@ -1,9 +0,0 @@
|
||||
# This is a "dev" image for running eqemu in development, also for dev containers
|
||||
ARG USERNAME=user-name-goes-here
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
FROM mcr.microsoft.com/devcontainers/base:debian
|
||||
RUN sudo apt update && sudo apt install -y --no-install-recommends build-essential libtool cmake curl debconf-utils git libluabind-dev libsodium-dev liblua5.2-0 liblua5.2-dev libmariadb-dev libssl-dev minizip make mariadb-client locales nano open-vm-tools unzip uuid-dev iputils-ping wget libcurl4-openssl-dev gdb libyaml-cpp-dev ccache ninja-build pv mariadb-server libperl-dev libjson-perl libio-stringy-perl liblua5.1-dev libluabind-dev libboost-dev mariadb-server valgrind telnet libgoogle-perftools-dev google-perftools
|
||||
|
||||
USER $USERNAME
|
||||
@@ -1,284 +0,0 @@
|
||||
NAME := eqemu-server
|
||||
.ONESHELL:
|
||||
|
||||
DOCKER_ARGS := --rm --name ${NAME} -v $$PWD:/src -w /src ${NAME}
|
||||
DOCKER_ARM64_ARGS := --rm --platform linux/arm64 --name ${NAME}-arm64 -v $$PWD:/src -w /src ${NAME}-arm64
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build$$BUILD_SUFFIX && cmake --build . --config Release --target all --
|
||||
|
||||
.PHONY: cmake
|
||||
cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
mkdir -p build$$BUILD_SUFFIX
|
||||
@cd build$$BUILD_SUFFIX && cmake -DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_TESTS=ON \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G Ninja ..
|
||||
|
||||
clean:
|
||||
ifneq (,$(findstring .devcontainer,$$PWD))
|
||||
@make -C ../ -f .devcontainer/Makefile clean --no-print-directory
|
||||
endif
|
||||
rm -rf build
|
||||
|
||||
docker-cmake:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "working directory: $$PWD"
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARGS} make cmake
|
||||
|
||||
docker-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARGS} make build
|
||||
|
||||
# Build image if it doesn't exist
|
||||
docker-image-build:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-image-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
ifeq ($(shell docker images -q ${NAME} 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.dev -t ${NAME} .
|
||||
endif
|
||||
|
||||
docker-arm-cmake: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-cmake --no-print-directory
|
||||
exit
|
||||
endif
|
||||
git submodule update --init --recursive
|
||||
docker run ${DOCKER_ARM64_ARGS} make cmake BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-build: docker-arm-image-build
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile docker-arm-build --no-print-directory
|
||||
exit
|
||||
endif
|
||||
docker run ${DOCKER_ARM64_ARGS} make build BUILD_SUFFIX=arm64
|
||||
|
||||
docker-arm-image-build:
|
||||
ifeq ($(shell docker images -q ${NAME}-arm64 2> /dev/null),)
|
||||
@echo "Docker image not found. Building..."
|
||||
docker build -f Dockerfile.debian.arm.dev -t ${NAME}-arm64 .
|
||||
endif
|
||||
|
||||
docker-clean: clean
|
||||
|
||||
.PHONY: prep
|
||||
prep:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile prep --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@echo "Preparing build/bin for usage..."
|
||||
mkdir -p build/bin/assets/patches
|
||||
cp -R -u -p .devcontainer/base/eqemu_config.json build/bin/eqemu_config.json
|
||||
cp -R -u -p .devcontainer/base/login.json build/bin/login.json
|
||||
cp -R -u -p loginserver/login_util/* build/bin/assets/patches/
|
||||
mkdir -p build/bin/assets
|
||||
cp -R -u -p utils/patches build/bin/assets/
|
||||
-unlink build/bin/lua_modules
|
||||
cd build/bin && ln -s quests/lua_modules lua_modules
|
||||
-unlink build/bin/mods
|
||||
cd build/bin && ln -s quests/mods mods
|
||||
-unlink build/bin/maps
|
||||
cd build/bin && ln -s ../../base/maps maps
|
||||
mkdir -p build/bin/logs
|
||||
mkdir -p build/bin/shared
|
||||
@echo "Eqemu is prepared. Edit build/bin/eqemu_config.json to configure."
|
||||
|
||||
maps:
|
||||
@echo "Downloading maps..."
|
||||
@mkdir -p base/maps
|
||||
@cd base/maps && wget -nc https://github.com/Akkadius/eqemu-maps/archive/refs/heads/master.zip
|
||||
@cd base/maps && unzip -o master.zip
|
||||
@cd base/maps && mv eqemu-maps-master/* .
|
||||
@cd base/maps && rm -rf eqemu-maps-master
|
||||
@echo "Maps downloaded."
|
||||
|
||||
quests:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile quests --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && git clone https://github.com/ProjectEQ/projecteqquests.git quests
|
||||
|
||||
# Runs tests
|
||||
.PHONY: test
|
||||
test:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile test --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && ./tests
|
||||
|
||||
# Runs login binary
|
||||
.PHONY: login
|
||||
login:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile login --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && ./loginserver
|
||||
|
||||
# Runs shared_memory binary
|
||||
.PHONY: shared
|
||||
shared:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile shared --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && ./shared_memory
|
||||
|
||||
# Runs zone binary
|
||||
.PHONY: zone
|
||||
zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/zone/zone*.log
|
||||
cd build/bin && ./zone
|
||||
|
||||
# Runs world binary
|
||||
.PHONY: world
|
||||
world:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile world --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/world*.log
|
||||
cd build/bin && ./world
|
||||
|
||||
# Runs ucs binary
|
||||
.PHONY: ucs
|
||||
ucs:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile ucs --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/ucs*.log
|
||||
cd build/bin && ./ucs
|
||||
|
||||
# Runs queryserv binary
|
||||
.PHONY: queryserv
|
||||
queryserv:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile queryserv --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@-rm build/bin/logs/query_server*.log
|
||||
cd build/bin && ./queryserv
|
||||
|
||||
valgrind-%:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile valgrind --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --log-file=logs/$*.valgrind.log ./$*
|
||||
|
||||
# Start mariaDB standalone
|
||||
.PHONY: mariadb
|
||||
mariadb:
|
||||
@sudo service mariadb start
|
||||
|
||||
.PHONY: inject-mariadb
|
||||
inject-mariadb:
|
||||
-sudo service mariadb start
|
||||
-mkdir -p base/db/
|
||||
-sudo mariadb -e 'DROP DATABASE IF EXISTS peq;'
|
||||
-sudo mariadb -e 'CREATE DATABASE peq;'
|
||||
-sudo mariadb -e "CREATE USER 'peq'@'127.0.0.1' IDENTIFIED BY 'peqpass';"
|
||||
-sudo mariadb -e "GRANT ALL PRIVILEGES ON *.* TO 'peq'@'127.0.0.1';"
|
||||
ifeq (,$(wildcard base/db/db.sql.zip))
|
||||
@echo "base/db.sql.zip not found. Downloading latest from https://db.projecteq.net/"
|
||||
wget -nc https://db.projecteq.net/latest -O base/db/db.sql.zip
|
||||
-cd base/db && unzip db.sql.zip
|
||||
endif
|
||||
@echo "Sourcing db may take a while, please wait..."
|
||||
@cd base/db/peq-dump && sudo mariadb --database peq -e "source create_all_tables.sql"
|
||||
@echo "MariaDB is now injected."
|
||||
|
||||
.PHONY: gm-%
|
||||
gm-%:
|
||||
sudo mariadb --database peq -e "UPDATE account SET status=255 WHERE name = '$*';"
|
||||
@echo "Account $* is now a GM. /camp to have it go into effect."
|
||||
|
||||
depends:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile depends --no-print-directory
|
||||
exit
|
||||
endif
|
||||
sudo apt install graphviz pip time
|
||||
pip3 install graphviz
|
||||
mkdir -p build/depends
|
||||
@if [ ! -f "build/depends/dependency_graph.py" ]; then \
|
||||
wget https://raw.githubusercontent.com/pvigier/dependency-graph/master/dependency_graph.py -O build/depends/dependency_graph.py; \
|
||||
fi
|
||||
@echo "Generating dependency graphs (This may take a while)..."
|
||||
@echo "Login..."
|
||||
time python3 build/depends/dependency_graph.py -f png login build/depends/login.dot
|
||||
@echo "World..."
|
||||
time python3 build/depends/dependency_graph.py -f png world build/depends/world.dot
|
||||
@echo "Zone..."
|
||||
time python3 build/depends/dependency_graph.py -f png zone build/depends/zone.dot
|
||||
@echo "Common..."
|
||||
time python3 build/depends/dependency_graph.py -f png common build/depends/common.dot
|
||||
|
||||
backup:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile backup --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@mkdir -p build/bin/backup
|
||||
cd build/bin && ./world database:dump --compress --player-tables --state-tables --system-tables --query-serv-tables
|
||||
|
||||
cpu-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile cpu-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && CPUPROFILE=prof.out ./zone
|
||||
|
||||
pprof-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --pdf zone prof.out > prof.pdf
|
||||
pprof-web-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-web-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --web zone prof.out
|
||||
pprof-gv-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile pprof-gv-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
cd build/bin && google-pprof --gv zone prof.out > prof.gv
|
||||
heap-zone:
|
||||
ifeq ($(findstring .devcontainer,$(CURDIR)),.devcontainer)
|
||||
@make -C ../ -f .devcontainer/Makefile heap-zone --no-print-directory
|
||||
exit
|
||||
endif
|
||||
@cd build/bin && mkdir -p tmp
|
||||
cd build/bin && HEAPPROFILE=prof.out ./zone
|
||||
@@ -1,73 +0,0 @@
|
||||
{
|
||||
"server": {
|
||||
"zones": {
|
||||
"defaultstatus": "0",
|
||||
"ports": {
|
||||
"low": "7000",
|
||||
"high": "7400"
|
||||
}
|
||||
},
|
||||
"qsdatabase": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"username": "peq",
|
||||
"password": "peqpass",
|
||||
"db": "peq"
|
||||
},
|
||||
"chatserver": {
|
||||
"port": "7778",
|
||||
"host": ""
|
||||
},
|
||||
"mailserver": {
|
||||
"host": "",
|
||||
"port": "7778"
|
||||
},
|
||||
"webinterface": {
|
||||
"port": "9081"
|
||||
},
|
||||
"world": {
|
||||
"longname": "New Devbox",
|
||||
"address": "192.168.1.100",
|
||||
"localaddress": "192.168.1.100",
|
||||
"loginserver1": {
|
||||
"account": "",
|
||||
"password": "",
|
||||
"legacy": 0,
|
||||
"host": "login.projecteq.net",
|
||||
"port": "5998"
|
||||
},
|
||||
"tcp": {
|
||||
"ip": "127.0.0.1",
|
||||
"port": "9001"
|
||||
},
|
||||
"telnet": {
|
||||
"ip": "0.0.0.0",
|
||||
"port": "9000",
|
||||
"enabled": "true"
|
||||
},
|
||||
"key": "random-generate-here",
|
||||
"http": {
|
||||
"port": "9080",
|
||||
"enabled": "true",
|
||||
"mimefile": "mime.types"
|
||||
},
|
||||
"shortname": "dev"
|
||||
},
|
||||
"database": {
|
||||
"db": "peq",
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"username": "peq",
|
||||
"password": "peqpass"
|
||||
},
|
||||
"files": {
|
||||
"opcodes": "assets/patches/opcodes.conf",
|
||||
"mail_opcodes": "assets/patches/mail_opcodes.conf"
|
||||
},
|
||||
"directories": {
|
||||
"patches": "assets/patches/",
|
||||
"opcodes": "assets/patches/",
|
||||
"plugins": "quests/plugins/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
{
|
||||
"database": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "3306",
|
||||
"db": "peq",
|
||||
"user": "peq",
|
||||
"password": "peqpass"
|
||||
},
|
||||
"account": {
|
||||
"auto_create_accounts": true
|
||||
},
|
||||
"worldservers": {
|
||||
"unregistered_allowed": true,
|
||||
"reject_duplicate_servers": false
|
||||
},
|
||||
"web_api": {
|
||||
"enabled": true,
|
||||
"port": 6000
|
||||
},
|
||||
"security": {
|
||||
"mode": 14,
|
||||
"allow_password_login": true,
|
||||
"allow_token_login": true
|
||||
},
|
||||
"logging": {
|
||||
"trace": false,
|
||||
"world_trace": false,
|
||||
"dump_packets_in": false,
|
||||
"dump_packets_out": false
|
||||
},
|
||||
"client_configuration": {
|
||||
"titanium_port": 5998,
|
||||
"titanium_opcodes": "assets/patches/login_opcodes.conf",
|
||||
"sod_port": 5999,
|
||||
"sod_opcodes": "assets/patches/login_opcodes_sod.conf"
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
|
||||
{
|
||||
"name": "eqemu",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile.debian.dev"
|
||||
},
|
||||
"appPort": [
|
||||
"5998:5998/udp",
|
||||
"7000:7000/udp",
|
||||
"7001:7001/udp",
|
||||
"7002:7002/udp",
|
||||
"7003:7003/udp",
|
||||
"7004:7004/udp",
|
||||
"7005:7005/udp",
|
||||
"9000:9000/udp",
|
||||
"9001:9001/udp"
|
||||
],
|
||||
"forwardPorts": [
|
||||
3306
|
||||
],
|
||||
"remoteEnv": {
|
||||
"LOCALWSF": "${localWorkspaceFolder}",
|
||||
"CONTAINERWSF": "${containerWorkspaceFolder}"
|
||||
},
|
||||
"containerUser": "vscode",
|
||||
// add ptrace
|
||||
"runArgs": [
|
||||
"--cap-add=SYS_PTRACE",
|
||||
"--security-opt",
|
||||
"seccomp=unconfined"
|
||||
],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools-extension-pack",
|
||||
"vilicvane.sensitive-replace",
|
||||
"maattdd.gitless",
|
||||
"bibhasdn.unique-lines",
|
||||
"GitHub.copilot",
|
||||
"xackery.make-magic",
|
||||
"Gruntfuggly.todo-tree",
|
||||
"ms-vscode.cmake-tools"
|
||||
]
|
||||
}
|
||||
},
|
||||
"workspaceFolder": "/src",
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/src,type=bind,consistency=cached"
|
||||
}
|
||||
@@ -61,6 +61,9 @@ bin/
|
||||
compile_flags.txt
|
||||
.cache/
|
||||
|
||||
# vscode generated settings
|
||||
.vscode/
|
||||
|
||||
# Build pipeline
|
||||
!utils/scripts/build/
|
||||
!utils/scripts/build/should-release/should-release
|
||||
|
||||
Vendored
-23
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${default}",
|
||||
"${workspaceFolder}/submodules/fmt/include",
|
||||
"${workspaceFolder}/submodules/cereal/include",
|
||||
"${workspaceFolder}/submodules/glm",
|
||||
"${workspaceFolder}/submodules/libuv/include"
|
||||
],
|
||||
"defines": [
|
||||
"LUA_EQEMU=1"
|
||||
],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
Vendored
-173
@@ -1,173 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) attach",
|
||||
"type": "cppdbg",
|
||||
"request": "attach",
|
||||
"program": "${workspaceFolder}/build/bin/world",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) shared_memory",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/shared_memory",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) world",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/world",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) zone",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/zone",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"args": [
|
||||
"",
|
||||
],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) zone neriakb",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/zone",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"args": [
|
||||
"neriakb",
|
||||
],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) login",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/loginserver",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) ucs",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/ucs",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "(gdb) queryserv",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/queryserv",
|
||||
"cwd": "${workspaceFolder}/build/bin",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
-136
@@ -1,136 +0,0 @@
|
||||
{
|
||||
"editor.detectIndentation": false,
|
||||
"editor.insertSpaces": false,
|
||||
"editor.tabSize": 4,
|
||||
"editor.autoIndent": "full",
|
||||
"editor.trimAutoWhitespace": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
//"editor.formatOnSave": true,
|
||||
"search.exclude": {
|
||||
"dependencies": false,
|
||||
},
|
||||
"C_Cpp.default.includePath": [
|
||||
"/usr/include/x86_64-linux-gnu",
|
||||
"/usr/include/lua5.2",
|
||||
"/usr/include/mariadb",
|
||||
"${workspaceFolder}/dependencies/curl_x64/include",
|
||||
"${workspaceFolder}/dependencies/fmt/include",
|
||||
"${workspaceFolder}/dependencies/glm",
|
||||
"${workspaceFolder}/dependencies/libuv/include",
|
||||
"${workspaceFolder}/dependencies/sol2",
|
||||
"${workspaceFolder}/dependencies/zlibng"
|
||||
],
|
||||
"telemetry.enableTelemetry": false,
|
||||
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||
"cmake.configureArgs": [
|
||||
"-DEQEMU_BUILD_LOGIN=ON",
|
||||
"-DEQEMU_BUILD_TESTS=ON",
|
||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache",
|
||||
"-DEQEMU_ADD_PROFILER=ON",
|
||||
"Ninja"
|
||||
],
|
||||
"cmake.skipConfigureIfCachePresent": true,
|
||||
"cmake.configureOnOpen": false,
|
||||
"files.associations": {
|
||||
"*.ipp": "cpp",
|
||||
"functional": "cpp",
|
||||
"string": "cpp",
|
||||
"iostream": "cpp",
|
||||
"map": "cpp",
|
||||
"fstream": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"cstring": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"strstream": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"source_location": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"charconv": "cpp",
|
||||
"format": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp"
|
||||
},
|
||||
"cmake.statusbar.advanced": {
|
||||
"kit": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"debug": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"buildTarget": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"launch": {
|
||||
"visibility": "hidden",
|
||||
},
|
||||
"ctest": {
|
||||
"visibility": "icon",
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-873
@@ -1,863 +1,3 @@
|
||||
## [22.60.0] 11/25/2024
|
||||
|
||||
### Bazaar
|
||||
|
||||
* Further refinements for instanced bazaar ([#4544](https://github.com/EQEmu/Server/pull/4544)) @neckkola 2024-11-16
|
||||
|
||||
### Code
|
||||
|
||||
* Fix build with older C++ libraries ([#4549](https://github.com/EQEmu/Server/pull/4549)) @hgtw 2024-11-24
|
||||
|
||||
### Config
|
||||
|
||||
* Fix World TCP Address Configuration Default ([#4551](https://github.com/EQEmu/Server/pull/4551)) @Akkadius 2024-11-24
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix Issue with Perl EVENT_PAYLOAD ([#4545](https://github.com/EQEmu/Server/pull/4545)) @Kinglykrab 2024-11-24
|
||||
* Fix Possible Item Loss in Trades ([#4554](https://github.com/EQEmu/Server/pull/4554)) @Kinglykrab 2024-11-24
|
||||
* Fix Strings::Commify bug with #mystats ([#4547](https://github.com/EQEmu/Server/pull/4547)) @carolus21rex 2024-11-22
|
||||
* Fix an edge case with augmented items inside parceled containers ([#4546](https://github.com/EQEmu/Server/pull/4546)) @neckkola 2024-11-21
|
||||
* Fix for bazaar search of containers. ([#4540](https://github.com/EQEmu/Server/pull/4540)) @neckkola 2024-11-15
|
||||
* Fix for mult-instanced bazaar zones ([#4541](https://github.com/EQEmu/Server/pull/4541)) @neckkola 2024-11-15
|
||||
* Fix for sending money via Parcel, then changing your mind ([#4552](https://github.com/EQEmu/Server/pull/4552)) @neckkola 2024-11-24
|
||||
* Fix issue where NPC's are being hidden as traders ([#4539](https://github.com/EQEmu/Server/pull/4539)) @Akkadius 2024-11-15
|
||||
* Players could become flagged as a Trader when they were not trading ([#4553](https://github.com/EQEmu/Server/pull/4553)) @neckkola 2024-11-24
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Rule to Disable NPCs Facing Target ([#4543](https://github.com/EQEmu/Server/pull/4543)) @Kinglykrab 2024-11-24
|
||||
|
||||
### Tasks
|
||||
|
||||
* Update tasks in all zones if invalid zone set ([#4550](https://github.com/EQEmu/Server/pull/4550)) @hgtw 2024-11-25
|
||||
|
||||
## [22.59.1] 11/13/2024
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Fix faulty database migration condition with databuckets (9285)
|
||||
|
||||
## [22.59.0] 11/13/2024
|
||||
|
||||
### Databuckets
|
||||
|
||||
* Add database index to data_buckets ([#4535](https://github.com/EQEmu/Server/pull/4535)) @Akkadius 2024-11-09
|
||||
|
||||
### Fixes
|
||||
|
||||
* Bazaar two edge case issues resolved ([#4533](https://github.com/EQEmu/Server/pull/4533)) @neckkola 2024-11-09
|
||||
* Check if the mob is already in the close mobs list before inserting @Akkadius 2024-11-11
|
||||
* ScanCloseMobs - Ensure scanning mob has an entity ID @Akkadius 2024-11-10
|
||||
|
||||
### Performance
|
||||
|
||||
* Improvements to ScanCloseMobs logic ([#4534](https://github.com/EQEmu/Server/pull/4534)) @Akkadius 2024-11-08
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Native Database Querying Interface ([#4531](https://github.com/EQEmu/Server/pull/4531)) @hgtw 2024-11-13
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Rule for restricting client versions to world server ([#4527](https://github.com/EQEmu/Server/pull/4527)) @knervous 2024-11-12
|
||||
|
||||
## [22.58.0] 11/5/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Add mysql prepared statement support ([#4530](https://github.com/EQEmu/Server/pull/4530)) @hgtw 2024-11-06
|
||||
* Update perlbind to 1.1.0 ([#4529](https://github.com/EQEmu/Server/pull/4529)) @hgtw 2024-11-06
|
||||
|
||||
### Feature
|
||||
|
||||
* Focus Skill Attack Spells ([#4528](https://github.com/EQEmu/Server/pull/4528)) @mmcgarvey 2024-10-31
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add Missing Lua Registers ([#4525](https://github.com/EQEmu/Server/pull/4525)) @Kinglykrab 2024-10-24
|
||||
* Fix cross_zone_set_entity_variable_by_char_id in Lua ([#4526](https://github.com/EQEmu/Server/pull/4526)) @Kinglykrab 2024-10-24
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Automatifc Opcode File Creation ([#4521](https://github.com/EQEmu/Server/pull/4521)) @KimLS 2024-10-22
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Spawn Circle/Grid Methods to Perl/Lua ([#4524](https://github.com/EQEmu/Server/pull/4524)) @Kinglykrab 2024-10-24
|
||||
|
||||
## [22.57.1] 10/22/2024
|
||||
|
||||
### Bots
|
||||
|
||||
* Enable Bot Commands Only if Rule Enabled ([#4519](https://github.com/EQEmu/Server/pull/4519)) @Kinglykrab 2024-10-22
|
||||
* Fix pet buffs from saving duplicates every save ([#4520](https://github.com/EQEmu/Server/pull/4520)) @nytmyr 2024-10-22
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Automatic Opcode File Creation ([#4521](https://github.com/EQEmu/Server/pull/4521)) @KimLS 2024-10-22
|
||||
|
||||
## [22.57.0] 10/20/2024
|
||||
|
||||
### Bots
|
||||
|
||||
* Add "silent" option to ^spawn and mute raid spawn ([#4494](https://github.com/EQEmu/Server/pull/4494)) @nytmyr 2024-10-05
|
||||
* Add attack flag when told to attack ([#4490](https://github.com/EQEmu/Server/pull/4490)) @nytmyr 2024-09-29
|
||||
* Fix timers loading on spawn and zone ([#4516](https://github.com/EQEmu/Server/pull/4516)) @nytmyr 2024-10-20
|
||||
|
||||
### Code
|
||||
|
||||
* Fixed a typo in Zoning.cpp ([#4515](https://github.com/EQEmu/Server/pull/4515)) @carolus21rex 2024-10-20
|
||||
* Optimization Code Cleanup ([#4489](https://github.com/EQEmu/Server/pull/4489)) @Akkadius 2024-09-30
|
||||
* Remove Extra Skill in EQ::skills::GetExtraDamageSkills() ([#4486](https://github.com/EQEmu/Server/pull/4486)) @Kinglykrab 2024-10-03
|
||||
|
||||
### Crash
|
||||
|
||||
* Fixes a crash when the faction_list db table is empty. ([#4511](https://github.com/EQEmu/Server/pull/4511)) @KimLS 2024-10-14
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add character_instance_safereturns to tables_to_zero_id ([#4485](https://github.com/EQEmu/Server/pull/4485)) @Morzain 2024-09-26
|
||||
* Correctly limit max targets of PBAOE ([#4507](https://github.com/EQEmu/Server/pull/4507)) @catapultam-habeo 2024-10-11
|
||||
* FindBestZ selecting false zone floor as bestz - Results in roambox failures ([#4504](https://github.com/EQEmu/Server/pull/4504)) @fryguy503 2024-10-13
|
||||
* Fix #set motd Crash ([#4495](https://github.com/EQEmu/Server/pull/4495)) @Kinglykrab 2024-10-05
|
||||
* Fix `character_exp_modifiers` Default Values ([#4502](https://github.com/EQEmu/Server/pull/4502)) @Kinglykrab 2024-10-09
|
||||
* Fix a display error regarding a few trader/buyer query errors ([#4514](https://github.com/EQEmu/Server/pull/4514)) @neckkola 2024-10-17
|
||||
* Fix Group ID 0 in Group::SaveGroupLeaderAA() ([#4487](https://github.com/EQEmu/Server/pull/4487)) @Kinglykrab 2024-10-03
|
||||
* Fix Mercenary Encounter Crash ([#4509](https://github.com/EQEmu/Server/pull/4509)) @Kinglykrab 2024-10-12
|
||||
* Fix NPC::CanTalk() Crash ([#4499](https://github.com/EQEmu/Server/pull/4499)) @Kinglykrab 2024-10-07
|
||||
* Fix Spells:DefaultAOEMaxTargets Default Value ([#4508](https://github.com/EQEmu/Server/pull/4508)) @Kinglykrab 2024-10-12
|
||||
* Fix Targeted AOE Max Targets Rule ([#4488](https://github.com/EQEmu/Server/pull/4488)) @Kinglykrab 2024-10-03
|
||||
* fixed a bug where it would use npc value instead of faction value in the database. ([#4491](https://github.com/EQEmu/Server/pull/4491)) @regneq 2024-09-29
|
||||
* Master of Disguise should apply to illusions casted by others. ([#4506](https://github.com/EQEmu/Server/pull/4506)) @fryguy503 2024-10-11
|
||||
* Spells - Self Only (Yellow) cast when non group member is targeted ([#4503](https://github.com/EQEmu/Server/pull/4503)) @fryguy503 2024-10-11
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Larion loginserver support ([#4492](https://github.com/EQEmu/Server/pull/4492)) @KimLS 2024-10-03
|
||||
* Login Fatal Error Spamming ([#4476](https://github.com/EQEmu/Server/pull/4476)) @KimLS 2024-10-09
|
||||
|
||||
### Logs
|
||||
|
||||
* Add NPC Trades to Player Events ([#4505](https://github.com/EQEmu/Server/pull/4505)) @Kinglykrab 2024-10-13
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Buff Fade Methods to Perl/Lua ([#4501](https://github.com/EQEmu/Server/pull/4501)) @Kinglykrab 2024-10-09
|
||||
* Add EVENT_READ_ITEM to Perl/Lua ([#4497](https://github.com/EQEmu/Server/pull/4497)) @Kinglykrab 2024-10-08
|
||||
* Add NPC List Filter Methods to Perl/Lua ([#4493](https://github.com/EQEmu/Server/pull/4493)) @Kinglykrab 2024-10-04
|
||||
* Add Scripting Support to Mercenaries ([#4500](https://github.com/EQEmu/Server/pull/4500)) @Kinglykrab 2024-10-11
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Rule to disable PVP Regions ([#4513](https://github.com/EQEmu/Server/pull/4513)) @Kinglykrab 2024-10-17
|
||||
|
||||
## [22.56.3] 9/23/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix issue with Client::SaveDisciplines() not specifying character ID ([#4481](https://github.com/EQEmu/Server/pull/4477)) @Kinglykrab 2024-09-23
|
||||
|
||||
## [22.56.2] 9/20/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix Issue with Database::ReserveName ([#4477](https://github.com/EQEmu/Server/pull/4477)) @Kinglykrab 2024-09-20
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GrantAllAAPoints() Overload To Perl/Lua ([#4474](https://github.com/EQEmu/Server/pull/4474)) @Kinglykrab 2024-09-20
|
||||
|
||||
## [22.56.1] 9/20/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix Untrained Disciplines in Client::SaveDisciplines() ([#4472](https://github.com/EQEmu/Server/pull/4472)) @Kinglykrab 2024-09-13
|
||||
* Fix Infinite Loop in Adventure::Finished() ([#4473](https://github.com/EQEmu/Server/pull/4473)) @oddx2k 2024-09-13
|
||||
|
||||
## [22.56.0] 9/12/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Add IsCloseToBanker method ([#4462](https://github.com/EQEmu/Server/pull/4462)) @Akkadius 2024-08-27
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Rule to Limit Task Update Messages ([#4459](https://github.com/EQEmu/Server/pull/4459)) @Kinglykrab 2024-08-28
|
||||
* Allow NPCs to cast Sacrifice ([#4470](https://github.com/EQEmu/Server/pull/4470)) @fuzzlecutter 2024-09-12
|
||||
* Lazy Load Bank Contents ([#4453](https://github.com/EQEmu/Server/pull/4453)) @catapultam-habeo 2024-08-27
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add RULE_STRING to RuleManager::ResetRules ([#4467](https://github.com/EQEmu/Server/pull/4467)) @Kinglykrab 2024-09-07
|
||||
* Fix Bard Effect in Migration 9237 ([#4468](https://github.com/EQEmu/Server/pull/4468)) @Kinglykrab 2024-09-09
|
||||
* ModernAAScalingEnabled() Calculation Error ([#4469](https://github.com/EQEmu/Server/pull/4469)) @carolus21rex 2024-09-11
|
||||
|
||||
### Performance
|
||||
|
||||
* Move Discipline Loading to Client::CompleteConnect() ([#4466](https://github.com/EQEmu/Server/pull/4466)) @Kinglykrab 2024-09-09
|
||||
|
||||
### Rules
|
||||
|
||||
* Add a Bandolier Swap Delay Rule ([#4465](https://github.com/EQEmu/Server/pull/4465)) @Kinglykrab 2024-09-08
|
||||
|
||||
## [22.55.1] 8/26/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Remove unused methods ([#4449](https://github.com/EQEmu/Server/pull/4449)) @Kinglykrab 2024-08-22
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Character:DefaultGuildRank Rule ([#4438](https://github.com/EQEmu/Server/pull/4438)) @Kinglykrab 2024-08-04
|
||||
* Add Optional Return to EVENT_DAMAGE_TAKEN ([#4454](https://github.com/EQEmu/Server/pull/4454)) @Kinglykrab 2024-08-27
|
||||
* Extend Spell Buckets Functionality ([#4441](https://github.com/EQEmu/Server/pull/4441)) @Kinglykrab 2024-08-22
|
||||
|
||||
### Fixes
|
||||
|
||||
* Apply Race & Class restrictions to Auto-Combines ([#4452](https://github.com/EQEmu/Server/pull/4452)) @catapultam-habeo 2024-08-20
|
||||
* Attune Augments when Equipped ([#4446](https://github.com/EQEmu/Server/pull/4446)) @fryguy503 2024-08-10
|
||||
* Correct missed maxlevel reference in exp.cpp ([#4463](https://github.com/EQEmu/Server/pull/4463)) @N0ctrnl 2024-08-27
|
||||
* Ensure close of Tribute Item search ([#4439](https://github.com/EQEmu/Server/pull/4439)) @joligario 2024-08-04
|
||||
* Fix AddCrystals() in Perl/Lua ([#4445](https://github.com/EQEmu/Server/pull/4445)) @Kinglykrab 2024-08-10
|
||||
* Fix Bot Spell Entries IDs Capping at 32,767 ([#4444](https://github.com/EQEmu/Server/pull/4444)) @Kinglykrab 2024-08-27
|
||||
* Fix Character ID of 0 being inserted into character_stats_record ([#4458](https://github.com/EQEmu/Server/pull/4458)) @Kinglykrab 2024-08-22
|
||||
* Fix Issue with Removed #setfaction Command ([#4448](https://github.com/EQEmu/Server/pull/4448)) @Kinglykrab 2024-08-11
|
||||
* Fix Lua Client FilteredMessage ([#4437](https://github.com/EQEmu/Server/pull/4437)) @Kinglykrab 2024-07-31
|
||||
* Fix client hotbar exchanging items when zoning ([#4460](https://github.com/EQEmu/Server/pull/4460)) @neckkola 2024-08-27
|
||||
* Fix issue with killed mob coordinates ([#4457](https://github.com/EQEmu/Server/pull/4457)) @Kinglykrab 2024-08-22
|
||||
* Imitate Death should also clear zone feign aggro ([#4436](https://github.com/EQEmu/Server/pull/4436)) @fryguy503 2024-07-31
|
||||
* client_max_level allow leveling to end of level ([#4455](https://github.com/EQEmu/Server/pull/4455)) @fryguy503 2024-08-20
|
||||
|
||||
### Improvement
|
||||
|
||||
* Filtered Messages Extension ([#4435](https://github.com/EQEmu/Server/pull/4435)) @fryguy503 2024-07-31
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add AreTasksCompleted() to Perl/Lua. ([#4456](https://github.com/EQEmu/Server/pull/4456)) @Kinglykrab 2024-08-23
|
||||
* Add Area-Based Quest Methods to Perl/Lua ([#4447](https://github.com/EQEmu/Server/pull/4447)) @Kinglykrab 2024-08-27
|
||||
* Add Several Door Methods to Perl/Lua ([#4451](https://github.com/EQEmu/Server/pull/4451)) @Kinglykrab 2024-08-16
|
||||
|
||||
### World
|
||||
|
||||
* Fix slow world bootup bug ([#4461](https://github.com/EQEmu/Server/pull/4461)) @Akkadius 2024-08-27
|
||||
|
||||
## [22.54.0] 7/30/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup Client File Exporting ([#4348](https://github.com/EQEmu/Server/pull/4348)) @Kinglykrab 2024-07-31
|
||||
* Cleanup Stance Code ([#4368](https://github.com/EQEmu/Server/pull/4368)) @Kinglykrab 2024-07-03
|
||||
* Mask GM Show Buff message behind EntityVariable ([#4419](https://github.com/EQEmu/Server/pull/4419)) @nytmyr 2024-07-22
|
||||
|
||||
### Commands
|
||||
|
||||
* Extend #devtools Functionality ([#4425](https://github.com/EQEmu/Server/pull/4425)) @Kinglykrab 2024-07-23
|
||||
|
||||
### Databuckets
|
||||
|
||||
* Remove memory reserve from bulk load ([#4427](https://github.com/EQEmu/Server/pull/4427)) @Akkadius 2024-07-23
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Barter/Buyer Features ([#4405](https://github.com/EQEmu/Server/pull/4405)) @neckkola 2024-07-30
|
||||
* Add Parcel notification for online players when using the Quest API ([#4418](https://github.com/EQEmu/Server/pull/4418)) @neckkola 2024-07-22
|
||||
* Implement Move Multiple Items ([#4259](https://github.com/EQEmu/Server/pull/4259)) @catapultam-habeo 2024-07-30
|
||||
|
||||
### Fixes
|
||||
|
||||
* Aegolism Spell line stacking ([#4399](https://github.com/EQEmu/Server/pull/4399)) @KayenEQ 2024-07-07
|
||||
* AllowRaidTargetBlind logic backwards ([#4400](https://github.com/EQEmu/Server/pull/4400)) @fryguy503 2024-07-01
|
||||
* AutoSplit unknown bug and cleanup. ([#4401](https://github.com/EQEmu/Server/pull/4401)) @fryguy503 2024-07-07
|
||||
* Corpse Call removing Resurrection Effects ([#4410](https://github.com/EQEmu/Server/pull/4410)) @fryguy503 2024-07-22
|
||||
* Fix #parcels add subcommand ([#4431](https://github.com/EQEmu/Server/pull/4431)) @neckkola 2024-07-29
|
||||
* Fix #setlevel Allowing Skills Above Max ([#4423](https://github.com/EQEmu/Server/pull/4423)) @Kinglykrab 2024-07-23
|
||||
* Fix Bot::SetBotStance ([#4426](https://github.com/EQEmu/Server/pull/4426)) @Kinglykrab 2024-07-23
|
||||
* Fix Client::RemoveTitle ([#4421](https://github.com/EQEmu/Server/pull/4421)) @Kinglykrab 2024-07-23
|
||||
* Fix EVENT_USE_SKILL with Sense Heading ([#4424](https://github.com/EQEmu/Server/pull/4424)) @Kinglykrab 2024-07-23
|
||||
* Fix for random disconnects when a large number of guild members zone or disconnect ([#4402](https://github.com/EQEmu/Server/pull/4402)) @neckkola 2024-07-10
|
||||
* Fix issue with quest::echo and quest::me ([#4433](https://github.com/EQEmu/Server/pull/4433)) @Kinglykrab 2024-07-30
|
||||
* Personal tributes for bard items were not applying correctly ([#4416](https://github.com/EQEmu/Server/pull/4416)) @neckkola 2024-07-16
|
||||
* Potential fix for some undesired ranged explotative behavior. ([#4413](https://github.com/EQEmu/Server/pull/4413)) @fryguy503 2024-07-22
|
||||
* Proximity Aggro for Frustrated and Undead ([#4411](https://github.com/EQEmu/Server/pull/4411)) @fryguy503 2024-07-22
|
||||
* Slay Adjustments ([#4389](https://github.com/EQEmu/Server/pull/4389)) @fryguy503 2024-07-07
|
||||
* Stop DOSing ourselves with OP_WearChange ([#4432](https://github.com/EQEmu/Server/pull/4432)) @catapultam-habeo 2024-07-30
|
||||
* [Quest API] Fix getraididbycharid and getgroupidbycharid ([#4417](https://github.com/EQEmu/Server/pull/4417)) @nytmyr 2024-07-16
|
||||
|
||||
### Improvement
|
||||
|
||||
* Flee Overhaul ([#4407](https://github.com/EQEmu/Server/pull/4407)) @fryguy503 2024-07-30
|
||||
|
||||
### Rules
|
||||
|
||||
* Add HasteCap and Hastev3Cap rules for NPCs, Bots and Mercs ([#4406](https://github.com/EQEmu/Server/pull/4406)) @nytmyr 2024-07-22
|
||||
|
||||
### Zone Instances
|
||||
|
||||
* Revert " Handle routing to instances when using evac/succor " (#4429) ([#4297](https://github.com/EQEmu/Server/pull/4297)) @Akkadius 2024-07-30
|
||||
|
||||
### Zoning
|
||||
|
||||
* Improve zone routing ([#4428](https://github.com/EQEmu/Server/pull/4428)) @Akkadius 2024-07-30
|
||||
|
||||
## [22.53.1] 6/16/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix trader mode ([#4397](https://github.com/EQEmu/Server/pull/4397)) @joligario 2024-06-17
|
||||
|
||||
## [22.53.0] 6/14/2024
|
||||
|
||||
### Bug
|
||||
|
||||
* Anon players should not show in /who all ([#4392](https://github.com/EQEmu/Server/pull/4392)) @fryguy503 2024-06-14
|
||||
* Escape should put player into SOS if owned. ([#4388](https://github.com/EQEmu/Server/pull/4388)) @fryguy503 2024-06-07
|
||||
* Prevent Resurrection Spells from being resisted ([#4393](https://github.com/EQEmu/Server/pull/4393)) @fryguy503 2024-06-14
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup Account Status Code ([#4376](https://github.com/EQEmu/Server/pull/4376)) @Kinglykrab 2024-06-02
|
||||
* Cleanup Body Type Code ([#4366](https://github.com/EQEmu/Server/pull/4366)) @Kinglykrab 2024-06-02
|
||||
* Cleanup Object Type Code ([#4375](https://github.com/EQEmu/Server/pull/4375)) @Kinglykrab 2024-06-14
|
||||
* Remove unused code in emu_constants.h ([#4384](https://github.com/EQEmu/Server/pull/4384)) @Kinglykrab 2024-06-14
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix #goto Target ([#4382](https://github.com/EQEmu/Server/pull/4382)) @Kinglykrab 2024-06-03
|
||||
* Fix Swarm Pet Damage Messages ([#4383](https://github.com/EQEmu/Server/pull/4383)) @Kinglykrab 2024-06-04
|
||||
* Fix for players having empty bazaar window dropdown list, even though trader is tagged as a trader. ([#4391](https://github.com/EQEmu/Server/pull/4391)) @neckkola 2024-06-14
|
||||
* Fix potential trader crash when serialized item not found ([#4386](https://github.com/EQEmu/Server/pull/4386)) @joligario 2024-06-14
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Invisible Augment Rules ([#4385](https://github.com/EQEmu/Server/pull/4385)) @Kinglykrab 2024-06-14
|
||||
* Classic Harm Touch Formula ([#4394](https://github.com/EQEmu/Server/pull/4394)) @fryguy503 2024-06-14
|
||||
* Mend/Sneak allow success tuning ([#4390](https://github.com/EQEmu/Server/pull/4390)) @fryguy503 2024-06-14
|
||||
* Snare Override Movement Bonus ([#4381](https://github.com/EQEmu/Server/pull/4381)) @fryguy503 2024-06-02
|
||||
|
||||
## [22.52.0] 6/1/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup Bucket Comparison Code ([#4374](https://github.com/EQEmu/Server/pull/4374)) @Kinglykrab 2024-06-02
|
||||
* Cleanup Bug Category Code ([#4367](https://github.com/EQEmu/Server/pull/4367)) @Kinglykrab 2024-06-01
|
||||
* Cleanup Deity Code ([#4363](https://github.com/EQEmu/Server/pull/4363)) @Kinglykrab 2024-06-01
|
||||
* Cleanup Special Ability Code ([#4365](https://github.com/EQEmu/Server/pull/4365)) @Kinglykrab 2024-06-01
|
||||
* Remove unused code in common/eq_constants.h ([#4364](https://github.com/EQEmu/Server/pull/4364)) @Kinglykrab 2024-06-01
|
||||
|
||||
### Combat
|
||||
|
||||
* Adjustments to Crippling Blows/Slay Undead and Confirmed Critical Code ([#4354](https://github.com/EQEmu/Server/pull/4354)) @fryguy503 2024-05-27
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add protection to ensure adventure points award are only attempted on players ([#4371](https://github.com/EQEmu/Server/pull/4371)) @joligario 2024-05-31
|
||||
* Adjust Kick/RoundKick Damage Lower levels ([#4355](https://github.com/EQEmu/Server/pull/4355)) @fryguy503 2024-05-28
|
||||
* Bazaar Search not working correctly for Iksar, Vashir, Drakkin and Froglok races ([#4379](https://github.com/EQEmu/Server/pull/4379)) @neckkola 2024-06-02
|
||||
* Fix Unescaped String in Client::GotoPlayer ([#4373](https://github.com/EQEmu/Server/pull/4373)) @Kinglykrab 2024-06-01
|
||||
|
||||
### NPC Spells
|
||||
|
||||
* Fixed an issue where the repository spell adj value was overriding the spell difficulty default value ([#4370](https://github.com/EQEmu/Server/pull/4370)) @regneq 2024-06-01
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Item Link Methods to Perl/Lua ([#4359](https://github.com/EQEmu/Server/pull/4359)) @Kinglykrab 2024-06-01
|
||||
|
||||
### Quests
|
||||
|
||||
* Fix Lua encounter double register ([#4369](https://github.com/EQEmu/Server/pull/4369)) @Akkadius 2024-05-31
|
||||
* Fix issue with Lua encounters loading in certain circumstances ([#4378](https://github.com/EQEmu/Server/pull/4378)) @Akkadius 2024-06-01
|
||||
|
||||
### Rules
|
||||
|
||||
* Add Skill Base Damage Rules ([#4360](https://github.com/EQEmu/Server/pull/4360)) @Kinglykrab 2024-06-01
|
||||
|
||||
### Skills
|
||||
|
||||
* Fix caps out of bounds issue ([#4377](https://github.com/EQEmu/Server/pull/4377)) @Akkadius 2024-06-01
|
||||
|
||||
## [22.51.1] 5/27/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Adjust return for perl release check @Akkadius 2024-05-26
|
||||
* Corrected issue with bazaar purchase via parcels where an incorrect quantity would be calculated. ([#4352](https://github.com/EQEmu/Server/pull/4352)) @neckkola 2024-05-27
|
||||
|
||||
### Performance
|
||||
|
||||
* Improve SkillCaps::GetTrainLevel() Efficiency ([#4350](https://github.com/EQEmu/Server/pull/4350)) @Kinglykrab 2024-05-26
|
||||
|
||||
### Rules
|
||||
|
||||
* Legacy Compute Defense against modern agi based defense. ([#4349](https://github.com/EQEmu/Server/pull/4349)) @fryguy503 2024-05-27
|
||||
|
||||
## [22.51.0] 5/26/2024
|
||||
|
||||
### Commands
|
||||
|
||||
* #npcspawn Changes ([#4311](https://github.com/EQEmu/Server/pull/4311)) @twincannon 2024-05-16
|
||||
* Cleanup #resetaa Command ([#4310](https://github.com/EQEmu/Server/pull/4310)) @Kinglykrab 2024-05-22
|
||||
|
||||
### Crash
|
||||
|
||||
* Add validation to RemoveXTarget ([#4324](https://github.com/EQEmu/Server/pull/4324)) @Akkadius 2024-05-25
|
||||
* Fix Zone deconstructor crashes ([#4325](https://github.com/EQEmu/Server/pull/4325)) @Akkadius 2024-05-25
|
||||
* Fix crash issue when dividing by zero in CalcHPRegen ([#4320](https://github.com/EQEmu/Server/pull/4320)) @Akkadius 2024-05-25
|
||||
* Fix crash when map name is null ([#4322](https://github.com/EQEmu/Server/pull/4322)) @Akkadius 2024-05-25
|
||||
* Fix player event crash in ITEM_DESTROY ([#4326](https://github.com/EQEmu/Server/pull/4326)) @Akkadius 2024-05-25
|
||||
* Fix player events reload when out of bounds ([#4321](https://github.com/EQEmu/Server/pull/4321)) @Akkadius 2024-05-25
|
||||
* Fix rarer crash in EntityList::MobProcess ([#4319](https://github.com/EQEmu/Server/pull/4319)) @Akkadius 2024-05-25
|
||||
|
||||
### Feature
|
||||
|
||||
* Add RoF2 Bazaar Support ([#4315](https://github.com/EQEmu/Server/pull/4315)) @neckkola 2024-05-26
|
||||
* Add SE_IncreaseArchery and rules to tune archery ([#4335](https://github.com/EQEmu/Server/pull/4335)) @fryguy503 2024-05-26
|
||||
* Add parcel container support ([#4305](https://github.com/EQEmu/Server/pull/4305)) @neckkola 2024-05-17
|
||||
|
||||
### Fixes
|
||||
|
||||
* Accuracy, Avoidance and Atk adjustments ([#4336](https://github.com/EQEmu/Server/pull/4336)) @fryguy503 2024-05-26
|
||||
* Fix Crash with null Argument in #modifynpcstat ([#4318](https://github.com/EQEmu/Server/pull/4318)) @Kinglykrab 2024-05-24
|
||||
* Fix RemoveAlternateCurrencyValue not updating Client ([#4317](https://github.com/EQEmu/Server/pull/4317)) @Kinglykrab 2024-05-23
|
||||
* Fix Using Bind Wound Above 70% Health ([#4340](https://github.com/EQEmu/Server/pull/4340)) @Kinglykrab 2024-05-26
|
||||
* Fix issue with #hotfix ([#4316](https://github.com/EQEmu/Server/pull/4316)) @Kinglykrab 2024-05-22
|
||||
* Fix issue with #suspend ([#4314](https://github.com/EQEmu/Server/pull/4314)) @Kinglykrab 2024-05-23
|
||||
* Fix issue with KeepOneRecordPerCompletedTask ([#4313](https://github.com/EQEmu/Server/pull/4313)) @Kinglykrab 2024-05-23
|
||||
* Fix mistaken removed RULE_CATEGORY_END() ([#4341](https://github.com/EQEmu/Server/pull/4341)) @fryguy503 2024-05-26
|
||||
* Missed a mob offense section for PR #4328 ([#4331](https://github.com/EQEmu/Server/pull/4331)) @fryguy503 2024-05-26
|
||||
* Raid Targets should not be Blindable as this will break all spell casting AI. ([#4334](https://github.com/EQEmu/Server/pull/4334)) @fryguy503 2024-05-26
|
||||
* When Mounts are allowed to zone, block them from zoning to disallowed zones. ([#4330](https://github.com/EQEmu/Server/pull/4330)) @fryguy503 2024-05-25
|
||||
* When refreshing buffs, attempt to use the same buffslot if the buff still exists. ([#4338](https://github.com/EQEmu/Server/pull/4338)) @fryguy503 2024-05-26
|
||||
|
||||
### Lua Mod
|
||||
|
||||
* Fix issue with SetAAEXP and SetEXP firing when uninitialized ([#4345](https://github.com/EQEmu/Server/pull/4345)) @Akkadius 2024-05-26
|
||||
|
||||
### Merchants
|
||||
|
||||
* Add New Classic Greed/Faction/Charisma Prices Rule ([#4301](https://github.com/EQEmu/Server/pull/4301)) @noudess 2024-05-17
|
||||
|
||||
### Mobs
|
||||
|
||||
* Remove entity type checks from ScanCloseMobs ([#4323](https://github.com/EQEmu/Server/pull/4323)) @Akkadius 2024-05-25
|
||||
|
||||
### NPC Spells
|
||||
|
||||
* Fix an issue where procs wouldn't fire if no spell entries in list ([#4344](https://github.com/EQEmu/Server/pull/4344)) @Akkadius 2024-05-26
|
||||
|
||||
### Perl
|
||||
|
||||
* Linux /opt/eqemu-perl checks when using release binaries ([#4346](https://github.com/EQEmu/Server/pull/4346)) @Akkadius 2024-05-26
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Zone Uptime Exports to Perl/Lua ([#4339](https://github.com/EQEmu/Server/pull/4339)) @Kinglykrab 2024-05-26
|
||||
|
||||
### Rules
|
||||
|
||||
* Added MeleeMitigation Level Difference Roll Adjusted for level diffs ([#4332](https://github.com/EQEmu/Server/pull/4332)) @fryguy503 2024-05-26
|
||||
* Allow maximum per kill AA amount ([#4329](https://github.com/EQEmu/Server/pull/4329)) @fryguy503 2024-05-25
|
||||
* Allow servers to adjust the filtering threshold for heals from damage (e.g. Mark of Kings). ([#4327](https://github.com/EQEmu/Server/pull/4327)) @fryguy503 2024-05-25
|
||||
* Backstab Haste Correction ([#4337](https://github.com/EQEmu/Server/pull/4337)) @fryguy503 2024-05-26
|
||||
* Mob Offensive and Weapon Skill static tables ([#4328](https://github.com/EQEmu/Server/pull/4328)) @fryguy503 2024-05-25
|
||||
* Remove hard coded initial aggro in favor or an adjustable Rule ([#4333](https://github.com/EQEmu/Server/pull/4333)) @fryguy503 2024-05-26
|
||||
|
||||
### Scripts
|
||||
|
||||
* Fix zone data load ordering issue ([#4343](https://github.com/EQEmu/Server/pull/4343)) @Akkadius 2024-05-26
|
||||
|
||||
### Spells
|
||||
|
||||
* Add content filtering to NPC spells ([#4309](https://github.com/EQEmu/Server/pull/4309)) @Akkadius 2024-05-17
|
||||
|
||||
## [22.50.1] 5/12/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Clear GuildOnlineStatus on world boot ([#4306](https://github.com/EQEmu/Server/pull/4306)) @neckkola 2024-05-12
|
||||
|
||||
## [22.50.0] 5/9/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Fix Message in #find task ([#4270](https://github.com/EQEmu/Server/pull/4270)) @Kinglykrab 2024-04-19
|
||||
|
||||
### Combat
|
||||
|
||||
* Add rule to set stun duration. Add rule to add stun messages. ([#4284](https://github.com/EQEmu/Server/pull/4284)) @noudess 2024-04-25
|
||||
|
||||
### Commands
|
||||
|
||||
* Adjust #kill and #list Commands ([#4271](https://github.com/EQEmu/Server/pull/4271)) @Kinglykrab 2024-05-04
|
||||
|
||||
### Compiling
|
||||
|
||||
* Add profiler flag ([#4293](https://github.com/EQEmu/Server/pull/4293)) @xackery 2024-05-04
|
||||
|
||||
### Corpses
|
||||
|
||||
* Corpse searches for items did not search augs ([#4289](https://github.com/EQEmu/Server/pull/4289)) @noudess 2024-04-27
|
||||
|
||||
### Database
|
||||
|
||||
* Add Extra Haste to Bots/Character Tables ([#4286](https://github.com/EQEmu/Server/pull/4286)) @Kinglykrab 2024-05-04
|
||||
* Break out changes to `npc_types` from parcels ([#4295](https://github.com/EQEmu/Server/pull/4295)) @joligario 2024-05-03
|
||||
* Move pets query to content database ([#4296](https://github.com/EQEmu/Server/pull/4296)) @joligario 2024-05-04
|
||||
|
||||
### Doors
|
||||
|
||||
* Replace magic # in code with a field in doors table for when door closes. ([#4288](https://github.com/EQEmu/Server/pull/4288)) @noudess 2024-04-25
|
||||
|
||||
### Experience
|
||||
|
||||
* Add SetExp/SetAAExp lua mods ([#4292](https://github.com/EQEmu/Server/pull/4292)) @xackery 2024-05-04
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Augmentation Support for Parcels ([#4285](https://github.com/EQEmu/Server/pull/4285)) @neckkola 2024-04-24
|
||||
* Add Character Auto Login ([#4216](https://github.com/EQEmu/Server/pull/4216)) @Kinglykrab 2024-04-15
|
||||
* Add Parcel Feature for RoF2 Clients ([#4198](https://github.com/EQEmu/Server/pull/4198)) @neckkola 2024-04-21
|
||||
* Add `is_parcel_merchant` to #npcedit ([#4290](https://github.com/EQEmu/Server/pull/4290)) @Kinglykrab 2024-05-04
|
||||
* Add devcontainer support ([#4294](https://github.com/EQEmu/Server/pull/4294)) @xackery 2024-05-09
|
||||
* Fix ignore_default on lua mod damage ([#4228](https://github.com/EQEmu/Server/pull/4228)) @xackery 2024-04-15
|
||||
|
||||
### Fixes
|
||||
|
||||
* "GM flag" vs "GM Flag" @Akkadius 2024-05-04
|
||||
* All NPC classes could stun with kick/only warriors could be stunned ([#4273](https://github.com/EQEmu/Server/pull/4273)) @noudess 2024-04-24
|
||||
* Fix Account Flags Loading ([#4243](https://github.com/EQEmu/Server/pull/4243)) @Kinglykrab 2024-04-15
|
||||
* Fix Corpses "Disappearing" ([#4275](https://github.com/EQEmu/Server/pull/4275)) @joligario 2024-04-21
|
||||
* Fix Issue With Auto Login ([#4267](https://github.com/EQEmu/Server/pull/4267)) @Kinglykrab 2024-04-21
|
||||
* Fix crash from #4266 @Akkadius 2024-05-05
|
||||
* Fixes Issue 4257 - Double Taunt Message ([#4258](https://github.com/EQEmu/Server/pull/4258)) @fryguy503 2024-04-18
|
||||
* GLAA fix after database.cpp updates ([#4277](https://github.com/EQEmu/Server/pull/4277)) @neckkola 2024-04-21
|
||||
* GetSkill default return 0 @Akkadius 2024-05-05
|
||||
* Hero forge armor bug on login and show helm toggle. ([#4246](https://github.com/EQEmu/Server/pull/4246)) @noudess 2024-04-15
|
||||
* Perl__send_parcel GCC compile error @Akkadius 2024-05-05
|
||||
* Remove food or water GM message @Akkadius 2024-05-05
|
||||
* Revert GetSkill from #4234 @Akkadius 2024-05-05
|
||||
* Fix for world crash with over 1500 guilds ([#4299](https://github.com/EQEmu/Server/pull/4299)) @neckkola 2024-05-09
|
||||
|
||||
### Hot Fix
|
||||
|
||||
* Update database_update_manifest.cpp ([#4291](https://github.com/EQEmu/Server/pull/4291)) @noudess 2024-04-29
|
||||
|
||||
### Loot
|
||||
|
||||
* Add content filtering to lootdrop_entries ([#4229](https://github.com/EQEmu/Server/pull/4229)) @Akkadius 2024-04-15
|
||||
* Consolidate filtering logic ([#4280](https://github.com/EQEmu/Server/pull/4280)) @Akkadius 2024-04-21
|
||||
|
||||
### Lua
|
||||
|
||||
* Add IsImmuneToSpell Lua Mod ([#4278](https://github.com/EQEmu/Server/pull/4278)) @xackery 2024-04-28
|
||||
* Add UpdatePersonalFaction Lua Mod ([#4279](https://github.com/EQEmu/Server/pull/4279)) @xackery 2024-05-04
|
||||
|
||||
### Messages
|
||||
|
||||
* Add GM Status and Invulnerability Messages ([#4266](https://github.com/EQEmu/Server/pull/4266)) @Kinglykrab 2024-05-04
|
||||
* Fix bug where DoT messages stop coming out when mob dies. ([#4249](https://github.com/EQEmu/Server/pull/4249)) @noudess 2024-04-15
|
||||
* Fix multiple errors in spell damage at death. ([#4264](https://github.com/EQEmu/Server/pull/4264)) @noudess 2024-04-28
|
||||
|
||||
### Performance
|
||||
|
||||
* Change skill_cap from vector to map ([#4252](https://github.com/EQEmu/Server/pull/4252)) @xackery 2024-04-15
|
||||
|
||||
### Pets
|
||||
|
||||
* Fix errors in sync with client of sit/stand ([#4245](https://github.com/EQEmu/Server/pull/4245)) @noudess 2024-04-15
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add DescribeSpecialAbilities() to Perl/Lua ([#4269](https://github.com/EQEmu/Server/pull/4269)) @Kinglykrab 2024-04-21
|
||||
* Add GetConsiderColor() to Perl/Lua ([#4253](https://github.com/EQEmu/Server/pull/4253)) @Kinglykrab 2024-04-15
|
||||
* Add Parcel Sending to Perl/Lua ([#4287](https://github.com/EQEmu/Server/pull/4287)) @Kinglykrab 2024-05-04
|
||||
* Add Zone Methods to Perl/Lua ([#4268](https://github.com/EQEmu/Server/pull/4268)) @Kinglykrab 2024-04-21
|
||||
|
||||
### Quests
|
||||
|
||||
* Hot Reload Changes ([#4302](https://github.com/EQEmu/Server/pull/4302)) @Akkadius 2024-05-09
|
||||
* Reload Quests on Bootup, Init earlier ([#4298](https://github.com/EQEmu/Server/pull/4298)) @Akkadius 2024-05-05
|
||||
|
||||
### Spells
|
||||
|
||||
* Implemented SPA 122 SE_ReduceSkill ([#4234](https://github.com/EQEmu/Server/pull/4234)) @KayenEQ 2024-05-04
|
||||
* Normal Group Spells (non-raid) landed twice on caster ([#4240](https://github.com/EQEmu/Server/pull/4240)) @noudess 2024-04-15
|
||||
* SPA69 TotalHP can be used in Worn Slot, Fixes/Updates to Max HP related variables. ([#4244](https://github.com/EQEmu/Server/pull/4244)) @KayenEQ 2024-04-15
|
||||
|
||||
### Zone Instances
|
||||
|
||||
* Handle routing to instances when using evac/succor ([#4297](https://github.com/EQEmu/Server/pull/4297)) @joligario 2024-05-04
|
||||
|
||||
## [22.49.1] 4/15/2024
|
||||
|
||||
### Zoning
|
||||
|
||||
* Fix zone routing edge case ([#4255](https://github.com/EQEmu/Server/pull/4255)) @Akkadius 2024-04-15
|
||||
|
||||
## [22.49.0] 4/15/2024
|
||||
|
||||
### Code
|
||||
|
||||
* Avoid unnecessary copies in database functions ([#4220](https://github.com/EQEmu/Server/pull/4220)) @joligario 2024-03-29
|
||||
* Reference type in `GetRaidLeaderName` ([#4218](https://github.com/EQEmu/Server/pull/4218)) @joligario 2024-03-28
|
||||
* Remove unnecessary reference types ([#4212](https://github.com/EQEmu/Server/pull/4212)) @joligario 2024-03-28
|
||||
|
||||
### Crash
|
||||
|
||||
* Check mob pointer before trying to remove it ([#4230](https://github.com/EQEmu/Server/pull/4230)) @Akkadius 2024-04-01
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Character Auto Login ([#4216](https://github.com/EQEmu/Server/pull/4216)) @Kinglykrab 2024-04-15
|
||||
* Add LuaMod functions for CommonDamage and HealDamage ([#4227](https://github.com/EQEmu/Server/pull/4227)) @xackery 2024-03-31
|
||||
* Add RegisterBug LuaMod ([#4209](https://github.com/EQEmu/Server/pull/4209)) @xackery 2024-03-30
|
||||
* Additive Spell Focus from Worn slot with Limit Checks ([#4208](https://github.com/EQEmu/Server/pull/4208)) @KayenEQ 2024-03-30
|
||||
* Fix ignore_default on lua mod damage ([#4228](https://github.com/EQEmu/Server/pull/4228)) @xackery 2024-04-15
|
||||
|
||||
### Fixes
|
||||
|
||||
* Client not updating HP bar when an HP Buff with a Heal is applied. ([#4237](https://github.com/EQEmu/Server/pull/4237)) @KayenEQ 2024-04-02
|
||||
* Fix Account Flags Loading ([#4243](https://github.com/EQEmu/Server/pull/4243)) @Kinglykrab 2024-04-15
|
||||
* Fix Auto Login Issue ([#4213](https://github.com/EQEmu/Server/pull/4213)) @Kinglykrab 2024-03-28
|
||||
* Fix Bot Creation Issue ([#4235](https://github.com/EQEmu/Server/pull/4235)) @Kinglykrab 2024-04-02
|
||||
* Fix Bot/Character ID Overlap in Groups ([#4093](https://github.com/EQEmu/Server/pull/4093)) @Kinglykrab 2024-03-23
|
||||
* Fix Group Leadership ([#4214](https://github.com/EQEmu/Server/pull/4214)) @Kinglykrab 2024-03-28
|
||||
* Fix Issue With Bot Raid Aggro ([#4222](https://github.com/EQEmu/Server/pull/4222)) @Kinglykrab 2024-03-31
|
||||
* Fix Lua Crash with Spell Blocked Event ([#4236](https://github.com/EQEmu/Server/pull/4236)) @Kinglykrab 2024-04-01
|
||||
* Fix Luabind Double Class Register ([#4219](https://github.com/EQEmu/Server/pull/4219)) @Kinglykrab 2024-03-29
|
||||
* Fix crash in SendEnterWorld ([#4204](https://github.com/EQEmu/Server/pull/4204)) @Akkadius 2024-03-24
|
||||
* Fix event_consider any_cast error ([#4210](https://github.com/EQEmu/Server/pull/4210)) @xackery 2024-03-27
|
||||
* Fix fishing chances ([#4203](https://github.com/EQEmu/Server/pull/4203)) @joligario 2024-03-24
|
||||
* Fix manifest for skill caps schema type ([#4231](https://github.com/EQEmu/Server/pull/4231)) @Akkadius 2024-04-02
|
||||
* Hero forge armor bug on login and show helm toggle. ([#4246](https://github.com/EQEmu/Server/pull/4246)) @noudess 2024-04-15
|
||||
* Radiant/Ebon Crystals should only extract to 1000 ([#4195](https://github.com/EQEmu/Server/pull/4195)) @fryguy503 2024-03-23
|
||||
* SPA214 SE_MaxHPChange calculation errors corrected. ([#4238](https://github.com/EQEmu/Server/pull/4238)) @KayenEQ 2024-04-02
|
||||
* Shared Tasks - charid is now character_id ([#4233](https://github.com/EQEmu/Server/pull/4233)) @fryguy503 2024-04-01
|
||||
* Using %T in channel messages on fresh corpse yields mob, not corpse name. ([#4168](https://github.com/EQEmu/Server/pull/4168)) @noudess 2024-04-05
|
||||
|
||||
### Hot Fix
|
||||
|
||||
* Fix Group::AddToGroup ([#4201](https://github.com/EQEmu/Server/pull/4201)) @Kinglykrab 2024-03-23
|
||||
* Hot Fix for Group::AddToGroup Hot Fix ([#4202](https://github.com/EQEmu/Server/pull/4202)) @Kinglykrab 2024-03-23
|
||||
|
||||
### Loot
|
||||
|
||||
* Add content filtering to lootdrop_entries ([#4229](https://github.com/EQEmu/Server/pull/4229)) @Akkadius 2024-04-15
|
||||
|
||||
### Lua
|
||||
|
||||
* Add Zone and Language Constants ([#4211](https://github.com/EQEmu/Server/pull/4211)) @fryguy503 2024-03-28
|
||||
|
||||
### Messages
|
||||
|
||||
* Fix bug where DoT messages stop coming out when mob dies. ([#4249](https://github.com/EQEmu/Server/pull/4249)) @noudess 2024-04-15
|
||||
|
||||
### Performance
|
||||
|
||||
* Change skill_cap from vector to map ([#4252](https://github.com/EQEmu/Server/pull/4252)) @xackery 2024-04-15
|
||||
|
||||
### Pets
|
||||
|
||||
* Fix errors in sync with client of sit/stand ([#4245](https://github.com/EQEmu/Server/pull/4245)) @noudess 2024-04-15
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Archetype Methods to Perl/Lua ([#4181](https://github.com/EQEmu/Server/pull/4181)) @Kinglykrab 2024-03-23
|
||||
* Add Class/Deity/Race Methods to Perl/Lua ([#4215](https://github.com/EQEmu/Server/pull/4215)) @Kinglykrab 2024-03-28
|
||||
* Add GetConsiderColor() to Perl/Lua ([#4253](https://github.com/EQEmu/Server/pull/4253)) @Kinglykrab 2024-04-15
|
||||
* Add Spell Blocked Event to Perl/Lua ([#4217](https://github.com/EQEmu/Server/pull/4217)) @Kinglykrab 2024-04-01
|
||||
|
||||
### Quests
|
||||
|
||||
* Avoid Player and Bot quests in unloaded zone ([#4232](https://github.com/EQEmu/Server/pull/4232)) @hgtw 2024-04-01
|
||||
|
||||
### Repositories
|
||||
|
||||
* Convert database.cpp to Repositories ([#4054](https://github.com/EQEmu/Server/pull/4054)) @Kinglykrab 2024-03-24
|
||||
|
||||
### Skill Caps
|
||||
|
||||
* Further improvements ([#4205](https://github.com/EQEmu/Server/pull/4205)) @Akkadius 2024-03-24
|
||||
* Remove from shared memory and simplify ([#4069](https://github.com/EQEmu/Server/pull/4069)) @Kinglykrab 2024-03-23
|
||||
|
||||
### Spells
|
||||
|
||||
* Implemented SPA 463 SE_SHIELD_TARGET ([#4224](https://github.com/EQEmu/Server/pull/4224)) @KayenEQ 2024-03-30
|
||||
* Normal Group Spells (non-raid) landed twice on caster ([#4240](https://github.com/EQEmu/Server/pull/4240)) @noudess 2024-04-15
|
||||
* SPA148 Stacking Fix ([#4206](https://github.com/EQEmu/Server/pull/4206)) @KayenEQ 2024-03-27
|
||||
* SPA69 TotalHP can be used in Worn Slot, Fixes/Updates to Max HP related variables. ([#4244](https://github.com/EQEmu/Server/pull/4244)) @KayenEQ 2024-04-15
|
||||
|
||||
## [22.48.0] 3/23/2024
|
||||
|
||||
### Bots
|
||||
|
||||
* IsValidTarget Crash Fix ([#4187](https://github.com/EQEmu/Server/pull/4187)) @nytmyr 2024-03-12
|
||||
* Move BotGroupSay to Pet Response ([#4171](https://github.com/EQEmu/Server/pull/4171)) @nytmyr 2024-03-08
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup Zone Get Methods ([#4169](https://github.com/EQEmu/Server/pull/4169)) @Kinglykrab 2024-03-09
|
||||
|
||||
### Fixes
|
||||
|
||||
* An Update to Xtarget to exclude Bot owned Temp/Swarm Pets ([#4172](https://github.com/EQEmu/Server/pull/4172)) @MortimerGreenwald 2024-03-08
|
||||
* Fix #serverrules Command ([#4193](https://github.com/EQEmu/Server/pull/4193)) @Kinglykrab 2024-03-20
|
||||
* Fix Bot Cloning ([#4186](https://github.com/EQEmu/Server/pull/4186)) @Kinglykrab 2024-03-17
|
||||
* Fix Crash in ClientList::GetCLEIP ([#4173](https://github.com/EQEmu/Server/pull/4173)) @Kinglykrab 2024-03-10
|
||||
* Fix Default Value in `rule_values` table ([#4166](https://github.com/EQEmu/Server/pull/4166)) @Kinglykrab 2024-03-07
|
||||
* Fix EVENT_KILLED_MERIT firing before NPC removal ([#4185](https://github.com/EQEmu/Server/pull/4185)) @Kinglykrab 2024-03-17
|
||||
* Fix Empty Groups When Removing Bots ([#4178](https://github.com/EQEmu/Server/pull/4178)) @Kinglykrab 2024-03-14
|
||||
* Fix GetLeaderName() for Groups ([#4184](https://github.com/EQEmu/Server/pull/4184)) @Kinglykrab 2024-03-14
|
||||
* Fix Mob::CalculateDistance(mob) Typo ([#4183](https://github.com/EQEmu/Server/pull/4183)) @Kinglykrab 2024-03-10
|
||||
* Fix Proximity Say ([#4189](https://github.com/EQEmu/Server/pull/4189)) @Kinglykrab 2024-03-15
|
||||
* Fix ScaleNPC() in Perl ([#4196](https://github.com/EQEmu/Server/pull/4196)) @Kinglykrab 2024-03-23
|
||||
* Fix range_percent ([#4197](https://github.com/EQEmu/Server/pull/4197)) @Kinglykrab 2024-03-22
|
||||
* Fix reusing timers ([#4199](https://github.com/EQEmu/Server/pull/4199)) @joligario 2024-03-23
|
||||
|
||||
### Hot Fix
|
||||
|
||||
* Add bool return to fix Client::RemoveAAPoints ([#4176](https://github.com/EQEmu/Server/pull/4176)) @Kinglykrab 2024-03-09
|
||||
|
||||
### Loot
|
||||
|
||||
* Fix issue with nested data being loaded multiple times ([#4192](https://github.com/EQEmu/Server/pull/4192)) @Akkadius 2024-03-23
|
||||
|
||||
### Misc
|
||||
|
||||
* Windows preprocessor define in crash.cpp ([#4191](https://github.com/EQEmu/Server/pull/4191)) @joligario 2024-03-23
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Buff Support to Perl/Lua ([#4182](https://github.com/EQEmu/Server/pull/4182)) @Kinglykrab 2024-03-14
|
||||
* Add DeleteBot() to Perl/Lua ([#4167](https://github.com/EQEmu/Server/pull/4167)) @nytmyr 2024-03-07
|
||||
* Add GetDeityName() to Perl/Lua ([#4180](https://github.com/EQEmu/Server/pull/4180)) @Kinglykrab 2024-03-14
|
||||
* Add RemoveAAPoints() and AA Loss Event to Perl/Lua ([#4174](https://github.com/EQEmu/Server/pull/4174)) @Kinglykrab 2024-03-09
|
||||
* Add RemoveAlternateCurrencyValue() to Perl/Lua ([#4190](https://github.com/EQEmu/Server/pull/4190)) @Kinglykrab 2024-03-17
|
||||
* Add Restore Methods for Health, Mana, and Endurance to Perl/Lua ([#4179](https://github.com/EQEmu/Server/pull/4179)) @Kinglykrab 2024-03-23
|
||||
* Add Silent Saylink Methods to Perl/Lua ([#4177](https://github.com/EQEmu/Server/pull/4177)) @Kinglykrab 2024-03-14
|
||||
|
||||
### Rules
|
||||
|
||||
* Add World:Rules Rule ([#4194](https://github.com/EQEmu/Server/pull/4194)) @Kinglykrab 2024-03-23
|
||||
|
||||
### Tradeskills
|
||||
|
||||
* Implement learning recipes from books ([#4170](https://github.com/EQEmu/Server/pull/4170)) @hgtw 2024-03-23
|
||||
|
||||
## [22.47.0] 3/5/2024
|
||||
|
||||
### Crash Fix
|
||||
|
||||
* Added a guild_mgr check ([#4163](https://github.com/EQEmu/Server/pull/4163)) @neckkola 2024-03-06
|
||||
* Goto Command could crash using Developer Tools ([#4158](https://github.com/EQEmu/Server/pull/4158)) @neckkola 2024-03-04
|
||||
* Groundspawn Memory Corruption ([#4157](https://github.com/EQEmu/Server/pull/4157)) @neckkola 2024-03-04
|
||||
* Update to location of qGlobals initialization ([#4144](https://github.com/EQEmu/Server/pull/4144)) @neckkola 2024-03-02
|
||||
|
||||
### Feature
|
||||
|
||||
* Adds rules to control level requirements for Double Backstab, Assassinate, and Double Bowshot (#4159) ([#29](https://github.com/EQEmu/Server/pull/29)) @catapultam-habeo 2024-03-04
|
||||
* Adjust String-based Rules Length ([#4138](https://github.com/EQEmu/Server/pull/4138)) @Kinglykrab 2024-03-06
|
||||
* Exempt a zone from IP-limit checks. ([#4137](https://github.com/EQEmu/Server/pull/4137)) @catapultam-habeo 2024-03-02
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add id to the guild_bank table ([#4155](https://github.com/EQEmu/Server/pull/4155)) @neckkola 2024-03-05
|
||||
* Fix Bots/Bot Pets ending up on XTargets ([#4132](https://github.com/EQEmu/Server/pull/4132)) @Kinglykrab 2024-03-02
|
||||
* Fix Character EXP Modifiers default ([#4161](https://github.com/EQEmu/Server/pull/4161)) @Kinglykrab 2024-03-06
|
||||
* Fix Spawns Not Parsing Quest on Zone Bootup ([#4149](https://github.com/EQEmu/Server/pull/4149)) @Kinglykrab 2024-03-05
|
||||
* Fix typo when updating spawn events in spawn condition manager ([#4160](https://github.com/EQEmu/Server/pull/4160)) @joligario 2024-03-05
|
||||
* GetBotNameByID Temporary Reference Warning ([#4145](https://github.com/EQEmu/Server/pull/4145)) @Kinglykrab 2024-03-02
|
||||
* Prevent NPE when creating DZ using ad-hoc version IDs ([#4141](https://github.com/EQEmu/Server/pull/4141)) @catapultam-habeo 2024-03-05
|
||||
* Update FreeGuildID Routine ([#4143](https://github.com/EQEmu/Server/pull/4143)) @neckkola 2024-03-02
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Bot Special Attacks for Immune Aggro/Damage ([#4108](https://github.com/EQEmu/Server/pull/4108)) @Kinglykrab 2024-03-02
|
||||
* Add GetHeroicStrikethrough() to Perl/Lua ([#4150](https://github.com/EQEmu/Server/pull/4150)) @Kinglykrab 2024-03-03
|
||||
* Add IsAlwaysAggro() to Perl/Lua ([#4152](https://github.com/EQEmu/Server/pull/4152)) @Kinglykrab 2024-03-04
|
||||
* Add IsBoat()/IsControllableBoat() to Perl/Lua ([#4151](https://github.com/EQEmu/Server/pull/4151)) @Kinglykrab 2024-03-03
|
||||
* Add IsDestructibleObject() to Perl/Lua ([#4153](https://github.com/EQEmu/Server/pull/4153)) @Kinglykrab 2024-03-03
|
||||
|
||||
### Zone
|
||||
|
||||
* Zone Routing Improvements ([#4142](https://github.com/EQEmu/Server/pull/4142)) @Akkadius 2024-03-02
|
||||
|
||||
### Zoning
|
||||
|
||||
* Zone routing adjustment ([#4162](https://github.com/EQEmu/Server/pull/4162)) @Akkadius 2024-03-06
|
||||
|
||||
## [22.46.1] 3/2/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Change `UnburyCorpse` to use repository methods ([#4147](https://github.com/EQEmu/Server/pull/4147)) @joligario 2024-03-03
|
||||
|
||||
## [22.46.0] 3/2/2024
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #fish Command ([#4136](https://github.com/EQEmu/Server/pull/4136)) @Kinglykrab 2024-03-01
|
||||
|
||||
### Crash Fix
|
||||
|
||||
* Raid::UpdateGroupAAs ([#4139](https://github.com/EQEmu/Server/pull/4139)) @neckkola 2024-03-02
|
||||
* Update to location of qGlobals initialization ([#4144](https://github.com/EQEmu/Server/pull/4144)) @neckkola 2024-03-02
|
||||
|
||||
### Feature
|
||||
|
||||
* Exempt a zone from IP-limit checks. ([#4137](https://github.com/EQEmu/Server/pull/4137)) @catapultam-habeo 2024-03-02
|
||||
|
||||
### Fixes
|
||||
|
||||
* Cleanup NPC Mana Tap Logic ([#4134](https://github.com/EQEmu/Server/pull/4134)) @noudess 2024-03-02
|
||||
* Fix Bots/Bot Pets ending up on XTargets ([#4132](https://github.com/EQEmu/Server/pull/4132)) @Kinglykrab 2024-03-02
|
||||
* Fix issue with NPC Secondary Textures ([#4129](https://github.com/EQEmu/Server/pull/4129)) @Kinglykrab 2024-03-01
|
||||
* GetBotNameByID Temporary Reference Warning ([#4145](https://github.com/EQEmu/Server/pull/4145)) @Kinglykrab 2024-03-02
|
||||
* Update FreeGuildID Routine ([#4143](https://github.com/EQEmu/Server/pull/4143)) @neckkola 2024-03-02
|
||||
* Use std::clamp for Mob::ChangeSize ([#4140](https://github.com/EQEmu/Server/pull/4140)) @joligario 2024-03-02
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Bot Special Attacks for Immune Aggro/Damage ([#4108](https://github.com/EQEmu/Server/pull/4108)) @Kinglykrab 2024-03-02
|
||||
|
||||
### Zone
|
||||
|
||||
* Zone Routing Improvements ([#4142](https://github.com/EQEmu/Server/pull/4142)) @Akkadius 2024-03-02
|
||||
|
||||
## [22.45.1] 2/29/2024
|
||||
|
||||
### Character Creation
|
||||
|
||||
* Improved Random Name Generator ([#4081](https://github.com/EQEmu/Server/pull/4081)) @catapultam-habeo 2024-02-27
|
||||
|
||||
### Code
|
||||
|
||||
* Fix Server Rules Documentation Generation ([#4125](https://github.com/EQEmu/Server/pull/4125)) @Kinglykrab 2024-02-26
|
||||
* Remove unnecessary stoptimer logs ([#4128](https://github.com/EQEmu/Server/pull/4128)) @Kinglykrab 2024-02-28
|
||||
|
||||
### Commands
|
||||
|
||||
* Add `#forage` command ([#4133](https://github.com/EQEmu/Server/pull/4133)) @joligario 2024-02-29
|
||||
|
||||
### Crash
|
||||
|
||||
* Fix crash issue during database dump ([#4127](https://github.com/EQEmu/Server/pull/4127)) @Akkadius 2024-02-29
|
||||
|
||||
### Crash Fix
|
||||
|
||||
* D20 crash if mitigation average resulted in 0 ([#4131](https://github.com/EQEmu/Server/pull/4131)) @nytmyr 2024-02-29
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix forage returning first result from table ([#4130](https://github.com/EQEmu/Server/pull/4130)) @nytmyr 2024-02-29
|
||||
* Who /all displays incorrect guild name ([#4123](https://github.com/EQEmu/Server/pull/4123)) @neckkola 2024-02-25
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add Pet Owner Methods to Perl/Lua ([#4115](https://github.com/EQEmu/Server/pull/4115)) @Kinglykrab 2024-02-25
|
||||
|
||||
## [22.45.0] 2/24/2024
|
||||
|
||||
### Beacon
|
||||
@@ -1763,7 +903,7 @@
|
||||
|
||||
### EQTime
|
||||
|
||||
Hotfix for world not spamming save messages by setting to detail level logging @Akkadius 2023-11-20
|
||||
Hotfix for world not spamming save messages by setting to detail level logging @Akkadius 2023-11-20
|
||||
|
||||
## [22.34.0] - 11/19/2023
|
||||
|
||||
@@ -2845,7 +1985,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Telnet encoding fix ([#3269](https://github.com/EQEmu/Server/pull/3269)) @Akkadius 2023-04-05
|
||||
|
||||
## [22.9.1] - 04/03/2023
|
||||
## [22.9.1] - 04/03/2023
|
||||
|
||||
### Code
|
||||
|
||||
@@ -2890,7 +2030,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Change to use Pass by reference where valid. ([#3163](https://github.com/EQEmu/Server/pull/3163)) @Aeadoin 2023-04-02
|
||||
|
||||
## [22.9.0] - 04/01/2023
|
||||
## [22.9.0] - 04/01/2023
|
||||
|
||||
### Bots
|
||||
|
||||
@@ -2914,7 +2054,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Add missing Luabind definitions to lua_general.cpp ([#3167](https://github.com/EQEmu/Server/pull/3167)) @Kinglykrab 2023-04-01
|
||||
|
||||
## [22.8.2] - 03/30/2023
|
||||
## [22.8.2] - 03/30/2023
|
||||
|
||||
### Code
|
||||
|
||||
@@ -2938,13 +2078,13 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Remove Guild Bank Zone ID Rule ([#3156](https://github.com/EQEmu/Server/pull/3156)) @Kinglykrab 2023-03-29
|
||||
|
||||
## [22.8.1] - 03/27/2023
|
||||
## [22.8.1] - 03/27/2023
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix for NPCs having spells interrupted. ([#3150](https://github.com/EQEmu/Server/pull/3150)) @Aeadoin 2023-03-27
|
||||
|
||||
## [22.8.0] - 03/25/2023
|
||||
## [22.8.0] - 03/25/2023
|
||||
|
||||
### Code
|
||||
|
||||
@@ -2964,7 +2104,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
* Fix for Items looted from corpses. ([#3147](https://github.com/EQEmu/Server/pull/3147)) @Aeadoin 2023-03-26
|
||||
* Fix for SQL Query in npc_scale_global_base ([#3144](https://github.com/EQEmu/Server/pull/3144)) @Aeadoin 2023-03-26
|
||||
|
||||
## [22.7.0] - 03/24/2023
|
||||
## [22.7.0] - 03/24/2023
|
||||
|
||||
### Bots
|
||||
|
||||
@@ -3121,7 +2261,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
* Add exception handling to converters themselves ([#3029](https://github.com/EQEmu/Server/pull/3029)) @Akkadius 2023-03-05
|
||||
* Add more number formatters ([#2873](https://github.com/EQEmu/Server/pull/2873)) @Kinglykrab 2023-03-04
|
||||
|
||||
## [22.4.5] - 03/03/2023
|
||||
## [22.4.5] - 03/03/2023
|
||||
|
||||
### Bots
|
||||
|
||||
@@ -3163,7 +2303,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
* Add IsFindable() and IsTrackable() to Perl/Lua ([#2996](https://github.com/EQEmu/Server/pull/2996)) @Kinglykrab 2023-03-01
|
||||
* Add IsUnderwaterOnly() to Perl/Lua ([#2995](https://github.com/EQEmu/Server/pull/2995)) @Kinglykrab 2023-03-01
|
||||
|
||||
## [22.4.4] - 02/24/2023
|
||||
## [22.4.4] - 02/24/2023
|
||||
|
||||
### Bots
|
||||
|
||||
@@ -3210,7 +2350,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Fix for Lore Conflict ([#2977](https://github.com/EQEmu/Server/pull/2977)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-24
|
||||
|
||||
## [22.4.3] - 02/21/2023
|
||||
## [22.4.3] - 02/21/2023
|
||||
|
||||
### Bots
|
||||
|
||||
@@ -3257,7 +2397,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Add date to optional Drakkin Guktan Faction Update ([#2965](https://github.com/EQEmu/Server/pull/2965)) ([joligario](https://github.com/joligario)) 2023-02-19
|
||||
|
||||
## [22.4.2] - 02/18/2023
|
||||
## [22.4.2] - 02/18/2023
|
||||
|
||||
### Content
|
||||
|
||||
@@ -3279,7 +2419,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
|
||||
* Fix regression caused by #2932 ([#2956](https://github.com/EQEmu/Server/pull/2956)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
||||
|
||||
## [22.4.1] - 02/17/2023
|
||||
## [22.4.1] - 02/17/2023
|
||||
|
||||
### Bots
|
||||
|
||||
@@ -3300,7 +2440,7 @@ Revert Perl regression in #3648 causing scripts to not reliably initialize on zo
|
||||
* Fix rare out of bound issue when loading event types ([#2946](https://github.com/EQEmu/Server/pull/2946)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
* Turn off KILLED_NPC (trash) off by default ([#2948](https://github.com/EQEmu/Server/pull/2948)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
||||
|
||||
## [22.4.0] - 02/17/2023
|
||||
## [22.4.0] - 02/17/2023
|
||||
|
||||
### Bots
|
||||
|
||||
|
||||
@@ -31,13 +31,6 @@ IF (EQEMU_BUILD_STATIC)
|
||||
ENDIF ()
|
||||
ENDIF (EQEMU_BUILD_STATIC)
|
||||
|
||||
|
||||
# Requires libgoogle-perftools-dev google-perftools packages for linux (debian)
|
||||
IF(EQEMU_ADD_PROFILER)
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--no-as-needed,-lprofiler,--as-needed")
|
||||
ENDIF(EQEMU_ADD_PROFILER)
|
||||
|
||||
|
||||
IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ADD_DEFINITIONS(-DNOMINMAX)
|
||||
|
||||
+153
-51
@@ -29,19 +29,11 @@
|
||||
#include "../../common/content/world_content_service.h"
|
||||
#include "../../common/zone_store.h"
|
||||
#include "../../common/path_manager.h"
|
||||
#include "../../common/repositories/base_data_repository.h"
|
||||
#include "../../common/repositories/db_str_repository.h"
|
||||
#include "../../common/repositories/skill_caps_repository.h"
|
||||
#include "../../common/repositories/spells_new_repository.h"
|
||||
#include "../../common/file.h"
|
||||
#include "../../common/events/player_event_logs.h"
|
||||
#include "../../common/skill_caps.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
PlayerEventLogs player_event_logs;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ExportSpells(SharedDatabase *db);
|
||||
void ExportSkillCaps(SharedDatabase *db);
|
||||
@@ -102,22 +94,25 @@ int main(int argc, char **argv)
|
||||
->LoadLogDatabaseSettings()
|
||||
->StartFileLogs();
|
||||
|
||||
std::string export_type;
|
||||
std::string arg_1;
|
||||
|
||||
if (argv[1]) {
|
||||
export_type = argv[1];
|
||||
arg_1 = argv[1];
|
||||
}
|
||||
|
||||
if (Strings::EqualFold(export_type, "spells")) {
|
||||
if (arg_1 == "spells") {
|
||||
ExportSpells(&content_db);
|
||||
return 0;
|
||||
} else if (Strings::EqualFold(export_type, "skills")) {
|
||||
}
|
||||
if (arg_1 == "skills") {
|
||||
ExportSkillCaps(&content_db);
|
||||
return 0;
|
||||
} else if (Strings::EqualFold(export_type, "basedata") || Strings::EqualFold(export_type, "base_data")) {
|
||||
}
|
||||
if (arg_1 == "basedata") {
|
||||
ExportBaseData(&content_db);
|
||||
return 0;
|
||||
} else if (Strings::EqualFold(export_type, "dbstr") || Strings::EqualFold(export_type, "dbstring")) {
|
||||
}
|
||||
if (arg_1 == "dbstring") {
|
||||
ExportDBStrings(&database);
|
||||
return 0;
|
||||
}
|
||||
@@ -132,79 +127,186 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExportSpells(SharedDatabase* db)
|
||||
void ExportSpells(SharedDatabase *db)
|
||||
{
|
||||
std::ofstream file(fmt::format("{}/export/spells_us.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogInfo("Exporting Spells");
|
||||
|
||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& lines = SpellsNewRepository::GetSpellFileLines(*db);
|
||||
const std::string query = "SELECT * FROM spells_new ORDER BY id";
|
||||
auto results = db->QueryDatabase(query);
|
||||
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
if (results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for (unsigned int i = 0; i < fields; ++i) {
|
||||
if (i != 0) {
|
||||
line.push_back('^');
|
||||
}
|
||||
|
||||
file << file_string;
|
||||
if (row[i] != nullptr) {
|
||||
line += row[i];
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
|
||||
LogInfo("Exported [{}] Spell{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase* db)
|
||||
bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
||||
{
|
||||
std::ofstream file(fmt::format("{}/export/SkillCaps.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
|
||||
bool res = false;
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT max(cap) FROM skill_caps WHERE class=%d AND skillID=%d",
|
||||
class_id, skill_id
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
||||
{
|
||||
|
||||
std::string query = StringFormat(
|
||||
"SELECT cap FROM skill_caps WHERE class=%d AND skillID=%d AND level=%d",
|
||||
class_id, skill_id, level
|
||||
);
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return Strings::ToInt(row[0]);
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db)
|
||||
{
|
||||
LogInfo("Exporting Skill Caps");
|
||||
|
||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& lines = SkillCapsRepository::GetSkillCapFileLines(*db);
|
||||
for (int cl = 1; cl <= 16; ++cl) {
|
||||
for (int skill = 0; skill <= 77; ++skill) {
|
||||
if (SkillUsable(db, skill, cl)) {
|
||||
int previous_cap = 0;
|
||||
for (int level = 1; level <= 100; ++level) {
|
||||
int cap = GetSkill(db, skill, cl, level);
|
||||
if (cap < previous_cap) {
|
||||
cap = previous_cap;
|
||||
}
|
||||
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
fprintf(f, "%d^%d^%d^%d^0\n", cl, skill, level, cap);
|
||||
previous_cap = cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file << file_string;
|
||||
|
||||
file.close();
|
||||
|
||||
LogInfo("Exported [{}] Skill Cap{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ExportBaseData(SharedDatabase *db)
|
||||
{
|
||||
std::ofstream file(fmt::format("{}/export/BaseData.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogInfo("Exporting Base Data");
|
||||
|
||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& lines = BaseDataRepository::GetBaseDataFileLines(*db);
|
||||
const std::string query = "SELECT * FROM base_data ORDER BY level, class";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for (unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||
if (rowIndex != 0) {
|
||||
line.push_back('^');
|
||||
}
|
||||
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
if (row[rowIndex] != nullptr) {
|
||||
line += row[rowIndex];
|
||||
}
|
||||
}
|
||||
|
||||
file << file_string;
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
LogInfo("Exported [{}] Base Data Entr{}", lines.size(), lines.size() != 1 ? "ies" : "y");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ExportDBStrings(SharedDatabase *db)
|
||||
{
|
||||
std::ofstream file(fmt::format("{}/export/dbstr_us.txt", path.GetServerPath()));
|
||||
if (!file || !file.is_open()) {
|
||||
LogInfo("Exporting DB Strings");
|
||||
|
||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
||||
FILE *f = fopen(file.c_str(), "w");
|
||||
if (!f) {
|
||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& lines = DbStrRepository::GetDBStrFileLines(*db);
|
||||
fprintf(f, "Major^Minor^String(New)\n");
|
||||
const std::string query = "SELECT * FROM db_str ORDER BY id, type";
|
||||
auto results = db->QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string line;
|
||||
unsigned int fields = results.ColumnCount();
|
||||
for (unsigned int rowIndex = 0; rowIndex < fields; ++rowIndex) {
|
||||
if (rowIndex != 0) {
|
||||
line.push_back('^');
|
||||
}
|
||||
|
||||
const std::string& file_string = Strings::Implode("\n", lines);
|
||||
if (row[rowIndex] != nullptr) {
|
||||
line += row[rowIndex];
|
||||
}
|
||||
}
|
||||
|
||||
file << file_string;
|
||||
fprintf(f, "%s\n", line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
LogInfo("Exported [{}] Database String{}", lines.size(), lines.size() != 1 ? "s" : "");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,13 +29,11 @@
|
||||
#include "../../common/path_manager.h"
|
||||
#include "../../common/repositories/base_data_repository.h"
|
||||
#include "../../common/file.h"
|
||||
#include "../../common/events/player_event_logs.h"
|
||||
|
||||
EQEmuLogSys LogSys;
|
||||
EQEmuLogSys LogSys;
|
||||
WorldContentService content_service;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
PlayerEventLogs player_event_logs;
|
||||
ZoneStore zone_store;
|
||||
PathManager path;
|
||||
|
||||
void ImportSpells(SharedDatabase *db);
|
||||
void ImportSkillCaps(SharedDatabase *db);
|
||||
|
||||
+11
-36
@@ -2,8 +2,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
||||
|
||||
SET(common_sources
|
||||
base_packet.cpp
|
||||
bazaar.cpp
|
||||
bodytypes.cpp
|
||||
classes.cpp
|
||||
cli/eqemu_command_handler.cpp
|
||||
compression.cpp
|
||||
@@ -62,7 +60,6 @@ SET(common_sources
|
||||
mutex.cpp
|
||||
mysql_request_result.cpp
|
||||
mysql_request_row.cpp
|
||||
mysql_stmt.cpp
|
||||
opcode_map.cpp
|
||||
opcodemgr.cpp
|
||||
packet_dump.cpp
|
||||
@@ -86,7 +83,6 @@ SET(common_sources
|
||||
shared_tasks.cpp
|
||||
shareddb.cpp
|
||||
skills.cpp
|
||||
skill_caps.cpp
|
||||
spdat.cpp
|
||||
strings.cpp
|
||||
struct_strategy.cpp
|
||||
@@ -112,8 +108,6 @@ SET(common_sources
|
||||
net/websocket_server.cpp
|
||||
net/websocket_server_connection.cpp
|
||||
patches/patches.cpp
|
||||
patches/laurion.cpp
|
||||
patches/laurion_limits.cpp
|
||||
patches/sod.cpp
|
||||
patches/sod_limits.cpp
|
||||
patches/sof.cpp
|
||||
@@ -161,7 +155,6 @@ SET(repositories
|
||||
repositories/base/base_bugs_repository.h
|
||||
repositories/base/base_bug_reports_repository.h
|
||||
repositories/base/base_buyer_repository.h
|
||||
repositories/base/base_buyer_trade_items_repository.h
|
||||
repositories/base/base_character_activities_repository.h
|
||||
repositories/base/base_character_alternate_abilities_repository.h
|
||||
repositories/base/base_character_alt_currency_repository.h
|
||||
@@ -183,8 +176,6 @@ SET(repositories
|
||||
repositories/base/base_character_leadership_abilities_repository.h
|
||||
repositories/base/base_character_material_repository.h
|
||||
repositories/base/base_character_memmed_spells_repository.h
|
||||
repositories/base/base_character_parcels_repository.h
|
||||
repositories/base/base_character_parcels_containers_repository.h
|
||||
repositories/base/base_character_peqzone_flags_repository.h
|
||||
repositories/base/base_character_pet_buffs_repository.h
|
||||
repositories/base/base_character_pet_info_repository.h
|
||||
@@ -343,8 +334,7 @@ SET(repositories
|
||||
repositories/books_repository.h
|
||||
repositories/bugs_repository.h
|
||||
repositories/bug_reports_repository.h
|
||||
repositories/buyer_buy_lines_repository.h
|
||||
repositories/buyer_trade_items_repository.h
|
||||
repositories/buyer_repository.h
|
||||
repositories/character_activities_repository.h
|
||||
repositories/character_alternate_abilities_repository.h
|
||||
repositories/character_alt_currency_repository.h
|
||||
@@ -366,8 +356,6 @@ SET(repositories
|
||||
repositories/character_leadership_abilities_repository.h
|
||||
repositories/character_material_repository.h
|
||||
repositories/character_memmed_spells_repository.h
|
||||
repositories/character_parcels_repository.h
|
||||
repositories/character_parcels_containers_repository.h
|
||||
repositories/character_peqzone_flags_repository.h
|
||||
repositories/character_pet_buffs_repository.h
|
||||
repositories/character_pet_info_repository.h
|
||||
@@ -504,11 +492,10 @@ SET(repositories
|
||||
repositories/zone_repository.h
|
||||
repositories/zone_points_repository.h
|
||||
|
||||
)
|
||||
)
|
||||
|
||||
SET(common_headers
|
||||
additive_lagged_fibonacci_engine.h
|
||||
bazaar.h
|
||||
base_packet.h
|
||||
bodytypes.h
|
||||
classes.h
|
||||
@@ -589,7 +576,6 @@ SET(common_headers
|
||||
mutex.h
|
||||
mysql_request_result.h
|
||||
mysql_request_row.h
|
||||
mysql_stmt.h
|
||||
op_codes.h
|
||||
opcode_dispatch.h
|
||||
opcodemgr.h
|
||||
@@ -606,7 +592,7 @@ SET(common_headers
|
||||
ptimer.h
|
||||
queue.h
|
||||
races.h
|
||||
raid.h
|
||||
raid.h
|
||||
random.h
|
||||
rdtsc.h
|
||||
rulesys.h
|
||||
@@ -620,7 +606,6 @@ SET(common_headers
|
||||
shared_tasks.h
|
||||
shareddb.h
|
||||
skills.h
|
||||
skill_caps.h
|
||||
spdat.h
|
||||
strings.h
|
||||
struct_strategy.h
|
||||
@@ -657,11 +642,7 @@ SET(common_headers
|
||||
net/websocket_server.h
|
||||
net/websocket_server_connection.h
|
||||
patches/patches.h
|
||||
patches/laurion.h
|
||||
patches/laurion_limits.h
|
||||
patches/laurion_ops.h
|
||||
patches/laurion_structs.h
|
||||
patches/sod.h
|
||||
patches/sod.h
|
||||
patches/sod_limits.h
|
||||
patches/sod_ops.h
|
||||
patches/sod_structs.h
|
||||
@@ -700,13 +681,13 @@ SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
event/timer.h
|
||||
event/task.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Json FILES
|
||||
json/json.h
|
||||
json/jsoncpp.cpp
|
||||
json/json-forwards.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Net FILES
|
||||
net/console_server.cpp
|
||||
@@ -743,14 +724,10 @@ SOURCE_GROUP(Net FILES
|
||||
net/websocket_server.h
|
||||
net/websocket_server_connection.cpp
|
||||
net/websocket_server_connection.h
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patches FILES
|
||||
patches/patches.h
|
||||
patches/laurion.h
|
||||
patches/laurion_limits.h
|
||||
patches/laurion_ops.h
|
||||
patches/laurion_structs.h
|
||||
patches/sod.h
|
||||
patches/sod_limits.h
|
||||
patches/sod_ops.h
|
||||
@@ -779,8 +756,6 @@ SOURCE_GROUP(Patches FILES
|
||||
patches/uf_ops.h
|
||||
patches/uf_structs.h
|
||||
patches/patches.cpp
|
||||
patches/laurion.cpp
|
||||
patches/laurion_limits.cpp
|
||||
patches/sod.cpp
|
||||
patches/sod_limits.cpp
|
||||
patches/sof.cpp
|
||||
@@ -793,12 +768,12 @@ SOURCE_GROUP(Patches FILES
|
||||
patches/titanium_limits.cpp
|
||||
patches/uf.cpp
|
||||
patches/uf_limits.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(StackWalker FILES
|
||||
StackWalker/StackWalker.h
|
||||
StackWalker/StackWalker.cpp
|
||||
)
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Util FILES
|
||||
util/memory_stream.h
|
||||
@@ -806,7 +781,7 @@ SOURCE_GROUP(Util FILES
|
||||
util/directory.h
|
||||
util/uuid.cpp
|
||||
util/uuid.h
|
||||
)
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||
|
||||
@@ -819,6 +794,6 @@ ENDIF (UNIX)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
||||
ENDIF ()
|
||||
ENDIF()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
@@ -59,7 +59,6 @@ public:
|
||||
void WriteUInt8(uint8 value) { *(uint8 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint8); }
|
||||
void WriteUInt32(uint32 value) { *(uint32 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint32); }
|
||||
void WriteUInt64(uint64 value) { *(uint64 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint64); }
|
||||
void WriteSInt16(int32 value) { *(int16*)(pBuffer + _wpos) = value; _wpos += sizeof(int16); }
|
||||
void WriteUInt16(uint32 value) { *(uint16 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint16); }
|
||||
void WriteSInt32(int32 value) { *(int32 *)(pBuffer + _wpos) = value; _wpos += sizeof(int32); }
|
||||
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
#include "bazaar.h"
|
||||
|
||||
#include "../../common/item_instance.h"
|
||||
#include "repositories/trader_repository.h"
|
||||
#include <memory>
|
||||
|
||||
std::vector<BazaarSearchResultsFromDB_Struct>
|
||||
Bazaar::GetSearchResults(
|
||||
SharedDatabase &db,
|
||||
BazaarSearchCriteria_Struct search,
|
||||
uint32 char_zone_id
|
||||
)
|
||||
{
|
||||
LogTrading(
|
||||
"Searching for items with search criteria - item_name [{}] min_cost [{}] max_cost [{}] min_level [{}] "
|
||||
"max_level [{}] max_results [{}] prestige [{}] augment [{}] trader_entity_id [{}] trader_id [{}] "
|
||||
"search_scope [{}] char_zone_id [{}]",
|
||||
search.item_name,
|
||||
search.min_cost,
|
||||
search.max_cost,
|
||||
search.min_level,
|
||||
search.max_level,
|
||||
search.max_results,
|
||||
search.prestige,
|
||||
search.augment,
|
||||
search.trader_entity_id,
|
||||
search.trader_id,
|
||||
search.search_scope,
|
||||
char_zone_id
|
||||
);
|
||||
|
||||
std::string search_criteria_trader("TRUE ");
|
||||
|
||||
if (search.search_scope == NonRoFBazaarSearchScope) {
|
||||
search_criteria_trader.append(
|
||||
fmt::format(
|
||||
" AND trader.char_entity_id = {} AND trader.char_zone_id = {}",
|
||||
search.trader_entity_id,
|
||||
Zones::BAZAAR
|
||||
)
|
||||
);
|
||||
}
|
||||
else if (search.search_scope == Local_Scope) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.char_zone_id = {}", char_zone_id));
|
||||
}
|
||||
else if (search.trader_id > 0) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.char_id = {}", search.trader_id));
|
||||
}
|
||||
if (search.min_cost != 0) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.item_cost >= {}", search.min_cost * 1000));
|
||||
}
|
||||
if (search.max_cost != 0) {
|
||||
search_criteria_trader.append(fmt::format(" AND trader.item_cost <= {}", (uint64) search.max_cost * 1000));
|
||||
}
|
||||
|
||||
// not yet implemented
|
||||
// if (search.prestige != 0) {
|
||||
// 0xffffffff prestige only, 0xfffffffe non-prestige, 0 all
|
||||
// search_criteria.append(fmt::format(" AND items.type = {} ", search.prestige));
|
||||
// }
|
||||
|
||||
std::string query = fmt::format(
|
||||
"SELECT COUNT(item_id), trader.char_id, trader.item_id, trader.item_sn, trader.item_charges, trader.item_cost, "
|
||||
"trader.slot_id, SUM(trader.item_charges), trader.char_zone_id, trader.char_entity_id, character_data.name, "
|
||||
"aug_slot_1, aug_slot_2, aug_slot_3, aug_slot_4, aug_slot_5, aug_slot_6 "
|
||||
"FROM trader, character_data "
|
||||
"WHERE {} AND trader.char_id = character_data.id "
|
||||
"GROUP BY trader.item_sn, trader.item_charges, trader.char_id",
|
||||
search_criteria_trader.c_str()
|
||||
);
|
||||
|
||||
std::vector<BazaarSearchResultsFromDB_Struct> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
struct ItemSearchType {
|
||||
EQ::item::ItemType type;
|
||||
bool condition;
|
||||
};
|
||||
|
||||
struct AddititiveSearchCriteria {
|
||||
bool should_check;
|
||||
bool condition;
|
||||
};
|
||||
|
||||
for (auto row: results) {
|
||||
BazaarSearchResultsFromDB_Struct r{};
|
||||
|
||||
r.item_id = Strings::ToInt(row[2]);
|
||||
r.charges = Strings::ToInt(row[4]);
|
||||
|
||||
auto item = db.GetItem(r.item_id);
|
||||
if (!item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 aug_slot_1 = Strings::ToUnsignedInt(row[11]);
|
||||
uint32 aug_slot_2 = Strings::ToUnsignedInt(row[12]);
|
||||
uint32 aug_slot_3 = Strings::ToUnsignedInt(row[13]);
|
||||
uint32 aug_slot_4 = Strings::ToUnsignedInt(row[14]);
|
||||
uint32 aug_slot_5 = Strings::ToUnsignedInt(row[15]);
|
||||
uint32 aug_slot_6 = Strings::ToUnsignedInt(row[16]);
|
||||
|
||||
std::unique_ptr<EQ::ItemInstance> inst(
|
||||
db.CreateItem(
|
||||
item,
|
||||
r.charges,
|
||||
aug_slot_1,
|
||||
aug_slot_2,
|
||||
aug_slot_3,
|
||||
aug_slot_4,
|
||||
aug_slot_5,
|
||||
aug_slot_6
|
||||
)
|
||||
);
|
||||
|
||||
if (!inst->GetItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
r.count = Strings::ToInt(row[0]);
|
||||
r.trader_id = Strings::ToInt(row[1]);
|
||||
r.serial_number = Strings::ToInt(row[3]);
|
||||
r.cost = Strings::ToInt(row[5]);
|
||||
r.slot_id = Strings::ToInt(row[6]);
|
||||
r.sum_charges = Strings::ToInt(row[7]);
|
||||
r.stackable = item->Stackable;
|
||||
r.icon_id = item->Icon;
|
||||
r.trader_zone_id = Strings::ToInt(row[8]);
|
||||
r.trader_entity_id = Strings::ToInt(row[9]);
|
||||
r.serial_number_RoF = fmt::format("{:016}\0", Strings::ToInt(row[3]));
|
||||
r.item_name = fmt::format("{:.63}\0", item->Name);
|
||||
r.trader_name = fmt::format("{:.63}\0", std::string(row[10]).c_str());
|
||||
|
||||
LogTradingDetail(
|
||||
"Searching against item [{}] ({}) for trader [{}]",
|
||||
item->Name,
|
||||
item->ID,
|
||||
r.trader_name
|
||||
);
|
||||
|
||||
// item stat searches
|
||||
std::map<uint32, uint32> item_stat_searches = {
|
||||
|
||||
{STAT_AC, inst->GetItemArmorClass(true)},
|
||||
{STAT_AGI, static_cast<uint32>(inst->GetItemAgi(true))},
|
||||
{STAT_CHA, static_cast<uint32>(inst->GetItemCha(true))},
|
||||
{STAT_DEX, static_cast<uint32>(inst->GetItemDex(true))},
|
||||
{STAT_INT, static_cast<uint32>(inst->GetItemInt(true))},
|
||||
{STAT_STA, static_cast<uint32>(inst->GetItemSta(true))},
|
||||
{STAT_STR, static_cast<uint32>(inst->GetItemStr(true))},
|
||||
{STAT_WIS, static_cast<uint32>(inst->GetItemWis(true))},
|
||||
{STAT_COLD, static_cast<uint32>(inst->GetItemCR(true))},
|
||||
{STAT_DISEASE, static_cast<uint32>(inst->GetItemDR(true))},
|
||||
{STAT_FIRE, static_cast<uint32>(inst->GetItemFR(true))},
|
||||
{STAT_MAGIC, static_cast<uint32>(inst->GetItemMR(true))},
|
||||
{STAT_POISON, static_cast<uint32>(inst->GetItemPR(true))},
|
||||
{STAT_HP, static_cast<uint32>(inst->GetItemHP(true))},
|
||||
{STAT_MANA, static_cast<uint32>(inst->GetItemMana(true))},
|
||||
{STAT_ENDURANCE, static_cast<uint32>(inst->GetItemEndur(true))},
|
||||
{STAT_ATTACK, static_cast<uint32>(inst->GetItemAttack(true))},
|
||||
{STAT_HP_REGEN, static_cast<uint32>(inst->GetItemRegen(true))},
|
||||
{STAT_MANA_REGEN, static_cast<uint32>(inst->GetItemManaRegen(true))},
|
||||
{STAT_HASTE, static_cast<uint32>(inst->GetItemHaste(true))},
|
||||
{STAT_DAMAGE_SHIELD, static_cast<uint32>(inst->GetItemDamageShield(true))},
|
||||
{STAT_DS_MITIGATION, static_cast<uint32>(inst->GetItemDSMitigation(true))},
|
||||
{STAT_HEAL_AMOUNT, static_cast<uint32>(inst->GetItemHealAmt(true))},
|
||||
{STAT_SPELL_DAMAGE, static_cast<uint32>(inst->GetItemSpellDamage(true))},
|
||||
{STAT_CLAIRVOYANCE, static_cast<uint32>(inst->GetItemClairvoyance(true))},
|
||||
{STAT_HEROIC_AGILITY, static_cast<uint32>(inst->GetItemHeroicAgi(true))},
|
||||
{STAT_HEROIC_CHARISMA, static_cast<uint32>(inst->GetItemHeroicCha(true))},
|
||||
{STAT_HEROIC_DEXTERITY, static_cast<uint32>(inst->GetItemHeroicDex(true))},
|
||||
{STAT_HEROIC_INTELLIGENCE, static_cast<uint32>(inst->GetItemHeroicInt(true))},
|
||||
{STAT_HEROIC_STAMINA, static_cast<uint32>(inst->GetItemHeroicSta(true))},
|
||||
{STAT_HEROIC_STRENGTH, static_cast<uint32>(inst->GetItemHeroicStr(true))},
|
||||
{STAT_HEROIC_WISDOM, static_cast<uint32>(inst->GetItemHeroicWis(true))},
|
||||
{STAT_BASH, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillBash, true))},
|
||||
{STAT_BACKSTAB, static_cast<uint32>(inst->GetItemBackstabDamage(true))},
|
||||
{STAT_DRAGON_PUNCH, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillDragonPunch, true))},
|
||||
{STAT_EAGLE_STRIKE, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillEagleStrike, true))},
|
||||
{STAT_FLYING_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillFlyingKick, true))},
|
||||
{STAT_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillKick, true))},
|
||||
{STAT_ROUND_KICK, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillRoundKick, true))},
|
||||
{STAT_TIGER_CLAW, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillTigerClaw, true))},
|
||||
{STAT_FRENZY, static_cast<uint32>(inst->GetItemSkillsStat(EQ::skills::SkillFrenzy, true))},
|
||||
};
|
||||
|
||||
r.item_stat = item_stat_searches.contains(search.item_stat) ? item_stat_searches[search.item_stat] : 0;
|
||||
if (item_stat_searches.contains(search.item_stat) && item_stat_searches[search.item_stat] <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
static std::map<uint8, uint32> item_slot_searches = {
|
||||
{EQ::invslot::slotCharm, 1},
|
||||
{EQ::invslot::slotEar1, 2},
|
||||
{EQ::invslot::slotHead, 4},
|
||||
{EQ::invslot::slotFace, 8},
|
||||
{EQ::invslot::slotEar2, 16},
|
||||
{EQ::invslot::slotNeck, 32},
|
||||
{EQ::invslot::slotShoulders, 64},
|
||||
{EQ::invslot::slotArms, 128},
|
||||
{EQ::invslot::slotBack, 256},
|
||||
{EQ::invslot::slotWrist1, 512},
|
||||
{EQ::invslot::slotWrist2, 1024},
|
||||
{EQ::invslot::slotRange, 2048},
|
||||
{EQ::invslot::slotHands, 4096},
|
||||
{EQ::invslot::slotPrimary, 8192},
|
||||
{EQ::invslot::slotSecondary, 16384},
|
||||
{EQ::invslot::slotFinger1, 32768},
|
||||
{EQ::invslot::slotFinger2, 65536},
|
||||
{EQ::invslot::slotChest, 131072},
|
||||
{EQ::invslot::slotLegs, 262144},
|
||||
{EQ::invslot::slotFeet, 524288},
|
||||
{EQ::invslot::slotWaist, 1048576},
|
||||
{EQ::invslot::slotPowerSource, 2097152},
|
||||
{EQ::invslot::slotAmmo, 4194304},
|
||||
};
|
||||
|
||||
auto GetEquipmentSlotBit = [&](uint32 slot) -> uint32 {
|
||||
return item_slot_searches.contains(slot) ? item_slot_searches[slot] : 0;
|
||||
};
|
||||
|
||||
auto FindItemAugSlot = [&]() -> bool {
|
||||
for (auto const &s: inst->GetItem()->AugSlotType) {
|
||||
return s == search.augment;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// item type searches
|
||||
std::vector<ItemSearchType> item_search_types = {
|
||||
{EQ::item::ItemType::ItemTypeAll, true},
|
||||
{EQ::item::ItemType::ItemTypeBook, item->ItemClass == EQ::item::ItemType::ItemTypeBook},
|
||||
{EQ::item::ItemType::ItemTypeContainer, item->ItemClass == EQ::item::ItemType::ItemTypeContainer ||
|
||||
item->IsClassBag()},
|
||||
{EQ::item::ItemType::ItemTypeAllEffects, item->Scroll.Effect > 0 && item->Scroll.Effect < 65000},
|
||||
{EQ::item::ItemType::ItemTypeUnknown9, item->Worn.Effect == 998},
|
||||
{EQ::item::ItemType::ItemTypeUnknown10, item->Worn.Effect >= 1298 && item->Worn.Effect <= 1307},
|
||||
{EQ::item::ItemType::ItemTypeFocusEffect, item->Focus.Effect > 0},
|
||||
{EQ::item::ItemType::ItemTypeArmor, item->ItemType == EQ::item::ItemType::ItemTypeArmor},
|
||||
{EQ::item::ItemType::ItemType1HBlunt, item->ItemType == EQ::item::ItemType::ItemType1HBlunt},
|
||||
{EQ::item::ItemType::ItemType1HPiercing, item->ItemType == EQ::item::ItemType::ItemType1HPiercing},
|
||||
{EQ::item::ItemType::ItemType1HSlash, item->ItemType == EQ::item::ItemType::ItemType1HSlash},
|
||||
{EQ::item::ItemType::ItemType2HBlunt, item->ItemType == EQ::item::ItemType::ItemType2HBlunt},
|
||||
{EQ::item::ItemType::ItemType2HSlash, item->ItemType == EQ::item::ItemType::ItemType2HSlash},
|
||||
{EQ::item::ItemType::ItemTypeBow, item->ItemType == EQ::item::ItemType::ItemTypeBow},
|
||||
{EQ::item::ItemType::ItemTypeShield, item->ItemType == EQ::item::ItemType::ItemTypeShield},
|
||||
{EQ::item::ItemType::ItemTypeMisc, item->ItemType == EQ::item::ItemType::ItemTypeMisc},
|
||||
{EQ::item::ItemType::ItemTypeFood, item->ItemType == EQ::item::ItemType::ItemTypeFood},
|
||||
{EQ::item::ItemType::ItemTypeDrink, item->ItemType == EQ::item::ItemType::ItemTypeDrink},
|
||||
{EQ::item::ItemType::ItemTypeLight, item->ItemType == EQ::item::ItemType::ItemTypeLight},
|
||||
{EQ::item::ItemType::ItemTypeCombinable, item->ItemType == EQ::item::ItemType::ItemTypeCombinable},
|
||||
{EQ::item::ItemType::ItemTypeBandage, item->ItemType == EQ::item::ItemType::ItemTypeBandage},
|
||||
{EQ::item::ItemType::ItemTypeSmallThrowing, item->ItemType == EQ::item::ItemType::ItemTypeSmallThrowing ||
|
||||
item->ItemType == EQ::item::ItemType::ItemTypeLargeThrowing},
|
||||
{EQ::item::ItemType::ItemTypeSpell, item->ItemType == EQ::item::ItemType::ItemTypeSpell},
|
||||
{EQ::item::ItemType::ItemTypePotion, item->ItemType == EQ::item::ItemType::ItemTypePotion},
|
||||
{EQ::item::ItemType::ItemTypeBrassInstrument, item->ItemType == EQ::item::ItemType::ItemTypeBrassInstrument},
|
||||
{EQ::item::ItemType::ItemTypeWindInstrument, item->ItemType == EQ::item::ItemType::ItemTypeWindInstrument},
|
||||
{EQ::item::ItemType::ItemTypeStringedInstrument, item->ItemType == EQ::item::ItemType::ItemTypeStringedInstrument},
|
||||
{EQ::item::ItemType::ItemTypePercussionInstrument, item->ItemType == EQ::item::ItemType::ItemTypePercussionInstrument},
|
||||
{EQ::item::ItemType::ItemTypeArrow, item->ItemType == EQ::item::ItemType::ItemTypeArrow},
|
||||
{EQ::item::ItemType::ItemTypeJewelry, item->ItemType == EQ::item::ItemType::ItemTypeJewelry},
|
||||
{EQ::item::ItemType::ItemTypeNote, item->ItemType == EQ::item::ItemType::ItemTypeNote},
|
||||
{EQ::item::ItemType::ItemTypeKey, item->ItemType == EQ::item::ItemType::ItemTypeKey},
|
||||
{EQ::item::ItemType::ItemType2HPiercing, item->ItemType == EQ::item::ItemType::ItemType2HPiercing},
|
||||
{EQ::item::ItemType::ItemTypeAlcohol, item->ItemType == EQ::item::ItemType::ItemTypeAlcohol},
|
||||
{EQ::item::ItemType::ItemTypeMartial, item->ItemType == EQ::item::ItemType::ItemTypeMartial},
|
||||
{EQ::item::ItemType::ItemTypeAugmentation, item->ItemType == EQ::item::ItemType::ItemTypeAugmentation},
|
||||
{EQ::item::ItemType::ItemTypeAlternateAbility, item->ItemType == EQ::item::ItemType::ItemTypeAlternateAbility},
|
||||
{EQ::item::ItemType::ItemTypeCount, item->ItemType == EQ::item::ItemType::ItemTypeCount},
|
||||
{EQ::item::ItemType::ItemTypeCollectible, item->ItemType == EQ::item::ItemType::ItemTypeCollectible}
|
||||
};
|
||||
|
||||
bool met_filter = false;
|
||||
bool has_filter = false;
|
||||
|
||||
for (auto &i: item_search_types) {
|
||||
if (i.type == search.type) {
|
||||
has_filter = true;
|
||||
if (i.condition) {
|
||||
LogTradingDetail("Item [{}] met search criteria for type [{}]", item->Name, uint8(i.type));
|
||||
met_filter = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has_filter && !met_filter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Add catch-all item type filter for specific item types
|
||||
|
||||
// item additive searches
|
||||
std::vector<AddititiveSearchCriteria> item_additive_searches = {
|
||||
{
|
||||
.should_check = search.min_level != 1 && inst->GetItemRequiredLevel(true) > 0,
|
||||
.condition = inst->GetItemRequiredLevel(true) >= search.min_level
|
||||
},
|
||||
{
|
||||
.should_check = search.max_level != 1 && inst->GetItemRequiredLevel(true) > 0,
|
||||
.condition = inst->GetItemRequiredLevel(true) <= search.max_level
|
||||
},
|
||||
{
|
||||
.should_check = !std::string(search.item_name).empty(),
|
||||
.condition = Strings::ContainsLower(item->Name, search.item_name)
|
||||
},
|
||||
{
|
||||
.should_check = search._class != 0xFFFFFFFF,
|
||||
.condition = static_cast<bool>(item->Classes & GetPlayerClassBit(search._class))
|
||||
},
|
||||
{
|
||||
.should_check = search.race != 0xFFFFFFFF,
|
||||
.condition = static_cast<bool>(item->Races & GetPlayerRaceBit(GetRaceIDFromPlayerRaceValue(search.race)))
|
||||
},
|
||||
{
|
||||
.should_check = search.augment != 0,
|
||||
.condition = FindItemAugSlot()
|
||||
},
|
||||
{
|
||||
.should_check = search.slot != 0xFFFFFFFF,
|
||||
.condition = static_cast<bool>(item->Slots & GetEquipmentSlotBit(search.slot))
|
||||
},
|
||||
};
|
||||
|
||||
bool should_add = true;
|
||||
|
||||
for (auto &i: item_additive_searches) {
|
||||
LogTradingDetail(
|
||||
"Checking item [{}] for search criteria - should_check [{}] condition [{}]",
|
||||
item->Name,
|
||||
i.should_check,
|
||||
i.condition
|
||||
);
|
||||
if (i.should_check && !i.condition) {
|
||||
should_add = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!should_add) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LogTradingDetail("Found item [{}] meeting search criteria.", r.item_name);
|
||||
all_entries.push_back(r);
|
||||
}
|
||||
|
||||
if (all_entries.size() > search.max_results) {
|
||||
all_entries.resize(search.max_results);
|
||||
}
|
||||
|
||||
LogTrading("Returning [{}] items from search results", all_entries.size());
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef EQEMU_BAZAAR_H
|
||||
#define EQEMU_BAZAAR_H
|
||||
|
||||
#include <vector>
|
||||
#include "shareddb.h"
|
||||
|
||||
class Bazaar {
|
||||
public:
|
||||
static std::vector<BazaarSearchResultsFromDB_Struct>
|
||||
GetSearchResults(SharedDatabase &db, BazaarSearchCriteria_Struct search, unsigned int char_zone_id);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_BAZAAR_H
|
||||
@@ -1,12 +0,0 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/bodytypes.h"
|
||||
|
||||
std::string BodyType::GetName(uint8 body_type_id)
|
||||
{
|
||||
return IsValid(body_type_id) ? body_type_names[body_type_id] : "UNKNOWN BODY TYPE";
|
||||
}
|
||||
|
||||
bool BodyType::IsValid(uint8 body_type_id)
|
||||
{
|
||||
return body_type_names.find(body_type_id) != body_type_names.end();
|
||||
}
|
||||
+46
-90
@@ -18,96 +18,52 @@
|
||||
#ifndef BODYTYPES_H
|
||||
#define BODYTYPES_H
|
||||
|
||||
#include "types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
typedef enum {
|
||||
BT_Humanoid = 1,
|
||||
BT_Lycanthrope = 2,
|
||||
BT_Undead = 3,
|
||||
BT_Giant = 4,
|
||||
BT_Construct = 5,
|
||||
BT_Extraplanar = 6,
|
||||
BT_Magical = 7, //this name might be a bit off,
|
||||
BT_SummonedUndead = 8,
|
||||
BT_RaidGiant = 9, //Velious era Raid Giant
|
||||
BT_RaidColdain = 10, //Velious era Raid Coldain
|
||||
BT_NoTarget = 11, //no name, can't target this bodytype
|
||||
BT_Vampire = 12,
|
||||
BT_Atenha_Ra = 13,
|
||||
BT_Greater_Akheva = 14,
|
||||
BT_Khati_Sha = 15,
|
||||
BT_Seru = 16,
|
||||
BT_Grieg_Veneficus = 17,
|
||||
BT_Draz_Nurakk = 18,
|
||||
BT_Zek = 19, //"creatures from the Plane of War."
|
||||
BT_Luggald = 20,
|
||||
BT_Animal = 21,
|
||||
BT_Insect = 22,
|
||||
BT_Monster = 23,
|
||||
BT_Summoned = 24, //Elemental?
|
||||
BT_Plant = 25,
|
||||
BT_Dragon = 26,
|
||||
BT_Summoned2 = 27,
|
||||
BT_Summoned3 = 28,
|
||||
BT_Dragon2 = 29, //database data indicates this is a dragon type (kunark and DoN?)
|
||||
BT_VeliousDragon = 30, //might not be a tight set
|
||||
BT_Familiar = 31,
|
||||
BT_Dragon3 = 32,
|
||||
BT_Boxes = 33,
|
||||
BT_Muramite = 34, //tribal dudes
|
||||
// ...
|
||||
BT_NoTarget2 = 60,
|
||||
// ...
|
||||
BT_SwarmPet = 63, //Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
|
||||
BT_MonsterSummon = 64,
|
||||
// 65, trap or effect related?
|
||||
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
|
||||
BT_Special = 67
|
||||
} bodyType;
|
||||
/* bodytypes above 64 make the mob not show up */
|
||||
|
||||
// body types above 64 make the mob invisible
|
||||
namespace BodyType {
|
||||
constexpr uint8 Humanoid = 1;
|
||||
constexpr uint8 Lycanthrope = 2;
|
||||
constexpr uint8 Undead = 3;
|
||||
constexpr uint8 Giant = 4;
|
||||
constexpr uint8 Construct = 5;
|
||||
constexpr uint8 Extraplanar = 6;
|
||||
constexpr uint8 Magical = 7; // this name might be a bit off,
|
||||
constexpr uint8 SummonedUndead = 8;
|
||||
constexpr uint8 RaidGiant = 9; // Velious era Raid Giant
|
||||
constexpr uint8 RaidColdain = 10; // Velious era Raid Coldain
|
||||
constexpr uint8 NoTarget = 11; // no name, can't target this bodytype
|
||||
constexpr uint8 Vampire = 12;
|
||||
constexpr uint8 AtenHaRa = 13;
|
||||
constexpr uint8 GreaterAkheva = 14;
|
||||
constexpr uint8 KhatiSha = 15;
|
||||
constexpr uint8 Seru = 16;
|
||||
constexpr uint8 GriegVeneficus = 17;
|
||||
constexpr uint8 DrazNurakk = 18;
|
||||
constexpr uint8 Zek = 19; //"creatures from the Plane of War."
|
||||
constexpr uint8 Luggald = 20;
|
||||
constexpr uint8 Animal = 21;
|
||||
constexpr uint8 Insect = 22;
|
||||
constexpr uint8 Monster = 23;
|
||||
constexpr uint8 Summoned = 24; // Elemental?
|
||||
constexpr uint8 Plant = 25;
|
||||
constexpr uint8 Dragon = 26;
|
||||
constexpr uint8 Summoned2 = 27;
|
||||
constexpr uint8 Summoned3 = 28;
|
||||
constexpr uint8 Dragon2 = 29; // database data indicates this is a dragon type (Kunark and DoN?)
|
||||
constexpr uint8 VeliousDragon = 30; // might not be a tight set
|
||||
constexpr uint8 Familiar = 31;
|
||||
constexpr uint8 Dragon3 = 32;
|
||||
constexpr uint8 Boxes = 33;
|
||||
constexpr uint8 Muramite = 34; // tribal dudes
|
||||
constexpr uint8 NoTarget2 = 60;
|
||||
constexpr uint8 SwarmPet = 63; // Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
|
||||
constexpr uint8 MonsterSummon = 64;
|
||||
constexpr uint8 InvisibleMan = 66; // no name, seen on 'InvisMan', can be /targeted
|
||||
constexpr uint8 Special = 67;
|
||||
|
||||
std::string GetName(uint8 body_type_id);
|
||||
bool IsValid(uint8 body_type_id);
|
||||
}
|
||||
|
||||
static std::map<uint8, std::string> body_type_names = {
|
||||
{ BodyType::Humanoid, "Humanoid" },
|
||||
{ BodyType::Lycanthrope, "Lycanthrope" },
|
||||
{ BodyType::Undead, "Undead" },
|
||||
{ BodyType::Giant, "Giant" },
|
||||
{ BodyType::Construct, "Construct" },
|
||||
{ BodyType::Extraplanar, "Extraplanar" },
|
||||
{ BodyType::Magical, "Magical" },
|
||||
{ BodyType::SummonedUndead, "Summoned Undead" },
|
||||
{ BodyType::RaidGiant, "Raid Giant" },
|
||||
{ BodyType::RaidColdain, "Raid Coldain" },
|
||||
{ BodyType::NoTarget, "Untargetable" },
|
||||
{ BodyType::Vampire, "Vampire" },
|
||||
{ BodyType::AtenHaRa, "Aten Ha Ra" },
|
||||
{ BodyType::GreaterAkheva, "Greater Akheva" },
|
||||
{ BodyType::KhatiSha, "Khati Sha" },
|
||||
{ BodyType::Seru, "Seru" },
|
||||
{ BodyType::GriegVeneficus, "Grieg Veneficus" },
|
||||
{ BodyType::DrazNurakk, "Draz Nurakk" },
|
||||
{ BodyType::Zek, "Zek" },
|
||||
{ BodyType::Luggald, "Luggald" },
|
||||
{ BodyType::Animal, "Animal" },
|
||||
{ BodyType::Insect, "Insect" },
|
||||
{ BodyType::Monster, "Monster" },
|
||||
{ BodyType::Summoned, "Summoned" },
|
||||
{ BodyType::Plant, "Plant" },
|
||||
{ BodyType::Dragon, "Dragon" },
|
||||
{ BodyType::Summoned2, "Summoned 2" },
|
||||
{ BodyType::Summoned3, "Summoned 3" },
|
||||
{ BodyType::Dragon2, "Dragon 2" },
|
||||
{ BodyType::VeliousDragon, "Velious Dragon" },
|
||||
{ BodyType::Familiar, "Familiar" },
|
||||
{ BodyType::Dragon3, "Dragon 3" },
|
||||
{ BodyType::Boxes, "Boxes" },
|
||||
{ BodyType::Muramite, "Muramite" },
|
||||
{ BodyType::NoTarget2, "Untargetable 2" },
|
||||
{ BodyType::SwarmPet, "Swarm Pet" },
|
||||
{ BodyType::MonsterSummon, "Monster Summon" },
|
||||
{ BodyType::InvisibleMan, "Invisible Man" },
|
||||
{ BodyType::Special, "Special" },
|
||||
};
|
||||
constexpr int format_as(bodyType type) { return static_cast<int>(type); }
|
||||
|
||||
#endif
|
||||
|
||||
@@ -71,9 +71,6 @@ namespace Class {
|
||||
constexpr uint8 FellowshipMaster = 69;
|
||||
constexpr uint8 AlternateCurrencyMerchant = 70;
|
||||
constexpr uint8 MercenaryLiaison = 71;
|
||||
constexpr uint8 RealEstateMerchant = 72;
|
||||
constexpr uint8 LoyaltyMerchant = 73;
|
||||
constexpr uint8 TributeMaster2 = 74;
|
||||
|
||||
constexpr uint8 PLAYER_CLASS_COUNT = 16;
|
||||
constexpr uint16 ALL_CLASSES_BITMASK = 65535;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "../rulesys.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
#include "../zone_store.h"
|
||||
|
||||
|
||||
WorldContentService::WorldContentService()
|
||||
@@ -179,13 +178,12 @@ void WorldContentService::ReloadContentFlags()
|
||||
LogInfo(
|
||||
"Loaded content flag [{}] [{}]",
|
||||
f.flag_name,
|
||||
(f.enabled ? "enabled" : "disabled")
|
||||
(f.enabled ? "Enabled" : "Disabled")
|
||||
);
|
||||
}
|
||||
|
||||
SetContentFlags(set_content_flags);
|
||||
LoadStaticGlobalZoneInstances();
|
||||
zone_store.LoadZones(*m_content_database);
|
||||
SetContentZones(ZoneRepository::All(*m_content_database));
|
||||
}
|
||||
|
||||
Database *WorldContentService::GetDatabase() const
|
||||
@@ -237,113 +235,84 @@ void WorldContentService::SetContentFlag(const std::string &content_flag_name, b
|
||||
ReloadContentFlags();
|
||||
}
|
||||
|
||||
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
||||
// SetZones sets the zones for the world content service
|
||||
// this is used for zone routing middleware
|
||||
// we pull the zone list from the zone repository and feed from the zone store for now
|
||||
// we're holding a copy in the content service - but we're talking 250kb of data in memory to handle routing of zoning
|
||||
WorldContentService *WorldContentService::SetContentZones(const std::vector<BaseZoneRepository::Zone>& zones)
|
||||
{
|
||||
auto r = FindZone(zc->zoneID, zc->instanceID);
|
||||
if (r.zone_id == 0) {
|
||||
return;
|
||||
}
|
||||
m_zones = zones;
|
||||
|
||||
zc->instanceID = r.instance.id;
|
||||
}
|
||||
|
||||
// LoadStaticGlobalZoneInstances loads all static global zone instances
|
||||
// these are zones that are never set to expire and are global
|
||||
// these are used commonly in v1/v2/v3 versions of the same zone for expansion routing
|
||||
WorldContentService *WorldContentService::LoadStaticGlobalZoneInstances()
|
||||
{
|
||||
m_zone_static_instances = InstanceListRepository::GetWhere(
|
||||
*GetDatabase(),
|
||||
fmt::format("never_expires = 1 AND is_global = 1")
|
||||
);
|
||||
|
||||
LogInfo("Loaded [{}] zone_instances", m_zone_static_instances.size());
|
||||
LogInfo("Loaded [{}] zones", m_zones.size());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// FindZone handles content and context aware zone routing (middleware)
|
||||
// HandleZoneRoutingMiddleware is meant to handle content and context aware zone routing
|
||||
//
|
||||
// this is a middleware function that is meant to be used in the zone change process
|
||||
// this hooks all core zone changes within the server and routes the player to the correct zone
|
||||
// returning a zone_id of non-zero means the middleware will route the player
|
||||
// returning a zone_id of 0 means the middleware will not route the player
|
||||
// this is useful for handling multiple versions of the same zone
|
||||
//
|
||||
// implementation >
|
||||
// the zoning and process spawning logic already is handled by two keys "zone_id" and "instance_id"
|
||||
// we leverage static, never expires instances to handle this and client still sees it as a normal zone
|
||||
//
|
||||
// content awareness >
|
||||
// simply use the zone_id, server content settings and the middleware will handle the rest
|
||||
// you don't have to think about instances in any data tables (use instance_id 0)
|
||||
// you don't have to keep track of instance ids in scripts (use instance_id 0)
|
||||
// example # 1
|
||||
// lavastorm (pre-don) version 0 (classic)
|
||||
// lavastorm (don) version 1
|
||||
// we want to route players to the correct version of lavastorm based on the current server side expansion
|
||||
// in order to do that the simplest and cleanest way we intercept the zoning process and route players to an "instance" of the zone
|
||||
// the reason why we're doing this is because all of the zoning logic already is handled by two keys "zone_id" and "instance_id"
|
||||
// we can leverage static, never expires instances to handle this but to the client they don't see it any other way than a public normal zone
|
||||
// scripts handle all the same way, you don't have to think about instances, the middleware will handle the magic
|
||||
// the versions of zones are represented by two zone entries that have potentially different min/max expansion and/or different content flags
|
||||
// we decide to route the client to the correct version of the zone based on the current server side expansion
|
||||
//
|
||||
// example >
|
||||
// we want to route players to the correct version of lavastorm based on the current server side expansion (DoesZonePassContentFiltering)
|
||||
// lavastorm (pre-don) version 0 (classic)
|
||||
// zone table entry for version = 0, min_expansion = 0, max_expansion = 8
|
||||
// instance_list table entry for lavastorm has version = 0, is_global = 1, never_expires = 1
|
||||
// lavastorm (don) version 1
|
||||
// zone table entry for version = 1, min_expansion = 9, max_expansion = 99
|
||||
// instance_list table entry for lavastorm has version = 1, is_global = 1, never_expires = 1
|
||||
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
|
||||
// example # 2
|
||||
void WorldContentService::HandleZoneRoutingMiddleware(ZoneChange_Struct *zc)
|
||||
{
|
||||
for (const auto &z: zone_store.GetZones()) {
|
||||
for (auto &i: m_zone_static_instances) {
|
||||
if (
|
||||
z.zoneidnumber == zone_id &&
|
||||
DoesZonePassContentFiltering(z) &&
|
||||
i.zone == zone_id &&
|
||||
i.version == z.version) {
|
||||
// if we're already in an instance, we don't want to route the player to another instance
|
||||
if (zc->instanceID > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (instance_id > 0 && i.id != instance_id) {
|
||||
continue;
|
||||
}
|
||||
for (auto &z: m_zones) {
|
||||
if (z.zoneidnumber == zc->zoneID) {
|
||||
auto f = ContentFlags{
|
||||
.min_expansion = z.min_expansion,
|
||||
.max_expansion = z.max_expansion,
|
||||
.content_flags = z.content_flags,
|
||||
.content_flags_disabled = z.content_flags_disabled
|
||||
};
|
||||
|
||||
if (DoesPassContentFiltering(f)) {
|
||||
LogInfo(
|
||||
"Routed player to public static instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
||||
i.id,
|
||||
"Attempting to route player to zone [{}] ({}) version [{}] long_name [{}]",
|
||||
z.short_name,
|
||||
z.zoneidnumber,
|
||||
z.version,
|
||||
z.long_name,
|
||||
i.notes
|
||||
z.long_name
|
||||
);
|
||||
|
||||
return WorldContentService::FindZoneResult{
|
||||
.zone_id = static_cast<uint32>(z.zoneidnumber),
|
||||
.instance = i,
|
||||
.zone = z
|
||||
};
|
||||
auto instances = InstanceListRepository::GetWhere(
|
||||
*GetDatabase(),
|
||||
fmt::format(
|
||||
"zone = {} AND version = {} AND never_expires = 1 AND is_global = 1",
|
||||
z.zoneidnumber,
|
||||
z.version
|
||||
)
|
||||
);
|
||||
|
||||
if (!instances.empty()) {
|
||||
auto instance = instances.front();
|
||||
zc->instanceID = instance.id;
|
||||
|
||||
LogInfo(
|
||||
"Routed player to instance [{}] of zone [{}] ({}) version [{}] long_name [{}] notes [{}]",
|
||||
instance.id,
|
||||
z.short_name,
|
||||
z.zoneidnumber,
|
||||
z.version,
|
||||
z.long_name,
|
||||
instance.notes
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WorldContentService::FindZoneResult{.zone_id = 0};
|
||||
}
|
||||
|
||||
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
|
||||
{
|
||||
for (auto &i: m_zone_static_instances) {
|
||||
if (i.id == instance_id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorldContentService::DoesZonePassContentFiltering(const ZoneRepository::Zone &z)
|
||||
{
|
||||
auto f = ContentFlags{
|
||||
.min_expansion = z.min_expansion,
|
||||
.max_expansion = z.max_expansion,
|
||||
.content_flags = z.content_flags,
|
||||
.content_flags_disabled = z.content_flags_disabled
|
||||
};
|
||||
|
||||
return DoesPassContentFiltering(f);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <vector>
|
||||
#include "../repositories/content_flags_repository.h"
|
||||
#include "../repositories/zone_repository.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
|
||||
class Database;
|
||||
|
||||
@@ -160,7 +159,6 @@ public:
|
||||
WorldContentService * SetExpansionContext();
|
||||
|
||||
bool DoesPassContentFiltering(const ContentFlags& f);
|
||||
bool DoesZonePassContentFiltering(const ZoneRepository::Zone& z);
|
||||
|
||||
WorldContentService * SetDatabase(Database *database);
|
||||
Database *GetDatabase() const;
|
||||
@@ -171,16 +169,7 @@ public:
|
||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
||||
|
||||
void HandleZoneRoutingMiddleware(ZoneChange_Struct *zc);
|
||||
|
||||
struct FindZoneResult {
|
||||
uint32 zone_id = 0;
|
||||
InstanceListRepository::InstanceList instance;
|
||||
ZoneRepository::Zone zone;
|
||||
};
|
||||
|
||||
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
|
||||
bool IsInPublicStaticInstance(uint32 instance_id);
|
||||
|
||||
WorldContentService * SetContentZones(const std::vector<ZoneRepository::Zone>& zones);
|
||||
private:
|
||||
int current_expansion{};
|
||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||
@@ -190,8 +179,7 @@ private:
|
||||
Database *m_content_database;
|
||||
|
||||
// holds a record of the zone table from the database
|
||||
WorldContentService *LoadStaticGlobalZoneInstances();
|
||||
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
|
||||
std::vector<ZoneRepository::Zone> m_zones = {};
|
||||
};
|
||||
|
||||
extern WorldContentService content_service;
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if WINDOWS
|
||||
#define popen _popen
|
||||
#endif
|
||||
|
||||
|
||||
@@ -101,24 +101,6 @@ void CRC32::SetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at)
|
||||
memcpy(in_data, (char*)&check, 4);
|
||||
}
|
||||
|
||||
unsigned long CRC32::GetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at)
|
||||
{
|
||||
unsigned long data;
|
||||
unsigned long check = 0xffffffff;
|
||||
|
||||
for (uint32 i = start_at; i < in_length; i++)
|
||||
{
|
||||
data = in_data[i];
|
||||
data = data ^ (check);
|
||||
data = data & 0x000000ff;
|
||||
check = check >> 8;
|
||||
data = CRC32Table[data];
|
||||
check = check ^ data;
|
||||
}
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
uint32 CRC32::Update(const uint8* buf, uint32 bufsize, uint32 crc32var) {
|
||||
for(uint32 i=0; i < bufsize; i++)
|
||||
Calc(buf[i], crc32var);
|
||||
|
||||
@@ -8,7 +8,6 @@ public:
|
||||
static uint32 Generate(const uint8* buf, uint32 bufsize);
|
||||
static uint32 GenerateNoFlip(const uint8* buf, uint32 bufsize); // Same as Generate(), but without the ~
|
||||
static void SetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at=4);
|
||||
static unsigned long GetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at = 4);
|
||||
|
||||
// Multiple buffer CRC32
|
||||
static uint32 Update(const uint8* buf, uint32 bufsize, uint32 crc32 = 0xFFFFFFFF);
|
||||
|
||||
+1282
-1127
File diff suppressed because it is too large
Load Diff
+139
-151
@@ -18,8 +18,8 @@
|
||||
#ifndef EQEMU_DATABASE_H
|
||||
#define EQEMU_DATABASE_H
|
||||
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
#define AUTHENTICATION_TIMEOUT 60
|
||||
#define INVALID_ID 0xFFFFFFFF
|
||||
|
||||
#include "global_define.h"
|
||||
#include "eqemu_logsys.h"
|
||||
@@ -38,7 +38,8 @@
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
|
||||
namespace EQ {
|
||||
namespace EQ
|
||||
{
|
||||
class InventoryProfile;
|
||||
}
|
||||
|
||||
@@ -51,11 +52,10 @@ struct npcDecayTimes_Struct {
|
||||
|
||||
struct VarCache_Struct {
|
||||
std::map<std::string, std::string> m_cache;
|
||||
uint32 last_update;
|
||||
uint32 last_update;
|
||||
VarCache_Struct() : last_update(0) { }
|
||||
void Add(const std::string& key, const std::string& value) { m_cache[key] = value; }
|
||||
const std::string* Get(const std::string& key)
|
||||
{
|
||||
void Add(const std::string &key, const std::string &value) { m_cache[key] = value; }
|
||||
const std::string *Get(const std::string &key) {
|
||||
auto it = m_cache.find(key);
|
||||
return (it != m_cache.end() ? &it->second : nullptr);
|
||||
}
|
||||
@@ -76,33 +76,37 @@ class PTimerList;
|
||||
|
||||
#define SQL(...) #__VA_ARGS__
|
||||
|
||||
class LogSettings;
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
Database(
|
||||
const std::string& host,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
const std::string& database,
|
||||
uint32 port
|
||||
);
|
||||
bool Connect(
|
||||
const std::string& host,
|
||||
const std::string& user,
|
||||
const std::string& password,
|
||||
const std::string& database,
|
||||
uint32 port,
|
||||
std::string connection_label = "default"
|
||||
);
|
||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port, std::string connection_label = "default");
|
||||
~Database();
|
||||
|
||||
/* Character Creation */
|
||||
bool DeleteCharacter(const std::string& name);
|
||||
bool MoveCharacterToZone(const std::string& name, uint32 zone_id);
|
||||
|
||||
bool CreateCharacter(
|
||||
uint32 account_id,
|
||||
char *name,
|
||||
uint16 gender,
|
||||
uint16 race,
|
||||
uint16 class_,
|
||||
uint8 str,
|
||||
uint8 sta,
|
||||
uint8 cha,
|
||||
uint8 dex,
|
||||
uint8 int_,
|
||||
uint8 agi,
|
||||
uint8 wis,
|
||||
uint8 face
|
||||
);
|
||||
bool DeleteCharacter(char *character_name);
|
||||
bool MoveCharacterToZone(const char *charname, uint32 zone_id);
|
||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||
bool ReserveName(uint32 account_id, const std::string& name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
bool UpdateName(const std::string& old_name, const std::string& new_name);
|
||||
bool ReserveName(uint32 account_id, char *name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||
bool UpdateName(const char *oldname, const char *newname);
|
||||
bool CopyCharacter(
|
||||
const std::string& source_character_name,
|
||||
const std::string& destination_character_name,
|
||||
@@ -110,177 +114,161 @@ public:
|
||||
);
|
||||
|
||||
/* General Information Queries */
|
||||
bool AddBannedIP(const std::string& banned_ip, const std::string& notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(const std::string& name);
|
||||
bool CheckBannedIPs(const std::string& login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(const std::string& login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(const std::string& name, bool surname = false);
|
||||
bool IsNameUsed(const std::string& name);
|
||||
|
||||
uint32 GetAccountIDByChar(const std::string& name, uint32* character_id = 0);
|
||||
uint32 GetAccountIDByChar(uint32 character_id);
|
||||
uint32 GetAccountIDByName(const std::string& account_name, const std::string& loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const std::string& name);
|
||||
uint32 GetGuildIDByCharID(uint32 character_id);
|
||||
uint32 GetGroupIDByCharID(uint32 character_id);
|
||||
uint32 GetRaidIDByCharID(uint32 character_id);
|
||||
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
||||
bool AddToNameFilter(std::string name);
|
||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
||||
bool CheckNameFilter(std::string name, bool surname = false);
|
||||
bool CheckUsedName(std::string name);
|
||||
|
||||
const std::string GetAccountName(uint32 account_id, uint32* lsaccount_id = 0);
|
||||
const std::string GetCharName(uint32 character_id);
|
||||
const std::string GetCharNameByID(uint32 character_id);
|
||||
const std::string GetNPCNameByID(uint32 npc_id);
|
||||
const std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, const std::string& login_ip);
|
||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||
uint32 GetAccountIDByChar(uint32 char_id);
|
||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
||||
uint32 GetCharacterID(const std::string& name);
|
||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||
|
||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||
void GetCharName(uint32 char_id, char* name);
|
||||
std::string GetCharNameByID(uint32 char_id);
|
||||
std::string GetNPCNameByID(uint32 npc_id);
|
||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||
void LoginIP(uint32 account_id, std::string login_ip);
|
||||
|
||||
/* Instancing */
|
||||
|
||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
||||
bool CheckInstanceExists(uint16 instance_id);
|
||||
bool CheckInstanceExpired(uint16 instance_id);
|
||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
||||
bool GetUnusedInstanceID(uint16& instance_id);
|
||||
bool GetUnusedInstanceID(uint16 &instance_id);
|
||||
bool IsGlobalInstance(uint16 instance_id);
|
||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||
bool RemoveClientsFromInstance(uint16 instance_id);
|
||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
||||
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||
|
||||
uint16 GetInstanceID(uint32 zone, uint32 character_id, int16 version);
|
||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
||||
uint8_t GetInstanceVersion(uint16 instance_id);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool& is_perma);
|
||||
uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma);
|
||||
uint32 GetInstanceZoneID(uint16 instance_id);
|
||||
|
||||
void AssignGroupToInstance(uint32 group_id, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 raid_id, uint32 instance_id);
|
||||
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
||||
void DeleteInstance(uint16 instance_id);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32>& character_ids);
|
||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
||||
void PurgeExpiredInstances();
|
||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||
void CleanupInstanceCorpses();
|
||||
|
||||
/* Adventure related. */
|
||||
void UpdateAdventureStatsEntry(uint32 character_id, uint8 theme_id, bool is_win = false, bool is_remove = false);
|
||||
bool GetAdventureStats(uint32 character_id, AdventureStats_Struct* as);
|
||||
|
||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win = false, bool remove = false);
|
||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
||||
|
||||
/* Account Related */
|
||||
const std::string GetLiveChar(uint32 account_id);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 account_id, const std::string& password);
|
||||
bool UpdateLiveChar(const std::string& name, uint32 account_id);
|
||||
int16 GetAccountStatus(uint32 account_id);
|
||||
void SetAccountCRCField(uint32 account_id, const std::string& field_name, uint64 checksum);
|
||||
uint32 CheckLogin(const std::string& name, const std::string& password, const std::string& loginserver, int16* status = 0);
|
||||
uint32 CreateAccount(
|
||||
const std::string& name,
|
||||
const std::string& password,
|
||||
int16 status,
|
||||
const std::string& loginserver,
|
||||
uint32 lsaccount_id
|
||||
);
|
||||
uint32 GetAccountIDFromLSID(
|
||||
const std::string& in_loginserver_id,
|
||||
uint32 in_loginserver_account_id,
|
||||
char* in_account_name = 0,
|
||||
int16* in_status = 0
|
||||
);
|
||||
|
||||
uint8 GetAgreementFlag(uint32 account_id);
|
||||
void SetAgreementFlag(uint32 account_id);
|
||||
bool DeleteAccount(const char *name, const char* loginserver);
|
||||
bool GetLiveChar(uint32 account_id, char* cname);
|
||||
bool SetAccountStatus(const char* name, int16 status);
|
||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
||||
bool SetLocalPassword(uint32 accid, const char* password);
|
||||
bool UpdateLiveChar(char* charname, uint32 account_id);
|
||||
|
||||
int GetIPExemption(const std::string& account_ip);
|
||||
void SetIPExemption(const std::string& account_ip, int exemption_amount);
|
||||
int16 CheckStatus(uint32 account_id);
|
||||
|
||||
int GetInstanceID(uint32 character_id, uint32 zone_id);
|
||||
void SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum);
|
||||
|
||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
||||
uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id);
|
||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||
uint8 GetAgreementFlag(uint32 account_id);
|
||||
|
||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||
void SetAgreementFlag(uint32 account_id);
|
||||
|
||||
int GetIPExemption(std::string account_ip);
|
||||
void SetIPExemption(std::string account_ip, int exemption_amount);
|
||||
|
||||
int GetInstanceID(uint32 char_id, uint32 zone_id);
|
||||
|
||||
|
||||
/* Groups */
|
||||
std::string GetGroupLeaderForLogin(const std::string& character_name);
|
||||
char* GetGroupLeadershipInfo(
|
||||
uint32 group_id,
|
||||
char* leaderbuf,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
char* mentoree = nullptr,
|
||||
int* mentor_percent = nullptr,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr
|
||||
);
|
||||
std::string GetGroupLeaderName(uint32 group_id);
|
||||
uint32 GetGroupID(const std::string& name);
|
||||
void ClearGroup(uint32 group_id = 0);
|
||||
void ClearGroupLeader(uint32 group_id = 0);
|
||||
void SetGroupLeaderName(uint32 group_id, const std::string& name);
|
||||
|
||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
||||
char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
|
||||
uint32 GetGroupID(const char* name);
|
||||
|
||||
void ClearGroup(uint32 gid = 0);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false);
|
||||
void SetGroupLeaderName(uint32 gid, const char* name);
|
||||
|
||||
/* Raids */
|
||||
const std::string GetRaidLeaderName(uint32 raid_id);
|
||||
uint32 GetRaidID(const std::string& name);
|
||||
void ClearRaid(uint32 raid_id = 0);
|
||||
void ClearRaidDetails(uint32 raid_id = 0);
|
||||
void ClearRaidLeader(uint32 group_id = std::numeric_limits<uint32>::max(), uint32 raid_id = 0);
|
||||
void GetGroupLeadershipInfo(
|
||||
uint32 group_id,
|
||||
uint32 raid_id,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
char* mentoree = nullptr,
|
||||
int* mentor_percent = nullptr,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr
|
||||
);
|
||||
void GetRaidLeadershipInfo(
|
||||
uint32 raid_id,
|
||||
char* maintank = nullptr,
|
||||
char* assist = nullptr,
|
||||
char* puller = nullptr,
|
||||
char* marknpc = nullptr,
|
||||
RaidLeadershipAA_Struct* RLAA = nullptr
|
||||
);
|
||||
void SetRaidGroupLeaderInfo(uint32 group_id, uint32 raid_id);
|
||||
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
void ClearGuildOnlineStatus();
|
||||
void ClearTraderDetails();
|
||||
void ClearBuyerDetails();
|
||||
const char *GetRaidLeaderName(uint32 rid);
|
||||
|
||||
uint32 GetRaidID(const char* name);
|
||||
|
||||
void ClearRaid(uint32 rid = 0);
|
||||
void ClearRaidDetails(uint32 rid = 0);
|
||||
void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0);
|
||||
void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr);
|
||||
void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid);
|
||||
|
||||
void PurgeAllDeletedDataBuckets();
|
||||
|
||||
|
||||
/* Database Variables */
|
||||
bool GetVariable(const std::string& name, std::string& value);
|
||||
bool SetVariable(const std::string& name, const std::string& value);
|
||||
bool LoadVariables();
|
||||
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint32 GetServerType();
|
||||
void AddReport(const std::string& who, const std::string& against, const std::string& lines);
|
||||
struct TimeOfDay_Struct LoadTime(time_t& realtime);
|
||||
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||
void ClearMerchantTemp();
|
||||
void ClearPTimers(uint32 character_id);
|
||||
void SetFirstLogon(uint32 character_id, uint8 first_logon);
|
||||
void SetLFG(uint32 character_id, bool is_lfg);
|
||||
void SetLFP(uint32 character_id, bool is_lfp);
|
||||
void SetLoginFlags(uint32 character_id, bool is_lfp, bool is_lfg, uint8 first_logon);
|
||||
bool GetVariable(std::string varname, std::string &varvalue);
|
||||
bool SetVariable(const std::string& varname, const std::string &varvalue);
|
||||
bool LoadVariables();
|
||||
|
||||
int64 CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
/* General Queries */
|
||||
|
||||
void SourceDatabaseTableFromUrl(const std::string& table_name, const std::string& url);
|
||||
void SourceSqlFromUrl(const std::string& url);
|
||||
void PurgeCharacterParcels();
|
||||
void Encode(std::string &in);
|
||||
void Decode(std::string &in);
|
||||
bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0);
|
||||
bool LoadPTimers(uint32 charid, PTimerList &into);
|
||||
|
||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
|
||||
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
||||
uint8 GetServerType();
|
||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||
|
||||
void AddReport(std::string who, std::string against, std::string lines);
|
||||
struct TimeOfDay_Struct LoadTime(time_t &realtime);
|
||||
bool SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year);
|
||||
void ClearMerchantTemp();
|
||||
void ClearPTimers(uint32 charid);
|
||||
void SetFirstLogon(uint32 CharID, uint8 firstlogon);
|
||||
void SetLFG(uint32 CharID, bool LFG);
|
||||
void SetLFP(uint32 CharID, bool LFP);
|
||||
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
|
||||
|
||||
int CountInvSnapshots();
|
||||
void ClearInvSnapshots(bool from_now = false);
|
||||
|
||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||
void SourceSqlFromUrl(std::string url);
|
||||
|
||||
private:
|
||||
Mutex Mvarcache;
|
||||
|
||||
Mutex Mvarcache;
|
||||
VarCache_Struct varcache;
|
||||
|
||||
/* Groups, utility methods. */
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
void ClearAllGroupLeaders();
|
||||
void ClearAllGroups();
|
||||
|
||||
/* Raid, utility methods. */
|
||||
void ClearAllRaids();
|
||||
|
||||
@@ -575,12 +575,7 @@ void DatabaseDumpService::RemoveSqlBackup()
|
||||
{
|
||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
||||
if (File::Exists(file)) {
|
||||
try {
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
LogError("std::filesystem::remove err [{}]", e.what());
|
||||
}
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
|
||||
RemoveCredentialsFile();
|
||||
|
||||
@@ -4947,7 +4947,7 @@ UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `cha
|
||||
.version = 9237,
|
||||
.description = "2023_10_15_import_13th_floor.sql",
|
||||
.check = "SHOW COLUMNS FROM `items` LIKE 'bardeffect';",
|
||||
.condition = "missing",
|
||||
.condition = "contains",
|
||||
.match = "mediumint",
|
||||
.sql = R"(
|
||||
ALTER TABLE `items`
|
||||
@@ -5410,367 +5410,6 @@ ADD COLUMN `augment_five` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_fou
|
||||
ADD COLUMN `augment_six` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9265,
|
||||
.description = "2024_03_03_add_id_to_guild_bank.sql",
|
||||
.check = "SHOW COLUMNS FROM `guild_bank` LIKE 'id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `guild_bank`
|
||||
ADD COLUMN `id` INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
ADD PRIMARY KEY (`id`);
|
||||
)",
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9266,
|
||||
.description = "2024_03_02_rule_values_rule_value_length.sql",
|
||||
.check = "SHOW COLUMNS FROM `rule_values` LIKE 'rule_value'",
|
||||
.condition = "contains",
|
||||
.match = "varchar(30)",
|
||||
.sql = R"(
|
||||
ALTER TABLE `rule_values`
|
||||
MODIFY COLUMN `rule_value` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `rule_name`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9267,
|
||||
.description = "2024_02_18_group_id_bot_id.sql",
|
||||
.check = "SHOW COLUMNS FROM `group_id` LIKE 'bot_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `group_id`
|
||||
CHANGE COLUMN `groupid` `group_id` int(11) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `charid` `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `group_id`,
|
||||
CHANGE COLUMN `ismerc` `merc_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `name`,
|
||||
ADD COLUMN `bot_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `character_id`,
|
||||
MODIFY COLUMN `name` varchar(64) NOT NULL DEFAULT '' AFTER `character_id`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`group_id`, `character_id`, `bot_id`, `merc_id`) USING BTREE;
|
||||
ALTER TABLE `group_id`
|
||||
MODIFY COLUMN `character_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `name`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9268,
|
||||
.description = "2024_03_23_skill_caps.sql",
|
||||
.check = "SHOW COLUMNS FROM `skill_caps` LIKE 'skill_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `skill_caps`
|
||||
CHANGE COLUMN `skillID` `skill_id` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 FIRST,
|
||||
CHANGE COLUMN `class` `class_id` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `skill_id`,
|
||||
ADD COLUMN `id` int(3) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||
ADD INDEX `level_skill_cap`(`skill_id`, `class_id`, `level`, `cap`);
|
||||
)",
|
||||
.content_schema_update = true,
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9269,
|
||||
.description = "2024_03_27_account_auto_login_charname.sql",
|
||||
.check = "SHOW COLUMNS FROM `account` LIKE 'auto_login_charname'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `account`
|
||||
ADD COLUMN `auto_login_charname` varchar(64) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `charname`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9270,
|
||||
.description = "2024_04_31_content_flagging_lootdrop_entries.sql",
|
||||
.check = "SHOW COLUMNS FROM `lootdrop_entries` LIKE 'content_flags'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `lootdrop_entries` ADD `min_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `lootdrop_entries` ADD `max_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `lootdrop_entries` ADD `content_flags` varchar(100) NULL;
|
||||
ALTER TABLE `lootdrop_entries` ADD `content_flags_disabled` varchar(100) NULL;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9271,
|
||||
.description = "2024_03_10_parcel_implementation.sql",
|
||||
.check = "SHOW TABLES LIKE 'character_parcels'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(CREATE TABLE `character_parcels` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`char_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`slot_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`from_name` VARCHAR(64) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
|
||||
`note` VARCHAR(1024) NULL DEFAULT NULL COLLATE 'latin1_swedish_ci',
|
||||
`sent_date` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `data_constraint` (`slot_id`, `char_id`) USING BTREE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9272,
|
||||
.description = "2024_04_23_add_parcel_support_for_augmented_items.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_parcels` LIKE 'aug_slot_1'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_parcels`
|
||||
ADD COLUMN `aug_slot_1` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `item_id`,
|
||||
ADD COLUMN `aug_slot_2` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_1`,
|
||||
ADD COLUMN `aug_slot_3` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_2`,
|
||||
ADD COLUMN `aug_slot_4` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_3`,
|
||||
ADD COLUMN `aug_slot_5` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_4`,
|
||||
ADD COLUMN `aug_slot_6` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_5`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9273,
|
||||
.description = "2024_04_24_door_close_timer.sql",
|
||||
.check = "SHOW COLUMNS FROM `doors` LIKE 'close_timer_ms'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `doors`
|
||||
ADD COLUMN `close_timer_ms` smallint(8) UNSIGNED NOT NULL DEFAULT 5000 AFTER `is_ldon_door`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9274,
|
||||
.description = "2024_05_02_parcel_npc_content.sql",
|
||||
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'is_parcel_merchant'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_types`
|
||||
ADD COLUMN `is_parcel_merchant` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `keeps_sold_items`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9275,
|
||||
.description = "2024_04_28_character_extra_haste.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_data` LIKE 'extra_haste'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_data`
|
||||
ADD COLUMN `extra_haste` int(11) NOT NULL DEFAULT 0 AFTER `wis`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9276,
|
||||
.description = "2024_05_12_fix_guild_bank_dup_issue.sql",
|
||||
.check = "SHOW COLUMNS FROM `guild_bank` WHERE FIELD = 'qty' AND Type LIKE '%unsigned';",
|
||||
.condition = "not_empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `guild_bank`
|
||||
CHANGE COLUMN `qty` `qty` INT(10) NOT NULL DEFAULT '0' AFTER `itemid`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9277,
|
||||
.description = "2024_05_09_parcel_enable_containers.sql",
|
||||
.check = "SHOW TABLES LIKE 'character_parcels_containers'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
CREATE TABLE `character_parcels_containers` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`parcels_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`slot_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_1` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_2` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_3` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_4` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_5` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`aug_slot_6` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `fk_character_parcels_id` (`parcels_id`) USING BTREE,
|
||||
CONSTRAINT `fk_character_parcels_id` FOREIGN KEY (`parcels_id`) REFERENCES `character_parcels` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1
|
||||
;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9278,
|
||||
.description = "2024_05_06_npc_greed.sql",
|
||||
.check = "SHOW COLUMNS FROM `npc_types` LIKE 'greed'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_types`
|
||||
ADD COLUMN `greed` tinyint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `merchant_id`;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9279,
|
||||
.description = "2024_05_13_content_flagging_npc_spells_entries.sql",
|
||||
.check = "SHOW COLUMNS FROM `npc_spells_entries` LIKE 'content_flags'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `npc_spells_entries` ADD `min_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `npc_spells_entries` ADD `max_expansion` tinyint(4) NOT NULL DEFAULT -1;
|
||||
ALTER TABLE `npc_spells_entries` ADD `content_flags` varchar(100) NULL;
|
||||
ALTER TABLE `npc_spells_entries` ADD `content_flags_disabled` varchar(100) NULL;
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9280,
|
||||
.description = "2024_05_11_update_trader_support.sql",
|
||||
.check = "SHOW COLUMNS FROM `trader` LIKE 'aug_slot_1'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `trader`
|
||||
ADD COLUMN `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
CHANGE COLUMN `char_id` `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`,
|
||||
CHANGE COLUMN `item_id` `item_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_id`,
|
||||
ADD COLUMN `aug_slot_1` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `item_id`,
|
||||
ADD COLUMN `aug_slot_2` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_1`,
|
||||
ADD COLUMN `aug_slot_3` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_2`,
|
||||
ADD COLUMN `aug_slot_4` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_3`,
|
||||
ADD COLUMN `aug_slot_5` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_4`,
|
||||
ADD COLUMN `aug_slot_6` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_5`,
|
||||
CHANGE COLUMN `serialnumber` `item_sn` INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `aug_slot_6`,
|
||||
CHANGE COLUMN `charges` `item_charges` INT(11) NOT NULL DEFAULT '0' AFTER `item_sn`,
|
||||
ADD COLUMN `char_entity_id` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `slot_id`,
|
||||
ADD COLUMN `char_zone_id` INT(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `char_entity_id`,
|
||||
ADD COLUMN `active_transaction` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `char_zone_id`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD INDEX `charid_slotid` (`char_id`, `slot_id`);
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9281,
|
||||
.description = "2024_06_24_update_buyer_support.sql",
|
||||
.check = "SHOW COLUMNS FROM `buyer` LIKE 'id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `buyer`
|
||||
ADD COLUMN `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
|
||||
CHANGE COLUMN `charid` `char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `id`,
|
||||
ADD COLUMN `char_entity_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_id`,
|
||||
ADD COLUMN `char_name` VARCHAR(64) NULL DEFAULT NULL AFTER `char_entity_id`,
|
||||
ADD COLUMN `char_zone_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_name`,
|
||||
ADD COLUMN `char_zone_instance_id` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `char_zone_id`,
|
||||
ADD COLUMN `transaction_date` DATETIME NULL DEFAULT NULL AFTER `char_zone_instance_id`,
|
||||
ADD COLUMN `welcome_message` VARCHAR(256) NULL DEFAULT NULL AFTER `transaction_date`,
|
||||
DROP COLUMN `buyslot`,
|
||||
DROP COLUMN `itemid`,
|
||||
DROP COLUMN `itemname`,
|
||||
DROP COLUMN `quantity`,
|
||||
DROP COLUMN `price`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||
ADD INDEX `charid` (`char_id`);
|
||||
|
||||
CREATE TABLE `buyer_buy_lines` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`buyer_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`char_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`buy_slot_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_qty` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_price` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_icon` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_name` VARCHAR(64) NOT NULL DEFAULT '' COLLATE 'latin1_swedish_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `buyerid_charid_buyslotid` (`buyer_id`, `char_id`, `buy_slot_id`) USING BTREE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
|
||||
CREATE TABLE `buyer_trade_items` (
|
||||
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`buyer_buy_lines_id` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`item_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_qty` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_icon` INT(11) NOT NULL DEFAULT '0',
|
||||
`item_name` VARCHAR(64) NOT NULL DEFAULT '0' COLLATE 'latin1_swedish_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
INDEX `buyerbuylinesid` (`buyer_buy_lines_id`) USING BTREE
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9282,
|
||||
.description = "2024_08_02_spell_buckets_comparison.sql",
|
||||
.check = "SHOW COLUMNS FROM `spell_buckets` LIKE 'bucket_comparison'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `spell_buckets`
|
||||
CHANGE COLUMN `spellid` `spell_id` int UNSIGNED NOT NULL FIRST,
|
||||
CHANGE COLUMN `key` `bucket_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `spell_id`,
|
||||
CHANGE COLUMN `value` `bucket_value` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `bucket_name`,
|
||||
ADD COLUMN `bucket_comparison` tinyint UNSIGNED NOT NULL DEFAULT 0 AFTER `bucket_value`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`spell_id`) USING BTREE;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9283,
|
||||
.description = "2024_08_05_fix_client_hotbar",
|
||||
.check = "SHOW COLUMNS FROM `inventory` LIKE 'guid'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `inventory`
|
||||
ADD COLUMN `guid` BIGINT UNSIGNED NULL DEFAULT '0' AFTER `ornament_hero_model`;
|
||||
ALTER TABLE `inventory_snapshots`
|
||||
ADD COLUMN `guid` BIGINT UNSIGNED NULL DEFAULT '0' AFTER `ornament_hero_model`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9284,
|
||||
.description = "2024_10_08_character_exp_modifiers_default.sql",
|
||||
.check = "SHOW CREATE TABLE `character_exp_modifiers`",
|
||||
.condition = "contains",
|
||||
.match = "`exp_modifier` float NOT NULL,",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_exp_modifiers`
|
||||
MODIFY COLUMN `aa_modifier` float NOT NULL DEFAULT 1.0 AFTER `instance_version`,
|
||||
MODIFY COLUMN `exp_modifier` float NOT NULL DEFAULT 1.0 AFTER `aa_modifier`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9285,
|
||||
.description = "2024_11_08_data_buckets_indexes.sql",
|
||||
.check = "SHOW CREATE TABLE `data_buckets`",
|
||||
.condition = "missing",
|
||||
.match = "idx_character_expires",
|
||||
.sql = R"(
|
||||
CREATE INDEX idx_character_expires ON data_buckets (character_id, expires);
|
||||
CREATE INDEX idx_npc_expires ON data_buckets (npc_id, expires);
|
||||
CREATE INDEX idx_bot_expires ON data_buckets (bot_id, expires);
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
|
||||
@@ -139,28 +139,6 @@ ADD COLUMN `augment_three` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_tw
|
||||
ADD COLUMN `augment_four` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_three`,
|
||||
ADD COLUMN `augment_five` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_four`,
|
||||
ADD COLUMN `augment_six` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9044,
|
||||
.description = "2024_04_23_bot_extra_haste.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'extra_haste'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_data`
|
||||
ADD COLUMN `extra_haste` mediumint(8) NOT NULL DEFAULT 0 AFTER `wis`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9045,
|
||||
.description = "2024_08_05_bot_spells_entries_unsigned_spell_id.sql",
|
||||
.check = "SHOW COLUMNS FROM `bot_spells_entries` LIKE 'spell_id'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `bot_spells_entries`
|
||||
CHANGE COLUMN `spellid` `spell_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `npc_spells_id`;
|
||||
)"
|
||||
}
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
|
||||
@@ -421,25 +421,20 @@ void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
||||
auto zone_id = GetInstanceZoneID(instance_id);
|
||||
auto version = GetInstanceVersion(instance_id);
|
||||
|
||||
const auto& l = GroupIdRepository::GetWhere(
|
||||
auto l = GroupIdRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"`group_id` = {}",
|
||||
"groupid = {}",
|
||||
group_id
|
||||
)
|
||||
);
|
||||
|
||||
if (l.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& e : l) {
|
||||
if (!e.character_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!GetInstanceID(zone_id, e.character_id, version)) {
|
||||
AddClientToInstance(instance_id, e.character_id);
|
||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
||||
AddClientToInstance(instance_id, e.charid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -509,7 +504,7 @@ void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 ch
|
||||
return;
|
||||
}
|
||||
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id).c_str());
|
||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
||||
|
||||
if (!raid_leader_instance_id) {
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace DatabaseSchema {
|
||||
{
|
||||
return {
|
||||
{"adventure_stats", "player_id"},
|
||||
{"buyer", "charid"},
|
||||
{"char_recipe_list", "char_id"},
|
||||
{"character_activities", "charid"},
|
||||
{"character_alt_currency", "char_id"},
|
||||
@@ -58,8 +59,6 @@ namespace DatabaseSchema {
|
||||
{"character_leadership_abilities", "id"},
|
||||
{"character_material", "id"},
|
||||
{"character_memmed_spells", "id"},
|
||||
{"character_parcels", "char_id"},
|
||||
{"character_parcels_containers", "id"},
|
||||
{"character_pet_buffs", "char_id"},
|
||||
{"character_pet_info", "char_id"},
|
||||
{"character_pet_inventory", "char_id"},
|
||||
@@ -106,8 +105,6 @@ namespace DatabaseSchema {
|
||||
"adventure_details",
|
||||
"adventure_stats",
|
||||
"buyer",
|
||||
"buyer_buy_lines",
|
||||
"buyer_trade_items",
|
||||
"char_recipe_list",
|
||||
"character_activities",
|
||||
"character_alt_currency",
|
||||
@@ -131,8 +128,6 @@ namespace DatabaseSchema {
|
||||
"character_leadership_abilities",
|
||||
"character_material",
|
||||
"character_memmed_spells",
|
||||
"character_parcels",
|
||||
"character_parcels_containers",
|
||||
"character_pet_buffs",
|
||||
"character_pet_info",
|
||||
"character_pet_inventory",
|
||||
@@ -326,9 +321,6 @@ namespace DatabaseSchema {
|
||||
"banned_ips",
|
||||
"bug_reports",
|
||||
"bugs",
|
||||
"buyer",
|
||||
"buyer_buy_lines",
|
||||
"buyer_trade_items",
|
||||
"completed_shared_task_activity_state",
|
||||
"completed_shared_task_members",
|
||||
"completed_shared_tasks",
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "timer.h"
|
||||
|
||||
#include "dbcore.h"
|
||||
#include "mysql_stmt.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -437,8 +436,3 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
||||
{
|
||||
return mysql::PreparedStmt(*mysql, std::move(query), m_mutex);
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#define CR_SERVER_GONE_ERROR 2006
|
||||
#define CR_SERVER_LOST 2013
|
||||
|
||||
namespace mysql { class PreparedStmt; }
|
||||
|
||||
class DBcore {
|
||||
public:
|
||||
enum eStatus {
|
||||
@@ -50,11 +48,6 @@ public:
|
||||
}
|
||||
void SetMutex(Mutex *mutex);
|
||||
|
||||
// only safe on connections shared with other threads if results buffered
|
||||
// unsafe to use off main thread due to internal server logging
|
||||
// throws std::runtime_error on failure
|
||||
mysql::PreparedStmt Prepare(std::string query);
|
||||
|
||||
protected:
|
||||
bool Open(
|
||||
const char *iHost,
|
||||
|
||||
+70
-6
@@ -19,17 +19,81 @@
|
||||
|
||||
#include "deity.h"
|
||||
|
||||
uint32 Deity::GetBitmask(uint32 deity_id)
|
||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
||||
{
|
||||
return IsValid(deity_id) ? deity_bitmasks[deity_id] : Deity::Bitmask::All;
|
||||
switch (deity_type) {
|
||||
case DeityBertoxxulous:
|
||||
return bit_DeityBertoxxulous;
|
||||
case DeityBrellSirilis:
|
||||
return bit_DeityBrellSirilis;
|
||||
case DeityCazicThule:
|
||||
return bit_DeityCazicThule;
|
||||
case DeityErollisiMarr:
|
||||
return bit_DeityErollisiMarr;
|
||||
case DeityBristlebane:
|
||||
return bit_DeityBristlebane;
|
||||
case DeityInnoruuk:
|
||||
return bit_DeityInnoruuk;
|
||||
case DeityKarana:
|
||||
return bit_DeityKarana;
|
||||
case DeityMithanielMarr:
|
||||
return bit_DeityMithanielMarr;
|
||||
case DeityPrexus:
|
||||
return bit_DeityPrexus;
|
||||
case DeityQuellious:
|
||||
return bit_DeityQuellious;
|
||||
case DeityRallosZek:
|
||||
return bit_DeityRallosZek;
|
||||
case DeityRodcetNife:
|
||||
return bit_DeityRodcetNife;
|
||||
case DeitySolusekRo:
|
||||
return bit_DeitySolusekRo;
|
||||
case DeityTheTribunal:
|
||||
return bit_DeityTheTribunal;
|
||||
case DeityTunare:
|
||||
return bit_DeityTunare;
|
||||
case DeityVeeshan:
|
||||
return bit_DeityVeeshan;
|
||||
case DeityAgnostic_LB:
|
||||
case DeityAgnostic:
|
||||
return bit_DeityAgnostic;
|
||||
default:
|
||||
return bit_DeityAll;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Deity::GetName(uint32 deity_id)
|
||||
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
|
||||
{
|
||||
return IsValid(deity_id) ? deity_names[deity_id] : "UNKNOWN DEITY";
|
||||
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
|
||||
{ DeityAgnostic, "Agnostic" },
|
||||
{ DeityAgnostic_LB, "Agnostic" },
|
||||
{ DeityBertoxxulous, "Bertoxxulous" },
|
||||
{ DeityBrellSirilis, "Brell Serilis" },
|
||||
{ DeityBristlebane, "Bristlebane" },
|
||||
{ DeityCazicThule, "Cazic-Thule" },
|
||||
{ DeityErollisiMarr, "Erollisi Marr" },
|
||||
{ DeityInnoruuk, "Innoruuk" },
|
||||
{ DeityKarana, "Karana" },
|
||||
{ DeityMithanielMarr, "Mithaniel Marr" },
|
||||
{ DeityPrexus, "Prexus" },
|
||||
{ DeityQuellious, "Quellious" },
|
||||
{ DeityRallosZek, "Rallos Zek" },
|
||||
{ DeityRodcetNife, "Rodcet Nife" },
|
||||
{ DeitySolusekRo, "Solusek Ro" },
|
||||
{ DeityTheTribunal, "The Tribunal" },
|
||||
{ DeityTunare, "Tunare" },
|
||||
{ DeityVeeshan, "Veeshan" }
|
||||
};
|
||||
|
||||
return deity_map;
|
||||
}
|
||||
|
||||
bool Deity::IsValid(uint32 deity_id)
|
||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
||||
{
|
||||
return deity_names.find(deity_id) != deity_names.end();
|
||||
|
||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
+52
-85
@@ -23,95 +23,62 @@
|
||||
#include "types.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
namespace Deity {
|
||||
constexpr uint32 Unknown = 0;
|
||||
constexpr uint32 Agnostic1 = 140;
|
||||
constexpr uint32 Bertoxxulous = 201;
|
||||
constexpr uint32 BrellSirilis = 202;
|
||||
constexpr uint32 CazicThule = 203;
|
||||
constexpr uint32 ErollisiMarr = 204;
|
||||
constexpr uint32 Bristlebane = 205;
|
||||
constexpr uint32 Innoruuk = 206;
|
||||
constexpr uint32 Karana = 207;
|
||||
constexpr uint32 MithanielMarr = 208;
|
||||
constexpr uint32 Prexus = 209;
|
||||
constexpr uint32 Quellious = 210;
|
||||
constexpr uint32 RallosZek = 211;
|
||||
constexpr uint32 RodcetNife = 212;
|
||||
constexpr uint32 SolusekRo = 213;
|
||||
constexpr uint32 TheTribunal = 214;
|
||||
constexpr uint32 Tunare = 215;
|
||||
constexpr uint32 Veeshan = 216;
|
||||
constexpr uint32 Agnostic2 = 396;
|
||||
|
||||
namespace Bitmask {
|
||||
constexpr uint32 Agnostic = 1;
|
||||
constexpr uint32 Bertoxxulous = 2;
|
||||
constexpr uint32 BrellSirilis = 4;
|
||||
constexpr uint32 CazicThule = 8;
|
||||
constexpr uint32 ErollisiMarr = 16;
|
||||
constexpr uint32 Bristlebane = 32;
|
||||
constexpr uint32 Innoruuk = 64;
|
||||
constexpr uint32 Karana = 128;
|
||||
constexpr uint32 MithanielMarr = 256;
|
||||
constexpr uint32 Prexus = 512;
|
||||
constexpr uint32 Quellious = 1024;
|
||||
constexpr uint32 RallosZek = 2048;
|
||||
constexpr uint32 RodcetNife = 4096;
|
||||
constexpr uint32 SolusekRo = 8192;
|
||||
constexpr uint32 TheTribunal = 16384;
|
||||
constexpr uint32 Tunare = 32768;
|
||||
constexpr uint32 Veeshan = 65536;
|
||||
constexpr uint32 All = std::numeric_limits<uint32>::max();
|
||||
}
|
||||
namespace EQ
|
||||
{
|
||||
namespace deity {
|
||||
enum DeityType {
|
||||
DeityUnknown = 0,
|
||||
DeityAgnostic_LB = 140,
|
||||
DeityBertoxxulous = 201,
|
||||
DeityBrellSirilis,
|
||||
DeityCazicThule,
|
||||
DeityErollisiMarr,
|
||||
DeityBristlebane,
|
||||
DeityInnoruuk,
|
||||
DeityKarana,
|
||||
DeityMithanielMarr,
|
||||
DeityPrexus,
|
||||
DeityQuellious,
|
||||
DeityRallosZek,
|
||||
DeityRodcetNife,
|
||||
DeitySolusekRo,
|
||||
DeityTheTribunal,
|
||||
DeityTunare,
|
||||
DeityVeeshan,
|
||||
DeityAgnostic = 396
|
||||
};
|
||||
|
||||
uint32 GetBitmask(uint32 deity_id);
|
||||
std::string GetName(uint32 deity_id);
|
||||
bool IsValid(uint32 deity_id);
|
||||
}
|
||||
enum DeityTypeBit : uint32 {
|
||||
bit_DeityAgnostic = 0x00000001,
|
||||
bit_DeityBertoxxulous = 0x00000002,
|
||||
bit_DeityBrellSirilis = 0x00000004,
|
||||
bit_DeityCazicThule = 0x00000008,
|
||||
bit_DeityErollisiMarr = 0x00000010,
|
||||
bit_DeityBristlebane = 0x00000020,
|
||||
bit_DeityInnoruuk = 0x00000040,
|
||||
bit_DeityKarana = 0x00000080,
|
||||
bit_DeityMithanielMarr = 0x00000100,
|
||||
bit_DeityPrexus = 0x00000200,
|
||||
bit_DeityQuellious = 0x00000400,
|
||||
bit_DeityRallosZek = 0x00000800,
|
||||
bit_DeityRodcetNife = 0x00001000,
|
||||
bit_DeitySolusekRo = 0x00002000,
|
||||
bit_DeityTheTribunal = 0x00004000,
|
||||
bit_DeityTunare = 0x00008000,
|
||||
bit_DeityVeeshan = 0x00010000,
|
||||
bit_DeityAll = UINT32_MAX
|
||||
};
|
||||
|
||||
static std::map<uint32, std::string> deity_names = {
|
||||
{ Deity::Agnostic1, "Agnostic" },
|
||||
{ Deity::Agnostic2, "Agnostic" },
|
||||
{ Deity::Bertoxxulous, "Bertoxxulous" },
|
||||
{ Deity::BrellSirilis, "Brell Serilis" },
|
||||
{ Deity::Bristlebane, "Bristlebane" },
|
||||
{ Deity::CazicThule, "Cazic-Thule" },
|
||||
{ Deity::ErollisiMarr, "Erollisi Marr" },
|
||||
{ Deity::Innoruuk, "Innoruuk" },
|
||||
{ Deity::Karana, "Karana" },
|
||||
{ Deity::MithanielMarr, "Mithaniel Marr" },
|
||||
{ Deity::Prexus, "Prexus" },
|
||||
{ Deity::Quellious, "Quellious" },
|
||||
{ Deity::RallosZek, "Rallos Zek" },
|
||||
{ Deity::RodcetNife, "Rodcet Nife" },
|
||||
{ Deity::SolusekRo, "Solusek Ro" },
|
||||
{ Deity::TheTribunal, "The Tribunal" },
|
||||
{ Deity::Tunare, "Tunare" },
|
||||
{ Deity::Veeshan, "Veeshan" }
|
||||
};
|
||||
constexpr int format_as(DeityType type) { return static_cast<int>(type); }
|
||||
|
||||
static std::map<uint32, uint32> deity_bitmasks = {
|
||||
{ Deity::Agnostic1, Deity::Bitmask::Agnostic },
|
||||
{ Deity::Agnostic2, Deity::Bitmask::Agnostic },
|
||||
{ Deity::Bertoxxulous, Deity::Bitmask::Bertoxxulous },
|
||||
{ Deity::BrellSirilis, Deity::Bitmask::BrellSirilis },
|
||||
{ Deity::CazicThule, Deity::Bitmask::CazicThule },
|
||||
{ Deity::ErollisiMarr, Deity::Bitmask::ErollisiMarr },
|
||||
{ Deity::Bristlebane, Deity::Bitmask::Bristlebane },
|
||||
{ Deity::Innoruuk, Deity::Bitmask::Innoruuk },
|
||||
{ Deity::Karana, Deity::Bitmask::Karana },
|
||||
{ Deity::MithanielMarr, Deity::Bitmask::MithanielMarr },
|
||||
{ Deity::Prexus, Deity::Bitmask::Prexus },
|
||||
{ Deity::Quellious, Deity::Bitmask::Quellious },
|
||||
{ Deity::RallosZek, Deity::Bitmask::RallosZek },
|
||||
{ Deity::RodcetNife, Deity::Bitmask::RodcetNife },
|
||||
{ Deity::SolusekRo, Deity::Bitmask::SolusekRo },
|
||||
{ Deity::TheTribunal, Deity::Bitmask::TheTribunal },
|
||||
{ Deity::Tunare, Deity::Bitmask::Tunare },
|
||||
{ Deity::Veeshan, Deity::Bitmask::Veeshan }
|
||||
};
|
||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
||||
extern std::string GetDeityName(DeityType deity_type);
|
||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
||||
|
||||
} /*deity*/
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /* COMMON_DEITY_H */
|
||||
|
||||
+332
-79
@@ -59,40 +59,103 @@ int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
return local_array[inv_type];
|
||||
}
|
||||
|
||||
uint32 Bug::GetID(const std::string& category_name)
|
||||
{
|
||||
for (const auto& e : bug_category_names) {
|
||||
if (e.second == category_name) {
|
||||
return e.first;
|
||||
}
|
||||
const char* EQ::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||
switch (category_id) {
|
||||
case catVideo:
|
||||
return "Video";
|
||||
case catAudio:
|
||||
return "Audio";
|
||||
case catPathing:
|
||||
return "Pathing";
|
||||
case catQuest:
|
||||
return "Quest";
|
||||
case catTradeskills:
|
||||
return "Tradeskills";
|
||||
case catSpellStacking:
|
||||
return "Spell stacking";
|
||||
case catDoorsPortals:
|
||||
return "Doors/Portals";
|
||||
case catItems:
|
||||
return "Items";
|
||||
case catNPC:
|
||||
return "NPC";
|
||||
case catDialogs:
|
||||
return "Dialogs";
|
||||
case catLoNTCG:
|
||||
return "LoN - TCG";
|
||||
case catMercenaries:
|
||||
return "Mercenaries";
|
||||
case catOther:
|
||||
default:
|
||||
return "Other";
|
||||
}
|
||||
}
|
||||
|
||||
EQ::bug::CategoryID EQ::bug::CategoryNameToCategoryID(const char* category_name) {
|
||||
if (!category_name)
|
||||
return catOther;
|
||||
|
||||
if (!strcmp(category_name, "Video"))
|
||||
return catVideo;
|
||||
if (!strcmp(category_name, "Audio"))
|
||||
return catAudio;
|
||||
if (!strcmp(category_name, "Pathing"))
|
||||
return catPathing;
|
||||
if (!strcmp(category_name, "Quest"))
|
||||
return catQuest;
|
||||
if (!strcmp(category_name, "Tradeskills"))
|
||||
return catTradeskills;
|
||||
if (!strcmp(category_name, "Spell stacking"))
|
||||
return catSpellStacking;
|
||||
if (!strcmp(category_name, "Doors/Portals"))
|
||||
return catDoorsPortals;
|
||||
if (!strcmp(category_name, "Items"))
|
||||
return catItems;
|
||||
if (!strcmp(category_name, "NPC"))
|
||||
return catNPC;
|
||||
if (!strcmp(category_name, "Dialogs"))
|
||||
return catDialogs;
|
||||
if (!strcmp(category_name, "LoN - TCG"))
|
||||
return catLoNTCG;
|
||||
if (!strcmp(category_name, "Mercenaries"))
|
||||
return catMercenaries;
|
||||
|
||||
return catOther;
|
||||
}
|
||||
|
||||
const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
||||
switch (stance_type) {
|
||||
case stanceUnknown:
|
||||
return "Unknown";
|
||||
case stancePassive:
|
||||
return "Passive";
|
||||
case stanceBalanced:
|
||||
return "Balanced";
|
||||
case stanceEfficient:
|
||||
return "Efficient";
|
||||
case stanceReactive:
|
||||
return "Reactive";
|
||||
case stanceAggressive:
|
||||
return "Aggressive";
|
||||
case stanceAssist:
|
||||
return "Assist";
|
||||
case stanceBurn:
|
||||
return "Burn";
|
||||
case stanceEfficient2:
|
||||
return "Efficient2";
|
||||
case stanceBurnAE:
|
||||
return "BurnAE";
|
||||
default:
|
||||
return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
||||
return (stance_type - EQ::constants::stancePassive);
|
||||
}
|
||||
|
||||
return Bug::Category::Other;
|
||||
}
|
||||
|
||||
std::string Bug::GetName(uint32 category_id)
|
||||
{
|
||||
return IsValid(category_id) ? bug_category_names[category_id] : "UNKNOWN BUG CATEGORY";
|
||||
}
|
||||
|
||||
bool Bug::IsValid(uint32 category_id)
|
||||
{
|
||||
return bug_category_names.find(category_id) != bug_category_names.end();
|
||||
}
|
||||
|
||||
std::string Stance::GetName(uint8 stance_id)
|
||||
{
|
||||
return IsValid(stance_id) ? stance_names[stance_id] : "UNKNOWN STANCE";
|
||||
}
|
||||
|
||||
bool Stance::IsValid(uint8 stance_id)
|
||||
{
|
||||
return stance_names.find(stance_id) != stance_names.end();
|
||||
}
|
||||
|
||||
uint8 Stance::GetIndex(uint8 stance_id)
|
||||
{
|
||||
return IsValid(stance_id) ? (stance_id - Stance::Passive) : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
|
||||
@@ -186,6 +249,102 @@ std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||
}
|
||||
|
||||
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
|
||||
{
|
||||
static const std::map<bodyType, std::string> bodytype_map = {
|
||||
{ BT_Humanoid, "Humanoid" },
|
||||
{ BT_Lycanthrope, "Lycanthrope" },
|
||||
{ BT_Undead, "Undead" },
|
||||
{ BT_Giant, "Giant" },
|
||||
{ BT_Construct, "Construct" },
|
||||
{ BT_Extraplanar, "Extraplanar" },
|
||||
{ BT_Magical, "Magical" },
|
||||
{ BT_SummonedUndead, "Summoned Undead" },
|
||||
{ BT_RaidGiant, "Raid Giant" },
|
||||
{ BT_RaidColdain, "Raid Coldain" },
|
||||
{ BT_NoTarget, "Untargetable" },
|
||||
{ BT_Vampire, "Vampire" },
|
||||
{ BT_Atenha_Ra, "Aten Ha Ra" },
|
||||
{ BT_Greater_Akheva, "Greater Akheva" },
|
||||
{ BT_Khati_Sha, "Khati Sha" },
|
||||
{ BT_Seru, "Seru" },
|
||||
{ BT_Grieg_Veneficus, "Grieg Veneficus" },
|
||||
{ BT_Draz_Nurakk, "Draz Nurakk" },
|
||||
{ BT_Zek, "Zek" },
|
||||
{ BT_Luggald, "Luggald" },
|
||||
{ BT_Animal, "Animal" },
|
||||
{ BT_Insect, "Insect" },
|
||||
{ BT_Monster, "Monster" },
|
||||
{ BT_Summoned, "Summoned" },
|
||||
{ BT_Plant, "Plant" },
|
||||
{ BT_Dragon, "Dragon" },
|
||||
{ BT_Summoned2, "Summoned 2" },
|
||||
{ BT_Summoned3, "Summoned 3" },
|
||||
{ BT_Dragon2, "Dragon 2" },
|
||||
{ BT_VeliousDragon, "Velious Dragon" },
|
||||
{ BT_Familiar, "Familiar" },
|
||||
{ BT_Dragon3, "Dragon 3" },
|
||||
{ BT_Boxes, "Boxes" },
|
||||
{ BT_Muramite, "Muramite" },
|
||||
{ BT_NoTarget2, "Untargetable 2" },
|
||||
{ BT_SwarmPet, "Swarm Pet" },
|
||||
{ BT_MonsterSummon, "Monster Summon" },
|
||||
{ BT_InvisMan, "Invisible Man" },
|
||||
{ BT_Special, "Special" },
|
||||
};
|
||||
|
||||
return bodytype_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
|
||||
{
|
||||
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
|
||||
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> account_status_map = {
|
||||
{ AccountStatus::Player, "Player" },
|
||||
{ AccountStatus::Steward, "Steward" },
|
||||
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
|
||||
{ AccountStatus::Guide, "Guide" },
|
||||
{ AccountStatus::QuestTroupe, "Quest Troupe" },
|
||||
{ AccountStatus::SeniorGuide, "Senior Guide" },
|
||||
{ AccountStatus::GMTester, "GM Tester" },
|
||||
{ AccountStatus::EQSupport, "EQ Support" },
|
||||
{ AccountStatus::GMStaff, "GM Staff" },
|
||||
{ AccountStatus::GMAdmin, "GM Admin" },
|
||||
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
|
||||
{ AccountStatus::QuestMaster, "Quest Master" },
|
||||
{ AccountStatus::GMAreas, "GM Areas" },
|
||||
{ AccountStatus::GMCoder, "GM Coder" },
|
||||
{ AccountStatus::GMMgmt, "GM Mgmt" },
|
||||
{ AccountStatus::GMImpossible, "GM Impossible" },
|
||||
{ AccountStatus::Max, "GM Max" }
|
||||
};
|
||||
|
||||
return account_status_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
|
||||
{
|
||||
for (
|
||||
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
|
||||
status_level != EQ::constants::GetAccountStatusMap().rend();
|
||||
++status_level
|
||||
) {
|
||||
if (account_status >= status_level->first) {
|
||||
return status_level->second;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> consider_level_map = {
|
||||
@@ -276,6 +435,84 @@ std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||
}
|
||||
|
||||
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
||||
{
|
||||
static const std::map<int, std::string> object_type_map = {
|
||||
{ ObjectTypes::SmallBag, "Small Bag" },
|
||||
{ ObjectTypes::LargeBag, "Large Bag" },
|
||||
{ ObjectTypes::Quiver, "Quiver" },
|
||||
{ ObjectTypes::BeltPouch, "Belt Pouch" },
|
||||
{ ObjectTypes::WristPouch, "Wrist Pouch" },
|
||||
{ ObjectTypes::Backpack, "Backpack" },
|
||||
{ ObjectTypes::SmallChest, "Small Chest" },
|
||||
{ ObjectTypes::LargeChest, "Large Chest" },
|
||||
{ ObjectTypes::Bandolier, "Bandolier" },
|
||||
{ ObjectTypes::Medicine, "Medicine" },
|
||||
{ ObjectTypes::Tinkering, "Tinkering" },
|
||||
{ ObjectTypes::Lexicon, "Lexicon" },
|
||||
{ ObjectTypes::PoisonMaking, "Mortar and Pestle" },
|
||||
{ ObjectTypes::Quest, "Quest" },
|
||||
{ ObjectTypes::MixingBowl, "Mixing Bowl" },
|
||||
{ ObjectTypes::Baking, "Baking" },
|
||||
{ ObjectTypes::Tailoring, "Tailoring" },
|
||||
{ ObjectTypes::Blacksmithing, "Blacksmithing" },
|
||||
{ ObjectTypes::Fletching, "Fletching" },
|
||||
{ ObjectTypes::Brewing, "Brewing" },
|
||||
{ ObjectTypes::JewelryMaking, "Jewelry Making" },
|
||||
{ ObjectTypes::Pottery, "Pottery" },
|
||||
{ ObjectTypes::Kiln, "Kiln" },
|
||||
{ ObjectTypes::KeyMaker, "Key Maker" },
|
||||
{ ObjectTypes::ResearchWIZ, "Lexicon" },
|
||||
{ ObjectTypes::ResearchMAG, "Lexicon" },
|
||||
{ ObjectTypes::ResearchNEC, "Lexicon" },
|
||||
{ ObjectTypes::ResearchENC, "Lexicon" },
|
||||
{ ObjectTypes::Unknown, "Unknown" },
|
||||
{ ObjectTypes::ResearchPractice, "Lexicon" },
|
||||
{ ObjectTypes::Alchemy, "Alchemy" },
|
||||
{ ObjectTypes::HighElfForge, "High Elf Forge" },
|
||||
{ ObjectTypes::DarkElfForge, "Dark Elf Forge" },
|
||||
{ ObjectTypes::OgreForge, "Ogre Forge" },
|
||||
{ ObjectTypes::DwarfForge, "Dwarf Forge" },
|
||||
{ ObjectTypes::GnomeForge, "Gnome Forge" },
|
||||
{ ObjectTypes::BarbarianForge, "Barbarian Forge" },
|
||||
{ ObjectTypes::IksarForge, "Iksar Forge" },
|
||||
{ ObjectTypes::HumanForgeOne, "Human Forge" },
|
||||
{ ObjectTypes::HumanForgeTwo, "Human Forge" },
|
||||
{ ObjectTypes::HalflingTailoringOne, "Halfling Tailoring" },
|
||||
{ ObjectTypes::HalflingTailoringTwo, "Halfling Tailoring" },
|
||||
{ ObjectTypes::EruditeTailoring, "Erudite Tailoring" },
|
||||
{ ObjectTypes::WoodElfTailoring, "Wood Elf Tailoring" },
|
||||
{ ObjectTypes::WoodElfFletching, "Wood Elf Fletching" },
|
||||
{ ObjectTypes::IksarPottery, "Iksar Pottery" },
|
||||
{ ObjectTypes::Fishing, "Fishing" },
|
||||
{ ObjectTypes::TrollForge, "Troll Forge" },
|
||||
{ ObjectTypes::WoodElfForge, "Wood Elf Forge" },
|
||||
{ ObjectTypes::HalflingForge, "Halfling Forge" },
|
||||
{ ObjectTypes::EruditeForge, "Erudite Forge" },
|
||||
{ ObjectTypes::Merchant, "Merchant" },
|
||||
{ ObjectTypes::FroglokForge, "Froglok Forge" },
|
||||
{ ObjectTypes::Augmenter, "Augmenter" },
|
||||
{ ObjectTypes::Churn, "Churn" },
|
||||
{ ObjectTypes::TransformationMold, "Transformation Mold" },
|
||||
{ ObjectTypes::DetransformationMold, "Detransformation Mold" },
|
||||
{ ObjectTypes::Unattuner, "Unattuner" },
|
||||
{ ObjectTypes::TradeskillBag, "Tradeskill Bag" },
|
||||
{ ObjectTypes::CollectibleBag, "Collectible Bag" },
|
||||
{ ObjectTypes::NoDeposit, "No Deposit" }
|
||||
};
|
||||
|
||||
return object_type_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetObjectTypeName(int object_type)
|
||||
{
|
||||
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||
}
|
||||
|
||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||
{
|
||||
static const std::map<uint8, std::string> weather_type_map = {
|
||||
@@ -403,59 +640,75 @@ std::string EQ::constants::GetAppearanceTypeName(uint32 appearance_type)
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string SpecialAbility::GetName(int ability_id)
|
||||
const std::map<uint32, std::string>& EQ::constants::GetSpecialAbilityMap()
|
||||
{
|
||||
return IsValid(ability_id) ? special_ability_names[ability_id] : "UNKNOWN SPECIAL ABILITY";
|
||||
}
|
||||
|
||||
bool SpecialAbility::IsValid(int ability_id)
|
||||
{
|
||||
return special_ability_names.find(ability_id) != special_ability_names.end();
|
||||
}
|
||||
|
||||
const std::map<uint32, std::string>& EQ::constants::GetConsiderColorMap()
|
||||
{
|
||||
static const std::map<uint32, std::string> consider_color_map = {
|
||||
{ ConsiderColor::Green, "Green" },
|
||||
{ ConsiderColor::DarkBlue, "Dark Blue" },
|
||||
{ ConsiderColor::Gray, "Gray" },
|
||||
{ ConsiderColor::White, "White" },
|
||||
{ ConsiderColor::Red, "Red" },
|
||||
{ ConsiderColor::Yellow, "Yellow" },
|
||||
{ ConsiderColor::LightBlue, "Light Blue" },
|
||||
{ ConsiderColor::WhiteTitanium, "White" },
|
||||
static const std::map<uint32, std::string> special_ability_map = {
|
||||
{ SPECATK_SUMMON, "Summon" },
|
||||
{ SPECATK_ENRAGE, "Enrage" },
|
||||
{ SPECATK_RAMPAGE, "Rampage" },
|
||||
{ SPECATK_AREA_RAMPAGE, "Area Rampage" },
|
||||
{ SPECATK_FLURRY, "Flurry" },
|
||||
{ SPECATK_TRIPLE, "Triple Attack" },
|
||||
{ SPECATK_QUAD, "Quadruple Attack" },
|
||||
{ SPECATK_INNATE_DW, "Dual Wield" },
|
||||
{ SPECATK_BANE, "Bane Attack" },
|
||||
{ SPECATK_MAGICAL, "Magical Attack" },
|
||||
{ SPECATK_RANGED_ATK, "Ranged Attack" },
|
||||
{ UNSLOWABLE, "Immune to Slow" },
|
||||
{ UNMEZABLE, "Immune to Mesmerize" },
|
||||
{ UNCHARMABLE, "Immune to Charm" },
|
||||
{ UNSTUNABLE, "Immune to Stun" },
|
||||
{ UNSNAREABLE, "Immune to Snare" },
|
||||
{ UNFEARABLE, "Immune to Fear" },
|
||||
{ UNDISPELLABLE, "Immune to Dispell" },
|
||||
{ IMMUNE_MELEE, "Immune to Melee" },
|
||||
{ IMMUNE_MAGIC, "Immune to Magic" },
|
||||
{ IMMUNE_FLEEING, "Immune to Fleeing" },
|
||||
{ IMMUNE_MELEE_EXCEPT_BANE, "Immune to Melee except Bane" },
|
||||
{ IMMUNE_MELEE_NONMAGICAL, "Immune to Non-Magical Melee" },
|
||||
{ IMMUNE_AGGRO, "Immune to Aggro" },
|
||||
{ IMMUNE_AGGRO_ON, "Immune to Being Aggro" },
|
||||
{ IMMUNE_CASTING_FROM_RANGE, "Immune to Ranged Spells" },
|
||||
{ IMMUNE_FEIGN_DEATH, "Immune to Feign Death" },
|
||||
{ IMMUNE_TAUNT, "Immune to Taunt" },
|
||||
{ NPC_TUNNELVISION, "Tunnel Vision" },
|
||||
{ NPC_NO_BUFFHEAL_FRIENDS, "Does Not Heal of Buff Allies" },
|
||||
{ IMMUNE_PACIFY, "Immune to Pacify" },
|
||||
{ LEASH, "Leashed" },
|
||||
{ TETHER, "Tethered" },
|
||||
{ DESTRUCTIBLE_OBJECT, "Destructible Object" },
|
||||
{ NO_HARM_FROM_CLIENT, "Immune to Harm from Client" },
|
||||
{ ALWAYS_FLEE, "Always Flees" },
|
||||
{ FLEE_PERCENT, "Flee Percentage" },
|
||||
{ ALLOW_BENEFICIAL, "Allows Beneficial Spells" },
|
||||
{ DISABLE_MELEE, "Melee is Disabled" },
|
||||
{ NPC_CHASE_DISTANCE, "Chase Distance" },
|
||||
{ ALLOW_TO_TANK, "Allowed to Tank" },
|
||||
{ IGNORE_ROOT_AGGRO_RULES, "Ignores Root Aggro" },
|
||||
{ CASTING_RESIST_DIFF, "Casting Resist Difficulty" },
|
||||
{ COUNTER_AVOID_DAMAGE, "Counter Damage Avoidance" },
|
||||
{ PROX_AGGRO, "Proximity Aggro" },
|
||||
{ IMMUNE_RANGED_ATTACKS, "Immune to Ranged Attacks" },
|
||||
{ IMMUNE_DAMAGE_CLIENT, "Immune to Client Damage" },
|
||||
{ IMMUNE_DAMAGE_NPC, "Immune to NPC Damage" },
|
||||
{ IMMUNE_AGGRO_CLIENT, "Immune to Client Aggro" },
|
||||
{ IMMUNE_AGGRO_NPC, "Immune to NPC Aggro" },
|
||||
{ MODIFY_AVOID_DAMAGE, "Modify Damage Avoidance" },
|
||||
{ IMMUNE_FADING_MEMORIES, "Immune to Memory Fades" },
|
||||
{ IMMUNE_OPEN, "Immune to Open" },
|
||||
{ IMMUNE_ASSASSINATE, "Immune to Assassinate" },
|
||||
{ IMMUNE_HEADSHOT, "Immune to Headshot" },
|
||||
};
|
||||
|
||||
return consider_color_map;
|
||||
return special_ability_map;
|
||||
}
|
||||
|
||||
std::string EQ::constants::GetConsiderColorName(uint32 consider_color)
|
||||
std::string EQ::constants::GetSpecialAbilityName(uint32 ability_id)
|
||||
{
|
||||
const auto& c = EQ::constants::GetConsiderColorMap().find(consider_color);
|
||||
return c != EQ::constants::GetConsiderColorMap().end() ? c->second : std::string();
|
||||
}
|
||||
|
||||
std::string AccountStatus::GetName(uint8 account_status)
|
||||
{
|
||||
for (
|
||||
auto e = account_status_names.rbegin();
|
||||
e != account_status_names.rend();
|
||||
++e
|
||||
) {
|
||||
if (account_status >= e->first) {
|
||||
return e->second;
|
||||
}
|
||||
const auto& a = EQ::constants::GetSpecialAbilityMap().find(ability_id);
|
||||
if (a != EQ::constants::GetSpecialAbilityMap().end()) {
|
||||
return a->second;
|
||||
}
|
||||
|
||||
return "UNKNOWN ACCOUNT STATUS";
|
||||
}
|
||||
|
||||
std::string ComparisonType::GetName(uint8 type)
|
||||
{
|
||||
return IsValid(type) ? comparison_types[type] : "UNKNOWN COMPARISON TYPE";
|
||||
}
|
||||
|
||||
bool ComparisonType::IsValid(uint8 type)
|
||||
{
|
||||
return comparison_types.find(type) != comparison_types.end();
|
||||
return std::string();
|
||||
}
|
||||
|
||||
+218
-296
@@ -26,76 +26,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace AccountStatus {
|
||||
constexpr uint8 Player = 0;
|
||||
constexpr uint8 Steward = 10;
|
||||
constexpr uint8 ApprenticeGuide = 20;
|
||||
constexpr uint8 Guide = 50;
|
||||
constexpr uint8 QuestTroupe = 80;
|
||||
constexpr uint8 SeniorGuide = 81;
|
||||
constexpr uint8 GMTester = 85;
|
||||
constexpr uint8 EQSupport = 90;
|
||||
constexpr uint8 GMStaff = 95;
|
||||
constexpr uint8 GMAdmin = 100;
|
||||
constexpr uint8 GMLeadAdmin = 150;
|
||||
constexpr uint8 QuestMaster = 160;
|
||||
constexpr uint8 GMAreas = 170;
|
||||
constexpr uint8 GMCoder = 180;
|
||||
constexpr uint8 GMMgmt = 200;
|
||||
constexpr uint8 GMImpossible = 250;
|
||||
constexpr uint8 Max = 255;
|
||||
|
||||
std::string GetName(uint8 account_status);
|
||||
}
|
||||
|
||||
static std::map<uint8, std::string> account_status_names = {
|
||||
{ AccountStatus::Player, "Player" },
|
||||
{ AccountStatus::Steward, "Steward" },
|
||||
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
|
||||
{ AccountStatus::Guide, "Guide" },
|
||||
{ AccountStatus::QuestTroupe, "Quest Troupe" },
|
||||
{ AccountStatus::SeniorGuide, "Senior Guide" },
|
||||
{ AccountStatus::GMTester, "GM Tester" },
|
||||
{ AccountStatus::EQSupport, "EQ Support" },
|
||||
{ AccountStatus::GMStaff, "GM Staff" },
|
||||
{ AccountStatus::GMAdmin, "GM Admin" },
|
||||
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
|
||||
{ AccountStatus::QuestMaster, "Quest Master" },
|
||||
{ AccountStatus::GMAreas, "GM Areas" },
|
||||
{ AccountStatus::GMCoder, "GM Coder" },
|
||||
{ AccountStatus::GMMgmt, "GM Mgmt" },
|
||||
{ AccountStatus::GMImpossible, "GM Impossible" },
|
||||
{ AccountStatus::Max, "GM Max" }
|
||||
};
|
||||
|
||||
namespace ComparisonType {
|
||||
constexpr uint8 Equal = 0;
|
||||
constexpr uint8 NotEqual = 1;
|
||||
constexpr uint8 GreaterOrEqual = 2;
|
||||
constexpr uint8 LesserOrEqual = 3;
|
||||
constexpr uint8 Greater = 4;
|
||||
constexpr uint8 Lesser = 5;
|
||||
constexpr uint8 Any = 6;
|
||||
constexpr uint8 NotAny = 7;
|
||||
constexpr uint8 Between = 8;
|
||||
constexpr uint8 NotBetween = 9;
|
||||
|
||||
std::string GetName(uint8 type);
|
||||
bool IsValid(uint8 type);
|
||||
}
|
||||
|
||||
static std::map<uint8, std::string> comparison_types = {
|
||||
{ ComparisonType::Equal, "Equal" },
|
||||
{ ComparisonType::NotEqual, "Not Equal" },
|
||||
{ ComparisonType::GreaterOrEqual, "Greater or Equal" },
|
||||
{ ComparisonType::LesserOrEqual, "Lesser or Equal" },
|
||||
{ ComparisonType::Greater, "Greater" },
|
||||
{ ComparisonType::Lesser, "Lesser" },
|
||||
{ ComparisonType::Any, "Any" },
|
||||
{ ComparisonType::NotAny, "Not Any" },
|
||||
{ ComparisonType::Between, "Between" },
|
||||
{ ComparisonType::NotBetween, "Not Between" },
|
||||
};
|
||||
|
||||
// local definitions are the result of using hybrid-client or server-only values and methods
|
||||
namespace EQ
|
||||
@@ -274,6 +204,19 @@ namespace EQ
|
||||
const size_t SAY_LINK_CLOSER_SIZE = 1;
|
||||
const size_t SAY_LINK_MAXIMUM_SIZE = (SAY_LINK_OPENER_SIZE + SAY_LINK_BODY_SIZE + SAY_LINK_TEXT_SIZE + SAY_LINK_CLOSER_SIZE);
|
||||
|
||||
enum StanceType : int {
|
||||
stanceUnknown = 0,
|
||||
stancePassive,
|
||||
stanceBalanced,
|
||||
stanceEfficient,
|
||||
stanceReactive,
|
||||
stanceAggressive,
|
||||
stanceAssist,
|
||||
stanceBurn,
|
||||
stanceEfficient2,
|
||||
stanceBurnAE
|
||||
};
|
||||
|
||||
enum BotSpellIDs : int {
|
||||
Warrior = 3001,
|
||||
Cleric,
|
||||
@@ -324,6 +267,70 @@ namespace EQ
|
||||
Looting
|
||||
};
|
||||
|
||||
enum ObjectTypes : int {
|
||||
SmallBag,
|
||||
LargeBag,
|
||||
Quiver,
|
||||
BeltPouch,
|
||||
WristPouch,
|
||||
Backpack,
|
||||
SmallChest,
|
||||
LargeChest,
|
||||
Bandolier,
|
||||
Medicine,
|
||||
Tinkering,
|
||||
Lexicon,
|
||||
PoisonMaking,
|
||||
Quest,
|
||||
MixingBowl,
|
||||
Baking,
|
||||
Tailoring,
|
||||
Blacksmithing,
|
||||
Fletching,
|
||||
Brewing,
|
||||
JewelryMaking,
|
||||
Pottery,
|
||||
Kiln,
|
||||
KeyMaker,
|
||||
ResearchWIZ,
|
||||
ResearchMAG,
|
||||
ResearchNEC,
|
||||
ResearchENC,
|
||||
Unknown,
|
||||
ResearchPractice,
|
||||
Alchemy,
|
||||
HighElfForge,
|
||||
DarkElfForge,
|
||||
OgreForge,
|
||||
DwarfForge,
|
||||
GnomeForge,
|
||||
BarbarianForge,
|
||||
IksarForge,
|
||||
HumanForgeOne,
|
||||
HumanForgeTwo,
|
||||
HalflingTailoringOne,
|
||||
HalflingTailoringTwo,
|
||||
EruditeTailoring,
|
||||
WoodElfTailoring,
|
||||
WoodElfFletching,
|
||||
IksarPottery,
|
||||
Fishing,
|
||||
TrollForge,
|
||||
WoodElfForge,
|
||||
HalflingForge,
|
||||
EruditeForge,
|
||||
Merchant,
|
||||
FroglokForge,
|
||||
Augmenter,
|
||||
Churn,
|
||||
TransformationMold,
|
||||
DetransformationMold,
|
||||
Unattuner,
|
||||
TradeskillBag,
|
||||
CollectibleBag,
|
||||
NoDeposit
|
||||
};
|
||||
|
||||
enum WeatherTypes : uint8 {
|
||||
None,
|
||||
Raining,
|
||||
@@ -349,6 +356,9 @@ namespace EQ
|
||||
Proximity
|
||||
};
|
||||
|
||||
const char *GetStanceName(StanceType stance_type);
|
||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetLanguageMap();
|
||||
std::string GetLanguageName(uint8 language_id);
|
||||
|
||||
@@ -358,6 +368,12 @@ namespace EQ
|
||||
extern const std::map<int8, std::string>& GetFlyModeMap();
|
||||
std::string GetFlyModeName(int8 flymode_id);
|
||||
|
||||
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
|
||||
std::string GetBodyTypeName(bodyType bodytype_id);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetAccountStatusMap();
|
||||
std::string GetAccountStatusName(uint8 account_status);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
|
||||
std::string GetConsiderLevelName(uint8 consider_level);
|
||||
|
||||
@@ -370,6 +386,9 @@ namespace EQ
|
||||
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
|
||||
std::string GetSpawnAnimationName(uint8 animation_id);
|
||||
|
||||
extern const std::map<int, std::string>& GetObjectTypeMap();
|
||||
std::string GetObjectTypeName(int object_type);
|
||||
|
||||
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
|
||||
std::string GetWeatherTypeName(uint8 weather_type);
|
||||
|
||||
@@ -382,8 +401,12 @@ namespace EQ
|
||||
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
||||
std::string GetAppearanceTypeName(uint32 animation_type);
|
||||
|
||||
extern const std::map<uint32, std::string>& GetConsiderColorMap();
|
||||
std::string GetConsiderColorName(uint32 consider_color);
|
||||
extern const std::map<uint32, std::string>& GetSpecialAbilityMap();
|
||||
std::string GetSpecialAbilityName(uint32 ability_id);
|
||||
|
||||
const int STANCE_TYPE_FIRST = stancePassive;
|
||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
@@ -438,6 +461,37 @@ namespace EQ
|
||||
|
||||
} // namespace spells
|
||||
|
||||
namespace bug {
|
||||
enum CategoryID : uint32 {
|
||||
catOther = 0,
|
||||
catVideo,
|
||||
catAudio,
|
||||
catPathing,
|
||||
catQuest,
|
||||
catTradeskills,
|
||||
catSpellStacking,
|
||||
catDoorsPortals,
|
||||
catItems,
|
||||
catNPC,
|
||||
catDialogs,
|
||||
catLoNTCG,
|
||||
catMercenaries
|
||||
};
|
||||
|
||||
enum OptionalInfoFlag : uint32 {
|
||||
infoNoOptionalInfo = 0x0,
|
||||
infoCanDuplicate = 0x1,
|
||||
infoCrashBug = 0x2,
|
||||
infoTargetInfo = 0x4,
|
||||
infoCharacterFlags = 0x8,
|
||||
infoUnknownValue = 0xFFFFFFF0
|
||||
};
|
||||
|
||||
const char* CategoryIDToCategoryName(CategoryID category_id);
|
||||
CategoryID CategoryNameToCategoryID(const char* category_name);
|
||||
|
||||
} // namespace bug
|
||||
|
||||
enum WaypointStatus : int {
|
||||
RoamBoxPauseInProgress = -3,
|
||||
QuestControlNoGrid = -2,
|
||||
@@ -451,7 +505,7 @@ namespace EQ
|
||||
Raid,
|
||||
Guild
|
||||
};
|
||||
};
|
||||
}; // namespace consent
|
||||
} /*EQEmu*/
|
||||
|
||||
enum ServerLockType : int {
|
||||
@@ -460,6 +514,26 @@ enum ServerLockType : int {
|
||||
Unlock
|
||||
};
|
||||
|
||||
enum AccountStatus : uint8 {
|
||||
Player = 0,
|
||||
Steward = 10,
|
||||
ApprenticeGuide = 20,
|
||||
Guide = 50,
|
||||
QuestTroupe = 80,
|
||||
SeniorGuide = 81,
|
||||
GMTester = 85,
|
||||
EQSupport = 90,
|
||||
GMStaff = 95,
|
||||
GMAdmin = 100,
|
||||
GMLeadAdmin = 150,
|
||||
QuestMaster = 160,
|
||||
GMAreas = 170,
|
||||
GMCoder = 180,
|
||||
GMMgmt = 200,
|
||||
GMImpossible = 250,
|
||||
Max = 255
|
||||
};
|
||||
|
||||
enum Invisibility : uint8 {
|
||||
Visible,
|
||||
Invisible,
|
||||
@@ -485,17 +559,6 @@ enum ConsiderLevel : uint8 {
|
||||
Scowls
|
||||
};
|
||||
|
||||
namespace ConsiderColor {
|
||||
constexpr uint32 Green = 2;
|
||||
constexpr uint32 DarkBlue = 4;
|
||||
constexpr uint32 Gray = 6;
|
||||
constexpr uint32 White = 10;
|
||||
constexpr uint32 Red = 13;
|
||||
constexpr uint32 Yellow = 15;
|
||||
constexpr uint32 LightBlue = 18;
|
||||
constexpr uint32 WhiteTitanium = 20;
|
||||
};
|
||||
|
||||
enum TargetDescriptionType : uint8 {
|
||||
LCSelf,
|
||||
UCSelf,
|
||||
@@ -511,6 +574,19 @@ enum ReloadWorld : uint8 {
|
||||
ForceRepop
|
||||
};
|
||||
|
||||
enum BucketComparison : uint8 {
|
||||
BucketEqualTo = 0,
|
||||
BucketNotEqualTo,
|
||||
BucketGreaterThanOrEqualTo,
|
||||
BucketLesserThanOrEqualTo,
|
||||
BucketGreaterThan,
|
||||
BucketLesserThan,
|
||||
BucketIsAny,
|
||||
BucketIsNotAny,
|
||||
BucketIsBetween,
|
||||
BucketIsNotBetween
|
||||
};
|
||||
|
||||
enum class EntityFilterType {
|
||||
All,
|
||||
Bots,
|
||||
@@ -524,132 +600,66 @@ enum class ApplySpellType {
|
||||
Raid
|
||||
};
|
||||
|
||||
namespace SpecialAbility {
|
||||
constexpr int Summon = 1;
|
||||
constexpr int Enrage = 2;
|
||||
constexpr int Rampage = 3;
|
||||
constexpr int AreaRampage = 4;
|
||||
constexpr int Flurry = 5;
|
||||
constexpr int TripleAttack = 6;
|
||||
constexpr int QuadrupleAttack = 7;
|
||||
constexpr int DualWield = 8;
|
||||
constexpr int BaneAttack = 9;
|
||||
constexpr int MagicalAttack = 10;
|
||||
constexpr int RangedAttack = 11;
|
||||
constexpr int SlowImmunity = 12;
|
||||
constexpr int MesmerizeImmunity = 13;
|
||||
constexpr int CharmImmunity = 14;
|
||||
constexpr int StunImmunity = 15;
|
||||
constexpr int SnareImmunity = 16;
|
||||
constexpr int FearImmunity = 17;
|
||||
constexpr int DispellImmunity = 18;
|
||||
constexpr int MeleeImmunity = 19;
|
||||
constexpr int MagicImmunity = 20;
|
||||
constexpr int FleeingImmunity = 21;
|
||||
constexpr int MeleeImmunityExceptBane = 22;
|
||||
constexpr int MeleeImmunityExceptMagical = 23;
|
||||
constexpr int AggroImmunity = 24;
|
||||
constexpr int BeingAggroImmunity = 25;
|
||||
constexpr int CastingFromRangeImmunity = 26;
|
||||
constexpr int FeignDeathImmunity = 27;
|
||||
constexpr int TauntImmunity = 28;
|
||||
constexpr int TunnelVision = 29;
|
||||
constexpr int NoBuffHealFriends = 30;
|
||||
constexpr int PacifyImmunity = 31;
|
||||
constexpr int Leash = 32;
|
||||
constexpr int Tether = 33;
|
||||
constexpr int DestructibleObject = 34;
|
||||
constexpr int HarmFromClientImmunity = 35;
|
||||
constexpr int AlwaysFlee = 36;
|
||||
constexpr int FleePercent = 37;
|
||||
constexpr int AllowBeneficial = 38;
|
||||
constexpr int DisableMelee = 39;
|
||||
constexpr int NPCChaseDistance = 40;
|
||||
constexpr int AllowedToTank = 41;
|
||||
constexpr int IgnoreRootAggroRules = 42;
|
||||
constexpr int CastingResistDifficulty = 43;
|
||||
constexpr int CounterAvoidDamage = 44;
|
||||
constexpr int ProximityAggro = 45;
|
||||
constexpr int RangedAttackImmunity = 46;
|
||||
constexpr int ClientDamageImmunity = 47;
|
||||
constexpr int NPCDamageImmunity = 48;
|
||||
constexpr int ClientAggroImmunity = 49;
|
||||
constexpr int NPCAggroImmunity = 50;
|
||||
constexpr int ModifyAvoidDamage = 51;
|
||||
constexpr int MemoryFadeImmunity = 52;
|
||||
constexpr int OpenImmunity = 53;
|
||||
constexpr int AssassinateImmunity = 54;
|
||||
constexpr int HeadshotImmunity = 55;
|
||||
constexpr int BotAggroImmunity = 56;
|
||||
constexpr int BotDamageImmunity = 57;
|
||||
constexpr int Max = 58;
|
||||
|
||||
constexpr int MaxParameters = 9;
|
||||
|
||||
std::string GetName(int ability_id);
|
||||
bool IsValid(int ability_id);
|
||||
}
|
||||
|
||||
static std::map<int, std::string> special_ability_names = {
|
||||
{ SpecialAbility::Summon, "Summon" },
|
||||
{ SpecialAbility::Enrage, "Enrage" },
|
||||
{ SpecialAbility::Rampage, "Rampage" },
|
||||
{ SpecialAbility::AreaRampage, "Area Rampage" },
|
||||
{ SpecialAbility::Flurry, "Flurry" },
|
||||
{ SpecialAbility::TripleAttack, "Triple Attack" },
|
||||
{ SpecialAbility::QuadrupleAttack, "Quadruple Attack" },
|
||||
{ SpecialAbility::DualWield, "Dual Wield" },
|
||||
{ SpecialAbility::BaneAttack, "Bane Attack" },
|
||||
{ SpecialAbility::MagicalAttack, "Magical Attack" },
|
||||
{ SpecialAbility::RangedAttack, "Ranged Attack" },
|
||||
{ SpecialAbility::SlowImmunity, "Immune to Slow" },
|
||||
{ SpecialAbility::MesmerizeImmunity, "Immune to Mesmerize" },
|
||||
{ SpecialAbility::CharmImmunity, "Immune to Charm" },
|
||||
{ SpecialAbility::StunImmunity, "Immune to Stun" },
|
||||
{ SpecialAbility::SnareImmunity, "Immune to Snare" },
|
||||
{ SpecialAbility::FearImmunity, "Immune to Fear" },
|
||||
{ SpecialAbility::DispellImmunity, "Immune to Dispell" },
|
||||
{ SpecialAbility::MeleeImmunity, "Immune to Melee" },
|
||||
{ SpecialAbility::MagicImmunity, "Immune to Magic" },
|
||||
{ SpecialAbility::FleeingImmunity, "Immune to Fleeing" },
|
||||
{ SpecialAbility::MeleeImmunityExceptBane, "Immune to Melee except Bane" },
|
||||
{ SpecialAbility::MeleeImmunityExceptMagical, "Immune to Non-Magical Melee" },
|
||||
{ SpecialAbility::AggroImmunity, "Immune to Aggro" },
|
||||
{ SpecialAbility::BeingAggroImmunity, "Immune to Being Aggro" },
|
||||
{ SpecialAbility::CastingFromRangeImmunity, "Immune to Ranged Spells" },
|
||||
{ SpecialAbility::FeignDeathImmunity, "Immune to Feign Death" },
|
||||
{ SpecialAbility::TauntImmunity, "Immune to Taunt" },
|
||||
{ SpecialAbility::TunnelVision, "Tunnel Vision" },
|
||||
{ SpecialAbility::NoBuffHealFriends, "Does Not Heal or Buff Allies" },
|
||||
{ SpecialAbility::PacifyImmunity, "Immune to Pacify" },
|
||||
{ SpecialAbility::Leash, "Leashed" },
|
||||
{ SpecialAbility::Tether, "Tethered" },
|
||||
{ SpecialAbility::DestructibleObject, "Destructible Object" },
|
||||
{ SpecialAbility::HarmFromClientImmunity, "Immune to Harm from Client" },
|
||||
{ SpecialAbility::AlwaysFlee, "Always Flees" },
|
||||
{ SpecialAbility::FleePercent, "Flee Percentage" },
|
||||
{ SpecialAbility::AllowBeneficial, "Allows Beneficial Spells" },
|
||||
{ SpecialAbility::DisableMelee, "Melee is Disabled" },
|
||||
{ SpecialAbility::NPCChaseDistance, "Chase Distance" },
|
||||
{ SpecialAbility::AllowedToTank, "Allowed to Tank" },
|
||||
{ SpecialAbility::IgnoreRootAggroRules, "Ignores Root Aggro" },
|
||||
{ SpecialAbility::CastingResistDifficulty, "Casting Resist Difficulty" },
|
||||
{ SpecialAbility::CounterAvoidDamage, "Counter Damage Avoidance" },
|
||||
{ SpecialAbility::ProximityAggro, "Proximity Aggro" },
|
||||
{ SpecialAbility::RangedAttackImmunity, "Immune to Ranged Attacks" },
|
||||
{ SpecialAbility::ClientDamageImmunity, "Immune to Client Damage" },
|
||||
{ SpecialAbility::NPCDamageImmunity, "Immune to NPC Damage" },
|
||||
{ SpecialAbility::ClientAggroImmunity, "Immune to Client Aggro" },
|
||||
{ SpecialAbility::NPCAggroImmunity, "Immune to NPC Aggro" },
|
||||
{ SpecialAbility::ModifyAvoidDamage, "Modify Damage Avoidance" },
|
||||
{ SpecialAbility::MemoryFadeImmunity, "Immune to Memory Fades" },
|
||||
{ SpecialAbility::OpenImmunity, "Immune to Open" },
|
||||
{ SpecialAbility::AssassinateImmunity, "Immune to Assassinate" },
|
||||
{ SpecialAbility::HeadshotImmunity, "Immune to Headshot" },
|
||||
{ SpecialAbility::BotAggroImmunity, "Immune to Bot Aggro" },
|
||||
{ SpecialAbility::BotDamageImmunity, "Immune to Bot Damage" },
|
||||
enum {
|
||||
SPECATK_SUMMON = 1,
|
||||
SPECATK_ENRAGE = 2,
|
||||
SPECATK_RAMPAGE = 3,
|
||||
SPECATK_AREA_RAMPAGE = 4,
|
||||
SPECATK_FLURRY = 5,
|
||||
SPECATK_TRIPLE = 6,
|
||||
SPECATK_QUAD = 7,
|
||||
SPECATK_INNATE_DW = 8,
|
||||
SPECATK_BANE = 9,
|
||||
SPECATK_MAGICAL = 10,
|
||||
SPECATK_RANGED_ATK = 11,
|
||||
UNSLOWABLE = 12,
|
||||
UNMEZABLE = 13,
|
||||
UNCHARMABLE = 14,
|
||||
UNSTUNABLE = 15,
|
||||
UNSNAREABLE = 16,
|
||||
UNFEARABLE = 17,
|
||||
UNDISPELLABLE = 18,
|
||||
IMMUNE_MELEE = 19,
|
||||
IMMUNE_MAGIC = 20,
|
||||
IMMUNE_FLEEING = 21,
|
||||
IMMUNE_MELEE_EXCEPT_BANE = 22,
|
||||
IMMUNE_MELEE_NONMAGICAL = 23,
|
||||
IMMUNE_AGGRO = 24,
|
||||
IMMUNE_AGGRO_ON = 25,
|
||||
IMMUNE_CASTING_FROM_RANGE = 26,
|
||||
IMMUNE_FEIGN_DEATH = 27,
|
||||
IMMUNE_TAUNT = 28,
|
||||
NPC_TUNNELVISION = 29,
|
||||
NPC_NO_BUFFHEAL_FRIENDS = 30,
|
||||
IMMUNE_PACIFY = 31,
|
||||
LEASH = 32,
|
||||
TETHER = 33,
|
||||
DESTRUCTIBLE_OBJECT = 34,
|
||||
NO_HARM_FROM_CLIENT = 35,
|
||||
ALWAYS_FLEE = 36,
|
||||
FLEE_PERCENT = 37,
|
||||
ALLOW_BENEFICIAL = 38,
|
||||
DISABLE_MELEE = 39,
|
||||
NPC_CHASE_DISTANCE = 40,
|
||||
ALLOW_TO_TANK = 41,
|
||||
IGNORE_ROOT_AGGRO_RULES = 42,
|
||||
CASTING_RESIST_DIFF = 43,
|
||||
COUNTER_AVOID_DAMAGE = 44, // Modify by percent NPC's opponents chance to riposte, block, parry or dodge individually, or for all skills
|
||||
PROX_AGGRO = 45,
|
||||
IMMUNE_RANGED_ATTACKS = 46,
|
||||
IMMUNE_DAMAGE_CLIENT = 47,
|
||||
IMMUNE_DAMAGE_NPC = 48,
|
||||
IMMUNE_AGGRO_CLIENT = 49,
|
||||
IMMUNE_AGGRO_NPC = 50,
|
||||
MODIFY_AVOID_DAMAGE = 51, // Modify by percent the NPCs chance to riposte, block, parry or dodge individually, or for all skills
|
||||
IMMUNE_FADING_MEMORIES = 52,
|
||||
IMMUNE_OPEN = 53,
|
||||
IMMUNE_ASSASSINATE = 54,
|
||||
IMMUNE_HEADSHOT = 55,
|
||||
MAX_SPECIAL_ATTACK = 56
|
||||
};
|
||||
|
||||
|
||||
namespace HeroicBonusBucket
|
||||
{
|
||||
const std::string WisMaxMana = "HWIS-MaxMana";
|
||||
@@ -674,92 +684,4 @@ namespace HeroicBonusBucket
|
||||
const std::string DexEnduranceRegen = "HDEX-EnduranceRegen";
|
||||
}
|
||||
|
||||
namespace Bug {
|
||||
namespace Category {
|
||||
constexpr uint32 Other = 0;
|
||||
constexpr uint32 Video = 1;
|
||||
constexpr uint32 Audio = 2;
|
||||
constexpr uint32 Pathing = 3;
|
||||
constexpr uint32 Quest = 4;
|
||||
constexpr uint32 Tradeskills = 5;
|
||||
constexpr uint32 SpellStacking = 6;
|
||||
constexpr uint32 DoorsPortals = 7;
|
||||
constexpr uint32 Items = 8;
|
||||
constexpr uint32 NPC = 9;
|
||||
constexpr uint32 Dialogs = 10;
|
||||
constexpr uint32 LoNTCG = 11;
|
||||
constexpr uint32 Mercenaries = 12;
|
||||
}
|
||||
|
||||
namespace InformationFlag {
|
||||
constexpr uint32 None = 0;
|
||||
constexpr uint32 Repeatable = 1;
|
||||
constexpr uint32 Crash = 2;
|
||||
constexpr uint32 TargetInfo = 4;
|
||||
constexpr uint32 CharacterFlags = 8;
|
||||
constexpr uint32 Unknown = 4294967280;
|
||||
}
|
||||
|
||||
uint32 GetID(const std::string& category_name);
|
||||
std::string GetName(uint32 category_id);
|
||||
bool IsValid(uint32 category_id);
|
||||
}
|
||||
|
||||
static std::map<uint32, std::string> bug_category_names = {
|
||||
{ Bug::Category::Other, "Other" },
|
||||
{ Bug::Category::Video, "Video" },
|
||||
{ Bug::Category::Audio, "Audio" },
|
||||
{ Bug::Category::Pathing, "Pathing" },
|
||||
{ Bug::Category::Quest, "Quest" },
|
||||
{ Bug::Category::Tradeskills, "Tradeskills" },
|
||||
{ Bug::Category::SpellStacking, "Spell Stacking" },
|
||||
{ Bug::Category::DoorsPortals, "Doors and Portals" },
|
||||
{ Bug::Category::Items, "Items" },
|
||||
{ Bug::Category::NPC, "NPC" },
|
||||
{ Bug::Category::Dialogs, "Dialogs" },
|
||||
{ Bug::Category::LoNTCG, "LoN - TCG" },
|
||||
{ Bug::Category::Mercenaries, "Mercenaries" }
|
||||
};
|
||||
|
||||
namespace Stance {
|
||||
constexpr uint32 Unknown = 0;
|
||||
constexpr uint32 Passive = 1;
|
||||
constexpr uint32 Balanced = 2;
|
||||
constexpr uint32 Efficient = 3;
|
||||
constexpr uint32 Reactive = 4;
|
||||
constexpr uint32 Aggressive = 5;
|
||||
constexpr uint32 Assist = 6;
|
||||
constexpr uint32 Burn = 7;
|
||||
constexpr uint32 Efficient2 = 8;
|
||||
constexpr uint32 AEBurn = 9;
|
||||
|
||||
std::string GetName(uint8 stance_id);
|
||||
uint8 GetIndex(uint8 stance_id);
|
||||
bool IsValid(uint8 stance_id);
|
||||
}
|
||||
|
||||
static std::map<uint32, std::string> stance_names = {
|
||||
{ Stance::Unknown, "Unknown" },
|
||||
{ Stance::Passive, "Passive" },
|
||||
{ Stance::Balanced, "Balanced" },
|
||||
{ Stance::Efficient, "Efficient" },
|
||||
{ Stance::Reactive, "Reactive" },
|
||||
{ Stance::Aggressive, "Aggressive" },
|
||||
{ Stance::Assist, "Assist" },
|
||||
{ Stance::Burn, "Burn" },
|
||||
{ Stance::Efficient2, "Efficient" },
|
||||
{ Stance::AEBurn, "AE Burn" }
|
||||
};
|
||||
|
||||
namespace PCNPCOnlyFlagType {
|
||||
constexpr int PC = 1;
|
||||
constexpr int NPC = 2;
|
||||
}
|
||||
|
||||
namespace BookType {
|
||||
constexpr uint8 Scroll = 0;
|
||||
constexpr uint8 Book = 1;
|
||||
constexpr uint8 ItemInfo = 2;
|
||||
}
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
+2
-10
@@ -1,6 +1,8 @@
|
||||
// system use
|
||||
N(OP_ExploreUnknown),
|
||||
// start (please add new opcodes in descending order and re-order any name changes where applicable)
|
||||
N(OP_0x0193),
|
||||
N(OP_0x0347),
|
||||
N(OP_AAAction),
|
||||
N(OP_AAExpUpdate),
|
||||
N(OP_AcceptNewTask),
|
||||
@@ -65,7 +67,6 @@ N(OP_Buff),
|
||||
N(OP_BuffCreate),
|
||||
N(OP_BuffRemoveRequest),
|
||||
N(OP_Bug),
|
||||
N(OP_BuyerItems),
|
||||
N(OP_CameraEffect),
|
||||
N(OP_Camp),
|
||||
N(OP_CancelSneakHide),
|
||||
@@ -354,7 +355,6 @@ N(OP_MercenaryTimer),
|
||||
N(OP_MercenaryTimerRequest),
|
||||
N(OP_MercenaryUnknown1),
|
||||
N(OP_MercenaryUnsuspendResponse),
|
||||
N(OP_MerchantBulkItems),
|
||||
N(OP_MobEnduranceUpdate),
|
||||
N(OP_MobHealth),
|
||||
N(OP_MobManaUpdate),
|
||||
@@ -373,7 +373,6 @@ N(OP_MultiLineMsg),
|
||||
N(OP_NewSpawn),
|
||||
N(OP_NewTitlesAvailable),
|
||||
N(OP_NewZone),
|
||||
N(OP_NPCMoveUpdate),
|
||||
N(OP_OnLevelMessage),
|
||||
N(OP_OpenContainer),
|
||||
N(OP_OpenDiscordMerchant),
|
||||
@@ -511,11 +510,6 @@ N(OP_ShopEndConfirm),
|
||||
N(OP_ShopItem),
|
||||
N(OP_ShopPlayerBuy),
|
||||
N(OP_ShopPlayerSell),
|
||||
N(OP_ShopSendParcel),
|
||||
N(OP_ShopDeleteParcel),
|
||||
N(OP_ShopRespondParcel),
|
||||
N(OP_ShopRetrieveParcel),
|
||||
N(OP_ShopParcelIcon),
|
||||
N(OP_ShopRequest),
|
||||
N(OP_SimpleMessage),
|
||||
N(OP_SkillUpdate),
|
||||
@@ -534,7 +528,6 @@ N(OP_Stamina),
|
||||
N(OP_Stun),
|
||||
N(OP_Surname),
|
||||
N(OP_SwapSpell),
|
||||
N(OP_SystemFingerprint),
|
||||
N(OP_TargetBuffs),
|
||||
N(OP_TargetCommand),
|
||||
N(OP_TargetHoTT),
|
||||
@@ -559,7 +552,6 @@ N(OP_TradeBusy),
|
||||
N(OP_TradeCoins),
|
||||
N(OP_TradeMoneyUpdate),
|
||||
N(OP_Trader),
|
||||
N(OP_TraderBulkSend),
|
||||
N(OP_TraderBuy),
|
||||
N(OP_TraderDelItem),
|
||||
N(OP_TradeRequest),
|
||||
|
||||
@@ -56,8 +56,6 @@ const char* EQ::versions::ClientVersionName(ClientVersion client_version)
|
||||
return "RoF";
|
||||
case ClientVersion::RoF2:
|
||||
return "RoF2";
|
||||
case ClientVersion::Laurion:
|
||||
return "Laurion";
|
||||
default:
|
||||
return "Invalid Version";
|
||||
};
|
||||
@@ -78,8 +76,6 @@ uint32 EQ::versions::ConvertClientVersionToClientVersionBit(ClientVersion client
|
||||
return bitRoF;
|
||||
case ClientVersion::RoF2:
|
||||
return bitRoF2;
|
||||
case ClientVersion::Laurion:
|
||||
return bitLaurion;
|
||||
default:
|
||||
return bitUnknown;
|
||||
}
|
||||
@@ -100,8 +96,6 @@ EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion
|
||||
return ClientVersion::RoF;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)) :
|
||||
return ClientVersion::RoF2;
|
||||
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::Laurion) - 1)):
|
||||
return ClientVersion::Laurion;
|
||||
default:
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
@@ -190,8 +184,6 @@ const char* EQ::versions::MobVersionName(MobVersion mob_version)
|
||||
return "RoF";
|
||||
case MobVersion::RoF2:
|
||||
return "RoF2";
|
||||
case MobVersion::Laurion:
|
||||
return "Laurion";
|
||||
case MobVersion::NPC:
|
||||
return "NPC";
|
||||
case MobVersion::NPCMerchant:
|
||||
@@ -220,8 +212,6 @@ const char* EQ::versions::MobVersionName(MobVersion mob_version)
|
||||
return "Offline RoF";
|
||||
case MobVersion::OfflineRoF2:
|
||||
return "Offline RoF2";
|
||||
case MobVersion::OfflineLaurion:
|
||||
return "Offline Laurion";
|
||||
default:
|
||||
return "Invalid Version";
|
||||
};
|
||||
@@ -245,8 +235,6 @@ EQ::versions::ClientVersion EQ::versions::ConvertMobVersionToClientVersion(MobVe
|
||||
return ClientVersion::RoF;
|
||||
case MobVersion::RoF2:
|
||||
return ClientVersion::RoF2;
|
||||
case MobVersion::Laurion:
|
||||
return ClientVersion::Laurion;
|
||||
default:
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
@@ -270,8 +258,6 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToMobVersion(ClientVe
|
||||
return MobVersion::RoF;
|
||||
case ClientVersion::RoF2:
|
||||
return MobVersion::RoF2;
|
||||
case ClientVersion::Laurion:
|
||||
return MobVersion::Laurion;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
}
|
||||
@@ -292,8 +278,6 @@ EQ::versions::MobVersion EQ::versions::ConvertPCMobVersionToOfflinePCMobVersion(
|
||||
return MobVersion::OfflineRoF;
|
||||
case MobVersion::RoF2:
|
||||
return MobVersion::OfflineRoF2;
|
||||
case MobVersion::Laurion:
|
||||
return MobVersion::OfflineLaurion;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
}
|
||||
@@ -314,8 +298,6 @@ EQ::versions::MobVersion EQ::versions::ConvertOfflinePCMobVersionToPCMobVersion(
|
||||
return MobVersion::RoF;
|
||||
case MobVersion::OfflineRoF2:
|
||||
return MobVersion::RoF2;
|
||||
case MobVersion::OfflineLaurion:
|
||||
return MobVersion::Laurion;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
}
|
||||
@@ -336,8 +318,6 @@ EQ::versions::ClientVersion EQ::versions::ConvertOfflinePCMobVersionToClientVers
|
||||
return ClientVersion::RoF;
|
||||
case MobVersion::OfflineRoF2:
|
||||
return ClientVersion::RoF2;
|
||||
case MobVersion::OfflineLaurion:
|
||||
return ClientVersion::Laurion;
|
||||
default:
|
||||
return ClientVersion::Unknown;
|
||||
}
|
||||
@@ -358,8 +338,6 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion
|
||||
return MobVersion::OfflineRoF;
|
||||
case ClientVersion::RoF2:
|
||||
return MobVersion::OfflineRoF2;
|
||||
case ClientVersion::Laurion:
|
||||
return MobVersion::OfflineLaurion;
|
||||
default:
|
||||
return MobVersion::Unknown;
|
||||
}
|
||||
@@ -410,27 +388,6 @@ const char* EQ::expansions::ExpansionName(Expansion expansion)
|
||||
return "Rain of Fear";
|
||||
case Expansion::CotF:
|
||||
return "Call of the Forsaken";
|
||||
case Expansion::TDS:
|
||||
return "The Darkened Sea";
|
||||
case Expansion::TBM:
|
||||
return "The Broken Mirror";
|
||||
case Expansion::EoK:
|
||||
return "Empires of Kunark";
|
||||
case Expansion::RoS:
|
||||
return "Ring of Scale";
|
||||
case Expansion::TBL:
|
||||
return "The Burning Lands";
|
||||
case Expansion::ToV:
|
||||
return "Torment of Velious";
|
||||
case Expansion::CoV:
|
||||
return "Claws of Veeshan";
|
||||
case Expansion::ToL:
|
||||
return "Terror of Luclin";
|
||||
case Expansion::NoS:
|
||||
return "Night of Shadows";
|
||||
case Expansion::LS:
|
||||
return "Laurion's Song";
|
||||
|
||||
default:
|
||||
return "Invalid Expansion";
|
||||
}
|
||||
@@ -484,26 +441,6 @@ uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
|
||||
return bitRoF;
|
||||
case Expansion::CotF:
|
||||
return bitCotF;
|
||||
case Expansion::TDS:
|
||||
return bitTDS;
|
||||
case Expansion::TBM:
|
||||
return bitTBM;
|
||||
case Expansion::EoK:
|
||||
return bitEoK;
|
||||
case Expansion::RoS:
|
||||
return bitRoS;
|
||||
case Expansion::TBL:
|
||||
return bitTBL;
|
||||
case Expansion::ToV:
|
||||
return bitToV;
|
||||
case Expansion::CoV:
|
||||
return bitCoV;
|
||||
case Expansion::ToL:
|
||||
return bitToL;
|
||||
case Expansion::NoS:
|
||||
return bitNoS;
|
||||
case Expansion::LS:
|
||||
return bitLS;
|
||||
default:
|
||||
return bitEverQuest;
|
||||
}
|
||||
@@ -552,26 +489,6 @@ EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32
|
||||
return Expansion::RoF;
|
||||
case bitCotF:
|
||||
return Expansion::CotF;
|
||||
case bitTDS:
|
||||
return Expansion::TDS;
|
||||
case bitTBM:
|
||||
return Expansion::TBM;
|
||||
case bitEoK:
|
||||
return Expansion::EoK;
|
||||
case bitRoS:
|
||||
return Expansion::RoS;
|
||||
case bitTBL:
|
||||
return Expansion::TBL;
|
||||
case bitToV:
|
||||
return Expansion::ToV;
|
||||
case bitCoV:
|
||||
return Expansion::CoV;
|
||||
case bitToL:
|
||||
return Expansion::ToL;
|
||||
case bitNoS:
|
||||
return Expansion::NoS;
|
||||
case bitLS:
|
||||
return Expansion::LS;
|
||||
default:
|
||||
return Expansion::EverQuest;
|
||||
}
|
||||
@@ -620,26 +537,6 @@ uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
|
||||
return maskRoF;
|
||||
case Expansion::CotF:
|
||||
return maskCotF;
|
||||
case Expansion::TDS:
|
||||
return maskTDS;
|
||||
case Expansion::TBM:
|
||||
return maskTBM;
|
||||
case Expansion::EoK:
|
||||
return maskEoK;
|
||||
case Expansion::RoS:
|
||||
return maskRoS;
|
||||
case Expansion::TBL:
|
||||
return maskTBL;
|
||||
case Expansion::ToV:
|
||||
return maskToV;
|
||||
case Expansion::CoV:
|
||||
return maskCoV;
|
||||
case Expansion::ToL:
|
||||
return maskToL;
|
||||
case Expansion::NoS:
|
||||
return maskNoS;
|
||||
case Expansion::LS:
|
||||
return maskLS;
|
||||
default:
|
||||
return maskEverQuest;
|
||||
}
|
||||
|
||||
+9
-45
@@ -36,8 +36,7 @@ namespace EQ
|
||||
SoD, // Build: 'Dec 19 2008 15:22:49'
|
||||
UF, // Build: 'Jun 8 2010 16:44:32'
|
||||
RoF, // Build: 'Dec 10 2012 17:35:44'
|
||||
RoF2, // Build: 'May 10 2013 23:30:08'
|
||||
Laurion
|
||||
RoF2 // Build: 'May 10 2013 23:30:08'
|
||||
};
|
||||
|
||||
enum ClientVersionBitmask : uint32 {
|
||||
@@ -49,7 +48,6 @@ namespace EQ
|
||||
bitUF = 0x00000010,
|
||||
bitRoF = 0x00000020,
|
||||
bitRoF2 = 0x00000040,
|
||||
bitLaurion = 0x00000080,
|
||||
maskUnknown = 0x00000000,
|
||||
maskTitaniumAndEarlier = 0x00000003,
|
||||
maskSoFAndEarlier = 0x00000007,
|
||||
@@ -61,11 +59,10 @@ namespace EQ
|
||||
maskUFAndLater = 0xFFFFFFF0,
|
||||
maskRoFAndLater = 0xFFFFFFE0,
|
||||
maskRoF2AndLater = 0xFFFFFFC0,
|
||||
maskLaurionAndLater = 0xFFFFFF80,
|
||||
maskAllClients = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
const ClientVersion LastClientVersion = ClientVersion::Laurion;
|
||||
const ClientVersion LastClientVersion = ClientVersion::RoF2;
|
||||
const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1);
|
||||
|
||||
bool IsValidClientVersion(ClientVersion client_version);
|
||||
@@ -83,7 +80,6 @@ namespace EQ
|
||||
UF,
|
||||
RoF,
|
||||
RoF2,
|
||||
Laurion,
|
||||
NPC,
|
||||
NPCMerchant,
|
||||
Merc,
|
||||
@@ -97,14 +93,13 @@ namespace EQ
|
||||
OfflineSoD,
|
||||
OfflineUF,
|
||||
OfflineRoF,
|
||||
OfflineRoF2,
|
||||
OfflineLaurion
|
||||
OfflineRoF2
|
||||
};
|
||||
|
||||
const MobVersion LastMobVersion = MobVersion::OfflineLaurion;
|
||||
const MobVersion LastPCMobVersion = MobVersion::Laurion;
|
||||
const MobVersion LastMobVersion = MobVersion::OfflineRoF2;
|
||||
const MobVersion LastPCMobVersion = MobVersion::RoF2;
|
||||
const MobVersion LastNonPCMobVersion = MobVersion::BotPet;
|
||||
const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineLaurion;
|
||||
const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineRoF2;
|
||||
const size_t MobVersionCount = (static_cast<size_t>(LastMobVersion) + 1);
|
||||
|
||||
bool IsValidMobVersion(MobVersion mob_version);
|
||||
@@ -136,8 +131,7 @@ namespace EQ
|
||||
ucsSoDCombined = 'D',
|
||||
ucsUFCombined = 'E',
|
||||
ucsRoFCombined = 'F',
|
||||
ucsRoF2Combined = 'G',
|
||||
ucsLaurionCombined = 'G'
|
||||
ucsRoF2Combined = 'G'
|
||||
};
|
||||
|
||||
} /*versions*/
|
||||
@@ -164,17 +158,7 @@ namespace EQ
|
||||
HoT,
|
||||
VoA,
|
||||
RoF,
|
||||
CotF,
|
||||
TDS,
|
||||
TBM,
|
||||
EoK,
|
||||
RoS,
|
||||
TBL,
|
||||
ToV,
|
||||
CoV,
|
||||
ToL,
|
||||
NoS,
|
||||
LS
|
||||
CotF
|
||||
};
|
||||
|
||||
enum ExpansionBitmask : uint32 {
|
||||
@@ -199,16 +183,6 @@ namespace EQ
|
||||
bitVoA = 0x00020000,
|
||||
bitRoF = 0x00040000,
|
||||
bitCotF = 0x00080000,
|
||||
bitTDS = 0x00100000,
|
||||
bitTBM = 0x00200000,
|
||||
bitEoK = 0x00400000,
|
||||
bitRoS = 0x00800000,
|
||||
bitTBL = 0x01000000,
|
||||
bitToV = 0x02000000,
|
||||
bitCoV = 0x04000000,
|
||||
bitToL = 0x08000000,
|
||||
bitNoS = 0x10000000,
|
||||
bitLS = 0x20000000,
|
||||
maskEverQuest = 0x00000000,
|
||||
maskRoK = 0x00000001,
|
||||
maskSoV = 0x00000003,
|
||||
@@ -229,17 +203,7 @@ namespace EQ
|
||||
maskHoT = 0x0001FFFF,
|
||||
maskVoA = 0x0003FFFF,
|
||||
maskRoF = 0x0007FFFF,
|
||||
maskCotF = 0x000FFFFF,
|
||||
maskTDS = 0x001FFFFF,
|
||||
maskTBM = 0x003FFFFF,
|
||||
maskEoK = 0x007FFFFF,
|
||||
maskRoS = 0x00FFFFFF,
|
||||
maskTBL = 0x01FFFFFF,
|
||||
maskToV = 0x03FFFFFF,
|
||||
maskCoV = 0x07FFFFFF,
|
||||
maskToL = 0x0FFFFFFF,
|
||||
maskNoS = 0x1FFFFFFF,
|
||||
maskLS = 0x3FFFFFFF,
|
||||
maskCotF = 0x000FFFFF
|
||||
};
|
||||
|
||||
const char* ExpansionName(Expansion expansion);
|
||||
|
||||
+65
-106
@@ -758,50 +758,10 @@ typedef enum {
|
||||
FilterFocusEffects = 22, //0=show, 1=hide
|
||||
FilterPetSpells = 23, //0=show, 1=hide
|
||||
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
||||
FilterItemSpeech = 25, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed
|
||||
FilterSwarmPetDeath = 29,
|
||||
FilterFellowshipChat = 30,
|
||||
FilterMercenaryMessages = 31,
|
||||
FilterSpam = 32,
|
||||
FilterAchievements = 33,
|
||||
FilterPvPMessages = 34,
|
||||
FilterSpellNameInCast = 35,
|
||||
FilterRandomMine = 36,
|
||||
FilterRandomGroupRaid = 37,
|
||||
FilterRandomOthers = 38,
|
||||
FilterEnvironmentalDamage = 39,
|
||||
FilterMessages = 40,
|
||||
FilterOverwriteDetrimental = 41,
|
||||
FilterOverwriteBeneficial = 42,
|
||||
FilterCantUseCommand = 43,
|
||||
FilterCombatAbilityReuse = 44,
|
||||
FilterAAAbilityReuse = 45,
|
||||
FilterProcBeginCasting = 46,
|
||||
FilterDestroyedItems = 47,
|
||||
FilterYourAuras = 48,
|
||||
FilterOtherAuras = 49,
|
||||
FilterYourHeals = 50,
|
||||
FilterOtherHeals = 51,
|
||||
FilterYourDoTs = 52,
|
||||
FilterOtherDoTs = 53,
|
||||
FilterOtherDirectDamage = 54,
|
||||
FilterSpellEmotes = 55,
|
||||
FilterFactionMessages = 56,
|
||||
FilterTauntMessages = 57,
|
||||
FilterYourDisciplines = 58,
|
||||
FilterOtherDisplines = 59,
|
||||
FilterAchievementsOthers = 60,
|
||||
FilterRaidVictory = 61,
|
||||
FilterOtherDirectDamageCrits = 62,
|
||||
FilterDoTYoursCritical = 63,
|
||||
FilterDoTOthersCritical = 64,
|
||||
FilterDoTDamageTaken = 65,
|
||||
FilterHealsReceived = 66,
|
||||
FilterHealsYoursCritical = 67,
|
||||
FilterHealsOthersCritical = 68,
|
||||
FilterUnknown25 = 25,
|
||||
FilterUnknown26 = 26,
|
||||
FilterUnknown27 = 27,
|
||||
FilterUnknown28 = 28,
|
||||
_FilterCount
|
||||
} eqFilterType;
|
||||
|
||||
@@ -812,47 +772,67 @@ typedef enum {
|
||||
FilterShowSelfOnly
|
||||
} eqFilterMode;
|
||||
|
||||
#define STAT_STR 0
|
||||
#define STAT_STA 1
|
||||
#define STAT_AGI 2
|
||||
#define STAT_DEX 3
|
||||
#define STAT_INT 4
|
||||
#define STAT_WIS 5
|
||||
#define STAT_CHA 6
|
||||
#define STAT_MAGIC 7
|
||||
#define STAT_COLD 8
|
||||
#define STAT_FIRE 9
|
||||
#define STAT_POISON 10
|
||||
#define STAT_DISEASE 11
|
||||
#define STAT_MANA 12
|
||||
#define STAT_HP 13
|
||||
#define STAT_AC 14
|
||||
#define STAT_ENDURANCE 15
|
||||
#define STAT_ATTACK 16
|
||||
#define STAT_HP_REGEN 17
|
||||
#define STAT_MANA_REGEN 18
|
||||
#define STAT_HASTE 19
|
||||
#define STAT_DAMAGE_SHIELD 20
|
||||
#define STAT_DS_MITIGATION 22
|
||||
#define STAT_HEAL_AMOUNT 23
|
||||
#define STAT_SPELL_DAMAGE 24
|
||||
#define STAT_CLAIRVOYANCE 25
|
||||
#define STAT_HEROIC_AGILITY 26
|
||||
#define STAT_HEROIC_CHARISMA 27
|
||||
#define STAT_HEROIC_DEXTERITY 28
|
||||
#define STAT_HEROIC_INTELLIGENCE 29
|
||||
#define STAT_HEROIC_STAMINA 30
|
||||
#define STAT_HEROIC_STRENGTH 31
|
||||
#define STAT_HEROIC_WISDOM 32
|
||||
#define STAT_BASH 33
|
||||
#define STAT_BACKSTAB 34
|
||||
#define STAT_DRAGON_PUNCH 35
|
||||
#define STAT_EAGLE_STRIKE 36
|
||||
#define STAT_FLYING_KICK 37
|
||||
#define STAT_KICK 38
|
||||
#define STAT_ROUND_KICK 39
|
||||
#define STAT_TIGER_CLAW 40
|
||||
#define STAT_FRENZY 41
|
||||
#define STAT_STR 0
|
||||
#define STAT_STA 1
|
||||
#define STAT_AGI 2
|
||||
#define STAT_DEX 3
|
||||
#define STAT_INT 4
|
||||
#define STAT_WIS 5
|
||||
#define STAT_CHA 6
|
||||
#define STAT_MAGIC 7
|
||||
#define STAT_COLD 8
|
||||
#define STAT_FIRE 9
|
||||
#define STAT_POISON 10
|
||||
#define STAT_DISEASE 11
|
||||
#define STAT_MANA 12
|
||||
#define STAT_HP 13
|
||||
#define STAT_AC 14
|
||||
#define STAT_ENDURANCE 15
|
||||
#define STAT_ATTACK 16
|
||||
#define STAT_HP_REGEN 17
|
||||
#define STAT_MANA_REGEN 18
|
||||
#define STAT_HASTE 19
|
||||
#define STAT_DAMAGE_SHIELD 20
|
||||
|
||||
/*
|
||||
** Recast timer types. Used as an off set to charProfileStruct timers.
|
||||
**
|
||||
** (Another orphaned enumeration...)
|
||||
*/
|
||||
enum RecastTimerTypes
|
||||
{
|
||||
RecTimer_0 = 0,
|
||||
RecTimer_1,
|
||||
RecTimer_WeaponHealClick, // 2
|
||||
RecTimer_MuramiteBaneNukeClick, // 3
|
||||
RecTimer_4,
|
||||
RecTimer_DispellClick, // 5 (also click heal orbs?)
|
||||
RecTimer_Epic, // 6
|
||||
RecTimer_OoWBPClick, // 7
|
||||
RecTimer_VishQuestClassItem, // 8
|
||||
RecTimer_HealPotion, // 9
|
||||
RecTimer_10,
|
||||
RecTimer_11,
|
||||
RecTimer_12,
|
||||
RecTimer_13,
|
||||
RecTimer_14,
|
||||
RecTimer_15,
|
||||
RecTimer_16,
|
||||
RecTimer_17,
|
||||
RecTimer_18,
|
||||
RecTimer_ModRod, // 19
|
||||
_RecTimerCount
|
||||
};
|
||||
|
||||
enum GroupUpdateAction
|
||||
{
|
||||
GUA_Joined = 0,
|
||||
GUA_Left = 1,
|
||||
GUA_LastLeft = 6,
|
||||
GUA_FullGroupInfo = 7,
|
||||
GUA_MakeLeader = 8,
|
||||
GUA_Started = 9
|
||||
};
|
||||
|
||||
static const uint8 DamageTypeSomething = 0x1C; //0x1c is something...
|
||||
static const uint8 DamageTypeFalling = 0xFC;
|
||||
@@ -1151,25 +1131,4 @@ namespace LeadershipAbilitySlot {
|
||||
constexpr uint16 HealthOfTargetsTarget = 14;
|
||||
}
|
||||
|
||||
enum ExpSource
|
||||
{
|
||||
Quest,
|
||||
GM,
|
||||
Kill,
|
||||
Death,
|
||||
Resurrection,
|
||||
LDoNChest,
|
||||
Task,
|
||||
Sacrifice
|
||||
};
|
||||
|
||||
#define PARCEL_SEND_ITEMS 0
|
||||
#define PARCEL_SEND_MONEY 1
|
||||
#define PARCEL_MONEY_ITEM_ID 99990 // item id of money
|
||||
#define PARCEL_LIMIT 5
|
||||
#define PARCEL_BEGIN_SLOT 1
|
||||
|
||||
namespace DoorType {
|
||||
constexpr uint32 BuyerStall = 155;
|
||||
}
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
@@ -104,14 +104,6 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
|
||||
RoF2::constants::EXPANSIONS_MASK,
|
||||
RoF2::constants::CHARACTER_CREATION_LIMIT,
|
||||
RoF2::constants::SAY_LINK_BODY_SIZE
|
||||
),
|
||||
/*[ClientVersion::Laurion] =*/
|
||||
EQ::constants::LookupEntry(
|
||||
Laurion::constants::EXPANSION,
|
||||
Laurion::constants::EXPANSION_BIT,
|
||||
Laurion::constants::EXPANSIONS_MASK,
|
||||
Laurion::constants::CHARACTER_CREATION_LIMIT,
|
||||
Laurion::constants::SAY_LINK_BODY_SIZE
|
||||
)
|
||||
};
|
||||
|
||||
@@ -378,33 +370,6 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF2::inventory::ConcatenateInvTypeLimbo,
|
||||
RoF2::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::LS] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
EQ::invtype::POSSESSIONS_SIZE, RoF2::invtype::BANK_SIZE, RoF2::invtype::SHARED_BANK_SIZE,
|
||||
RoF2::invtype::TRADE_SIZE, RoF2::invtype::WORLD_SIZE, RoF2::invtype::LIMBO_SIZE,
|
||||
RoF2::invtype::TRIBUTE_SIZE, RoF2::invtype::TROPHY_TRIBUTE_SIZE, RoF2::invtype::GUILD_TRIBUTE_SIZE,
|
||||
RoF2::invtype::MERCHANT_SIZE, RoF2::invtype::DELETED_SIZE, RoF2::invtype::CORPSE_SIZE,
|
||||
RoF2::invtype::BAZAAR_SIZE, RoF2::invtype::INSPECT_SIZE, RoF2::invtype::REAL_ESTATE_SIZE,
|
||||
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::invtype::ALT_STORAGE_SIZE, RoF2::invtype::ARCHIVED_SIZE,
|
||||
RoF2::invtype::MAIL_SIZE, RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE, RoF2::invtype::KRONO_SIZE,
|
||||
RoF2::invtype::OTHER_SIZE
|
||||
),
|
||||
|
||||
RoF2::invslot::EQUIPMENT_BITMASK,
|
||||
RoF2::invslot::GENERAL_BITMASK,
|
||||
RoF2::invslot::CURSOR_BITMASK,
|
||||
RoF2::invslot::POSSESSIONS_BITMASK,
|
||||
RoF2::invslot::CORPSE_BITMASK,
|
||||
RoF2::invbag::SLOT_COUNT,
|
||||
RoF2::invaug::SOCKET_COUNT,
|
||||
|
||||
RoF2::inventory::AllowEmptyBagInBag,
|
||||
RoF2::inventory::AllowClickCastFromBag,
|
||||
RoF2::inventory::ConcatenateInvTypeLimbo,
|
||||
RoF2::inventory::AllowOverLevelEquipment
|
||||
),
|
||||
/*[MobVersion::NPC] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
@@ -778,33 +743,6 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
|
||||
RoF2::invbag::SLOT_COUNT,
|
||||
RoF2::invaug::SOCKET_COUNT,
|
||||
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
),
|
||||
/*[MobVersion::OfflineLS] =*/
|
||||
EQ::inventory::LookupEntry(
|
||||
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::invtype::TRADE_SIZE, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::invtype::MERCHANT_SIZE, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::invtype::BAZAAR_SIZE, RoF2::invtype::INSPECT_SIZE, RoF2::INULL,
|
||||
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
|
||||
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::INULL, RoF2::INULL, RoF2::INULL,
|
||||
RoF2::INULL
|
||||
),
|
||||
|
||||
RoF2::INULL,
|
||||
RoF2::INULL,
|
||||
RoF2::INULL,
|
||||
RoF2::INULL,
|
||||
RoF2::INULL,
|
||||
RoF2::invbag::SLOT_COUNT,
|
||||
RoF2::invaug::SOCKET_COUNT,
|
||||
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@@ -1056,10 +994,6 @@ static const EQ::behavior::LookupEntry behavior_static_lookup_entries[EQ::versio
|
||||
EQ::behavior::LookupEntry(
|
||||
RoF2::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::LS] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
RoF2::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::NPC] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
EQ::behavior::CoinHasWeight
|
||||
@@ -1113,10 +1047,6 @@ static const EQ::behavior::LookupEntry behavior_static_lookup_entries[EQ::versio
|
||||
RoF::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineRoF2] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
RoF2::behavior::CoinHasWeight
|
||||
),
|
||||
/*[MobVersion::OfflineLS] =*/
|
||||
EQ::behavior::LookupEntry(
|
||||
RoF2::behavior::CoinHasWeight
|
||||
)
|
||||
@@ -1272,19 +1202,6 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
|
||||
RoF2::spells::NPC_BUFFS,
|
||||
RoF2::spells::PET_BUFFS,
|
||||
RoF2::spells::MERC_BUFFS
|
||||
),
|
||||
/*[ClientVersion::Laurion] =*/
|
||||
EQ::spells::LookupEntry(
|
||||
Laurion::spells::SPELL_ID_MAX,
|
||||
Laurion::spells::SPELLBOOK_SIZE,
|
||||
UF::spells::SPELL_GEM_COUNT, // client translators are setup to allow the max value a client supports..however, the top 4 indices are not valid in this case
|
||||
Laurion::spells::LONG_BUFFS,
|
||||
Laurion::spells::SHORT_BUFFS,
|
||||
Laurion::spells::DISC_BUFFS,
|
||||
Laurion::spells::TOTAL_BUFFS,
|
||||
Laurion::spells::NPC_BUFFS,
|
||||
Laurion::spells::PET_BUFFS,
|
||||
Laurion::spells::MERC_BUFFS
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
#include "../common/patches/uf_limits.h"
|
||||
#include "../common/patches/rof_limits.h"
|
||||
#include "../common/patches/rof2_limits.h"
|
||||
#include "../common/patches/laurion_limits.h"
|
||||
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
|
||||
+156
-724
File diff suppressed because it is too large
Load Diff
@@ -94,7 +94,7 @@ void EQEmuConfig::parse_config()
|
||||
auto_database_updates = true;
|
||||
}
|
||||
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("ip", "127.0.0.1").asString();
|
||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
||||
|
||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||
@@ -171,7 +171,6 @@ void EQEmuConfig::parse_config()
|
||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
|
||||
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
|
||||
OpcodeDir = _root["server"]["directories"].get("opcodes", "./").asString();
|
||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@ class EQEmuConfig
|
||||
std::string PluginDir;
|
||||
std::string LuaModuleDir;
|
||||
std::string PatchDir;
|
||||
std::string OpcodeDir;
|
||||
std::string SharedMemDir;
|
||||
std::string LogDir;
|
||||
|
||||
|
||||
@@ -141,7 +141,6 @@ namespace Logs {
|
||||
Zoning,
|
||||
EqTime,
|
||||
Corpses,
|
||||
XTargets,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -242,7 +241,6 @@ namespace Logs {
|
||||
"Zoning",
|
||||
"EqTime",
|
||||
"Corpses",
|
||||
"XTargets"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -834,16 +834,6 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::Corpses, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogXTargets(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::XTargets))\
|
||||
OutF(LogSys, Logs::General, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogXTargetsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::XTargets))\
|
||||
OutF(LogSys, Logs::Detail, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
@@ -789,36 +789,50 @@ std::string PlayerEventDiscordFormatter::FormatNPCHandinEvent(
|
||||
);
|
||||
}
|
||||
|
||||
std::string npc_info = fmt::format(
|
||||
"{} ({})\n",
|
||||
e.npc_name,
|
||||
e.npc_id
|
||||
);
|
||||
|
||||
npc_info += fmt::format(
|
||||
"Is Quest Handin: {}",
|
||||
e.is_quest_handin ? "Yes" : "No"
|
||||
);
|
||||
|
||||
std::vector<DiscordField> f = {};
|
||||
|
||||
|
||||
BuildDiscordField(&f, "NPC", npc_info);
|
||||
|
||||
if (!handin_items_info.empty()) {
|
||||
BuildDiscordField(&f, "Handin Items", handin_items_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Handin Items",
|
||||
fmt::format(
|
||||
"{}",
|
||||
handin_items_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!handin_money_info.empty()) {
|
||||
BuildDiscordField(&f, "Handin Money", handin_money_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Handin Money",
|
||||
fmt::format(
|
||||
"{}",
|
||||
handin_money_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!return_items_info.empty()) {
|
||||
BuildDiscordField(&f, "Return Items", return_items_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Return Items",
|
||||
fmt::format(
|
||||
"{}",
|
||||
return_items_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!return_money_info.empty()) {
|
||||
BuildDiscordField(&f, "Return Money", return_money_info);
|
||||
BuildDiscordField(
|
||||
&f,
|
||||
"Return Money",
|
||||
fmt::format(
|
||||
"{}",
|
||||
return_money_info
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<DiscordEmbed> embeds = {};
|
||||
|
||||
@@ -642,10 +642,6 @@ void PlayerEventLogs::ProcessRetentionTruncation()
|
||||
void PlayerEventLogs::ReloadSettings()
|
||||
{
|
||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
||||
if (e.id >= PlayerEvent::MAX || e.id < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_settings[e.id] = e;
|
||||
}
|
||||
}
|
||||
@@ -654,59 +650,55 @@ const int32_t RETENTION_DAYS_DEFAULT = 7;
|
||||
|
||||
void PlayerEventLogs::SetSettingsDefaults()
|
||||
{
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_PLAT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_SEND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_RETRIEVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::PARCEL_DELETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BARTER_TRANSACTION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GUILD_TRIBUTE_DONATE_PLAT].event_enabled = 1;
|
||||
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||
|
||||
@@ -58,10 +58,6 @@ namespace PlayerEvent {
|
||||
ITEM_CREATION,
|
||||
GUILD_TRIBUTE_DONATE_ITEM,
|
||||
GUILD_TRIBUTE_DONATE_PLAT,
|
||||
PARCEL_SEND,
|
||||
PARCEL_RETRIEVE,
|
||||
PARCEL_DELETE,
|
||||
BARTER_TRANSACTION,
|
||||
MAX // dont remove
|
||||
};
|
||||
|
||||
@@ -70,7 +66,7 @@ namespace PlayerEvent {
|
||||
// If event is unimplemented just tag (Unimplemented) in the name
|
||||
// Events don't get saved to the database if unimplemented or deprecated
|
||||
// Events tagged as deprecated will get automatically removed
|
||||
static const char *EventName[EventType::MAX] = {
|
||||
static const char *EventName[PlayerEvent::MAX] = {
|
||||
"None",
|
||||
"GM Command",
|
||||
"Zoning",
|
||||
@@ -120,11 +116,7 @@ namespace PlayerEvent {
|
||||
"Killed Raid NPC",
|
||||
"Item Creation",
|
||||
"Guild Tribute Donate Item",
|
||||
"Guild Tribute Donate Platinum",
|
||||
"Parcel Item Sent",
|
||||
"Parcel Item Retrieved",
|
||||
"Parcel Prune Routine",
|
||||
"Barter Transaction"
|
||||
"Guild Tribute Donate Platinum"
|
||||
};
|
||||
|
||||
// Generic struct used by all events
|
||||
@@ -860,12 +852,10 @@ namespace PlayerEvent {
|
||||
|
||||
class HandinEntry {
|
||||
public:
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
std::vector<uint32> augment_ids;
|
||||
std::vector<std::string> augment_names;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -874,8 +864,6 @@ namespace PlayerEvent {
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(augment_ids),
|
||||
CEREAL_NVP(augment_names),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(attuned)
|
||||
);
|
||||
@@ -909,7 +897,6 @@ namespace PlayerEvent {
|
||||
HandinMoney handin_money;
|
||||
std::vector<HandinEntry> return_items;
|
||||
HandinMoney return_money;
|
||||
bool is_quest_handin;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
@@ -921,8 +908,7 @@ namespace PlayerEvent {
|
||||
CEREAL_NVP(handin_items),
|
||||
CEREAL_NVP(handin_money),
|
||||
CEREAL_NVP(return_items),
|
||||
CEREAL_NVP(return_money),
|
||||
CEREAL_NVP(is_quest_handin)
|
||||
CEREAL_NVP(return_money)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -990,131 +976,6 @@ namespace PlayerEvent {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelRetrieve {
|
||||
uint32 item_id;
|
||||
uint32 quantity;
|
||||
std::string from_player_name;
|
||||
uint32 sent_date;
|
||||
uint32 aug_slot_1;
|
||||
uint32 aug_slot_2;
|
||||
uint32 aug_slot_3;
|
||||
uint32 aug_slot_4;
|
||||
uint32 aug_slot_5;
|
||||
uint32 aug_slot_6;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(from_player_name),
|
||||
CEREAL_NVP(sent_date),
|
||||
CEREAL_NVP(aug_slot_1),
|
||||
CEREAL_NVP(aug_slot_2),
|
||||
CEREAL_NVP(aug_slot_3),
|
||||
CEREAL_NVP(aug_slot_4),
|
||||
CEREAL_NVP(aug_slot_5),
|
||||
CEREAL_NVP(aug_slot_6)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelSend {
|
||||
uint32 item_id;
|
||||
uint32 quantity;
|
||||
std::string from_player_name;
|
||||
std::string to_player_name;
|
||||
uint32 sent_date;
|
||||
uint32 aug_slot_1;
|
||||
uint32 aug_slot_2;
|
||||
uint32 aug_slot_3;
|
||||
uint32 aug_slot_4;
|
||||
uint32 aug_slot_5;
|
||||
uint32 aug_slot_6;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(from_player_name),
|
||||
CEREAL_NVP(to_player_name),
|
||||
CEREAL_NVP(sent_date),
|
||||
CEREAL_NVP(aug_slot_1),
|
||||
CEREAL_NVP(aug_slot_2),
|
||||
CEREAL_NVP(aug_slot_3),
|
||||
CEREAL_NVP(aug_slot_4),
|
||||
CEREAL_NVP(aug_slot_5),
|
||||
CEREAL_NVP(aug_slot_6)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ParcelDelete {
|
||||
uint32 item_id;
|
||||
uint32 quantity;
|
||||
uint32 char_id;
|
||||
std::string from_name;
|
||||
std::string note;
|
||||
uint32 sent_date;
|
||||
uint32 aug_slot_1;
|
||||
uint32 aug_slot_2;
|
||||
uint32 aug_slot_3;
|
||||
uint32 aug_slot_4;
|
||||
uint32 aug_slot_5;
|
||||
uint32 aug_slot_6;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(quantity),
|
||||
CEREAL_NVP(char_id),
|
||||
CEREAL_NVP(from_name),
|
||||
CEREAL_NVP(note),
|
||||
CEREAL_NVP(sent_date),
|
||||
CEREAL_NVP(aug_slot_1),
|
||||
CEREAL_NVP(aug_slot_2),
|
||||
CEREAL_NVP(aug_slot_3),
|
||||
CEREAL_NVP(aug_slot_4),
|
||||
CEREAL_NVP(aug_slot_5),
|
||||
CEREAL_NVP(aug_slot_6)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct BarterTransaction {
|
||||
std::string status;
|
||||
uint32 item_id;
|
||||
uint32 item_quantity;
|
||||
std::string item_name;
|
||||
std::vector<BuyerLineTradeItems_Struct> trade_items;
|
||||
std::string buyer_name;
|
||||
std::string seller_name;
|
||||
uint64 total_cost;
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(status),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_quantity),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(trade_items),
|
||||
CEREAL_NVP(buyer_name),
|
||||
CEREAL_NVP(seller_name),
|
||||
CEREAL_NVP(total_cost)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENTS_H
|
||||
|
||||
+65
-44
@@ -92,20 +92,10 @@ BaseGuildManager::~BaseGuildManager()
|
||||
bool BaseGuildManager::LoadGuilds()
|
||||
{
|
||||
ClearGuilds();
|
||||
auto guilds = GuildsRepository::GetWhere(
|
||||
*m_db,
|
||||
fmt::format("`id` < '{}'", RoF2::constants::MAX_GUILD_ID)
|
||||
);
|
||||
auto guilds_ranks = GuildRanksRepository::LoadAll(*m_db);
|
||||
auto guilds_permissions = GuildPermissionsRepository::LoadAll(*m_db);
|
||||
auto guilds_tributes = GuildTributesRepository::GetWhere(
|
||||
*m_db,
|
||||
fmt::format(
|
||||
"`guild_id` < '{}'",
|
||||
RoF2::constants::MAX_GUILD_ID
|
||||
)
|
||||
);
|
||||
|
||||
auto guilds = GuildsRepository::All(*m_db);
|
||||
auto guilds_ranks = GuildRanksRepository::All(*m_db);
|
||||
auto guilds_permissions = GuildPermissionsRepository::All(*m_db);
|
||||
auto guilds_tributes = GuildTributesRepository::All(*m_db);
|
||||
|
||||
if (guilds.empty()) {
|
||||
LogGuilds("No Guilds found in database.");
|
||||
@@ -118,27 +108,22 @@ bool BaseGuildManager::LoadGuilds()
|
||||
|
||||
_CreateGuild(g.id, g.name, g.leader, g.minstatus, g.motd, g.motd_setter, g.channel, g.url, g.favor);
|
||||
|
||||
for (int i = 1; i <= GUILD_MAX_RANK; i++) {
|
||||
auto key = fmt::format("{}-{}", g.id, i);
|
||||
|
||||
if (guilds_ranks.contains(key)) {
|
||||
m_guilds[g.id]->rank_names[i] = guilds_ranks.find(key)->second;
|
||||
for (auto const &r: guilds_ranks) {
|
||||
if (r.guild_id == g.id) {
|
||||
m_guilds[g.id]->rank_names[r.rank_] = r.title;
|
||||
}
|
||||
}
|
||||
|
||||
auto count = 0;
|
||||
|
||||
for (int i = 1; i <= GUILD_MAX_FUNCTIONS; i++) {
|
||||
auto key = fmt::format("{}-{}", g.id, i);
|
||||
if (guilds_permissions.contains(key)) {
|
||||
auto p = guilds_permissions.find(key)->second;
|
||||
for (auto const &p: guilds_permissions) {
|
||||
if (p.guild_id == g.id) {
|
||||
m_guilds[g.id]->functions[p.perm_id].id = p.id;
|
||||
m_guilds[g.id]->functions[p.perm_id].guild_id = p.guild_id;
|
||||
m_guilds[g.id]->functions[p.perm_id].perm_id = p.perm_id;
|
||||
m_guilds[g.id]->functions[p.perm_id].perm_value = p.permission;
|
||||
count++;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count < GUILD_MAX_FUNCTIONS) {
|
||||
@@ -357,14 +342,41 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 BaseGuildManager::_GetFreeGuildID()
|
||||
{
|
||||
GuildsRepository::DeleteWhere(*m_db, "`name` = ''");
|
||||
|
||||
GuildsRepository::Guilds out;
|
||||
out.id = 0;
|
||||
out.leader = 0;
|
||||
out.minstatus = 0;
|
||||
out.tribute = 0;
|
||||
out.name = "";
|
||||
out.motd = "";
|
||||
out.motd_setter = "";
|
||||
out.url = "";
|
||||
out.channel = "";
|
||||
auto last_insert_id = GuildsRepository::InsertOne(*m_db, out);
|
||||
if (last_insert_id.id > 0) {
|
||||
LogGuilds("Located a free guild ID [{}] in the database", last_insert_id.id);
|
||||
return last_insert_id.id;
|
||||
}
|
||||
|
||||
LogGuilds("Unable to find a free guild ID in the database");
|
||||
return GUILD_NONE;
|
||||
}
|
||||
|
||||
uint32 BaseGuildManager::CreateGuild(std::string name, uint32 leader_char_id)
|
||||
{
|
||||
uint32 guild_id = UpdateDbCreateGuild(name, leader_char_id);
|
||||
if (guild_id == GUILD_NONE) {
|
||||
return (GUILD_NONE);
|
||||
}
|
||||
uint32 guild_id = UpdateDbCreateGuild(name, leader_char_id);
|
||||
if (guild_id == GUILD_NONE) {
|
||||
return (GUILD_NONE);
|
||||
}
|
||||
//RefreshGuild(guild_id);
|
||||
//SendGuildRefresh(guild_id, true, false, false, false);
|
||||
//SendCharRefresh(GUILD_NONE, guild_id, leader_char_id);
|
||||
|
||||
return guild_id;
|
||||
return guild_id;
|
||||
}
|
||||
|
||||
bool BaseGuildManager::DeleteGuild(uint32 guild_id)
|
||||
@@ -527,8 +539,8 @@ bool BaseGuildManager::SetPublicNote(uint32 charid, std::string public_note)
|
||||
|
||||
uint32 BaseGuildManager::UpdateDbCreateGuild(std::string name, uint32 leader)
|
||||
{
|
||||
auto new_id = GuildsRepository::GetMaxId(*m_db) + 1;
|
||||
if (!new_id) {
|
||||
auto new_id = _GetFreeGuildID();
|
||||
if (new_id == GUILD_NONE) {
|
||||
return GUILD_NONE;
|
||||
}
|
||||
|
||||
@@ -944,24 +956,33 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into)
|
||||
|
||||
}
|
||||
|
||||
GuildsListMessaging_Struct BaseGuildManager::MakeGuildList()
|
||||
//returns ownership of the buffer.
|
||||
uint8 *BaseGuildManager::MakeGuildList(const char *head_name, uint32 &length) const
|
||||
{
|
||||
GuildsListMessaging_Struct guild_list_messaging{};
|
||||
uint32 string_length = 0;
|
||||
//dynamic structs will make this a lot less painful.
|
||||
|
||||
for (auto const &g: m_guilds) {
|
||||
GuildsListMessagingEntry_Struct guild_entry{};
|
||||
length = sizeof(GuildsList_Struct);
|
||||
auto buffer = new uint8[length];
|
||||
|
||||
guild_entry.guild_id = g.first;
|
||||
guild_entry.guild_name = g.second->name;
|
||||
string_length += g.second->name.length() + 1;
|
||||
guild_list_messaging.guild_detail.push_back(guild_entry);
|
||||
//a bit little better than memsetting the whole thing...
|
||||
uint32 r, pos;
|
||||
for (r = 0, pos = 0; r <= MAX_NUMBER_GUILDS; r++, pos += 64) {
|
||||
//strcpy((char *) buffer+pos, "BAD GUILD");
|
||||
// These 'BAD GUILD' entries were showing in the drop-downs for selecting guilds in the LFP window,
|
||||
// so just fill unused entries with an empty string instead.
|
||||
buffer[pos] = '\0';
|
||||
}
|
||||
|
||||
guild_list_messaging.no_of_guilds = m_guilds.size();
|
||||
guild_list_messaging.string_length = string_length;
|
||||
strn0cpy((char *) buffer, head_name, 64);
|
||||
|
||||
return guild_list_messaging;
|
||||
std::map<uint32, GuildInfo *>::const_iterator cur, end;
|
||||
cur = m_guilds.begin();
|
||||
end = m_guilds.end();
|
||||
for (; cur != end; ++cur) {
|
||||
pos = 64 + (64 * cur->first);
|
||||
strn0cpy((char *) buffer + pos, cur->second->name.c_str(), 64);
|
||||
}
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
const char *BaseGuildManager::GetRankName(uint32 guild_id, uint8 rank) const
|
||||
|
||||
+2
-1
@@ -134,7 +134,7 @@ class BaseGuildManager
|
||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||
bool CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const;
|
||||
bool UpdateDbBankerFlag(uint32 charid, bool is_banker);
|
||||
GuildsListMessaging_Struct MakeGuildList();
|
||||
uint8* MakeGuildList(const char* head_name, uint32& length) const; //make a guild list packet, returns ownership of the buffer.
|
||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||
uint32 GetGuildIDByName(const char *GuildName);
|
||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
||||
@@ -208,6 +208,7 @@ class BaseGuildManager
|
||||
|
||||
bool _StoreGuildDB(uint32 guild_id);
|
||||
GuildInfo* _CreateGuild(uint32 guild_id, std::string guild_name, uint32 leader_char_id, uint8 minstatus, std::string guild_motd, std::string motd_setter, std::string Channel, std::string URL, uint32 favour);
|
||||
uint32 _GetFreeGuildID();
|
||||
GuildsRepository::Guilds CreateGuildRepoFromGuildInfo(uint32 guild_id, BaseGuildManager::GuildInfo& in);
|
||||
};
|
||||
#endif /*GUILD_BASE_H_*/
|
||||
|
||||
@@ -276,7 +276,7 @@ bool EQ::InventoryProfile::SwapItem(
|
||||
SwapItemFailState &fail_state,
|
||||
uint16 race_id,
|
||||
uint8 class_id,
|
||||
uint32 deity_id,
|
||||
uint16 deity_id,
|
||||
uint8 level
|
||||
) {
|
||||
fail_state = swapInvalid;
|
||||
@@ -354,7 +354,7 @@ bool EQ::InventoryProfile::SwapItem(
|
||||
fail_state = swapRaceClass;
|
||||
return false;
|
||||
}
|
||||
if (deity_id && source_item->Deity && !(Deity::GetBitmask(deity_id) & source_item->Deity)) {
|
||||
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
|
||||
fail_state = swapDeity;
|
||||
return false;
|
||||
}
|
||||
@@ -380,7 +380,7 @@ bool EQ::InventoryProfile::SwapItem(
|
||||
fail_state = swapRaceClass;
|
||||
return false;
|
||||
}
|
||||
if (deity_id && destination_item->Deity && !(Deity::GetBitmask(deity_id) & destination_item->Deity)) {
|
||||
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
|
||||
fail_state = swapDeity;
|
||||
return false;
|
||||
}
|
||||
@@ -1743,68 +1743,3 @@ std::vector<uint32> EQ::InventoryProfile::GetAugmentIDsBySlotID(int16 slot_id)
|
||||
|
||||
return augments;
|
||||
}
|
||||
|
||||
std::vector<int16> EQ::InventoryProfile::FindAllFreeSlotsThatFitItem(const EQ::ItemData *item_data)
|
||||
{
|
||||
std::vector<int16> free_slots{};
|
||||
for (int16 i = EQ::invslot::GENERAL_BEGIN; i <= EQ::invslot::GENERAL_END; i++) {
|
||||
if ((((uint64) 1 << i) & GetLookup()->PossessionsBitmask) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EQ::ItemInstance *inv_item = GetItem(i);
|
||||
|
||||
if (!inv_item) {
|
||||
// Found available slot in personal inventory
|
||||
free_slots.push_back(i);
|
||||
}
|
||||
|
||||
if (inv_item->IsClassBag() &&
|
||||
EQ::InventoryProfile::CanItemFitInContainer(item_data, inv_item->GetItem())) {
|
||||
|
||||
int16 base_slot_id = EQ::InventoryProfile::CalcSlotId(i, EQ::invbag::SLOT_BEGIN);
|
||||
uint8 bag_size = inv_item->GetItem()->BagSlots;
|
||||
|
||||
for (uint8 bag_slot = EQ::invbag::SLOT_BEGIN; bag_slot < bag_size; bag_slot++) {
|
||||
auto bag_item = GetItem(base_slot_id + bag_slot);
|
||||
if (!bag_item) {
|
||||
// Found available slot within bag
|
||||
free_slots.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return free_slots;
|
||||
}
|
||||
|
||||
int16 EQ::InventoryProfile::FindFirstFreeSlotThatFitsItem(const EQ::ItemData *item_data)
|
||||
{
|
||||
for (int16 i = EQ::invslot::GENERAL_BEGIN; i <= EQ::invslot::GENERAL_END; i++) {
|
||||
if ((((uint64) 1 << i) & GetLookup()->PossessionsBitmask) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
EQ::ItemInstance *inv_item = GetItem(i);
|
||||
|
||||
if (!inv_item) {
|
||||
// Found available slot in personal inventory
|
||||
return i;
|
||||
}
|
||||
|
||||
if (inv_item->IsClassBag() &&
|
||||
EQ::InventoryProfile::CanItemFitInContainer(item_data, inv_item->GetItem())) {
|
||||
|
||||
int16 base_slot_id = EQ::InventoryProfile::CalcSlotId(i, EQ::invbag::SLOT_BEGIN);
|
||||
uint8 bag_size = inv_item->GetItem()->BagSlots;
|
||||
|
||||
for (uint8 bag_slot = EQ::invbag::SLOT_BEGIN; bag_slot < bag_size; bag_slot++) {
|
||||
auto bag_item = GetItem(base_slot_id + bag_slot);
|
||||
if (!bag_item) {
|
||||
// Found available slot within bag
|
||||
return base_slot_id + bag_slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ namespace EQ
|
||||
|
||||
// Swap items in inventory
|
||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = Race::Doug, uint8 class_id = Class::None, uint32 deity_id = Deity::Unknown, uint8 level = 0);
|
||||
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = Race::Doug, uint8 class_id = Class::None, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
||||
|
||||
// Remove item from inventory
|
||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
||||
@@ -176,8 +176,6 @@ namespace EQ
|
||||
// Locate an available inventory slot
|
||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = invslot::GENERAL_BEGIN, uint8 bag_start = invbag::SLOT_BEGIN);
|
||||
std::vector<int16> FindAllFreeSlotsThatFitItem(const EQ::ItemData *inst);
|
||||
int16 FindFirstFreeSlotThatFitsItem(const EQ::ItemData *inst);
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||
|
||||
+21
-55
@@ -81,79 +81,45 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* Gets local address - pings google to inspect what interface was used locally
|
||||
* @return
|
||||
*/
|
||||
std::string IpUtil::GetLocalIPAddress()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
char my_ip_address[INET_ADDRSTRLEN];
|
||||
char my_ip_address[16];
|
||||
unsigned int my_port;
|
||||
struct sockaddr_in server_address{};
|
||||
struct sockaddr_in my_address{};
|
||||
int sockfd;
|
||||
int sockfd;
|
||||
|
||||
// Create a UDP socket
|
||||
#ifdef _WIN32
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd == INVALID_SOCKET) {
|
||||
WSACleanup();
|
||||
return "";
|
||||
}
|
||||
#else
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sockfd < 0) {
|
||||
// Connect to server
|
||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set server_addr (dummy address)
|
||||
// Set server_addr
|
||||
memset(&server_address, 0, sizeof(server_address));
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = inet_addr("8.8.8.8"); // Google DNS
|
||||
server_address.sin_port = htons(53); // DNS port
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
|
||||
server_address.sin_port = htons(80);
|
||||
|
||||
// Perform a dummy connection to the server (UDP)
|
||||
connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
|
||||
// Connect to server
|
||||
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
|
||||
close(sockfd);
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get my IP address
|
||||
// Get my ip address and port
|
||||
memset(&my_address, 0, sizeof(my_address));
|
||||
socklen_t len = sizeof(my_address);
|
||||
getsockname(sockfd, (struct sockaddr *) &my_address, &len);
|
||||
inet_ntop(AF_INET, &my_address.sin_addr, my_ip_address, sizeof(my_ip_address));
|
||||
my_port = ntohs(my_address.sin_port);
|
||||
|
||||
#ifdef _WIN32
|
||||
closesocket(sockfd);
|
||||
WSACleanup();
|
||||
#else
|
||||
close(sockfd);
|
||||
#endif
|
||||
|
||||
LogInfo("Local IP Address [{}]", my_ip_address);
|
||||
|
||||
return std::string(my_ip_address);
|
||||
return fmt::format("{}", my_ip_address);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets public address
|
||||
* Uses various websites as options to return raw public IP back to the client
|
||||
|
||||
+66
-69
@@ -58,75 +58,72 @@ namespace EQ
|
||||
};
|
||||
|
||||
enum ItemType : uint8 {
|
||||
/*9138*/ ItemType1HSlash = 0,
|
||||
/*9141*/ ItemType2HSlash,
|
||||
/*9140*/ ItemType1HPiercing,
|
||||
/*9139*/ ItemType1HBlunt,
|
||||
/*9142*/ ItemType2HBlunt,
|
||||
/*5504*/ ItemTypeBow, // 5
|
||||
/*----*/ ItemTypeUnknown1,
|
||||
/*----*/ ItemTypeLargeThrowing,
|
||||
/*5505*/ ItemTypeShield,
|
||||
/*5506*/ ItemTypeScroll,
|
||||
/*5507*/ ItemTypeArmor, // 10
|
||||
/*5508*/ ItemTypeMisc, // a lot of random crap has this item use.
|
||||
/*7564*/ ItemTypeLockPick,
|
||||
/*----*/ ItemTypeUnknown2,
|
||||
/*5509*/ ItemTypeFood,
|
||||
/*5510*/ ItemTypeDrink, // 15
|
||||
/*5511*/ ItemTypeLight,
|
||||
/*5512*/ ItemTypeCombinable, // not all stackable items are this use...
|
||||
/*5513*/ ItemTypeBandage,
|
||||
/*----*/ ItemTypeSmallThrowing,
|
||||
/*----*/ ItemTypeSpell, // 20 // spells and tomes
|
||||
/*5514*/ ItemTypePotion,
|
||||
/*----*/ ItemTypeUnknown3,
|
||||
/*0406*/ ItemTypeWindInstrument,
|
||||
/*0407*/ ItemTypeStringedInstrument,
|
||||
/*0408*/ ItemTypeBrassInstrument, // 25
|
||||
/*0405*/ ItemTypePercussionInstrument,
|
||||
/*5515*/ ItemTypeArrow,
|
||||
/*----*/ ItemTypeUnknown4,
|
||||
/*5521*/ ItemTypeJewelry,
|
||||
/*----*/ ItemTypeSkull, // 30
|
||||
/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...)
|
||||
/*5517*/ ItemTypeNote,
|
||||
/*5518*/ ItemTypeKey,
|
||||
/*----*/ ItemTypeCoin,
|
||||
/*5520*/ ItemType2HPiercing, // 35
|
||||
/*----*/ ItemTypeFishingPole,
|
||||
/*----*/ ItemTypeFishingBait,
|
||||
/*5519*/ ItemTypeAlcohol,
|
||||
/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?)
|
||||
/*----*/ ItemTypeCompass, // 40
|
||||
/*----*/ ItemTypeUnknown5,
|
||||
/*----*/ ItemTypePoison, // might be wrong, but includes poisons
|
||||
/*----*/ ItemTypeUnknown6,
|
||||
/*----*/ ItemTypeUnknown7,
|
||||
/*5522*/ ItemTypeMartial, // 45
|
||||
/*----*/ ItemTypeAllEffects,
|
||||
/*----*/ ItemTypeUnknown9,
|
||||
/*----*/ ItemTypeUnknown10,
|
||||
/*----*/ ItemTypeFocusEffect,
|
||||
/*----*/ ItemTypeSinging, // 50
|
||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||
/*5776*/ ItemTypeCharm,
|
||||
/*----*/ ItemTypeDye,
|
||||
/*----*/ ItemTypeAugmentation,
|
||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||
/*----*/ ItemTypeAugmentationDistiller,
|
||||
/*----*/ ItemTypeAlternateAbility,
|
||||
/*----*/ ItemTypeFellowshipKit,
|
||||
/*----*/ ItemTypeUnknown13,
|
||||
/*----*/ ItemTypeRecipe, // 60
|
||||
/*----*/ ItemTypeAdvancedRecipe,
|
||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||
/*----*/ ItemTypeCount,
|
||||
/*----*/ ItemTypeCollectible,
|
||||
/*----*/ ItemTypeContainer,
|
||||
/*----*/ ItemTypeAll = 0xFF
|
||||
/*9138*/ ItemType1HSlash = 0,
|
||||
/*9141*/ ItemType2HSlash,
|
||||
/*9140*/ ItemType1HPiercing,
|
||||
/*9139*/ ItemType1HBlunt,
|
||||
/*9142*/ ItemType2HBlunt,
|
||||
/*5504*/ ItemTypeBow, // 5
|
||||
/*----*/ ItemTypeUnknown1,
|
||||
/*----*/ ItemTypeLargeThrowing,
|
||||
/*5505*/ ItemTypeShield,
|
||||
/*5506*/ ItemTypeScroll,
|
||||
/*5507*/ ItemTypeArmor, // 10
|
||||
/*5508*/ ItemTypeMisc, // a lot of random crap has this item use.
|
||||
/*7564*/ ItemTypeLockPick,
|
||||
/*----*/ ItemTypeUnknown2,
|
||||
/*5509*/ ItemTypeFood,
|
||||
/*5510*/ ItemTypeDrink, // 15
|
||||
/*5511*/ ItemTypeLight,
|
||||
/*5512*/ ItemTypeCombinable, // not all stackable items are this use...
|
||||
/*5513*/ ItemTypeBandage,
|
||||
/*----*/ ItemTypeSmallThrowing,
|
||||
/*----*/ ItemTypeSpell, // 20 // spells and tomes
|
||||
/*5514*/ ItemTypePotion,
|
||||
/*----*/ ItemTypeUnknown3,
|
||||
/*0406*/ ItemTypeWindInstrument,
|
||||
/*0407*/ ItemTypeStringedInstrument,
|
||||
/*0408*/ ItemTypeBrassInstrument, // 25
|
||||
/*0405*/ ItemTypePercussionInstrument,
|
||||
/*5515*/ ItemTypeArrow,
|
||||
/*----*/ ItemTypeUnknown4,
|
||||
/*5521*/ ItemTypeJewelry,
|
||||
/*----*/ ItemTypeSkull, // 30
|
||||
/*5516*/ ItemTypeBook, // skill-up tomes/books? (would probably need a pp flag if true...)
|
||||
/*5517*/ ItemTypeNote,
|
||||
/*5518*/ ItemTypeKey,
|
||||
/*----*/ ItemTypeCoin,
|
||||
/*5520*/ ItemType2HPiercing, // 35
|
||||
/*----*/ ItemTypeFishingPole,
|
||||
/*----*/ ItemTypeFishingBait,
|
||||
/*5519*/ ItemTypeAlcohol,
|
||||
/*----*/ ItemTypeKey2, // keys and satchels?? (questable keys?)
|
||||
/*----*/ ItemTypeCompass, // 40
|
||||
/*----*/ ItemTypeUnknown5,
|
||||
/*----*/ ItemTypePoison, // might be wrong, but includes poisons
|
||||
/*----*/ ItemTypeUnknown6,
|
||||
/*----*/ ItemTypeUnknown7,
|
||||
/*5522*/ ItemTypeMartial, // 45
|
||||
/*----*/ ItemTypeUnknown8,
|
||||
/*----*/ ItemTypeUnknown9,
|
||||
/*----*/ ItemTypeUnknown10,
|
||||
/*----*/ ItemTypeUnknown11,
|
||||
/*----*/ ItemTypeSinging, // 50
|
||||
/*5750*/ ItemTypeAllInstrumentTypes,
|
||||
/*5776*/ ItemTypeCharm,
|
||||
/*----*/ ItemTypeDye,
|
||||
/*----*/ ItemTypeAugmentation,
|
||||
/*----*/ ItemTypeAugmentationSolvent, // 55
|
||||
/*----*/ ItemTypeAugmentationDistiller,
|
||||
/*----*/ ItemTypeUnknown12,
|
||||
/*----*/ ItemTypeFellowshipKit,
|
||||
/*----*/ ItemTypeUnknown13,
|
||||
/*----*/ ItemTypeRecipe, // 60
|
||||
/*----*/ ItemTypeAdvancedRecipe,
|
||||
/*----*/ ItemTypeJournal, // only one(1) database entry
|
||||
/*----*/ ItemTypeAltCurrency, // alt-currency (as opposed to coinage)
|
||||
/*5881*/ ItemTypePerfectedAugmentationDistiller,
|
||||
/*----*/ ItemTypeCount
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
|
||||
+37
-176
@@ -32,11 +32,10 @@
|
||||
|
||||
//#include <iostream>
|
||||
|
||||
int32 next_item_serial_number = 1;
|
||||
std::unordered_set<uint64> guids{};
|
||||
int32 NextItemInstSerialNumber = 1;
|
||||
|
||||
static inline int32 GetNextItemInstSerialNumber() {
|
||||
|
||||
static inline int32 GetNextItemInstSerialNumber()
|
||||
{
|
||||
// The Bazaar relies on each item a client has up for Trade having a unique
|
||||
// identifier. This 'SerialNumber' is sent in Serialized item packets and
|
||||
// is used in Bazaar packets to identify the item a player is buying or inspecting.
|
||||
@@ -47,18 +46,12 @@ static inline int32 GetNextItemInstSerialNumber()
|
||||
// NextItemInstSerialNumber is the next one to hand out.
|
||||
//
|
||||
// It is very unlikely to reach 2,147,483,647. Maybe we should call abort(), rather than wrapping back to 1.
|
||||
if (next_item_serial_number >= INT32_MAX) {
|
||||
next_item_serial_number = 1;
|
||||
}
|
||||
else {
|
||||
next_item_serial_number++;
|
||||
}
|
||||
if(NextItemInstSerialNumber >= INT_MAX)
|
||||
NextItemInstSerialNumber = 1;
|
||||
else
|
||||
NextItemInstSerialNumber++;
|
||||
|
||||
while (guids.contains(next_item_serial_number)) {
|
||||
next_item_serial_number++;
|
||||
}
|
||||
|
||||
return next_item_serial_number;
|
||||
return NextItemInstSerialNumber;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -310,34 +303,47 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
for (int16 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
||||
if (IsAugmentSlotAvailable(augment_type, slot_id)) {
|
||||
return slot_id;
|
||||
auto i = invaug::SOCKET_BEGIN;
|
||||
for (; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetItem(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[i] &&
|
||||
((1 << (m_item->AugSlotType[i] - 1)) & augment_type)
|
||||
)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon() || GetItem(slot)) {
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
if (
|
||||
(
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
)
|
||||
) &&
|
||||
(
|
||||
RuleB(Items, AugmentItemAllowInvisibleAugments) ||
|
||||
!GetItem(slot) &&
|
||||
m_item->AugSlotVisible[slot]
|
||||
) &&
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
)
|
||||
);
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve item inside container
|
||||
@@ -1286,7 +1292,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||
return race;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemBaneDamageBody(uint8 against, bool augments) const
|
||||
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
|
||||
{
|
||||
int64 damage = 0;
|
||||
const auto item = GetItem();
|
||||
@@ -1806,151 +1812,6 @@ std::vector<uint32> EQ::ItemInstance::GetAugmentIDs() const
|
||||
return augments;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemRegen(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->Regen;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemRegen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemManaRegen(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->ManaRegen;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemManaRegen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemDamageShield(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->DamageShield;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemDamageShield();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemDSMitigation(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->DSMitigation;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemDSMitigation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemHealAmt(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->HealAmt;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemHealAmt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemSpellDamage(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->SpellDmg;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemSpellDamage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemClairvoyance(bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->Clairvoyance;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemClairvoyance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int EQ::ItemInstance::GetItemSkillsStat(EQ::skills::SkillType skill, bool augments) const
|
||||
{
|
||||
int stat = 0;
|
||||
const auto item = GetItem();
|
||||
if (item) {
|
||||
stat = item->ExtraDmgSkill == skill ? item->ExtraDmgAmt : 0;
|
||||
if (augments) {
|
||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; ++i) {
|
||||
if (GetAugment(i)) {
|
||||
stat += GetAugment(i)->GetItemSkillsStat(skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::AddGUIDToMap(uint64 existing_serial_number)
|
||||
{
|
||||
guids.emplace(existing_serial_number);
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::ClearGUIDMap()
|
||||
{
|
||||
guids.clear();
|
||||
}
|
||||
//
|
||||
// class EvolveInfo
|
||||
//
|
||||
|
||||
+1
-11
@@ -265,12 +265,11 @@ namespace EQ
|
||||
// these two are just quick checks
|
||||
int GetItemBaneDamageBody(bool augments = false) const;
|
||||
int GetItemBaneDamageRace(bool augments = false) const;
|
||||
int GetItemBaneDamageBody(uint8 against, bool augments = false) const;
|
||||
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
|
||||
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
|
||||
int GetItemMagical(bool augments = false) const;
|
||||
int GetItemHP(bool augments = false) const;
|
||||
int GetItemMana(bool augments = false) const;
|
||||
int GetItemManaRegen(bool augments = false) const;
|
||||
int GetItemEndur(bool augments = false) const;
|
||||
int GetItemAttack(bool augments = false) const;
|
||||
int GetItemStr(bool augments = false) const;
|
||||
@@ -300,17 +299,8 @@ namespace EQ
|
||||
int GetItemHeroicDR(bool augments = false) const;
|
||||
int GetItemHeroicCorrup(bool augments = false) const;
|
||||
int GetItemHaste(bool augments = false) const;
|
||||
int GetItemRegen(bool augments = false) const;
|
||||
int GetItemDamageShield(bool augments = false) const;
|
||||
int GetItemDSMitigation(bool augments = false) const;
|
||||
int GetItemHealAmt(bool augments = false) const;
|
||||
int GetItemSpellDamage(bool augments = false) const;
|
||||
int GetItemClairvoyance(bool augments = false) const;
|
||||
int GetItemSkillsStat(EQ::skills::SkillType skill, bool augments = false) const;
|
||||
uint32 GetItemGuildFavor() const;
|
||||
std::vector<uint32> GetAugmentIDs() const;
|
||||
static void AddGUIDToMap(uint64 existing_serial_number);
|
||||
static void ClearGUIDMap();
|
||||
|
||||
protected:
|
||||
//////////////////////////
|
||||
|
||||
@@ -1,600 +0,0 @@
|
||||
#include "mysql_stmt.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "mutex.h"
|
||||
#include "timer.h"
|
||||
#include <charconv>
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
void PreparedStmt::StmtDeleter::operator()(MYSQL_STMT* stmt) noexcept
|
||||
{
|
||||
// The connection must be locked when closing the stmt to avoid mysql errors
|
||||
// in case another thread tries to use it during the close. If the mutex is
|
||||
// changed to one that throws then exceptions need to be caught here.
|
||||
LockMutex lock(mutex);
|
||||
mysql_stmt_close(stmt);
|
||||
}
|
||||
|
||||
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts)
|
||||
: m_stmt(mysql_stmt_init(&mysql), { mutex }), m_query(std::move(query)), m_mutex(mutex), m_options(opts)
|
||||
{
|
||||
LockMutex lock(m_mutex);
|
||||
if (mysql_stmt_prepare(m_stmt.get(), m_query.c_str(), static_cast<unsigned long>(m_query.size())) != 0)
|
||||
{
|
||||
ThrowError(fmt::format("Prepare error: {}", GetStmtError()));
|
||||
}
|
||||
|
||||
m_params.resize(mysql_stmt_param_count(m_stmt.get()));
|
||||
m_inputs.resize(m_params.size());
|
||||
}
|
||||
|
||||
void PreparedStmt::ThrowError(const std::string& error)
|
||||
{
|
||||
LogMySQLError("{}", error);
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
|
||||
std::string PreparedStmt::GetStmtError()
|
||||
{
|
||||
auto err = mysql_stmt_errno(m_stmt.get());
|
||||
auto str = mysql_stmt_error(m_stmt.get());
|
||||
return fmt::format("({}) [{}] for query [{}]", err, str, m_query);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void PreparedStmt::BindInput(size_t index, T value)
|
||||
{
|
||||
if (index >= m_inputs.size())
|
||||
{
|
||||
ThrowError(fmt::format("Cannot bind input, index {} out of range", index));
|
||||
}
|
||||
|
||||
impl::Bind& arg = m_inputs[index];
|
||||
arg.is_null = std::is_same_v<T, std::nullptr_t>;
|
||||
|
||||
MYSQL_BIND& bind = m_params[index];
|
||||
bind.is_unsigned = std::is_unsigned_v<T>;
|
||||
bind.is_null = &arg.is_null;
|
||||
bind.length = &arg.length;
|
||||
|
||||
auto old_type = bind.buffer_type;
|
||||
|
||||
if constexpr (std::is_arithmetic_v<T>)
|
||||
{
|
||||
if (arg.buffer.size() < sizeof(T))
|
||||
{
|
||||
arg.buffer.resize(std::max(sizeof(T), sizeof(int64_t)));
|
||||
bind.buffer = arg.buffer.data();
|
||||
m_need_bind = true;
|
||||
}
|
||||
memcpy(arg.buffer.data(), &value, sizeof(T));
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<T, int8_t> || std::is_same_v<T, uint8_t> || std::is_same_v<T, bool>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_TINY;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int16_t> || std::is_same_v<T, uint16_t>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_SHORT;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_LONG;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_LONGLONG;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_FLOAT;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_DOUBLE;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, std::string_view>)
|
||||
{
|
||||
bind.buffer_type = MYSQL_TYPE_STRING;
|
||||
if (arg.buffer.empty() || arg.buffer.size() < value.size())
|
||||
{
|
||||
arg.buffer.resize(static_cast<size_t>((value.size() + 1) * 1.5));
|
||||
bind.buffer = arg.buffer.data();
|
||||
bind.buffer_length = static_cast<unsigned long>(arg.buffer.size());
|
||||
m_need_bind = true;
|
||||
}
|
||||
std::copy(value.begin(), value.end(), arg.buffer.begin());
|
||||
arg.length = static_cast<unsigned long>(value.size());
|
||||
}
|
||||
else if constexpr (!std::is_same_v<T, std::nullptr_t>)
|
||||
{
|
||||
static_assert(false_v<T>, "Cannot bind unsupported type");
|
||||
}
|
||||
|
||||
if (old_type != bind.buffer_type)
|
||||
{
|
||||
m_need_bind = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PreparedStmt::BindInput(size_t index, const char* str)
|
||||
{
|
||||
BindInput(index, std::string_view(str));
|
||||
}
|
||||
|
||||
void PreparedStmt::BindInput(size_t index, const std::string& str)
|
||||
{
|
||||
BindInput(index, std::string_view(str));
|
||||
}
|
||||
|
||||
StmtResult PreparedStmt::Execute()
|
||||
{
|
||||
CheckArgs(0);
|
||||
return DoExecute();
|
||||
}
|
||||
|
||||
StmtResult PreparedStmt::Execute(const std::vector<param_t>& args)
|
||||
{
|
||||
CheckArgs(args.size());
|
||||
for (size_t i = 0; i < args.size(); ++i)
|
||||
{
|
||||
std::visit([&](const auto& arg) { BindInput(i, arg); }, args[i]);
|
||||
}
|
||||
return DoExecute();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StmtResult PreparedStmt::Execute(const std::vector<T>& args)
|
||||
{
|
||||
CheckArgs(args.size());
|
||||
for (size_t i = 0; i < args.size(); ++i)
|
||||
{
|
||||
BindInput(i, args[i]);
|
||||
}
|
||||
return DoExecute();
|
||||
}
|
||||
|
||||
void PreparedStmt::CheckArgs(size_t argc)
|
||||
{
|
||||
if (argc != m_params.size())
|
||||
{
|
||||
ThrowError(fmt::format("Bad arg count (got {}, expected {}) for [{}]", argc, m_params.size(), m_query));
|
||||
}
|
||||
}
|
||||
|
||||
StmtResult PreparedStmt::DoExecute()
|
||||
{
|
||||
BenchTimer timer;
|
||||
LockMutex lock(m_mutex);
|
||||
|
||||
if (m_need_bind && mysql_stmt_bind_param(m_stmt.get(), m_params.data()) != 0)
|
||||
{
|
||||
ThrowError(fmt::format("Bind param error: {}", GetStmtError()));
|
||||
}
|
||||
|
||||
m_need_bind = false;
|
||||
|
||||
if (mysql_stmt_execute(m_stmt.get()) != 0)
|
||||
{
|
||||
ThrowError(fmt::format("Execute error: {}", GetStmtError()));
|
||||
}
|
||||
|
||||
my_bool attr = m_options.use_max_length;
|
||||
mysql_stmt_attr_set(m_stmt.get(), STMT_ATTR_UPDATE_MAX_LENGTH, &attr);
|
||||
|
||||
if (m_options.buffer_results && mysql_stmt_store_result(m_stmt.get()) != 0)
|
||||
{
|
||||
ThrowError(fmt::format("Store result error: {}", GetStmtError()));
|
||||
}
|
||||
|
||||
// Result buffers are bound on first execute and re-used if needed
|
||||
if (m_results.empty())
|
||||
{
|
||||
BindResults();
|
||||
}
|
||||
|
||||
StmtResult res(m_stmt.get(), m_results.size());
|
||||
|
||||
if (m_results.empty())
|
||||
{
|
||||
LogMySQLQuery("{} -- ({} row(s) affected) ({:.6f}s)", m_query, res.RowsAffected(), timer.elapsed());
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMySQLQuery("{} -- ({} row(s) returned) ({:.6f}s)", m_query, res.RowCount(), timer.elapsed());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void PreparedStmt::BindResults()
|
||||
{
|
||||
MYSQL_RES* res = mysql_stmt_result_metadata(m_stmt.get());
|
||||
if (!res)
|
||||
{
|
||||
return; // did not produce a result set
|
||||
}
|
||||
|
||||
MYSQL_FIELD* fields = mysql_fetch_fields(res);
|
||||
m_columns.resize(mysql_num_fields(res));
|
||||
m_results.resize(m_columns.size());
|
||||
|
||||
for (int i = 0; i < static_cast<int>(m_columns.size()); ++i)
|
||||
{
|
||||
impl::BindColumn& col = m_columns[i].m_col;
|
||||
MYSQL_BIND& bind = m_results[i];
|
||||
|
||||
col.index = i;
|
||||
col.name = fields[i].name;
|
||||
col.buffer_type = fields[i].type;
|
||||
col.is_unsigned = (fields[i].flags & UNSIGNED_FLAG) != 0;
|
||||
col.buffer.resize(GetResultBufferSize(fields[i]));
|
||||
|
||||
bind.buffer_type = col.buffer_type;
|
||||
bind.buffer = col.buffer.data();
|
||||
bind.buffer_length = static_cast<unsigned long>(col.buffer.size());
|
||||
bind.is_unsigned = col.is_unsigned;
|
||||
bind.is_null = &col.is_null;
|
||||
bind.length = &col.length;
|
||||
bind.error = &col.error;
|
||||
}
|
||||
|
||||
mysql_free_result(res);
|
||||
|
||||
if (!m_results.empty() && mysql_stmt_bind_result(m_stmt.get(), m_results.data()) != 0)
|
||||
{
|
||||
ThrowError(fmt::format("Bind result error: {}", GetStmtError()));
|
||||
}
|
||||
}
|
||||
|
||||
int PreparedStmt::GetResultBufferSize(const MYSQL_FIELD& field) const
|
||||
{
|
||||
switch (field.type)
|
||||
{
|
||||
case MYSQL_TYPE_TINY:
|
||||
return sizeof(int8_t);
|
||||
case MYSQL_TYPE_SHORT:
|
||||
return sizeof(int16_t);
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
return sizeof(int32_t);
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
return sizeof(int64_t);
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
return sizeof(float);
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
return sizeof(double);
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
return sizeof(MYSQL_TIME);
|
||||
default: // if max_length is unavailable for strings buffers are resized on fetch
|
||||
return field.max_length + 1; // ensure valid buffer created
|
||||
}
|
||||
}
|
||||
|
||||
StmtRow PreparedStmt::Fetch()
|
||||
{
|
||||
StmtRow row;
|
||||
if (!m_columns.empty())
|
||||
{
|
||||
int rc = mysql_stmt_fetch(m_stmt.get());
|
||||
if (rc == 1)
|
||||
{
|
||||
ThrowError(fmt::format("Fetch error: {}", GetStmtError()));
|
||||
}
|
||||
|
||||
if (rc != MYSQL_NO_DATA)
|
||||
{
|
||||
if (rc == MYSQL_DATA_TRUNCATED)
|
||||
{
|
||||
FetchTruncated();
|
||||
}
|
||||
row = StmtRow(m_columns);
|
||||
}
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
void PreparedStmt::FetchTruncated()
|
||||
{
|
||||
for (int i = 0; i < static_cast<int>(m_columns.size()); ++i)
|
||||
{
|
||||
impl::BindColumn& col = m_columns[i].m_col;
|
||||
if (col.error)
|
||||
{
|
||||
MYSQL_BIND& bind = m_results[i];
|
||||
col.buffer.resize(static_cast<size_t>(col.length * 1.5));
|
||||
bind.buffer = col.buffer.data();
|
||||
bind.buffer_length = static_cast<unsigned long>(col.buffer.size());
|
||||
|
||||
mysql_stmt_fetch_column(m_stmt.get(), &bind, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (mysql_stmt_bind_result(m_stmt.get(), m_results.data()) != 0)
|
||||
{
|
||||
ThrowError(fmt::format("Fetch rebind result error: {}", GetStmtError()));
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
StmtResult::StmtResult(MYSQL_STMT* stmt, size_t columns)
|
||||
{
|
||||
m_num_cols = static_cast<int>(columns);
|
||||
m_num_rows = mysql_stmt_num_rows(stmt); // requires buffered results
|
||||
m_affected = mysql_stmt_affected_rows(stmt);
|
||||
m_insert_id = mysql_stmt_insert_id(stmt);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const StmtColumn* StmtRow::GetColumn(size_t index) const
|
||||
{
|
||||
return index < m_columns.size() ? &m_columns[index] : nullptr;
|
||||
}
|
||||
|
||||
const StmtColumn* StmtRow::GetColumn(std::string_view name) const
|
||||
{
|
||||
auto it = std::ranges::find_if(m_columns,
|
||||
[name](const StmtColumn& col) { return col.Name() == name; });
|
||||
|
||||
return it != m_columns.end() ? &(*it) : nullptr;
|
||||
}
|
||||
|
||||
std::optional<std::string> StmtRow::operator[](size_t index) const
|
||||
{
|
||||
return GetStr(index);
|
||||
}
|
||||
|
||||
std::optional<std::string> StmtRow::operator[](std::string_view name) const
|
||||
{
|
||||
return GetStr(name);
|
||||
}
|
||||
|
||||
std::optional<std::string> StmtRow::GetStr(size_t index) const
|
||||
{
|
||||
const StmtColumn* col = GetColumn(index);
|
||||
return col ? col->GetStr() : std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> StmtRow::GetStr(std::string_view name) const
|
||||
{
|
||||
const StmtColumn* col = GetColumn(name);
|
||||
return col ? col->GetStr() : std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T> requires std::is_arithmetic_v<T>
|
||||
std::optional<T> StmtRow::Get(size_t index) const
|
||||
{
|
||||
const StmtColumn* col = GetColumn(index);
|
||||
return col ? col->Get<T>() : std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T> requires std::is_arithmetic_v<T>
|
||||
std::optional<T> StmtRow::Get(std::string_view name) const
|
||||
{
|
||||
const StmtColumn* col = GetColumn(name);
|
||||
return col ? col->Get<T>() : std::nullopt;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static time_t MakeTime(const MYSQL_TIME& mt)
|
||||
{
|
||||
// buffer mt given in mysql session time zone (assumes local)
|
||||
std::tm tm{};
|
||||
tm.tm_year = mt.year - 1900;
|
||||
tm.tm_mon = mt.month - 1;
|
||||
tm.tm_mday = mt.day;
|
||||
tm.tm_hour = mt.hour;
|
||||
tm.tm_min = mt.minute;
|
||||
tm.tm_sec = mt.second;
|
||||
tm.tm_isdst = -1;
|
||||
return std::mktime(&tm);
|
||||
}
|
||||
|
||||
static int MakeSeconds(const MYSQL_TIME& mt)
|
||||
{
|
||||
return (mt.neg ? -1 : 1) * static_cast<int>(mt.hour * 3600 + mt.minute * 60 + mt.second);
|
||||
}
|
||||
|
||||
static uint64_t MakeBits(std::span<const uint8_t> data)
|
||||
{
|
||||
// byte stream for bits is in big endian
|
||||
uint64_t bits = 0;
|
||||
for (size_t i = 0; i < data.size() && i < sizeof(uint64_t); ++i)
|
||||
{
|
||||
bits |= static_cast<uint64_t>(data[data.size() - i - 1] & 0xff) << (i * 8);
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
concept has_from_chars = requires (const char* first, const char* last, T value)
|
||||
{
|
||||
std::from_chars(first, last, value);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static T FromString(std::string_view sv)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, bool>)
|
||||
{
|
||||
// return false for empty (zero-length) strings
|
||||
return !sv.empty();
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float> && !has_from_chars<T>)
|
||||
{
|
||||
return std::strtof(std::string(sv).c_str(), nullptr);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double> && !has_from_chars<T>)
|
||||
{
|
||||
return std::strtod(std::string(sv).c_str(), nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// non numbers return a zero initialized T (could return nullopt instead)
|
||||
T value = {};
|
||||
std::from_chars(sv.data(), sv.data() + sv.size(), value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
static std::string FormatTime(enum_field_types type, const MYSQL_TIME& mt)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MYSQL_TYPE_TIME: // hhh:mm:ss '-838:59:59' to '838:59:59'
|
||||
return fmt::format("{}{:02d}:{:02d}:{:02d}", mt.neg ? "-" : "", mt.hour, mt.minute, mt.second);
|
||||
case MYSQL_TYPE_DATE: // YYYY-MM-DD '1000-01-01' to '9999-12-31'
|
||||
return fmt::format("{}-{:02d}-{:02d}", mt.year, mt.month, mt.day);
|
||||
case MYSQL_TYPE_DATETIME: // YYYY-MM-DD hh:mm:ss '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
|
||||
case MYSQL_TYPE_TIMESTAMP: // YYYY-MM-DD hh:mm:ss '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC
|
||||
return fmt::format("{}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}", mt.year, mt.month, mt.day, mt.hour, mt.minute, mt.second);
|
||||
default:
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string_view> StmtColumn::GetStrView() const
|
||||
{
|
||||
if (m_col.is_null)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (m_col.buffer_type)
|
||||
{
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
return std::make_optional<std::string_view>(reinterpret_cast<const char*>(m_col.buffer.data()), m_col.length);
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> StmtColumn::GetStr() const
|
||||
{
|
||||
if (m_col.is_null)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (m_col.buffer_type)
|
||||
{
|
||||
case MYSQL_TYPE_TINY:
|
||||
return m_col.is_unsigned ? fmt::format_int(BitCast<uint8_t>()).c_str() : fmt::format_int(BitCast<int8_t>()).c_str();
|
||||
case MYSQL_TYPE_SHORT:
|
||||
return m_col.is_unsigned ? fmt::format_int(BitCast<uint16_t>()).c_str() : fmt::format_int(BitCast<int16_t>()).c_str();
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
return m_col.is_unsigned ? fmt::format_int(BitCast<uint32_t>()).c_str() : fmt::format_int(BitCast<int32_t>()).c_str();
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
return m_col.is_unsigned ? fmt::format_int(BitCast<uint64_t>()).c_str() : fmt::format_int(BitCast<int64_t>()).c_str();
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
return fmt::format("{}", BitCast<float>());
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
return fmt::format("{}", BitCast<double>());
|
||||
case MYSQL_TYPE_TIME:
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
return FormatTime(m_col.buffer_type, BitCast<MYSQL_TIME>());
|
||||
case MYSQL_TYPE_BIT:
|
||||
return fmt::format_int(*Get<uint64_t>()).c_str();
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
return std::make_optional<std::string>(reinterpret_cast<const char*>(m_col.buffer.data()), m_col.length);
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> requires std::is_arithmetic_v<T>
|
||||
std::optional<T> StmtColumn::Get() const
|
||||
{
|
||||
if (m_col.is_null)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (m_col.buffer_type)
|
||||
{
|
||||
case MYSQL_TYPE_TINY:
|
||||
return m_col.is_unsigned ? static_cast<T>(BitCast<uint8_t>()) : static_cast<T>(BitCast<int8_t>());
|
||||
case MYSQL_TYPE_SHORT:
|
||||
return m_col.is_unsigned ? static_cast<T>(BitCast<uint16_t>()) : static_cast<T>(BitCast<int16_t>());
|
||||
case MYSQL_TYPE_INT24:
|
||||
case MYSQL_TYPE_LONG:
|
||||
return m_col.is_unsigned ? static_cast<T>(BitCast<uint32_t>()) : static_cast<T>(BitCast<int32_t>());
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
return m_col.is_unsigned ? static_cast<T>(BitCast<uint64_t>()) : static_cast<T>(BitCast<int64_t>());
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
return static_cast<T>(BitCast<float>());
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
return static_cast<T>(BitCast<double>());
|
||||
case MYSQL_TYPE_TIME: // return as total seconds
|
||||
return static_cast<T>(MakeSeconds(BitCast<MYSQL_TIME>()));
|
||||
case MYSQL_TYPE_DATE:
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP: // return as epoch timestamp
|
||||
return static_cast<T>(MakeTime(BitCast<MYSQL_TIME>()));
|
||||
case MYSQL_TYPE_BIT:
|
||||
return static_cast<T>(MakeBits({ m_col.buffer.data(), m_col.length }));
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
case MYSQL_TYPE_STRING:
|
||||
return FromString<T>({ reinterpret_cast<const char*>(m_col.buffer.data()), m_col.length });
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// explicit template instantiations for supported types
|
||||
template void PreparedStmt::BindInput(size_t, std::string_view);
|
||||
template void PreparedStmt::BindInput(size_t, std::nullptr_t);
|
||||
template StmtResult PreparedStmt::Execute(const std::vector<std::string_view>&);
|
||||
template StmtResult PreparedStmt::Execute(const std::vector<std::string>&);
|
||||
template StmtResult PreparedStmt::Execute(const std::vector<const char*>&);
|
||||
|
||||
#define INSTANTIATE(T) \
|
||||
template void PreparedStmt::BindInput(size_t, T); \
|
||||
template StmtResult PreparedStmt::Execute(const std::vector<T>&); \
|
||||
template std::optional<T> StmtRow::Get(size_t) const; \
|
||||
template std::optional<T> StmtRow::Get(std::string_view) const; \
|
||||
template std::optional<T> StmtColumn::Get() const;
|
||||
|
||||
INSTANTIATE(bool);
|
||||
INSTANTIATE(int8_t);
|
||||
INSTANTIATE(uint8_t);
|
||||
INSTANTIATE(int16_t);
|
||||
INSTANTIATE(uint16_t);
|
||||
INSTANTIATE(int32_t);
|
||||
INSTANTIATE(uint32_t);
|
||||
INSTANTIATE(int64_t);
|
||||
INSTANTIATE(uint64_t);
|
||||
INSTANTIATE(float);
|
||||
INSTANTIATE(double);
|
||||
|
||||
} // namespace mysql
|
||||
@@ -1,221 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "mysql.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
class Mutex;
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
|
||||
// support MySQL 8.0.1+ API which removed the my_bool type
|
||||
#if !defined(MARIADB_VERSION_ID) && MYSQL_VERSION_ID >= 80001
|
||||
using my_bool = bool;
|
||||
#endif
|
||||
|
||||
template <typename>
|
||||
inline constexpr bool false_v = false;
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
struct Bind
|
||||
{
|
||||
std::vector<uint8_t> buffer;
|
||||
unsigned long length = 0;
|
||||
my_bool is_null = false;
|
||||
my_bool error = false;
|
||||
};
|
||||
|
||||
struct BindColumn : Bind
|
||||
{
|
||||
int index = 0;
|
||||
std::string name;
|
||||
bool is_unsigned = false;
|
||||
enum_field_types buffer_type = {};
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
struct StmtOptions
|
||||
{
|
||||
// Enable buffering (storing) entire result set after executing a statement
|
||||
bool buffer_results = true;
|
||||
|
||||
// Enable MySQL to update max_length of fields in execute result set (requires buffering)
|
||||
bool use_max_length = true;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Holds ownership of bound column value buffer
|
||||
class StmtColumn
|
||||
{
|
||||
public:
|
||||
int Index() const { return m_col.index; }
|
||||
bool IsNull() const { return m_col.is_null; }
|
||||
bool IsUnsigned() const { return m_col.is_unsigned; }
|
||||
enum_field_types Type() const { return m_col.buffer_type; }
|
||||
const std::string& Name() const { return m_col.name; }
|
||||
|
||||
// Get view of column value buffer
|
||||
std::span<const uint8_t> GetBuf() const { return { m_col.buffer.data(), m_col.length }; }
|
||||
|
||||
// Get view of column string value. Returns nullopt if value is NULL or not a string
|
||||
std::optional<std::string_view> GetStrView() const;
|
||||
|
||||
// Get column value as string. Returns nullopt if value is NULL or field type unsupported
|
||||
std::optional<std::string> GetStr() const;
|
||||
|
||||
// Get column value as numeric T. Returns nullopt if value NULL or field type unsupported
|
||||
template <typename T> requires std::is_arithmetic_v<T>
|
||||
std::optional<T> Get() const;
|
||||
|
||||
private:
|
||||
// uses memcpy for type punning buffer data to avoid UB with strict aliasing
|
||||
template <typename T>
|
||||
T BitCast() const
|
||||
{
|
||||
T val;
|
||||
assert(sizeof(T) == m_col.length);
|
||||
memcpy(&val, m_col.buffer.data(), sizeof(T));
|
||||
return val;
|
||||
}
|
||||
|
||||
friend class PreparedStmt; // access to allocate and bind buffers
|
||||
friend class StmtResult; // access to resize truncated buffers
|
||||
impl::BindColumn m_col;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Provides a non-owning view of PreparedStmt column value buffers
|
||||
// Evaluates false if it does not contain a valid row
|
||||
class StmtRow
|
||||
{
|
||||
public:
|
||||
StmtRow() = default;
|
||||
StmtRow(std::span<const StmtColumn> columns) : m_columns(columns) {};
|
||||
|
||||
explicit operator bool() const noexcept { return !m_columns.empty(); }
|
||||
|
||||
int ColumnCount() const { return static_cast<int>(m_columns.size()); }
|
||||
const StmtColumn* GetColumn(size_t index) const;
|
||||
const StmtColumn* GetColumn(std::string_view name) const;
|
||||
|
||||
// Get specified column value as string
|
||||
// Returns nullopt if column invalid, value is NULL, or field type unsupported
|
||||
std::optional<std::string> operator[](size_t index) const;
|
||||
std::optional<std::string> operator[](std::string_view name) const;
|
||||
std::optional<std::string> GetStr(size_t index) const;
|
||||
std::optional<std::string> GetStr(std::string_view name) const;
|
||||
|
||||
// Get specified column value as numeric T
|
||||
// Returns nullopt if column invalid, value is NULL, or field type unsupported
|
||||
template <typename T> requires std::is_arithmetic_v<T>
|
||||
std::optional<T> Get(size_t index) const;
|
||||
|
||||
template <typename T> requires std::is_arithmetic_v<T>
|
||||
std::optional<T> Get(std::string_view name) const;
|
||||
|
||||
auto begin() const { return m_columns.begin(); }
|
||||
auto end() const { return m_columns.end(); }
|
||||
|
||||
private:
|
||||
std::span<const StmtColumn> m_columns;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Result meta data for an executed prepared statement
|
||||
class StmtResult
|
||||
{
|
||||
public:
|
||||
StmtResult() = default;
|
||||
StmtResult(MYSQL_STMT* stmt, size_t columns);
|
||||
|
||||
int ColumnCount() const { return m_num_cols; }
|
||||
uint64_t RowCount() const { return m_num_rows; }
|
||||
uint64_t RowsAffected() const { return m_affected; }
|
||||
uint64_t LastInsertID() const { return m_insert_id; }
|
||||
|
||||
private:
|
||||
int m_num_cols = 0;
|
||||
uint64_t m_num_rows = 0;
|
||||
uint64_t m_affected = 0;
|
||||
uint64_t m_insert_id = 0;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class PreparedStmt
|
||||
{
|
||||
public:
|
||||
// Supported argument types for execute
|
||||
using param_t = std::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
|
||||
int64_t, uint64_t, float, double, bool, std::string_view, std::nullptr_t>;
|
||||
|
||||
PreparedStmt() = delete;
|
||||
PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts = {});
|
||||
|
||||
const std::string& GetQuery() const { return m_query; }
|
||||
StmtOptions GetOptions() const { return m_options; }
|
||||
void SetOptions(StmtOptions options) { m_options = options; }
|
||||
void FreeResult() { mysql_stmt_free_result(m_stmt.get()); }
|
||||
|
||||
// Execute the prepared statement with specified arguments
|
||||
// Throws exception on error
|
||||
template <typename T>
|
||||
StmtResult Execute(const std::vector<T>& args);
|
||||
StmtResult Execute(const std::vector<param_t>& args);
|
||||
StmtResult Execute();
|
||||
|
||||
// Fetch the next row into column buffers (overwrites previous row values)
|
||||
// Return value evaluates false if no more rows to fetch
|
||||
// Throws exception on error
|
||||
StmtRow Fetch();
|
||||
|
||||
private:
|
||||
void CheckArgs(size_t argc);
|
||||
StmtResult DoExecute();
|
||||
void BindResults();
|
||||
void FetchTruncated();
|
||||
int GetResultBufferSize(const MYSQL_FIELD& field) const;
|
||||
void ThrowError(const std::string& error);
|
||||
std::string GetStmtError();
|
||||
|
||||
// bind an input value to a query parameter by index
|
||||
template <typename T>
|
||||
void BindInput(size_t index, T value);
|
||||
void BindInput(size_t index, const char* str);
|
||||
void BindInput(size_t index, const std::string& str);
|
||||
|
||||
struct StmtDeleter
|
||||
{
|
||||
Mutex* mutex = nullptr;
|
||||
void operator()(MYSQL_STMT* stmt) noexcept;
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<MYSQL_STMT, StmtDeleter> m_stmt;
|
||||
std::vector<MYSQL_BIND> m_params; // input binds
|
||||
std::vector<MYSQL_BIND> m_results; // result binds
|
||||
std::vector<impl::Bind> m_inputs; // execute buffers (addresses bound)
|
||||
std::vector<StmtColumn> m_columns; // fetch buffers (addresses bound)
|
||||
std::string m_query;
|
||||
StmtOptions m_options = {};
|
||||
bool m_need_bind = true;
|
||||
Mutex* m_mutex = nullptr; // connection mutex
|
||||
};
|
||||
|
||||
} // namespace mysql
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_LAURION_H
|
||||
#define COMMON_LAURION_H
|
||||
|
||||
#include "../struct_strategy.h"
|
||||
|
||||
class EQStreamIdentifier;
|
||||
|
||||
namespace Laurion
|
||||
{
|
||||
|
||||
//these are the only public member of this namespace.
|
||||
extern void Register(EQStreamIdentifier& into);
|
||||
extern void Reload();
|
||||
|
||||
|
||||
|
||||
//you should not directly access anything below..
|
||||
//I just dont feel like making a seperate header for it.
|
||||
|
||||
class Strategy : public StructStrategy {
|
||||
public:
|
||||
Strategy();
|
||||
|
||||
protected:
|
||||
|
||||
virtual std::string Describe() const;
|
||||
virtual const EQ::versions::ClientVersion ClientVersion() const;
|
||||
|
||||
//magic macro to declare our opcode processors
|
||||
#include "ss_declare.h"
|
||||
#include "laurion_ops.h"
|
||||
};
|
||||
|
||||
}; /*Laurion*/
|
||||
|
||||
#endif /*COMMON_LAURION_H*/
|
||||
@@ -1,284 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "laurion_limits.h"
|
||||
|
||||
#include "../strings.h"
|
||||
|
||||
|
||||
int16 Laurion::invtype::GetInvTypeSize(int16 inv_type)
|
||||
{
|
||||
switch (inv_type) {
|
||||
case invtype::typePossessions:
|
||||
return invtype::POSSESSIONS_SIZE;
|
||||
case invtype::typeBank:
|
||||
return invtype::BANK_SIZE;
|
||||
case invtype::typeSharedBank:
|
||||
return invtype::SHARED_BANK_SIZE;
|
||||
case invtype::typeTrade:
|
||||
return invtype::TRADE_SIZE;
|
||||
case invtype::typeWorld:
|
||||
return invtype::WORLD_SIZE;
|
||||
case invtype::typeLimbo:
|
||||
return invtype::LIMBO_SIZE;
|
||||
case invtype::typeTribute:
|
||||
return invtype::TRIBUTE_SIZE;
|
||||
case invtype::typeTrophyTribute:
|
||||
return invtype::TROPHY_TRIBUTE_SIZE;
|
||||
case invtype::typeGuildTribute:
|
||||
return invtype::GUILD_TRIBUTE_SIZE;
|
||||
case invtype::typeMerchant:
|
||||
return invtype::MERCHANT_SIZE;
|
||||
case invtype::typeDeleted:
|
||||
return invtype::DELETED_SIZE;
|
||||
case invtype::typeCorpse:
|
||||
return invtype::CORPSE_SIZE;
|
||||
case invtype::typeBazaar:
|
||||
return invtype::BAZAAR_SIZE;
|
||||
case invtype::typeInspect:
|
||||
return invtype::INSPECT_SIZE;
|
||||
case invtype::typeRealEstate:
|
||||
return invtype::REAL_ESTATE_SIZE;
|
||||
case invtype::typeViewMODPC:
|
||||
return invtype::VIEW_MOD_PC_SIZE;
|
||||
case invtype::typeViewMODBank:
|
||||
return invtype::VIEW_MOD_BANK_SIZE;
|
||||
case invtype::typeViewMODSharedBank:
|
||||
return invtype::VIEW_MOD_SHARED_BANK_SIZE;
|
||||
case invtype::typeViewMODLimbo:
|
||||
return invtype::VIEW_MOD_LIMBO_SIZE;
|
||||
case invtype::typeAltStorage:
|
||||
return invtype::ALT_STORAGE_SIZE;
|
||||
case invtype::typeArchived:
|
||||
return invtype::ARCHIVED_SIZE;
|
||||
case invtype::typeMail:
|
||||
return invtype::MAIL_SIZE;
|
||||
case invtype::typeGuildTrophyTribute:
|
||||
return invtype::GUILD_TROPHY_TRIBUTE_SIZE;
|
||||
case invtype::typeKrono:
|
||||
return invtype::KRONO_SIZE;
|
||||
case invtype::typeOther:
|
||||
return invtype::OTHER_SIZE;
|
||||
default:
|
||||
return INULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Laurion::invtype::GetInvTypeName(int16 inv_type)
|
||||
{
|
||||
switch (inv_type) {
|
||||
case invtype::TYPE_INVALID:
|
||||
return "Invalid Type";
|
||||
case invtype::typePossessions:
|
||||
return "Possessions";
|
||||
case invtype::typeBank:
|
||||
return "Bank";
|
||||
case invtype::typeSharedBank:
|
||||
return "Shared Bank";
|
||||
case invtype::typeTrade:
|
||||
return "Trade";
|
||||
case invtype::typeWorld:
|
||||
return "World";
|
||||
case invtype::typeLimbo:
|
||||
return "Limbo";
|
||||
case invtype::typeTribute:
|
||||
return "Tribute";
|
||||
case invtype::typeTrophyTribute:
|
||||
return "Trophy Tribute";
|
||||
case invtype::typeGuildTribute:
|
||||
return "Guild Tribute";
|
||||
case invtype::typeMerchant:
|
||||
return "Merchant";
|
||||
case invtype::typeDeleted:
|
||||
return "Deleted";
|
||||
case invtype::typeCorpse:
|
||||
return "Corpse";
|
||||
case invtype::typeBazaar:
|
||||
return "Bazaar";
|
||||
case invtype::typeInspect:
|
||||
return "Inspect";
|
||||
case invtype::typeRealEstate:
|
||||
return "Real Estate";
|
||||
case invtype::typeViewMODPC:
|
||||
return "View MOD PC";
|
||||
case invtype::typeViewMODBank:
|
||||
return "View MOD Bank";
|
||||
case invtype::typeViewMODSharedBank:
|
||||
return "View MOD Shared Bank";
|
||||
case invtype::typeViewMODLimbo:
|
||||
return "View MOD Limbo";
|
||||
case invtype::typeAltStorage:
|
||||
return "Alt Storage";
|
||||
case invtype::typeArchived:
|
||||
return "Archived";
|
||||
case invtype::typeMail:
|
||||
return "Mail";
|
||||
case invtype::typeGuildTrophyTribute:
|
||||
return "Guild Trophy Tribute";
|
||||
case invtype::typeKrono:
|
||||
return "Krono";
|
||||
case invtype::typeOther:
|
||||
return "Other";
|
||||
default:
|
||||
return "Unknown Type";
|
||||
}
|
||||
}
|
||||
|
||||
bool Laurion::invtype::IsInvTypePersistent(int16 inv_type)
|
||||
{
|
||||
switch (inv_type) {
|
||||
case invtype::typePossessions:
|
||||
case invtype::typeBank:
|
||||
case invtype::typeSharedBank:
|
||||
case invtype::typeTrade:
|
||||
case invtype::typeWorld:
|
||||
case invtype::typeLimbo:
|
||||
case invtype::typeTribute:
|
||||
case invtype::typeTrophyTribute:
|
||||
case invtype::typeGuildTribute:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Laurion::invslot::GetInvPossessionsSlotName(int16 inv_slot)
|
||||
{
|
||||
switch (inv_slot) {
|
||||
case invslot::SLOT_INVALID:
|
||||
return "Invalid Slot";
|
||||
case invslot::slotCharm:
|
||||
return "Charm";
|
||||
case invslot::slotEar1:
|
||||
return "Ear 1";
|
||||
case invslot::slotHead:
|
||||
return "Head";
|
||||
case invslot::slotFace:
|
||||
return "Face";
|
||||
case invslot::slotEar2:
|
||||
return "Ear 2";
|
||||
case invslot::slotNeck:
|
||||
return "Neck";
|
||||
case invslot::slotShoulders:
|
||||
return "Shoulders";
|
||||
case invslot::slotArms:
|
||||
return "Arms";
|
||||
case invslot::slotBack:
|
||||
return "Back";
|
||||
case invslot::slotWrist1:
|
||||
return "Wrist 1";
|
||||
case invslot::slotWrist2:
|
||||
return "Wrist 2";
|
||||
case invslot::slotRange:
|
||||
return "Range";
|
||||
case invslot::slotHands:
|
||||
return "Hands";
|
||||
case invslot::slotPrimary:
|
||||
return "Primary";
|
||||
case invslot::slotSecondary:
|
||||
return "Secondary";
|
||||
case invslot::slotFinger1:
|
||||
return "Finger 1";
|
||||
case invslot::slotFinger2:
|
||||
return "Finger 2";
|
||||
case invslot::slotChest:
|
||||
return "Chest";
|
||||
case invslot::slotLegs:
|
||||
return "Legs";
|
||||
case invslot::slotFeet:
|
||||
return "Feet";
|
||||
case invslot::slotWaist:
|
||||
return "Waist";
|
||||
case invslot::slotPowerSource:
|
||||
return "Power Source";
|
||||
case invslot::slotAmmo:
|
||||
return "Ammo";
|
||||
case invslot::slotGeneral1:
|
||||
return "General 1";
|
||||
case invslot::slotGeneral2:
|
||||
return "General 2";
|
||||
case invslot::slotGeneral3:
|
||||
return "General 3";
|
||||
case invslot::slotGeneral4:
|
||||
return "General 4";
|
||||
case invslot::slotGeneral5:
|
||||
return "General 5";
|
||||
case invslot::slotGeneral6:
|
||||
return "General 6";
|
||||
case invslot::slotGeneral7:
|
||||
return "General 7";
|
||||
case invslot::slotGeneral8:
|
||||
return "General 8";
|
||||
case invslot::slotGeneral9:
|
||||
return "General 9";
|
||||
case invslot::slotGeneral10:
|
||||
return "General 10";
|
||||
case invslot::slotCursor:
|
||||
return "Cursor";
|
||||
default:
|
||||
return "Unknown Slot";
|
||||
}
|
||||
}
|
||||
|
||||
const char* Laurion::invslot::GetInvSlotName(int16 inv_type, int16 inv_slot)
|
||||
{
|
||||
if (inv_type == invtype::typePossessions)
|
||||
return invslot::GetInvPossessionsSlotName(inv_slot);
|
||||
|
||||
int16 type_size = invtype::GetInvTypeSize(inv_type);
|
||||
|
||||
if (!type_size || inv_slot == invslot::SLOT_INVALID)
|
||||
return "Invalid Slot";
|
||||
|
||||
if ((inv_slot + 1) >= type_size)
|
||||
return "Unknown Slot";
|
||||
|
||||
static std::string ret_str;
|
||||
ret_str = StringFormat("Slot %i", (inv_slot + 1));
|
||||
|
||||
return ret_str.c_str();
|
||||
}
|
||||
|
||||
const char* Laurion::invbag::GetInvBagIndexName(int16 bag_index)
|
||||
{
|
||||
if (bag_index == invbag::SLOT_INVALID)
|
||||
return "Invalid Bag";
|
||||
|
||||
if (bag_index >= invbag::SLOT_COUNT)
|
||||
return "Unknown Bag";
|
||||
|
||||
static std::string ret_str;
|
||||
ret_str = StringFormat("Bag %i", (bag_index + 1));
|
||||
|
||||
return ret_str.c_str();
|
||||
}
|
||||
|
||||
const char* Laurion::invaug::GetInvAugIndexName(int16 aug_index)
|
||||
{
|
||||
if (aug_index == invaug::SOCKET_INVALID)
|
||||
return "Invalid Augment";
|
||||
|
||||
if (aug_index >= invaug::SOCKET_COUNT)
|
||||
return "Unknown Augment";
|
||||
|
||||
static std::string ret_str;
|
||||
ret_str = StringFormat("Augment %i", (aug_index + 1));
|
||||
|
||||
return ret_str.c_str();
|
||||
}
|
||||
@@ -1,355 +0,0 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef COMMON_LAURION_LIMITS_H
|
||||
#define COMMON_LAURION_LIMITS_H
|
||||
|
||||
#include "../types.h"
|
||||
#include "../emu_versions.h"
|
||||
#include "../skills.h"
|
||||
|
||||
namespace Laurion
|
||||
{
|
||||
const int16 IINVALID = -1;
|
||||
const int16 INULL = 0;
|
||||
|
||||
namespace inventory {
|
||||
inline EQ::versions::ClientVersion GetInventoryRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const bool ConcatenateInvTypeLimbo = false;
|
||||
|
||||
const bool AllowOverLevelEquipment = true;
|
||||
|
||||
const bool AllowEmptyBagInBag = true;
|
||||
const bool AllowClickCastFromBag = true;
|
||||
|
||||
} /*inventory*/
|
||||
|
||||
namespace invtype {
|
||||
inline EQ::versions::ClientVersion GetInvTypeRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
namespace enum_ {
|
||||
enum InventoryTypes : int16 {
|
||||
typePossessions = INULL,
|
||||
typeBank,
|
||||
typeSharedBank,
|
||||
typeTrade,
|
||||
typeWorld,
|
||||
typeLimbo,
|
||||
typeTribute,
|
||||
typeTrophyTribute,
|
||||
typeGuildTribute,
|
||||
typeMerchant,
|
||||
typeDeleted,
|
||||
typeCorpse,
|
||||
typeBazaar,
|
||||
typeInspect,
|
||||
typeRealEstate,
|
||||
typeViewMODPC,
|
||||
typeViewMODBank,
|
||||
typeViewMODSharedBank,
|
||||
typeViewMODLimbo,
|
||||
typeAltStorage,
|
||||
typeArchived,
|
||||
typeMail,
|
||||
typeGuildTrophyTribute,
|
||||
typeKrono,
|
||||
typeOther,
|
||||
typeMercenaryItems,
|
||||
typeViewModMercenaryItems,
|
||||
typeMountKeyRingItems,
|
||||
typeViewModMountKeyRingItems,
|
||||
typeIllusionKeyRingItems,
|
||||
typeViewModIllusionKeyRingItems,
|
||||
typeFamiliarKeyRingItems,
|
||||
typeViewModFamiliarKeyRingItems,
|
||||
typeHeroForgeKeyRingItems,
|
||||
typeViewModHeroForgeKeyRingItems,
|
||||
typeTeleportationKeyRingItems,
|
||||
typeViewModTeleportationKeyRingItems,
|
||||
typeOverflow,
|
||||
typeDragonHoard,
|
||||
typeTradeskillDepot,
|
||||
typeGuildTradeskillDepot
|
||||
};
|
||||
|
||||
} // namespace enum_
|
||||
using namespace enum_;
|
||||
|
||||
const int16 POSSESSIONS_SIZE = 34;
|
||||
const int16 BANK_SIZE = 24;
|
||||
const int16 SHARED_BANK_SIZE = 2;
|
||||
const int16 TRADE_SIZE = 8;
|
||||
const int16 WORLD_SIZE = 10;
|
||||
const int16 LIMBO_SIZE = 36;
|
||||
const int16 TRIBUTE_SIZE = 5;
|
||||
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
|
||||
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
|
||||
const int16 MERCHANT_SIZE = 200;
|
||||
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
|
||||
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
|
||||
const int16 BAZAAR_SIZE = 200;
|
||||
const int16 INSPECT_SIZE = 23;
|
||||
const int16 REAL_ESTATE_SIZE = 0;//unknown
|
||||
const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE;
|
||||
const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE;
|
||||
const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE;
|
||||
const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE;
|
||||
const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank"
|
||||
const int16 ARCHIVED_SIZE = 0;//unknown
|
||||
const int16 MAIL_SIZE = 0;//unknown
|
||||
const int16 GUILD_TROPHY_TRIBUTE_SIZE = 0;//unknown
|
||||
const int16 KRONO_SIZE = 0;//unknown
|
||||
const int16 OTHER_SIZE = 0;//unknown
|
||||
|
||||
const int16 TRADE_NPC_SIZE = 4; // defined by implication
|
||||
|
||||
const int16 TYPE_INVALID = IINVALID;
|
||||
const int16 TYPE_BEGIN = typePossessions;
|
||||
const int16 TYPE_END = typeOther;
|
||||
const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1;
|
||||
|
||||
int16 GetInvTypeSize(int16 inv_type);
|
||||
const char* GetInvTypeName(int16 inv_type);
|
||||
|
||||
bool IsInvTypePersistent(int16 inv_type);
|
||||
|
||||
} /*invtype*/
|
||||
|
||||
namespace invslot {
|
||||
inline EQ::versions::ClientVersion GetInvSlotRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
namespace enum_ {
|
||||
enum InventorySlots : int16 {
|
||||
slotCharm = INULL,
|
||||
slotEar1,
|
||||
slotHead,
|
||||
slotFace,
|
||||
slotEar2,
|
||||
slotNeck,
|
||||
slotShoulders,
|
||||
slotArms,
|
||||
slotBack,
|
||||
slotWrist1,
|
||||
slotWrist2,
|
||||
slotRange,
|
||||
slotHands,
|
||||
slotPrimary,
|
||||
slotSecondary,
|
||||
slotFinger1,
|
||||
slotFinger2,
|
||||
slotChest,
|
||||
slotLegs,
|
||||
slotFeet,
|
||||
slotWaist,
|
||||
slotPowerSource,
|
||||
slotAmmo,
|
||||
slotGeneral1,
|
||||
slotGeneral2,
|
||||
slotGeneral3,
|
||||
slotGeneral4,
|
||||
slotGeneral5,
|
||||
slotGeneral6,
|
||||
slotGeneral7,
|
||||
slotGeneral8,
|
||||
slotGeneral9,
|
||||
slotGeneral10,
|
||||
slotGeneral11,
|
||||
slotGeneral12,
|
||||
slotCursor
|
||||
};
|
||||
|
||||
constexpr int16 format_as(InventorySlots slot) { return static_cast<int16>(slot); }
|
||||
} // namespace enum_
|
||||
using namespace enum_;
|
||||
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
|
||||
const int16 POSSESSIONS_BEGIN = slotCharm;
|
||||
const int16 POSSESSIONS_END = slotCursor;
|
||||
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
|
||||
|
||||
const int16 EQUIPMENT_BEGIN = slotCharm;
|
||||
const int16 EQUIPMENT_END = slotAmmo;
|
||||
const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN) + 1;
|
||||
|
||||
//We support more if enabled but for now lets leave it at the 10 slots
|
||||
const int16 GENERAL_BEGIN = slotGeneral1;
|
||||
const int16 GENERAL_END = slotGeneral10;
|
||||
const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN) + 1;
|
||||
|
||||
const int16 BONUS_BEGIN = invslot::slotCharm;
|
||||
const int16 BONUS_STAT_END = invslot::slotPowerSource;
|
||||
const int16 BONUS_SKILL_END = invslot::slotAmmo;
|
||||
|
||||
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
|
||||
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
|
||||
|
||||
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
|
||||
const uint64 GENERAL_BITMASK = 0x00000007FF800000;
|
||||
const uint64 CURSOR_BITMASK = 0x0000000800000000;
|
||||
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 36-slot count (Laurion+)
|
||||
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 36)); // based on 36-slot count (Laurion+)
|
||||
|
||||
|
||||
const char* GetInvPossessionsSlotName(int16 inv_slot);
|
||||
const char* GetInvSlotName(int16 inv_type, int16 inv_slot);
|
||||
|
||||
} /*invslot*/
|
||||
|
||||
namespace invbag {
|
||||
inline EQ::versions::ClientVersion GetInvBagRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const int16 SLOT_INVALID = IINVALID;
|
||||
const int16 SLOT_BEGIN = INULL;
|
||||
const int16 SLOT_END = 9; //254;
|
||||
const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test)
|
||||
|
||||
const char* GetInvBagIndexName(int16 bag_index);
|
||||
|
||||
} /*invbag*/
|
||||
|
||||
namespace invaug {
|
||||
inline EQ::versions::ClientVersion GetInvAugRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const int16 SOCKET_INVALID = IINVALID;
|
||||
const int16 SOCKET_BEGIN = INULL;
|
||||
const int16 SOCKET_END = 5;
|
||||
const int16 SOCKET_COUNT = 6;
|
||||
|
||||
const char* GetInvAugIndexName(int16 aug_index);
|
||||
|
||||
} /*invaug*/
|
||||
|
||||
namespace item {
|
||||
inline EQ::versions::ClientVersion GetItemRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
//enum Unknown : int { // looks like item class..but, RoF has it too - nothing in UF-
|
||||
// Unknown1 = 0,
|
||||
// Unknown2 = 1,
|
||||
// Unknown3 = 2,
|
||||
// Unknown4 = 5 // krono?
|
||||
//};
|
||||
|
||||
enum ItemPacketType : int {
|
||||
ItemPacketMerchant = 0x64,
|
||||
ItemPacketTradeView = 0x65,
|
||||
ItemPacketLoot = 0x66,
|
||||
ItemPacketTrade = 0x67,
|
||||
//looks like they added something at 0x68 that didn't exist before and shifted everything after it up by 1
|
||||
ItemPacketUnknown068 = 0x68, //Not sure but it seems to deal with the cursor somehow.
|
||||
ItemPacketCharInventory = 0x6A, //Rof 0x69 -> Larion 0x6a (requires translation)
|
||||
ItemPacketLimbo = 0x6B, //0x6A -> 0x6B
|
||||
ItemPacketWorldContainer = 0x6C,
|
||||
ItemPacketTributeItem = 0x6D,
|
||||
ItemPacketGuildTribute = 0x6E,
|
||||
ItemPacketCharmUpdate = 0x6f,
|
||||
ItemPacketRecovery = 0x72,
|
||||
ItemPacketParcel = 0x74,
|
||||
ItemPacketUnknown075 = 0x75, //Not sure but uses a lot of the same logic as the trade and char inventory types
|
||||
ItemPacketOverflow = 0x76,
|
||||
ItemPacketDragonHoard = 0x77,
|
||||
ItemPacketTradeskill = 0x78,
|
||||
ItemPacketTradeskillDepot = 0x79,
|
||||
ItemPacketInvalid = 0xFF
|
||||
};
|
||||
|
||||
} /*item*/
|
||||
|
||||
namespace profile {
|
||||
inline EQ::versions::ClientVersion GetProfileRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances
|
||||
const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
|
||||
|
||||
const int16 POTION_BELT_SIZE = 5;
|
||||
|
||||
const int16 SKILL_ARRAY_SIZE = 100;
|
||||
|
||||
} /*profile*/
|
||||
|
||||
namespace constants {
|
||||
inline EQ::versions::ClientVersion GetConstantsRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const EQ::expansions::Expansion EXPANSION = EQ::expansions::Expansion::LS;
|
||||
const uint32 EXPANSION_BIT = EQ::expansions::bitLS;
|
||||
const uint32 EXPANSIONS_MASK = EQ::expansions::maskLS;
|
||||
|
||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 56;
|
||||
const uint32 MAX_GUILD_ID = 50000;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
namespace behavior {
|
||||
inline EQ::versions::ClientVersion GetBehaviorRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const bool CoinHasWeight = false;
|
||||
|
||||
} /*behavior*/
|
||||
|
||||
namespace skills {
|
||||
inline EQ::versions::ClientVersion GetSkillsRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
const size_t LastUsableSkill = EQ::skills::Skill2HPiercing;
|
||||
|
||||
} /*skills*/
|
||||
|
||||
namespace spells {
|
||||
inline EQ::versions::ClientVersion GetSkillsRef() { return EQ::versions::ClientVersion::Laurion; }
|
||||
|
||||
enum class CastingSlot : uint32 {
|
||||
Gem1 = 0,
|
||||
Gem2 = 1,
|
||||
Gem3 = 2,
|
||||
Gem4 = 3,
|
||||
Gem5 = 4,
|
||||
Gem6 = 5,
|
||||
Gem7 = 6,
|
||||
Gem8 = 7,
|
||||
Gem9 = 8,
|
||||
Gem10 = 9,
|
||||
Gem11 = 10,
|
||||
Gem12 = 11,
|
||||
MaxGems = 18, // fallacy..only 12 slot are useable...
|
||||
Item = 12,
|
||||
Discipline = 13,
|
||||
AltAbility = 0xFF
|
||||
};
|
||||
|
||||
const int SPELL_ID_MAX = 71999;
|
||||
const int SPELLBOOK_SIZE = 1120;
|
||||
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
|
||||
const int SPELL_GEM_RECAST_TIMER = 15;
|
||||
|
||||
const int LONG_BUFFS = 42;
|
||||
const int SHORT_BUFFS = 30;
|
||||
const int DISC_BUFFS = 1;
|
||||
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
|
||||
const int NPC_BUFFS = 400;
|
||||
const int PET_BUFFS = NPC_BUFFS;
|
||||
const int MERC_BUFFS = LONG_BUFFS;
|
||||
|
||||
} /*spells*/
|
||||
|
||||
}; /* Laurion */
|
||||
|
||||
#endif /*COMMON_LAURION_LIMITS_H*/
|
||||
@@ -1,96 +0,0 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
E(OP_Action)
|
||||
E(OP_Animation)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_AugmentInfo)
|
||||
E(OP_BeginCast)
|
||||
E(OP_BlockedBuffs)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_CastSpell)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClickObjectAction)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
E(OP_Damage)
|
||||
E(OP_Death)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_DisciplineUpdate)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_ExpUpdate)
|
||||
E(OP_FormattedMessage)
|
||||
E(OP_GMTraining)
|
||||
E(OP_GMTrainSkillConfirm)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_HPUpdate)
|
||||
E(OP_Illusion)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_LogServer)
|
||||
E(OP_ManaChange)
|
||||
E(OP_MobHealth)
|
||||
E(OP_MoneyOnCorpse)
|
||||
E(OP_MoveItem)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_NewZone)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_RemoveBlockedBuffs)
|
||||
E(OP_RespondAA)
|
||||
E(OP_RequestClientZoneChange)
|
||||
E(OP_RecipeAutoCombine)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendMaxCharacters)
|
||||
E(OP_SendMembership)
|
||||
E(OP_SendMembershipDetails)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SkillUpdate)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_Stun)
|
||||
E(OP_WearChange)
|
||||
E(OP_ZoneChange)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_ZoneSpawns)
|
||||
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_Animation)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BlockedBuffs)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_ClickDoor)
|
||||
D(OP_Consider)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_EnterWorld)
|
||||
D(OP_GMTraining)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_MoveItem)
|
||||
D(OP_RemoveBlockedBuffs)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_SpawnAppearance)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_WearChange)
|
||||
D(OP_ZoneEntry)
|
||||
D(OP_ZoneChange)
|
||||
#undef E
|
||||
#undef D
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@
|
||||
#include "sod.h"
|
||||
#include "rof.h"
|
||||
#include "rof2.h"
|
||||
#include "laurion.h"
|
||||
|
||||
|
||||
void RegisterAllPatches(EQStreamIdentifier &into)
|
||||
{
|
||||
@@ -36,7 +36,6 @@ void RegisterAllPatches(EQStreamIdentifier &into)
|
||||
UF::Register(into);
|
||||
RoF::Register(into);
|
||||
RoF2::Register(into);
|
||||
Laurion::Register(into);
|
||||
}
|
||||
|
||||
void ReloadAllPatches()
|
||||
@@ -47,5 +46,4 @@ void ReloadAllPatches()
|
||||
UF::Reload();
|
||||
RoF::Reload();
|
||||
RoF2::Reload();
|
||||
Laurion::Reload();
|
||||
}
|
||||
|
||||
+54
-24
@@ -3089,6 +3089,21 @@ namespace RoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(Merchant_Click_Struct);
|
||||
SETUP_DIRECT_ENCODE(Merchant_Click_Struct, structs::Merchant_Click_Struct);
|
||||
|
||||
OUT(npcid);
|
||||
OUT(playerid);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
eq->unknown01 = 3; // Not sure what these values do yet, but list won't display without them
|
||||
eq->unknown02 = 2592000;
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SkillUpdate)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(SkillUpdate_Struct);
|
||||
@@ -3494,13 +3509,14 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(ClickTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||
|
||||
eq->Code = emu->action;
|
||||
for (uint32 i = 0; i < RoF::invtype::BAZAAR_SIZE; i++)
|
||||
eq->Code = emu->Code;
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
for (uint32 i = 0; i < 200; i++)
|
||||
{
|
||||
strncpy(eq->items[i].SerialNumber, "0000000000000000", sizeof(eq->items[i].SerialNumber));
|
||||
eq->items[i].Unknown18 = 0;
|
||||
if (i < 80) {
|
||||
eq->ItemCost[i] = emu->item_cost[i];
|
||||
eq->ItemCost[i] = emu->ItemCost[i];
|
||||
}
|
||||
else {
|
||||
eq->ItemCost[i] = 0;
|
||||
@@ -3514,9 +3530,9 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
|
||||
eq->Code = emu->action;
|
||||
eq->Code = emu->Code;
|
||||
strncpy(eq->SerialNumber, "0000000000000000", sizeof(eq->SerialNumber));
|
||||
eq->TraderID = emu->entity_id;
|
||||
eq->TraderID = emu->TraderID;
|
||||
eq->Stacksize = 0;
|
||||
eq->Price = 0;
|
||||
|
||||
@@ -3542,13 +3558,13 @@ namespace RoF
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
OUT(item_id);
|
||||
OUT(quantity);
|
||||
OUT(already_sold);
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -5031,6 +5047,19 @@ namespace RoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::Merchant_Click_Struct);
|
||||
SETUP_DIRECT_DECODE(Merchant_Click_Struct, structs::Merchant_Click_Struct);
|
||||
|
||||
IN(npcid);
|
||||
IN(playerid);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Trader)
|
||||
{
|
||||
uint32 psize = __packet->size;
|
||||
@@ -5040,11 +5069,12 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::ClickTrader_Struct);
|
||||
MEMSET_IN(ClickTrader_Struct);
|
||||
|
||||
emu->action = eq->Code;
|
||||
for (uint32 i = 0; i < RoF::invtype::BAZAAR_SIZE; i++)
|
||||
emu->Code = eq->Code;
|
||||
// Live actually has 200 items now, but 80 is the most our internal struct supports
|
||||
for (uint32 i = 0; i < 80; i++)
|
||||
{
|
||||
emu->serial_number[i] = 0; // eq->SerialNumber[i];
|
||||
emu->item_cost[i] = eq->ItemCost[i];
|
||||
emu->SerialNumber[i] = 0; // eq->SerialNumber[i];
|
||||
emu->ItemCost[i] = eq->ItemCost[i];
|
||||
}
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -5055,8 +5085,8 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
MEMSET_IN(Trader_ShowItems_Struct);
|
||||
|
||||
emu->action = eq->Code;
|
||||
emu->entity_id = eq->TraderID;
|
||||
emu->Code = eq->Code;
|
||||
emu->TraderID = eq->TraderID;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
@@ -5078,12 +5108,12 @@ namespace RoF
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
+365
-1224
File diff suppressed because it is too large
Load Diff
@@ -271,7 +271,6 @@ namespace RoF2
|
||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 56;
|
||||
const uint32 MAX_GUILD_ID = 50000;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
|
||||
@@ -43,12 +43,10 @@ E(OP_ApplyPoison)
|
||||
E(OP_AugmentInfo)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_BeginCast)
|
||||
E(OP_BlockedBuffs)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_BuyerItems)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_CastSpell)
|
||||
E(OP_ChannelMessage)
|
||||
@@ -151,13 +149,11 @@ D(OP_Animation)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Barter)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_BlockedBuffs)
|
||||
D(OP_BookButton)
|
||||
D(OP_Buff)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_BuyerItems)
|
||||
D(OP_CastSpell)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
@@ -205,7 +201,6 @@ D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_ShopSendParcel)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
|
||||
+148
-312
@@ -354,15 +354,15 @@ struct Spawn_Struct_Bitfields
|
||||
/*29*/ unsigned showname:1;
|
||||
/*30*/ unsigned idleanimationsoff:1; // what we called statue?
|
||||
/*31*/ unsigned untargetable:1; // bClickThrough
|
||||
// byte 5
|
||||
/*32 unsigned buyer:1;
|
||||
/*33 unsigned offline:1;
|
||||
/*34 unsigned interactiveobject:1;
|
||||
/*35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
||||
/*36 unsigned title:1;
|
||||
/*37 unsigned suffix:1;
|
||||
/*38 unsigned padding1:1;
|
||||
/*39 unsigned padding2:1;
|
||||
/* do these later
|
||||
32 unsigned buyer:1;
|
||||
33 unsigned offline:1;
|
||||
34 unsigned interactiveobject:1;
|
||||
35 unsigned flung:1; // hmm this vfunc appears to do stuff with leve and flung variables
|
||||
36 unsigned title:1;
|
||||
37 unsigned suffix:1;
|
||||
38 unsigned padding1:1;
|
||||
39 unsigned padding2:1;
|
||||
40 unsinged padding3:1;
|
||||
*/
|
||||
/*
|
||||
@@ -2247,17 +2247,15 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 unknown01; // Seen 3 from Server or -1 from Client
|
||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -3106,163 +3104,28 @@ struct EnvDamage2_Struct {
|
||||
};
|
||||
|
||||
//Bazaar Stuff
|
||||
enum RoF2BazaarTraderBuyerActions {
|
||||
Zero = 0,
|
||||
BeginTraderMode = 1,
|
||||
EndTraderMode = 2,
|
||||
PriceUpdate = 3,
|
||||
EndTransaction = 4,
|
||||
BazaarSearch = 7,
|
||||
WelcomeMessage = 9,
|
||||
BuyTraderItem = 10,
|
||||
ListTraderItems = 11,
|
||||
BazaarInspect = 18,
|
||||
ClickTrader = 28,
|
||||
ItemMove = 19,
|
||||
ReconcileItems = 20
|
||||
};
|
||||
|
||||
enum RoF2BuyerActions {
|
||||
BuyerSearchResults = 0x00,
|
||||
BuyerBuyLine = 0x06,
|
||||
BuyerModifyBuyLine = 0x07,
|
||||
BuyerRemoveItem = 0x08,
|
||||
BuyerSellItem = 0x09,
|
||||
BuyerBuyItem = 0x0a,
|
||||
BuyerInspectBegin = 0x0b,
|
||||
BuyerInspectEnd = 0x0c,
|
||||
BuyerAppearance = 0x0d,
|
||||
BuyerSendBuyLine = 0x0e,
|
||||
BuyerItemInspect = 0x0f,
|
||||
BuyerBrowsingBuyLine = 0x10,
|
||||
BarterWelcomeMessage = 0x11,
|
||||
BuyerWelcomeMessage = 0x13,
|
||||
BuyerGreeting = 0x14,
|
||||
BuyerInventoryFull = 0x16
|
||||
};
|
||||
|
||||
struct BarterItemSearchLinkRequest_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 seller_id;
|
||||
uint32 buyer_id;
|
||||
uint32 unknown_016;
|
||||
uint32 slot_id; // 0xffffffff main buy line 0x0 trade_item_1, 0x1 trade_item_2
|
||||
uint32 item_id;
|
||||
uint32 unknown_028;
|
||||
};
|
||||
|
||||
struct BuyerWelcomeMessageUpdate_Struct {
|
||||
uint32 action;
|
||||
char unknown_004[64];
|
||||
uint32 unknown_068;
|
||||
char welcome_message[256];
|
||||
};
|
||||
|
||||
struct Buyer_SetAppearance_Struct {
|
||||
uint32 action;
|
||||
uint32 entity_id;
|
||||
char unknown[64];
|
||||
uint32 enabled;
|
||||
};
|
||||
|
||||
struct BuyerRemoveItem_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown004;
|
||||
uint32 slot_id;
|
||||
uint32 toggle;
|
||||
};
|
||||
|
||||
struct BuyerLineSellItem_Struct {
|
||||
uint32 action;
|
||||
uint32 purchase_method; // 0 direct merchant, 1 via /barter window
|
||||
uint32 unknown008;
|
||||
uint32 buyer_entity_id;
|
||||
uint32 seller_entity_id;
|
||||
char unknown[15];
|
||||
uint32 slot;
|
||||
uint8 enabled;
|
||||
uint32 item_id;
|
||||
char item_name[64];
|
||||
uint32 item_icon;
|
||||
uint32 item_quantity;
|
||||
uint8 item_toggle;
|
||||
uint32 item_cost;
|
||||
uint32 no_trade_items;
|
||||
BuyerLineTradeItems_Struct trade_items[10];
|
||||
char unknown2[13];
|
||||
uint32 seller_quantity;
|
||||
};
|
||||
|
||||
struct BuyerLineItemsSearch_Struct {
|
||||
uint32 slot;
|
||||
uint8 enabled;
|
||||
uint32 item_id;
|
||||
char item_name[64];
|
||||
uint32 item_icon;
|
||||
uint32 item_quantity;
|
||||
uint8 item_toggle;
|
||||
uint32 item_cost;
|
||||
uint32 buyer_id;
|
||||
BuyerLineTradeItems_Struct trade_items[MAX_BUYER_COMPENSATION_ITEMS];
|
||||
};
|
||||
|
||||
struct BuyerLineSearch_Struct {
|
||||
uint32 action;
|
||||
uint32 no_items;
|
||||
std::vector<BuyerLineItemsSearch_Struct> buy_line;
|
||||
};
|
||||
|
||||
struct BuyerStart_Struct {
|
||||
uint32 action;
|
||||
uint16 no_buyer_lines;
|
||||
uint32 slot;
|
||||
uint8 enabled;
|
||||
uint32 item_id;
|
||||
char item_name[1]; // vary length
|
||||
uint32 item_icon;
|
||||
uint32 item_quantity;
|
||||
uint8 toggle;
|
||||
uint32 item_cost;
|
||||
uint32 no_trade_items;
|
||||
BuyerLineTradeItems_Struct trade_items[1]; // size is actually no_trade_items. If 0, then this is not in packet
|
||||
char unknown[13];
|
||||
};
|
||||
|
||||
struct BuyerItemSearchResultEntry_Struct {
|
||||
char item_name[64];
|
||||
uint32 item_id;
|
||||
uint32 item_icon;
|
||||
uint32 unknown_072;
|
||||
};
|
||||
|
||||
struct BuyerItemSearchResults_Struct {
|
||||
uint32 action;
|
||||
uint32 result_count;
|
||||
BuyerItemSearchResultEntry_Struct results[];
|
||||
};
|
||||
|
||||
enum {
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_CustomerBrowsing = 13,
|
||||
BazaarInspectItem = 18,
|
||||
BazaarSearchDone2 = 19,
|
||||
BazaarInspectItem = 18,
|
||||
BazaarSearchDone2 = 19,
|
||||
BazaarTrader_StartTraderMode2 = 22
|
||||
};
|
||||
|
||||
enum {
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_UpdatePrice = 1,
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
};
|
||||
|
||||
struct BazaarWindowStart_Struct {
|
||||
@@ -3271,51 +3134,34 @@ struct BazaarWindowStart_Struct {
|
||||
uint16 Unknown002;
|
||||
};
|
||||
|
||||
struct BazaarDeliveryCost_Struct {
|
||||
uint32 action;
|
||||
uint32 voucher_delivery_cost;
|
||||
float parcel_deliver_cost; //percentage of item cost
|
||||
uint32 unknown_010;
|
||||
};
|
||||
|
||||
struct BazaarWelcome_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 num_of_traders;
|
||||
uint32 num_of_items;
|
||||
uint32 Code;
|
||||
uint32 EntityID;
|
||||
uint32 Traders;
|
||||
uint32 Items;
|
||||
uint32 Traders2;
|
||||
uint32 Items2;
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint8 search_scope;//1 all traders 0 local traders
|
||||
/*005*/ uint8 unknown_005{0};
|
||||
/*006*/ uint16 unknown_006{0};
|
||||
/*008*/ uint32 unknown_008{0};
|
||||
/*012*/ uint32 unknown_012{0};
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ uint32 _class;
|
||||
/*024*/ uint32 race;
|
||||
/*028*/ uint32 item_stat;
|
||||
/*032*/ uint32 slot;
|
||||
/*036*/ uint32 type;
|
||||
/*040*/ char item_name[64];
|
||||
/*104*/ uint32 min_cost;
|
||||
/*108*/ uint32 max_cost;
|
||||
/*112*/ uint32 min_level;
|
||||
/*116*/ uint32 max_level;
|
||||
/*120*/ uint32 max_results;
|
||||
/*124*/ uint32 prestige;
|
||||
/*128*/ uint32 augment;
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 TraderID;
|
||||
uint32 Class_;
|
||||
uint32 Race;
|
||||
uint32 ItemStat;
|
||||
uint32 Slot;
|
||||
uint32 Type;
|
||||
char Name[64];
|
||||
uint32 MinPrice;
|
||||
uint32 MaxPrice;
|
||||
uint32 Minlevel;
|
||||
uint32 MaxLlevel;
|
||||
};
|
||||
|
||||
struct BazaarInspect_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 trader_id;
|
||||
char serial_number[17];
|
||||
char unknown_029[3];
|
||||
uint32 item_id;
|
||||
uint32 unknown_036;
|
||||
struct BazaarInspect_Struct{
|
||||
uint32 ItemID;
|
||||
uint32 Unknown004;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct NewBazaarInspect_Struct {
|
||||
@@ -3336,23 +3182,18 @@ struct BazaarReturnDone_Struct{
|
||||
uint32 Unknown016;
|
||||
};
|
||||
|
||||
struct BazaarSearchDetails_Struct { //24+name+17
|
||||
/*014*/ uint32 trader_id;
|
||||
/*018*/ char serial_num[17];
|
||||
/*022*/ uint32 cost;
|
||||
/*026*/ uint32 quanity;
|
||||
/*030*/ uint32 id;
|
||||
/*034*/ uint32 icon;
|
||||
/*038*/ char name[1];
|
||||
/*039*/ uint32 stat;
|
||||
};
|
||||
|
||||
struct BazaarSearchResults_Struct { //14
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint16 zone_id;
|
||||
/*006*/ uint32 entity_id;
|
||||
/*010*/ uint32 num_items;
|
||||
/*014*/ BazaarSearchDetails_Struct items[];
|
||||
struct BazaarSearchResults_Struct {
|
||||
/*000*/ BazaarWindowStart_Struct Beginning;
|
||||
/*004*/ uint32 SellerID;
|
||||
/*008*/ char SellerName[64];
|
||||
/*072*/ uint32 NumItems;
|
||||
/*076*/ uint32 ItemID;
|
||||
/*080*/ uint32 SerialNumber;
|
||||
/*084*/ uint32 Unknown084;
|
||||
/*088*/ char ItemName[64];
|
||||
/*152*/ uint32 Cost;
|
||||
/*156*/ uint32 ItemStat;
|
||||
/*160*/
|
||||
};
|
||||
|
||||
struct ServerSideFilters_Struct {
|
||||
@@ -3555,26 +3396,21 @@ struct WhoAllPlayerPart4 {
|
||||
};
|
||||
|
||||
struct TraderItemSerial_Struct {
|
||||
char serial_number[17];
|
||||
uint8 unknown_018;
|
||||
|
||||
void operator=(uint32 a) {
|
||||
auto _tmp = fmt::format("{:016}", a);
|
||||
strn0cpy(this->serial_number, _tmp.c_str(), sizeof(this->serial_number));
|
||||
}
|
||||
char SerialNumber[17];
|
||||
uint8 Unknown18;
|
||||
};
|
||||
|
||||
struct BeginTrader_Struct {
|
||||
/*0000*/ uint32 action;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 item_cost[200];
|
||||
struct Trader_Struct {
|
||||
/*0000*/ uint32 Code;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 ItemCost[200];
|
||||
/*4404*/
|
||||
};
|
||||
|
||||
struct ClickTrader_Struct {
|
||||
/*0000*/ uint32 action;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 item_cost[200];
|
||||
/*0000*/ uint32 Code;
|
||||
/*0004*/ TraderItemSerial_Struct items[200];
|
||||
/*3604*/ uint32 ItemCost[200];
|
||||
/*4404*/
|
||||
};
|
||||
|
||||
@@ -3583,55 +3419,67 @@ struct GetItems_Struct {
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct {
|
||||
uint32 entity_id;
|
||||
uint32 action;
|
||||
};
|
||||
|
||||
struct BazaarWindowRemoveTrader_Struct {
|
||||
uint32 action;
|
||||
uint32 trader_id;
|
||||
};
|
||||
|
||||
struct TraderPriceUpdate_Struct {
|
||||
uint32 action;
|
||||
char serial_number[17];
|
||||
char unknown_021[3];
|
||||
uint32 unknown_024;
|
||||
uint32 new_price;
|
||||
uint32 id;
|
||||
uint32 code;
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 entity_id;
|
||||
/*008*/ uint32 unknown_008;
|
||||
/*012*/
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint16 TraderID;
|
||||
/*008*/ uint32 Unknown08;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct_WIP {
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ char SerialNumber[17];
|
||||
/*021*/ uint8 Unknown21;
|
||||
/*022*/ uint16 TraderID;
|
||||
/*026*/ uint32 Stacksize;
|
||||
/*030*/ uint32 Price;
|
||||
/*032*/
|
||||
};
|
||||
|
||||
struct TraderStatus_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 sub_action;
|
||||
/*008*/ uint32 uknown_008;
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 Uknown04;
|
||||
/*008*/ uint32 Uknown08;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 method;
|
||||
/*008*/ uint32 sub_action;
|
||||
/*012*/ uint32 unknown_012;
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ char buyer_name[64];
|
||||
/*084*/ char seller_name[64];
|
||||
/*148*/ char unknown_148[32];
|
||||
/*180*/ char item_name[64];
|
||||
/*244*/ char serial_number[17];
|
||||
/*261*/ char unknown_261[3];
|
||||
/*264*/ uint32 item_id;
|
||||
/*268*/ uint32 price;
|
||||
/*272*/ uint32 already_sold;
|
||||
/*276*/ uint32 unknown_276;
|
||||
/*280*/ uint32 quantity;
|
||||
/*284*/
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Unknown008;
|
||||
/*012*/ uint32 Unknown012;
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char BuyerName[64];
|
||||
/*084*/ char SellerName[64];
|
||||
/*148*/ char Unknown148[32];
|
||||
/*180*/ char ItemName[64];
|
||||
/*244*/ char SerialNumber[16];
|
||||
/*260*/ uint32 Unknown076;
|
||||
/*264*/ uint32 ItemID;
|
||||
/*268*/ uint32 Price;
|
||||
/*272*/ uint32 AlreadySold;
|
||||
/*276*/ uint32 Unknown276;
|
||||
/*280*/ uint32 Quantity;
|
||||
/*284*/
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct_OLD {
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Price;
|
||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char ItemName[64];
|
||||
/*084*/ uint32 Unknown076;
|
||||
/*088*/ uint32 ItemID;
|
||||
/*092*/ uint32 AlreadySold;
|
||||
/*096*/ uint32 Quantity;
|
||||
/*100*/ uint32 Unknown092;
|
||||
/*104*/
|
||||
};
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
@@ -3652,15 +3500,15 @@ struct MoneyUpdate_Struct{
|
||||
struct TraderDelItem_Struct{
|
||||
/*000*/ uint32 Unknown000;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ char SerialNumber[17];
|
||||
/*008*/ char SerialNumber[16];
|
||||
/*024*/ uint32 Unknown012;
|
||||
/*028*/
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 trader_id;
|
||||
/*008*/ uint32 unknown_008;
|
||||
/*000*/ uint32 Code;
|
||||
/*004*/ uint32 TraderID;
|
||||
/*008*/ uint32 Approval;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
@@ -4724,25 +4572,25 @@ struct RoF2SlotStruct
|
||||
|
||||
struct ItemSerializationHeader
|
||||
{
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
/*026*/ uint16 main_slot;
|
||||
/*028*/ uint16 sub_slot;
|
||||
/*030*/ uint16 aug_slot; // 0xffff
|
||||
/*032*/ uint32 price;
|
||||
/*036*/ uint32 merchant_slot; // 1 if not a merchant item
|
||||
/*040*/ uint32 scaled_value; // 0
|
||||
/*044*/ uint32 instance_id; // unique instance id if not merchant item, else is merchant slot
|
||||
/*048*/ uint32 parcel_item_id;
|
||||
/*052*/ uint32 last_cast_time; // Unix Time from PP of last cast for this recast type if recast delay > 0
|
||||
/*056*/ uint32 charges; // Total Charges an item has (-1 for unlimited)
|
||||
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
|
||||
/*064*/ uint32 unknown044; // 0
|
||||
/*068*/ uint32 unknown048; // 0
|
||||
/*072*/ uint32 unknown052; // 0
|
||||
uint8 isEvolving;
|
||||
/*000*/ char unknown000[17]; // New for HoT. Looks like a string.
|
||||
/*017*/ uint32 stacksize;
|
||||
/*021*/ uint32 unknown004;
|
||||
/*025*/ uint8 slot_type; // 0 = normal, 1 = bank, 2 = shared bank, 9 = merchant, 20 = ?
|
||||
/*026*/ uint16 main_slot;
|
||||
/*028*/ uint16 sub_slot;
|
||||
/*030*/ uint16 aug_slot; // 0xffff
|
||||
/*032*/ uint32 price;
|
||||
/*036*/ uint32 merchant_slot; //1 if not a merchant item
|
||||
/*040*/ uint32 scaled_value; //0
|
||||
/*044*/ uint32 instance_id; //unique instance id if not merchant item, else is merchant slot
|
||||
/*048*/ uint32 unknown028; //0
|
||||
/*052*/ uint32 last_cast_time; // Unix Time from PP of last cast for this recast type if recast delay > 0
|
||||
/*056*/ uint32 charges; //Total Charges an item has (-1 for unlimited)
|
||||
/*060*/ uint32 inst_nodrop; // 1 if the item is no drop (attuned items)
|
||||
/*064*/ uint32 unknown044; // 0
|
||||
/*068*/ uint32 unknown048; // 0
|
||||
/*072*/ uint32 unknown052; // 0
|
||||
uint8 isEvolving;
|
||||
};
|
||||
|
||||
struct EvolvingItem {
|
||||
@@ -5413,18 +5261,6 @@ struct Checksum_Struct {
|
||||
uint8_t data[2048];
|
||||
};
|
||||
|
||||
struct Parcel_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id;
|
||||
/*004*/ TypelessInventorySlot_Struct inventory_slot;
|
||||
/*012*/ uint32 quantity;
|
||||
/*016*/ uint32 money_flag;
|
||||
/*020*/ char send_to[64];
|
||||
/*084*/ char note[128];
|
||||
/*212*/ uint32 unknown_212;
|
||||
/*216*/ uint32 unknown_216;
|
||||
/*220*/ uint32 unknown_220;
|
||||
};
|
||||
}; /*structs*/
|
||||
|
||||
}; /*RoF2*/
|
||||
|
||||
@@ -101,6 +101,7 @@ E(OP_SendZonepoints)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
@@ -182,6 +183,7 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
|
||||
@@ -2200,17 +2200,15 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 unknown01; // Seen 3 from Server or -1 from Client
|
||||
/*020*/ int32 unknown02; // Seen 2592000 from Server or -1 from Client
|
||||
/*024*/
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -3376,17 +3374,17 @@ struct TraderStatus_Struct {
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 unknown_004;
|
||||
/*008*/ uint32 price;
|
||||
/*012*/ uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ char item_name[64];
|
||||
/*084*/ uint32 unknown_076;
|
||||
/*088*/ uint32 item_id;
|
||||
/*092*/ uint32 already_sold;
|
||||
/*096*/ uint32 quantity;
|
||||
/*100*/ uint32 unknown_092;
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Price;
|
||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char ItemName[64];
|
||||
/*084*/ uint32 Unknown076;
|
||||
/*088*/ uint32 ItemID;
|
||||
/*092*/ uint32 AlreadySold;
|
||||
/*096*/ uint32 Quantity;
|
||||
/*100*/ uint32 Unknown092;
|
||||
/*104*/
|
||||
};
|
||||
|
||||
|
||||
+13
-41
@@ -2026,19 +2026,6 @@ namespace SoD
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MerchantClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
OUT(npc_id);
|
||||
OUT(player_id);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SomeItemPacketMaybe)
|
||||
{
|
||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||
@@ -2286,13 +2273,13 @@ namespace SoD
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
OUT(item_id);
|
||||
OUT(quantity);
|
||||
OUT(already_sold);
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -3496,33 +3483,18 @@ namespace SoD
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MerchantClick_Struct);
|
||||
SETUP_DIRECT_DECODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
IN(npc_id);
|
||||
IN(player_id);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
emu->tab_display = 0;
|
||||
emu->unknown020 = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderBuy)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -78,7 +78,6 @@ E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
@@ -142,7 +141,6 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
|
||||
@@ -1845,16 +1845,12 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -2879,21 +2875,20 @@ struct Trader_ShowItems_Struct{
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 unknown_004;
|
||||
/*008*/ uint32 price;
|
||||
/*012*/ uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 trader_id;
|
||||
/*020*/ char item_name[64];
|
||||
/*084*/ uint32 unknown_076;
|
||||
/*088*/ uint32 item_id;
|
||||
/*092*/ uint32 already_sold;
|
||||
/*096*/ uint32 quantity;
|
||||
/*100*/ uint32 unknown_092;
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Price;
|
||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char ItemName[64];
|
||||
/*084*/ uint32 Unknown076;
|
||||
/*088*/ uint32 ItemID;
|
||||
/*092*/ uint32 AlreadySold;
|
||||
/*096*/ uint32 Quantity;
|
||||
/*100*/ uint32 Unknown092;
|
||||
/*104*/
|
||||
};
|
||||
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
uint32 unknown0;
|
||||
uint32 traderid;
|
||||
|
||||
+16
-44
@@ -270,8 +270,8 @@ namespace SoF
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
|
||||
OUT(trader_id);
|
||||
OUT(action);
|
||||
OUT(ID);
|
||||
OUT(Code);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -1683,19 +1683,6 @@ namespace SoF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MerchantClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
OUT(npc_id);
|
||||
OUT(player_id);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SomeItemPacketMaybe)
|
||||
{
|
||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||
@@ -1902,13 +1889,13 @@ namespace SoF
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
memcpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
OUT(item_id);
|
||||
OUT(quantity);
|
||||
OUT(already_sold);
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
@@ -2349,7 +2336,7 @@ namespace SoF
|
||||
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||
|
||||
emu->category_id = Bug::GetID(eq->category_name);
|
||||
emu->category_id = EQ::bug::CategoryNameToCategoryID(eq->category_name);
|
||||
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -2887,33 +2874,18 @@ namespace SoF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MerchantClick_Struct);
|
||||
SETUP_DIRECT_DECODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
IN(npc_id);
|
||||
IN(player_id);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
emu->tab_display = 0;
|
||||
emu->unknown020 = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderBuy)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -72,7 +72,6 @@ E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_SpecialMesg)
|
||||
@@ -129,7 +128,6 @@ D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
|
||||
@@ -1859,16 +1859,12 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct MerchantClick_Struct
|
||||
{
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
/*008*/ uint32 command; // 1=open, 0=cancel/close
|
||||
/*012*/ float rate; // cost multiplier, dosent work anymore
|
||||
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
|
||||
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
};
|
||||
|
||||
/*
|
||||
Unknowns:
|
||||
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
|
||||
@@ -2771,8 +2767,8 @@ struct GetItems_Struct{
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct{
|
||||
uint32 trader_id;
|
||||
uint32 action;
|
||||
uint32 ID;
|
||||
uint32 Code;
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct{
|
||||
@@ -2782,15 +2778,15 @@ struct Trader_ShowItems_Struct{
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 price;
|
||||
/*008*/ uint32 trader_id;
|
||||
/*012*/ char item_name[64];
|
||||
/*076*/ uint32 unknown_076;
|
||||
/*080*/ uint32 item_id;
|
||||
/*084*/ uint32 already_sold;
|
||||
/*088*/ uint32 quantity;
|
||||
/*092*/ uint32 unknown_092;
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Price;
|
||||
/*008*/ uint32 TraderID;
|
||||
/*012*/ char ItemName[64];
|
||||
/*076*/ uint32 Unknown076;
|
||||
/*080*/ uint32 ItemID;
|
||||
/*084*/ uint32 AlreadySold;
|
||||
/*088*/ uint32 Quantity;
|
||||
/*092*/ uint32 Unknown092;
|
||||
};
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
|
||||
|
||||
#define ALLOC_LEN_ENCODE(len) \
|
||||
__packet->pBuffer = new unsigned char[len] {}; \
|
||||
__packet->pBuffer = new unsigned char[len]; \
|
||||
__packet->size = len; \
|
||||
memset(__packet->pBuffer, 0, len); \
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
#define SETUP_DIRECT_DECODE(emu_struct, eq_struct) \
|
||||
unsigned char *__eq_buffer = __packet->pBuffer; \
|
||||
__packet->size = sizeof(emu_struct); \
|
||||
__packet->pBuffer = new unsigned char[__packet->size] {}; \
|
||||
__packet->pBuffer = new unsigned char[__packet->size]; \
|
||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
||||
auto size = strlen(in->var_field); \
|
||||
__packet->size = sizeof(emu_struct) + size + 1; \
|
||||
__packet->pBuffer = new unsigned char[__packet->size] {}; \
|
||||
__packet->pBuffer = new unsigned char[__packet->size]; \
|
||||
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
||||
eq_struct *eq = (eq_struct *) __eq_buffer;
|
||||
|
||||
|
||||
+70
-449
@@ -32,7 +32,6 @@
|
||||
#include "../strings.h"
|
||||
#include "../item_instance.h"
|
||||
#include "titanium_structs.h"
|
||||
#include "../rulesys.h"
|
||||
#include "../path_manager.h"
|
||||
#include "../raid.h"
|
||||
#include "../guilds.h"
|
||||
@@ -198,135 +197,64 @@ namespace Titanium
|
||||
|
||||
ENCODE(OP_BazaarSearch)
|
||||
{
|
||||
if (((*p)->size == sizeof(BazaarReturnDone_Struct)) || ((*p)->size == sizeof(BazaarWelcome_Struct))) {
|
||||
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
//consume the packet
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
uint32 action = *(uint32 *)in->pBuffer;
|
||||
//store away the emu struct
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
BazaarSearchResults_Struct *emu = (BazaarSearchResults_Struct *)__emu_buffer;
|
||||
|
||||
switch (action) {
|
||||
case BazaarSearch: {
|
||||
LogTrading(
|
||||
"Encode OP_BazaarSearch(Ti) BazaarSearch action <green>[{}]",
|
||||
action
|
||||
);
|
||||
std::vector<BazaarSearchResultsFromDB_Struct> results {};
|
||||
auto bsms = (BazaarSearchMessaging_Struct *)in->pBuffer;
|
||||
EQ::Util::MemoryStreamReader ss(
|
||||
reinterpret_cast<char *>(bsms->payload),
|
||||
in->size - sizeof(BazaarSearchMessaging_Struct)
|
||||
);
|
||||
cereal::BinaryInputArchive ar(ss);
|
||||
ar(results);
|
||||
|
||||
auto size = results.size() * sizeof(structs::BazaarSearchResults_Struct);
|
||||
auto buffer = new uchar[size];
|
||||
uchar *bufptr = buffer;
|
||||
memset(buffer, 0, size);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, structs::TiBazaarTraderBuyerActions::BazaarSearch);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->trader_entity_id);
|
||||
bufptr += 4;
|
||||
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->item_id);
|
||||
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->serial_number);
|
||||
bufptr += 4;
|
||||
if (row->stackable) {
|
||||
strn0cpy(
|
||||
reinterpret_cast<char *>(bufptr),
|
||||
fmt::format("{}({})", row->item_name.c_str(), row->charges).c_str(),
|
||||
64
|
||||
);
|
||||
}
|
||||
else {
|
||||
strn0cpy(
|
||||
reinterpret_cast<char *>(bufptr),
|
||||
fmt::format("{}({})", row->item_name.c_str(), row->count).c_str(),
|
||||
64
|
||||
);
|
||||
}
|
||||
bufptr += 64;
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->cost);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->item_stat);
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_BazaarSearch, size);
|
||||
memcpy(outapp->pBuffer, buffer, size);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
safe_delete_array(buffer);
|
||||
safe_delete(in);
|
||||
break;
|
||||
}
|
||||
case BazaarInspect:
|
||||
case WelcomeMessage: {
|
||||
LogTrading(
|
||||
"Encode OP_BazaarSearch(Ti) BazaarInspect/WelcomeMessage action <green>[{}]",
|
||||
action
|
||||
);
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogTrading(
|
||||
"Encode OP_BazaarSearch(Ti) unhandled action <red>[{}]",
|
||||
action
|
||||
);
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
//determine and verify length
|
||||
int entrycount = in->size / sizeof(BazaarSearchResults_Struct);
|
||||
if (entrycount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0) {
|
||||
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d",
|
||||
opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
|
||||
//make the EQ struct.
|
||||
in->size = sizeof(structs::BazaarSearchResults_Struct)*entrycount;
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
structs::BazaarSearchResults_Struct *eq = (structs::BazaarSearchResults_Struct *) in->pBuffer;
|
||||
|
||||
//zero out the packet. We could avoid this memset by setting all fields (including unknowns) in the loop.
|
||||
memset(in->pBuffer, 0, in->size);
|
||||
|
||||
for (int i = 0; i < entrycount; i++, eq++, emu++) {
|
||||
eq->Beginning.Action = emu->Beginning.Action;
|
||||
eq->Beginning.Unknown001 = emu->Beginning.Unknown001;
|
||||
eq->Beginning.Unknown002 = emu->Beginning.Unknown002;
|
||||
eq->NumItems = emu->NumItems;
|
||||
eq->SerialNumber = emu->SerialNumber;
|
||||
eq->SellerID = emu->SellerID;
|
||||
eq->Cost = emu->Cost;
|
||||
eq->ItemStat = emu->ItemStat;
|
||||
strcpy(eq->ItemName, emu->ItemName);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_BecomeTrader)
|
||||
{
|
||||
uint32 action = *(uint32 *)(*p)->pBuffer;
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case TraderOff:
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_BecomeTrader(Ti) TraderOff action <green>[{}] entity_id <green>[{}] trader_name "
|
||||
"<green>[{}]",
|
||||
emu->action,
|
||||
emu->entity_id,
|
||||
emu->trader_name
|
||||
);
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::Zero;
|
||||
eq->entity_id = emu->entity_id;
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case TraderOn:
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_BecomeTrader(Ti) TraderOn action <green>[{}] entity_id <green>[{}] trader_name "
|
||||
"<green>[{}]",
|
||||
emu->action,
|
||||
emu->entity_id,
|
||||
emu->trader_name
|
||||
);
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::BeginTraderMode;
|
||||
eq->entity_id = emu->entity_id;
|
||||
strn0cpy(eq->trader_name, emu->trader_name, sizeof(eq->trader_name));
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LogTrading(
|
||||
"Encode OP_BecomeTrader(Ti) unhandled action <red>[{}] Sending packet as is.",
|
||||
action
|
||||
);
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
}
|
||||
OUT(ID);
|
||||
OUT(Code);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_Buff)
|
||||
@@ -806,7 +734,7 @@ namespace Titanium
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case AppearanceType::GuildShow: {
|
||||
FAIL_ENCODE();
|
||||
@@ -820,28 +748,6 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildsList)
|
||||
{
|
||||
EQApplicationPacket* in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
GuildsListMessaging_Struct glms{};
|
||||
EQ::Util::MemoryStreamReader ss(reinterpret_cast<char *>(in->pBuffer), in->size);
|
||||
cereal::BinaryInputArchive ar(ss);
|
||||
ar(glms);
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_GuildsList, sizeof(structs::GuildsList_Struct));
|
||||
auto out = (structs::GuildsList_Struct *) outapp->pBuffer;
|
||||
|
||||
for (auto const& g : glms.guild_detail) {
|
||||
if (g.guild_id < Titanium::constants::MAX_GUILD_ID) {
|
||||
strn0cpy(out->Guilds[g.guild_id].name, g.guild_name.c_str(), sizeof(out->Guilds[g.guild_id].name));
|
||||
}
|
||||
}
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildMemberAdd)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(GuildMemberAdd_Struct)
|
||||
@@ -1952,19 +1858,6 @@ namespace Titanium
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MerchantClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
OUT(npc_id);
|
||||
OUT(player_id);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SpecialMesg)
|
||||
{
|
||||
EQApplicationPacket *in = *p;
|
||||
@@ -2082,170 +1975,32 @@ namespace Titanium
|
||||
|
||||
ENCODE(OP_Trader)
|
||||
{
|
||||
auto action = *(uint32 *) (*p)->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case TraderOn: {
|
||||
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader BeginTraderMode action <green>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::BeginTraderMode;
|
||||
OUT(entity_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case TraderOff: {
|
||||
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader EndTraderMode action <green>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::EndTraderMode;
|
||||
OUT(entity_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case ListTraderItems: {
|
||||
ENCODE_LENGTH_EXACT(Trader_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_Struct, structs::Trader_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader ListTraderItems action <green>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::ListTraderItems;
|
||||
std::copy_n(emu->items, UF::invtype::BAZAAR_SIZE, eq->item_id);
|
||||
std::copy_n(emu->item_cost, UF::invtype::BAZAAR_SIZE, eq->item_cost);
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case BuyTraderItem: {
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
eq->item_id,
|
||||
eq->price,
|
||||
eq->quantity,
|
||||
eq->trader_id
|
||||
);
|
||||
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::BuyTraderItem;
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
OUT(item_id);
|
||||
OUT(already_sold);
|
||||
OUT(quantity);
|
||||
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case ItemMove: {
|
||||
LogTrading(
|
||||
"Encode OP_Trader ItemMove action <green>[{}]",
|
||||
action
|
||||
);
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
LogError("Unknown Encode OP_Trader action <red>{} received. Unhandled.", action);
|
||||
}
|
||||
if ((*p)->size != sizeof(TraderBuy_Struct)) {
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
ENCODE_FORWARD(OP_TraderBuy);
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderBuy)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_TraderBuy item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
emu->item_id,
|
||||
emu->price,
|
||||
emu->quantity,
|
||||
emu->trader_id
|
||||
);
|
||||
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
OUT(item_id);
|
||||
OUT(already_sold);
|
||||
OUT(quantity);
|
||||
OUT_str(item_name);
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderShop)
|
||||
{
|
||||
auto action = *(uint32 *)(*p)->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case ClickTrader: {
|
||||
ENCODE_LENGTH_EXACT(TraderClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
LogTrading(
|
||||
"ClickTrader action <green>[{}] trader_id <green>[{}]",
|
||||
action,
|
||||
emu->TraderID
|
||||
);
|
||||
|
||||
eq->action = 0;
|
||||
eq->trader_id = emu->TraderID;
|
||||
eq->approval = emu->Approval;
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case BuyTraderItem: {
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_TraderShop item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
eq->item_id,
|
||||
eq->price,
|
||||
eq->quantity,
|
||||
eq->trader_id
|
||||
);
|
||||
|
||||
eq->action = structs::TiBazaarTraderBuyerActions::BuyTraderItem;
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
OUT(item_id);
|
||||
OUT(already_sold);
|
||||
OUT(quantity);
|
||||
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
LogError("Unknown Encode OP_TraderShop action <red>[{}] received. Unhandled.", action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ENCODE(OP_TributeItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TributeItem_Struct);
|
||||
@@ -2496,53 +2251,6 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_BazaarSearch)
|
||||
{
|
||||
uint32 action = *(uint32 *) __packet->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case structs::TiBazaarTraderBuyerActions::BazaarSearch: {
|
||||
DECODE_LENGTH_EXACT(structs::BazaarSearch_Struct);
|
||||
SETUP_DIRECT_DECODE(BazaarSearchCriteria_Struct, structs::BazaarSearch_Struct);
|
||||
|
||||
emu->action = eq->Beginning.Action;
|
||||
emu->item_stat = eq->ItemStat;
|
||||
emu->max_cost = eq->MaxPrice;
|
||||
emu->min_cost = eq->MinPrice;
|
||||
emu->max_level = eq->MaxLlevel;
|
||||
emu->min_level = eq->Minlevel;
|
||||
emu->race = eq->Race;
|
||||
emu->slot = eq->Slot;
|
||||
emu->type = eq->Type == UINT32_MAX ? UINT8_MAX : eq->Type;
|
||||
emu->trader_entity_id = eq->TraderID;
|
||||
emu->trader_id = 0;
|
||||
emu->_class = eq->Class_;
|
||||
emu->search_scope = eq->TraderID > 0 ? NonRoFBazaarSearchScope : Local_Scope;
|
||||
emu->max_results = RuleI(Bazaar, MaxSearchResults);
|
||||
strn0cpy(emu->item_name, eq->Name, sizeof(emu->item_name));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::TiBazaarTraderBuyerActions::BazaarInspect: {
|
||||
SETUP_DIRECT_DECODE(BazaarInspect_Struct, structs::BazaarInspect_Struct);
|
||||
|
||||
IN(action);
|
||||
memcpy(emu->player_name, eq->player_name, sizeof(emu->player_name));
|
||||
IN(serial_number);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::TiBazaarTraderBuyerActions::WelcomeMessage: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogTrading("(Ti) Unhandled action <red>[{}]", action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_Buff)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||
@@ -2567,7 +2275,7 @@ namespace Titanium
|
||||
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||
|
||||
emu->category_id = Bug::GetID(eq->category_name);
|
||||
emu->category_id = EQ::bug::CategoryNameToCategoryID(eq->category_name);
|
||||
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
@@ -3167,105 +2875,18 @@ namespace Titanium
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MerchantClick_Struct);
|
||||
SETUP_DIRECT_DECODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
IN(npc_id);
|
||||
IN(player_id);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
emu->tab_display = 0;
|
||||
emu->unknown020 = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Trader)
|
||||
{
|
||||
auto action = (uint32) __packet->pBuffer[0];
|
||||
|
||||
switch (action) {
|
||||
case structs::TiBazaarTraderBuyerActions::BeginTraderMode: {
|
||||
DECODE_LENGTH_EXACT(structs::BeginTrader_Struct);
|
||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::BeginTrader_Struct);
|
||||
LogTrading(
|
||||
"Decode OP_Trader BeginTraderMode action <red>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
emu->action = TraderOn;
|
||||
emu->unknown_004 = 0;
|
||||
std::copy_n(eq->serial_number, Titanium::invtype::BAZAAR_SIZE, emu->serial_number);
|
||||
std::copy_n(eq->cost, Titanium::invtype::BAZAAR_SIZE, emu->item_cost);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::TiBazaarTraderBuyerActions::EndTraderMode: {
|
||||
DECODE_LENGTH_EXACT(structs::Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
LogTrading(
|
||||
"Decode OP_Trader(Ti) EndTraderMode action <red>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
emu->action = TraderOff;
|
||||
IN(entity_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::TiBazaarTraderBuyerActions::PriceUpdate:
|
||||
case structs::TiBazaarTraderBuyerActions::ItemMove:
|
||||
case structs::TiBazaarTraderBuyerActions::EndTransaction:
|
||||
case structs::TiBazaarTraderBuyerActions::ListTraderItems: {
|
||||
LogTrading(
|
||||
"Decode OP_Trader(Ti) Price/ItemMove/EndTransaction/ListTraderItems action <red>[{}]",
|
||||
action
|
||||
);
|
||||
break;
|
||||
}
|
||||
case structs::TiBazaarTraderBuyerActions::ReconcileItems: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogError("Unhandled(Ti) action <red>[{}] received.", action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_TraderBuy)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
IN(action);
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
memcpy(emu->item_name, eq->item_name, sizeof(emu->item_name));
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderShop)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderClick_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
LogTrading(
|
||||
"(Ti) action <green>[{}] trader_id <green>[{}] approval <green>[{}]",
|
||||
eq->action,
|
||||
eq->trader_id,
|
||||
eq->approval
|
||||
);
|
||||
|
||||
emu->Code = ClickTrader;
|
||||
emu->TraderID = eq->trader_id;
|
||||
emu->Approval = eq->approval;
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -287,7 +287,6 @@ namespace Titanium
|
||||
const size_t CHARACTER_CREATION_LIMIT = 8; // Hard-coded in client - DO NOT ALTER
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 45;
|
||||
const uint32 MAX_GUILD_ID = 1500;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ E(OP_Emote)
|
||||
E(OP_FormattedMessage)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_GuildsList)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildMemberAdd)
|
||||
@@ -75,14 +74,12 @@ E(OP_SendCharInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SetFace)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpecialMesg)
|
||||
E(OP_TaskDescription)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TraderShop)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
@@ -93,7 +90,6 @@ E(OP_ZoneSpawns)
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
@@ -124,10 +120,7 @@ D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TraderShop)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
|
||||
@@ -1669,9 +1669,9 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct MerchantClick_Struct {
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
};
|
||||
@@ -2273,29 +2273,24 @@ struct BazaarWelcome_Struct {
|
||||
};
|
||||
|
||||
struct BazaarSearch_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 TraderID;
|
||||
uint32 Class_;
|
||||
uint32 Race;
|
||||
uint32 ItemStat;
|
||||
uint32 Slot;
|
||||
uint32 Type;
|
||||
char Name[64];
|
||||
uint32 MinPrice;
|
||||
uint32 MaxPrice;
|
||||
uint32 Minlevel;
|
||||
uint32 MaxLlevel;
|
||||
BazaarWindowStart_Struct beginning;
|
||||
uint32 traderid;
|
||||
uint32 class_;
|
||||
uint32 race;
|
||||
uint32 stat;
|
||||
uint32 slot;
|
||||
uint32 type;
|
||||
char name[64];
|
||||
uint32 minprice;
|
||||
uint32 maxprice;
|
||||
uint32 minlevel;
|
||||
uint32 maxlevel;
|
||||
};
|
||||
|
||||
struct BazaarInspect_Struct {
|
||||
uint32 action;
|
||||
char player_name[64];
|
||||
uint32 unknown_068;
|
||||
uint32 serial_number;
|
||||
uint32 unknown_076;
|
||||
struct BazaarInspect_Struct{
|
||||
uint32 item_id;
|
||||
uint32 unknown;
|
||||
char name[64];
|
||||
};
|
||||
|
||||
struct BazaarReturnDone_Struct{
|
||||
uint32 type;
|
||||
uint32 traderid;
|
||||
@@ -2303,17 +2298,16 @@ struct BazaarReturnDone_Struct{
|
||||
uint32 unknown12;
|
||||
uint32 unknown16;
|
||||
};
|
||||
|
||||
struct BazaarSearchResults_Struct {
|
||||
BazaarWindowStart_Struct Beginning;
|
||||
uint32 entity_id;
|
||||
uint32 unknown_008;
|
||||
uint32 item_id;
|
||||
uint32 serial_number;
|
||||
uint32 unknown_020;
|
||||
char item_name[64];
|
||||
uint32 item_cost;
|
||||
uint32 item_stat;
|
||||
uint32 SellerID;
|
||||
uint32 NumItems; // Don't know. Don't know the significance of this field.
|
||||
uint32 SerialNumber;
|
||||
uint32 Unknown016;
|
||||
uint32 Unknown020; // Something to do with stats as well
|
||||
char ItemName[64];
|
||||
uint32 Cost;
|
||||
uint32 ItemStat;
|
||||
};
|
||||
|
||||
struct ServerSideFilters_Struct {
|
||||
@@ -2460,18 +2454,11 @@ struct WhoAllReturnStruct {
|
||||
struct WhoAllPlayer player[0];
|
||||
};
|
||||
|
||||
struct BeginTrader_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown04;
|
||||
uint64 serial_number[80];
|
||||
uint32 cost[80];
|
||||
};
|
||||
|
||||
struct Trader_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown004;
|
||||
uint64 item_id[80];
|
||||
uint32 item_cost[80];
|
||||
uint32 code;
|
||||
uint32 itemid[160];
|
||||
uint32 unknown;
|
||||
uint32 itemcost[80];
|
||||
};
|
||||
|
||||
struct ClickTrader_Struct {
|
||||
@@ -2484,28 +2471,27 @@ struct GetItems_Struct{
|
||||
uint32 items[80];
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct {
|
||||
uint32 entity_id;
|
||||
uint32 action;
|
||||
char trader_name[64];
|
||||
struct BecomeTrader_Struct{
|
||||
uint32 ID;
|
||||
uint32 Code;
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct{
|
||||
uint32 action;
|
||||
uint32 entity_id;
|
||||
uint32 code;
|
||||
uint32 traderid;
|
||||
uint32 unknown08[3];
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 price;
|
||||
/*008*/ uint32 trader_id;
|
||||
/*012*/ char item_name[64];
|
||||
/*076*/ uint32 unknown_076;
|
||||
/*080*/ uint32 item_id;
|
||||
/*084*/ uint32 already_sold;
|
||||
/*088*/ uint32 quantity;
|
||||
/*092*/ uint32 unknown_092;
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Price;
|
||||
/*008*/ uint32 TraderID;
|
||||
/*012*/ char ItemName[64];
|
||||
/*076*/ uint32 Unknown076;
|
||||
/*080*/ uint32 ItemID;
|
||||
/*084*/ uint32 AlreadySold;
|
||||
/*088*/ uint32 Quantity;
|
||||
/*092*/ uint32 Unknown092;
|
||||
};
|
||||
|
||||
|
||||
@@ -2531,9 +2517,8 @@ struct TraderDelItem_Struct{
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
uint32 trader_id;
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 traderid;
|
||||
uint32 unknown4[2];
|
||||
uint32 approval;
|
||||
};
|
||||
|
||||
@@ -3759,21 +3744,6 @@ struct GuildMemberRank_Struct {
|
||||
/*076*/ uint32 alt_banker; //Banker/Alt bit 00 - none 10 - Alt 11 - Alt and Banker 01 - Banker. Banker not functional for RoF2+
|
||||
};
|
||||
|
||||
enum TiBazaarTraderBuyerActions {
|
||||
Zero = 0,
|
||||
BeginTraderMode = 1,
|
||||
EndTraderMode = 2,
|
||||
PriceUpdate = 3,
|
||||
EndTransaction = 4,
|
||||
BazaarSearch = 7,
|
||||
WelcomeMessage = 9,
|
||||
BuyTraderItem = 10,
|
||||
ListTraderItems = 11,
|
||||
BazaarInspect = 18,
|
||||
ItemMove = 19,
|
||||
ReconcileItems = 20
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
}; /*Titanium*/
|
||||
|
||||
+110
-454
@@ -37,8 +37,6 @@
|
||||
#include "../races.h"
|
||||
#include "../raid.h"
|
||||
#include "../guilds.h"
|
||||
//#include "../repositories/trader_repository.h"
|
||||
#include "../cereal/include/cereal/types/vector.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -309,134 +307,50 @@ namespace UF
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
uint32 action = *(uint32 *)in->pBuffer;
|
||||
char *Buffer = (char *)in->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case BazaarSearch: {
|
||||
LogTrading(
|
||||
"Encode OP_BazaarSearch(UF) BazaarSearch action <green>[{}]",
|
||||
action
|
||||
);
|
||||
std::vector<BazaarSearchResultsFromDB_Struct> results {};
|
||||
auto bsms = (BazaarSearchMessaging_Struct *)in->pBuffer;
|
||||
EQ::Util::MemoryStreamReader ss(
|
||||
reinterpret_cast<char *>(bsms->payload),
|
||||
in->size - sizeof(BazaarSearchMessaging_Struct)
|
||||
);
|
||||
cereal::BinaryInputArchive ar(ss);
|
||||
ar(results);
|
||||
uint8 SubAction = VARSTRUCT_DECODE_TYPE(uint8, Buffer);
|
||||
|
||||
auto size = results.size() * sizeof(BazaarSearchResults_Struct);
|
||||
auto buffer = new uchar[size];
|
||||
uchar *bufptr = buffer;
|
||||
memset(buffer, 0, size);
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, structs::UFBazaarTraderBuyerActions::BazaarSearch);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->trader_entity_id);
|
||||
strn0cpy(reinterpret_cast<char *>(bufptr), row->trader_name.c_str(), 64);
|
||||
bufptr += 64;
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, 1);
|
||||
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->item_id);
|
||||
VARSTRUCT_ENCODE_TYPE(int32, bufptr, row->serial_number);
|
||||
bufptr += 4;
|
||||
if (row->stackable) {
|
||||
strn0cpy(
|
||||
reinterpret_cast<char *>(bufptr),
|
||||
fmt::format("{}({})", row->item_name.c_str(), row->charges).c_str(),
|
||||
64
|
||||
);
|
||||
}
|
||||
else {
|
||||
strn0cpy(
|
||||
reinterpret_cast<char *>(bufptr),
|
||||
fmt::format("{}({})", row->item_name.c_str(), row->count).c_str(),
|
||||
64
|
||||
);
|
||||
}
|
||||
bufptr += 64;
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->cost);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, bufptr, row->item_stat);
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_BazaarSearch, size);
|
||||
memcpy(outapp->pBuffer, buffer, size);
|
||||
dest->FastQueuePacket(&outapp);
|
||||
|
||||
safe_delete(outapp);
|
||||
safe_delete_array(buffer);
|
||||
safe_delete(in);
|
||||
break;
|
||||
}
|
||||
case BazaarInspect:
|
||||
case WelcomeMessage: {
|
||||
LogTrading(
|
||||
"Encode OP_BazaarSearch(UF) BazaarInspect/WelcomeMessage action <green>[{}]",
|
||||
action
|
||||
);
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogTrading(
|
||||
"Encode OP_BazaarSearch(UF) unhandled action <red>[{}]",
|
||||
action
|
||||
);
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ENCODE(OP_BecomeTrader)
|
||||
{
|
||||
uint32 action = *(uint32 *)(*p)->pBuffer;
|
||||
|
||||
switch (action)
|
||||
if (SubAction != BazaarSearchResults)
|
||||
{
|
||||
case TraderOff:
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_BecomeTrader(UF) TraderOff action <green>[{}] entity_id <green>[{}] trader_name "
|
||||
"<green>[{}]",
|
||||
emu->action,
|
||||
emu->entity_id,
|
||||
emu->trader_name
|
||||
);
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::Zero;
|
||||
eq->entity_id = emu->entity_id;
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case TraderOn:
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(BecomeTrader_Struct);
|
||||
SETUP_DIRECT_ENCODE(BecomeTrader_Struct, structs::BecomeTrader_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_BecomeTrader(UF) TraderOn action <green>[{}] entity_id <green>[{}] trader_name "
|
||||
"<green>[{}]",
|
||||
emu->action,
|
||||
emu->entity_id,
|
||||
emu->trader_name
|
||||
);
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::BeginTraderMode;
|
||||
eq->entity_id = emu->entity_id;
|
||||
strn0cpy(eq->trader_name, emu->trader_name, sizeof(eq->trader_name));
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LogTrading(
|
||||
"Encode OP_BecomeTrader(UF) unhandled action <red>[{}] Sending packet as is.",
|
||||
action
|
||||
);
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
|
||||
BazaarSearchResults_Struct *emu = (BazaarSearchResults_Struct *)__emu_buffer;
|
||||
|
||||
int EntryCount = in->size / sizeof(BazaarSearchResults_Struct);
|
||||
|
||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||
{
|
||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
|
||||
in->size = EntryCount * sizeof(structs::BazaarSearchResults_Struct);
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
memset(in->pBuffer, 0, in->size);
|
||||
|
||||
structs::BazaarSearchResults_Struct *eq = (structs::BazaarSearchResults_Struct *)in->pBuffer;
|
||||
|
||||
for (int i = 0; i < EntryCount; ++i, ++emu, ++eq)
|
||||
{
|
||||
OUT(Beginning.Action);
|
||||
OUT(SellerID);
|
||||
memcpy(eq->SellerName, emu->SellerName, sizeof(eq->SellerName));
|
||||
OUT(NumItems);
|
||||
OUT(ItemID);
|
||||
OUT(SerialNumber);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(Cost);
|
||||
OUT(ItemStat);
|
||||
}
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_Buff)
|
||||
@@ -1268,37 +1182,53 @@ namespace UF
|
||||
|
||||
ENCODE(OP_GuildsList)
|
||||
{
|
||||
EQApplicationPacket* in = *p;
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
GuildsListMessaging_Struct glms{};
|
||||
EQ::Util::MemoryStreamReader ss(reinterpret_cast<char *>(in->pBuffer), in->size);
|
||||
cereal::BinaryInputArchive ar(ss);
|
||||
ar(glms);
|
||||
uint32 NumberOfGuilds = in->size / 64;
|
||||
uint32 PacketSize = 68; // 64 x 0x00 + a uint32 that I am guessing is the highest guild ID in use.
|
||||
|
||||
auto packet_size = 64 + 4 + glms.guild_detail.size() * 4 + glms.string_length;
|
||||
auto buffer = new uchar[packet_size];
|
||||
auto buf_pos = buffer;
|
||||
unsigned char *__emu_buffer = in->pBuffer;
|
||||
char *InBuffer = (char *)__emu_buffer;
|
||||
uint32 actual_no_guilds = 0;
|
||||
|
||||
memset(buf_pos, 0, 64);
|
||||
buf_pos += 64;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, buf_pos, glms.no_of_guilds);
|
||||
|
||||
for (auto const& g : glms.guild_detail) {
|
||||
if (g.guild_id < UF::constants::MAX_GUILD_ID) {
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, buf_pos, g.guild_id);
|
||||
strn0cpy((char *) buf_pos, g.guild_name.c_str(), g.guild_name.length() + 1);
|
||||
buf_pos += g.guild_name.length() + 1;
|
||||
for (unsigned int i = 0; i < NumberOfGuilds; ++i)
|
||||
{
|
||||
if (InBuffer[0])
|
||||
{
|
||||
PacketSize += (5 + strlen(InBuffer));
|
||||
actual_no_guilds++;
|
||||
}
|
||||
InBuffer += 64;
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_GuildsList);
|
||||
PacketSize++; // Appears to be an extra 0x00 at the very end.
|
||||
in->size = PacketSize;
|
||||
in->pBuffer = new unsigned char[in->size];
|
||||
InBuffer = (char *)__emu_buffer;
|
||||
char *OutBuffer = (char *)in->pBuffer;
|
||||
|
||||
outapp->size = packet_size;
|
||||
outapp->pBuffer = buffer;
|
||||
// Init the first 64 bytes to zero, as per live.
|
||||
//
|
||||
memset(OutBuffer, 0, 64);
|
||||
OutBuffer += 64;
|
||||
|
||||
dest->FastQueuePacket(&outapp);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, actual_no_guilds);
|
||||
|
||||
for (unsigned int i = 0; i < NumberOfGuilds; ++i)
|
||||
{
|
||||
if (InBuffer[0])
|
||||
{
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, i - 1);
|
||||
VARSTRUCT_ENCODE_STRING(OutBuffer, InBuffer);
|
||||
}
|
||||
InBuffer += 64;
|
||||
}
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, 0x00);
|
||||
|
||||
delete[] __emu_buffer;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
}
|
||||
|
||||
ENCODE(OP_GuildMemberAdd)
|
||||
@@ -2524,19 +2454,6 @@ namespace UF
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_ShopRequest)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(MerchantClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
OUT(npc_id);
|
||||
OUT(player_id);
|
||||
OUT(command);
|
||||
OUT(rate);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_SomeItemPacketMaybe)
|
||||
{
|
||||
// This Opcode is not named very well. It is used for the animation of arrows leaving the player's bow
|
||||
@@ -2829,170 +2746,32 @@ namespace UF
|
||||
|
||||
ENCODE(OP_Trader)
|
||||
{
|
||||
auto action = *(uint32 *) (*p)->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case TraderOn: {
|
||||
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader BeginTraderMode action <green>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::BeginTraderMode;
|
||||
OUT(entity_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case TraderOff: {
|
||||
ENCODE_LENGTH_EXACT(Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader EndTraderMode action <green>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::EndTraderMode;
|
||||
OUT(entity_id);
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case ListTraderItems: {
|
||||
ENCODE_LENGTH_EXACT(Trader_Struct);
|
||||
SETUP_DIRECT_ENCODE(Trader_Struct, structs::Trader_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader ListTraderItems action <green>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::ListTraderItems;
|
||||
std::copy_n(emu->items, UF::invtype::BAZAAR_SIZE, eq->item_id);
|
||||
std::copy_n(emu->item_cost, UF::invtype::BAZAAR_SIZE, eq->item_cost);
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case BuyTraderItem: {
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_Trader item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
eq->item_id,
|
||||
eq->price,
|
||||
eq->quantity,
|
||||
eq->trader_id
|
||||
);
|
||||
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::BuyTraderItem;
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
OUT(item_id);
|
||||
OUT(already_sold);
|
||||
OUT(quantity);
|
||||
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case ItemMove: {
|
||||
LogTrading(
|
||||
"Encode OP_Trader ItemMove action <green>[{}]",
|
||||
action
|
||||
);
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
LogError("Unknown Encode OP_Trader action <red>{} received. Unhandled.", action);
|
||||
}
|
||||
if ((*p)->size != sizeof(TraderBuy_Struct)) {
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
ENCODE_FORWARD(OP_TraderBuy);
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderBuy)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_TraderBuy item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
emu->item_id,
|
||||
emu->price,
|
||||
emu->quantity,
|
||||
emu->trader_id
|
||||
);
|
||||
|
||||
OUT(action);
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
OUT(item_id);
|
||||
OUT(already_sold);
|
||||
OUT(quantity);
|
||||
OUT_str(item_name);
|
||||
OUT(Action);
|
||||
OUT(Price);
|
||||
OUT(TraderID);
|
||||
memcpy(eq->ItemName, emu->ItemName, sizeof(eq->ItemName));
|
||||
OUT(ItemID);
|
||||
OUT(Quantity);
|
||||
OUT(AlreadySold);
|
||||
|
||||
FINISH_ENCODE();
|
||||
}
|
||||
|
||||
ENCODE(OP_TraderShop)
|
||||
{
|
||||
auto action = *(uint32 *)(*p)->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case ClickTrader: {
|
||||
ENCODE_LENGTH_EXACT(TraderClick_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
LogTrading(
|
||||
"ClickTrader action <green>[{}] trader_id <green>[{}]",
|
||||
action,
|
||||
emu->TraderID
|
||||
);
|
||||
|
||||
eq->action = 0;
|
||||
eq->trader_id = emu->TraderID;
|
||||
eq->approval = emu->Approval;
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
case BuyTraderItem: {
|
||||
ENCODE_LENGTH_EXACT(TraderBuy_Struct);
|
||||
SETUP_DIRECT_ENCODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Encode OP_TraderShop item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
eq->item_id,
|
||||
eq->price,
|
||||
eq->quantity,
|
||||
eq->trader_id
|
||||
);
|
||||
|
||||
eq->action = structs::UFBazaarTraderBuyerActions::BuyTraderItem;
|
||||
OUT(price);
|
||||
OUT(trader_id);
|
||||
OUT(item_id);
|
||||
OUT(already_sold);
|
||||
OUT(quantity);
|
||||
strn0cpy(eq->item_name, emu->item_name, sizeof(eq->item_name));
|
||||
|
||||
FINISH_ENCODE();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
EQApplicationPacket *in = *p;
|
||||
*p = nullptr;
|
||||
|
||||
dest->FastQueuePacket(&in, ack_req);
|
||||
LogError("Unknown Encode OP_TraderShop action <red>[{}] received. Unhandled.", action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ENCODE(OP_TributeItem)
|
||||
{
|
||||
ENCODE_LENGTH_EXACT(TributeItem_Struct);
|
||||
@@ -3264,7 +3043,7 @@ namespace UF
|
||||
Bitfields->targetable = 1;
|
||||
Bitfields->targetable_with_hotkey = emu->targetable_with_hotkey ? 1 : 0;
|
||||
Bitfields->statue = 0;
|
||||
Bitfields->trader = emu->trader ? 1 : 0;
|
||||
Bitfields->trader = 0;
|
||||
Bitfields->buyer = 0;
|
||||
|
||||
Bitfields->showname = ShowName;
|
||||
@@ -3587,49 +3366,20 @@ namespace UF
|
||||
|
||||
DECODE(OP_BazaarSearch)
|
||||
{
|
||||
uint32 action = *(uint32 *) __packet->pBuffer;
|
||||
char *Buffer = (char *)__packet->pBuffer;
|
||||
|
||||
switch (action) {
|
||||
case structs::UFBazaarTraderBuyerActions::BazaarSearch: {
|
||||
DECODE_LENGTH_EXACT(structs::BazaarSearch_Struct);
|
||||
SETUP_DIRECT_DECODE(BazaarSearchCriteria_Struct, structs::BazaarSearch_Struct);
|
||||
uint8 SubAction = VARSTRUCT_DECODE_TYPE(uint8, Buffer);
|
||||
|
||||
emu->action = eq->Beginning.Action;
|
||||
emu->item_stat = eq->ItemStat;
|
||||
emu->max_cost = eq->MaxPrice;
|
||||
emu->min_cost = eq->MinPrice;
|
||||
emu->max_level = eq->MaxLlevel;
|
||||
emu->min_level = eq->Minlevel;
|
||||
emu->race = eq->Race;
|
||||
emu->slot = eq->Slot;
|
||||
emu->type = eq->Type == UINT32_MAX ? UINT8_MAX : eq->Type;
|
||||
emu->trader_entity_id = eq->TraderID;
|
||||
emu->trader_id = 0;
|
||||
emu->_class = eq->Class_;
|
||||
emu->search_scope = eq->TraderID > 0 ? NonRoFBazaarSearchScope : Local_Scope;
|
||||
emu->max_results = RuleI(Bazaar, MaxSearchResults);
|
||||
strn0cpy(emu->item_name, eq->Name, sizeof(emu->item_name));
|
||||
if ((SubAction != BazaarInspectItem) || (__packet->size != sizeof(structs::NewBazaarInspect_Struct)))
|
||||
return;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::UFBazaarTraderBuyerActions::BazaarInspect: {
|
||||
SETUP_DIRECT_DECODE(BazaarInspect_Struct, structs::BazaarInspect_Struct);
|
||||
SETUP_DIRECT_DECODE(NewBazaarInspect_Struct, structs::NewBazaarInspect_Struct);
|
||||
MEMSET_IN(structs::NewBazaarInspect_Struct);
|
||||
IN(Beginning.Action);
|
||||
memcpy(emu->Name, eq->Name, sizeof(emu->Name));
|
||||
IN(SerialNumber);
|
||||
|
||||
IN(action);
|
||||
memcpy(emu->player_name, eq->player_name, sizeof(emu->player_name));
|
||||
IN(serial_number);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::UFBazaarTraderBuyerActions::WelcomeMessage: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogTrading("(UF) Unhandled action <red>[{}]", action);
|
||||
}
|
||||
}
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_BookButton)
|
||||
@@ -4297,112 +4047,18 @@ namespace UF
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_ShopRequest)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::MerchantClick_Struct);
|
||||
SETUP_DIRECT_DECODE(MerchantClick_Struct, structs::MerchantClick_Struct);
|
||||
|
||||
IN(npc_id);
|
||||
IN(player_id);
|
||||
IN(command);
|
||||
IN(rate);
|
||||
emu->tab_display = 0;
|
||||
emu->unknown020 = 0;
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_Trader)
|
||||
{
|
||||
auto action = (uint32) __packet->pBuffer[0];
|
||||
|
||||
switch (action) {
|
||||
case structs::UFBazaarTraderBuyerActions::BeginTraderMode: {
|
||||
DECODE_LENGTH_EXACT(structs::BeginTrader_Struct);
|
||||
SETUP_DIRECT_DECODE(ClickTrader_Struct, structs::BeginTrader_Struct);
|
||||
LogTrading(
|
||||
"Decode OP_Trader BeginTraderMode action <red>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
emu->action = TraderOn;
|
||||
emu->unknown_004 = 0;
|
||||
std::copy_n(eq->serial_number, UF::invtype::BAZAAR_SIZE, emu->serial_number);
|
||||
std::copy_n(eq->cost, UF::invtype::BAZAAR_SIZE, emu->item_cost);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::UFBazaarTraderBuyerActions::EndTraderMode: {
|
||||
DECODE_LENGTH_EXACT(structs::Trader_ShowItems_Struct);
|
||||
SETUP_DIRECT_DECODE(Trader_ShowItems_Struct, structs::Trader_ShowItems_Struct);
|
||||
LogTrading(
|
||||
"Decode OP_Trader(UF) EndTraderMode action <red>[{}]",
|
||||
action
|
||||
);
|
||||
|
||||
emu->action = TraderOff;
|
||||
IN(entity_id);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
break;
|
||||
}
|
||||
case structs::UFBazaarTraderBuyerActions::PriceUpdate:
|
||||
case structs::UFBazaarTraderBuyerActions::ItemMove:
|
||||
case structs::UFBazaarTraderBuyerActions::EndTransaction:
|
||||
case structs::UFBazaarTraderBuyerActions::ListTraderItems: {
|
||||
LogTrading(
|
||||
"Decode OP_Trader(UF) Price/ItemMove/EndTransaction/ListTraderItems action <red>[{}]",
|
||||
action
|
||||
);
|
||||
break;
|
||||
}
|
||||
case structs::UFBazaarTraderBuyerActions::ReconcileItems: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogError("Unhandled(UF) action <red>[{}] received.", action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DECODE(OP_TraderBuy)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderBuy_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderBuy_Struct, structs::TraderBuy_Struct);
|
||||
LogTrading(
|
||||
"Decode OP_TraderBuy(UF) item_id <green>[{}] price <green>[{}] quantity <green>[{}] trader_id <green>[{}]",
|
||||
eq->item_id,
|
||||
eq->price,
|
||||
eq->quantity,
|
||||
eq->trader_id
|
||||
);
|
||||
MEMSET_IN(TraderBuy_Struct);
|
||||
|
||||
emu->action = BuyTraderItem;
|
||||
IN(price);
|
||||
IN(trader_id);
|
||||
IN(item_id);
|
||||
IN(quantity);
|
||||
IN(already_sold);
|
||||
strn0cpy(emu->item_name, eq->item_name, sizeof(eq->item_name));
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
DECODE(OP_TraderShop)
|
||||
{
|
||||
DECODE_LENGTH_EXACT(structs::TraderClick_Struct);
|
||||
SETUP_DIRECT_DECODE(TraderClick_Struct, structs::TraderClick_Struct);
|
||||
LogTrading(
|
||||
"(UF) action <green>[{}] trader_id <green>[{}] approval <green>[{}]",
|
||||
eq->action,
|
||||
eq->trader_id,
|
||||
eq->approval
|
||||
);
|
||||
|
||||
emu->Code = ClickTrader;
|
||||
emu->TraderID = eq->trader_id;
|
||||
emu->Approval = eq->approval;
|
||||
IN(Action);
|
||||
IN(Price);
|
||||
IN(TraderID);
|
||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||
IN(ItemID);
|
||||
IN(Quantity);
|
||||
|
||||
FINISH_DIRECT_DECODE();
|
||||
}
|
||||
|
||||
@@ -289,7 +289,6 @@ namespace UF
|
||||
const size_t CHARACTER_CREATION_LIMIT = 12;
|
||||
|
||||
const size_t SAY_LINK_BODY_SIZE = 50;
|
||||
const uint32 MAX_GUILD_ID = 50000;
|
||||
|
||||
} /*constants*/
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ E(OP_ApplyPoison)
|
||||
E(OP_AugmentInfo)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_CancelTrade)
|
||||
@@ -90,7 +89,6 @@ E(OP_SendZonepoints)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
@@ -101,7 +99,6 @@ E(OP_TaskDescription)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TraderShop)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
@@ -161,10 +158,7 @@ D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TraderShop)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
|
||||
+42
-78
@@ -1916,9 +1916,9 @@ struct TimeOfDay_Struct {
|
||||
};
|
||||
|
||||
// Darvik: shopkeeper structs
|
||||
struct MerchantClick_Struct {
|
||||
/*000*/ uint32 npc_id; // Merchant NPC's entity id
|
||||
/*004*/ uint32 player_id;
|
||||
struct Merchant_Click_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ uint32 playerid;
|
||||
/*008*/ uint32 command; //1=open, 0=cancel/close
|
||||
/*012*/ float rate; //cost multiplier, dosent work anymore
|
||||
};
|
||||
@@ -2640,23 +2640,23 @@ struct EnvDamage2_Struct {
|
||||
//Bazaar Stuff
|
||||
|
||||
enum {
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_StartTraderMode = 1,
|
||||
BazaarTrader_EndTraderMode = 2,
|
||||
BazaarTrader_UpdatePrice = 3,
|
||||
BazaarTrader_EndTransaction = 4,
|
||||
BazaarSearchResults = 7,
|
||||
BazaarWelcome = 9,
|
||||
BazaarBuyItem = 10,
|
||||
BazaarTrader_ShowItems = 11,
|
||||
BazaarSearchDone = 12,
|
||||
BazaarTrader_CustomerBrowsing = 13
|
||||
};
|
||||
|
||||
enum {
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_Fail = 0,
|
||||
BazaarPriceChange_UpdatePrice = 1,
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
BazaarPriceChange_RemoveItem = 2,
|
||||
BazaarPriceChange_AddItem = 3
|
||||
};
|
||||
|
||||
struct BazaarWindowStart_Struct {
|
||||
@@ -2687,14 +2687,10 @@ struct BazaarSearch_Struct {
|
||||
uint32 Minlevel;
|
||||
uint32 MaxLlevel;
|
||||
};
|
||||
|
||||
struct BazaarInspect_Struct {
|
||||
uint32 action;
|
||||
char player_name[64];
|
||||
uint32 unknown_068;
|
||||
uint32 serial_number;
|
||||
uint32 unknown_076;
|
||||
uint32 item_id;
|
||||
struct BazaarInspect_Struct{
|
||||
uint32 ItemID;
|
||||
uint32 Unknown004;
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
struct NewBazaarInspect_Struct {
|
||||
@@ -2933,17 +2929,10 @@ struct WhoAllPlayerPart4 {
|
||||
};
|
||||
|
||||
struct Trader_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown004;
|
||||
uint64 item_id[80];
|
||||
uint32 item_cost[80];
|
||||
};
|
||||
|
||||
struct BeginTrader_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown04;
|
||||
uint64 serial_number[80];
|
||||
uint32 cost[80];
|
||||
uint32 code;
|
||||
uint32 itemid[160];
|
||||
uint32 unknown;
|
||||
uint32 itemcost[80];
|
||||
};
|
||||
|
||||
struct ClickTrader_Struct {
|
||||
@@ -2956,30 +2945,30 @@ struct GetItems_Struct{
|
||||
uint32 items[80];
|
||||
};
|
||||
|
||||
struct BecomeTrader_Struct {
|
||||
uint32 entity_id;
|
||||
uint32 action;
|
||||
char trader_name[64];
|
||||
struct BecomeTrader_Struct{
|
||||
uint32 id;
|
||||
uint32 code;
|
||||
};
|
||||
|
||||
struct Trader_ShowItems_Struct{
|
||||
uint32 action;
|
||||
uint32 entity_id;
|
||||
uint32 code;
|
||||
uint32 traderid;
|
||||
uint32 unknown08[3];
|
||||
};
|
||||
|
||||
struct TraderBuy_Struct {
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 price;
|
||||
uint32 unknown_008; // Probably high order bits of a 64 bit price.
|
||||
uint32 trader_id;
|
||||
char item_name[64];
|
||||
uint32 unknown_076;
|
||||
uint32 item_id;
|
||||
uint32 already_sold;
|
||||
uint32 quantity;
|
||||
uint32 unknown_092;
|
||||
/*000*/ uint32 Action;
|
||||
/*004*/ uint32 Unknown004;
|
||||
/*008*/ uint32 Price;
|
||||
/*012*/ uint32 Unknown008; // Probably high order bits of a 64 bit price.
|
||||
/*016*/ uint32 TraderID;
|
||||
/*020*/ char ItemName[64];
|
||||
/*084*/ uint32 Unknown076;
|
||||
/*088*/ uint32 ItemID;
|
||||
/*092*/ uint32 AlreadySold;
|
||||
/*096*/ uint32 Quantity;
|
||||
/*100*/ uint32 Unknown092;
|
||||
/*104*/
|
||||
};
|
||||
|
||||
struct TraderItemUpdate_Struct{
|
||||
@@ -3013,9 +3002,8 @@ struct TraderDelItem_Struct{
|
||||
};
|
||||
|
||||
struct TraderClick_Struct{
|
||||
uint32 trader_id;
|
||||
uint32 action;
|
||||
uint32 unknown_004;
|
||||
uint32 traderid;
|
||||
uint32 unknown4[2];
|
||||
uint32 approval;
|
||||
};
|
||||
|
||||
@@ -4686,30 +4674,6 @@ struct SayLinkBodyFrame_Struct {
|
||||
/*050*/
|
||||
};
|
||||
|
||||
struct TraderPriceUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ uint32 sub_action;
|
||||
/*008*/ int32 serial_number;
|
||||
/*012*/ uint32 unknown_012;
|
||||
/*016*/ uint32 new_price;
|
||||
/*020*/ uint32 unknown_016;
|
||||
};
|
||||
|
||||
enum UFBazaarTraderBuyerActions {
|
||||
Zero = 0,
|
||||
BeginTraderMode = 1,
|
||||
EndTraderMode = 2,
|
||||
PriceUpdate = 3,
|
||||
EndTransaction = 4,
|
||||
BazaarSearch = 7,
|
||||
WelcomeMessage = 9,
|
||||
BuyTraderItem = 10,
|
||||
ListTraderItems = 11,
|
||||
BazaarInspect = 18,
|
||||
ItemMove = 19,
|
||||
ReconcileItems = 20
|
||||
};
|
||||
|
||||
}; /*structs*/
|
||||
|
||||
}; /*UF*/
|
||||
|
||||
@@ -74,11 +74,6 @@ void PathManager::LoadPaths()
|
||||
m_patch_path = fs::relative(fs::path{m_server_path + "/" + c->PatchDir}).string();
|
||||
}
|
||||
|
||||
// patches
|
||||
if (File::Exists(fs::path{ m_server_path + "/" + c->OpcodeDir }.string())) {
|
||||
m_opcode_path = fs::relative(fs::path{ m_server_path + "/" + c->OpcodeDir }).string();
|
||||
}
|
||||
|
||||
// shared_memory_path
|
||||
if (File::Exists(fs::path{m_server_path + "/" + c->SharedMemDir}.string())) {
|
||||
m_shared_memory_path = fs::relative(fs::path{ m_server_path + "/" + c->SharedMemDir }).string();
|
||||
@@ -94,7 +89,6 @@ void PathManager::LoadPaths()
|
||||
LogInfo("lua_modules path [{}]", m_lua_modules_path);
|
||||
LogInfo("maps path [{}]", m_maps_path);
|
||||
LogInfo("patches path [{}]", m_patch_path);
|
||||
LogInfo("opcode path [{}]", m_opcode_path);
|
||||
LogInfo("plugins path [{}]", m_plugins_path);
|
||||
LogInfo("quests path [{}]", m_quests_path);
|
||||
LogInfo("shared_memory path [{}]", m_shared_memory_path);
|
||||
@@ -135,11 +129,6 @@ const std::string &PathManager::GetPatchPath() const
|
||||
return m_patch_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetOpcodePath() const
|
||||
{
|
||||
return m_opcode_path;
|
||||
}
|
||||
|
||||
const std::string &PathManager::GetLuaModulesPath() const
|
||||
{
|
||||
return m_lua_modules_path;
|
||||
|
||||
@@ -13,7 +13,6 @@ public:
|
||||
[[nodiscard]] const std::string &GetLuaModulesPath() const;
|
||||
[[nodiscard]] const std::string &GetMapsPath() const;
|
||||
[[nodiscard]] const std::string &GetPatchPath() const;
|
||||
[[nodiscard]] const std::string &GetOpcodePath() const;
|
||||
[[nodiscard]] const std::string &GetPluginsPath() const;
|
||||
[[nodiscard]] const std::string &GetQuestsPath() const;
|
||||
[[nodiscard]] const std::string &GetServerPath() const;
|
||||
@@ -25,7 +24,6 @@ private:
|
||||
std::string m_lua_modules_path;
|
||||
std::string m_maps_path;
|
||||
std::string m_patch_path;
|
||||
std::string m_opcode_path;
|
||||
std::string m_plugins_path;
|
||||
std::string m_quests_path;
|
||||
std::string m_server_path;
|
||||
|
||||
+1
-1
@@ -1379,7 +1379,7 @@ uint32 GetPlayerRaceValue(uint16 race_id) {
|
||||
}
|
||||
}
|
||||
|
||||
uint16 GetPlayerRaceBit(uint16 race_id) {
|
||||
uint32 GetPlayerRaceBit(uint16 race_id) {
|
||||
switch (race_id) {
|
||||
case HUMAN:
|
||||
return PLAYER_RACE_HUMAN_BIT;
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ bool IsPlayerRace(uint16 race_id);
|
||||
const std::string GetPlayerRaceAbbreviation(uint16 race_id);
|
||||
|
||||
uint32 GetPlayerRaceValue(uint16 race_id);
|
||||
uint16 GetPlayerRaceBit(uint16 race_id);
|
||||
uint32 GetPlayerRaceBit(uint16 race_id);
|
||||
|
||||
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
|
||||
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
|
||||
|
||||
@@ -44,69 +44,7 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static int16 GetAccountStatus(Database& db, const uint32 account_id)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `{}` WHERE `{}` = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
account_id
|
||||
)
|
||||
);
|
||||
|
||||
if (!results.Success() || !results.RowCount()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
int16 status = static_cast<int16>(Strings::ToInt(row[0]));
|
||||
int date_diff = 0;
|
||||
|
||||
if (row[1]) {
|
||||
date_diff = Strings::ToInt(row[1]);
|
||||
}
|
||||
|
||||
if (date_diff > 0) {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool UpdatePassword(Database& db, const uint32 account_id, const std::string& password)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `{}` SET `password` = MD5('{}') WHERE `{}` = {}",
|
||||
TableName(),
|
||||
password,
|
||||
PrimaryKey(),
|
||||
account_id
|
||||
)
|
||||
);
|
||||
|
||||
return results.Success();
|
||||
}
|
||||
|
||||
static std::string GetAutoLoginCharacterNameByAccountID(Database& db, const uint32 account_id)
|
||||
{
|
||||
return AccountRepository::FindOne(db, account_id).auto_login_charname;
|
||||
}
|
||||
|
||||
static bool SetAutoLoginCharacterNameByAccountID(Database& db, const uint32 account_id, const std::string& character_name)
|
||||
{
|
||||
auto e = AccountRepository::FindOne(db, account_id);
|
||||
|
||||
if (!e.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
e.auto_login_charname = character_name;
|
||||
|
||||
return AccountRepository::UpdateOne(db, e);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_ACCOUNT_REPOSITORY_H
|
||||
|
||||
@@ -44,65 +44,7 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
static void UpdateAdventureStatsEntry(Database& db, uint32 character_id, uint8 theme_id, bool is_win, bool is_remove)
|
||||
{
|
||||
std::string field;
|
||||
|
||||
switch (theme_id) {
|
||||
case LDoNThemes::GUK: {
|
||||
field = "guk_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::MIR: {
|
||||
field = "mir_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::MMC: {
|
||||
field = "mmc_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::RUJ: {
|
||||
field = "ruj_";
|
||||
break;
|
||||
}
|
||||
case LDoNThemes::TAK: {
|
||||
field = "tak_";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
field += is_win ? "wins" : "losses";
|
||||
|
||||
auto e = FindOne(db, character_id);
|
||||
|
||||
if (!e.player_id && !is_remove) {
|
||||
const std::string& query = fmt::format(
|
||||
"INSERT INTO `{}` SET `{}` = 1, `{}` = {}",
|
||||
TableName(),
|
||||
field,
|
||||
PrimaryKey(),
|
||||
character_id
|
||||
);
|
||||
|
||||
db.QueryDatabase(query);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& field_operation = is_remove ? "-" : "+";
|
||||
|
||||
const std::string& query = fmt::format(
|
||||
"UPDATE `{}` SET `{}` = {} {} 1 WHERE `{}` = {}",
|
||||
TableName(),
|
||||
field,
|
||||
field,
|
||||
field_operation,
|
||||
PrimaryKey(),
|
||||
character_id
|
||||
);
|
||||
|
||||
db.QueryDatabase(query);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //EQEMU_ADVENTURE_STATS_REPOSITORY_H
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
int32_t accid;
|
||||
std::string ip;
|
||||
int32_t count;
|
||||
time_t lastused;
|
||||
std::string lastused;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
"accid",
|
||||
"ip",
|
||||
"count",
|
||||
"UNIX_TIMESTAMP(lastused)",
|
||||
"lastused",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.ip = row[1] ? row[1] : "";
|
||||
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
|
||||
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
|
||||
e.lastused = row[3] ? row[3] : std::time(nullptr);
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.accid));
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.count));
|
||||
v.push_back(columns[3] + " = FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.lastused) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -192,7 +192,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -225,7 +225,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public:
|
||||
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.ip = row[1] ? row[1] : "";
|
||||
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
|
||||
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
|
||||
e.lastused = row[3] ? row[3] : std::time(nullptr);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -290,7 +290,7 @@ public:
|
||||
e.accid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
|
||||
e.ip = row[1] ? row[1] : "";
|
||||
e.count = row[2] ? static_cast<int32_t>(atoi(row[2])) : 1;
|
||||
e.lastused = strtoll(row[3] ? row[3] : "-1", nullptr, 10);
|
||||
e.lastused = row[3] ? row[3] : std::time(nullptr);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -368,7 +368,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -394,7 +394,7 @@ public:
|
||||
v.push_back(std::to_string(e.accid));
|
||||
v.push_back("'" + Strings::Escape(e.ip) + "'");
|
||||
v.push_back(std::to_string(e.count));
|
||||
v.push_back("FROM_UNIXTIME(" + (e.lastused > 0 ? std::to_string(e.lastused) : "null") + ")");
|
||||
v.push_back("'" + Strings::Escape(e.lastused) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user