Compare commits

..

2 Commits

Author SHA1 Message Date
Trust 2434bab697 Updated for bypass all rule 2024-02-25 16:00:44 -05:00
Trust 7a5a755033 [Bug Fix] Cleanup NPC Mana Tap Logic
Mana Tap rule logic was invalid - Cleaned up and simplified, either we care about npc mana or we dont.
2024-02-25 15:20:58 -05:00
405 changed files with 14998 additions and 36126 deletions
-6
View File
@@ -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
-9
View File
@@ -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
-284
View File
@@ -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
-73
View File
@@ -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/"
}
}
}
-37
View File
@@ -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"
}
}
-49
View File
@@ -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"
}
+3
View File
@@ -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
-23
View File
@@ -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
}
-173
View File
@@ -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
}
]
}
]
}
-136
View File
@@ -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
View File
@@ -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
-7
View File
@@ -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
View File
@@ -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);
}
+3 -5
View File
@@ -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);
+10 -23
View File
@@ -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
@@ -159,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
@@ -181,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
@@ -341,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
@@ -364,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
@@ -502,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
@@ -587,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
@@ -604,7 +592,7 @@ SET(common_headers
ptimer.h
queue.h
races.h
raid.h
raid.h
random.h
rdtsc.h
rulesys.h
@@ -618,7 +606,6 @@ SET(common_headers
shared_tasks.h
shareddb.h
skills.h
skill_caps.h
spdat.h
strings.h
struct_strategy.h
@@ -694,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
@@ -737,7 +724,7 @@ 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
@@ -781,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
@@ -794,7 +781,7 @@ SOURCE_GROUP(Util FILES
util/directory.h
util/uuid.cpp
util/uuid.h
)
)
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
@@ -807,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)
-368
View File
@@ -1,368 +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,
int32 char_zone_instance_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 [{}], char_zone_instance_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,
char_zone_instance_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 = {} AND trader.char_zone_instance_id = {}",
search.trader_entity_id,
Zones::BAZAAR,
char_zone_instance_id
)
);
}
else if (search.search_scope == Local_Scope) {
search_criteria_trader.append(fmt::format(
" AND trader.char_zone_id = {} AND trader.char_zone_instance_id = {}",
char_zone_id,
char_zone_instance_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, trader.char_zone_instance_id "
"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_zone_instance_id = Strings::ToInt(row[17]);
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;
}
-14
View File
@@ -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, int char_zone_instance_id);
};
#endif //EQEMU_BAZAAR_H
-12
View File
@@ -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
View File
@@ -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
+60 -91
View File
@@ -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);
}
+2 -14
View File
@@ -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
View File
@@ -15,7 +15,7 @@
#include <cstdio>
#include <vector>
#ifdef _WINDOWS
#if WINDOWS
#define popen _popen
#endif
+1282 -1127
View File
File diff suppressed because it is too large Load Diff
+139 -151
View File
@@ -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();
+1 -6
View File
@@ -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();
+1 -373
View File
@@ -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,378 +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);
)"
},
ManifestEntry{
.version = 9286,
.description = "2024_11_26_bazaar_find_trader.sql",
.check = "SHOW COLUMNS FROM `trader` LIKE 'char_zone_instance_id'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `trader`
ADD COLUMN `char_zone_instance_id` INT NULL DEFAULT '0' AFTER `char_zone_id`;
)"
}
// -- 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
+5 -10
View File
@@ -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) {
+1 -9
View File
@@ -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",
-6
View File
@@ -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);
}
-7
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+355 -94
View File
@@ -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()
@@ -140,6 +203,29 @@ std::string EQ::constants::GetLanguageName(uint8 language_id)
return EQ::constants::GetLanguageMap().find(language_id)->second;
}
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
{
static const std::map<uint32, std::string> ldon_theme_map = {
{ LDoNThemes::Unused, "Unused" },
{ LDoNThemes::GUK, "Deepest Guk" },
{ LDoNThemes::MIR, "Miragul's Menagerie" },
{ LDoNThemes::MMC, "Mistmoore Catacombs" },
{ LDoNThemes::RUJ, "Rujarkian Hills" },
{ LDoNThemes::TAK, "Takish-Hiz" },
};
return ldon_theme_map;
}
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
{
if (!EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
return std::string();
}
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
}
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
{
static const std::map<int8, std::string> flymode_map = {
@@ -163,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 = {
@@ -253,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 = {
@@ -380,74 +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();
}
uint32 LDoNTheme::GetBitmask(uint32 theme_id)
{
return IsValid(theme_id) ? ldon_theme_names[theme_id].second : LDoNTheme::UnusedBit;
}
std::string LDoNTheme::GetName(uint32 theme_id)
{
return IsValid(theme_id) ? ldon_theme_names[theme_id].first : "UNKNOWN LDON THEME";
}
bool LDoNTheme::IsValid(uint32 theme_id)
{
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
return std::string();
}
+221 -325
View File
@@ -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,12 +356,24 @@ 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);
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
std::string GetLDoNThemeName(uint32 theme_id);
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);
@@ -367,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);
@@ -379,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*/
@@ -435,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,
@@ -448,7 +505,7 @@ namespace EQ
Raid,
Guild
};
};
}; // namespace consent
} /*EQEmu*/
enum ServerLockType : int {
@@ -457,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,
@@ -482,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,
@@ -508,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,
@@ -521,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";
@@ -671,121 +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 LDoNTheme {
constexpr uint32 Unused = 0;
constexpr uint32 GUK = 1;
constexpr uint32 MIR = 2;
constexpr uint32 MMC = 3;
constexpr uint32 RUJ = 4;
constexpr uint32 TAK = 5;
constexpr uint32 UnusedBit = 0;
constexpr uint32 GUKBit = 1;
constexpr uint32 MIRBit = 2;
constexpr uint32 MMCBit = 4;
constexpr uint32 RUJBit = 8;
constexpr uint32 TAKBit = 16;
uint32 GetBitmask(uint32 theme_id);
std::string GetName(uint32 theme_id);
bool IsValid(uint32 theme_id);
}
static std::map<uint32, std::pair<std::string, uint32>> ldon_theme_names = {
{ LDoNTheme::Unused, { "Unused", LDoNTheme::UnusedBit }, },
{ LDoNTheme::GUK, { "Deepest Guk", LDoNTheme::GUKBit }, },
{ LDoNTheme::MIR, { "Miragul's Menagerie", LDoNTheme::MIRBit }, },
{ LDoNTheme::MMC, { "Mistmoore Catacombs", LDoNTheme::MMCBit }, },
{ LDoNTheme::RUJ, { "Rujarkian Hills", LDoNTheme::RUJBit }, },
{ LDoNTheme::TAK, { "Takish-Hiz", LDoNTheme::TAKBit }, },
};
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*/
-8
View File
@@ -67,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),
@@ -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),
+83 -66
View File
@@ -758,10 +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
FilterUnknown25 = 25,
FilterUnknown26 = 26,
FilterUnknown27 = 27,
FilterUnknown28 = 28,
_FilterCount
} eqFilterType;
@@ -772,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;
@@ -993,6 +1013,24 @@ enum class DynamicZoneMemberStatus : uint8_t
LinkDead
};
enum LDoNThemes {
Unused = 0,
GUK,
MIR,
MMC,
RUJ,
TAK
};
enum LDoNThemeBits {
UnusedBit = 0,
GUKBit = 1,
MIRBit = 2,
MMCBit = 4,
RUJBit = 8,
TAKBit = 16
};
enum StartZoneIndex {
Odus = 0,
Qeynos,
@@ -1093,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*/
+156 -720
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -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();
-1
View File
@@ -95,7 +95,6 @@ class EQEmuConfig
std::string PluginDir;
std::string LuaModuleDir;
std::string PatchDir;
std::string OpcodeDir;
std::string SharedMemDir;
std::string LogDir;
-2
View File
@@ -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"
};
}
-10
View File
@@ -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 = {};
+49 -57
View File
@@ -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;
+7 -146
View File
@@ -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
View File
@@ -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
View File
@@ -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_*/
+3 -68
View File
@@ -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;
}
+1 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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:
//////////////////////////
-600
View File
@@ -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
-221
View File
@@ -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
+3 -10
View File
@@ -4,7 +4,6 @@
#include "../eqemu_logsys.h"
#include "../servertalk.h"
#include "../rulesys.h"
#include "../event/timer.h"
#include <fmt/format.h>
EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent, std::shared_ptr<TCPConnection> connection)
@@ -22,11 +21,7 @@ EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent,
m_connection->OnDisconnect(std::bind(&ConsoleServerConnection::OnDisconnect, this, std::placeholders::_1));
m_connection->Start();
ClearBuffer();
m_keepalive = std::make_unique<EQ::Timer>(1000, true, [this](EQ::Timer *t) {
m_connection->Write("", 0);
});
auto addr = m_connection->RemoteIP();
SendLine(fmt::format("Establishing connection from: {0}:{1}", addr, m_connection->RemotePort()));
@@ -90,12 +85,12 @@ void EQ::Net::ConsoleServerConnection::QueueMessage(const std::string &msg)
}
else {
std::string cmd(m_line, m_line + m_cursor);
size_t len = m_user.length() + 2 + cmd.length();
for (size_t i = 0; i < len; ++i) {
Send("\x08");
}
if (msg.length() < cmd.length()) {
Send(msg);
size_t blank_spaces = 2 + cmd.length() - msg.length();
@@ -232,8 +227,6 @@ void EQ::Net::ConsoleServerConnection::OnRead(TCPConnection *c, const unsigned c
void EQ::Net::ConsoleServerConnection::OnDisconnect(TCPConnection *c)
{
LogInfo("Console connection disconnected");
m_parent->ConnectionDisconnected(this);
}
-2
View File
@@ -1,7 +1,6 @@
#pragma once
#include "tcp_server.h"
#include "../event/timer.h"
#include <memory>
#include <map>
@@ -59,7 +58,6 @@ namespace EQ
int m_user_id;
int m_admin;
bool m_accept_messages;
std::unique_ptr<EQ::Timer> m_keepalive;
size_t m_cursor;
char m_line[MaxConsoleLineLength];
+54 -24
View File
@@ -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();
}
+371 -1216
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -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*/
+2 -5
View File
@@ -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)
@@ -118,6 +116,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)
@@ -150,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)
@@ -203,7 +200,7 @@ D(OP_Save)
D(OP_SetServerFilter)
D(OP_ShopPlayerBuy)
D(OP_ShopPlayerSell)
D(OP_ShopSendParcel)
D(OP_ShopRequest)
D(OP_Trader)
D(OP_TraderBuy)
D(OP_TradeSkillCombine)
+148 -313
View File
@@ -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,164 +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,
FirstOpenSearch = 26
};
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 {
@@ -3272,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 {
@@ -3337,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 {
@@ -3556,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*/
};
@@ -3584,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{
@@ -3653,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*/
};
@@ -4725,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 {
@@ -5414,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*/
+2
View File
@@ -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)
+19 -21
View File
@@ -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
View File
@@ -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();
}
-2
View File
@@ -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)
+16 -21
View File
@@ -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
View File
@@ -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();
}
-2
View File
@@ -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)
+16 -20
View File
@@ -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{
+3 -3
View File
@@ -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
View File
@@ -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();
}
-1
View File
@@ -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*/
-7
View File
@@ -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)
+46 -76
View File
@@ -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
View File
@@ -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();
}
-1
View File
@@ -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*/
-6
View File
@@ -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
View File
@@ -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*/
-11
View File
@@ -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;
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
-62
View File
@@ -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 LDoNTheme::GUK: {
field = "guk_";
break;
}
case LDoNTheme::MIR: {
field = "mir_";
break;
}
case LDoNTheme::MMC: {
field = "mmc_";
break;
}
case LDoNTheme::RUJ: {
field = "ruj_";
break;
}
case LDoNTheme::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) + ")");
}
+117 -129
View File
@@ -22,7 +22,6 @@ public:
int32_t id;
std::string name;
std::string charname;
std::string auto_login_charname;
uint32_t sharedplat;
std::string password;
int32_t status;
@@ -57,7 +56,6 @@ public:
"id",
"name",
"charname",
"auto_login_charname",
"sharedplat",
"password",
"status",
@@ -88,7 +86,6 @@ public:
"id",
"name",
"charname",
"auto_login_charname",
"sharedplat",
"password",
"status",
@@ -150,31 +147,30 @@ public:
{
Account e{};
e.id = 0;
e.name = "";
e.charname = "";
e.auto_login_charname = "";
e.sharedplat = 0;
e.password = "";
e.status = 0;
e.ls_id = "eqemu";
e.lsaccount_id = 0;
e.gmspeed = 0;
e.invulnerable = 0;
e.flymode = 0;
e.ignore_tells = 0;
e.revoked = 0;
e.karma = 0;
e.minilogin_ip = "";
e.hideme = 0;
e.rulesflag = 0;
e.suspendeduntil = 0;
e.time_creation = 0;
e.ban_reason = "";
e.suspend_reason = "";
e.crc_eqgame = "";
e.crc_skillcaps = "";
e.crc_basedata = "";
e.id = 0;
e.name = "";
e.charname = "";
e.sharedplat = 0;
e.password = "";
e.status = 0;
e.ls_id = "eqemu";
e.lsaccount_id = 0;
e.gmspeed = 0;
e.invulnerable = 0;
e.flymode = 0;
e.ignore_tells = 0;
e.revoked = 0;
e.karma = 0;
e.minilogin_ip = "";
e.hideme = 0;
e.rulesflag = 0;
e.suspendeduntil = 0;
e.time_creation = 0;
e.ban_reason = "";
e.suspend_reason = "";
e.crc_eqgame = "";
e.crc_skillcaps = "";
e.crc_basedata = "";
return e;
}
@@ -211,31 +207,30 @@ public:
if (results.RowCount() == 1) {
Account e{};
e.id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.name = row[1] ? row[1] : "";
e.charname = row[2] ? row[2] : "";
e.auto_login_charname = row[3] ? row[3] : "";
e.sharedplat = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.password = row[5] ? row[5] : "";
e.status = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.ls_id = row[7] ? row[7] : "eqemu";
e.lsaccount_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.gmspeed = row[9] ? static_cast<uint8_t>(strtoul(row[9], nullptr, 10)) : 0;
e.invulnerable = row[10] ? static_cast<int8_t>(atoi(row[10])) : 0;
e.flymode = row[11] ? static_cast<int8_t>(atoi(row[11])) : 0;
e.ignore_tells = row[12] ? static_cast<int8_t>(atoi(row[12])) : 0;
e.revoked = row[13] ? static_cast<uint8_t>(strtoul(row[13], nullptr, 10)) : 0;
e.karma = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.minilogin_ip = row[15] ? row[15] : "";
e.hideme = row[16] ? static_cast<int8_t>(atoi(row[16])) : 0;
e.rulesflag = row[17] ? static_cast<uint8_t>(strtoul(row[17], nullptr, 10)) : 0;
e.suspendeduntil = strtoll(row[18] ? row[18] : "-1", nullptr, 10);
e.time_creation = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.ban_reason = row[20] ? row[20] : "";
e.suspend_reason = row[21] ? row[21] : "";
e.crc_eqgame = row[22] ? row[22] : "";
e.crc_skillcaps = row[23] ? row[23] : "";
e.crc_basedata = row[24] ? row[24] : "";
e.id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.name = row[1] ? row[1] : "";
e.charname = row[2] ? row[2] : "";
e.sharedplat = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.password = row[4] ? row[4] : "";
e.status = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.ls_id = row[6] ? row[6] : "eqemu";
e.lsaccount_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.gmspeed = row[8] ? static_cast<uint8_t>(strtoul(row[8], nullptr, 10)) : 0;
e.invulnerable = row[9] ? static_cast<int8_t>(atoi(row[9])) : 0;
e.flymode = row[10] ? static_cast<int8_t>(atoi(row[10])) : 0;
e.ignore_tells = row[11] ? static_cast<int8_t>(atoi(row[11])) : 0;
e.revoked = row[12] ? static_cast<uint8_t>(strtoul(row[12], nullptr, 10)) : 0;
e.karma = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.minilogin_ip = row[14] ? row[14] : "";
e.hideme = row[15] ? static_cast<int8_t>(atoi(row[15])) : 0;
e.rulesflag = row[16] ? static_cast<uint8_t>(strtoul(row[16], nullptr, 10)) : 0;
e.suspendeduntil = strtoll(row[17] ? row[17] : "-1", nullptr, 10);
e.time_creation = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.ban_reason = row[19] ? row[19] : "";
e.suspend_reason = row[20] ? row[20] : "";
e.crc_eqgame = row[21] ? row[21] : "";
e.crc_skillcaps = row[22] ? row[22] : "";
e.crc_basedata = row[23] ? row[23] : "";
return e;
}
@@ -271,28 +266,27 @@ public:
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.charname) + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.auto_login_charname) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.sharedplat));
v.push_back(columns[5] + " = '" + Strings::Escape(e.password) + "'");
v.push_back(columns[6] + " = " + std::to_string(e.status));
v.push_back(columns[7] + " = '" + Strings::Escape(e.ls_id) + "'");
v.push_back(columns[8] + " = " + std::to_string(e.lsaccount_id));
v.push_back(columns[9] + " = " + std::to_string(e.gmspeed));
v.push_back(columns[10] + " = " + std::to_string(e.invulnerable));
v.push_back(columns[11] + " = " + std::to_string(e.flymode));
v.push_back(columns[12] + " = " + std::to_string(e.ignore_tells));
v.push_back(columns[13] + " = " + std::to_string(e.revoked));
v.push_back(columns[14] + " = " + std::to_string(e.karma));
v.push_back(columns[15] + " = '" + Strings::Escape(e.minilogin_ip) + "'");
v.push_back(columns[16] + " = " + std::to_string(e.hideme));
v.push_back(columns[17] + " = " + std::to_string(e.rulesflag));
v.push_back(columns[18] + " = FROM_UNIXTIME(" + (e.suspendeduntil > 0 ? std::to_string(e.suspendeduntil) : "null") + ")");
v.push_back(columns[19] + " = " + std::to_string(e.time_creation));
v.push_back(columns[20] + " = '" + Strings::Escape(e.ban_reason) + "'");
v.push_back(columns[21] + " = '" + Strings::Escape(e.suspend_reason) + "'");
v.push_back(columns[22] + " = '" + Strings::Escape(e.crc_eqgame) + "'");
v.push_back(columns[23] + " = '" + Strings::Escape(e.crc_skillcaps) + "'");
v.push_back(columns[24] + " = '" + Strings::Escape(e.crc_basedata) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.sharedplat));
v.push_back(columns[4] + " = '" + Strings::Escape(e.password) + "'");
v.push_back(columns[5] + " = " + std::to_string(e.status));
v.push_back(columns[6] + " = '" + Strings::Escape(e.ls_id) + "'");
v.push_back(columns[7] + " = " + std::to_string(e.lsaccount_id));
v.push_back(columns[8] + " = " + std::to_string(e.gmspeed));
v.push_back(columns[9] + " = " + std::to_string(e.invulnerable));
v.push_back(columns[10] + " = " + std::to_string(e.flymode));
v.push_back(columns[11] + " = " + std::to_string(e.ignore_tells));
v.push_back(columns[12] + " = " + std::to_string(e.revoked));
v.push_back(columns[13] + " = " + std::to_string(e.karma));
v.push_back(columns[14] + " = '" + Strings::Escape(e.minilogin_ip) + "'");
v.push_back(columns[15] + " = " + std::to_string(e.hideme));
v.push_back(columns[16] + " = " + std::to_string(e.rulesflag));
v.push_back(columns[17] + " = FROM_UNIXTIME(" + (e.suspendeduntil > 0 ? std::to_string(e.suspendeduntil) : "null") + ")");
v.push_back(columns[18] + " = " + std::to_string(e.time_creation));
v.push_back(columns[19] + " = '" + Strings::Escape(e.ban_reason) + "'");
v.push_back(columns[20] + " = '" + Strings::Escape(e.suspend_reason) + "'");
v.push_back(columns[21] + " = '" + Strings::Escape(e.crc_eqgame) + "'");
v.push_back(columns[22] + " = '" + Strings::Escape(e.crc_skillcaps) + "'");
v.push_back(columns[23] + " = '" + Strings::Escape(e.crc_basedata) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -317,7 +311,6 @@ public:
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.charname) + "'");
v.push_back("'" + Strings::Escape(e.auto_login_charname) + "'");
v.push_back(std::to_string(e.sharedplat));
v.push_back("'" + Strings::Escape(e.password) + "'");
v.push_back(std::to_string(e.status));
@@ -371,7 +364,6 @@ public:
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.charname) + "'");
v.push_back("'" + Strings::Escape(e.auto_login_charname) + "'");
v.push_back(std::to_string(e.sharedplat));
v.push_back("'" + Strings::Escape(e.password) + "'");
v.push_back(std::to_string(e.status));
@@ -426,31 +418,30 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
Account e{};
e.id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.name = row[1] ? row[1] : "";
e.charname = row[2] ? row[2] : "";
e.auto_login_charname = row[3] ? row[3] : "";
e.sharedplat = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.password = row[5] ? row[5] : "";
e.status = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.ls_id = row[7] ? row[7] : "eqemu";
e.lsaccount_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.gmspeed = row[9] ? static_cast<uint8_t>(strtoul(row[9], nullptr, 10)) : 0;
e.invulnerable = row[10] ? static_cast<int8_t>(atoi(row[10])) : 0;
e.flymode = row[11] ? static_cast<int8_t>(atoi(row[11])) : 0;
e.ignore_tells = row[12] ? static_cast<int8_t>(atoi(row[12])) : 0;
e.revoked = row[13] ? static_cast<uint8_t>(strtoul(row[13], nullptr, 10)) : 0;
e.karma = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.minilogin_ip = row[15] ? row[15] : "";
e.hideme = row[16] ? static_cast<int8_t>(atoi(row[16])) : 0;
e.rulesflag = row[17] ? static_cast<uint8_t>(strtoul(row[17], nullptr, 10)) : 0;
e.suspendeduntil = strtoll(row[18] ? row[18] : "-1", nullptr, 10);
e.time_creation = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.ban_reason = row[20] ? row[20] : "";
e.suspend_reason = row[21] ? row[21] : "";
e.crc_eqgame = row[22] ? row[22] : "";
e.crc_skillcaps = row[23] ? row[23] : "";
e.crc_basedata = row[24] ? row[24] : "";
e.id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.name = row[1] ? row[1] : "";
e.charname = row[2] ? row[2] : "";
e.sharedplat = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.password = row[4] ? row[4] : "";
e.status = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.ls_id = row[6] ? row[6] : "eqemu";
e.lsaccount_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.gmspeed = row[8] ? static_cast<uint8_t>(strtoul(row[8], nullptr, 10)) : 0;
e.invulnerable = row[9] ? static_cast<int8_t>(atoi(row[9])) : 0;
e.flymode = row[10] ? static_cast<int8_t>(atoi(row[10])) : 0;
e.ignore_tells = row[11] ? static_cast<int8_t>(atoi(row[11])) : 0;
e.revoked = row[12] ? static_cast<uint8_t>(strtoul(row[12], nullptr, 10)) : 0;
e.karma = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.minilogin_ip = row[14] ? row[14] : "";
e.hideme = row[15] ? static_cast<int8_t>(atoi(row[15])) : 0;
e.rulesflag = row[16] ? static_cast<uint8_t>(strtoul(row[16], nullptr, 10)) : 0;
e.suspendeduntil = strtoll(row[17] ? row[17] : "-1", nullptr, 10);
e.time_creation = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.ban_reason = row[19] ? row[19] : "";
e.suspend_reason = row[20] ? row[20] : "";
e.crc_eqgame = row[21] ? row[21] : "";
e.crc_skillcaps = row[22] ? row[22] : "";
e.crc_basedata = row[23] ? row[23] : "";
all_entries.push_back(e);
}
@@ -475,31 +466,30 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
Account e{};
e.id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.name = row[1] ? row[1] : "";
e.charname = row[2] ? row[2] : "";
e.auto_login_charname = row[3] ? row[3] : "";
e.sharedplat = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.password = row[5] ? row[5] : "";
e.status = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.ls_id = row[7] ? row[7] : "eqemu";
e.lsaccount_id = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.gmspeed = row[9] ? static_cast<uint8_t>(strtoul(row[9], nullptr, 10)) : 0;
e.invulnerable = row[10] ? static_cast<int8_t>(atoi(row[10])) : 0;
e.flymode = row[11] ? static_cast<int8_t>(atoi(row[11])) : 0;
e.ignore_tells = row[12] ? static_cast<int8_t>(atoi(row[12])) : 0;
e.revoked = row[13] ? static_cast<uint8_t>(strtoul(row[13], nullptr, 10)) : 0;
e.karma = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.minilogin_ip = row[15] ? row[15] : "";
e.hideme = row[16] ? static_cast<int8_t>(atoi(row[16])) : 0;
e.rulesflag = row[17] ? static_cast<uint8_t>(strtoul(row[17], nullptr, 10)) : 0;
e.suspendeduntil = strtoll(row[18] ? row[18] : "-1", nullptr, 10);
e.time_creation = row[19] ? static_cast<uint32_t>(strtoul(row[19], nullptr, 10)) : 0;
e.ban_reason = row[20] ? row[20] : "";
e.suspend_reason = row[21] ? row[21] : "";
e.crc_eqgame = row[22] ? row[22] : "";
e.crc_skillcaps = row[23] ? row[23] : "";
e.crc_basedata = row[24] ? row[24] : "";
e.id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.name = row[1] ? row[1] : "";
e.charname = row[2] ? row[2] : "";
e.sharedplat = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.password = row[4] ? row[4] : "";
e.status = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.ls_id = row[6] ? row[6] : "eqemu";
e.lsaccount_id = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.gmspeed = row[8] ? static_cast<uint8_t>(strtoul(row[8], nullptr, 10)) : 0;
e.invulnerable = row[9] ? static_cast<int8_t>(atoi(row[9])) : 0;
e.flymode = row[10] ? static_cast<int8_t>(atoi(row[10])) : 0;
e.ignore_tells = row[11] ? static_cast<int8_t>(atoi(row[11])) : 0;
e.revoked = row[12] ? static_cast<uint8_t>(strtoul(row[12], nullptr, 10)) : 0;
e.karma = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.minilogin_ip = row[14] ? row[14] : "";
e.hideme = row[15] ? static_cast<int8_t>(atoi(row[15])) : 0;
e.rulesflag = row[16] ? static_cast<uint8_t>(strtoul(row[16], nullptr, 10)) : 0;
e.suspendeduntil = strtoll(row[17] ? row[17] : "-1", nullptr, 10);
e.time_creation = row[18] ? static_cast<uint32_t>(strtoul(row[18], nullptr, 10)) : 0;
e.ban_reason = row[19] ? row[19] : "";
e.suspend_reason = row[20] ? row[20] : "";
e.crc_eqgame = row[21] ? row[21] : "";
e.crc_skillcaps = row[22] ? row[22] : "";
e.crc_basedata = row[23] ? row[23] : "";
all_entries.push_back(e);
}
@@ -577,7 +567,6 @@ public:
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.charname) + "'");
v.push_back("'" + Strings::Escape(e.auto_login_charname) + "'");
v.push_back(std::to_string(e.sharedplat));
v.push_back("'" + Strings::Escape(e.password) + "'");
v.push_back(std::to_string(e.status));
@@ -624,7 +613,6 @@ public:
v.push_back(std::to_string(e.id));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back("'" + Strings::Escape(e.charname) + "'");
v.push_back("'" + Strings::Escape(e.auto_login_charname) + "'");
v.push_back(std::to_string(e.sharedplat));
v.push_back("'" + Strings::Escape(e.password) + "'");
v.push_back(std::to_string(e.status));
@@ -57,7 +57,6 @@ public:
int32_t int_;
int32_t agi;
int32_t wis;
int32_t extra_haste;
int16_t fire;
int16_t cold;
int16_t magic;
@@ -119,7 +118,6 @@ public:
"`int`",
"agi",
"wis",
"extra_haste",
"fire",
"cold",
"magic",
@@ -177,7 +175,6 @@ public:
"`int`",
"agi",
"wis",
"extra_haste",
"fire",
"cold",
"magic",
@@ -269,7 +266,6 @@ public:
e.int_ = 75;
e.agi = 75;
e.wis = 75;
e.extra_haste = 0;
e.fire = 0;
e.cold = 0;
e.magic = 0;
@@ -357,20 +353,19 @@ public:
e.int_ = row[35] ? static_cast<int32_t>(atoi(row[35])) : 75;
e.agi = row[36] ? static_cast<int32_t>(atoi(row[36])) : 75;
e.wis = row[37] ? static_cast<int32_t>(atoi(row[37])) : 75;
e.extra_haste = row[38] ? static_cast<int32_t>(atoi(row[38])) : 0;
e.fire = row[39] ? static_cast<int16_t>(atoi(row[39])) : 0;
e.cold = row[40] ? static_cast<int16_t>(atoi(row[40])) : 0;
e.magic = row[41] ? static_cast<int16_t>(atoi(row[41])) : 0;
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
e.fire = row[38] ? static_cast<int16_t>(atoi(row[38])) : 0;
e.cold = row[39] ? static_cast<int16_t>(atoi(row[39])) : 0;
e.magic = row[40] ? static_cast<int16_t>(atoi(row[40])) : 0;
e.poison = row[41] ? static_cast<int16_t>(atoi(row[41])) : 0;
e.disease = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.corruption = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.show_helm = row[44] ? static_cast<uint32_t>(strtoul(row[44], nullptr, 10)) : 0;
e.follow_distance = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 200;
e.stop_melee_level = row[46] ? static_cast<uint8_t>(strtoul(row[46], nullptr, 10)) : 255;
e.expansion_bitmask = row[47] ? static_cast<int32_t>(atoi(row[47])) : -1;
e.enforce_spell_settings = row[48] ? static_cast<uint8_t>(strtoul(row[48], nullptr, 10)) : 0;
e.archery_setting = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.caster_range = row[50] ? static_cast<uint32_t>(strtoul(row[50], nullptr, 10)) : 300;
return e;
}
@@ -441,20 +436,19 @@ public:
v.push_back(columns[35] + " = " + std::to_string(e.int_));
v.push_back(columns[36] + " = " + std::to_string(e.agi));
v.push_back(columns[37] + " = " + std::to_string(e.wis));
v.push_back(columns[38] + " = " + std::to_string(e.extra_haste));
v.push_back(columns[39] + " = " + std::to_string(e.fire));
v.push_back(columns[40] + " = " + std::to_string(e.cold));
v.push_back(columns[41] + " = " + std::to_string(e.magic));
v.push_back(columns[42] + " = " + std::to_string(e.poison));
v.push_back(columns[43] + " = " + std::to_string(e.disease));
v.push_back(columns[44] + " = " + std::to_string(e.corruption));
v.push_back(columns[45] + " = " + std::to_string(e.show_helm));
v.push_back(columns[46] + " = " + std::to_string(e.follow_distance));
v.push_back(columns[47] + " = " + std::to_string(e.stop_melee_level));
v.push_back(columns[48] + " = " + std::to_string(e.expansion_bitmask));
v.push_back(columns[49] + " = " + std::to_string(e.enforce_spell_settings));
v.push_back(columns[50] + " = " + std::to_string(e.archery_setting));
v.push_back(columns[51] + " = " + std::to_string(e.caster_range));
v.push_back(columns[38] + " = " + std::to_string(e.fire));
v.push_back(columns[39] + " = " + std::to_string(e.cold));
v.push_back(columns[40] + " = " + std::to_string(e.magic));
v.push_back(columns[41] + " = " + std::to_string(e.poison));
v.push_back(columns[42] + " = " + std::to_string(e.disease));
v.push_back(columns[43] + " = " + std::to_string(e.corruption));
v.push_back(columns[44] + " = " + std::to_string(e.show_helm));
v.push_back(columns[45] + " = " + std::to_string(e.follow_distance));
v.push_back(columns[46] + " = " + std::to_string(e.stop_melee_level));
v.push_back(columns[47] + " = " + std::to_string(e.expansion_bitmask));
v.push_back(columns[48] + " = " + std::to_string(e.enforce_spell_settings));
v.push_back(columns[49] + " = " + std::to_string(e.archery_setting));
v.push_back(columns[50] + " = " + std::to_string(e.caster_range));
auto results = db.QueryDatabase(
fmt::format(
@@ -514,7 +508,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.fire));
v.push_back(std::to_string(e.cold));
v.push_back(std::to_string(e.magic));
@@ -595,7 +588,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.fire));
v.push_back(std::to_string(e.cold));
v.push_back(std::to_string(e.magic));
@@ -680,20 +672,19 @@ public:
e.int_ = row[35] ? static_cast<int32_t>(atoi(row[35])) : 75;
e.agi = row[36] ? static_cast<int32_t>(atoi(row[36])) : 75;
e.wis = row[37] ? static_cast<int32_t>(atoi(row[37])) : 75;
e.extra_haste = row[38] ? static_cast<int32_t>(atoi(row[38])) : 0;
e.fire = row[39] ? static_cast<int16_t>(atoi(row[39])) : 0;
e.cold = row[40] ? static_cast<int16_t>(atoi(row[40])) : 0;
e.magic = row[41] ? static_cast<int16_t>(atoi(row[41])) : 0;
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
e.fire = row[38] ? static_cast<int16_t>(atoi(row[38])) : 0;
e.cold = row[39] ? static_cast<int16_t>(atoi(row[39])) : 0;
e.magic = row[40] ? static_cast<int16_t>(atoi(row[40])) : 0;
e.poison = row[41] ? static_cast<int16_t>(atoi(row[41])) : 0;
e.disease = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.corruption = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.show_helm = row[44] ? static_cast<uint32_t>(strtoul(row[44], nullptr, 10)) : 0;
e.follow_distance = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 200;
e.stop_melee_level = row[46] ? static_cast<uint8_t>(strtoul(row[46], nullptr, 10)) : 255;
e.expansion_bitmask = row[47] ? static_cast<int32_t>(atoi(row[47])) : -1;
e.enforce_spell_settings = row[48] ? static_cast<uint8_t>(strtoul(row[48], nullptr, 10)) : 0;
e.archery_setting = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.caster_range = row[50] ? static_cast<uint32_t>(strtoul(row[50], nullptr, 10)) : 300;
all_entries.push_back(e);
}
@@ -756,20 +747,19 @@ public:
e.int_ = row[35] ? static_cast<int32_t>(atoi(row[35])) : 75;
e.agi = row[36] ? static_cast<int32_t>(atoi(row[36])) : 75;
e.wis = row[37] ? static_cast<int32_t>(atoi(row[37])) : 75;
e.extra_haste = row[38] ? static_cast<int32_t>(atoi(row[38])) : 0;
e.fire = row[39] ? static_cast<int16_t>(atoi(row[39])) : 0;
e.cold = row[40] ? static_cast<int16_t>(atoi(row[40])) : 0;
e.magic = row[41] ? static_cast<int16_t>(atoi(row[41])) : 0;
e.poison = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.disease = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.corruption = row[44] ? static_cast<int16_t>(atoi(row[44])) : 0;
e.show_helm = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 0;
e.follow_distance = row[46] ? static_cast<uint32_t>(strtoul(row[46], nullptr, 10)) : 200;
e.stop_melee_level = row[47] ? static_cast<uint8_t>(strtoul(row[47], nullptr, 10)) : 255;
e.expansion_bitmask = row[48] ? static_cast<int32_t>(atoi(row[48])) : -1;
e.enforce_spell_settings = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.archery_setting = row[50] ? static_cast<uint8_t>(strtoul(row[50], nullptr, 10)) : 0;
e.caster_range = row[51] ? static_cast<uint32_t>(strtoul(row[51], nullptr, 10)) : 300;
e.fire = row[38] ? static_cast<int16_t>(atoi(row[38])) : 0;
e.cold = row[39] ? static_cast<int16_t>(atoi(row[39])) : 0;
e.magic = row[40] ? static_cast<int16_t>(atoi(row[40])) : 0;
e.poison = row[41] ? static_cast<int16_t>(atoi(row[41])) : 0;
e.disease = row[42] ? static_cast<int16_t>(atoi(row[42])) : 0;
e.corruption = row[43] ? static_cast<int16_t>(atoi(row[43])) : 0;
e.show_helm = row[44] ? static_cast<uint32_t>(strtoul(row[44], nullptr, 10)) : 0;
e.follow_distance = row[45] ? static_cast<uint32_t>(strtoul(row[45], nullptr, 10)) : 200;
e.stop_melee_level = row[46] ? static_cast<uint8_t>(strtoul(row[46], nullptr, 10)) : 255;
e.expansion_bitmask = row[47] ? static_cast<int32_t>(atoi(row[47])) : -1;
e.enforce_spell_settings = row[48] ? static_cast<uint8_t>(strtoul(row[48], nullptr, 10)) : 0;
e.archery_setting = row[49] ? static_cast<uint8_t>(strtoul(row[49], nullptr, 10)) : 0;
e.caster_range = row[50] ? static_cast<uint32_t>(strtoul(row[50], nullptr, 10)) : 300;
all_entries.push_back(e);
}
@@ -882,7 +872,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.fire));
v.push_back(std::to_string(e.cold));
v.push_back(std::to_string(e.magic));
@@ -956,7 +945,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.fire));
v.push_back(std::to_string(e.cold));
v.push_back(std::to_string(e.magic));
@@ -21,7 +21,7 @@ public:
struct BotSpellsEntries {
uint32_t id;
int32_t npc_spells_id;
uint16_t spell_id;
int16_t spellid;
uint32_t type;
uint8_t minlevel;
uint8_t maxlevel;
@@ -46,7 +46,7 @@ public:
return {
"id",
"npc_spells_id",
"spell_id",
"spellid",
"type",
"minlevel",
"maxlevel",
@@ -67,7 +67,7 @@ public:
return {
"id",
"npc_spells_id",
"spell_id",
"spellid",
"type",
"minlevel",
"maxlevel",
@@ -122,7 +122,7 @@ public:
e.id = 0;
e.npc_spells_id = 0;
e.spell_id = 0;
e.spellid = 0;
e.type = 0;
e.minlevel = 0;
e.maxlevel = 255;
@@ -173,7 +173,7 @@ public:
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.spell_id = row[2] ? static_cast<uint16_t>(strtoul(row[2], nullptr, 10)) : 0;
e.spellid = row[2] ? static_cast<int16_t>(atoi(row[2])) : 0;
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
@@ -220,7 +220,7 @@ public:
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.npc_spells_id));
v.push_back(columns[2] + " = " + std::to_string(e.spell_id));
v.push_back(columns[2] + " = " + std::to_string(e.spellid));
v.push_back(columns[3] + " = " + std::to_string(e.type));
v.push_back(columns[4] + " = " + std::to_string(e.minlevel));
v.push_back(columns[5] + " = " + std::to_string(e.maxlevel));
@@ -256,7 +256,7 @@ public:
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_spells_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.spellid));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
@@ -300,7 +300,7 @@ public:
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_spells_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.spellid));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
@@ -348,7 +348,7 @@ public:
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.spell_id = row[2] ? static_cast<uint16_t>(strtoul(row[2], nullptr, 10)) : 0;
e.spellid = row[2] ? static_cast<int16_t>(atoi(row[2])) : 0;
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
@@ -387,7 +387,7 @@ public:
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.npc_spells_id = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.spell_id = row[2] ? static_cast<uint16_t>(strtoul(row[2], nullptr, 10)) : 0;
e.spellid = row[2] ? static_cast<int16_t>(atoi(row[2])) : 0;
e.type = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.minlevel = row[4] ? static_cast<uint8_t>(strtoul(row[4], nullptr, 10)) : 0;
e.maxlevel = row[5] ? static_cast<uint8_t>(strtoul(row[5], nullptr, 10)) : 255;
@@ -476,7 +476,7 @@ public:
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_spells_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.spellid));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
@@ -513,7 +513,7 @@ public:
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.npc_spells_id));
v.push_back(std::to_string(e.spell_id));
v.push_back(std::to_string(e.spellid));
v.push_back(std::to_string(e.type));
v.push_back(std::to_string(e.minlevel));
v.push_back(std::to_string(e.maxlevel));
@@ -1,475 +0,0 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_BUYER_BUY_LINES_REPOSITORY_H
#define EQEMU_BASE_BUYER_BUY_LINES_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseBuyerBuyLinesRepository {
public:
struct BuyerBuyLines {
uint64_t id;
uint64_t buyer_id;
uint32_t char_id;
int32_t buy_slot_id;
int32_t item_id;
int32_t item_qty;
int32_t item_price;
uint32_t item_icon;
std::string item_name;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"buyer_id",
"char_id",
"buy_slot_id",
"item_id",
"item_qty",
"item_price",
"item_icon",
"item_name",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"buyer_id",
"char_id",
"buy_slot_id",
"item_id",
"item_qty",
"item_price",
"item_icon",
"item_name",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("buyer_buy_lines");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static BuyerBuyLines NewEntity()
{
BuyerBuyLines e{};
e.id = 0;
e.buyer_id = 0;
e.char_id = 0;
e.buy_slot_id = 0;
e.item_id = 0;
e.item_qty = 0;
e.item_price = 0;
e.item_icon = 0;
e.item_name = "";
return e;
}
static BuyerBuyLines GetBuyerBuyLines(
const std::vector<BuyerBuyLines> &buyer_buy_liness,
int buyer_buy_lines_id
)
{
for (auto &buyer_buy_lines : buyer_buy_liness) {
if (buyer_buy_lines.id == buyer_buy_lines_id) {
return buyer_buy_lines;
}
}
return NewEntity();
}
static BuyerBuyLines FindOne(
Database& db,
int buyer_buy_lines_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
buyer_buy_lines_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
BuyerBuyLines e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.buyer_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.buy_slot_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.item_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.item_qty = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.item_price = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.item_icon = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.item_name = row[8] ? row[8] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int buyer_buy_lines_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
buyer_buy_lines_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const BuyerBuyLines &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.buyer_id));
v.push_back(columns[2] + " = " + std::to_string(e.char_id));
v.push_back(columns[3] + " = " + std::to_string(e.buy_slot_id));
v.push_back(columns[4] + " = " + std::to_string(e.item_id));
v.push_back(columns[5] + " = " + std::to_string(e.item_qty));
v.push_back(columns[6] + " = " + std::to_string(e.item_price));
v.push_back(columns[7] + " = " + std::to_string(e.item_icon));
v.push_back(columns[8] + " = '" + Strings::Escape(e.item_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static BuyerBuyLines InsertOne(
Database& db,
BuyerBuyLines e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.buy_slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_price));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<BuyerBuyLines> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.buy_slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_price));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<BuyerBuyLines> All(Database& db)
{
std::vector<BuyerBuyLines> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BuyerBuyLines e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.buyer_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.buy_slot_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.item_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.item_qty = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.item_price = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.item_icon = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.item_name = row[8] ? row[8] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<BuyerBuyLines> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<BuyerBuyLines> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BuyerBuyLines e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.buyer_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.char_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.buy_slot_id = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.item_id = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.item_qty = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
e.item_price = row[6] ? static_cast<int32_t>(atoi(row[6])) : 0;
e.item_icon = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.item_name = row[8] ? row[8] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const BuyerBuyLines &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.buy_slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_price));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<BuyerBuyLines> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.buy_slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_price));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_BUYER_BUY_LINES_REPOSITORY_H
@@ -19,46 +19,40 @@
class BaseBuyerRepository {
public:
struct Buyer {
uint64_t id;
uint32_t char_id;
uint32_t char_entity_id;
std::string char_name;
uint32_t char_zone_id;
uint32_t char_zone_instance_id;
time_t transaction_date;
std::string welcome_message;
int32_t charid;
int32_t buyslot;
int32_t itemid;
std::string itemname;
int32_t quantity;
int32_t price;
};
static std::string PrimaryKey()
{
return std::string("id");
return std::string("charid");
}
static std::vector<std::string> Columns()
{
return {
"id",
"char_id",
"char_entity_id",
"char_name",
"char_zone_id",
"char_zone_instance_id",
"transaction_date",
"welcome_message",
"charid",
"buyslot",
"itemid",
"itemname",
"quantity",
"price",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"char_id",
"char_entity_id",
"char_name",
"char_zone_id",
"char_zone_instance_id",
"UNIX_TIMESTAMP(transaction_date)",
"welcome_message",
"charid",
"buyslot",
"itemid",
"itemname",
"quantity",
"price",
};
}
@@ -99,14 +93,12 @@ public:
{
Buyer e{};
e.id = 0;
e.char_id = 0;
e.char_entity_id = 0;
e.char_name = "";
e.char_zone_id = 0;
e.char_zone_instance_id = 0;
e.transaction_date = 0;
e.welcome_message = "";
e.charid = 0;
e.buyslot = 0;
e.itemid = 0;
e.itemname = "";
e.quantity = 0;
e.price = 0;
return e;
}
@@ -117,7 +109,7 @@ public:
)
{
for (auto &buyer : buyers) {
if (buyer.id == buyer_id) {
if (buyer.charid == buyer_id) {
return buyer;
}
}
@@ -143,14 +135,12 @@ public:
if (results.RowCount() == 1) {
Buyer e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.char_entity_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.char_name = row[3] ? row[3] : "";
e.char_zone_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.char_zone_instance_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.transaction_date = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
e.welcome_message = row[7] ? row[7] : "";
e.charid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.buyslot = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.itemid = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.itemname = row[3] ? row[3] : "";
e.quantity = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.price = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
return e;
}
@@ -184,13 +174,12 @@ public:
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.char_id));
v.push_back(columns[2] + " = " + std::to_string(e.char_entity_id));
v.push_back(columns[3] + " = '" + Strings::Escape(e.char_name) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.char_zone_id));
v.push_back(columns[5] + " = " + std::to_string(e.char_zone_instance_id));
v.push_back(columns[6] + " = FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
v.push_back(columns[7] + " = '" + Strings::Escape(e.welcome_message) + "'");
v.push_back(columns[0] + " = " + std::to_string(e.charid));
v.push_back(columns[1] + " = " + std::to_string(e.buyslot));
v.push_back(columns[2] + " = " + std::to_string(e.itemid));
v.push_back(columns[3] + " = '" + Strings::Escape(e.itemname) + "'");
v.push_back(columns[4] + " = " + std::to_string(e.quantity));
v.push_back(columns[5] + " = " + std::to_string(e.price));
auto results = db.QueryDatabase(
fmt::format(
@@ -198,7 +187,7 @@ public:
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
e.charid
)
);
@@ -212,14 +201,12 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.char_entity_id));
v.push_back("'" + Strings::Escape(e.char_name) + "'");
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.buyslot));
v.push_back(std::to_string(e.itemid));
v.push_back("'" + Strings::Escape(e.itemname) + "'");
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.price));
auto results = db.QueryDatabase(
fmt::format(
@@ -230,7 +217,7 @@ public:
);
if (results.Success()) {
e.id = results.LastInsertedID();
e.charid = results.LastInsertedID();
return e;
}
@@ -249,14 +236,12 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.char_entity_id));
v.push_back("'" + Strings::Escape(e.char_name) + "'");
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.buyslot));
v.push_back(std::to_string(e.itemid));
v.push_back("'" + Strings::Escape(e.itemname) + "'");
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.price));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -290,14 +275,12 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
Buyer e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.char_entity_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.char_name = row[3] ? row[3] : "";
e.char_zone_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.char_zone_instance_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.transaction_date = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
e.welcome_message = row[7] ? row[7] : "";
e.charid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.buyslot = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.itemid = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.itemname = row[3] ? row[3] : "";
e.quantity = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.price = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
all_entries.push_back(e);
}
@@ -322,14 +305,12 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
Buyer e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.char_entity_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.char_name = row[3] ? row[3] : "";
e.char_zone_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.char_zone_instance_id = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.transaction_date = strtoll(row[6] ? row[6] : "-1", nullptr, 10);
e.welcome_message = row[7] ? row[7] : "";
e.charid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.buyslot = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.itemid = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.itemname = row[3] ? row[3] : "";
e.quantity = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.price = row[5] ? static_cast<int32_t>(atoi(row[5])) : 0;
all_entries.push_back(e);
}
@@ -404,14 +385,12 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.char_entity_id));
v.push_back("'" + Strings::Escape(e.char_name) + "'");
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.buyslot));
v.push_back(std::to_string(e.itemid));
v.push_back("'" + Strings::Escape(e.itemname) + "'");
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.price));
auto results = db.QueryDatabase(
fmt::format(
@@ -434,14 +413,12 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.char_entity_id));
v.push_back("'" + Strings::Escape(e.char_name) + "'");
v.push_back(std::to_string(e.char_zone_id));
v.push_back(std::to_string(e.char_zone_instance_id));
v.push_back("FROM_UNIXTIME(" + (e.transaction_date > 0 ? std::to_string(e.transaction_date) : "null") + ")");
v.push_back("'" + Strings::Escape(e.welcome_message) + "'");
v.push_back(std::to_string(e.charid));
v.push_back(std::to_string(e.buyslot));
v.push_back(std::to_string(e.itemid));
v.push_back("'" + Strings::Escape(e.itemname) + "'");
v.push_back(std::to_string(e.quantity));
v.push_back(std::to_string(e.price));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -1,439 +0,0 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_BUYER_TRADE_ITEMS_REPOSITORY_H
#define EQEMU_BASE_BUYER_TRADE_ITEMS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseBuyerTradeItemsRepository {
public:
struct BuyerTradeItems {
uint64_t id;
uint64_t buyer_buy_lines_id;
int32_t item_id;
int32_t item_qty;
int32_t item_icon;
std::string item_name;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"buyer_buy_lines_id",
"item_id",
"item_qty",
"item_icon",
"item_name",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"buyer_buy_lines_id",
"item_id",
"item_qty",
"item_icon",
"item_name",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("buyer_trade_items");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static BuyerTradeItems NewEntity()
{
BuyerTradeItems e{};
e.id = 0;
e.buyer_buy_lines_id = 0;
e.item_id = 0;
e.item_qty = 0;
e.item_icon = 0;
e.item_name = "0";
return e;
}
static BuyerTradeItems GetBuyerTradeItems(
const std::vector<BuyerTradeItems> &buyer_trade_itemss,
int buyer_trade_items_id
)
{
for (auto &buyer_trade_items : buyer_trade_itemss) {
if (buyer_trade_items.id == buyer_trade_items_id) {
return buyer_trade_items;
}
}
return NewEntity();
}
static BuyerTradeItems FindOne(
Database& db,
int buyer_trade_items_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
buyer_trade_items_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
BuyerTradeItems e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.buyer_buy_lines_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.item_id = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.item_qty = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.item_icon = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.item_name = row[5] ? row[5] : "0";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int buyer_trade_items_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
buyer_trade_items_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const BuyerTradeItems &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.buyer_buy_lines_id));
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
v.push_back(columns[3] + " = " + std::to_string(e.item_qty));
v.push_back(columns[4] + " = " + std::to_string(e.item_icon));
v.push_back(columns[5] + " = '" + Strings::Escape(e.item_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static BuyerTradeItems InsertOne(
Database& db,
BuyerTradeItems e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_buy_lines_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<BuyerTradeItems> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_buy_lines_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<BuyerTradeItems> All(Database& db)
{
std::vector<BuyerTradeItems> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BuyerTradeItems e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.buyer_buy_lines_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.item_id = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.item_qty = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.item_icon = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.item_name = row[5] ? row[5] : "0";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<BuyerTradeItems> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<BuyerTradeItems> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BuyerTradeItems e{};
e.id = row[0] ? strtoull(row[0], nullptr, 10) : 0;
e.buyer_buy_lines_id = row[1] ? strtoull(row[1], nullptr, 10) : 0;
e.item_id = row[2] ? static_cast<int32_t>(atoi(row[2])) : 0;
e.item_qty = row[3] ? static_cast<int32_t>(atoi(row[3])) : 0;
e.item_icon = row[4] ? static_cast<int32_t>(atoi(row[4])) : 0;
e.item_name = row[5] ? row[5] : "0";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const BuyerTradeItems &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_buy_lines_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<BuyerTradeItems> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.buyer_buy_lines_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_qty));
v.push_back(std::to_string(e.item_icon));
v.push_back("'" + Strings::Escape(e.item_name) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_BUYER_TRADE_ITEMS_REPOSITORY_H
@@ -77,7 +77,6 @@ public:
uint32_t int_;
uint32_t agi;
uint32_t wis;
int32_t extra_haste;
uint32_t zone_change_count;
uint32_t toxicity;
uint32_t hunger_level;
@@ -191,7 +190,6 @@ public:
"`int`",
"agi",
"wis",
"extra_haste",
"zone_change_count",
"toxicity",
"hunger_level",
@@ -301,7 +299,6 @@ public:
"`int`",
"agi",
"wis",
"extra_haste",
"zone_change_count",
"toxicity",
"hunger_level",
@@ -445,7 +442,6 @@ public:
e.int_ = 0;
e.agi = 0;
e.wis = 0;
e.extra_haste = 0;
e.zone_change_count = 0;
e.toxicity = 0;
e.hunger_level = 0;
@@ -585,52 +581,51 @@ public:
e.int_ = row[55] ? static_cast<uint32_t>(strtoul(row[55], nullptr, 10)) : 0;
e.agi = row[56] ? static_cast<uint32_t>(strtoul(row[56], nullptr, 10)) : 0;
e.wis = row[57] ? static_cast<uint32_t>(strtoul(row[57], nullptr, 10)) : 0;
e.extra_haste = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.zone_change_count = row[59] ? static_cast<uint32_t>(strtoul(row[59], nullptr, 10)) : 0;
e.toxicity = row[60] ? static_cast<uint32_t>(strtoul(row[60], nullptr, 10)) : 0;
e.hunger_level = row[61] ? static_cast<uint32_t>(strtoul(row[61], nullptr, 10)) : 0;
e.thirst_level = row[62] ? static_cast<uint32_t>(strtoul(row[62], nullptr, 10)) : 0;
e.ability_up = row[63] ? static_cast<uint32_t>(strtoul(row[63], nullptr, 10)) : 0;
e.ldon_points_guk = row[64] ? static_cast<uint32_t>(strtoul(row[64], nullptr, 10)) : 0;
e.ldon_points_mir = row[65] ? static_cast<uint32_t>(strtoul(row[65], nullptr, 10)) : 0;
e.ldon_points_mmc = row[66] ? static_cast<uint32_t>(strtoul(row[66], nullptr, 10)) : 0;
e.ldon_points_ruj = row[67] ? static_cast<uint32_t>(strtoul(row[67], nullptr, 10)) : 0;
e.ldon_points_tak = row[68] ? static_cast<uint32_t>(strtoul(row[68], nullptr, 10)) : 0;
e.ldon_points_available = row[69] ? static_cast<uint32_t>(strtoul(row[69], nullptr, 10)) : 0;
e.tribute_time_remaining = row[70] ? static_cast<uint32_t>(strtoul(row[70], nullptr, 10)) : 0;
e.career_tribute_points = row[71] ? static_cast<uint32_t>(strtoul(row[71], nullptr, 10)) : 0;
e.tribute_points = row[72] ? static_cast<uint32_t>(strtoul(row[72], nullptr, 10)) : 0;
e.tribute_active = row[73] ? static_cast<uint32_t>(strtoul(row[73], nullptr, 10)) : 0;
e.pvp_status = row[74] ? static_cast<uint8_t>(strtoul(row[74], nullptr, 10)) : 0;
e.pvp_kills = row[75] ? static_cast<uint32_t>(strtoul(row[75], nullptr, 10)) : 0;
e.pvp_deaths = row[76] ? static_cast<uint32_t>(strtoul(row[76], nullptr, 10)) : 0;
e.pvp_current_points = row[77] ? static_cast<uint32_t>(strtoul(row[77], nullptr, 10)) : 0;
e.pvp_career_points = row[78] ? static_cast<uint32_t>(strtoul(row[78], nullptr, 10)) : 0;
e.pvp_best_kill_streak = row[79] ? static_cast<uint32_t>(strtoul(row[79], nullptr, 10)) : 0;
e.pvp_worst_death_streak = row[80] ? static_cast<uint32_t>(strtoul(row[80], nullptr, 10)) : 0;
e.pvp_current_kill_streak = row[81] ? static_cast<uint32_t>(strtoul(row[81], nullptr, 10)) : 0;
e.pvp2 = row[82] ? static_cast<uint32_t>(strtoul(row[82], nullptr, 10)) : 0;
e.pvp_type = row[83] ? static_cast<uint32_t>(strtoul(row[83], nullptr, 10)) : 0;
e.show_helm = row[84] ? static_cast<uint32_t>(strtoul(row[84], nullptr, 10)) : 0;
e.group_auto_consent = row[85] ? static_cast<uint8_t>(strtoul(row[85], nullptr, 10)) : 0;
e.raid_auto_consent = row[86] ? static_cast<uint8_t>(strtoul(row[86], nullptr, 10)) : 0;
e.guild_auto_consent = row[87] ? static_cast<uint8_t>(strtoul(row[87], nullptr, 10)) : 0;
e.leadership_exp_on = row[88] ? static_cast<uint8_t>(strtoul(row[88], nullptr, 10)) : 0;
e.RestTimer = row[89] ? static_cast<uint32_t>(strtoul(row[89], nullptr, 10)) : 0;
e.air_remaining = row[90] ? static_cast<uint32_t>(strtoul(row[90], nullptr, 10)) : 0;
e.autosplit_enabled = row[91] ? static_cast<uint32_t>(strtoul(row[91], nullptr, 10)) : 0;
e.lfp = row[92] ? static_cast<uint8_t>(strtoul(row[92], nullptr, 10)) : 0;
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.firstlogon = row[96] ? static_cast<int8_t>(atoi(row[96])) : 0;
e.e_aa_effects = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_percent_to_aa = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_spent_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.zone_change_count = row[58] ? static_cast<uint32_t>(strtoul(row[58], nullptr, 10)) : 0;
e.toxicity = row[59] ? static_cast<uint32_t>(strtoul(row[59], nullptr, 10)) : 0;
e.hunger_level = row[60] ? static_cast<uint32_t>(strtoul(row[60], nullptr, 10)) : 0;
e.thirst_level = row[61] ? static_cast<uint32_t>(strtoul(row[61], nullptr, 10)) : 0;
e.ability_up = row[62] ? static_cast<uint32_t>(strtoul(row[62], nullptr, 10)) : 0;
e.ldon_points_guk = row[63] ? static_cast<uint32_t>(strtoul(row[63], nullptr, 10)) : 0;
e.ldon_points_mir = row[64] ? static_cast<uint32_t>(strtoul(row[64], nullptr, 10)) : 0;
e.ldon_points_mmc = row[65] ? static_cast<uint32_t>(strtoul(row[65], nullptr, 10)) : 0;
e.ldon_points_ruj = row[66] ? static_cast<uint32_t>(strtoul(row[66], nullptr, 10)) : 0;
e.ldon_points_tak = row[67] ? static_cast<uint32_t>(strtoul(row[67], nullptr, 10)) : 0;
e.ldon_points_available = row[68] ? static_cast<uint32_t>(strtoul(row[68], nullptr, 10)) : 0;
e.tribute_time_remaining = row[69] ? static_cast<uint32_t>(strtoul(row[69], nullptr, 10)) : 0;
e.career_tribute_points = row[70] ? static_cast<uint32_t>(strtoul(row[70], nullptr, 10)) : 0;
e.tribute_points = row[71] ? static_cast<uint32_t>(strtoul(row[71], nullptr, 10)) : 0;
e.tribute_active = row[72] ? static_cast<uint32_t>(strtoul(row[72], nullptr, 10)) : 0;
e.pvp_status = row[73] ? static_cast<uint8_t>(strtoul(row[73], nullptr, 10)) : 0;
e.pvp_kills = row[74] ? static_cast<uint32_t>(strtoul(row[74], nullptr, 10)) : 0;
e.pvp_deaths = row[75] ? static_cast<uint32_t>(strtoul(row[75], nullptr, 10)) : 0;
e.pvp_current_points = row[76] ? static_cast<uint32_t>(strtoul(row[76], nullptr, 10)) : 0;
e.pvp_career_points = row[77] ? static_cast<uint32_t>(strtoul(row[77], nullptr, 10)) : 0;
e.pvp_best_kill_streak = row[78] ? static_cast<uint32_t>(strtoul(row[78], nullptr, 10)) : 0;
e.pvp_worst_death_streak = row[79] ? static_cast<uint32_t>(strtoul(row[79], nullptr, 10)) : 0;
e.pvp_current_kill_streak = row[80] ? static_cast<uint32_t>(strtoul(row[80], nullptr, 10)) : 0;
e.pvp2 = row[81] ? static_cast<uint32_t>(strtoul(row[81], nullptr, 10)) : 0;
e.pvp_type = row[82] ? static_cast<uint32_t>(strtoul(row[82], nullptr, 10)) : 0;
e.show_helm = row[83] ? static_cast<uint32_t>(strtoul(row[83], nullptr, 10)) : 0;
e.group_auto_consent = row[84] ? static_cast<uint8_t>(strtoul(row[84], nullptr, 10)) : 0;
e.raid_auto_consent = row[85] ? static_cast<uint8_t>(strtoul(row[85], nullptr, 10)) : 0;
e.guild_auto_consent = row[86] ? static_cast<uint8_t>(strtoul(row[86], nullptr, 10)) : 0;
e.leadership_exp_on = row[87] ? static_cast<uint8_t>(strtoul(row[87], nullptr, 10)) : 0;
e.RestTimer = row[88] ? static_cast<uint32_t>(strtoul(row[88], nullptr, 10)) : 0;
e.air_remaining = row[89] ? static_cast<uint32_t>(strtoul(row[89], nullptr, 10)) : 0;
e.autosplit_enabled = row[90] ? static_cast<uint32_t>(strtoul(row[90], nullptr, 10)) : 0;
e.lfp = row[91] ? static_cast<uint8_t>(strtoul(row[91], nullptr, 10)) : 0;
e.lfg = row[92] ? static_cast<uint8_t>(strtoul(row[92], nullptr, 10)) : 0;
e.mailkey = row[93] ? row[93] : "";
e.xtargets = row[94] ? static_cast<uint8_t>(strtoul(row[94], nullptr, 10)) : 5;
e.firstlogon = row[95] ? static_cast<int8_t>(atoi(row[95])) : 0;
e.e_aa_effects = row[96] ? static_cast<uint32_t>(strtoul(row[96], nullptr, 10)) : 0;
e.e_percent_to_aa = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.aa_points_spent_old = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[102] ? row[102] : "-1", nullptr, 10);
return e;
}
@@ -721,52 +716,51 @@ public:
v.push_back(columns[55] + " = " + std::to_string(e.int_));
v.push_back(columns[56] + " = " + std::to_string(e.agi));
v.push_back(columns[57] + " = " + std::to_string(e.wis));
v.push_back(columns[58] + " = " + std::to_string(e.extra_haste));
v.push_back(columns[59] + " = " + std::to_string(e.zone_change_count));
v.push_back(columns[60] + " = " + std::to_string(e.toxicity));
v.push_back(columns[61] + " = " + std::to_string(e.hunger_level));
v.push_back(columns[62] + " = " + std::to_string(e.thirst_level));
v.push_back(columns[63] + " = " + std::to_string(e.ability_up));
v.push_back(columns[64] + " = " + std::to_string(e.ldon_points_guk));
v.push_back(columns[65] + " = " + std::to_string(e.ldon_points_mir));
v.push_back(columns[66] + " = " + std::to_string(e.ldon_points_mmc));
v.push_back(columns[67] + " = " + std::to_string(e.ldon_points_ruj));
v.push_back(columns[68] + " = " + std::to_string(e.ldon_points_tak));
v.push_back(columns[69] + " = " + std::to_string(e.ldon_points_available));
v.push_back(columns[70] + " = " + std::to_string(e.tribute_time_remaining));
v.push_back(columns[71] + " = " + std::to_string(e.career_tribute_points));
v.push_back(columns[72] + " = " + std::to_string(e.tribute_points));
v.push_back(columns[73] + " = " + std::to_string(e.tribute_active));
v.push_back(columns[74] + " = " + std::to_string(e.pvp_status));
v.push_back(columns[75] + " = " + std::to_string(e.pvp_kills));
v.push_back(columns[76] + " = " + std::to_string(e.pvp_deaths));
v.push_back(columns[77] + " = " + std::to_string(e.pvp_current_points));
v.push_back(columns[78] + " = " + std::to_string(e.pvp_career_points));
v.push_back(columns[79] + " = " + std::to_string(e.pvp_best_kill_streak));
v.push_back(columns[80] + " = " + std::to_string(e.pvp_worst_death_streak));
v.push_back(columns[81] + " = " + std::to_string(e.pvp_current_kill_streak));
v.push_back(columns[82] + " = " + std::to_string(e.pvp2));
v.push_back(columns[83] + " = " + std::to_string(e.pvp_type));
v.push_back(columns[84] + " = " + std::to_string(e.show_helm));
v.push_back(columns[85] + " = " + std::to_string(e.group_auto_consent));
v.push_back(columns[86] + " = " + std::to_string(e.raid_auto_consent));
v.push_back(columns[87] + " = " + std::to_string(e.guild_auto_consent));
v.push_back(columns[88] + " = " + std::to_string(e.leadership_exp_on));
v.push_back(columns[89] + " = " + std::to_string(e.RestTimer));
v.push_back(columns[90] + " = " + std::to_string(e.air_remaining));
v.push_back(columns[91] + " = " + std::to_string(e.autosplit_enabled));
v.push_back(columns[92] + " = " + std::to_string(e.lfp));
v.push_back(columns[93] + " = " + std::to_string(e.lfg));
v.push_back(columns[94] + " = '" + Strings::Escape(e.mailkey) + "'");
v.push_back(columns[95] + " = " + std::to_string(e.xtargets));
v.push_back(columns[96] + " = " + std::to_string(e.firstlogon));
v.push_back(columns[97] + " = " + std::to_string(e.e_aa_effects));
v.push_back(columns[98] + " = " + std::to_string(e.e_percent_to_aa));
v.push_back(columns[99] + " = " + std::to_string(e.e_expended_aa_spent));
v.push_back(columns[100] + " = " + std::to_string(e.aa_points_spent_old));
v.push_back(columns[101] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[102] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[103] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
v.push_back(columns[58] + " = " + std::to_string(e.zone_change_count));
v.push_back(columns[59] + " = " + std::to_string(e.toxicity));
v.push_back(columns[60] + " = " + std::to_string(e.hunger_level));
v.push_back(columns[61] + " = " + std::to_string(e.thirst_level));
v.push_back(columns[62] + " = " + std::to_string(e.ability_up));
v.push_back(columns[63] + " = " + std::to_string(e.ldon_points_guk));
v.push_back(columns[64] + " = " + std::to_string(e.ldon_points_mir));
v.push_back(columns[65] + " = " + std::to_string(e.ldon_points_mmc));
v.push_back(columns[66] + " = " + std::to_string(e.ldon_points_ruj));
v.push_back(columns[67] + " = " + std::to_string(e.ldon_points_tak));
v.push_back(columns[68] + " = " + std::to_string(e.ldon_points_available));
v.push_back(columns[69] + " = " + std::to_string(e.tribute_time_remaining));
v.push_back(columns[70] + " = " + std::to_string(e.career_tribute_points));
v.push_back(columns[71] + " = " + std::to_string(e.tribute_points));
v.push_back(columns[72] + " = " + std::to_string(e.tribute_active));
v.push_back(columns[73] + " = " + std::to_string(e.pvp_status));
v.push_back(columns[74] + " = " + std::to_string(e.pvp_kills));
v.push_back(columns[75] + " = " + std::to_string(e.pvp_deaths));
v.push_back(columns[76] + " = " + std::to_string(e.pvp_current_points));
v.push_back(columns[77] + " = " + std::to_string(e.pvp_career_points));
v.push_back(columns[78] + " = " + std::to_string(e.pvp_best_kill_streak));
v.push_back(columns[79] + " = " + std::to_string(e.pvp_worst_death_streak));
v.push_back(columns[80] + " = " + std::to_string(e.pvp_current_kill_streak));
v.push_back(columns[81] + " = " + std::to_string(e.pvp2));
v.push_back(columns[82] + " = " + std::to_string(e.pvp_type));
v.push_back(columns[83] + " = " + std::to_string(e.show_helm));
v.push_back(columns[84] + " = " + std::to_string(e.group_auto_consent));
v.push_back(columns[85] + " = " + std::to_string(e.raid_auto_consent));
v.push_back(columns[86] + " = " + std::to_string(e.guild_auto_consent));
v.push_back(columns[87] + " = " + std::to_string(e.leadership_exp_on));
v.push_back(columns[88] + " = " + std::to_string(e.RestTimer));
v.push_back(columns[89] + " = " + std::to_string(e.air_remaining));
v.push_back(columns[90] + " = " + std::to_string(e.autosplit_enabled));
v.push_back(columns[91] + " = " + std::to_string(e.lfp));
v.push_back(columns[92] + " = " + std::to_string(e.lfg));
v.push_back(columns[93] + " = '" + Strings::Escape(e.mailkey) + "'");
v.push_back(columns[94] + " = " + std::to_string(e.xtargets));
v.push_back(columns[95] + " = " + std::to_string(e.firstlogon));
v.push_back(columns[96] + " = " + std::to_string(e.e_aa_effects));
v.push_back(columns[97] + " = " + std::to_string(e.e_percent_to_aa));
v.push_back(columns[98] + " = " + std::to_string(e.e_expended_aa_spent));
v.push_back(columns[99] + " = " + std::to_string(e.aa_points_spent_old));
v.push_back(columns[100] + " = " + std::to_string(e.aa_points_old));
v.push_back(columns[101] + " = " + std::to_string(e.e_last_invsnapshot));
v.push_back(columns[102] + " = FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
@@ -846,7 +840,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.zone_change_count));
v.push_back(std::to_string(e.toxicity));
v.push_back(std::to_string(e.hunger_level));
@@ -979,7 +972,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.zone_change_count));
v.push_back(std::to_string(e.toxicity));
v.push_back(std::to_string(e.hunger_level));
@@ -1116,52 +1108,51 @@ public:
e.int_ = row[55] ? static_cast<uint32_t>(strtoul(row[55], nullptr, 10)) : 0;
e.agi = row[56] ? static_cast<uint32_t>(strtoul(row[56], nullptr, 10)) : 0;
e.wis = row[57] ? static_cast<uint32_t>(strtoul(row[57], nullptr, 10)) : 0;
e.extra_haste = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.zone_change_count = row[59] ? static_cast<uint32_t>(strtoul(row[59], nullptr, 10)) : 0;
e.toxicity = row[60] ? static_cast<uint32_t>(strtoul(row[60], nullptr, 10)) : 0;
e.hunger_level = row[61] ? static_cast<uint32_t>(strtoul(row[61], nullptr, 10)) : 0;
e.thirst_level = row[62] ? static_cast<uint32_t>(strtoul(row[62], nullptr, 10)) : 0;
e.ability_up = row[63] ? static_cast<uint32_t>(strtoul(row[63], nullptr, 10)) : 0;
e.ldon_points_guk = row[64] ? static_cast<uint32_t>(strtoul(row[64], nullptr, 10)) : 0;
e.ldon_points_mir = row[65] ? static_cast<uint32_t>(strtoul(row[65], nullptr, 10)) : 0;
e.ldon_points_mmc = row[66] ? static_cast<uint32_t>(strtoul(row[66], nullptr, 10)) : 0;
e.ldon_points_ruj = row[67] ? static_cast<uint32_t>(strtoul(row[67], nullptr, 10)) : 0;
e.ldon_points_tak = row[68] ? static_cast<uint32_t>(strtoul(row[68], nullptr, 10)) : 0;
e.ldon_points_available = row[69] ? static_cast<uint32_t>(strtoul(row[69], nullptr, 10)) : 0;
e.tribute_time_remaining = row[70] ? static_cast<uint32_t>(strtoul(row[70], nullptr, 10)) : 0;
e.career_tribute_points = row[71] ? static_cast<uint32_t>(strtoul(row[71], nullptr, 10)) : 0;
e.tribute_points = row[72] ? static_cast<uint32_t>(strtoul(row[72], nullptr, 10)) : 0;
e.tribute_active = row[73] ? static_cast<uint32_t>(strtoul(row[73], nullptr, 10)) : 0;
e.pvp_status = row[74] ? static_cast<uint8_t>(strtoul(row[74], nullptr, 10)) : 0;
e.pvp_kills = row[75] ? static_cast<uint32_t>(strtoul(row[75], nullptr, 10)) : 0;
e.pvp_deaths = row[76] ? static_cast<uint32_t>(strtoul(row[76], nullptr, 10)) : 0;
e.pvp_current_points = row[77] ? static_cast<uint32_t>(strtoul(row[77], nullptr, 10)) : 0;
e.pvp_career_points = row[78] ? static_cast<uint32_t>(strtoul(row[78], nullptr, 10)) : 0;
e.pvp_best_kill_streak = row[79] ? static_cast<uint32_t>(strtoul(row[79], nullptr, 10)) : 0;
e.pvp_worst_death_streak = row[80] ? static_cast<uint32_t>(strtoul(row[80], nullptr, 10)) : 0;
e.pvp_current_kill_streak = row[81] ? static_cast<uint32_t>(strtoul(row[81], nullptr, 10)) : 0;
e.pvp2 = row[82] ? static_cast<uint32_t>(strtoul(row[82], nullptr, 10)) : 0;
e.pvp_type = row[83] ? static_cast<uint32_t>(strtoul(row[83], nullptr, 10)) : 0;
e.show_helm = row[84] ? static_cast<uint32_t>(strtoul(row[84], nullptr, 10)) : 0;
e.group_auto_consent = row[85] ? static_cast<uint8_t>(strtoul(row[85], nullptr, 10)) : 0;
e.raid_auto_consent = row[86] ? static_cast<uint8_t>(strtoul(row[86], nullptr, 10)) : 0;
e.guild_auto_consent = row[87] ? static_cast<uint8_t>(strtoul(row[87], nullptr, 10)) : 0;
e.leadership_exp_on = row[88] ? static_cast<uint8_t>(strtoul(row[88], nullptr, 10)) : 0;
e.RestTimer = row[89] ? static_cast<uint32_t>(strtoul(row[89], nullptr, 10)) : 0;
e.air_remaining = row[90] ? static_cast<uint32_t>(strtoul(row[90], nullptr, 10)) : 0;
e.autosplit_enabled = row[91] ? static_cast<uint32_t>(strtoul(row[91], nullptr, 10)) : 0;
e.lfp = row[92] ? static_cast<uint8_t>(strtoul(row[92], nullptr, 10)) : 0;
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.firstlogon = row[96] ? static_cast<int8_t>(atoi(row[96])) : 0;
e.e_aa_effects = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_percent_to_aa = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_spent_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.zone_change_count = row[58] ? static_cast<uint32_t>(strtoul(row[58], nullptr, 10)) : 0;
e.toxicity = row[59] ? static_cast<uint32_t>(strtoul(row[59], nullptr, 10)) : 0;
e.hunger_level = row[60] ? static_cast<uint32_t>(strtoul(row[60], nullptr, 10)) : 0;
e.thirst_level = row[61] ? static_cast<uint32_t>(strtoul(row[61], nullptr, 10)) : 0;
e.ability_up = row[62] ? static_cast<uint32_t>(strtoul(row[62], nullptr, 10)) : 0;
e.ldon_points_guk = row[63] ? static_cast<uint32_t>(strtoul(row[63], nullptr, 10)) : 0;
e.ldon_points_mir = row[64] ? static_cast<uint32_t>(strtoul(row[64], nullptr, 10)) : 0;
e.ldon_points_mmc = row[65] ? static_cast<uint32_t>(strtoul(row[65], nullptr, 10)) : 0;
e.ldon_points_ruj = row[66] ? static_cast<uint32_t>(strtoul(row[66], nullptr, 10)) : 0;
e.ldon_points_tak = row[67] ? static_cast<uint32_t>(strtoul(row[67], nullptr, 10)) : 0;
e.ldon_points_available = row[68] ? static_cast<uint32_t>(strtoul(row[68], nullptr, 10)) : 0;
e.tribute_time_remaining = row[69] ? static_cast<uint32_t>(strtoul(row[69], nullptr, 10)) : 0;
e.career_tribute_points = row[70] ? static_cast<uint32_t>(strtoul(row[70], nullptr, 10)) : 0;
e.tribute_points = row[71] ? static_cast<uint32_t>(strtoul(row[71], nullptr, 10)) : 0;
e.tribute_active = row[72] ? static_cast<uint32_t>(strtoul(row[72], nullptr, 10)) : 0;
e.pvp_status = row[73] ? static_cast<uint8_t>(strtoul(row[73], nullptr, 10)) : 0;
e.pvp_kills = row[74] ? static_cast<uint32_t>(strtoul(row[74], nullptr, 10)) : 0;
e.pvp_deaths = row[75] ? static_cast<uint32_t>(strtoul(row[75], nullptr, 10)) : 0;
e.pvp_current_points = row[76] ? static_cast<uint32_t>(strtoul(row[76], nullptr, 10)) : 0;
e.pvp_career_points = row[77] ? static_cast<uint32_t>(strtoul(row[77], nullptr, 10)) : 0;
e.pvp_best_kill_streak = row[78] ? static_cast<uint32_t>(strtoul(row[78], nullptr, 10)) : 0;
e.pvp_worst_death_streak = row[79] ? static_cast<uint32_t>(strtoul(row[79], nullptr, 10)) : 0;
e.pvp_current_kill_streak = row[80] ? static_cast<uint32_t>(strtoul(row[80], nullptr, 10)) : 0;
e.pvp2 = row[81] ? static_cast<uint32_t>(strtoul(row[81], nullptr, 10)) : 0;
e.pvp_type = row[82] ? static_cast<uint32_t>(strtoul(row[82], nullptr, 10)) : 0;
e.show_helm = row[83] ? static_cast<uint32_t>(strtoul(row[83], nullptr, 10)) : 0;
e.group_auto_consent = row[84] ? static_cast<uint8_t>(strtoul(row[84], nullptr, 10)) : 0;
e.raid_auto_consent = row[85] ? static_cast<uint8_t>(strtoul(row[85], nullptr, 10)) : 0;
e.guild_auto_consent = row[86] ? static_cast<uint8_t>(strtoul(row[86], nullptr, 10)) : 0;
e.leadership_exp_on = row[87] ? static_cast<uint8_t>(strtoul(row[87], nullptr, 10)) : 0;
e.RestTimer = row[88] ? static_cast<uint32_t>(strtoul(row[88], nullptr, 10)) : 0;
e.air_remaining = row[89] ? static_cast<uint32_t>(strtoul(row[89], nullptr, 10)) : 0;
e.autosplit_enabled = row[90] ? static_cast<uint32_t>(strtoul(row[90], nullptr, 10)) : 0;
e.lfp = row[91] ? static_cast<uint8_t>(strtoul(row[91], nullptr, 10)) : 0;
e.lfg = row[92] ? static_cast<uint8_t>(strtoul(row[92], nullptr, 10)) : 0;
e.mailkey = row[93] ? row[93] : "";
e.xtargets = row[94] ? static_cast<uint8_t>(strtoul(row[94], nullptr, 10)) : 5;
e.firstlogon = row[95] ? static_cast<int8_t>(atoi(row[95])) : 0;
e.e_aa_effects = row[96] ? static_cast<uint32_t>(strtoul(row[96], nullptr, 10)) : 0;
e.e_percent_to_aa = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.aa_points_spent_old = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[102] ? row[102] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@@ -1244,52 +1235,51 @@ public:
e.int_ = row[55] ? static_cast<uint32_t>(strtoul(row[55], nullptr, 10)) : 0;
e.agi = row[56] ? static_cast<uint32_t>(strtoul(row[56], nullptr, 10)) : 0;
e.wis = row[57] ? static_cast<uint32_t>(strtoul(row[57], nullptr, 10)) : 0;
e.extra_haste = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
e.zone_change_count = row[59] ? static_cast<uint32_t>(strtoul(row[59], nullptr, 10)) : 0;
e.toxicity = row[60] ? static_cast<uint32_t>(strtoul(row[60], nullptr, 10)) : 0;
e.hunger_level = row[61] ? static_cast<uint32_t>(strtoul(row[61], nullptr, 10)) : 0;
e.thirst_level = row[62] ? static_cast<uint32_t>(strtoul(row[62], nullptr, 10)) : 0;
e.ability_up = row[63] ? static_cast<uint32_t>(strtoul(row[63], nullptr, 10)) : 0;
e.ldon_points_guk = row[64] ? static_cast<uint32_t>(strtoul(row[64], nullptr, 10)) : 0;
e.ldon_points_mir = row[65] ? static_cast<uint32_t>(strtoul(row[65], nullptr, 10)) : 0;
e.ldon_points_mmc = row[66] ? static_cast<uint32_t>(strtoul(row[66], nullptr, 10)) : 0;
e.ldon_points_ruj = row[67] ? static_cast<uint32_t>(strtoul(row[67], nullptr, 10)) : 0;
e.ldon_points_tak = row[68] ? static_cast<uint32_t>(strtoul(row[68], nullptr, 10)) : 0;
e.ldon_points_available = row[69] ? static_cast<uint32_t>(strtoul(row[69], nullptr, 10)) : 0;
e.tribute_time_remaining = row[70] ? static_cast<uint32_t>(strtoul(row[70], nullptr, 10)) : 0;
e.career_tribute_points = row[71] ? static_cast<uint32_t>(strtoul(row[71], nullptr, 10)) : 0;
e.tribute_points = row[72] ? static_cast<uint32_t>(strtoul(row[72], nullptr, 10)) : 0;
e.tribute_active = row[73] ? static_cast<uint32_t>(strtoul(row[73], nullptr, 10)) : 0;
e.pvp_status = row[74] ? static_cast<uint8_t>(strtoul(row[74], nullptr, 10)) : 0;
e.pvp_kills = row[75] ? static_cast<uint32_t>(strtoul(row[75], nullptr, 10)) : 0;
e.pvp_deaths = row[76] ? static_cast<uint32_t>(strtoul(row[76], nullptr, 10)) : 0;
e.pvp_current_points = row[77] ? static_cast<uint32_t>(strtoul(row[77], nullptr, 10)) : 0;
e.pvp_career_points = row[78] ? static_cast<uint32_t>(strtoul(row[78], nullptr, 10)) : 0;
e.pvp_best_kill_streak = row[79] ? static_cast<uint32_t>(strtoul(row[79], nullptr, 10)) : 0;
e.pvp_worst_death_streak = row[80] ? static_cast<uint32_t>(strtoul(row[80], nullptr, 10)) : 0;
e.pvp_current_kill_streak = row[81] ? static_cast<uint32_t>(strtoul(row[81], nullptr, 10)) : 0;
e.pvp2 = row[82] ? static_cast<uint32_t>(strtoul(row[82], nullptr, 10)) : 0;
e.pvp_type = row[83] ? static_cast<uint32_t>(strtoul(row[83], nullptr, 10)) : 0;
e.show_helm = row[84] ? static_cast<uint32_t>(strtoul(row[84], nullptr, 10)) : 0;
e.group_auto_consent = row[85] ? static_cast<uint8_t>(strtoul(row[85], nullptr, 10)) : 0;
e.raid_auto_consent = row[86] ? static_cast<uint8_t>(strtoul(row[86], nullptr, 10)) : 0;
e.guild_auto_consent = row[87] ? static_cast<uint8_t>(strtoul(row[87], nullptr, 10)) : 0;
e.leadership_exp_on = row[88] ? static_cast<uint8_t>(strtoul(row[88], nullptr, 10)) : 0;
e.RestTimer = row[89] ? static_cast<uint32_t>(strtoul(row[89], nullptr, 10)) : 0;
e.air_remaining = row[90] ? static_cast<uint32_t>(strtoul(row[90], nullptr, 10)) : 0;
e.autosplit_enabled = row[91] ? static_cast<uint32_t>(strtoul(row[91], nullptr, 10)) : 0;
e.lfp = row[92] ? static_cast<uint8_t>(strtoul(row[92], nullptr, 10)) : 0;
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.firstlogon = row[96] ? static_cast<int8_t>(atoi(row[96])) : 0;
e.e_aa_effects = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_percent_to_aa = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_spent_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.aa_points_old = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[102] ? static_cast<uint32_t>(strtoul(row[102], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[103] ? row[103] : "-1", nullptr, 10);
e.zone_change_count = row[58] ? static_cast<uint32_t>(strtoul(row[58], nullptr, 10)) : 0;
e.toxicity = row[59] ? static_cast<uint32_t>(strtoul(row[59], nullptr, 10)) : 0;
e.hunger_level = row[60] ? static_cast<uint32_t>(strtoul(row[60], nullptr, 10)) : 0;
e.thirst_level = row[61] ? static_cast<uint32_t>(strtoul(row[61], nullptr, 10)) : 0;
e.ability_up = row[62] ? static_cast<uint32_t>(strtoul(row[62], nullptr, 10)) : 0;
e.ldon_points_guk = row[63] ? static_cast<uint32_t>(strtoul(row[63], nullptr, 10)) : 0;
e.ldon_points_mir = row[64] ? static_cast<uint32_t>(strtoul(row[64], nullptr, 10)) : 0;
e.ldon_points_mmc = row[65] ? static_cast<uint32_t>(strtoul(row[65], nullptr, 10)) : 0;
e.ldon_points_ruj = row[66] ? static_cast<uint32_t>(strtoul(row[66], nullptr, 10)) : 0;
e.ldon_points_tak = row[67] ? static_cast<uint32_t>(strtoul(row[67], nullptr, 10)) : 0;
e.ldon_points_available = row[68] ? static_cast<uint32_t>(strtoul(row[68], nullptr, 10)) : 0;
e.tribute_time_remaining = row[69] ? static_cast<uint32_t>(strtoul(row[69], nullptr, 10)) : 0;
e.career_tribute_points = row[70] ? static_cast<uint32_t>(strtoul(row[70], nullptr, 10)) : 0;
e.tribute_points = row[71] ? static_cast<uint32_t>(strtoul(row[71], nullptr, 10)) : 0;
e.tribute_active = row[72] ? static_cast<uint32_t>(strtoul(row[72], nullptr, 10)) : 0;
e.pvp_status = row[73] ? static_cast<uint8_t>(strtoul(row[73], nullptr, 10)) : 0;
e.pvp_kills = row[74] ? static_cast<uint32_t>(strtoul(row[74], nullptr, 10)) : 0;
e.pvp_deaths = row[75] ? static_cast<uint32_t>(strtoul(row[75], nullptr, 10)) : 0;
e.pvp_current_points = row[76] ? static_cast<uint32_t>(strtoul(row[76], nullptr, 10)) : 0;
e.pvp_career_points = row[77] ? static_cast<uint32_t>(strtoul(row[77], nullptr, 10)) : 0;
e.pvp_best_kill_streak = row[78] ? static_cast<uint32_t>(strtoul(row[78], nullptr, 10)) : 0;
e.pvp_worst_death_streak = row[79] ? static_cast<uint32_t>(strtoul(row[79], nullptr, 10)) : 0;
e.pvp_current_kill_streak = row[80] ? static_cast<uint32_t>(strtoul(row[80], nullptr, 10)) : 0;
e.pvp2 = row[81] ? static_cast<uint32_t>(strtoul(row[81], nullptr, 10)) : 0;
e.pvp_type = row[82] ? static_cast<uint32_t>(strtoul(row[82], nullptr, 10)) : 0;
e.show_helm = row[83] ? static_cast<uint32_t>(strtoul(row[83], nullptr, 10)) : 0;
e.group_auto_consent = row[84] ? static_cast<uint8_t>(strtoul(row[84], nullptr, 10)) : 0;
e.raid_auto_consent = row[85] ? static_cast<uint8_t>(strtoul(row[85], nullptr, 10)) : 0;
e.guild_auto_consent = row[86] ? static_cast<uint8_t>(strtoul(row[86], nullptr, 10)) : 0;
e.leadership_exp_on = row[87] ? static_cast<uint8_t>(strtoul(row[87], nullptr, 10)) : 0;
e.RestTimer = row[88] ? static_cast<uint32_t>(strtoul(row[88], nullptr, 10)) : 0;
e.air_remaining = row[89] ? static_cast<uint32_t>(strtoul(row[89], nullptr, 10)) : 0;
e.autosplit_enabled = row[90] ? static_cast<uint32_t>(strtoul(row[90], nullptr, 10)) : 0;
e.lfp = row[91] ? static_cast<uint8_t>(strtoul(row[91], nullptr, 10)) : 0;
e.lfg = row[92] ? static_cast<uint8_t>(strtoul(row[92], nullptr, 10)) : 0;
e.mailkey = row[93] ? row[93] : "";
e.xtargets = row[94] ? static_cast<uint8_t>(strtoul(row[94], nullptr, 10)) : 5;
e.firstlogon = row[95] ? static_cast<int8_t>(atoi(row[95])) : 0;
e.e_aa_effects = row[96] ? static_cast<uint32_t>(strtoul(row[96], nullptr, 10)) : 0;
e.e_percent_to_aa = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.aa_points_spent_old = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.aa_points_old = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
e.e_last_invsnapshot = row[101] ? static_cast<uint32_t>(strtoul(row[101], nullptr, 10)) : 0;
e.deleted_at = strtoll(row[102] ? row[102] : "-1", nullptr, 10);
all_entries.push_back(e);
}
@@ -1422,7 +1412,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.zone_change_count));
v.push_back(std::to_string(e.toxicity));
v.push_back(std::to_string(e.hunger_level));
@@ -1548,7 +1537,6 @@ public:
v.push_back(std::to_string(e.int_));
v.push_back(std::to_string(e.agi));
v.push_back(std::to_string(e.wis));
v.push_back(std::to_string(e.extra_haste));
v.push_back(std::to_string(e.zone_change_count));
v.push_back(std::to_string(e.toxicity));
v.push_back(std::to_string(e.hunger_level));
@@ -1,499 +0,0 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_CHARACTER_PARCELS_CONTAINERS_REPOSITORY_H
#define EQEMU_BASE_CHARACTER_PARCELS_CONTAINERS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseCharacterParcelsContainersRepository {
public:
struct CharacterParcelsContainers {
uint32_t id;
uint32_t parcels_id;
uint32_t slot_id;
uint32_t item_id;
uint32_t aug_slot_1;
uint32_t aug_slot_2;
uint32_t aug_slot_3;
uint32_t aug_slot_4;
uint32_t aug_slot_5;
uint32_t aug_slot_6;
uint32_t quantity;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"parcels_id",
"slot_id",
"item_id",
"aug_slot_1",
"aug_slot_2",
"aug_slot_3",
"aug_slot_4",
"aug_slot_5",
"aug_slot_6",
"quantity",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"parcels_id",
"slot_id",
"item_id",
"aug_slot_1",
"aug_slot_2",
"aug_slot_3",
"aug_slot_4",
"aug_slot_5",
"aug_slot_6",
"quantity",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_parcels_containers");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static CharacterParcelsContainers NewEntity()
{
CharacterParcelsContainers e{};
e.id = 0;
e.parcels_id = 0;
e.slot_id = 0;
e.item_id = 0;
e.aug_slot_1 = 0;
e.aug_slot_2 = 0;
e.aug_slot_3 = 0;
e.aug_slot_4 = 0;
e.aug_slot_5 = 0;
e.aug_slot_6 = 0;
e.quantity = 0;
return e;
}
static CharacterParcelsContainers GetCharacterParcelsContainers(
const std::vector<CharacterParcelsContainers> &character_parcels_containerss,
int character_parcels_containers_id
)
{
for (auto &character_parcels_containers : character_parcels_containerss) {
if (character_parcels_containers.id == character_parcels_containers_id) {
return character_parcels_containers;
}
}
return NewEntity();
}
static CharacterParcelsContainers FindOne(
Database& db,
int character_parcels_containers_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
character_parcels_containers_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
CharacterParcelsContainers e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int character_parcels_containers_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
character_parcels_containers_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const CharacterParcelsContainers &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.parcels_id));
v.push_back(columns[2] + " = " + std::to_string(e.slot_id));
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
v.push_back(columns[4] + " = " + std::to_string(e.aug_slot_1));
v.push_back(columns[5] + " = " + std::to_string(e.aug_slot_2));
v.push_back(columns[6] + " = " + std::to_string(e.aug_slot_3));
v.push_back(columns[7] + " = " + std::to_string(e.aug_slot_4));
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_5));
v.push_back(columns[9] + " = " + std::to_string(e.aug_slot_6));
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static CharacterParcelsContainers InsertOne(
Database& db,
CharacterParcelsContainers e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.parcels_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<CharacterParcelsContainers> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.parcels_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<CharacterParcelsContainers> All(Database& db)
{
std::vector<CharacterParcelsContainers> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcelsContainers e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CharacterParcelsContainers> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CharacterParcelsContainers> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcelsContainers e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.parcels_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.slot_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.item_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_1 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_2 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_3 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_4 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_5 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.aug_slot_6 = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const CharacterParcelsContainers &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.parcels_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity));
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<CharacterParcelsContainers> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.parcels_id));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.quantity));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_CHARACTER_PARCELS_CONTAINERS_REPOSITORY_H
@@ -1,535 +0,0 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://docs.eqemu.io/developer/repositories
*/
#ifndef EQEMU_BASE_CHARACTER_PARCELS_REPOSITORY_H
#define EQEMU_BASE_CHARACTER_PARCELS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseCharacterParcelsRepository {
public:
struct CharacterParcels {
uint32_t id;
uint32_t char_id;
uint32_t item_id;
uint32_t aug_slot_1;
uint32_t aug_slot_2;
uint32_t aug_slot_3;
uint32_t aug_slot_4;
uint32_t aug_slot_5;
uint32_t aug_slot_6;
uint32_t slot_id;
uint32_t quantity;
std::string from_name;
std::string note;
time_t sent_date;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"char_id",
"item_id",
"aug_slot_1",
"aug_slot_2",
"aug_slot_3",
"aug_slot_4",
"aug_slot_5",
"aug_slot_6",
"slot_id",
"quantity",
"from_name",
"note",
"sent_date",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"char_id",
"item_id",
"aug_slot_1",
"aug_slot_2",
"aug_slot_3",
"aug_slot_4",
"aug_slot_5",
"aug_slot_6",
"slot_id",
"quantity",
"from_name",
"note",
"UNIX_TIMESTAMP(sent_date)",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("character_parcels");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static CharacterParcels NewEntity()
{
CharacterParcels e{};
e.id = 0;
e.char_id = 0;
e.item_id = 0;
e.aug_slot_1 = 0;
e.aug_slot_2 = 0;
e.aug_slot_3 = 0;
e.aug_slot_4 = 0;
e.aug_slot_5 = 0;
e.aug_slot_6 = 0;
e.slot_id = 0;
e.quantity = 0;
e.from_name = "";
e.note = "";
e.sent_date = 0;
return e;
}
static CharacterParcels GetCharacterParcels(
const std::vector<CharacterParcels> &character_parcelss,
int character_parcels_id
)
{
for (auto &character_parcels : character_parcelss) {
if (character_parcels.id == character_parcels_id) {
return character_parcels;
}
}
return NewEntity();
}
static CharacterParcels FindOne(
Database& db,
int character_parcels_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
character_parcels_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
CharacterParcels e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.from_name = row[11] ? row[11] : "";
e.note = row[12] ? row[12] : "";
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int character_parcels_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
character_parcels_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const CharacterParcels &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.char_id));
v.push_back(columns[2] + " = " + std::to_string(e.item_id));
v.push_back(columns[3] + " = " + std::to_string(e.aug_slot_1));
v.push_back(columns[4] + " = " + std::to_string(e.aug_slot_2));
v.push_back(columns[5] + " = " + std::to_string(e.aug_slot_3));
v.push_back(columns[6] + " = " + std::to_string(e.aug_slot_4));
v.push_back(columns[7] + " = " + std::to_string(e.aug_slot_5));
v.push_back(columns[8] + " = " + std::to_string(e.aug_slot_6));
v.push_back(columns[9] + " = " + std::to_string(e.slot_id));
v.push_back(columns[10] + " = " + std::to_string(e.quantity));
v.push_back(columns[11] + " = '" + Strings::Escape(e.from_name) + "'");
v.push_back(columns[12] + " = '" + Strings::Escape(e.note) + "'");
v.push_back(columns[13] + " = FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static CharacterParcels InsertOne(
Database& db,
CharacterParcels e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<CharacterParcels> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<CharacterParcels> All(Database& db)
{
std::vector<CharacterParcels> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcels e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.from_name = row[11] ? row[11] : "";
e.note = row[12] ? row[12] : "";
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<CharacterParcels> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<CharacterParcels> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterParcels e{};
e.id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.char_id = row[1] ? static_cast<uint32_t>(strtoul(row[1], nullptr, 10)) : 0;
e.item_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.aug_slot_1 = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.aug_slot_2 = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.aug_slot_3 = row[5] ? static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) : 0;
e.aug_slot_4 = row[6] ? static_cast<uint32_t>(strtoul(row[6], nullptr, 10)) : 0;
e.aug_slot_5 = row[7] ? static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) : 0;
e.aug_slot_6 = row[8] ? static_cast<uint32_t>(strtoul(row[8], nullptr, 10)) : 0;
e.slot_id = row[9] ? static_cast<uint32_t>(strtoul(row[9], nullptr, 10)) : 0;
e.quantity = row[10] ? static_cast<uint32_t>(strtoul(row[10], nullptr, 10)) : 0;
e.from_name = row[11] ? row[11] : "";
e.note = row[12] ? row[12] : "";
e.sent_date = strtoll(row[13] ? row[13] : "-1", nullptr, 10);
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static std::string BaseReplace()
{
return fmt::format(
"REPLACE INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static int ReplaceOne(
Database& db,
const CharacterParcels &e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseReplace(),
Strings::Implode(",", v)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int ReplaceMany(
Database& db,
const std::vector<CharacterParcels> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.char_id));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.aug_slot_1));
v.push_back(std::to_string(e.aug_slot_2));
v.push_back(std::to_string(e.aug_slot_3));
v.push_back(std::to_string(e.aug_slot_4));
v.push_back(std::to_string(e.aug_slot_5));
v.push_back(std::to_string(e.aug_slot_6));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.quantity));
v.push_back("'" + Strings::Escape(e.from_name) + "'");
v.push_back("'" + Strings::Escape(e.note) + "'");
v.push_back("FROM_UNIXTIME(" + (e.sent_date > 0 ? std::to_string(e.sent_date) : "null") + ")");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseReplace(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
};
#endif //EQEMU_BASE_CHARACTER_PARCELS_REPOSITORY_H
@@ -50,7 +50,6 @@ public:
float buffer;
uint32_t client_version_mask;
int16_t is_ldon_door;
int16_t close_timer_ms;
int32_t dz_switch_id;
int8_t min_expansion;
int8_t max_expansion;
@@ -97,7 +96,6 @@ public:
"buffer",
"client_version_mask",
"is_ldon_door",
"close_timer_ms",
"dz_switch_id",
"min_expansion",
"max_expansion",
@@ -140,7 +138,6 @@ public:
"buffer",
"client_version_mask",
"is_ldon_door",
"close_timer_ms",
"dz_switch_id",
"min_expansion",
"max_expansion",
@@ -217,7 +214,6 @@ public:
e.buffer = 0;
e.client_version_mask = 4294967295;
e.is_ldon_door = 0;
e.close_timer_ms = 5000;
e.dz_switch_id = 0;
e.min_expansion = -1;
e.max_expansion = -1;
@@ -290,12 +286,11 @@ public:
e.buffer = row[28] ? strtof(row[28], nullptr) : 0;
e.client_version_mask = row[29] ? static_cast<uint32_t>(strtoul(row[29], nullptr, 10)) : 4294967295;
e.is_ldon_door = row[30] ? static_cast<int16_t>(atoi(row[30])) : 0;
e.close_timer_ms = row[31] ? static_cast<int16_t>(atoi(row[31])) : 5000;
e.dz_switch_id = row[32] ? static_cast<int32_t>(atoi(row[32])) : 0;
e.min_expansion = row[33] ? static_cast<int8_t>(atoi(row[33])) : -1;
e.max_expansion = row[34] ? static_cast<int8_t>(atoi(row[34])) : -1;
e.content_flags = row[35] ? row[35] : "";
e.content_flags_disabled = row[36] ? row[36] : "";
e.dz_switch_id = row[31] ? static_cast<int32_t>(atoi(row[31])) : 0;
e.min_expansion = row[32] ? static_cast<int8_t>(atoi(row[32])) : -1;
e.max_expansion = row[33] ? static_cast<int8_t>(atoi(row[33])) : -1;
e.content_flags = row[34] ? row[34] : "";
e.content_flags_disabled = row[35] ? row[35] : "";
return e;
}
@@ -359,12 +354,11 @@ public:
v.push_back(columns[28] + " = " + std::to_string(e.buffer));
v.push_back(columns[29] + " = " + std::to_string(e.client_version_mask));
v.push_back(columns[30] + " = " + std::to_string(e.is_ldon_door));
v.push_back(columns[31] + " = " + std::to_string(e.close_timer_ms));
v.push_back(columns[32] + " = " + std::to_string(e.dz_switch_id));
v.push_back(columns[33] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[34] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[35] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[36] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
v.push_back(columns[31] + " = " + std::to_string(e.dz_switch_id));
v.push_back(columns[32] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[33] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[34] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[35] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
auto results = db.QueryDatabase(
fmt::format(
@@ -417,7 +411,6 @@ public:
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.is_ldon_door));
v.push_back(std::to_string(e.close_timer_ms));
v.push_back(std::to_string(e.dz_switch_id));
v.push_back(std::to_string(e.min_expansion));
v.push_back(std::to_string(e.max_expansion));
@@ -483,7 +476,6 @@ public:
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.is_ldon_door));
v.push_back(std::to_string(e.close_timer_ms));
v.push_back(std::to_string(e.dz_switch_id));
v.push_back(std::to_string(e.min_expansion));
v.push_back(std::to_string(e.max_expansion));
@@ -553,12 +545,11 @@ public:
e.buffer = row[28] ? strtof(row[28], nullptr) : 0;
e.client_version_mask = row[29] ? static_cast<uint32_t>(strtoul(row[29], nullptr, 10)) : 4294967295;
e.is_ldon_door = row[30] ? static_cast<int16_t>(atoi(row[30])) : 0;
e.close_timer_ms = row[31] ? static_cast<int16_t>(atoi(row[31])) : 5000;
e.dz_switch_id = row[32] ? static_cast<int32_t>(atoi(row[32])) : 0;
e.min_expansion = row[33] ? static_cast<int8_t>(atoi(row[33])) : -1;
e.max_expansion = row[34] ? static_cast<int8_t>(atoi(row[34])) : -1;
e.content_flags = row[35] ? row[35] : "";
e.content_flags_disabled = row[36] ? row[36] : "";
e.dz_switch_id = row[31] ? static_cast<int32_t>(atoi(row[31])) : 0;
e.min_expansion = row[32] ? static_cast<int8_t>(atoi(row[32])) : -1;
e.max_expansion = row[33] ? static_cast<int8_t>(atoi(row[33])) : -1;
e.content_flags = row[34] ? row[34] : "";
e.content_flags_disabled = row[35] ? row[35] : "";
all_entries.push_back(e);
}
@@ -614,12 +605,11 @@ public:
e.buffer = row[28] ? strtof(row[28], nullptr) : 0;
e.client_version_mask = row[29] ? static_cast<uint32_t>(strtoul(row[29], nullptr, 10)) : 4294967295;
e.is_ldon_door = row[30] ? static_cast<int16_t>(atoi(row[30])) : 0;
e.close_timer_ms = row[31] ? static_cast<int16_t>(atoi(row[31])) : 5000;
e.dz_switch_id = row[32] ? static_cast<int32_t>(atoi(row[32])) : 0;
e.min_expansion = row[33] ? static_cast<int8_t>(atoi(row[33])) : -1;
e.max_expansion = row[34] ? static_cast<int8_t>(atoi(row[34])) : -1;
e.content_flags = row[35] ? row[35] : "";
e.content_flags_disabled = row[36] ? row[36] : "";
e.dz_switch_id = row[31] ? static_cast<int32_t>(atoi(row[31])) : 0;
e.min_expansion = row[32] ? static_cast<int8_t>(atoi(row[32])) : -1;
e.max_expansion = row[33] ? static_cast<int8_t>(atoi(row[33])) : -1;
e.content_flags = row[34] ? row[34] : "";
e.content_flags_disabled = row[35] ? row[35] : "";
all_entries.push_back(e);
}
@@ -725,7 +715,6 @@ public:
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.is_ldon_door));
v.push_back(std::to_string(e.close_timer_ms));
v.push_back(std::to_string(e.dz_switch_id));
v.push_back(std::to_string(e.min_expansion));
v.push_back(std::to_string(e.max_expansion));
@@ -784,7 +773,6 @@ public:
v.push_back(std::to_string(e.buffer));
v.push_back(std::to_string(e.client_version_mask));
v.push_back(std::to_string(e.is_ldon_door));
v.push_back(std::to_string(e.close_timer_ms));
v.push_back(std::to_string(e.dz_switch_id));
v.push_back(std::to_string(e.min_expansion));
v.push_back(std::to_string(e.max_expansion));
@@ -19,37 +19,34 @@
class BaseGroupIdRepository {
public:
struct GroupId {
uint32_t group_id;
int32_t groupid;
int32_t charid;
std::string name;
uint32_t character_id;
uint32_t bot_id;
uint32_t merc_id;
int8_t ismerc;
};
static std::string PrimaryKey()
{
return std::string("group_id");
return std::string("groupid");
}
static std::vector<std::string> Columns()
{
return {
"group_id",
"groupid",
"charid",
"name",
"character_id",
"bot_id",
"merc_id",
"ismerc",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"group_id",
"groupid",
"charid",
"name",
"character_id",
"bot_id",
"merc_id",
"ismerc",
};
}
@@ -90,11 +87,10 @@ public:
{
GroupId e{};
e.group_id = 0;
e.name = "";
e.character_id = 0;
e.bot_id = 0;
e.merc_id = 0;
e.groupid = 0;
e.charid = 0;
e.name = "";
e.ismerc = 0;
return e;
}
@@ -105,7 +101,7 @@ public:
)
{
for (auto &group_id : group_ids) {
if (group_id.group_id == group_id_id) {
if (group_id.groupid == group_id_id) {
return group_id;
}
}
@@ -131,11 +127,10 @@ public:
if (results.RowCount() == 1) {
GroupId e{};
e.group_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.name = row[1] ? row[1] : "";
e.character_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.bot_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.merc_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.groupid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.charid = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.name = row[2] ? row[2] : "";
e.ismerc = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
return e;
}
@@ -169,11 +164,10 @@ public:
auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.group_id));
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[2] + " = " + std::to_string(e.character_id));
v.push_back(columns[3] + " = " + std::to_string(e.bot_id));
v.push_back(columns[4] + " = " + std::to_string(e.merc_id));
v.push_back(columns[0] + " = " + std::to_string(e.groupid));
v.push_back(columns[1] + " = " + std::to_string(e.charid));
v.push_back(columns[2] + " = '" + Strings::Escape(e.name) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.ismerc));
auto results = db.QueryDatabase(
fmt::format(
@@ -181,7 +175,7 @@ public:
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.group_id
e.groupid
)
);
@@ -195,11 +189,10 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.group_id));
v.push_back(std::to_string(e.groupid));
v.push_back(std::to_string(e.charid));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.merc_id));
v.push_back(std::to_string(e.ismerc));
auto results = db.QueryDatabase(
fmt::format(
@@ -210,7 +203,7 @@ public:
);
if (results.Success()) {
e.group_id = results.LastInsertedID();
e.groupid = results.LastInsertedID();
return e;
}
@@ -229,11 +222,10 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.group_id));
v.push_back(std::to_string(e.groupid));
v.push_back(std::to_string(e.charid));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.merc_id));
v.push_back(std::to_string(e.ismerc));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -267,11 +259,10 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
GroupId e{};
e.group_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.name = row[1] ? row[1] : "";
e.character_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.bot_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.merc_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.groupid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.charid = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.name = row[2] ? row[2] : "";
e.ismerc = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
all_entries.push_back(e);
}
@@ -296,11 +287,10 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
GroupId e{};
e.group_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.name = row[1] ? row[1] : "";
e.character_id = row[2] ? static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) : 0;
e.bot_id = row[3] ? static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) : 0;
e.merc_id = row[4] ? static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) : 0;
e.groupid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.charid = row[1] ? static_cast<int32_t>(atoi(row[1])) : 0;
e.name = row[2] ? row[2] : "";
e.ismerc = row[3] ? static_cast<int8_t>(atoi(row[3])) : 0;
all_entries.push_back(e);
}
@@ -375,11 +365,10 @@ public:
{
std::vector<std::string> v;
v.push_back(std::to_string(e.group_id));
v.push_back(std::to_string(e.groupid));
v.push_back(std::to_string(e.charid));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.merc_id));
v.push_back(std::to_string(e.ismerc));
auto results = db.QueryDatabase(
fmt::format(
@@ -402,11 +391,10 @@ public:
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.group_id));
v.push_back(std::to_string(e.groupid));
v.push_back(std::to_string(e.charid));
v.push_back("'" + Strings::Escape(e.name) + "'");
v.push_back(std::to_string(e.character_id));
v.push_back(std::to_string(e.bot_id));
v.push_back(std::to_string(e.merc_id));
v.push_back(std::to_string(e.ismerc));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -105,7 +105,7 @@ public:
e.gid = 0;
e.leadername = "";
e.marknpc = "";
e.leadershipaa = "";
e.leadershipaa = 0;
e.maintank = "";
e.assist = "";
e.puller = "";
@@ -150,7 +150,7 @@ public:
e.gid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.leadername = row[1] ? row[1] : "";
e.marknpc = row[2] ? row[2] : "";
e.leadershipaa = row[3] ? row[3] : "";
e.leadershipaa = row[3] ? row[3] : 0;
e.maintank = row[4] ? row[4] : "";
e.assist = row[5] ? row[5] : "";
e.puller = row[6] ? row[6] : "";
@@ -192,7 +192,7 @@ public:
v.push_back(columns[0] + " = " + std::to_string(e.gid));
v.push_back(columns[1] + " = '" + Strings::Escape(e.leadername) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.marknpc) + "'");
v.push_back(columns[3] + " = '" + e.leadershipaa + "'");
v.push_back(columns[3] + " = '" + Strings::Escape(e.leadershipaa) + "'");
v.push_back(columns[4] + " = '" + Strings::Escape(e.maintank) + "'");
v.push_back(columns[5] + " = '" + Strings::Escape(e.assist) + "'");
v.push_back(columns[6] + " = '" + Strings::Escape(e.puller) + "'");
@@ -222,7 +222,7 @@ public:
v.push_back(std::to_string(e.gid));
v.push_back("'" + Strings::Escape(e.leadername) + "'");
v.push_back("'" + Strings::Escape(e.marknpc) + "'");
v.push_back("'" + e.leadershipaa + "'");
v.push_back("'" + Strings::Escape(e.leadershipaa) + "'");
v.push_back("'" + Strings::Escape(e.maintank) + "'");
v.push_back("'" + Strings::Escape(e.assist) + "'");
v.push_back("'" + Strings::Escape(e.puller) + "'");
@@ -260,7 +260,7 @@ public:
v.push_back(std::to_string(e.gid));
v.push_back("'" + Strings::Escape(e.leadername) + "'");
v.push_back("'" + Strings::Escape(e.marknpc) + "'");
v.push_back("'" + e.leadershipaa + "'");
v.push_back("'" + Strings::Escape(e.leadershipaa) + "'");
v.push_back("'" + Strings::Escape(e.maintank) + "'");
v.push_back("'" + Strings::Escape(e.assist) + "'");
v.push_back("'" + Strings::Escape(e.puller) + "'");
@@ -302,7 +302,7 @@ public:
e.gid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.leadername = row[1] ? row[1] : "";
e.marknpc = row[2] ? row[2] : "";
e.leadershipaa = row[3] ? row[3] : "";
e.leadershipaa = row[3] ? row[3] : 0;
e.maintank = row[4] ? row[4] : "";
e.assist = row[5] ? row[5] : "";
e.puller = row[6] ? row[6] : "";
@@ -335,7 +335,7 @@ public:
e.gid = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.leadername = row[1] ? row[1] : "";
e.marknpc = row[2] ? row[2] : "";
e.leadershipaa = row[3] ? row[3] : "";
e.leadershipaa = row[3] ? row[3] : 0;
e.maintank = row[4] ? row[4] : "";
e.assist = row[5] ? row[5] : "";
e.puller = row[6] ? row[6] : "";
@@ -418,7 +418,7 @@ public:
v.push_back(std::to_string(e.gid));
v.push_back("'" + Strings::Escape(e.leadername) + "'");
v.push_back("'" + Strings::Escape(e.marknpc) + "'");
v.push_back("'" + e.leadershipaa + "'");
v.push_back("'" + Strings::Escape(e.leadershipaa) + "'");
v.push_back("'" + Strings::Escape(e.maintank) + "'");
v.push_back("'" + Strings::Escape(e.assist) + "'");
v.push_back("'" + Strings::Escape(e.puller) + "'");
@@ -449,7 +449,7 @@ public:
v.push_back(std::to_string(e.gid));
v.push_back("'" + Strings::Escape(e.leadername) + "'");
v.push_back("'" + Strings::Escape(e.marknpc) + "'");
v.push_back("'" + e.leadershipaa + "'");
v.push_back("'" + Strings::Escape(e.leadershipaa) + "'");
v.push_back("'" + Strings::Escape(e.maintank) + "'");
v.push_back("'" + Strings::Escape(e.assist) + "'");
v.push_back("'" + Strings::Escape(e.puller) + "'");
@@ -35,7 +35,6 @@ public:
uint32_t ornamenticon;
uint32_t ornamentidfile;
int32_t ornament_hero_model;
uint64_t guid;
};
static std::string PrimaryKey()
@@ -62,7 +61,6 @@ public:
"ornamenticon",
"ornamentidfile",
"ornament_hero_model",
"guid",
};
}
@@ -85,7 +83,6 @@ public:
"ornamenticon",
"ornamentidfile",
"ornament_hero_model",
"guid",
};
}
@@ -142,7 +139,6 @@ public:
e.ornamenticon = 0;
e.ornamentidfile = 0;
e.ornament_hero_model = 0;
e.guid = 0;
return e;
}
@@ -195,7 +191,6 @@ public:
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
return e;
}
@@ -245,7 +240,6 @@ public:
v.push_back(columns[13] + " = " + std::to_string(e.ornamenticon));
v.push_back(columns[14] + " = " + std::to_string(e.ornamentidfile));
v.push_back(columns[15] + " = " + std::to_string(e.ornament_hero_model));
v.push_back(columns[16] + " = " + std::to_string(e.guid));
auto results = db.QueryDatabase(
fmt::format(
@@ -283,7 +277,6 @@ public:
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
auto results = db.QueryDatabase(
fmt::format(
@@ -329,7 +322,6 @@ public:
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
@@ -379,7 +371,6 @@ public:
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
all_entries.push_back(e);
}
@@ -420,7 +411,6 @@ public:
e.ornamenticon = row[13] ? static_cast<uint32_t>(strtoul(row[13], nullptr, 10)) : 0;
e.ornamentidfile = row[14] ? static_cast<uint32_t>(strtoul(row[14], nullptr, 10)) : 0;
e.ornament_hero_model = row[15] ? static_cast<int32_t>(atoi(row[15])) : 0;
e.guid = row[16] ? strtoull(row[16], nullptr, 10) : 0;
all_entries.push_back(e);
}
@@ -511,7 +501,6 @@ public:
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
auto results = db.QueryDatabase(
fmt::format(
@@ -550,7 +539,6 @@ public:
v.push_back(std::to_string(e.ornamenticon));
v.push_back(std::to_string(e.ornamentidfile));
v.push_back(std::to_string(e.ornament_hero_model));
v.push_back(std::to_string(e.guid));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}

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