mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 13:16:39 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd01ed87df | |||
| 8a79994b4e | |||
| 93a661a434 | |||
| 3e8796bb4c | |||
| c23fc4ade7 | |||
| 3b628c1ace |
@@ -0,0 +1,21 @@
|
|||||||
|
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.101.1/containers/ubuntu-18.04-git
|
||||||
|
{
|
||||||
|
"name": "Ubuntu 18.04 EQEMU",
|
||||||
|
// Moved from dockerfile to image so it builds faster
|
||||||
|
"image": "eqemu/devcontainer:0.0.2",
|
||||||
|
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.shell.linux": "/bin/bash"
|
||||||
|
},
|
||||||
|
|
||||||
|
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
|
||||||
|
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": ["ms-vscode.cpptools", "ms-azuretools.vscode-docker"],
|
||||||
|
"mounts": ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"],
|
||||||
|
"remoteEnv": {
|
||||||
|
"HOST_PROJECT_PATH": "${localWorkspaceFolder}"
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-88
@@ -1,98 +1,16 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: Build Linux
|
name: EQEmulator Server Linux CI
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||||
concurrency:
|
concurrency:
|
||||||
limit: 1
|
limit: 1
|
||||||
|
|
||||||
volumes:
|
|
||||||
- name: cache
|
|
||||||
host:
|
|
||||||
path: /var/lib/cache-release
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Build Linux X64
|
- name: server-build
|
||||||
image: akkadius/eqemu-server:v11
|
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
|
||||||
environment:
|
image: akkadius/eqemu-server:latest
|
||||||
GITHUB_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
|
||||||
RCLONE_FTP_HOST: drone.akkadius.com
|
|
||||||
RCLONE_FTP_USER: artifacts
|
|
||||||
RCLONE_FTP_PASS:
|
|
||||||
from_secret: RCLONE_FTP_PASS
|
|
||||||
commands:
|
commands:
|
||||||
- ./utils/scripts/build/linux-build.sh
|
- sudo chown eqemu:eqemu /drone/src/ * -R
|
||||||
volumes:
|
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
|
||||||
- name: cache
|
|
||||||
path: /home/eqemu/.ccache/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
kind: pipeline
|
|
||||||
type: exec
|
|
||||||
name: Build Windows
|
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
|
||||||
concurrency:
|
|
||||||
limit: 1
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: windows
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Build Windows X64
|
|
||||||
environment:
|
|
||||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
|
||||||
RCLONE_FTP_HOST: drone.akkadius.com
|
|
||||||
RCLONE_FTP_USER: artifacts
|
|
||||||
RCLONE_FTP_PASS:
|
|
||||||
from_secret: RCLONE_FTP_PASS
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
commands:
|
|
||||||
- .\utils\scripts\build\windows-build.ps1
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
kind: pipeline
|
|
||||||
type: docker
|
|
||||||
name: Publish Artifacts to Github
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Upload Artifacts
|
|
||||||
image: akkadius/eqemu-build-releaser:v3
|
|
||||||
environment:
|
|
||||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
|
||||||
RCLONE_FTP_HOST: drone.akkadius.com
|
|
||||||
RCLONE_FTP_USER: artifacts
|
|
||||||
RCLONE_FTP_PASS:
|
|
||||||
from_secret: RCLONE_FTP_PASS
|
|
||||||
GH_RELEASE_GITHUB_API_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
|
||||||
commands:
|
|
||||||
- ./utils/scripts/build/should-release/should-release
|
|
||||||
- rclone config create remote ftp env_auth true > /dev/null
|
|
||||||
- |
|
|
||||||
rclone copy remote: --include "eqemu-server*.zip" .
|
|
||||||
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
|
|
||||||
- |
|
|
||||||
rclone delete remote: --include "eqemu-server*.zip"
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
|
|
||||||
depends_on:
|
|
||||||
- Build Windows
|
|
||||||
- Build Linux
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-17
@@ -54,20 +54,3 @@ bin/
|
|||||||
/Win32
|
/Win32
|
||||||
/x64
|
/x64
|
||||||
/client_files/**/CMakeFiles/
|
/client_files/**/CMakeFiles/
|
||||||
|
|
||||||
.idea
|
|
||||||
|
|
||||||
# Clangd Generated Files.
|
|
||||||
compile_flags.txt
|
|
||||||
.cache/
|
|
||||||
|
|
||||||
# vscode generated settings
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Build pipeline
|
|
||||||
!utils/scripts/build/
|
|
||||||
!utils/scripts/build/should-release/should-release
|
|
||||||
!utils/scripts/build/should-release/should-release.exe
|
|
||||||
|
|
||||||
# CMake Files
|
|
||||||
cmake-build-relwithdebinfo/*
|
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
language: cpp
|
||||||
|
compiler: gcc
|
||||||
|
dist: bionic
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libmysqlclient-dev
|
||||||
|
- libperl-dev
|
||||||
|
- libboost-dev
|
||||||
|
- liblua5.1-0-dev
|
||||||
|
- zlib1g-dev
|
||||||
|
- uuid-dev
|
||||||
|
- libssl-dev
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
||||||
|
- make -j2
|
||||||
|
- ./bin/tests
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"/usr/include/mysql"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"configurationProvider": "ms-vscode.cmake-tools"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"chrono": "cpp",
|
||||||
|
"xutility": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"*.ipp": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+164
@@ -0,0 +1,164 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "make",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build && make",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "make clean",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build && make clean",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "cmake",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build && rm CMakeCache.txt && cmake -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -G 'Unix Makefiles' ..",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher":{
|
||||||
|
"owner": "cpp",
|
||||||
|
"fileLocation": "relative",
|
||||||
|
"pattern":[
|
||||||
|
{
|
||||||
|
"regexp": "([\\w+|\\\\]*\\.\\w+)\\((\\d+)\\)\\: (warning|error) (.*)$",
|
||||||
|
"file": 1,
|
||||||
|
"location": 2,
|
||||||
|
"severity": 3,
|
||||||
|
"message": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "download maps",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build/bin && wget https://codeload.github.com/Akkadius/EQEmuMaps/zip/master -O maps.zip && unzip -o maps.zip && rm ./maps -rf && mv EQEmuMaps-master maps && rm maps.zip",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "download quests",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build/bin && cd server && git -C ./quests pull 2> /dev/null || git clone https://github.com/ProjectEQ/projecteqquests.git quests",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "download eqemu_config",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build/bin && wget --no-check-certificate https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/eqemu_config_docker.json -O eqemu_config.json",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "rebuild database (mariadb must be started)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "mkdir -p build && cd build/bin && docker run -i --rm --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --network=eqemu -it eqemu/server:0.0.3 bash -c './eqemu_server.pl source_peq_db && ./eqemu_server.pl check_db_updates && ./eqemu_server.pl assets && ./eqemu_server.pl lua_modules && ./eqemu_server.pl opcodes && ./eqemu_server.pl linux_login_server_setup'",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "zone 7000",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop zone7000 | true && docker network create eqemu | true && docker run -i --rm --name zone7000 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu -p 7000:7000/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7000:7000",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "zone 7001",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop zone7001 | true && docker network create eqemu | true && docker run -i --rm --name zone7001 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu -p 7001:7001/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./zone dynamic_zone7001:7001",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "loginserver",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop loginserver | true && docker network create eqemu | true && docker run -i --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --privileged -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 --network=eqemu --name loginserver -p 5999:5999/udp -p 5998:5998/udp -e LD_LIBRARY_PATH=/src/ eqemu/server:0.0.3 gdb -ex run --args ./loginserver",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "shared_memory, world",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop sharedmemory | true && docker stop world | true && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --network=eqemu --name sharedmemory eqemu/server:0.0.3 ./shared_memory && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name world -p 9000:9000 -p 9000:9000/udp -p 9001:9001 -p 9080:9080 eqemu/server:0.0.3 gdb -ex run ./world",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "queryserv",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop queryserv | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src --ulimit core=10000000 -e LD_LIBRARY_PATH=/src/ --network=eqemu --name queryserv eqemu/server:0.0.3 gdb -ex run ./queryserv",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "mariadb",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop mariadb | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin/db:/bitnami/mariadb -p 3306:3306 -e MARIADB_DATABASE=peq -e MARIADB_USER=eqemu -e MARIADB_PASSWORD=eqemupass -e ALLOW_EMPTY_PASSWORD=yes --name mariadb --network=eqemu bitnami/mariadb:latest",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "ucs",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "docker stop ucs | true && cd bin && docker network create eqemu | true && docker run --rm -v ${HOST_PROJECT_PATH}/build/bin:/src -p 7778:7778 --name ucs --network=eqemu eqemu/server:0.0.3 gdb -ex run ./ucs",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -40,14 +40,14 @@ Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extra
|
|||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
|
cmake -G "Visual Studio 15 2017 Win64" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_ZLIB=ON -DEQEMU_ENABLE_BOTS=ON -DCMAKE_TOOLCHAIN_FILE="c:/projects/eqemu/vcpkg/vcpkg-export-20180828-145455/scripts/buildsystems/vcpkg.cmake" ..
|
||||||
|
|
||||||
##### Linux
|
##### Linux
|
||||||
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
|
|||||||
-979
@@ -1,979 +0,0 @@
|
|||||||
## [22.4.3] - 02/21/2023
|
|
||||||
|
|
||||||
### Bots
|
|
||||||
|
|
||||||
* Change HasBotItem(item_id) to return slot_id instead of bool. ([#2966](https://github.com/EQEmu/Server/pull/2966)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-19
|
|
||||||
* Change SaveTimers to Replace instead of Insert. ([#2951](https://github.com/EQEmu/Server/pull/2951)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
|
||||||
* Fix output of ^spells while ^Enforcespellsettings is enabled ([#2959](https://github.com/EQEmu/Server/pull/2959)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-18
|
|
||||||
|
|
||||||
### Crash
|
|
||||||
|
|
||||||
* Fix crash with EVENT_UNEQUIP_ITEM_BOT ([#2973](https://github.com/EQEmu/Server/pull/2973)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-20
|
|
||||||
* Fix world crash in player event processing ([#2960](https://github.com/EQEmu/Server/pull/2960)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### Database
|
|
||||||
|
|
||||||
* Address deadlock in player events ([#2974](https://github.com/EQEmu/Server/pull/2974)) ([Akkadius](https://github.com/Akkadius)) 2023-02-21
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* Fix MIR LDoN Theme Items on LDoN Merchants ([#2971](https://github.com/EQEmu/Server/pull/2971)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-20
|
|
||||||
* Fix OOCMute not functioning ([#2970](https://github.com/EQEmu/Server/pull/2970)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-20
|
|
||||||
|
|
||||||
### Pathing
|
|
||||||
|
|
||||||
* Improvements to z-clipping, z-recovery and z-calculations ([#2975](https://github.com/EQEmu/Server/pull/2975)) ([Akkadius](https://github.com/Akkadius)) 2023-02-21
|
|
||||||
|
|
||||||
### Pets
|
|
||||||
|
|
||||||
* Client Pet summoned by NPC should not change guard location. ([#2967](https://github.com/EQEmu/Server/pull/2967)) ([noudess](https://github.com/noudess)) 2023-02-19
|
|
||||||
|
|
||||||
### Player Events
|
|
||||||
|
|
||||||
* Create new event ITEM_CREATION ([#2944](https://github.com/EQEmu/Server/pull/2944)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### Quest API
|
|
||||||
|
|
||||||
* Add client->SignalClient() overload to Perl ([#2963](https://github.com/EQEmu/Server/pull/2963)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-19
|
|
||||||
* Fix Perl SetSimpleRoamBox Overloads ([#2961](https://github.com/EQEmu/Server/pull/2961)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-19
|
|
||||||
|
|
||||||
### Reload API
|
|
||||||
|
|
||||||
* Add world handlers for certain opcodes ([#2958](https://github.com/EQEmu/Server/pull/2958)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### SQL
|
|
||||||
|
|
||||||
* 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
|
|
||||||
|
|
||||||
### Content
|
|
||||||
|
|
||||||
* Added optional SQL 2023_02_17_fix_sseru_mischief_doors.sql to fix sseru/mischief doors ([#2955](https://github.com/EQEmu/Server/pull/2955)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### Logging
|
|
||||||
|
|
||||||
* Remove noisy raid/group/forage errors ([#2952](https://github.com/EQEmu/Server/pull/2952)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### MySQL
|
|
||||||
|
|
||||||
* Add keepalives to UCS and Loginserver ([#2953](https://github.com/EQEmu/Server/pull/2953)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### Player Events
|
|
||||||
|
|
||||||
* Add logging category to hold processing batch logs ([#2954](https://github.com/EQEmu/Server/pull/2954)) ([Akkadius](https://github.com/Akkadius)) 2023-02-18
|
|
||||||
|
|
||||||
### Tradeskills
|
|
||||||
|
|
||||||
* 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
|
|
||||||
|
|
||||||
### Bots
|
|
||||||
|
|
||||||
* Set Taunt to enabled for SK/Paladin Bots by Default. ([#2941](https://github.com/EQEmu/Server/pull/2941)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-17
|
|
||||||
|
|
||||||
### DevTools
|
|
||||||
|
|
||||||
* Fix NPC targetting dev tools display window ([#2943](https://github.com/EQEmu/Server/pull/2943)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* Issue with AssignRaidToInstance that was using the groups repository instead of raid ([#2947](https://github.com/EQEmu/Server/pull/2947)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
|
||||||
* Missing comma in schema list breaking dumps ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
|
||||||
|
|
||||||
### Player Events
|
|
||||||
|
|
||||||
* Fix issue with item instances not being validated properly before accessing causing crashes on handin ([#2945](https://github.com/EQEmu/Server/pull/2945)) ([Akkadius](https://github.com/Akkadius)) 2023-02-17
|
|
||||||
* 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
|
|
||||||
|
|
||||||
### Bots
|
|
||||||
|
|
||||||
* Add Additional HeroicAgi/Dex Modifiers. ([#2838](https://github.com/EQEmu/Server/pull/2838)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
|
||||||
* Add Additional HeroicStr modifiers. ([#2837](https://github.com/EQEmu/Server/pull/2837)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
|
||||||
* Add IsBot() to methods in attack.cpp where applicable. ([#2840](https://github.com/EQEmu/Server/pull/2840)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
|
||||||
* Add Lore Check for Augments. ([#2874](https://github.com/EQEmu/Server/pull/2874)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-12
|
|
||||||
* Add Pet Power Support for Temp Pets. ([#2853](https://github.com/EQEmu/Server/pull/2853)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-11
|
|
||||||
* Add Support for TryTriggerOnCastFocusEffect ([#2864](https://github.com/EQEmu/Server/pull/2864)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
|
||||||
* Add TotalDominationBonus modifiers. ([#2852](https://github.com/EQEmu/Server/pull/2852)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
|
||||||
* ST_AreaClientOnly spells to land on Bots ([#2849](https://github.com/EQEmu/Server/pull/2849)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
|
||||||
* Update ResistSpell to use temp_level_diff client formula ([#2851](https://github.com/EQEmu/Server/pull/2851)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
|
||||||
|
|
||||||
### Bots & Mercenaries
|
|
||||||
|
|
||||||
* Add 100% Hit chance if sitting while attacked. ([#2839](https://github.com/EQEmu/Server/pull/2839)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
|
||||||
* Add Support for TrySympatheticProc ([#2866](https://github.com/EQEmu/Server/pull/2866)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
|
||||||
|
|
||||||
### CI
|
|
||||||
|
|
||||||
* Fix Windows stderr not bubbling properly ([#2925](https://github.com/EQEmu/Server/pull/2925)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
|
|
||||||
### Code
|
|
||||||
|
|
||||||
* Add IsOfClientBot() virtual method. ([#2845](https://github.com/EQEmu/Server/pull/2845)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
|
||||||
* Doors EVENT_CLICK_DOOR syntax adjustment ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Remove Unused Mod Hooks ([#2856](https://github.com/EQEmu/Server/pull/2856)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
|
|
||||||
### Crash
|
|
||||||
|
|
||||||
* Crash fix where invalid input to #heromodel would crash zone ([#2937](https://github.com/EQEmu/Server/pull/2937)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
|
||||||
* Fix Bot Crash in Bot::Bot Constructor. ([#2868](https://github.com/EQEmu/Server/pull/2868)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-12
|
|
||||||
* Fix Crash in FindType ([#2867](https://github.com/EQEmu/Server/pull/2867)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
|
||||||
* Fix crash in Mob::CommonDamage when attacker was null ([#2872](https://github.com/EQEmu/Server/pull/2872)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-13
|
|
||||||
* Fix crash issue with dropping items and order of operations ([#2939](https://github.com/EQEmu/Server/pull/2939)) ([joligario](https://github.com/joligario)) 2023-02-16
|
|
||||||
* Fix issue where long short names overflow file_name ([Akkadius](https://github.com/Akkadius)) 2023-02-09
|
|
||||||
* Fix potential crash in Mob::CommonDamage ([#2848](https://github.com/EQEmu/Server/pull/2848)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-09
|
|
||||||
|
|
||||||
### Doors
|
|
||||||
|
|
||||||
* Fix issue where NPC's wouldn't open doors because door param overflow ([#2934](https://github.com/EQEmu/Server/pull/2934)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
|
||||||
|
|
||||||
### Feature
|
|
||||||
|
|
||||||
* Add IsOfClientBotMerc() virtual method. ([#2843](https://github.com/EQEmu/Server/pull/2843)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-07
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* Another doors fix ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Fix CheckNumHitsRemaining() with 1H Blunt ([#2846](https://github.com/EQEmu/Server/pull/2846)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-07
|
|
||||||
* Fix Door opening regression caused by #2880 ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Fix EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE regression caused by #2897 ([#2928](https://github.com/EQEmu/Server/pull/2928)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Fix HP_EVENT regression ([#2927](https://github.com/EQEmu/Server/pull/2927)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Fix crash in EVENT_DISCOVER_ITEM ([#2933](https://github.com/EQEmu/Server/pull/2933)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-15
|
|
||||||
* Fix crash where dropped items crash Lua logic ([#2936](https://github.com/EQEmu/Server/pull/2936)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
|
||||||
* Fix for interrupting item casts to no longer lock the client if cast time of item greater than 0 ([#2921](https://github.com/EQEmu/Server/pull/2921)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-13
|
|
||||||
* Fix issue where Lore groundspawn pickups will desync ROF2+ ([#2929](https://github.com/EQEmu/Server/pull/2929)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Fix issue with EVENT_HP firing regression from #2904 ([#2924](https://github.com/EQEmu/Server/pull/2924)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
* Replace uses of SPELL_UNKNOWN with IsValidSpell() ([#2938](https://github.com/EQEmu/Server/pull/2938)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-16
|
|
||||||
* Self Only Spells will no longer check target level or buff restrictions ([#2931](https://github.com/EQEmu/Server/pull/2931)) ([noudess](https://github.com/noudess)) 2023-02-15
|
|
||||||
|
|
||||||
### Groundspawns
|
|
||||||
|
|
||||||
* Fix issue where groundspawns appear floating high off the ground ([#2930](https://github.com/EQEmu/Server/pull/2930)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
|
||||||
|
|
||||||
### Logging
|
|
||||||
|
|
||||||
* Add raw opcode when emu translated opcode is not found (OP_Unknown) via (C->S) ([#2847](https://github.com/EQEmu/Server/pull/2847)) ([Akkadius](https://github.com/Akkadius)) 2023-02-08
|
|
||||||
* Implement Player Event Logging system ([#2833](https://github.com/EQEmu/Server/pull/2833)) ([Akkadius](https://github.com/Akkadius)) 2023-02-13
|
|
||||||
|
|
||||||
### Quest API
|
|
||||||
|
|
||||||
* (Performance) Check equip or scale item events exist before export and execute ([#2898](https://github.com/EQEmu/Server/pull/2898)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_AA_BUY or EVENT_AA_GAIN exist before export and execute ([#2892](https://github.com/EQEmu/Server/pull/2892)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_AGGRO, EVENT_ATTACK, or EVENT_COMBAT exist before export and execute ([#2901](https://github.com/EQEmu/Server/pull/2901)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_COMBINE, EVENT_COMBINE_SUCCESS, EVENT_COMBINE_FAILURE, or EVENT_COMBINE_VALIDATE exist before export and execute ([#2896](https://github.com/EQEmu/Server/pull/2896)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_DEATH, EVENT_DEATH_COMPLETE, or EVENT_DEATH_ZONE exist before export and execute ([#2909](https://github.com/EQEmu/Server/pull/2909)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_ENVIRONMENTAL_DAMAGE exists before export and execute ([#2899](https://github.com/EQEmu/Server/pull/2899)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_FEIGN_DEATH exists before export and execute ([#2916](https://github.com/EQEmu/Server/pull/2916)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_ITEM_TICK or EVENT_WEAPON_PROC exist before export and execute ([#2914](https://github.com/EQEmu/Server/pull/2914)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_LANGUAGE_SKILL_UP, EVENT_SKILL_UP, or EVENT_USE_SKILL exist before export and execute ([#2894](https://github.com/EQEmu/Server/pull/2894)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_PAYLOAD or EVENT_SIGNAL exist before export and execute ([#2902](https://github.com/EQEmu/Server/pull/2902)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_SLAY exists before export and execute ([#2910](https://github.com/EQEmu/Server/pull/2910)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event EVENT_WAYPOINT_ARRIVE or EVENT_WAYPOINT_DEPART exist before export and execute ([#2905](https://github.com/EQEmu/Server/pull/2905)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_AGGRO_SAY, EVENT_SAY, and EVENT_PROXIMITY_SAY ([#2882](https://github.com/EQEmu/Server/pull/2882)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_BOT_CREATE ([#2886](https://github.com/EQEmu/Server/pull/2886)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_CLICK_DOOR and EVENT_CLICK_OBJECT ([#2880](https://github.com/EQEmu/Server/pull/2880)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_DESPAWN and EVENT_DESPAWN_ZONE ([#2887](https://github.com/EQEmu/Server/pull/2887)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_DISCOVER_ITEM ([#2912](https://github.com/EQEmu/Server/pull/2912)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_DUEL_LOSE and EVENT_DUEL_WIN ([#2915](https://github.com/EQEmu/Server/pull/2915)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_ENTER_ZONE and EVENT_ZONE ([#2900](https://github.com/EQEmu/Server/pull/2900)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_GM_COMMAND ([#2890](https://github.com/EQEmu/Server/pull/2890)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_GROUP_CHANGE ([#2884](https://github.com/EQEmu/Server/pull/2884)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_HP ([#2904](https://github.com/EQEmu/Server/pull/2904)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_KILLED_MERIT ([#2911](https://github.com/EQEmu/Server/pull/2911)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_LEVEL_UP and EVENT_LEVEL_DOWN ([#2889](https://github.com/EQEmu/Server/pull/2889)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_POPUP_RESPONSE ([#2881](https://github.com/EQEmu/Server/pull/2881)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_RESPAWN ([#2917](https://github.com/EQEmu/Server/pull/2917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_TICK ([#2919](https://github.com/EQEmu/Server/pull/2919)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_TIMER ([#2903](https://github.com/EQEmu/Server/pull/2903)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_TRADE ([#2906](https://github.com/EQEmu/Server/pull/2906)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_UNHANDLED_OPCODE ([#2918](https://github.com/EQEmu/Server/pull/2918)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_WARP ([#2907](https://github.com/EQEmu/Server/pull/2907)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute area events ([#2888](https://github.com/EQEmu/Server/pull/2888)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check merchant events exist before export and execute ([#2893](https://github.com/EQEmu/Server/pull/2893)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check spell or cast events exist before export and execute ([#2897](https://github.com/EQEmu/Server/pull/2897)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check task events exist before export and execute ([#2883](https://github.com/EQEmu/Server/pull/2883)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_CONNECT and EVENT_DISCONNECT ([#2913](https://github.com/EQEmu/Server/pull/2913)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* (Performance) Check event exists before export and execute EVENT_TEST_BUFF ([#2920](https://github.com/EQEmu/Server/pull/2920)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Add $target export to EVENT_INSPECT in Perl ([#2891](https://github.com/EQEmu/Server/pull/2891)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Add Additional XP Events EVENT_AA_EXP_GAIN, EVENT_EXP_GAIN ([#2865](https://github.com/EQEmu/Server/pull/2865)) ([Valorith](https://github.com/Valorith)) 2023-02-13
|
|
||||||
* Add EVENT_DESTROY_ITEM_CLIENT to Perl/Lua. ([#2871](https://github.com/EQEmu/Server/pull/2871)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Add EVENT_DROP_ITEM_CLIENT to Perl/Lua ([#2869](https://github.com/EQEmu/Server/pull/2869)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Add Recipe-based methods to Perl/Lua. ([#2844](https://github.com/EQEmu/Server/pull/2844)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-08
|
|
||||||
* Export $door to EVENT_CLICKDOOR in Perl ([#2861](https://github.com/EQEmu/Server/pull/2861)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
|
||||||
* Export $hate_entity to EVENT_HATE_LIST in Perl ([#2885](https://github.com/EQEmu/Server/pull/2885)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export $item and $augment to augment events in Perl ([#2895](https://github.com/EQEmu/Server/pull/2895)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export $item and $corpse to EVENT_LOOT and EVENT_LOOT_ZONE in Perl ([#2878](https://github.com/EQEmu/Server/pull/2878)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export $item to Client/Bot Equip Events in Perl ([#2860](https://github.com/EQEmu/Server/pull/2860)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
|
||||||
* Export $item to EVENT_DISCOVER_ITEM in Perl ([#2863](https://github.com/EQEmu/Server/pull/2863)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
|
||||||
* Export $item to EVENT_PLAYER_PICKUP in Perl. ([#2875](https://github.com/EQEmu/Server/pull/2875)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export $item to Fishing and Forage Events in Perl ([#2876](https://github.com/EQEmu/Server/pull/2876)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export $killed_npc to EVENT_NPC_SLAY to Perl ([#2879](https://github.com/EQEmu/Server/pull/2879)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export $object to EVENT_CLICK_OBJECT in Perl ([#2862](https://github.com/EQEmu/Server/pull/2862)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-11
|
|
||||||
* Export $spawned to EVENT_SPAWN_ZONE in Perl ([#2877](https://github.com/EQEmu/Server/pull/2877)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export target to EVENT_TARGET_CHANGE in Perl/Lua. ([#2870](https://github.com/EQEmu/Server/pull/2870)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Export targets to EVENT_CONSIDER and EVENT_CONSIDER_CORPSE ([#2908](https://github.com/EQEmu/Server/pull/2908)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
* Fix SetSimpleRoamBox in Perl to have optional params again ([#2935](https://github.com/EQEmu/Server/pull/2935)) ([Akkadius](https://github.com/Akkadius)) 2023-02-15
|
|
||||||
|
|
||||||
### Rules
|
|
||||||
|
|
||||||
* Add Group/Raid Experience Rules ([#2850](https://github.com/EQEmu/Server/pull/2850)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-13
|
|
||||||
|
|
||||||
### Tradeskills
|
|
||||||
|
|
||||||
* Check if combine would result in lore conflict ([#2932](https://github.com/EQEmu/Server/pull/2932)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-16
|
|
||||||
|
|
||||||
### Windows
|
|
||||||
|
|
||||||
* Fix MSVC compilation bug via workaround ([#2926](https://github.com/EQEmu/Server/pull/2926)) ([Akkadius](https://github.com/Akkadius)) 2023-02-14
|
|
||||||
|
|
||||||
## [22.3.0] - 02/06/2023
|
|
||||||
|
|
||||||
### Bots
|
|
||||||
|
|
||||||
* Add GetAugmentIDsBySlotID & AddItem with table ref Methods. ([#2805](https://github.com/EQEmu/Server/pull/2805)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-29
|
|
||||||
|
|
||||||
### Commands
|
|
||||||
|
|
||||||
* #list now searches without case sensitivity ([#2825](https://github.com/EQEmu/Server/pull/2825)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
* Remove extraneous else from #weather ([#2819](https://github.com/EQEmu/Server/pull/2819)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
|
||||||
|
|
||||||
### Crash
|
|
||||||
|
|
||||||
* Fix IsUnderwaterOnly crash where npc data references can be stale ([#2830](https://github.com/EQEmu/Server/pull/2830)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
* Fix command crash with #npcedit weapon when second weapon not passed ni ([#2829](https://github.com/EQEmu/Server/pull/2829)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
* Fix crash in bot command botdyearmor ([#2832](https://github.com/EQEmu/Server/pull/2832)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
### DB Updates
|
|
||||||
|
|
||||||
* Add Windows MySQL path auto detection for users where the path is not found ([#2836](https://github.com/EQEmu/Server/pull/2836)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
### Doors
|
|
||||||
|
|
||||||
* Have NPCs trigger double doors ([#2821](https://github.com/EQEmu/Server/pull/2821)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
* Remove door dev tools spam on client controlled doors ([#2824](https://github.com/EQEmu/Server/pull/2824)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
### Feature
|
|
||||||
|
|
||||||
* Add Min/Max Status to Merchants ([#2806](https://github.com/EQEmu/Server/pull/2806)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* #reload aa will now refresh the AA table properly for every client when changes are made ([#2814](https://github.com/EQEmu/Server/pull/2814)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
|
||||||
* #reload static should now properly fill the entity_lists for… ([#2815](https://github.com/EQEmu/Server/pull/2815)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-31
|
|
||||||
* BuffLevelRestrictions were restricting group buffs if mob targeted ([#2809](https://github.com/EQEmu/Server/pull/2809)) ([noudess](https://github.com/noudess)) 2023-01-29
|
|
||||||
* Fix does_augment_fit_slot method. ([#2817](https://github.com/EQEmu/Server/pull/2817)) ([Aeadoin](https://github.com/Aeadoin)) 2023-02-01
|
|
||||||
* Fix NPC ghosting at safe coordinates ([#2823](https://github.com/EQEmu/Server/pull/2823)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
* Fixing % based mob see invis ([#2802](https://github.com/EQEmu/Server/pull/2802)) ([fryguy503](https://github.com/fryguy503)) 2023-01-29
|
|
||||||
* Resolve issue with max buff count being 25 in ROF2. ([#2800](https://github.com/EQEmu/Server/pull/2800)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-28
|
|
||||||
|
|
||||||
### Hotfix
|
|
||||||
|
|
||||||
* Post revert build fix for https://github.com/EQEmu/Server/commit/54050924d81d1f83268fe01f9c2b36fe10626601 ([Akkadius](https://github.com/Akkadius)) 2023-02-01
|
|
||||||
|
|
||||||
### Lua
|
|
||||||
|
|
||||||
* Resolve stoi Exception ([#2736](https://github.com/EQEmu/Server/pull/2736)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
### Pathing
|
|
||||||
|
|
||||||
* Improvements to handling tight corridors pathing, clipping detection and recovery ([#2826](https://github.com/EQEmu/Server/pull/2826)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
### Quest API
|
|
||||||
|
|
||||||
* Add Augment Slot support to does_augment_fit ([#2813](https://github.com/EQEmu/Server/pull/2813)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-31
|
|
||||||
* Add EVENT_DAMAGE_GIVEN and EVENT_DAMAGE_TAKEN to Perl/Lua. ([#2804](https://github.com/EQEmu/Server/pull/2804)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
|
||||||
* Add EVENT_ITEM_CLICK_CLIENT and EVENT_ITEM_CLICK_CAST_CLIENT to Perl/Lua. ([#2810](https://github.com/EQEmu/Server/pull/2810)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-30
|
|
||||||
* Add EVENT_TASKACCEPTED to Player scope ([#2822](https://github.com/EQEmu/Server/pull/2822)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
|
||||||
* Add GetItemCooldown to return the time remaining on items… ([#2811](https://github.com/EQEmu/Server/pull/2811)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-30
|
|
||||||
* Add LDoN Methods to Perl/Lua ([#2799](https://github.com/EQEmu/Server/pull/2799)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-29
|
|
||||||
* Add Override Parameters to ScaleNPC() in Perl/Lua. ([#2816](https://github.com/EQEmu/Server/pull/2816)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-01
|
|
||||||
* Add rule AlternateAugmentationSealer for using a different bagtype ([#2831](https://github.com/EQEmu/Server/pull/2831)) ([Natedog2012](https://github.com/Natedog2012)) 2023-02-06
|
|
||||||
* Default ScaleNPC to always scale. ([#2818](https://github.com/EQEmu/Server/pull/2818)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-02-06
|
|
||||||
|
|
||||||
### Readme
|
|
||||||
|
|
||||||
* Update build badges with Drone ([Akkadius](https://github.com/Akkadius)) 2023-01-29
|
|
||||||
|
|
||||||
### Rules
|
|
||||||
|
|
||||||
* Add rule to ignore name filter on chat channel creation. ([#2820](https://github.com/EQEmu/Server/pull/2820)) ([Valorith](https://github.com/Valorith)) 2023-02-06
|
|
||||||
* Added rule to bypass level based haste caps ([#2835](https://github.com/EQEmu/Server/pull/2835)) ([jcr4990](https://github.com/jcr4990)) 2023-02-06
|
|
||||||
* Fix rule updates that affected bot booting checks ([#2841](https://github.com/EQEmu/Server/pull/2841)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
### Tasks
|
|
||||||
|
|
||||||
* Implement alternate currency rewards ([#2827](https://github.com/EQEmu/Server/pull/2827)) ([Akkadius](https://github.com/Akkadius)) 2023-02-06
|
|
||||||
|
|
||||||
## [22.2.0] - 01/27/2023
|
|
||||||
|
|
||||||
### Bots
|
|
||||||
|
|
||||||
* Add EVENT_UNEQUIP_ITEM_BOT & EVENT_EQUIP_ITEM_BOT ([#2796](https://github.com/EQEmu/Server/pull/2796)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-27
|
|
||||||
* ^create and ^viewcombos popup messages fix. ([#2797](https://github.com/EQEmu/Server/pull/2797)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-26
|
|
||||||
|
|
||||||
### Code Cleanup
|
|
||||||
|
|
||||||
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
|
||||||
|
|
||||||
### Crash
|
|
||||||
|
|
||||||
* Fix crash issue with log formatting during character creation ([#2798](https://github.com/EQEmu/Server/pull/2798)) ([Akkadius](https://github.com/Akkadius)) 2023-01-27
|
|
||||||
|
|
||||||
### Feature
|
|
||||||
|
|
||||||
* ResetItemCooldown added to lua/perl and fix item re-cast times to show properly ([#2793](https://github.com/EQEmu/Server/pull/2793)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-26
|
|
||||||
|
|
||||||
### Git
|
|
||||||
|
|
||||||
* Add CMake Files to .gitignore ([#2792](https://github.com/EQEmu/Server/pull/2792)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-25
|
|
||||||
|
|
||||||
## [22.1.2] - 01/24/2023
|
|
||||||
|
|
||||||
### CI/CD
|
|
||||||
|
|
||||||
* Build / Release Pipeline Changes ([#2788](https://github.com/EQEmu/Server/pull/2788)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
|
|
||||||
|
|
||||||
### Code Cleanup
|
|
||||||
|
|
||||||
* Cleanup #door Command. ([#2783](https://github.com/EQEmu/Server/pull/2783)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
|
||||||
|
|
||||||
### Crash
|
|
||||||
|
|
||||||
* Fix rarer world crash issue where scheduler database was not available ([#2789](https://github.com/EQEmu/Server/pull/2789)) ([Akkadius](https://github.com/Akkadius)) 2023-01-24
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* Fix nullptr spell in BCSpells::Load() ([#2790](https://github.com/EQEmu/Server/pull/2790)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
|
||||||
* Remove duplicate logic in GetActSpellHealing reducing HOT criticals ([#2786](https://github.com/EQEmu/Server/pull/2786)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-24
|
|
||||||
|
|
||||||
## [22.1.1] - 01/23/2023
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
|
||||||
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
|
||||||
|
|
||||||
## [22.1.0] - 01/22/2023
|
|
||||||
|
|
||||||
This is a first release using the new build system. Changelog entry representative of last year. Subsequent releases will consist of incremental changes since the last release.
|
|
||||||
|
|
||||||
### AA
|
|
||||||
|
|
||||||
* Fix AA tables dump ([#2769](https://github.com/EQEmu/Server/pull/2769)) ([Akkadius](https://github.com/Akkadius)) 2023-01-22
|
|
||||||
|
|
||||||
### Appveyor
|
|
||||||
|
|
||||||
* Remove bots preprocessor ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
|
|
||||||
### Bot/Merc
|
|
||||||
|
|
||||||
* Cleanup methods, and virtual overrides. ([#2734](https://github.com/EQEmu/Server/pull/2734)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
|
||||||
|
|
||||||
### Bots
|
|
||||||
|
|
||||||
* Add Bot Command Reloading ([#2773](https://github.com/EQEmu/Server/pull/2773)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
|
||||||
* Add Bot-specific Spell Settings. ([#2553](https://github.com/EQEmu/Server/pull/2553)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Add Buff support for Bards under AI_IdleCastChecks ([#2590](https://github.com/EQEmu/Server/pull/2590)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-28
|
|
||||||
* Add Data Bucket support to Bot Spell Entries. ([#2505](https://github.com/EQEmu/Server/pull/2505)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
|
|
||||||
* Add EVENT_TRADE Support to Bots. ([#2560](https://github.com/EQEmu/Server/pull/2560)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
|
||||||
* Add Event_Trade Support for ^inventorygive Command ([#2628](https://github.com/EQEmu/Server/pull/2628)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-11
|
|
||||||
* Add Expansion Bitmask Quest APIs. ([#2523](https://github.com/EQEmu/Server/pull/2523)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
|
||||||
* Add GetBotOwnerByBotID Method ([#2715](https://github.com/EQEmu/Server/pull/2715)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
|
|
||||||
* Add Melee Support for Casting, Cleanup Bot Casting Logic ([#2571](https://github.com/EQEmu/Server/pull/2571)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
|
||||||
* Add Quest API Methods ([#2631](https://github.com/EQEmu/Server/pull/2631)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-12
|
|
||||||
* Add Quest API Support for Limits. ([#2522](https://github.com/EQEmu/Server/pull/2522)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
|
||||||
* Add Rule Allowing Bots to Equip Any Race Items ([#2578](https://github.com/EQEmu/Server/pull/2578)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-26
|
|
||||||
* Add Support for AA bonuses that were missing. ([#2764](https://github.com/EQEmu/Server/pull/2764)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
|
||||||
* Add Support for Bots to receive Auras, and other AoE Buffs. ([#2586](https://github.com/EQEmu/Server/pull/2586)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
|
||||||
* Add Virtual Override for Bot::Attack ([#2771](https://github.com/EQEmu/Server/pull/2771)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
|
||||||
* Add give/remove saylinks to ^itemuse. ([#2503](https://github.com/EQEmu/Server/pull/2503)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
|
||||||
* Add support for Bot scripting. ([#2515](https://github.com/EQEmu/Server/pull/2515)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
|
||||||
* Apply Spells:IgnoreSpellDmgLvlRestriction to bots ([#2024](https://github.com/EQEmu/Server/pull/2024)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
|
||||||
* Bot::PerformTradeWithClient Cleanup. ([#2084](https://github.com/EQEmu/Server/pull/2084)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
|
|
||||||
* Cleanup Bot Spell Functions, reduce reliance on NPC Functions/Attributes ([#2495](https://github.com/EQEmu/Server/pull/2495)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-29
|
|
||||||
* Cleanup Fast Rest Regen ([#2626](https://github.com/EQEmu/Server/pull/2626)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-07
|
|
||||||
* Cleanup Say Event Parse. ([#2557](https://github.com/EQEmu/Server/pull/2557)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
|
||||||
* Cleanup Spell Settings Commands ([#2607](https://github.com/EQEmu/Server/pull/2607)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
|
||||||
* Cleanup ^inventoryremove, ^inventorylist, and ^list Commands and bot groups. ([#2273](https://github.com/EQEmu/Server/pull/2273)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-03
|
|
||||||
* Cleanup and remove preprocessors. ([#2757](https://github.com/EQEmu/Server/pull/2757)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-20
|
|
||||||
* Cleanup various Bot Spell Focus methods ([#2649](https://github.com/EQEmu/Server/pull/2649)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-16
|
|
||||||
* Convert Load, Save, SaveNew, and Delete to Repositories. ([#2614](https://github.com/EQEmu/Server/pull/2614)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
|
||||||
* Expanded Bot Spell Settings List. ([#2606](https://github.com/EQEmu/Server/pull/2606)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-03
|
|
||||||
* Fix Bot Spell Type "In Combat Buffs" ([#2711](https://github.com/EQEmu/Server/pull/2711)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-08
|
|
||||||
* Fix Gender not saving as GetBaseGender on BotSave ([#2639](https://github.com/EQEmu/Server/pull/2639)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
|
|
||||||
* Fix Slow Query in QueryNameAvailablity ([#2781](https://github.com/EQEmu/Server/pull/2781)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
|
|
||||||
* Fix ^dyearmor command math. ([#2081](https://github.com/EQEmu/Server/pull/2081)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
|
||||||
* Fix bot spawn when bot id = char_id ([#1984](https://github.com/EQEmu/Server/pull/1984)) ([neckkola](https://github.com/neckkola)) 2022-03-07
|
|
||||||
* Hotfix for possible crash. ([#2539](https://github.com/EQEmu/Server/pull/2539)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Melee Bot Support for Spell Settings Commands ([#2599](https://github.com/EQEmu/Server/pull/2599)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
|
|
||||||
* Move Bot Spell Loading process to constructor from calcbotstats() ([#2583](https://github.com/EQEmu/Server/pull/2583)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
|
||||||
* Optimize inventory loading. ([#2588](https://github.com/EQEmu/Server/pull/2588)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-28
|
|
||||||
* Post pre-processor fixes ([#2770](https://github.com/EQEmu/Server/pull/2770)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
* Resolve incorrect values on Bot Creation ([#2644](https://github.com/EQEmu/Server/pull/2644)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-14
|
|
||||||
* Restrict Bot Groups from spawning while Feigned. ([#2761](https://github.com/EQEmu/Server/pull/2761)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
|
|
||||||
* Save Bot Toggle Archer Setting between Loads. ([#2612](https://github.com/EQEmu/Server/pull/2612)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
|
||||||
* Update Bot Heal & Damage methods to more closely match Clients + Bugfixes ([#2045](https://github.com/EQEmu/Server/pull/2045)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-11
|
|
||||||
* Update Bot Logic to ignore ST_TargetsTarget when buffing ([#2584](https://github.com/EQEmu/Server/pull/2584)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-27
|
|
||||||
|
|
||||||
### C++20
|
|
||||||
|
|
||||||
* Arithmetic on different enums is deprecated ([#2752](https://github.com/EQEmu/Server/pull/2752)) ([mackal](https://github.com/mackal)) 2023-01-17
|
|
||||||
* Enable C++20 + Fixes + FMT 9.1 ([#2664](https://github.com/EQEmu/Server/pull/2664)) ([Akkadius](https://github.com/Akkadius)) 2022-12-21
|
|
||||||
|
|
||||||
### Code
|
|
||||||
|
|
||||||
* Removed vscode setting ([#2753](https://github.com/EQEmu/Server/pull/2753)) ([xackery](https://github.com/xackery)) 2023-01-17
|
|
||||||
|
|
||||||
### Code Cleanup
|
|
||||||
|
|
||||||
* Add Validation to varchar number item fields. ([#2241](https://github.com/EQEmu/Server/pull/2241)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
|
||||||
* Cleanup #kick message. ([#2164](https://github.com/EQEmu/Server/pull/2164)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
|
||||||
* Cleanup Haste references and Lua API calls for unsigned to signed. ([#2240](https://github.com/EQEmu/Server/pull/2240)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
|
||||||
* Cleanup code smells and compiler warnings in common/shareddb ([#2270](https://github.com/EQEmu/Server/pull/2270)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
|
||||||
* Cleanup magic numbers ([#2662](https://github.com/EQEmu/Server/pull/2662)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-20
|
|
||||||
* Cleanup spell and max level bucket logic. ([#2181](https://github.com/EQEmu/Server/pull/2181)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
|
||||||
* Extra Space in NPC::AISpellsList(). ([#2555](https://github.com/EQEmu/Server/pull/2555)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
|
||||||
* Fix unintended copies in zone/zonedb.cpp by changing auto to auto& ([#2271](https://github.com/EQEmu/Server/pull/2271)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
|
||||||
* Make use of std::abs where possible. ([#2739](https://github.com/EQEmu/Server/pull/2739)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
|
||||||
* Merge Client::Attack and Bot::Attack into Mob::Attack ([#2756](https://github.com/EQEmu/Server/pull/2756)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-20
|
|
||||||
* Move Client::Undye() to client.cpp from #path Command. ([#2188](https://github.com/EQEmu/Server/pull/2188)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-21
|
|
||||||
* Possible issues with variable/parameter name equality. ([#2161](https://github.com/EQEmu/Server/pull/2161)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
|
||||||
* Quest API push methods using invalid types. ([#2172](https://github.com/EQEmu/Server/pull/2172)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-16
|
|
||||||
* Remove Unused EQEMU_DEPOP_INVALIDATES_CACHE ([#2292](https://github.com/EQEmu/Server/pull/2292)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
|
||||||
* Remove this-> in code where its implied ([#2088](https://github.com/EQEmu/Server/pull/2088)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
|
|
||||||
* Remove unused basic_functions.h ([#2729](https://github.com/EQEmu/Server/pull/2729)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
|
||||||
* Remove unused maxskill.h. ([#2728](https://github.com/EQEmu/Server/pull/2728)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
|
||||||
* Remove unused methods. ([#2171](https://github.com/EQEmu/Server/pull/2171)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
|
|
||||||
* Remove unusued Max Item ID Constant ([#2528](https://github.com/EQEmu/Server/pull/2528)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-08
|
|
||||||
* Remove use of bzero since it is deprecated for memset ([#2295](https://github.com/EQEmu/Server/pull/2295)) ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
|
||||||
* Resharper Warnings ([#2235](https://github.com/EQEmu/Server/pull/2235)) ([Quintinon](https://github.com/Quintinon)) 2022-06-01
|
|
||||||
* Resolve some warnings in loginserver/world_server.cpp ([#2347](https://github.com/EQEmu/Server/pull/2347)) ([mackal](https://github.com/mackal)) 2022-07-31
|
|
||||||
* Rework Lua QuestReward to not use try/catch blocks ([#2417](https://github.com/EQEmu/Server/pull/2417)) ([mackal](https://github.com/mackal)) 2022-09-03
|
|
||||||
* Send eqstr message in AddAAPoints ([#2507](https://github.com/EQEmu/Server/pull/2507)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
|
||||||
* Update to EQEmu #2253 to clean up message strings ([#2279](https://github.com/EQEmu/Server/pull/2279)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
|
||||||
* Zone Data Loading Refactor ([#2388](https://github.com/EQEmu/Server/pull/2388)) ([Akkadius](https://github.com/Akkadius)) 2022-09-01
|
|
||||||
|
|
||||||
### Commands
|
|
||||||
|
|
||||||
* #bind Typo. ([#2196](https://github.com/EQEmu/Server/pull/2196)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
* #ginfo Cleanup. ([#1955](https://github.com/EQEmu/Server/pull/1955)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
|
|
||||||
* #reload Command Overhaul. ([#2162](https://github.com/EQEmu/Server/pull/2162)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-10
|
|
||||||
* #reload level_mods could cause Non-Booted zones to crash. ([#2670](https://github.com/EQEmu/Server/pull/2670)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-24
|
|
||||||
* Add #bugs Command. ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Add #feature Command. ([#2142](https://github.com/EQEmu/Server/pull/2142)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Add #findcharacter Command. ([#2692](https://github.com/EQEmu/Server/pull/2692)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
|
||||||
* Add #findrecipe and #viewrecipe Commands. ([#2401](https://github.com/EQEmu/Server/pull/2401)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-31
|
|
||||||
* Add #setanon Command ([#2690](https://github.com/EQEmu/Server/pull/2690)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
|
||||||
* Add #suspendmulti Command. ([#2619](https://github.com/EQEmu/Server/pull/2619)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
|
||||||
* Add BestZ and Region Data to #loc ([#2245](https://github.com/EQEmu/Server/pull/2245)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-05
|
|
||||||
* Add additional #peqzone functionality. ([#2085](https://github.com/EQEmu/Server/pull/2085)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-01
|
|
||||||
* Add max_hp back to #modifynpcstat command. ([#2638](https://github.com/EQEmu/Server/pull/2638)) ([nytmyr](https://github.com/nytmyr)) 2022-12-13
|
|
||||||
* Adding movespeed to #showstats output ([#2596](https://github.com/EQEmu/Server/pull/2596)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
|
|
||||||
* Bug fix for #logs command. ([#2008](https://github.com/EQEmu/Server/pull/2008)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
|
|
||||||
* Cleanup #ai Command. ([#1980](https://github.com/EQEmu/Server/pull/1980)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
|
|
||||||
* Cleanup #appearanceeffects Command. ([#2777](https://github.com/EQEmu/Server/pull/2777)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
|
||||||
* Cleanup #attack Command. ([#2103](https://github.com/EQEmu/Server/pull/2103)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
|
||||||
* Cleanup #ban, #ipban, #flag, #kick, #setlsinfo, and #setpass Commands. ([#2104](https://github.com/EQEmu/Server/pull/2104)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
|
||||||
* Cleanup #chat Command. ([#2581](https://github.com/EQEmu/Server/pull/2581)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Cleanup #corpsefix Command. ([#2197](https://github.com/EQEmu/Server/pull/2197)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Cleanup #cvs Command. ([#2153](https://github.com/EQEmu/Server/pull/2153)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
|
||||||
* Cleanup #date Command. ([#2228](https://github.com/EQEmu/Server/pull/2228)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
|
||||||
* Cleanup #dbspawn2 Command. ([#2493](https://github.com/EQEmu/Server/pull/2493)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
|
||||||
* Cleanup #delacct Command. ([#2567](https://github.com/EQEmu/Server/pull/2567)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Cleanup #depop Command. ([#2536](https://github.com/EQEmu/Server/pull/2536)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Cleanup #depopzone Command. ([#2537](https://github.com/EQEmu/Server/pull/2537)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Cleanup #devtools Command. ([#2538](https://github.com/EQEmu/Server/pull/2538)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Cleanup #doanim Command. ([#2540](https://github.com/EQEmu/Server/pull/2540)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Cleanup #emote Command. ([#2535](https://github.com/EQEmu/Server/pull/2535)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Cleanup #emotesearch and #emoteview Command. ([#2494](https://github.com/EQEmu/Server/pull/2494)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
|
||||||
* Cleanup #emptyinventory Command. ([#2219](https://github.com/EQEmu/Server/pull/2219)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
|
|
||||||
* Cleanup #findaliases and #help Commands. ([#2204](https://github.com/EQEmu/Server/pull/2204)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Cleanup #findclass and #findrace Commands. ([#2211](https://github.com/EQEmu/Server/pull/2211)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Cleanup #flagedit Command. ([#1968](https://github.com/EQEmu/Server/pull/1968)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #freeze and #unfreeze Commands. ([#2102](https://github.com/EQEmu/Server/pull/2102)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
|
||||||
* Cleanup #gassign Command. ([#2101](https://github.com/EQEmu/Server/pull/2101)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #gearup Command. ([#2589](https://github.com/EQEmu/Server/pull/2589)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Cleanup #getvariable Command. ([#2100](https://github.com/EQEmu/Server/pull/2100)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
|
||||||
* Cleanup #guild Command ([#2693](https://github.com/EQEmu/Server/pull/2693)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-04
|
|
||||||
* Cleanup #hatelist Command. ([#1976](https://github.com/EQEmu/Server/pull/1976)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #heromodel Command. ([#2566](https://github.com/EQEmu/Server/pull/2566)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Cleanup #kill Command. ([#2195](https://github.com/EQEmu/Server/pull/2195)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
* Cleanup #level Command. ([#2203](https://github.com/EQEmu/Server/pull/2203)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Cleanup #logs Command. ([#1969](https://github.com/EQEmu/Server/pull/1969)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #makepet Command. ([#2105](https://github.com/EQEmu/Server/pull/2105)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #modifynpcstat Command. ([#2499](https://github.com/EQEmu/Server/pull/2499)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-30
|
|
||||||
* Cleanup #motd Command. ([#2190](https://github.com/EQEmu/Server/pull/2190)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
* Cleanup #name Command. ([#1977](https://github.com/EQEmu/Server/pull/1977)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #netstats Command. ([#1970](https://github.com/EQEmu/Server/pull/1970)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #npcedit Command. ([#2582](https://github.com/EQEmu/Server/pull/2582)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Cleanup #npcedit, #lastname, #title, and #titlesuffix Commands. ([#2215](https://github.com/EQEmu/Server/pull/2215)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
|
||||||
* Cleanup #npceditmass command. ([#1957](https://github.com/EQEmu/Server/pull/1957)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-03
|
|
||||||
* Cleanup #npcemote Command. ([#2106](https://github.com/EQEmu/Server/pull/2106)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #npcloot Command. ([#1974](https://github.com/EQEmu/Server/pull/1974)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-11
|
|
||||||
* Cleanup #npcsay and #npcshout Commands. ([#2107](https://github.com/EQEmu/Server/pull/2107)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #npcspecialattk Command. ([#2108](https://github.com/EQEmu/Server/pull/2108)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #npctype_cache Command. ([#2109](https://github.com/EQEmu/Server/pull/2109)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #npctypespawn Command. ([#2110](https://github.com/EQEmu/Server/pull/2110)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #nudge Command. ([#2220](https://github.com/EQEmu/Server/pull/2220)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-29
|
|
||||||
* Cleanup #oocmute Command. ([#2191](https://github.com/EQEmu/Server/pull/2191)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Cleanup #opcode Command. ([#2547](https://github.com/EQEmu/Server/pull/2547)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
|
||||||
* Cleanup #profanity Command. ([#2113](https://github.com/EQEmu/Server/pull/2113)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #push Command. ([#2114](https://github.com/EQEmu/Server/pull/2114)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #qglobal Command. ([#2115](https://github.com/EQEmu/Server/pull/2115)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #randomizefeatures Command. ([#2118](https://github.com/EQEmu/Server/pull/2118)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #refreshgroup Command. ([#2119](https://github.com/EQEmu/Server/pull/2119)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadaa Command. ([#2120](https://github.com/EQEmu/Server/pull/2120)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadallrules Command. ([#2121](https://github.com/EQEmu/Server/pull/2121)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadlevelmods Command. ([#2122](https://github.com/EQEmu/Server/pull/2122)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadmerchants Command. ([#2123](https://github.com/EQEmu/Server/pull/2123)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadperlexportsettings Command. ([#2124](https://github.com/EQEmu/Server/pull/2124)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadrulesworld Command. ([#2128](https://github.com/EQEmu/Server/pull/2128)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadstatic Command. ([#2130](https://github.com/EQEmu/Server/pull/2130)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadtitles Command. ([#2125](https://github.com/EQEmu/Server/pull/2125)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadtraps Command. ([#2126](https://github.com/EQEmu/Server/pull/2126)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadworld and #repop Command. ([#2127](https://github.com/EQEmu/Server/pull/2127)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #reloadzps Command. ([#2129](https://github.com/EQEmu/Server/pull/2129)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #resetaa Command. ([#2132](https://github.com/EQEmu/Server/pull/2132)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #resetaa_timer Command. ([#2131](https://github.com/EQEmu/Server/pull/2131)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #resetdisc_timer Command. ([#2133](https://github.com/EQEmu/Server/pull/2133)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #revoke Command. ([#2134](https://github.com/EQEmu/Server/pull/2134)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #roambox Command. ([#2135](https://github.com/EQEmu/Server/pull/2135)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #rules Command. ([#2593](https://github.com/EQEmu/Server/pull/2593)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
|
|
||||||
* Cleanup #save Command. ([#2136](https://github.com/EQEmu/Server/pull/2136)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #scale Command. ([#2591](https://github.com/EQEmu/Server/pull/2591)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
|
|
||||||
* Cleanup #scribespell and #scribespells Commands. ([#2534](https://github.com/EQEmu/Server/pull/2534)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Cleanup #sensetrap Command. ([#2137](https://github.com/EQEmu/Server/pull/2137)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #serverinfo Command. ([#2568](https://github.com/EQEmu/Server/pull/2568)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Cleanup #serverrules Command. ([#2139](https://github.com/EQEmu/Server/pull/2139)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #setlanguage Command. ([#2464](https://github.com/EQEmu/Server/pull/2464)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-13
|
|
||||||
* Cleanup #setskillall Command. ([#1992](https://github.com/EQEmu/Server/pull/1992)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
|
|
||||||
* Cleanup #shownpcgloballoot and #showzonegloballoot Command. ([#2141](https://github.com/EQEmu/Server/pull/2141)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #showskills Command. ([#1994](https://github.com/EQEmu/Server/pull/1994)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-15
|
|
||||||
* Cleanup #spawneditmass Command. ([#2229](https://github.com/EQEmu/Server/pull/2229)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
|
||||||
* Cleanup #spawnfix Command. ([#2143](https://github.com/EQEmu/Server/pull/2143)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #spawnstatus Command. ([#2144](https://github.com/EQEmu/Server/pull/2144)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #summon Command. ([#2145](https://github.com/EQEmu/Server/pull/2145)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-06
|
|
||||||
* Cleanup #summonburiedplayercorpse Command. ([#2146](https://github.com/EQEmu/Server/pull/2146)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #suspend Command. ([#2564](https://github.com/EQEmu/Server/pull/2564)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Cleanup #task Command. ([#2071](https://github.com/EQEmu/Server/pull/2071)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-14
|
|
||||||
* Cleanup #time and #timezone Command. ([#2147](https://github.com/EQEmu/Server/pull/2147)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #timers Command. ([#2562](https://github.com/EQEmu/Server/pull/2562)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Cleanup #trapinfo Command. ([#2148](https://github.com/EQEmu/Server/pull/2148)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #ucs Command. ([#2149](https://github.com/EQEmu/Server/pull/2149)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Cleanup #undye and #undyeme Commands. ([#1966](https://github.com/EQEmu/Server/pull/1966)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #unscribespell Command. ([#1998](https://github.com/EQEmu/Server/pull/1998)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
|
|
||||||
* Cleanup #untraindisc Command. ([#1996](https://github.com/EQEmu/Server/pull/1996)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-16
|
|
||||||
* Cleanup #version Command. ([#1967](https://github.com/EQEmu/Server/pull/1967)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Cleanup #worldwide command. ([#2021](https://github.com/EQEmu/Server/pull/2021)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
|
|
||||||
* Cleanup #xtargets Command. ([#2545](https://github.com/EQEmu/Server/pull/2545)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
|
||||||
* Cleanup #zone and #zoneinstance Commands. ([#2202](https://github.com/EQEmu/Server/pull/2202)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Command Status Reload and Helper Method ([#2377](https://github.com/EQEmu/Server/pull/2377)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
|
||||||
* Consolidate #lock and #unlock Commands into #serverlock. ([#2193](https://github.com/EQEmu/Server/pull/2193)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
* Fix #copycharacter command crash ([#2446](https://github.com/EQEmu/Server/pull/2446)) ([Akkadius](https://github.com/Akkadius)) 2022-09-25
|
|
||||||
* Fix #killallnpcs from crashing ([#2037](https://github.com/EQEmu/Server/pull/2037)) ([Akkadius](https://github.com/Akkadius)) 2022-03-07
|
|
||||||
* Fix Flymode Command Help Prompt ([#2669](https://github.com/EQEmu/Server/pull/2669)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-23
|
|
||||||
* Fix typos in #ban and #ipban Commands. ([#2209](https://github.com/EQEmu/Server/pull/2209)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
|
|
||||||
* Make #damage require a target ([#2426](https://github.com/EQEmu/Server/pull/2426)) ([hgtw](https://github.com/hgtw)) 2022-09-05
|
|
||||||
* Nested Command Aliases ([#2636](https://github.com/EQEmu/Server/pull/2636)) ([Akkadius](https://github.com/Akkadius)) 2022-12-15
|
|
||||||
* Remove #guildapprove, #guildcreate, and #guildlist Commands ([#2775](https://github.com/EQEmu/Server/pull/2775)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
|
||||||
* Remove #iteminfo Command. ([#2565](https://github.com/EQEmu/Server/pull/2565)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Remove #profiledump and #profilereset Commands. ([#2546](https://github.com/EQEmu/Server/pull/2546)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
|
||||||
* Remove #undyeme Command. ([#2776](https://github.com/EQEmu/Server/pull/2776)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
|
||||||
* Remove unused #bestz and #pf Commands. ([#2112](https://github.com/EQEmu/Server/pull/2112)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Remove unused/broken #deletegraveyard and #setgraveyard Commands. ([#2198](https://github.com/EQEmu/Server/pull/2198)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
|
|
||||||
### Diawind
|
|
||||||
|
|
||||||
* Plus sign markdown fix ([#2727](https://github.com/EQEmu/Server/pull/2727)) ([Akkadius](https://github.com/Akkadius)) 2023-01-12
|
|
||||||
|
|
||||||
### Feature
|
|
||||||
|
|
||||||
* AA Cap Limit ([#2423](https://github.com/EQEmu/Server/pull/2423)) ([fryguy503](https://github.com/fryguy503)) 2022-10-13
|
|
||||||
* Add "Keeps Sold Items" Flag to NPCs ([#2671](https://github.com/EQEmu/Server/pull/2671)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
|
||||||
* Add Experience Gain Toggle. ([#2676](https://github.com/EQEmu/Server/pull/2676)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-30
|
|
||||||
* Add Guild Chat to Console. ([#2387](https://github.com/EQEmu/Server/pull/2387)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
|
||||||
* Add Hate Override for Heals ([#2485](https://github.com/EQEmu/Server/pull/2485)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-14
|
|
||||||
* Add Rule to Disable Group EXP Modifier. ([#2741](https://github.com/EQEmu/Server/pull/2741)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
|
||||||
* Add Support for "Show Mine Only" Filters ([#2484](https://github.com/EQEmu/Server/pull/2484)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
|
||||||
* Add Type 49545 to Spell Resistrictions ([#2436](https://github.com/EQEmu/Server/pull/2436)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
|
|
||||||
* Add humanoid and non-wielded restrictions to pick pocket ([#2276](https://github.com/EQEmu/Server/pull/2276)) ([noudess](https://github.com/noudess)) 2022-07-03
|
|
||||||
* Add player /inspect quest event ([#2508](https://github.com/EQEmu/Server/pull/2508)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
|
||||||
* Add special ability to block /open ([#2506](https://github.com/EQEmu/Server/pull/2506)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
|
||||||
* Allow Focus Effects to be Filtered out. ([#2447](https://github.com/EQEmu/Server/pull/2447)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
|
|
||||||
* Allow pets to zone with permanent (buffdurationformula 50) buffs to maintain them through zone transitions ([#2035](https://github.com/EQEmu/Server/pull/2035)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
|
||||||
* Bind Wound and Forage while mounted. ([#2257](https://github.com/EQEmu/Server/pull/2257)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
|
||||||
* Change #scribespells to be aware of spellgroups & ranks ([#2501](https://github.com/EQEmu/Server/pull/2501)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-06
|
|
||||||
* Change GetSkillDmgAmt to int32 ([#2364](https://github.com/EQEmu/Server/pull/2364)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-10
|
|
||||||
* Change Lifetap Emotes to be filterable. ([#2454](https://github.com/EQEmu/Server/pull/2454)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-29
|
|
||||||
* Change Mana Costs to use Signed Int ([#2384](https://github.com/EQEmu/Server/pull/2384)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-21
|
|
||||||
* Change mana_used to int32 ([#2321](https://github.com/EQEmu/Server/pull/2321)) ([Aeadoin](https://github.com/Aeadoin)) 2022-07-30
|
|
||||||
* Client Checksum Verification (Resubmit old 1678) ([#1922](https://github.com/EQEmu/Server/pull/1922)) ([noudess](https://github.com/noudess)) 2022-03-07
|
|
||||||
* EQ2-style implied targeting for spells. ([#2032](https://github.com/EQEmu/Server/pull/2032)) ([catapultam-habeo](https://github.com/catapultam-habeo)) 2022-03-07
|
|
||||||
* Faction Association ([#2408](https://github.com/EQEmu/Server/pull/2408)) ([mackal](https://github.com/mackal)) 2022-09-03
|
|
||||||
* GM State Change Persistance ([#2328](https://github.com/EQEmu/Server/pull/2328)) ([fryguy503](https://github.com/fryguy503)) 2022-07-31
|
|
||||||
* Implement Heroic Strikethrough to NPCs ([#2395](https://github.com/EQEmu/Server/pull/2395)) ([Aeadoin](https://github.com/Aeadoin)) 2022-08-31
|
|
||||||
* Implement OP_CashReward ([#2307](https://github.com/EQEmu/Server/pull/2307)) ([mackal](https://github.com/mackal)) 2022-07-15
|
|
||||||
* Instance Version Specific Experience Modifiers ([#2376](https://github.com/EQEmu/Server/pull/2376)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
|
||||||
* NPCs with bows and arrows do ranged attacks ([#2322](https://github.com/EQEmu/Server/pull/2322)) ([mackal](https://github.com/mackal)) 2022-07-30
|
|
||||||
* Soft Delete Bots on Character Soft Delete ([#2467](https://github.com/EQEmu/Server/pull/2467)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
|
||||||
* Spell Ranks will now work with AllowSpellMemorizeFromItem Rule ([#2475](https://github.com/EQEmu/Server/pull/2475)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
|
||||||
* Update HateMod used by SPA 114 to Int32. ([#2428](https://github.com/EQEmu/Server/pull/2428)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-08
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
|
|
||||||
* #npcstats command displaying incorrect faction ([#2710](https://github.com/EQEmu/Server/pull/2710)) ([noudess](https://github.com/noudess)) 2023-01-08
|
|
||||||
* #peqzone no longer bypass Handle_OP_ZoneChange ([#2063](https://github.com/EQEmu/Server/pull/2063)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-19
|
|
||||||
* #scribespells triggered error on mysql keyword rank ([#2779](https://github.com/EQEmu/Server/pull/2779)) ([noudess](https://github.com/noudess)) 2023-01-21
|
|
||||||
* #tune command various fixes ([#2046](https://github.com/EQEmu/Server/pull/2046)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-11
|
|
||||||
* Add Complete Heal Spell back to IsCompleteHealSpell Method ([#2722](https://github.com/EQEmu/Server/pull/2722)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-11
|
|
||||||
* Add SE_MakeDrunk to avoid error message. ([#2601](https://github.com/EQEmu/Server/pull/2601)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
|
||||||
* Add omitted function call in UCS ([#2768](https://github.com/EQEmu/Server/pull/2768)) ([Valorith](https://github.com/Valorith)) 2023-01-20
|
|
||||||
* Add required distance to CoTH before aggro wipe ([#2253](https://github.com/EQEmu/Server/pull/2253)) ([fryguy503](https://github.com/fryguy503)) 2022-07-03
|
|
||||||
* Adjustment for nullptr crash ([#2232](https://github.com/EQEmu/Server/pull/2232)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
|
|
||||||
* Alleviate some lag with crosszone/worldwide spell casting. ([#2016](https://github.com/EQEmu/Server/pull/2016)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-21
|
|
||||||
* Allow High Level Spells to be Unmemorized. ([#2641](https://github.com/EQEmu/Server/pull/2641)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
|
||||||
* Allow Songs to be scribed from scrolls ([#2460](https://github.com/EQEmu/Server/pull/2460)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-12
|
|
||||||
* AltCurrencySelectItemReply_Struct was not handled correctly. ([#2702](https://github.com/EQEmu/Server/pull/2702)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-04
|
|
||||||
* Any use of TempName left old clean_name. ([#1946](https://github.com/EQEmu/Server/pull/1946)) ([noudess](https://github.com/noudess)) 2022-01-26
|
|
||||||
* Avoid erase in discord queue range loop ([#2411](https://github.com/EQEmu/Server/pull/2411)) ([hgtw](https://github.com/hgtw)) 2022-09-03
|
|
||||||
* Bandolier didn't recognize source weapon on cursor ([#2026](https://github.com/EQEmu/Server/pull/2026)) ([noudess](https://github.com/noudess)) 2022-03-07
|
|
||||||
* Bard Invisible causing display issues. ([#2067](https://github.com/EQEmu/Server/pull/2067)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-01
|
|
||||||
* Bard update fixes 1 ([#1982](https://github.com/EQEmu/Server/pull/1982)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-09
|
|
||||||
* Bazaar Search MYSQL Error ([#2252](https://github.com/EQEmu/Server/pull/2252)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
|
|
||||||
* Blocked spells max spell id increased ([#2207](https://github.com/EQEmu/Server/pull/2207)) ([Isaaru](https://github.com/Isaaru)) 2022-05-25
|
|
||||||
* Boats should never get FixZ'd ([#2246](https://github.com/EQEmu/Server/pull/2246)) ([noudess](https://github.com/noudess)) 2022-07-02
|
|
||||||
* Clamp Item Ldon Sell Back Rates. ([#2592](https://github.com/EQEmu/Server/pull/2592)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-30
|
|
||||||
* Clear title/suffix bug fix. ([#2068](https://github.com/EQEmu/Server/pull/2068)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
|
|
||||||
* Correct (probably) unintended bitwise AND instead of logical AND ([#2239](https://github.com/EQEmu/Server/pull/2239)) ([Quintinon](https://github.com/Quintinon)) 2022-06-02
|
|
||||||
* Correct type signed/unsigned int when reading item from database in shareddb ([#2269](https://github.com/EQEmu/Server/pull/2269)) ([Quintinon](https://github.com/Quintinon)) 2022-06-15
|
|
||||||
* Data Bucket Permanent Duration String ([#2624](https://github.com/EQEmu/Server/pull/2624)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
|
||||||
* Delete NpcType Struct returned by Bot::CreateDefaultNPCTypeStructForBot() when unused ([#2267](https://github.com/EQEmu/Server/pull/2267)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
|
|
||||||
* Do not allow /open to be used on traps or auras, causes crash ([#1951](https://github.com/EQEmu/Server/pull/1951)) ([KayenEQ](https://github.com/KayenEQ)) 2022-01-30
|
|
||||||
* Doors::GetSize() Perl Croak Typo. ([#2027](https://github.com/EQEmu/Server/pull/2027)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
|
|
||||||
* EVENT_ENTER_AREA/EVENT_LEAVE_AREA. ([#2698](https://github.com/EQEmu/Server/pull/2698)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
|
||||||
* Edge case AA reset timer issue fixes ([#1995](https://github.com/EQEmu/Server/pull/1995)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-14
|
|
||||||
* Fix #door Save ([#2699](https://github.com/EQEmu/Server/pull/2699)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
|
||||||
* Fix #findaa and GetAAName(). ([#2774](https://github.com/EQEmu/Server/pull/2774)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
|
||||||
* Fix #zone 0. ([#2691](https://github.com/EQEmu/Server/pull/2691)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Fix Aug Clicks where item has no click effect. ([#2725](https://github.com/EQEmu/Server/pull/2725)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-12
|
|
||||||
* Fix Bot "Failed to Load" Messages. ([#2719](https://github.com/EQEmu/Server/pull/2719)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
|
|
||||||
* Fix Bot Group Loading ([#2780](https://github.com/EQEmu/Server/pull/2780)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-22
|
|
||||||
* Fix Bot ^spellsettingsadd command ([#2603](https://github.com/EQEmu/Server/pull/2603)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-01
|
|
||||||
* Fix Duplicate Silent Saylink Messages ([#2386](https://github.com/EQEmu/Server/pull/2386)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
|
||||||
* Fix EntityList::GetBotListByCharacterID() ([#2569](https://github.com/EQEmu/Server/pull/2569)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Fix Flag Updating with SetGMStatus() in Lua. ([#2554](https://github.com/EQEmu/Server/pull/2554)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-20
|
|
||||||
* Fix Group XP not working. ([#2748](https://github.com/EQEmu/Server/pull/2748)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
|
|
||||||
* Fix HP Regen Per Second. ([#2206](https://github.com/EQEmu/Server/pull/2206)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-25
|
|
||||||
* Fix IDFile Crash with spaces or invalid data. ([#2597](https://github.com/EQEmu/Server/pull/2597)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
|
||||||
* Fix IP Exemptions. ([#2189](https://github.com/EQEmu/Server/pull/2189)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-28
|
|
||||||
* Fix Instance Repository ([#2598](https://github.com/EQEmu/Server/pull/2598)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
|
||||||
* Fix Legacy Combat Lua Script ([#2226](https://github.com/EQEmu/Server/pull/2226)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
|
|
||||||
* Fix MovePC in #zone and #zoneinstance Commands. ([#2236](https://github.com/EQEmu/Server/pull/2236)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
|
||||||
* Fix NPC Reference in EVENT_SPAWN ([#2712](https://github.com/EQEmu/Server/pull/2712)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-08
|
|
||||||
* Fix ST_TargetsTarget Spells with Restrictions ([#2746](https://github.com/EQEmu/Server/pull/2746)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
|
||||||
* Fix Silent Saylinks Sending Message to Others. ([#2389](https://github.com/EQEmu/Server/pull/2389)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-22
|
|
||||||
* Fix Spell Bucket and Spell Global Logic Checks. ([#2285](https://github.com/EQEmu/Server/pull/2285)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
|
||||||
* Fix Spellinfo Command to work with SpellIDs above int16 ([#2437](https://github.com/EQEmu/Server/pull/2437)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-20
|
|
||||||
* Fix Strings::Money Missing Conditions. ([#2383](https://github.com/EQEmu/Server/pull/2383)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-21
|
|
||||||
* Fix Swarm Pet Flurry/Rampages Messages ([#2444](https://github.com/EQEmu/Server/pull/2444)) ([Aeadoin](https://github.com/Aeadoin)) 2022-09-25
|
|
||||||
* Fix bot compile locking client on server enter. ([#2210](https://github.com/EQEmu/Server/pull/2210)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-26
|
|
||||||
* Fix bot guild removal. ([#2194](https://github.com/EQEmu/Server/pull/2194)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
* Fix botgrouplist to display unique entries. ([#2785](https://github.com/EQEmu/Server/pull/2785)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
|
||||||
* Fix bots equipping augments. ([#2772](https://github.com/EQEmu/Server/pull/2772)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-22
|
|
||||||
* Fix case-sensitivity in #suspend Command. ([#2613](https://github.com/EQEmu/Server/pull/2613)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-05
|
|
||||||
* Fix duplicate and missing messages due to innate in spells ([#2170](https://github.com/EQEmu/Server/pull/2170)) ([noudess](https://github.com/noudess)) 2022-05-20
|
|
||||||
* Fix empty spawned merchants ([#2275](https://github.com/EQEmu/Server/pull/2275)) ([hgtw](https://github.com/hgtw)) 2022-06-28
|
|
||||||
* Fix for Bot command casting ([#1990](https://github.com/EQEmu/Server/pull/1990)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-12
|
|
||||||
* Fix for PR1954 target restriction with npcpc_only_flag from groupbuffs ([#1986](https://github.com/EQEmu/Server/pull/1986)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
|
|
||||||
* Fix for being able to skill up on corspe. ([#2058](https://github.com/EQEmu/Server/pull/2058)) ([noudess](https://github.com/noudess)) 2022-03-19
|
|
||||||
* Fix for castspell command ([#2010](https://github.com/EQEmu/Server/pull/2010)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-18
|
|
||||||
* Fix issue where #advnpcspawn addspawn does not add spawn sometimes. ([#2247](https://github.com/EQEmu/Server/pull/2247)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
|
|
||||||
* Fix issue where you can set your title to titles you don't have. ([#1917](https://github.com/EQEmu/Server/pull/1917)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-30
|
|
||||||
* Fix issue with Bot::LoadAndSpawnAllZonedBots. ([#2733](https://github.com/EQEmu/Server/pull/2733)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
|
||||||
* Fix issue with mobs summoning PCs into ceilings ([#1921](https://github.com/EQEmu/Server/pull/1921)) ([noudess](https://github.com/noudess)) 2022-01-30
|
|
||||||
* Fix loading world shared task state ([#2398](https://github.com/EQEmu/Server/pull/2398)) ([hgtw](https://github.com/hgtw)) 2022-08-28
|
|
||||||
* Fix luamod GetExperienceForKill return value ([Cole-SoD](https://github.com/Cole-SoD)) 2023-01-12
|
|
||||||
* Fix memory leak in ucs ([#2409](https://github.com/EQEmu/Server/pull/2409)) ([hgtw](https://github.com/hgtw)) 2022-09-03
|
|
||||||
* Fix miscellaneous memory leaks related to EQApplicationPacket and it's pBuffer ([#2262](https://github.com/EQEmu/Server/pull/2262)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
|
||||||
* Fix null pointer crash on zones that have not booted a zone yet with #reload commands or anything that calls GetZoneDescription ([#2231](https://github.com/EQEmu/Server/pull/2231)) ([Akkadius](https://github.com/Akkadius)) 2022-06-01
|
|
||||||
* Fix possible crash in ProcessSpecialAbilities. ([#2630](https://github.com/EQEmu/Server/pull/2630)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
|
||||||
* Fix possible crash with zone name methods. ([#2055](https://github.com/EQEmu/Server/pull/2055)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
|
|
||||||
* Fix possible issue where variables have the same name. ([#2156](https://github.com/EQEmu/Server/pull/2156)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
|
||||||
* Fix quest::updatespawntimer() Perl croak. ([#1947](https://github.com/EQEmu/Server/pull/1947)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-01-26
|
|
||||||
* Fix recipient sound (vtell) on non-player races ([#2066](https://github.com/EQEmu/Server/pull/2066)) ([noudess](https://github.com/noudess)) 2022-04-02
|
|
||||||
* Fix scenario where dereferenced object could be null. ([#2784](https://github.com/EQEmu/Server/pull/2784)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-23
|
|
||||||
* Fix stack leaks in Lua events #2254 ([hgtw](https://github.com/hgtw)) 2022-06-09
|
|
||||||
* Fix trading with bots when in an illusion. ([#2645](https://github.com/EQEmu/Server/pull/2645)) ([nytmyr](https://github.com/nytmyr)) 2022-12-15
|
|
||||||
* Fix two invalid data accesses in zone/client.cpp ([#2238](https://github.com/EQEmu/Server/pull/2238)) ([Quintinon](https://github.com/Quintinon)) 2022-06-07
|
|
||||||
* Fixed Spell Logic for Bot Nukes ([#2481](https://github.com/EQEmu/Server/pull/2481)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-13
|
|
||||||
* Fixed message on promote/demote permissions check. ([#2700](https://github.com/EQEmu/Server/pull/2700)) ([Valorith](https://github.com/Valorith)) 2023-01-02
|
|
||||||
* Fixed several instances of incorrect comparision - & executes after == ([#2025](https://github.com/EQEmu/Server/pull/2025)) ([noudess](https://github.com/noudess)) 2022-03-07
|
|
||||||
* Force NPCs to respect special ability 24 and 50 when set on player pets ([#2059](https://github.com/EQEmu/Server/pull/2059)) ([Natedog2012](https://github.com/Natedog2012)) 2022-03-16
|
|
||||||
* Free return value of ZoneDatabase::LoadTraderItemWithCharges() ([#2264](https://github.com/EQEmu/Server/pull/2264)) ([Quintinon](https://github.com/Quintinon)) 2022-06-18
|
|
||||||
* Hacker_Str was causing sql errors - Non Escaped ([#2251](https://github.com/EQEmu/Server/pull/2251)) ([fryguy503](https://github.com/fryguy503)) 2022-06-08
|
|
||||||
* Handle memory leaks from return value of Client::GetTraderItems() ([#2266](https://github.com/EQEmu/Server/pull/2266)) ([Quintinon](https://github.com/Quintinon)) 2022-07-03
|
|
||||||
* Handle_OP_AugmentItem could cause Zone crash ([#2750](https://github.com/EQEmu/Server/pull/2750)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-17
|
|
||||||
* HasPet() Zone Crashes ([#2744](https://github.com/EQEmu/Server/pull/2744)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-15
|
|
||||||
* Illusions will now properly display armor to other clients when they zone in. ([#1958](https://github.com/EQEmu/Server/pull/1958)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-04
|
|
||||||
* Instrument Mods should not affect spells that change model size. ([#2072](https://github.com/EQEmu/Server/pull/2072)) ([KayenEQ](https://github.com/KayenEQ)) 2022-04-13
|
|
||||||
* Invisible will display as dropped now on air pets when they attack. ([#2042](https://github.com/EQEmu/Server/pull/2042)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
|
|
||||||
* IsDamage test for lifetap was not complete. ([#2213](https://github.com/EQEmu/Server/pull/2213)) ([noudess](https://github.com/noudess)) 2022-05-27
|
|
||||||
* Limit merchant temp item list to zone and instance ([#2346](https://github.com/EQEmu/Server/pull/2346)) ([mackal](https://github.com/mackal)) 2022-07-31
|
|
||||||
* Lua GetBlockNextSpell() no return. ([#2151](https://github.com/EQEmu/Server/pull/2151)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Make Perl TakeMoneyFromPP int64 ([#2158](https://github.com/EQEmu/Server/pull/2158)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-08
|
|
||||||
* Missing break ([#2031](https://github.com/EQEmu/Server/pull/2031)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-04
|
|
||||||
* Move EVENT_SPAWN for adding NPCs back to original spot, also add NPCs… ([#2749](https://github.com/EQEmu/Server/pull/2749)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-17
|
|
||||||
* NPC Constructor was passing hp_regen_per_second out of order to Mob(). ([#2681](https://github.com/EQEmu/Server/pull/2681)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-29
|
|
||||||
* NPC::CountItem and Corpse::CountItem 0 Charge Item Fix. ([#1959](https://github.com/EQEmu/Server/pull/1959)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-04
|
|
||||||
* NPC::GetNPCStat has no default return. ([#2150](https://github.com/EQEmu/Server/pull/2150)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* NPCs were getting weapon proc added twice ([#2277](https://github.com/EQEmu/Server/pull/2277)) ([noudess](https://github.com/noudess)) 2022-07-07
|
|
||||||
* Objects::GetTiltX() and Objects::GetTiltY() Perl Croak Typos. ([#2028](https://github.com/EQEmu/Server/pull/2028)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-04
|
|
||||||
* PR 1982 ([#1985](https://github.com/EQEmu/Server/pull/1985)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-10
|
|
||||||
* PR 2032 would lock client on casting fail as written ([#2038](https://github.com/EQEmu/Server/pull/2038)) ([KayenEQ](https://github.com/KayenEQ)) 2022-03-07
|
|
||||||
* Remove StringUtilTest::EscapeStringMemoryTest ([#2310](https://github.com/EQEmu/Server/pull/2310)) ([mackal](https://github.com/mackal)) 2022-07-15
|
|
||||||
* Remove Unnecessary Attack Log ([#2643](https://github.com/EQEmu/Server/pull/2643)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
|
||||||
* Remove unnecessary log messages. ([#2642](https://github.com/EQEmu/Server/pull/2642)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-14
|
|
||||||
* Removed Lua Event Argument Dispatch. ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-01
|
|
||||||
* Resolve Warning due to Virtual Mob Method GetInv() ([#2650](https://github.com/EQEmu/Server/pull/2650)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-19
|
|
||||||
* Resolve XP Calculation Bug introduced w/ recent Rule addition ([#2703](https://github.com/EQEmu/Server/pull/2703)) ([Valorith](https://github.com/Valorith)) 2023-01-07
|
|
||||||
* Resolve logic error in Raid::QueueClients ([#2404](https://github.com/EQEmu/Server/pull/2404)) ([mackal](https://github.com/mackal)) 2022-09-01
|
|
||||||
* Resolve subroutine redefinition due to bot methods. ([#2117](https://github.com/EQEmu/Server/pull/2117)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Restore missing messages for lifetap and dmg spells. ([#2057](https://github.com/EQEmu/Server/pull/2057)) ([noudess](https://github.com/noudess)) 2022-04-14
|
|
||||||
* Shared Memory Faction Association Typo ([#2419](https://github.com/EQEmu/Server/pull/2419)) ([mackal](https://github.com/mackal)) 2022-09-03
|
|
||||||
* Spell Buckets/Globals SQL Escape. ([#2019](https://github.com/EQEmu/Server/pull/2019)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-26
|
|
||||||
* Spell Buckets/Globals did not allow string-based values. ([#2043](https://github.com/EQEmu/Server/pull/2043)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-09
|
|
||||||
* Stop skill ups on Charmed NPCs. ([#2249](https://github.com/EQEmu/Server/pull/2249)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-10
|
|
||||||
* Summon Companion causing pets to warps away. ([#1972](https://github.com/EQEmu/Server/pull/1972)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-08
|
|
||||||
* Touch Of Vinitras was ignoring pet DT rule ([#2469](https://github.com/EQEmu/Server/pull/2469)) ([Aeadoin](https://github.com/Aeadoin)) 2022-10-03
|
|
||||||
* Tradeskill Autocombine MinSkill ([#2260](https://github.com/EQEmu/Server/pull/2260)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
|
||||||
* Tradeskill Item 0 Error ([#2256](https://github.com/EQEmu/Server/pull/2256)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
|
||||||
* Zone Flags Regression ([#2760](https://github.com/EQEmu/Server/pull/2760)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
|
|
||||||
* checking casting_spell_slot before its defined is bad ([#2013](https://github.com/EQEmu/Server/pull/2013)) ([KayenEQ](https://github.com/KayenEQ)) 2022-02-20
|
|
||||||
* manifest for db version 9176 had incorrect field name ([#2062](https://github.com/EQEmu/Server/pull/2062)) ([noudess](https://github.com/noudess)) 2022-03-19
|
|
||||||
* quest::MovePCInstance() Arguments Fix. ([#2020](https://github.com/EQEmu/Server/pull/2020)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-27
|
|
||||||
|
|
||||||
### Hotfix
|
|
||||||
|
|
||||||
* Add Bazaar portal discs to SQL ([Akkadius](https://github.com/Akkadius)) 2022-09-05
|
|
||||||
* Add discord_webhooks to server tables ([Akkadius](https://github.com/Akkadius)) 2022-07-03
|
|
||||||
* Blocks are nested too deeply. ([#2689](https://github.com/EQEmu/Server/pull/2689)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Cleanup #questerrors Command. ([#2116](https://github.com/EQEmu/Server/pull/2116)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-07
|
|
||||||
* Compiling fails on FMT 9.1 with Bots ([#2665](https://github.com/EQEmu/Server/pull/2665)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-21
|
|
||||||
* Correct database call to point to the content_db connection ([Akkadius](https://github.com/Akkadius)) 2022-06-12
|
|
||||||
* Corrected misnamed Database Query file for Experience Toggle ([#2683](https://github.com/EQEmu/Server/pull/2683)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-31
|
|
||||||
* Faction associations file naming / lock consistency ([Akkadius](https://github.com/Akkadius)) 2022-09-05
|
|
||||||
* Fix DB version merge ([Akkadius](https://github.com/Akkadius)) 2022-05-08
|
|
||||||
* Fix door click crash issue if destination zone doesn't exist ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
* Fix issue with Bot Loading with 0 Health causing buffs to be lost. ([#2552](https://github.com/EQEmu/Server/pull/2552)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-18
|
|
||||||
* Fix lua mod load path ([Akkadius](https://github.com/Akkadius)) 2022-09-29
|
|
||||||
* Fix merge issue ([Akkadius](https://github.com/Akkadius)) 2022-07-14
|
|
||||||
* Fix path load ordering for CLI commands ([Akkadius](https://github.com/Akkadius)) 2022-10-16
|
|
||||||
* Fix potential race for crash dumps (Linux) ([Akkadius](https://github.com/Akkadius)) 2022-07-31
|
|
||||||
* Fix regression caused by #2129 ([Akkadius](https://github.com/Akkadius)) 2022-05-09
|
|
||||||
* Flipped positive / negative values for legacy_combat.lua ([Akkadius](https://github.com/Akkadius)) 2022-06-09
|
|
||||||
* Force collation on conversion script ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
|
||||||
* Instances Repository Fix ([#2576](https://github.com/EQEmu/Server/pull/2576)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
|
||||||
* Login Server failing to compile on Windows. ([#2758](https://github.com/EQEmu/Server/pull/2758)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-19
|
|
||||||
* Lua Parser Needs Lua_ItemInst ([#2696](https://github.com/EQEmu/Server/pull/2696)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Make sure we have a proper split size before assuming we can split it ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
* Move discord_webhooks to state tables because we don't want webhooks being exported ([Akkadius](https://github.com/Akkadius)) 2022-07-03
|
|
||||||
* Possible windows compile fix ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
|
||||||
* Possible windows compile fix take 2 ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
|
||||||
* Remove appveyor fetch bots ([Akkadius](https://github.com/Akkadius)) 2023-01-21
|
|
||||||
* Remove expansion field from account for those who have it ([#2357](https://github.com/EQEmu/Server/pull/2357)) ([Akkadius](https://github.com/Akkadius)) 2022-08-01
|
|
||||||
* Resolve Zone Crashing when grouped with Bots. ([#2747](https://github.com/EQEmu/Server/pull/2747)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-16
|
|
||||||
* Resolve issue with Bot Casting after zoning. ([#2617](https://github.com/EQEmu/Server/pull/2617)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
|
||||||
* Return weather_type_map ([Akkadius](https://github.com/Akkadius)) 2022-10-14
|
|
||||||
* SQL Update ([Akkadius](https://github.com/Akkadius)) 2022-07-31
|
|
||||||
* Shared Memory Protection Fixes ([Akkadius](https://github.com/Akkadius)) 2022-07-27
|
|
||||||
* Windows compile fix take 3 (final) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
|
||||||
* fix manifest ([Akkadius](https://github.com/Akkadius)) 2022-07-16
|
|
||||||
|
|
||||||
### Logging
|
|
||||||
|
|
||||||
* Add stack trace in code paths that shouldn't occur ([#2453](https://github.com/EQEmu/Server/pull/2453)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
|
||||||
* Cleanup AI Logging Events ([#2615](https://github.com/EQEmu/Server/pull/2615)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-04
|
|
||||||
* Fix log messages to final damage values ([#2056](https://github.com/EQEmu/Server/pull/2056)) ([noudess](https://github.com/noudess)) 2022-03-14
|
|
||||||
* Fix zoning log typo ([#2478](https://github.com/EQEmu/Server/pull/2478)) ([Akkadius](https://github.com/Akkadius)) 2022-10-11
|
|
||||||
* Force crash logs to always be on regardless of setting ([#2762](https://github.com/EQEmu/Server/pull/2762)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
* Improvements to GM Say Logging ([#2765](https://github.com/EQEmu/Server/pull/2765)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
* Logging Improvements ([#2755](https://github.com/EQEmu/Server/pull/2755)) ([Akkadius](https://github.com/Akkadius)) 2023-01-18
|
|
||||||
* More AI Logging Cleanup ([#2616](https://github.com/EQEmu/Server/pull/2616)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-10
|
|
||||||
* Netcode Logging Unify ([#2443](https://github.com/EQEmu/Server/pull/2443)) ([Akkadius](https://github.com/Akkadius)) 2022-09-28
|
|
||||||
* Remove function prefixes ([#2766](https://github.com/EQEmu/Server/pull/2766)) ([Akkadius](https://github.com/Akkadius)) 2023-01-20
|
|
||||||
* Remove loginserver unhandled error ([#2458](https://github.com/EQEmu/Server/pull/2458)) ([Akkadius](https://github.com/Akkadius)) 2022-09-29
|
|
||||||
* Reset stream so we don't bold the whole line ([Akkadius](https://github.com/Akkadius)) 2023-01-18
|
|
||||||
* Table Injection - Member Variable Cleanup ([#2281](https://github.com/EQEmu/Server/pull/2281)) ([Akkadius](https://github.com/Akkadius)) 2022-07-07
|
|
||||||
* Update BUILD_LOGGING=false Blank Aliases ([#2083](https://github.com/EQEmu/Server/pull/2083)) ([Akkadius](https://github.com/Akkadius)) 2022-05-01
|
|
||||||
|
|
||||||
### Luamod
|
|
||||||
|
|
||||||
* Add CalcSpellEffectValue_formula to luamods ([#2721](https://github.com/EQEmu/Server/pull/2721)) ([Natedog2012](https://github.com/Natedog2012)) 2023-01-11
|
|
||||||
|
|
||||||
### Mercs
|
|
||||||
|
|
||||||
* Add Mercenary Support ([#2745](https://github.com/EQEmu/Server/pull/2745)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-17
|
|
||||||
|
|
||||||
### Optimization
|
|
||||||
|
|
||||||
* Handle channel name filter checks in memory ([#2767](https://github.com/EQEmu/Server/pull/2767)) ([Valorith](https://github.com/Valorith)) 2023-01-20
|
|
||||||
|
|
||||||
### QS
|
|
||||||
|
|
||||||
* Database class name change ([#2743](https://github.com/EQEmu/Server/pull/2743)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
|
|
||||||
|
|
||||||
### Quest API
|
|
||||||
|
|
||||||
* Add AddAISpellEffect(spell_effect_id, base_value, limit_value, max_value) and RemoveAISpellEffect(spell_effect_id) to Lua. ([#1981](https://github.com/EQEmu/Server/pull/1981)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-09
|
|
||||||
* Add AddItem() to Perl/Lua. ([#2054](https://github.com/EQEmu/Server/pull/2054)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-13
|
|
||||||
* Add AddPlatinum(), GetCarriedPlatinum() and TakePlatinum() to Perl/Lua. ([#2079](https://github.com/EQEmu/Server/pull/2079)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
|
||||||
* Add Area Damage Methods to Perl/Lua. ([#2549](https://github.com/EQEmu/Server/pull/2549)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-17
|
|
||||||
* Add Augment Slot Type/Visible to GetItemStat ([#2686](https://github.com/EQEmu/Server/pull/2686)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Add Bot Methods to Lua. ([#2731](https://github.com/EQEmu/Server/pull/2731)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
|
|
||||||
* Add Bot::Camp() to Perl/Lua. ([#2718](https://github.com/EQEmu/Server/pull/2718)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-11
|
|
||||||
* Add BuffCount() Overloads to Perl/Lua. ([#2679](https://github.com/EQEmu/Server/pull/2679)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-29
|
|
||||||
* Add CampAllBots() to Perl/Lua. ([#2732](https://github.com/EQEmu/Server/pull/2732)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-14
|
|
||||||
* Add Charges/Augment/Attuned Support to Varlink. ([#2685](https://github.com/EQEmu/Server/pull/2685)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Add CheckNameFilter to Perl/Lua. ([#2175](https://github.com/EQEmu/Server/pull/2175)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-20
|
|
||||||
* Add Client Augment Events to Perl/Lua. ([#2735](https://github.com/EQEmu/Server/pull/2735)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
|
||||||
* Add Client Spell Methods to Perl/Lua. ([#2550](https://github.com/EQEmu/Server/pull/2550)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Add CloneAppearance() to Perl/Lua. ([#2531](https://github.com/EQEmu/Server/pull/2531)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add CopyHateList() to Perl/Lua. ([#2623](https://github.com/EQEmu/Server/pull/2623)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
|
||||||
* Add Corpse::AddItem overloads for Lua ([#2509](https://github.com/EQEmu/Server/pull/2509)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
|
||||||
* Add Despawn Events to Perl/Lua. ([#2707](https://github.com/EQEmu/Server/pull/2707)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-07
|
|
||||||
* Add DoAnim Overloads to Perl/Lua. ([#2627](https://github.com/EQEmu/Server/pull/2627)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-10
|
|
||||||
* Add DoAugmentSlotsMatch() to Perl/Lua. ([#2687](https://github.com/EQEmu/Server/pull/2687)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Add DoesAugmentFit() to Perl/Lua. ([#2688](https://github.com/EQEmu/Server/pull/2688)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-01
|
|
||||||
* Add Door Methods to Perl/Lua. ([#2724](https://github.com/EQEmu/Server/pull/2724)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-12
|
|
||||||
* Add EVENT_AA_BUY and EVENT_AA_GAIN to Perl/Lua. ([#2504](https://github.com/EQEmu/Server/pull/2504)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
|
||||||
* Add EVENT_BOT_CREATE to Perl/Lua ([#2713](https://github.com/EQEmu/Server/pull/2713)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-09
|
|
||||||
* Add EVENT_CAST_ON exports to EVENT_CAST and EVENT_CAST_BEGIN. ([#2051](https://github.com/EQEmu/Server/pull/2051)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
|
||||||
* Add EVENT_EQUIP_ITEM_CLIENT and EVENT_UNEQUIP_ITEM_CLIENT to Perl/Lua. ([#2015](https://github.com/EQEmu/Server/pull/2015)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-23
|
|
||||||
* Add EVENT_GM_COMMAND to Perl/Lua. ([#2634](https://github.com/EQEmu/Server/pull/2634)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
|
||||||
* Add EVENT_LEVEL_DOWN to Perl/Lua. ([#2620](https://github.com/EQEmu/Server/pull/2620)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
|
||||||
* Add EVENT_PAYLOAD to Perl/Lua. ([#2611](https://github.com/EQEmu/Server/pull/2611)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
|
||||||
* Add EVENT_SKILL_UP & EVENT_LANGUAGE_SKILL_UP to Perl/Lua ([#2076](https://github.com/EQEmu/Server/pull/2076)) ([nytmyr](https://github.com/nytmyr)) 2022-04-25
|
|
||||||
* Add Entity Variable Methods to Perl/Lua. ([#2609](https://github.com/EQEmu/Server/pull/2609)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
|
||||||
* Add Fling Overloads to Perl/Lua. ([#2622](https://github.com/EQEmu/Server/pull/2622)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
|
||||||
* Add GetAugmentIDsBySlotID() to Perl/Lua. ([#2673](https://github.com/EQEmu/Server/pull/2673)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
|
||||||
* Add GetAverageLevel() to Perl/Lua. ([#2524](https://github.com/EQEmu/Server/pull/2524)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add GetBotItem() and GetBotItemIDBySlot() to Perl/Lua. ([#2350](https://github.com/EQEmu/Server/pull/2350)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-31
|
|
||||||
* Add GetBotListByCharacterID() to Perl/Lua. ([#2069](https://github.com/EQEmu/Server/pull/2069)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-02
|
|
||||||
* Add GetBotListByClientName() Class Overload to Perl/Lua. ([#2577](https://github.com/EQEmu/Server/pull/2577)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
|
||||||
* Add GetBotListByClientName(client_name) to Perl/Lua. ([#2064](https://github.com/EQEmu/Server/pull/2064)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-23
|
|
||||||
* Add GetEnvironmentalDamageName() to Perl/Lua. ([#1964](https://github.com/EQEmu/Server/pull/1964)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-10
|
|
||||||
* Add GetGMStatus() to Perl/Lua. ([#2448](https://github.com/EQEmu/Server/pull/2448)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
|
|
||||||
* Add GetGuildPublicNote() to Perl/Lua. ([#2608](https://github.com/EQEmu/Server/pull/2608)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
|
||||||
* Add GetHealAmount() and GetSpellDamage() to Perl/Lua. ([#2165](https://github.com/EQEmu/Server/pull/2165)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-11
|
|
||||||
* Add GetLeader() and GetLeaderName() to Perl/Lua. ([#2701](https://github.com/EQEmu/Server/pull/2701)) ([Valorith](https://github.com/Valorith)) 2023-01-04
|
|
||||||
* Add GetLowestLevel() to Perl. ([#2517](https://github.com/EQEmu/Server/pull/2517)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
|
||||||
* Add GetRandomBot() to Perl/Lua ([#2543](https://github.com/EQEmu/Server/pull/2543)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
|
||||||
* Add GetRandomClient(), GetRandomMob() and GetRandomNPC() overloads to Perl/Lua. ([#2541](https://github.com/EQEmu/Server/pull/2541)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add GetRandomMob() and GetRandomNPC() to Perl/Lua. ([#2006](https://github.com/EQEmu/Server/pull/2006)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-17
|
|
||||||
* Add GetSkillDmgAmt() to Perl. ([#2365](https://github.com/EQEmu/Server/pull/2365)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-10
|
|
||||||
* Add GetUltimateOwner() to Perl/Lua. ([#2516](https://github.com/EQEmu/Server/pull/2516)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
|
||||||
* Add Goto Player Teleport Methods. ([#2379](https://github.com/EQEmu/Server/pull/2379)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-20
|
|
||||||
* Add Group/Raid Overloads to Perl/Lua. ([#2587](https://github.com/EQEmu/Server/pull/2587)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Add Group/Raid overloads to Perl/Lua. ([#2526](https://github.com/EQEmu/Server/pull/2526)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add HasBotSpellEntry() to Perl/Lua. ([#2563](https://github.com/EQEmu/Server/pull/2563)) ([Aeadoin](https://github.com/Aeadoin)) 2022-11-25
|
|
||||||
* Add Hotzone Methods to Perl/Lua. ([#2558](https://github.com/EQEmu/Server/pull/2558)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Add Instance ID/Version exports to EVENT_ZONE. ([#2502](https://github.com/EQEmu/Server/pull/2502)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-05
|
|
||||||
* Add Instance Methods to Perl/Lua. ([#2573](https://github.com/EQEmu/Server/pull/2573)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
|
||||||
* Add IsAttackAllowed() to Perl/Lua. ([#2672](https://github.com/EQEmu/Server/pull/2672)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-25
|
|
||||||
* Add IsRaining() and IsSnowing() to Perl/Lua. ([#2477](https://github.com/EQEmu/Server/pull/2477)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-14
|
|
||||||
* Add IsRareSpawn() to Perl/Lua. ([#2338](https://github.com/EQEmu/Server/pull/2338)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-30
|
|
||||||
* Add Lua handlers for zone controller events ([#2514](https://github.com/EQEmu/Server/pull/2514)) ([hgtw](https://github.com/hgtw)) 2022-11-05
|
|
||||||
* Add Marquee methods to Perl/Lua. ([#2544](https://github.com/EQEmu/Server/pull/2544)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
|
||||||
* Add MaxSkills() to Perl/Lua. ([#2621](https://github.com/EQEmu/Server/pull/2621)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-06
|
|
||||||
* Add Merchant Events to Perl/Lua. ([#2452](https://github.com/EQEmu/Server/pull/2452)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-09-28
|
|
||||||
* Add Mob Hate Methods to Perl/Lua. ([#2548](https://github.com/EQEmu/Server/pull/2548)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-16
|
|
||||||
* Add Overloads to MoveZone Methods in Perl/Lua. ([#2551](https://github.com/EQEmu/Server/pull/2551)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-22
|
|
||||||
* Add Owner methods to Perl/Lua. ([#2542](https://github.com/EQEmu/Server/pull/2542)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add Popup methods to Perl/Lua. ([#2533](https://github.com/EQEmu/Server/pull/2533)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add Proximity Range Methods to Perl/Lua. ([#2572](https://github.com/EQEmu/Server/pull/2572)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
|
||||||
* Add RandomizeFeature() overloads to Perl/Lua. ([#2532](https://github.com/EQEmu/Server/pull/2532)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add Recipe Methods ([#2393](https://github.com/EQEmu/Server/pull/2393)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-23
|
|
||||||
* Add ResetAlternateAdvancementRank() to Perl/Lua. ([#2510](https://github.com/EQEmu/Server/pull/2510)) ([hgtw](https://github.com/hgtw)) 2022-10-29
|
|
||||||
* Add ResetDecayTimer() to Perl/Lua. ([#2520](https://github.com/EQEmu/Server/pull/2520)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
|
||||||
* Add SendGMCommand() to Perl/Lua. ([#2527](https://github.com/EQEmu/Server/pull/2527)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add SendPath() to Perl/Lua. ([#2740](https://github.com/EQEmu/Server/pull/2740)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-15
|
|
||||||
* Add SignalAllBotsByOwnerName() to Perl/Lua. ([#2730](https://github.com/EQEmu/Server/pull/2730)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-13
|
|
||||||
* Add SplitMoney() with Client splitter to Perl. ([#2525](https://github.com/EQEmu/Server/pull/2525)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-14
|
|
||||||
* Add TaskSelector to Perl/Lua. ([#2177](https://github.com/EQEmu/Server/pull/2177)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-15
|
|
||||||
* Add Time String to Seconds Method to Perl/Lua. ([#2580](https://github.com/EQEmu/Server/pull/2580)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Add TrackNPC to Perl/Lua. ([#2272](https://github.com/EQEmu/Server/pull/2272)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-29
|
|
||||||
* Add WearChange Overloads to Perl/Lua. ([#2600](https://github.com/EQEmu/Server/pull/2600)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-01
|
|
||||||
* Add Zone Flag Methods to Perl/Lua. ([#2574](https://github.com/EQEmu/Server/pull/2574)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-26
|
|
||||||
* Add apis to end shared tasks ([#2521](https://github.com/EQEmu/Server/pull/2521)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
|
||||||
* Add caster_id and caster_level export to EVENT_CAST_ON in Perl/Lua. ([#2049](https://github.com/EQEmu/Server/pull/2049)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-11
|
|
||||||
* Add commify to Perl/Lua. ([#2099](https://github.com/EQEmu/Server/pull/2099)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-03
|
|
||||||
* Add inventory->CountItemEquippedByID(item_id) and inventory->HasItemEquippedByID(item_id) to Perl/Lua. ([#1963](https://github.com/EQEmu/Server/pull/1963)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-02-06
|
|
||||||
* Add missing methods/package.adds to Perl API. ([#2287](https://github.com/EQEmu/Server/pull/2287)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
|
||||||
* Add multiple inventory method short hands to client. ([#2078](https://github.com/EQEmu/Server/pull/2078)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-04-30
|
|
||||||
* Add option to Ignore Mods to CalcEXP ([#2704](https://github.com/EQEmu/Server/pull/2704)) ([Aeadoin](https://github.com/Aeadoin)) 2023-01-06
|
|
||||||
* Adjustment to depop_all function. ([#2595](https://github.com/EQEmu/Server/pull/2595)) ([fryguy503](https://github.com/fryguy503)) 2022-11-30
|
|
||||||
* Allow CreateInstance to be used without a Client initiator. ([#2399](https://github.com/EQEmu/Server/pull/2399)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-28
|
|
||||||
* Allow EVENT_ZONE to be parsed as non-zero to prevent zoning. ([#2052](https://github.com/EQEmu/Server/pull/2052)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
|
||||||
* Allow scripts to prevent door click ([#2327](https://github.com/EQEmu/Server/pull/2327)) ([hgtw](https://github.com/hgtw)) 2022-07-27
|
|
||||||
* Cleanup Proximity Events ([#2697](https://github.com/EQEmu/Server/pull/2697)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-02
|
|
||||||
* Cleanup Signal Methods in Perl/Lua. ([#2604](https://github.com/EQEmu/Server/pull/2604)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-04
|
|
||||||
* Expand Bot quest API functionality. ([#2096](https://github.com/EQEmu/Server/pull/2096)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
|
||||||
* Expand SaveGuardSpot ([#2258](https://github.com/EQEmu/Server/pull/2258)) ([fryguy503](https://github.com/fryguy503)) 2022-06-10
|
|
||||||
* Export corpse in EVENT_DEATH_COMPLETE ([#2519](https://github.com/EQEmu/Server/pull/2519)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
|
||||||
* Export killed XYZH to EVENT_DEATH_ZONE in Perl. ([#2050](https://github.com/EQEmu/Server/pull/2050)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-03-12
|
|
||||||
* Fix Lua Door/Object Create Methods. ([#2633](https://github.com/EQEmu/Server/pull/2633)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-12-11
|
|
||||||
* Fix Perl EVENT_HP double parsing in Spire. ([#2585](https://github.com/EQEmu/Server/pull/2585)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-11-27
|
|
||||||
* Fix lua task selector count when over max ([#2353](https://github.com/EQEmu/Server/pull/2353)) ([hgtw](https://github.com/hgtw)) 2022-07-31
|
|
||||||
* Fix missing arg in perl set_proximity ([#2291](https://github.com/EQEmu/Server/pull/2291)) ([hgtw](https://github.com/hgtw)) 2022-07-09
|
|
||||||
* Fix parameters in some Perl worldwide methods. ([#2224](https://github.com/EQEmu/Server/pull/2224)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-31
|
|
||||||
* Let HasQuestSub check encounters ([#2435](https://github.com/EQEmu/Server/pull/2435)) ([hgtw](https://github.com/hgtw)) 2022-09-20
|
|
||||||
* Perl Doors Fix. ([#2288](https://github.com/EQEmu/Server/pull/2288)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-05
|
|
||||||
* Perl Money Fixes. ([#2098](https://github.com/EQEmu/Server/pull/2098)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-04
|
|
||||||
* Send delivered task items in trade events ([#2518](https://github.com/EQEmu/Server/pull/2518)) ([hgtw](https://github.com/hgtw)) 2022-11-06
|
|
||||||
* Use Floating Point for CameraEffect Intensity ([#2337](https://github.com/EQEmu/Server/pull/2337)) ([hgtw](https://github.com/hgtw)) 2022-07-31
|
|
||||||
* Use binding library for perl apis ([#2216](https://github.com/EQEmu/Server/pull/2216)) ([hgtw](https://github.com/hgtw)) 2022-07-04
|
|
||||||
|
|
||||||
### Rules
|
|
||||||
|
|
||||||
* Add Backstab Rules ([#2666](https://github.com/EQEmu/Server/pull/2666)) ([Valorith](https://github.com/Valorith)) 2022-12-21
|
|
||||||
* Add Frontal Stun Immunity Rules. ([#2217](https://github.com/EQEmu/Server/pull/2217)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-07
|
|
||||||
* Add Keep Level on Death ([#2319](https://github.com/EQEmu/Server/pull/2319)) ([trentdm](https://github.com/trentdm)) 2022-07-30
|
|
||||||
* Add LDoN Loot Count Modifier Rule ([#2694](https://github.com/EQEmu/Server/pull/2694)) ([Kinglykrab](https://github.com/Kinglykrab)) 2023-01-03
|
|
||||||
* Add ManaOnDeath and EndurOnDeath ([#2661](https://github.com/EQEmu/Server/pull/2661)) ([fryguy503](https://github.com/fryguy503)) 2022-12-20
|
|
||||||
* Add Rule to Disable NPC Last Names. ([#2227](https://github.com/EQEmu/Server/pull/2227)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-04
|
|
||||||
* Add Rule to Enable Tells with #hideme ([#2358](https://github.com/EQEmu/Server/pull/2358)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-08-04
|
|
||||||
* Add Rule to allow Assassinate on non-Humanoid body types. ([#2331](https://github.com/EQEmu/Server/pull/2331)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
|
|
||||||
* Add Rule to allow Headshots on non-Humanoid body types. ([#2329](https://github.com/EQEmu/Server/pull/2329)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-07-29
|
|
||||||
* Add Rules to disable various item functionalities and cleanup data types. ([#2225](https://github.com/EQEmu/Server/pull/2225)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-06-01
|
|
||||||
* Add Spells:BuffsFadeOnDeath. ([#2200](https://github.com/EQEmu/Server/pull/2200)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Add Spells:IllusionsAlwaysPersist. ([#2199](https://github.com/EQEmu/Server/pull/2199)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-27
|
|
||||||
* Add Toggle for Warrior Shielding ([#2496](https://github.com/EQEmu/Server/pull/2496)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-10-22
|
|
||||||
* Add adjustment for zone forage. ([#2330](https://github.com/EQEmu/Server/pull/2330)) ([fryguy503](https://github.com/fryguy503)) 2022-07-30
|
|
||||||
* Add rule for NPC Level Based Buff Restrictions. ([#2708](https://github.com/EQEmu/Server/pull/2708)) ([noudess](https://github.com/noudess)) 2023-01-15
|
|
||||||
* Add rule to allow players to permanently save chat channels to database, up to a limit. ([#2706](https://github.com/EQEmu/Server/pull/2706)) ([Valorith](https://github.com/Valorith)) 2023-01-19
|
|
||||||
* Change TradeskillUp Rules to be Floats ([#2674](https://github.com/EQEmu/Server/pull/2674)) ([Aeadoin](https://github.com/Aeadoin)) 2022-12-25
|
|
||||||
* Cleanup all unused rules. ([#2184](https://github.com/EQEmu/Server/pull/2184)) ([Kinglykrab](https://github.com/Kinglykrab)) 2022-05-23
|
|
||||||
* Rule Gate Pet Zoning ([#2625](https://github.com/EQEmu/Server/pull/2625)) ([fryguy503](https://github.com/fryguy503)) 2022-12-07
|
|
||||||
* Rule to allow cap on % XP gain per kill ([#2667](https://github.com/EQEmu/Server/pull/2667)) ([Valorith](https://github.com/Valorith)) 2022-12-25
|
|
||||||
* Update logic checks everywhere for FVNoDropFlag. ([#2179](https://github.com/EQEmu/Server/pull/2179)) ([Quintinon](https://github.com/Quintinon)) 2022-07-30
|
|
||||||
|
|
||||||
### SQL
|
|
||||||
|
|
||||||
* Bugs Table Migration (#2602) ([#2559](https://github.com/EQEmu/Server/pull/2559)) ([joligario](https://github.com/joligario)) 2022-12-01
|
|
||||||
* Update 2023_01_15_merc_data.sql ([#2763](https://github.com/EQEmu/Server/pull/2763)) ([joligario](https://github.com/joligario)) 2023-01-20
|
|
||||||
|
|
||||||
### UCS
|
|
||||||
|
|
||||||
* Auto Client Reconnection ([#2154](https://github.com/EQEmu/Server/pull/2154)) ([Akkadius](https://github.com/Akkadius)) 2022-05-08
|
|
||||||
|
|
||||||
### Websocket
|
|
||||||
|
|
||||||
* Fix cpp20/gcc11 compile failure ([#2737](https://github.com/EQEmu/Server/pull/2737)) ([Akkadius](https://github.com/Akkadius)) 2023-01-15
|
|
||||||
|
|
||||||
### Zone Flags
|
|
||||||
|
|
||||||
* Use database connection, not content connection ([#2759](https://github.com/EQEmu/Server/pull/2759)) ([Akkadius](https://github.com/Akkadius)) 2023-01-19
|
|
||||||
+13
-7
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
|
||||||
|
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ IF(NOT CMAKE_BUILD_TYPE)
|
|||||||
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
|
||||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||||
|
|
||||||
SET(CMAKE_CXX_STANDARD 20)
|
SET(CMAKE_CXX_STANDARD 14)
|
||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
@@ -20,10 +20,8 @@ IF(MSVC)
|
|||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
|
||||||
ELSE(MSVC)
|
ELSE(MSVC)
|
||||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
@@ -123,6 +121,8 @@ ENDIF()
|
|||||||
MESSAGE(STATUS "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
|
|
||||||
#options
|
#options
|
||||||
|
OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
|
||||||
|
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
|
||||||
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
|
OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON)
|
||||||
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||||
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
OPTION(EQEMU_BUILD_LOGIN "Build the login server." ON)
|
||||||
@@ -176,6 +176,10 @@ IF(EQEMU_COMMANDS_LOGGING)
|
|||||||
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
||||||
ENDIF(EQEMU_COMMANDS_LOGGING)
|
ENDIF(EQEMU_COMMANDS_LOGGING)
|
||||||
|
|
||||||
|
IF(EQEMU_ENABLE_BOTS)
|
||||||
|
ADD_DEFINITIONS(-DBOTS)
|
||||||
|
ENDIF(EQEMU_ENABLE_BOTS)
|
||||||
|
|
||||||
#database
|
#database
|
||||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
IF(MySQL_FOUND AND MariaDB_FOUND)
|
||||||
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
|
SET(DATABASE_LIBRARY_SELECTION MariaDB CACHE STRING "Database library to use:
|
||||||
@@ -336,8 +340,10 @@ INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigat
|
|||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
||||||
|
|
||||||
# silence obnoxious deprecation message
|
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
|
||||||
ADD_DEFINITIONS(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
|
IF(EQEMU_BUILD_LOGGING)
|
||||||
|
ADD_DEFINITIONS(-DBUILD_LOGGING)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(TLS_LIBRARY_ENABLED)
|
IF(TLS_LIBRARY_ENABLED)
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
||||||
@@ -367,7 +373,7 @@ ENDIF()
|
|||||||
IF(PERL_LIBRARY_ENABLED)
|
IF(PERL_LIBRARY_ENABLED)
|
||||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||||
IF(EQEMU_BUILD_PERL)
|
IF(EQEMU_BUILD_PERL)
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS} perlbind)
|
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||||
ADD_DEFINITIONS(-DEMBPERL)
|
ADD_DEFINITIONS(-DEMBPERL)
|
||||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# EQEmulator Core Server
|
# EQEmulator Core Server
|
||||||
| Drone (Linux x64) | Drone (Windows x64) |
|
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
||||||
|:---:|:---:|
|
|:---:|:---:|:---:|
|
||||||
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -18,11 +18,11 @@
|
|||||||
|**Install Count**|||
|
|**Install Count**|||
|
||||||
### > Windows
|
### > Windows
|
||||||
|
|
||||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-windows/)
|
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-windows)
|
||||||
|
|
||||||
### > Debian/Ubuntu/CentOS/Fedora
|
### > Debian/Ubuntu/CentOS/Fedora
|
||||||
|
|
||||||
* [Install Guide](https://docs.eqemu.io/server/installation/server-installation-linux/)
|
* [Install Guide](https://eqemu.gitbook.io/server/categories/installation/server-installation-linux)
|
||||||
|
|
||||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
* You can use curl or wget to kick off the installer (whichever your OS has)
|
||||||
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
||||||
@@ -56,7 +56,7 @@ forum, although pull requests will be much quicker and easier on all parties.
|
|||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
- [EQEmulator Forums](http://www.eqemulator.org/forums)
|
||||||
- [EQEmulator Wiki](https://docs.eqemu.io/)
|
- [EQEmulator Wiki](https://eqemu.gitbook.io/)
|
||||||
|
|
||||||
## Related Repositories
|
## Related Repositories
|
||||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
version: 1.0.{build}
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
image: Visual Studio 2017
|
||||||
|
configuration: RelWithDebInfo
|
||||||
|
clone_folder: c:\projects\eqemu
|
||||||
|
init:
|
||||||
|
- ps: git config --global core.autocrlf input
|
||||||
|
cache: c:\tools\vcpkg\installed\
|
||||||
|
before_build:
|
||||||
|
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||||
|
build:
|
||||||
|
project: C:\projects\eqemu\build\EQEmu.sln
|
||||||
|
parallel: true
|
||||||
|
verbosity: minimal
|
||||||
|
after_build:
|
||||||
|
- cmd: >-
|
||||||
|
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||||
|
|
||||||
|
appveyor PushArtifact build_x64-bots.zip
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
version: 1.0.{build}
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
image: Visual Studio 2017
|
||||||
|
configuration: RelWithDebInfo
|
||||||
|
clone_folder: c:\projects\eqemu
|
||||||
|
init:
|
||||||
|
- ps: git config --global core.autocrlf input
|
||||||
|
cache: c:\tools\vcpkg\installed\
|
||||||
|
before_build:
|
||||||
|
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -EQEMU_ENABLE_BOTS=OFF -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||||
|
build:
|
||||||
|
project: C:\projects\eqemu\build\EQEmu.sln
|
||||||
|
parallel: true
|
||||||
|
verbosity: minimal
|
||||||
|
after_build:
|
||||||
|
- cmd: >-
|
||||||
|
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||||
|
|
||||||
|
appveyor PushArtifact build_x64-no-bots.zip
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(export_sources
|
SET(export_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|||||||
@@ -25,15 +25,11 @@
|
|||||||
#include "../../common/platform.h"
|
#include "../../common/platform.h"
|
||||||
#include "../../common/crash.h"
|
#include "../../common/crash.h"
|
||||||
#include "../../common/rulesys.h"
|
#include "../../common/rulesys.h"
|
||||||
#include "../../common/strings.h"
|
#include "../../common/string_util.h"
|
||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
|
||||||
#include "../../common/path_manager.h"
|
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
|
||||||
PathManager path;
|
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase *db);
|
void ExportSpells(SharedDatabase *db);
|
||||||
void ExportSkillCaps(SharedDatabase *db);
|
void ExportSkillCaps(SharedDatabase *db);
|
||||||
@@ -46,8 +42,6 @@ int main(int argc, char **argv)
|
|||||||
LogSys.LoadLogSettingsDefaults();
|
LogSys.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
path.LoadPaths();
|
|
||||||
|
|
||||||
LogInfo("Client Files Export Utility");
|
LogInfo("Client Files Export Utility");
|
||||||
if (!EQEmuConfig::LoadConfig()) {
|
if (!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Unable to load configuration file");
|
LogError("Unable to load configuration file");
|
||||||
@@ -90,7 +84,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
->SetLogPath(path.GetLogPath())
|
|
||||||
->LoadLogDatabaseSettings()
|
->LoadLogDatabaseSettings()
|
||||||
->StartFileLogs();
|
->StartFileLogs();
|
||||||
|
|
||||||
@@ -131,8 +124,7 @@ void ExportSpells(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting Spells");
|
LogInfo("Exporting Spells");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/spells_us.txt", path.GetServerPath());
|
FILE *f = fopen("export/spells_us.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@@ -214,8 +206,7 @@ void ExportSkillCaps(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting Skill Caps");
|
LogInfo("Exporting Skill Caps");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/SkillCaps.txt", path.GetServerPath());
|
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@@ -245,8 +236,7 @@ void ExportBaseData(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting Base Data");
|
LogInfo("Exporting Base Data");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/BaseData.txt", path.GetServerPath());
|
FILE *f = fopen("export/BaseData.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
@@ -279,8 +269,7 @@ void ExportDBStrings(SharedDatabase *db)
|
|||||||
{
|
{
|
||||||
LogInfo("Exporting DB Strings");
|
LogInfo("Exporting DB Strings");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/export/dbstr_us.txt", path.GetServerPath());
|
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||||
FILE *f = fopen(file.c_str(), "w");
|
|
||||||
if (!f) {
|
if (!f) {
|
||||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(import_sources
|
SET(import_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|||||||
@@ -23,15 +23,11 @@
|
|||||||
#include "../../common/platform.h"
|
#include "../../common/platform.h"
|
||||||
#include "../../common/crash.h"
|
#include "../../common/crash.h"
|
||||||
#include "../../common/rulesys.h"
|
#include "../../common/rulesys.h"
|
||||||
#include "../../common/strings.h"
|
#include "../../common/string_util.h"
|
||||||
#include "../../common/content/world_content_service.h"
|
#include "../../common/content/world_content_service.h"
|
||||||
#include "../../common/zone_store.h"
|
|
||||||
#include "../../common/path_manager.h"
|
|
||||||
|
|
||||||
EQEmuLogSys LogSys;
|
EQEmuLogSys LogSys;
|
||||||
WorldContentService content_service;
|
WorldContentService content_service;
|
||||||
ZoneStore zone_store;
|
|
||||||
PathManager path;
|
|
||||||
|
|
||||||
void ImportSpells(SharedDatabase *db);
|
void ImportSpells(SharedDatabase *db);
|
||||||
void ImportSkillCaps(SharedDatabase *db);
|
void ImportSkillCaps(SharedDatabase *db);
|
||||||
@@ -43,8 +39,6 @@ int main(int argc, char **argv) {
|
|||||||
LogSys.LoadLogSettingsDefaults();
|
LogSys.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
path.LoadPaths();
|
|
||||||
|
|
||||||
LogInfo("Client Files Import Utility");
|
LogInfo("Client Files Import Utility");
|
||||||
if(!EQEmuConfig::LoadConfig()) {
|
if(!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Unable to load configuration file.");
|
LogError("Unable to load configuration file.");
|
||||||
@@ -87,7 +81,6 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
->SetLogPath(path.GetLogPath())
|
|
||||||
->LoadLogDatabaseSettings()
|
->LoadLogDatabaseSettings()
|
||||||
->StartFileLogs();
|
->StartFileLogs();
|
||||||
|
|
||||||
@@ -132,10 +125,9 @@ bool IsStringField(int i) {
|
|||||||
|
|
||||||
void ImportSpells(SharedDatabase *db) {
|
void ImportSpells(SharedDatabase *db) {
|
||||||
LogInfo("Importing Spells");
|
LogInfo("Importing Spells");
|
||||||
std::string file = fmt::format("{}/import/spells_us.txt", path.GetServerPath());
|
FILE *f = fopen("import/spells_us.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/spells_us.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,8 +146,8 @@ void ImportSpells(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string escaped = ::Strings::Escape(buffer);
|
std::string escaped = ::EscapeString(buffer);
|
||||||
auto split = Strings::Split(escaped, '^');
|
auto split = SplitString(escaped, '^');
|
||||||
int line_columns = (int)split.size();
|
int line_columns = (int)split.size();
|
||||||
|
|
||||||
std::string sql;
|
std::string sql;
|
||||||
@@ -222,10 +214,9 @@ void ImportSpells(SharedDatabase *db) {
|
|||||||
void ImportSkillCaps(SharedDatabase *db) {
|
void ImportSkillCaps(SharedDatabase *db) {
|
||||||
LogInfo("Importing Skill Caps");
|
LogInfo("Importing Skill Caps");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/SkillCaps.txt", path.GetServerPath());
|
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +225,7 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
while(fgets(buffer, 2048, f)) {
|
while(fgets(buffer, 2048, f)) {
|
||||||
auto split = Strings::Split(buffer, '^');
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
if(split.size() < 4) {
|
if(split.size() < 4) {
|
||||||
continue;
|
continue;
|
||||||
@@ -258,10 +249,9 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
void ImportBaseData(SharedDatabase *db) {
|
void ImportBaseData(SharedDatabase *db) {
|
||||||
LogInfo("Importing Base Data");
|
LogInfo("Importing Base Data");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/BaseData.txt", path.GetServerPath());
|
FILE *f = fopen("import/BaseData.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/BaseData.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +260,7 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
|
|
||||||
char buffer[2048];
|
char buffer[2048];
|
||||||
while(fgets(buffer, 2048, f)) {
|
while(fgets(buffer, 2048, f)) {
|
||||||
auto split = Strings::Split(buffer, '^');
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
if(split.size() < 10) {
|
if(split.size() < 10) {
|
||||||
continue;
|
continue;
|
||||||
@@ -304,10 +294,9 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
void ImportDBStrings(SharedDatabase *db) {
|
void ImportDBStrings(SharedDatabase *db) {
|
||||||
LogInfo("Importing DB Strings");
|
LogInfo("Importing DB Strings");
|
||||||
|
|
||||||
std::string file = fmt::format("{}/import/dbstr_us.txt", path.GetServerPath());
|
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||||
FILE *f = fopen(file.c_str(), "r");
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open {} to read, skipping.", file);
|
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +318,7 @@ void ImportDBStrings(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto split = Strings::Split(buffer, '^');
|
auto split = SplitString(buffer, '^');
|
||||||
|
|
||||||
if(split.size() < 2) {
|
if(split.size() < 2) {
|
||||||
continue;
|
continue;
|
||||||
@@ -343,7 +332,7 @@ void ImportDBStrings(SharedDatabase *db) {
|
|||||||
type = atoi(split[1].c_str());
|
type = atoi(split[1].c_str());
|
||||||
|
|
||||||
if(split.size() >= 3) {
|
if(split.size() >= 3) {
|
||||||
value = ::Strings::Escape(split[2]);
|
value = ::EscapeString(split[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
|
sql = StringFormat("INSERT INTO db_str(id, type, value) VALUES(%u, %u, '%s')",
|
||||||
|
|||||||
+41
-68
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
||||||
|
|
||||||
SET(common_sources
|
SET(common_sources
|
||||||
base_packet.cpp
|
base_packet.cpp
|
||||||
@@ -7,7 +7,6 @@ SET(common_sources
|
|||||||
compression.cpp
|
compression.cpp
|
||||||
condition.cpp
|
condition.cpp
|
||||||
content/world_content_service.cpp
|
content/world_content_service.cpp
|
||||||
discord/discord.cpp
|
|
||||||
crash.cpp
|
crash.cpp
|
||||||
crc16.cpp
|
crc16.cpp
|
||||||
crc32.cpp
|
crc32.cpp
|
||||||
@@ -33,13 +32,10 @@ SET(common_sources
|
|||||||
eq_stream_proxy.cpp
|
eq_stream_proxy.cpp
|
||||||
eqtime.cpp
|
eqtime.cpp
|
||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
events/player_event_logs.cpp
|
|
||||||
events/player_event_discord_formatter.cpp
|
|
||||||
expedition_lockout_timer.cpp
|
expedition_lockout_timer.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
discord/discord_manager.cpp
|
|
||||||
faction.cpp
|
faction.cpp
|
||||||
file.cpp
|
file_util.cpp
|
||||||
guild_base.cpp
|
guild_base.cpp
|
||||||
guilds.cpp
|
guilds.cpp
|
||||||
inventory_profile.cpp
|
inventory_profile.cpp
|
||||||
@@ -63,10 +59,8 @@ SET(common_sources
|
|||||||
packet_dump.cpp
|
packet_dump.cpp
|
||||||
packet_dump_file.cpp
|
packet_dump_file.cpp
|
||||||
packet_functions.cpp
|
packet_functions.cpp
|
||||||
path_manager.cpp
|
|
||||||
perl_eqdb.cpp
|
perl_eqdb.cpp
|
||||||
perl_eqdb_res.cpp
|
perl_eqdb_res.cpp
|
||||||
process/process.cpp
|
|
||||||
proc_launcher.cpp
|
proc_launcher.cpp
|
||||||
profanity_manager.cpp
|
profanity_manager.cpp
|
||||||
ptimer.cpp
|
ptimer.cpp
|
||||||
@@ -81,14 +75,13 @@ SET(common_sources
|
|||||||
shareddb.cpp
|
shareddb.cpp
|
||||||
skills.cpp
|
skills.cpp
|
||||||
spdat.cpp
|
spdat.cpp
|
||||||
strings.cpp
|
string_util.cpp
|
||||||
struct_strategy.cpp
|
struct_strategy.cpp
|
||||||
textures.cpp
|
textures.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
unix.cpp
|
unix.cpp
|
||||||
platform.cpp
|
platform.cpp
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
zone_store.cpp
|
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
net/console_server_connection.cpp
|
net/console_server_connection.cpp
|
||||||
net/crc32.cpp
|
net/crc32.cpp
|
||||||
@@ -125,9 +118,6 @@ SET(repositories
|
|||||||
# Criteria
|
# Criteria
|
||||||
repositories/criteria/content_filter_criteria.h
|
repositories/criteria/content_filter_criteria.h
|
||||||
|
|
||||||
repositories/base/base_grid_repository.h
|
|
||||||
repositories/base/base_grid_entries_repository.h
|
|
||||||
|
|
||||||
# Base Repositories
|
# Base Repositories
|
||||||
repositories/base/base_aa_ability_repository.h
|
repositories/base/base_aa_ability_repository.h
|
||||||
repositories/base/base_aa_ranks_repository.h
|
repositories/base/base_aa_ranks_repository.h
|
||||||
@@ -147,7 +137,6 @@ SET(repositories
|
|||||||
repositories/base/base_auras_repository.h
|
repositories/base/base_auras_repository.h
|
||||||
repositories/base/base_base_data_repository.h
|
repositories/base/base_base_data_repository.h
|
||||||
repositories/base/base_blocked_spells_repository.h
|
repositories/base/base_blocked_spells_repository.h
|
||||||
repositories/base/base_books_repository.h
|
|
||||||
repositories/base/base_bugs_repository.h
|
repositories/base/base_bugs_repository.h
|
||||||
repositories/base/base_bug_reports_repository.h
|
repositories/base/base_bug_reports_repository.h
|
||||||
repositories/base/base_buyer_repository.h
|
repositories/base/base_buyer_repository.h
|
||||||
@@ -164,7 +153,6 @@ SET(repositories
|
|||||||
repositories/base/base_character_data_repository.h
|
repositories/base/base_character_data_repository.h
|
||||||
repositories/base/base_character_disciplines_repository.h
|
repositories/base/base_character_disciplines_repository.h
|
||||||
repositories/base/base_character_expedition_lockouts_repository.h
|
repositories/base/base_character_expedition_lockouts_repository.h
|
||||||
repositories/base/base_character_exp_modifiers_repository.h
|
|
||||||
repositories/base/base_character_inspect_messages_repository.h
|
repositories/base/base_character_inspect_messages_repository.h
|
||||||
repositories/base/base_character_instance_safereturns_repository.h
|
repositories/base/base_character_instance_safereturns_repository.h
|
||||||
repositories/base/base_character_item_recast_repository.h
|
repositories/base/base_character_item_recast_repository.h
|
||||||
@@ -172,37 +160,32 @@ SET(repositories
|
|||||||
repositories/base/base_character_leadership_abilities_repository.h
|
repositories/base/base_character_leadership_abilities_repository.h
|
||||||
repositories/base/base_character_material_repository.h
|
repositories/base/base_character_material_repository.h
|
||||||
repositories/base/base_character_memmed_spells_repository.h
|
repositories/base/base_character_memmed_spells_repository.h
|
||||||
repositories/base/base_character_peqzone_flags_repository.h
|
|
||||||
repositories/base/base_character_pet_buffs_repository.h
|
repositories/base/base_character_pet_buffs_repository.h
|
||||||
repositories/base/base_character_pet_info_repository.h
|
repositories/base/base_character_pet_info_repository.h
|
||||||
repositories/base/base_character_pet_inventory_repository.h
|
repositories/base/base_character_pet_inventory_repository.h
|
||||||
repositories/base/base_character_potionbelt_repository.h
|
repositories/base/base_character_potionbelt_repository.h
|
||||||
repositories/base/base_character_skills_repository.h
|
repositories/base/base_character_skills_repository.h
|
||||||
repositories/base/base_character_spells_repository.h
|
repositories/base/base_character_spells_repository.h
|
||||||
repositories/base/base_character_tasks_repository.h
|
|
||||||
repositories/base/base_character_task_timers_repository.h
|
repositories/base/base_character_task_timers_repository.h
|
||||||
|
repositories/base/base_character_tasks_repository.h
|
||||||
repositories/base/base_char_create_combinations_repository.h
|
repositories/base/base_char_create_combinations_repository.h
|
||||||
repositories/base/base_char_create_point_allocations_repository.h
|
repositories/base/base_char_create_point_allocations_repository.h
|
||||||
repositories/base/base_char_recipe_list_repository.h
|
repositories/base/base_char_recipe_list_repository.h
|
||||||
repositories/base/base_chatchannels_repository.h
|
|
||||||
repositories/base/base_chatchannel_reserved_names_repository.h
|
|
||||||
repositories/base/base_completed_shared_tasks_repository.h
|
|
||||||
repositories/base/base_completed_shared_task_activity_state_repository.h
|
|
||||||
repositories/base/base_completed_shared_task_members_repository.h
|
|
||||||
repositories/base/base_completed_tasks_repository.h
|
repositories/base/base_completed_tasks_repository.h
|
||||||
|
repositories/base/base_completed_shared_tasks_repository.h
|
||||||
|
repositories/base/base_completed_shared_task_members_repository.h
|
||||||
|
repositories/base/base_completed_shared_task_activity_state_repository.h
|
||||||
repositories/base/base_content_flags_repository.h
|
repositories/base/base_content_flags_repository.h
|
||||||
repositories/base/base_damageshieldtypes_repository.h
|
repositories/base/base_damageshieldtypes_repository.h
|
||||||
repositories/base/base_data_buckets_repository.h
|
repositories/base/base_data_buckets_repository.h
|
||||||
repositories/base/base_db_str_repository.h
|
repositories/base/base_db_str_repository.h
|
||||||
repositories/base/base_discord_webhooks_repository.h
|
|
||||||
repositories/base/base_discovered_items_repository.h
|
repositories/base/base_discovered_items_repository.h
|
||||||
repositories/base/base_doors_repository.h
|
repositories/base/base_doors_repository.h
|
||||||
repositories/base/base_dynamic_zones_repository.h
|
repositories/base/base_dynamic_zones_repository.h
|
||||||
repositories/base/base_dynamic_zone_members_repository.h
|
repositories/base/base_dynamic_zone_members_repository.h
|
||||||
repositories/base/base_dynamic_zone_templates_repository.h
|
repositories/base/base_eventlog_repository.h
|
||||||
repositories/base/base_expeditions_repository.h
|
repositories/base/base_expeditions_repository.h
|
||||||
repositories/base/base_expedition_lockouts_repository.h
|
repositories/base/base_expedition_lockouts_repository.h
|
||||||
repositories/base/base_faction_association_repository.h
|
|
||||||
repositories/base/base_faction_base_data_repository.h
|
repositories/base/base_faction_base_data_repository.h
|
||||||
repositories/base/base_faction_list_repository.h
|
repositories/base/base_faction_list_repository.h
|
||||||
repositories/base/base_faction_list_mod_repository.h
|
repositories/base/base_faction_list_mod_repository.h
|
||||||
@@ -212,14 +195,18 @@ SET(repositories
|
|||||||
repositories/base/base_friends_repository.h
|
repositories/base/base_friends_repository.h
|
||||||
repositories/base/base_global_loot_repository.h
|
repositories/base/base_global_loot_repository.h
|
||||||
repositories/base/base_gm_ips_repository.h
|
repositories/base/base_gm_ips_repository.h
|
||||||
|
repositories/base/base_goallists_repository.h
|
||||||
repositories/base/base_graveyard_repository.h
|
repositories/base/base_graveyard_repository.h
|
||||||
|
repositories/base/base_grid_repository.h
|
||||||
|
repositories/base/base_grid_entries_repository.h
|
||||||
repositories/base/base_ground_spawns_repository.h
|
repositories/base/base_ground_spawns_repository.h
|
||||||
repositories/base/base_group_id_repository.h
|
repositories/base/base_group_id_repository.h
|
||||||
repositories/base/base_group_leaders_repository.h
|
repositories/base/base_group_leaders_repository.h
|
||||||
repositories/base/base_guilds_repository.h
|
repositories/base/base_guilds_repository.h
|
||||||
|
repositories/base/base_guild_members_repository.h
|
||||||
repositories/base/base_guild_ranks_repository.h
|
repositories/base/base_guild_ranks_repository.h
|
||||||
repositories/base/base_guild_relations_repository.h
|
repositories/base/base_guild_relations_repository.h
|
||||||
repositories/base/base_horses_repository.h
|
repositories/base/base_hackers_repository.h
|
||||||
repositories/base/base_instance_list_repository.h
|
repositories/base/base_instance_list_repository.h
|
||||||
repositories/base/base_instance_list_player_repository.h
|
repositories/base/base_instance_list_player_repository.h
|
||||||
repositories/base/base_inventory_repository.h
|
repositories/base/base_inventory_repository.h
|
||||||
@@ -260,12 +247,10 @@ SET(repositories
|
|||||||
repositories/base/base_perl_event_export_settings_repository.h
|
repositories/base/base_perl_event_export_settings_repository.h
|
||||||
repositories/base/base_petitions_repository.h
|
repositories/base/base_petitions_repository.h
|
||||||
repositories/base/base_pets_repository.h
|
repositories/base/base_pets_repository.h
|
||||||
repositories/base/base_pets_beastlord_data_repository.h
|
|
||||||
repositories/base/base_pets_equipmentset_repository.h
|
repositories/base/base_pets_equipmentset_repository.h
|
||||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||||
repositories/base/base_player_titlesets_repository.h
|
repositories/base/base_player_titlesets_repository.h
|
||||||
repositories/base/base_player_event_log_settings_repository.h
|
repositories/base/base_proximities_repository.h
|
||||||
repositories/base/base_player_event_logs_repository.h
|
|
||||||
repositories/base/base_quest_globals_repository.h
|
repositories/base/base_quest_globals_repository.h
|
||||||
repositories/base/base_raid_details_repository.h
|
repositories/base/base_raid_details_repository.h
|
||||||
repositories/base/base_raid_members_repository.h
|
repositories/base/base_raid_members_repository.h
|
||||||
@@ -325,7 +310,6 @@ SET(repositories
|
|||||||
repositories/auras_repository.h
|
repositories/auras_repository.h
|
||||||
repositories/base_data_repository.h
|
repositories/base_data_repository.h
|
||||||
repositories/blocked_spells_repository.h
|
repositories/blocked_spells_repository.h
|
||||||
repositories/books_repository.h
|
|
||||||
repositories/bugs_repository.h
|
repositories/bugs_repository.h
|
||||||
repositories/bug_reports_repository.h
|
repositories/bug_reports_repository.h
|
||||||
repositories/buyer_repository.h
|
repositories/buyer_repository.h
|
||||||
@@ -342,7 +326,6 @@ SET(repositories
|
|||||||
repositories/character_data_repository.h
|
repositories/character_data_repository.h
|
||||||
repositories/character_disciplines_repository.h
|
repositories/character_disciplines_repository.h
|
||||||
repositories/character_expedition_lockouts_repository.h
|
repositories/character_expedition_lockouts_repository.h
|
||||||
repositories/character_exp_modifiers_repository.h
|
|
||||||
repositories/character_inspect_messages_repository.h
|
repositories/character_inspect_messages_repository.h
|
||||||
repositories/character_instance_safereturns_repository.h
|
repositories/character_instance_safereturns_repository.h
|
||||||
repositories/character_item_recast_repository.h
|
repositories/character_item_recast_repository.h
|
||||||
@@ -350,37 +333,32 @@ SET(repositories
|
|||||||
repositories/character_leadership_abilities_repository.h
|
repositories/character_leadership_abilities_repository.h
|
||||||
repositories/character_material_repository.h
|
repositories/character_material_repository.h
|
||||||
repositories/character_memmed_spells_repository.h
|
repositories/character_memmed_spells_repository.h
|
||||||
repositories/character_peqzone_flags_repository.h
|
|
||||||
repositories/character_pet_buffs_repository.h
|
repositories/character_pet_buffs_repository.h
|
||||||
repositories/character_pet_info_repository.h
|
repositories/character_pet_info_repository.h
|
||||||
repositories/character_pet_inventory_repository.h
|
repositories/character_pet_inventory_repository.h
|
||||||
repositories/character_potionbelt_repository.h
|
repositories/character_potionbelt_repository.h
|
||||||
repositories/character_skills_repository.h
|
repositories/character_skills_repository.h
|
||||||
repositories/character_spells_repository.h
|
repositories/character_spells_repository.h
|
||||||
repositories/character_tasks_repository.h
|
|
||||||
repositories/character_task_timers_repository.h
|
repositories/character_task_timers_repository.h
|
||||||
|
repositories/character_tasks_repository.h
|
||||||
repositories/char_create_combinations_repository.h
|
repositories/char_create_combinations_repository.h
|
||||||
repositories/char_create_point_allocations_repository.h
|
repositories/char_create_point_allocations_repository.h
|
||||||
repositories/char_recipe_list_repository.h
|
repositories/char_recipe_list_repository.h
|
||||||
repositories/chatchannels_repository.h
|
|
||||||
repositories/chatchannel_reserved_names_repository.h
|
|
||||||
repositories/completed_shared_tasks_repository.h
|
|
||||||
repositories/completed_shared_task_activity_state_repository.h
|
|
||||||
repositories/completed_shared_task_members_repository.h
|
|
||||||
repositories/completed_tasks_repository.h
|
repositories/completed_tasks_repository.h
|
||||||
|
repositories/completed_shared_tasks_repository.h
|
||||||
|
repositories/completed_shared_task_members_repository.h
|
||||||
|
repositories/completed_shared_task_activity_state_repository.h
|
||||||
repositories/content_flags_repository.h
|
repositories/content_flags_repository.h
|
||||||
repositories/damageshieldtypes_repository.h
|
repositories/damageshieldtypes_repository.h
|
||||||
repositories/data_buckets_repository.h
|
repositories/data_buckets_repository.h
|
||||||
repositories/db_str_repository.h
|
repositories/db_str_repository.h
|
||||||
repositories/discord_webhooks_repository.h
|
|
||||||
repositories/discovered_items_repository.h
|
repositories/discovered_items_repository.h
|
||||||
repositories/doors_repository.h
|
repositories/doors_repository.h
|
||||||
repositories/dynamic_zones_repository.h
|
repositories/dynamic_zones_repository.h
|
||||||
repositories/dynamic_zone_members_repository.h
|
repositories/dynamic_zone_members_repository.h
|
||||||
repositories/dynamic_zone_templates_repository.h
|
repositories/eventlog_repository.h
|
||||||
repositories/expeditions_repository.h
|
repositories/expeditions_repository.h
|
||||||
repositories/expedition_lockouts_repository.h
|
repositories/expedition_lockouts_repository.h
|
||||||
repositories/faction_association_repository.h
|
|
||||||
repositories/faction_base_data_repository.h
|
repositories/faction_base_data_repository.h
|
||||||
repositories/faction_list_repository.h
|
repositories/faction_list_repository.h
|
||||||
repositories/faction_list_mod_repository.h
|
repositories/faction_list_mod_repository.h
|
||||||
@@ -390,14 +368,18 @@ SET(repositories
|
|||||||
repositories/friends_repository.h
|
repositories/friends_repository.h
|
||||||
repositories/global_loot_repository.h
|
repositories/global_loot_repository.h
|
||||||
repositories/gm_ips_repository.h
|
repositories/gm_ips_repository.h
|
||||||
|
repositories/goallists_repository.h
|
||||||
repositories/graveyard_repository.h
|
repositories/graveyard_repository.h
|
||||||
|
repositories/grid_repository.h
|
||||||
|
repositories/grid_entries_repository.h
|
||||||
repositories/ground_spawns_repository.h
|
repositories/ground_spawns_repository.h
|
||||||
repositories/group_id_repository.h
|
repositories/group_id_repository.h
|
||||||
repositories/group_leaders_repository.h
|
repositories/group_leaders_repository.h
|
||||||
repositories/guilds_repository.h
|
repositories/guilds_repository.h
|
||||||
|
repositories/guild_members_repository.h
|
||||||
repositories/guild_ranks_repository.h
|
repositories/guild_ranks_repository.h
|
||||||
repositories/guild_relations_repository.h
|
repositories/guild_relations_repository.h
|
||||||
repositories/horses_repository.h
|
repositories/hackers_repository.h
|
||||||
repositories/instance_list_repository.h
|
repositories/instance_list_repository.h
|
||||||
repositories/instance_list_player_repository.h
|
repositories/instance_list_player_repository.h
|
||||||
repositories/inventory_repository.h
|
repositories/inventory_repository.h
|
||||||
@@ -438,12 +420,10 @@ SET(repositories
|
|||||||
repositories/perl_event_export_settings_repository.h
|
repositories/perl_event_export_settings_repository.h
|
||||||
repositories/petitions_repository.h
|
repositories/petitions_repository.h
|
||||||
repositories/pets_repository.h
|
repositories/pets_repository.h
|
||||||
repositories/pets_beastlord_data_repository.h
|
|
||||||
repositories/pets_equipmentset_repository.h
|
repositories/pets_equipmentset_repository.h
|
||||||
repositories/pets_equipmentset_entries_repository.h
|
repositories/pets_equipmentset_entries_repository.h
|
||||||
repositories/player_titlesets_repository.h
|
repositories/player_titlesets_repository.h
|
||||||
repositories/player_event_log_settings_repository.h
|
repositories/proximities_repository.h
|
||||||
repositories/player_event_logs_repository.h
|
|
||||||
repositories/quest_globals_repository.h
|
repositories/quest_globals_repository.h
|
||||||
repositories/raid_details_repository.h
|
repositories/raid_details_repository.h
|
||||||
repositories/raid_members_repository.h
|
repositories/raid_members_repository.h
|
||||||
@@ -484,10 +464,13 @@ SET(repositories
|
|||||||
repositories/zone_repository.h
|
repositories/zone_repository.h
|
||||||
repositories/zone_points_repository.h
|
repositories/zone_points_repository.h
|
||||||
|
|
||||||
)
|
# Non-Comformative
|
||||||
|
repositories/character_recipe_list_repository.h
|
||||||
|
)
|
||||||
|
|
||||||
SET(common_headers
|
SET(common_headers
|
||||||
additive_lagged_fibonacci_engine.h
|
additive_lagged_fibonacci_engine.h
|
||||||
|
any.h
|
||||||
base_packet.h
|
base_packet.h
|
||||||
base_data.h
|
base_data.h
|
||||||
bodytypes.h
|
bodytypes.h
|
||||||
@@ -508,8 +491,6 @@ SET(common_headers
|
|||||||
database_schema.h
|
database_schema.h
|
||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
discord/discord.h
|
|
||||||
discord/discord_manager.h
|
|
||||||
dynamic_zone_base.h
|
dynamic_zone_base.h
|
||||||
emu_constants.h
|
emu_constants.h
|
||||||
emu_limits.h
|
emu_limits.h
|
||||||
@@ -532,15 +513,12 @@ SET(common_headers
|
|||||||
eq_stream_locator.h
|
eq_stream_locator.h
|
||||||
eq_stream_proxy.h
|
eq_stream_proxy.h
|
||||||
eqtime.h
|
eqtime.h
|
||||||
events/player_event_logs.h
|
|
||||||
events/player_event_discord_formatter.h
|
|
||||||
events/player_events.h
|
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
extprofile.h
|
extprofile.h
|
||||||
faction.h
|
faction.h
|
||||||
file.h
|
file_util.h
|
||||||
features.h
|
features.h
|
||||||
fixed_memory_hash_set.h
|
fixed_memory_hash_set.h
|
||||||
fixed_memory_variable_hash_set.h
|
fixed_memory_variable_hash_set.h
|
||||||
@@ -576,9 +554,7 @@ SET(common_headers
|
|||||||
packet_dump.h
|
packet_dump.h
|
||||||
packet_dump_file.h
|
packet_dump_file.h
|
||||||
packet_functions.h
|
packet_functions.h
|
||||||
path_manager.cpp
|
|
||||||
platform.h
|
platform.h
|
||||||
process/process.h
|
|
||||||
proc_launcher.h
|
proc_launcher.h
|
||||||
profanity_manager.h
|
profanity_manager.h
|
||||||
profiler.h
|
profiler.h
|
||||||
@@ -599,7 +575,7 @@ SET(common_headers
|
|||||||
shareddb.h
|
shareddb.h
|
||||||
skills.h
|
skills.h
|
||||||
spdat.h
|
spdat.h
|
||||||
strings.h
|
string_util.h
|
||||||
struct_strategy.h
|
struct_strategy.h
|
||||||
tasks.h
|
tasks.h
|
||||||
textures.h
|
textures.h
|
||||||
@@ -609,11 +585,9 @@ SET(common_headers
|
|||||||
useperl.h
|
useperl.h
|
||||||
version.h
|
version.h
|
||||||
zone_numbers.h
|
zone_numbers.h
|
||||||
zone_store.h
|
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/task.h
|
event/task.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
json/json_archive_single_line.h
|
|
||||||
json/json.h
|
json/json.h
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
net/console_server.h
|
net/console_server.h
|
||||||
@@ -662,24 +636,23 @@ SET(common_headers
|
|||||||
patches/uf_limits.h
|
patches/uf_limits.h
|
||||||
patches/uf_ops.h
|
patches/uf_ops.h
|
||||||
patches/uf_structs.h
|
patches/uf_structs.h
|
||||||
termcolor/rang.hpp
|
|
||||||
stacktrace/backward.hpp
|
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.h)
|
util/uuid.h
|
||||||
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Event FILES
|
SOURCE_GROUP(Event FILES
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
event/task.h
|
event/task.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Json FILES
|
SOURCE_GROUP(Json FILES
|
||||||
json/json.h
|
json/json.h
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Net FILES
|
SOURCE_GROUP(Net FILES
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
@@ -716,7 +689,7 @@ SOURCE_GROUP(Net FILES
|
|||||||
net/websocket_server.h
|
net/websocket_server.h
|
||||||
net/websocket_server_connection.cpp
|
net/websocket_server_connection.cpp
|
||||||
net/websocket_server_connection.h
|
net/websocket_server_connection.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Patches FILES
|
SOURCE_GROUP(Patches FILES
|
||||||
patches/patches.h
|
patches/patches.h
|
||||||
@@ -760,12 +733,12 @@ SOURCE_GROUP(Patches FILES
|
|||||||
patches/titanium_limits.cpp
|
patches/titanium_limits.cpp
|
||||||
patches/uf.cpp
|
patches/uf.cpp
|
||||||
patches/uf_limits.cpp
|
patches/uf_limits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(StackWalker FILES
|
SOURCE_GROUP(StackWalker FILES
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
StackWalker/StackWalker.cpp
|
StackWalker/StackWalker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Util FILES
|
SOURCE_GROUP(Util FILES
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
@@ -773,16 +746,16 @@ SOURCE_GROUP(Util FILES
|
|||||||
util/directory.h
|
util/directory.h
|
||||||
util/uuid.cpp
|
util/uuid.cpp
|
||||||
util/uuid.h
|
util/uuid.h
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
||||||
|
|
||||||
ADD_LIBRARY(common ${common_sources} ${common_headers} ${repositories})
|
ADD_LIBRARY(common ${common_sources} ${common_headers} ${repositories})
|
||||||
|
|
||||||
IF (UNIX)
|
IF(UNIX)
|
||||||
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
|
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
|
||||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||||
ENDIF (UNIX)
|
ENDIF(UNIX)
|
||||||
|
|
||||||
|
|
||||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||||
|
|||||||
+190
@@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
* obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
* this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
* execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
* Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
* do so, all subject to the following:
|
||||||
|
*
|
||||||
|
* The copyright notices in the Software and this entire statement, including
|
||||||
|
* the above license grant, this restriction and the following disclaimer,
|
||||||
|
* must be included in all copies of the Software, in whole or in part, and
|
||||||
|
* all derivative works of the Software, unless such copies or derivative
|
||||||
|
* works are solely in the form of machine-executable object code generated by
|
||||||
|
* a source language processor.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// EQ::Any is a modified version of Boost::Any and as such retains the Boost licensing.
|
||||||
|
|
||||||
|
#ifndef EQEMU_COMMON_ANY_H
|
||||||
|
#define EQEMU_COMMON_ANY_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
namespace EQ
|
||||||
|
{
|
||||||
|
class Any
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Any()
|
||||||
|
: content(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
Any(const ValueType &value)
|
||||||
|
: content(new Holder<ValueType>(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Any(const Any &other)
|
||||||
|
: content(other.content ? other.content->clone() : 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Any()
|
||||||
|
{
|
||||||
|
if(content)
|
||||||
|
delete content;
|
||||||
|
}
|
||||||
|
|
||||||
|
Any& swap(Any &rhs)
|
||||||
|
{
|
||||||
|
std::swap(content, rhs.content);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
Any& operator=(const ValueType &rhs)
|
||||||
|
{
|
||||||
|
Any(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Any& operator=(Any rhs)
|
||||||
|
{
|
||||||
|
rhs.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return !content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return content ? content->type() : typeid(void);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Placeholder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Placeholder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const std::type_info& type() const = 0;
|
||||||
|
virtual Placeholder* clone() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
class Holder : public Placeholder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Holder(const ValueType &value)
|
||||||
|
: held(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return typeid(ValueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Placeholder* clone() const
|
||||||
|
{
|
||||||
|
return new Holder(held);
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType held;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Holder& operator=(const Holder&);
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename ValueType>
|
||||||
|
friend ValueType* any_cast(Any*);
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
friend ValueType* unsafe_any_cast(Any*);
|
||||||
|
|
||||||
|
Placeholder* content;
|
||||||
|
};
|
||||||
|
|
||||||
|
class bad_any_cast : public std::bad_cast
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char * what() const throw()
|
||||||
|
{
|
||||||
|
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
ValueType* any_cast(Any* operand)
|
||||||
|
{
|
||||||
|
return operand &&
|
||||||
|
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline const ValueType* any_cast(const Any* operand)
|
||||||
|
{
|
||||||
|
return any_cast<ValueType>(const_cast<Any*>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
ValueType any_cast(Any& operand)
|
||||||
|
{
|
||||||
|
typedef typename std::remove_reference<ValueType>::type nonref;
|
||||||
|
nonref* result = any_cast<nonref>(&operand);
|
||||||
|
if(!result)
|
||||||
|
throw bad_any_cast();
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType any_cast(const Any& operand)
|
||||||
|
{
|
||||||
|
typedef typename std::remove_reference<ValueType>::type nonref;
|
||||||
|
return any_cast<const nonref&>(const_cast<Any&>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType* unsafe_any_cast(Any* operand)
|
||||||
|
{
|
||||||
|
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline const ValueType* unsafe_any_cast(const Any* operand)
|
||||||
|
{
|
||||||
|
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,18 +23,18 @@
|
|||||||
|
|
||||||
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
|
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
|
||||||
{
|
{
|
||||||
pBuffer=nullptr;
|
this->pBuffer=nullptr;
|
||||||
size=0;
|
this->size=0;
|
||||||
_wpos = 0;
|
this->_wpos = 0;
|
||||||
_rpos = 0;
|
this->_rpos = 0;
|
||||||
timestamp.tv_sec = 0;
|
this->timestamp.tv_sec = 0;
|
||||||
if (len>0) {
|
if (len>0) {
|
||||||
size=len;
|
this->size=len;
|
||||||
pBuffer= new unsigned char[len];
|
pBuffer= new unsigned char[len];
|
||||||
if (buf) {
|
if (buf) {
|
||||||
memcpy(pBuffer,buf,len);
|
memcpy(this->pBuffer,buf,len);
|
||||||
} else {
|
} else {
|
||||||
memset(pBuffer,0,len);
|
memset(this->pBuffer,0,len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -380,12 +380,12 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
|
|||||||
return "Merchant";
|
return "Merchant";
|
||||||
case DISCORD_MERCHANT:
|
case DISCORD_MERCHANT:
|
||||||
return "Discord Merchant";
|
return "Discord Merchant";
|
||||||
case ADVENTURE_RECRUITER:
|
case ADVENTURERECRUITER:
|
||||||
return "Adventure Recruiter";
|
return "Adventure Recruiter";
|
||||||
case ADVENTURE_MERCHANT:
|
case ADVENTUREMERCHANT:
|
||||||
return "Adventure Merchant";
|
return "Adventure Merchant";
|
||||||
case LDON_TREASURE:
|
case CORPSE_CLASS:
|
||||||
return "LDoN Treasure";
|
return "Corpse Class";
|
||||||
case TRIBUTE_MASTER:
|
case TRIBUTE_MASTER:
|
||||||
return "Tribute Master";
|
return "Tribute Master";
|
||||||
case GUILD_TRIBUTE_MASTER:
|
case GUILD_TRIBUTE_MASTER:
|
||||||
@@ -400,7 +400,7 @@ const char *GetClassIDName(uint8 class_id, uint8 level)
|
|||||||
return "Fellowship Master";
|
return "Fellowship Master";
|
||||||
case ALT_CURRENCY_MERCHANT:
|
case ALT_CURRENCY_MERCHANT:
|
||||||
return "Alternate Currency Merchant";
|
return "Alternate Currency Merchant";
|
||||||
case MERCENARY_MASTER:
|
case MERCERNARY_MASTER:
|
||||||
return "Mercenary Liaison";
|
return "Mercenary Liaison";
|
||||||
default:
|
default:
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
|||||||
+5
-5
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
|
|
||||||
#define NO_CLASS 0
|
|
||||||
#define WARRIOR 1
|
#define WARRIOR 1
|
||||||
#define CLERIC 2
|
#define CLERIC 2
|
||||||
#define PALADIN 3
|
#define PALADIN 3
|
||||||
@@ -56,9 +55,10 @@
|
|||||||
#define BANKER 40
|
#define BANKER 40
|
||||||
#define MERCHANT 41
|
#define MERCHANT 41
|
||||||
#define DISCORD_MERCHANT 59
|
#define DISCORD_MERCHANT 59
|
||||||
#define ADVENTURE_RECRUITER 60
|
#define ADVENTURERECRUITER 60
|
||||||
#define ADVENTURE_MERCHANT 61
|
#define ADVENTUREMERCHANT 61
|
||||||
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs, seen on Danvi's Corpse in Akheva
|
#define LDON_TREASURE 62 // objects you can use /open on first seen in LDONs
|
||||||
|
#define CORPSE_CLASS 62 // only seen on Danvi's Corpse in Akheva so far..
|
||||||
#define TRIBUTE_MASTER 63
|
#define TRIBUTE_MASTER 63
|
||||||
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
#define GUILD_TRIBUTE_MASTER 64 // not sure
|
||||||
#define GUILD_BANKER 66
|
#define GUILD_BANKER 66
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
#define DARK_REIGN_MERCHANT 68
|
#define DARK_REIGN_MERCHANT 68
|
||||||
#define FELLOWSHIP_MASTER 69
|
#define FELLOWSHIP_MASTER 69
|
||||||
#define ALT_CURRENCY_MERCHANT 70
|
#define ALT_CURRENCY_MERCHANT 70
|
||||||
#define MERCENARY_MASTER 71
|
#define MERCERNARY_MASTER 71
|
||||||
|
|
||||||
|
|
||||||
// player class values
|
// player class values
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
#include "../database.h"
|
#include "../database.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../loottable.h"
|
|
||||||
#include "../repositories/content_flags_repository.h"
|
#include "../repositories/content_flags_repository.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -36,12 +35,8 @@ int WorldContentService::GetCurrentExpansion() const
|
|||||||
return current_expansion;
|
return current_expansion;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldContentService *WorldContentService::SetExpansionContext()
|
void WorldContentService::SetExpansionContext()
|
||||||
{
|
{
|
||||||
// do a rule manager reload until where we store expansion is changed to somewhere else
|
|
||||||
RuleManager::Instance()->LoadRules(GetDatabase(), "default", true);
|
|
||||||
|
|
||||||
// pull expansion from rules
|
|
||||||
int expansion = RuleI(Expansion, CurrentExpansion);
|
int expansion = RuleI(Expansion, CurrentExpansion);
|
||||||
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
|
||||||
content_service.SetCurrentExpansion(expansion);
|
content_service.SetCurrentExpansion(expansion);
|
||||||
@@ -52,8 +47,6 @@ WorldContentService *WorldContentService::SetExpansionContext()
|
|||||||
GetCurrentExpansion(),
|
GetCurrentExpansion(),
|
||||||
GetCurrentExpansionName()
|
GetCurrentExpansionName()
|
||||||
);
|
);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WorldContentService::GetCurrentExpansionName()
|
std::string WorldContentService::GetCurrentExpansionName()
|
||||||
@@ -80,47 +73,15 @@ void WorldContentService::SetCurrentExpansion(int current_expansion)
|
|||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::vector<ContentFlagsRepository::ContentFlags> &WorldContentService::GetContentFlags() const
|
const std::vector<std::string> &WorldContentService::GetContentFlags() const
|
||||||
{
|
{
|
||||||
return content_flags;
|
return content_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::vector<std::string> WorldContentService::GetContentFlagsEnabled()
|
|
||||||
{
|
|
||||||
std::vector<std::string> enabled_flags;
|
|
||||||
|
|
||||||
for (auto &f: GetContentFlags()) {
|
|
||||||
if (f.enabled) {
|
|
||||||
enabled_flags.emplace_back(f.flag_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return enabled_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
|
||||||
{
|
|
||||||
std::vector<std::string> disabled_flags;
|
|
||||||
|
|
||||||
for (auto &f: GetContentFlags()) {
|
|
||||||
if (!f.enabled) {
|
|
||||||
disabled_flags.emplace_back(f.flag_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return disabled_flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param content_flags
|
* @param content_flags
|
||||||
*/
|
*/
|
||||||
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
|
void WorldContentService::SetContentFlags(std::vector<std::string> content_flags)
|
||||||
{
|
{
|
||||||
WorldContentService::content_flags = content_flags;
|
WorldContentService::content_flags = content_flags;
|
||||||
}
|
}
|
||||||
@@ -129,10 +90,10 @@ void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::Co
|
|||||||
* @param content_flag
|
* @param content_flag
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
bool WorldContentService::IsContentFlagEnabled(const std::string& content_flag)
|
||||||
{
|
{
|
||||||
for (auto &f: GetContentFlags()) {
|
for (auto &flag : GetContentFlags()) {
|
||||||
if (f.flag_name == content_flag && f.enabled == true) {
|
if (flag == content_flag) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,102 +101,20 @@ bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void WorldContentService::ReloadContentFlags(Database &db)
|
||||||
* @param content_flag
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
|
|
||||||
{
|
{
|
||||||
for (auto &f: GetContentFlags()) {
|
std::vector<std::string> set_content_flags;
|
||||||
if (f.flag_name == content_flag && f.enabled == false) {
|
auto content_flags = ContentFlagsRepository::GetWhere(db, "enabled = 1");
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
set_content_flags.reserve(content_flags.size());
|
||||||
}
|
for (auto &flags: content_flags) {
|
||||||
|
set_content_flags.push_back(flags.flag_name);
|
||||||
bool WorldContentService::DoesPassContentFiltering(const ContentFlags &f)
|
|
||||||
{
|
|
||||||
// if we're not set to (-1 All) then fail when we aren't within minimum expansion
|
|
||||||
if (f.min_expansion > Expansion::EXPANSION_ALL && current_expansion < f.min_expansion && current_expansion != -1) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're not set to (-1 All) then fail when we aren't within max expansion
|
|
||||||
if (f.max_expansion > Expansion::EXPANSION_ALL && current_expansion > f.max_expansion && current_expansion != -1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we don't have any enabled flag in enabled flags, we fail
|
|
||||||
for (const auto& flag: Strings::Split(f.content_flags)) {
|
|
||||||
if (!Strings::Contains(GetContentFlagsEnabled(), flag)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we don't have any disabled flag in disabled flags, we fail
|
|
||||||
for (const auto& flag: Strings::Split(f.content_flags_disabled)) {
|
|
||||||
if (!Strings::Contains(GetContentFlagsDisabled(), flag)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldContentService::ReloadContentFlags()
|
|
||||||
{
|
|
||||||
std::vector<ContentFlagsRepository::ContentFlags> set_content_flags;
|
|
||||||
auto flags = ContentFlagsRepository::All(*GetDatabase());
|
|
||||||
|
|
||||||
set_content_flags.reserve(flags.size());
|
|
||||||
for (auto &f: flags) {
|
|
||||||
set_content_flags.push_back(f);
|
|
||||||
|
|
||||||
LogInfo(
|
LogInfo(
|
||||||
"Loaded content flag [{}] [{}]",
|
"Enabled content flags [{}]",
|
||||||
f.flag_name,
|
implode(", ", set_content_flags)
|
||||||
(f.enabled ? "Enabled" : "Disabled")
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
SetContentFlags(set_content_flags);
|
SetContentFlags(set_content_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Database *WorldContentService::GetDatabase() const
|
|
||||||
{
|
|
||||||
return m_database;
|
|
||||||
}
|
|
||||||
|
|
||||||
WorldContentService *WorldContentService::SetDatabase(Database *database)
|
|
||||||
{
|
|
||||||
WorldContentService::m_database = database;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldContentService::SetContentFlag(const std::string &content_flag_name, bool enabled)
|
|
||||||
{
|
|
||||||
auto flags = ContentFlagsRepository::GetWhere(
|
|
||||||
*GetDatabase(),
|
|
||||||
fmt::format("flag_name = '{}'", content_flag_name)
|
|
||||||
);
|
|
||||||
|
|
||||||
auto f = ContentFlagsRepository::NewEntity();
|
|
||||||
if (!flags.empty()) {
|
|
||||||
f = flags.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
f.enabled = enabled ? 1 : 0;
|
|
||||||
f.flag_name = content_flag_name;
|
|
||||||
|
|
||||||
if (!flags.empty()) {
|
|
||||||
ContentFlagsRepository::UpdateOne(*GetDatabase(), f);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ContentFlagsRepository::InsertOne(*GetDatabase(), f);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReloadContentFlags();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../loottable.h"
|
|
||||||
#include "../repositories/content_flags_repository.h"
|
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
@@ -54,7 +52,7 @@ namespace Expansion {
|
|||||||
VeilOfAlaris,
|
VeilOfAlaris,
|
||||||
RainOfFear,
|
RainOfFear,
|
||||||
CallOfTheForsaken,
|
CallOfTheForsaken,
|
||||||
TheDarkenedSea,
|
TheDarkendSea,
|
||||||
TheBrokenMirror,
|
TheBrokenMirror,
|
||||||
EmpiresOfKunark,
|
EmpiresOfKunark,
|
||||||
RingOfScale,
|
RingOfScale,
|
||||||
@@ -127,7 +125,7 @@ public:
|
|||||||
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsVeilOfAlarisEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::VeilOfAlaris || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsRainOfFearEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RainOfFear || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsCallOfTheForsakenEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::CallOfTheForsaken || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsTheDarkenedSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkenedSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsTheDarkendSeaEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheDarkendSea || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsTheBrokenMirrorEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::TheBrokenMirror || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsEmpiresOfKunarkEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::EmpiresOfKunark || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
bool IsRingOfScaleEnabled() { return GetCurrentExpansion() >= Expansion::ExpansionNumber::RingOfScale || GetCurrentExpansion() == Expansion::EXPANSION_ALL; }
|
||||||
@@ -155,35 +153,22 @@ public:
|
|||||||
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
|
bool IsCurrentExpansionVeilOfAlaris() { return current_expansion == Expansion::ExpansionNumber::VeilOfAlaris; }
|
||||||
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
|
bool IsCurrentExpansionRainOfFear() { return current_expansion == Expansion::ExpansionNumber::RainOfFear; }
|
||||||
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
|
bool IsCurrentExpansionCallOfTheForsaken() { return current_expansion == Expansion::ExpansionNumber::CallOfTheForsaken; }
|
||||||
bool IsCurrentExpansionTheDarkenedSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkenedSea; }
|
bool IsCurrentExpansionTheDarkendSea() { return current_expansion == Expansion::ExpansionNumber::TheDarkendSea; }
|
||||||
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
|
bool IsCurrentExpansionTheBrokenMirror() { return current_expansion == Expansion::ExpansionNumber::TheBrokenMirror; }
|
||||||
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
|
bool IsCurrentExpansionEmpiresOfKunark() { return current_expansion == Expansion::ExpansionNumber::EmpiresOfKunark; }
|
||||||
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
|
bool IsCurrentExpansionRingOfScale() { return current_expansion == Expansion::ExpansionNumber::RingOfScale; }
|
||||||
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
|
bool IsCurrentExpansionTheBurningLands() { return current_expansion == Expansion::ExpansionNumber::TheBurningLands; }
|
||||||
bool IsCurrentExpansionTormentOfVelious() { return current_expansion == Expansion::ExpansionNumber::TormentOfVelious; }
|
bool IsCurrentExpansionTormentOfVelious() { return current_expansion == Expansion::ExpansionNumber::TormentOfVelious; }
|
||||||
|
|
||||||
const std::vector<ContentFlagsRepository::ContentFlags> &GetContentFlags() const;
|
|
||||||
std::vector<std::string> GetContentFlagsEnabled();
|
|
||||||
std::vector<std::string> GetContentFlagsDisabled();
|
|
||||||
bool IsContentFlagEnabled(const std::string& content_flag);
|
|
||||||
bool IsContentFlagDisabled(const std::string& content_flag);
|
|
||||||
void SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags);
|
|
||||||
void ReloadContentFlags();
|
|
||||||
WorldContentService * SetExpansionContext();
|
|
||||||
|
|
||||||
bool DoesPassContentFiltering(const ContentFlags& f);
|
|
||||||
|
|
||||||
WorldContentService * SetDatabase(Database *database);
|
|
||||||
Database *GetDatabase() const;
|
|
||||||
|
|
||||||
void SetContentFlag(const std::string &content_flag_name, bool enabled);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int current_expansion{};
|
int current_expansion{};
|
||||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
std::vector<std::string> content_flags;
|
||||||
|
public:
|
||||||
// reference to database
|
const std::vector<std::string> &GetContentFlags() const;
|
||||||
Database *m_database;
|
bool IsContentFlagEnabled(const std::string& content_flag);
|
||||||
|
void SetContentFlags(std::vector<std::string> content_flags);
|
||||||
|
void ReloadContentFlags(Database &db);
|
||||||
|
void SetExpansionContext();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern WorldContentService content_service;
|
extern WorldContentService content_service;
|
||||||
|
|||||||
+8
-144
@@ -1,98 +1,6 @@
|
|||||||
#include "global_define.h"
|
#include "global_define.h"
|
||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
#include "crash.h"
|
#include "crash.h"
|
||||||
#include "strings.h"
|
|
||||||
#include "process/process.h"
|
|
||||||
#include "http/httplib.h"
|
|
||||||
#include "http/uri.h"
|
|
||||||
#include "json/json.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "eqemu_config.h"
|
|
||||||
#include "serverinfo.h"
|
|
||||||
#include "rulesys.h"
|
|
||||||
#include "platform.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#if WINDOWS
|
|
||||||
#define popen _popen
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SendCrashReport(const std::string &crash_report)
|
|
||||||
{
|
|
||||||
// can configure multiple endpoints if need be
|
|
||||||
std::vector<std::string> endpoints = {
|
|
||||||
"http://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
|
||||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
|
||||||
};
|
|
||||||
|
|
||||||
auto config = EQEmuConfig::get();
|
|
||||||
for (auto &e: endpoints) {
|
|
||||||
uri u(e);
|
|
||||||
|
|
||||||
std::string base_url = fmt::format("{}://{}", u.get_scheme(), u.get_host());
|
|
||||||
if (u.get_port()) {
|
|
||||||
base_url += fmt::format(":{}", u.get_port());
|
|
||||||
}
|
|
||||||
|
|
||||||
// client
|
|
||||||
httplib::Client r(base_url);
|
|
||||||
r.set_connection_timeout(1, 0);
|
|
||||||
r.set_read_timeout(1, 0);
|
|
||||||
r.set_write_timeout(1, 0);
|
|
||||||
httplib::Headers headers = {
|
|
||||||
{"Content-Type", "application/json"}
|
|
||||||
};
|
|
||||||
|
|
||||||
// os info
|
|
||||||
auto os = EQ::GetOS();
|
|
||||||
auto cpus = EQ::GetCPUs();
|
|
||||||
auto process_id = EQ::GetPID();
|
|
||||||
auto rss = EQ::GetRSS() / 1048576.0;
|
|
||||||
auto uptime = static_cast<uint32>(EQ::GetUptime());
|
|
||||||
|
|
||||||
// payload
|
|
||||||
Json::Value p;
|
|
||||||
p["platform_name"] = GetPlatformName();
|
|
||||||
p["crash_report"] = crash_report;
|
|
||||||
p["server_version"] = CURRENT_VERSION;
|
|
||||||
p["compile_date"] = COMPILE_DATE;
|
|
||||||
p["compile_time"] = COMPILE_TIME;
|
|
||||||
p["server_name"] = config->LongName;
|
|
||||||
p["server_short_name"] = config->ShortName;
|
|
||||||
p["uptime"] = uptime;
|
|
||||||
p["os_machine"] = os.machine;
|
|
||||||
p["os_release"] = os.release;
|
|
||||||
p["os_version"] = os.version;
|
|
||||||
p["os_sysname"] = os.sysname;
|
|
||||||
p["process_id"] = process_id;
|
|
||||||
p["rss_memory"] = rss;
|
|
||||||
p["cpus"] = cpus.size();
|
|
||||||
p["origination_info"] = "";
|
|
||||||
|
|
||||||
if (!LogSys.origination_info.zone_short_name.empty()) {
|
|
||||||
p["origination_info"] = fmt::format(
|
|
||||||
"{} ({}) instance_id [{}]",
|
|
||||||
LogSys.origination_info.zone_short_name,
|
|
||||||
LogSys.origination_info.zone_long_name,
|
|
||||||
LogSys.origination_info.instance_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream payload;
|
|
||||||
payload << p;
|
|
||||||
|
|
||||||
if (auto res = r.Post(e, payload.str(), "application/json")) {
|
|
||||||
if (res->status == 200) {
|
|
||||||
LogInfo("Sent crash report");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogError("Failed to send crash report to [{}]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
||||||
#include "StackWalker.h"
|
#include "StackWalker.h"
|
||||||
@@ -104,30 +12,22 @@ public:
|
|||||||
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
||||||
virtual void OnOutput(LPCSTR szText) {
|
virtual void OnOutput(LPCSTR szText) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
for (int i = 0; i < 4096; ++i) {
|
for(int i = 0; i < 4096; ++i) {
|
||||||
if (szText[i] == 0) {
|
if(szText[i] == 0) {
|
||||||
buffer[i] = '\0';
|
buffer[i] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (szText[i] == '\n' || szText[i] == '\r') {
|
if(szText[i] == '\n' || szText[i] == '\r') {
|
||||||
buffer[i] = ' ';
|
buffer[i] = ' ';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
buffer[i] = szText[i];
|
buffer[i] = szText[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line = buffer;
|
|
||||||
_lines.push_back(line);
|
|
||||||
|
|
||||||
Log(Logs::General, Logs::Crash, buffer);
|
Log(Logs::General, Logs::Crash, buffer);
|
||||||
StackWalker::OnOutput(szText);
|
StackWalker::OnOutput(szText);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& const GetLines() { return _lines; }
|
|
||||||
private:
|
|
||||||
std::vector<std::string> _lines;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
@@ -201,20 +101,7 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
|||||||
|
|
||||||
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||||
{
|
{
|
||||||
EQEmuStackWalker sw;
|
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||||
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
|
||||||
|
|
||||||
if (RuleB(Analytics, CrashReporting)) {
|
|
||||||
std::string crash_report;
|
|
||||||
auto& lines = sw.GetLines();
|
|
||||||
|
|
||||||
for (auto& line : lines) {
|
|
||||||
crash_report += line;
|
|
||||||
crash_report += "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
SendCrashReport(crash_report);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
@@ -238,27 +125,9 @@ void set_exception_handler() {
|
|||||||
|
|
||||||
void print_trace()
|
void print_trace()
|
||||||
{
|
{
|
||||||
bool does_gdb_exist = Strings::Contains(Process::execute("gdb -v"), "GNU");
|
|
||||||
if (!does_gdb_exist) {
|
|
||||||
LogCrash(
|
|
||||||
"[Error] GDB is not installed, if you want crash dumps on Linux to work properly you will need GDB installed"
|
|
||||||
);
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto uid = geteuid();
|
auto uid = geteuid();
|
||||||
std::string temp_output_file = fmt::format("/tmp/dump-output-{}", Strings::Random(10));
|
|
||||||
|
|
||||||
// check for passwordless sudo if not root
|
std::string temp_output_file = "/tmp/dump-output";
|
||||||
if (uid != 0) {
|
|
||||||
bool sudo_password_required = Strings::Contains(Process::execute("sudo -n true"), "a password is required");
|
|
||||||
if (sudo_password_required) {
|
|
||||||
LogCrash(
|
|
||||||
"[Error] Current user does not have passwordless sudo installed. It is required to automatically process crash dumps with GDB as non-root."
|
|
||||||
);
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char pid_buf[30];
|
char pid_buf[30];
|
||||||
sprintf(pid_buf, "%d", getpid());
|
sprintf(pid_buf, "%d", getpid());
|
||||||
@@ -267,6 +136,7 @@ void print_trace()
|
|||||||
int child_pid = fork();
|
int child_pid = fork();
|
||||||
if (!child_pid) {
|
if (!child_pid) {
|
||||||
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
dup2(fd, 1); // redirect output to stderr
|
dup2(fd, 1); // redirect output to stderr
|
||||||
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
||||||
if (uid == 0) {
|
if (uid == 0) {
|
||||||
@@ -281,22 +151,16 @@ void print_trace()
|
|||||||
abort(); /* If gdb failed to start */
|
abort(); /* If gdb failed to start */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
waitpid(child_pid, nullptr, 0);
|
waitpid(child_pid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream input(temp_output_file);
|
std::ifstream input(temp_output_file);
|
||||||
std::string crash_report;
|
|
||||||
for (std::string line; getline(input, line);) {
|
for (std::string line; getline(input, line);) {
|
||||||
LogCrash("{}", line);
|
LogCrash("{}", line);
|
||||||
crash_report += fmt::format("{}\n", line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::remove(temp_output_file.c_str());
|
std::remove(temp_output_file.c_str());
|
||||||
|
|
||||||
if (RuleB(Analytics, CrashReporting)) {
|
|
||||||
SendCrashReport(crash_report);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+369
-242
@@ -45,14 +45,11 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "eq_packet_structs.h"
|
#include "eq_packet_structs.h"
|
||||||
#include "extprofile.h"
|
#include "extprofile.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
#include "database_schema.h"
|
#include "database_schema.h"
|
||||||
#include "http/httplib.h"
|
#include "http/httplib.h"
|
||||||
#include "http/uri.h"
|
#include "http/uri.h"
|
||||||
|
|
||||||
#include "repositories/zone_repository.h"
|
|
||||||
#include "zone_store.h"
|
|
||||||
|
|
||||||
extern Client client;
|
extern Client client;
|
||||||
|
|
||||||
Database::Database () {
|
Database::Database () {
|
||||||
@@ -71,11 +68,11 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c
|
|||||||
uint32 errnum= 0;
|
uint32 errnum= 0;
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
|
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
|
||||||
LogError("Connection [{}] Failed to connect to database Error [{}]", connection_label, errbuf);
|
LogError("[MySQL] Connection [{}] Failed to connect to database: Error [{}]", connection_label, errbuf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogInfo("Connected to database [{}] [{}] @ [{}:{}]", connection_label, database, host,port);
|
LogInfo("[MySQL] Connection [{}] database [{}] at [{}]:[{}]", connection_label, database, host,port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,123 +92,112 @@ Database::~Database()
|
|||||||
*/
|
*/
|
||||||
uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) {
|
uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) {
|
||||||
|
|
||||||
if (strlen(name) >= 50 || strlen(password) >= 50)
|
if(strlen(name) >= 50 || strlen(password) >= 50)
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
char temporary_username[100];
|
char tmpUN[100];
|
||||||
char temporary_password[100];
|
char tmpPW[100];
|
||||||
|
|
||||||
DoEscapeString(temporary_username, name, strlen(name));
|
DoEscapeString(tmpUN, name, strlen(name));
|
||||||
DoEscapeString(temporary_password, password, strlen(password));
|
DoEscapeString(tmpPW, password, strlen(password));
|
||||||
|
|
||||||
std::string query = fmt::format(
|
std::string query = StringFormat("SELECT id, status FROM account WHERE `name`='%s' AND ls_id='%s' AND password is not null "
|
||||||
"SELECT id, status FROM account WHERE `name` = '{}' AND ls_id = '{}' AND password is NOT NULL "
|
"and length(password) > 0 and (password='%s' or password=MD5('%s'))",
|
||||||
"AND length(password) > 0 AND (password = '{}' OR password = MD5('{}'))",
|
tmpUN, EscapeString(loginserver).c_str(), tmpPW, tmpPW);
|
||||||
temporary_username,
|
|
||||||
Strings::Escape(loginserver),
|
|
||||||
temporary_password,
|
|
||||||
temporary_password
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
if (!results.Success())
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
auto id = std::stoul(row[0]);
|
uint32 id = atoi(row[0]);
|
||||||
|
|
||||||
if (oStatus) {
|
if (oStatus)
|
||||||
*oStatus = std::stoi(row[1]);
|
*oStatus = atoi(row[1]);
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table.
|
//Get Banned IP Address List - Only return false if the incoming connection's IP address is not present in the banned_ips table.
|
||||||
bool Database::CheckBannedIPs(std::string login_ip)
|
bool Database::CheckBannedIPs(const char* loginIP)
|
||||||
{
|
{
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT ip_address FROM banned_ips WHERE ip_address='%s'", loginIP);
|
||||||
"SELECT ip_address FROM banned_ips WHERE ip_address = '{}'",
|
|
||||||
login_ip
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || results.RowCount() != 0) {
|
if (!results.Success())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::AddBannedIP(std::string banned_ip, std::string notes) {
|
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("INSERT into banned_ips SET ip_address='%s', notes='%s'", bannedIP, notes);
|
||||||
"INSERT into banned_ips SET ip_address = '{}', notes = '{}'",
|
|
||||||
Strings::Escape(banned_ip),
|
|
||||||
Strings::Escape(notes)
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckGMIPs(std::string login_ip, uint32 account_id) {
|
bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) {
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id);
|
||||||
"SELECT * FROM `gm_ips` WHERE `ip_address` = '{}' AND `account_id` = {}",
|
|
||||||
login_ip,
|
|
||||||
account_id
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 1) {
|
if (results.RowCount() == 1)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LoginIP(uint32 account_id, std::string login_ip) {
|
bool Database::AddGMIP(char* ip_address, char* name) {
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name);
|
||||||
"INSERT INTO account_ip SET accid = {}, ip = '{}' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()",
|
auto results = QueryDatabase(query);
|
||||||
account_id,
|
return results.Success();
|
||||||
login_ip
|
}
|
||||||
);
|
|
||||||
|
void Database::LoginIP(uint32 AccountID, const char* LoginIP) {
|
||||||
|
std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP);
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Database::CheckStatus(uint32 account_id)
|
int16 Database::CheckStatus(uint32 account_id)
|
||||||
{
|
{
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat(
|
||||||
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = {}",
|
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = %i",
|
||||||
account_id
|
account_id);
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success() || results.RowCount() != 1) {
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (results.RowCount() != 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
int16 status = std::stoi(row[0]);
|
int16 status = atoi(row[0]);
|
||||||
int32 date_diff = 0;
|
int32 date_diff = 0;
|
||||||
|
|
||||||
if (row[1]) {
|
if (row[1] != nullptr)
|
||||||
date_diff = std::stoi(row[1]);
|
date_diff = atoi(row[1]);
|
||||||
}
|
|
||||||
|
|
||||||
if (date_diff > 0) {
|
if (date_diff > 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -281,7 +267,7 @@ bool Database::DeleteAccount(const char* name, const char *loginserver) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Database::SetLocalPassword(uint32 accid, const char* password) {
|
bool Database::SetLocalPassword(uint32 accid, const char* password) {
|
||||||
std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", Strings::Escape(password).c_str(), accid);
|
std::string query = StringFormat("UPDATE account SET password=MD5('%s') where id=%i;", EscapeString(password).c_str(), accid);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
@@ -321,7 +307,9 @@ bool Database::SetAccountStatus(const std::string& account_name, int16 status)
|
|||||||
LogInfo("Account [{}] is attempting to be set to status [{}]", account_name, status);
|
LogInfo("Account [{}] is attempting to be set to status [{}]", account_name, status);
|
||||||
|
|
||||||
std::string query = fmt::format(
|
std::string query = fmt::format(
|
||||||
"UPDATE account SET status = {} WHERE name = '{}'",
|
SQL(
|
||||||
|
UPDATE account SET status = {} WHERE name = '{}'
|
||||||
|
),
|
||||||
status,
|
status,
|
||||||
account_name
|
account_name
|
||||||
);
|
);
|
||||||
@@ -376,10 +364,9 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
|||||||
* @param character_name
|
* @param character_name
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool Database::DeleteCharacter(char *character_name)
|
bool Database::DeleteCharacter(char *character_name) {
|
||||||
{
|
|
||||||
uint32 character_id = 0;
|
uint32 character_id = 0;
|
||||||
if (!character_name || !strlen(character_name)) {
|
if(!character_name || !strlen(character_name)) {
|
||||||
LogInfo("DeleteCharacter: request to delete without a name (empty char slot)");
|
LogInfo("DeleteCharacter: request to delete without a name (empty char slot)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -391,14 +378,14 @@ bool Database::DeleteCharacter(char *character_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (character_id <= 0) {
|
if (character_id <= 0) {
|
||||||
LogError("Invalid Character ID [{}]", character_name);
|
LogError("DeleteCharacter | Invalid Character ID [{}]", character_name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string delete_type = "hard-deleted";
|
std::string delete_type = "hard-deleted";
|
||||||
if (RuleB(Character, SoftDeletes)) {
|
if (RuleB(Character, SoftDeletes)) {
|
||||||
delete_type = "soft-deleted";
|
delete_type = "soft-deleted";
|
||||||
query = fmt::format(
|
std::string query = fmt::format(
|
||||||
SQL(
|
SQL(
|
||||||
UPDATE
|
UPDATE
|
||||||
character_data
|
character_data
|
||||||
@@ -413,38 +400,23 @@ bool Database::DeleteCharacter(char *character_name)
|
|||||||
|
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
|
|
||||||
if (RuleB(Bots, Enabled)) {
|
|
||||||
query = fmt::format(
|
|
||||||
SQL(
|
|
||||||
UPDATE
|
|
||||||
bot_data
|
|
||||||
SET
|
|
||||||
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64)
|
|
||||||
WHERE
|
|
||||||
owner_id = '{}'
|
|
||||||
),
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
QueryDatabase(query);
|
|
||||||
LogInfo(
|
|
||||||
"[DeleteCharacter] character_name [{}] ({}) bots are being [{}]",
|
|
||||||
character_name,
|
|
||||||
character_id,
|
|
||||||
delete_type
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &iter: DatabaseSchema::GetCharacterTables()) {
|
LogInfo("DeleteCharacter | Character [{}] ({}) is being [{}]", character_name, character_id, delete_type);
|
||||||
|
|
||||||
|
for (const auto& iter : DatabaseSchema::GetCharacterTables()) {
|
||||||
std::string table_name = iter.first;
|
std::string table_name = iter.first;
|
||||||
std::string character_id_column_name = iter.second;
|
std::string character_id_column_name = iter.second;
|
||||||
|
|
||||||
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
|
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("character_name [{}] ({}) is being [{}]", character_name, character_id, delete_type);
|
#ifdef BOTS
|
||||||
|
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", character_id); // note: only use of GetMobTypeById()
|
||||||
|
QueryDatabase(query);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -636,8 +608,8 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
")",
|
")",
|
||||||
character_id, // " id, "
|
character_id, // " id, "
|
||||||
account_id, // " account_id, "
|
account_id, // " account_id, "
|
||||||
Strings::Escape(pp->name).c_str(), // " `name`, "
|
EscapeString(pp->name).c_str(), // " `name`, "
|
||||||
Strings::Escape(pp->last_name).c_str(), // " last_name, "
|
EscapeString(pp->last_name).c_str(), // " last_name, "
|
||||||
pp->gender, // " gender, "
|
pp->gender, // " gender, "
|
||||||
pp->race, // " race, "
|
pp->race, // " race, "
|
||||||
pp->class_, // " class, "
|
pp->class_, // " class, "
|
||||||
@@ -661,8 +633,8 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
pp->ability_number, // " ability_number, "
|
pp->ability_number, // " ability_number, "
|
||||||
pp->ability_time_minutes, // " ability_time_minutes, "
|
pp->ability_time_minutes, // " ability_time_minutes, "
|
||||||
pp->ability_time_hours, // " ability_time_hours, "
|
pp->ability_time_hours, // " ability_time_hours, "
|
||||||
Strings::Escape(pp->title).c_str(), // " title, "
|
EscapeString(pp->title).c_str(), // " title, "
|
||||||
Strings::Escape(pp->suffix).c_str(), // " suffix, "
|
EscapeString(pp->suffix).c_str(), // " suffix, "
|
||||||
pp->exp, // " exp, "
|
pp->exp, // " exp, "
|
||||||
pp->points, // " points, "
|
pp->points, // " points, "
|
||||||
pp->mana, // " mana, "
|
pp->mana, // " mana, "
|
||||||
@@ -744,7 +716,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
/* HoTT Ability */
|
/* HoTT Ability */
|
||||||
if(RuleB(Character, GrantHoTTOnCreate))
|
if(RuleB(Character, GrantHoTTOnCreate))
|
||||||
{
|
{
|
||||||
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)", character_id, 14, 1);
|
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, rank) VALUES (%u, %i, %i)", character_id, 14, 1);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +770,7 @@ uint32 Database::GetCharacterID(const char *name) {
|
|||||||
Zero will also be returned if there is a database error.
|
Zero will also be returned if there is a database error.
|
||||||
*/
|
*/
|
||||||
uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
||||||
std::string query = StringFormat("SELECT `account_id`, `id` FROM `character_data` WHERE name='%s'", Strings::Escape(charname).c_str());
|
std::string query = StringFormat("SELECT `account_id`, `id` FROM `character_data` WHERE name='%s'", EscapeString(charname).c_str());
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
@@ -835,34 +807,36 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
|
|||||||
return atoi(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
|
uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver, int16* status, uint32* lsid) {
|
||||||
if (!isAlphaNumeric(account_name.c_str())) {
|
if (!isAlphaNumeric(accname))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1",
|
||||||
"SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '{}' AND `ls_id` = '{}' LIMIT 1",
|
EscapeString(accname).c_str(), EscapeString(loginserver).c_str());
|
||||||
Strings::Escape(account_name),
|
|
||||||
Strings::Escape(loginserver)
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
if (!results.Success()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
if (results.RowCount() != 1)
|
||||||
auto account_id = std::stoul(row[0]);
|
return 0;
|
||||||
|
|
||||||
if (status) {
|
auto row = results.begin();
|
||||||
*status = static_cast<int16>(std::stoi(row[1]));
|
|
||||||
}
|
uint32 id = atoi(row[0]);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
*status = atoi(row[1]);
|
||||||
|
|
||||||
if (lsid) {
|
if (lsid) {
|
||||||
*lsid = row[2] ? std::stoul(row[2]) : 0;
|
if (row[2])
|
||||||
|
*lsid = atoi(row[2]);
|
||||||
|
else
|
||||||
|
*lsid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return account_id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) {
|
void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) {
|
||||||
@@ -975,8 +949,6 @@ bool Database::LoadVariables() {
|
|||||||
varcache.Add(key, value);
|
varcache.Add(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Loaded [{}] variable(s)", Strings::Commify(std::to_string(results.RowCount())));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1001,8 +973,8 @@ bool Database::GetVariable(std::string varname, std::string &varvalue)
|
|||||||
|
|
||||||
bool Database::SetVariable(const std::string varname, const std::string &varvalue)
|
bool Database::SetVariable(const std::string varname, const std::string &varvalue)
|
||||||
{
|
{
|
||||||
std::string escaped_name = Strings::Escape(varname);
|
std::string escaped_name = EscapeString(varname);
|
||||||
std::string escaped_value = Strings::Escape(varvalue);
|
std::string escaped_value = EscapeString(varvalue);
|
||||||
std::string query = StringFormat("Update variables set value='%s' WHERE varname like '%s'", escaped_value.c_str(), escaped_name.c_str());
|
std::string query = StringFormat("Update variables set value='%s' WHERE varname like '%s'", escaped_value.c_str(), escaped_name.c_str());
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
@@ -1025,16 +997,110 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetAccountCRCField(uint32 account_id, std::string field_name, uint64 checksum)
|
// Get zone starting points from DB
|
||||||
{
|
bool Database::GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x, float* safe_y, float* safe_z, float* safe_heading, int16* min_status, uint8* min_level, char *flag_needed) {
|
||||||
QueryDatabase(
|
|
||||||
fmt::format(
|
if (zone_short_name == nullptr)
|
||||||
"UPDATE `account` SET `{}` = '{}' WHERE `id` = {}",
|
return false;
|
||||||
field_name,
|
|
||||||
checksum,
|
std::string query = fmt::format(
|
||||||
account_id
|
SQL(
|
||||||
)
|
SELECT
|
||||||
|
`safe_x`, `safe_y`, `safe_z`, `safe_heading`, `min_status`, `min_level`, `flag_needed`
|
||||||
|
FROM
|
||||||
|
zone
|
||||||
|
WHERE
|
||||||
|
`short_name` = '{}'
|
||||||
|
AND
|
||||||
|
(`version` = {} OR `version` = 0)
|
||||||
|
ORDER BY `version` DESC
|
||||||
|
), zone_short_name, instance_version
|
||||||
);
|
);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
if (safe_x != nullptr)
|
||||||
|
*safe_x = atof(row[0]);
|
||||||
|
|
||||||
|
if (safe_y != nullptr)
|
||||||
|
*safe_y = atof(row[1]);
|
||||||
|
|
||||||
|
if (safe_z != nullptr)
|
||||||
|
*safe_z = atof(row[2]);
|
||||||
|
|
||||||
|
if (safe_heading != nullptr)
|
||||||
|
*safe_heading = atof(row[3]);
|
||||||
|
|
||||||
|
if (min_status != nullptr)
|
||||||
|
*min_status = atoi(row[4]);
|
||||||
|
|
||||||
|
if (min_level != nullptr)
|
||||||
|
*min_level = atoi(row[5]);
|
||||||
|
|
||||||
|
if (flag_needed != nullptr)
|
||||||
|
strcpy(flag_needed, row[6]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) {
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
if (long_name != nullptr)
|
||||||
|
*long_name = strcpy(new char[strlen(row[0])+1], row[0]);
|
||||||
|
|
||||||
|
if (file_name != nullptr) {
|
||||||
|
if (row[1] == nullptr)
|
||||||
|
strcpy(file_name, short_name);
|
||||||
|
else
|
||||||
|
strcpy(file_name, row[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (safe_x != nullptr)
|
||||||
|
*safe_x = atof(row[2]);
|
||||||
|
if (safe_y != nullptr)
|
||||||
|
*safe_y = atof(row[3]);
|
||||||
|
if (safe_z != nullptr)
|
||||||
|
*safe_z = atof(row[4]);
|
||||||
|
if (graveyard_id != nullptr)
|
||||||
|
*graveyard_id = atoi(row[5]);
|
||||||
|
if (maxclients != nullptr)
|
||||||
|
*maxclients = atoi(row[6]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) {
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT graveyard_id FROM zone WHERE zoneidnumber='%u' AND (version=%i OR version=0) ORDER BY version DESC", zone_id, version);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) {
|
bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) {
|
||||||
@@ -1065,74 +1131,108 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Database::GetPEQZone(uint32 zone_id, uint32 version){
|
uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){
|
||||||
|
|
||||||
auto z = GetZoneVersionWithFallback(zone_id, version);
|
std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
return z ? z->peqzone : 0;
|
if (!results.Success()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckNameFilter(std::string name, bool surname)
|
bool Database::CheckNameFilter(const char* name, bool surname)
|
||||||
{
|
{
|
||||||
name = Strings::ToLower(name);
|
std::string str_name = name;
|
||||||
|
|
||||||
// the minimum 4 is enforced by the client too
|
// the minimum 4 is enforced by the client too
|
||||||
if (name.empty() || name.size() < 4) {
|
if (!name || strlen(name) < 4)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given name length is enforced by the client too
|
// Given name length is enforced by the client too
|
||||||
if (!surname && name.size() > 15) {
|
if (!surname && strlen(name) > 15)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < name.size(); i++) {
|
for (size_t i = 0; i < str_name.size(); i++)
|
||||||
if (!isalpha(name[i])) {
|
{
|
||||||
|
if(!isalpha(str_name[i]))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(size_t x = 0; x < str_name.size(); ++x)
|
||||||
|
{
|
||||||
|
str_name[x] = tolower(str_name[x]);
|
||||||
|
}
|
||||||
|
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
uint8 num_c = 0;
|
uint8 num_c = 0;
|
||||||
for (size_t x = 0; x < name.size(); ++x) {
|
for(size_t x = 0; x < str_name.size(); ++x)
|
||||||
if (name[x] == c) {
|
{
|
||||||
|
if(str_name[x] == c)
|
||||||
|
{
|
||||||
num_c++;
|
num_c++;
|
||||||
} else {
|
|
||||||
num_c = 1;
|
|
||||||
c = name[x];
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (num_c > 2) {
|
{
|
||||||
|
num_c = 1;
|
||||||
|
c = str_name[x];
|
||||||
|
}
|
||||||
|
if(num_c > 2)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string query = "SELECT name FROM name_filter";
|
|
||||||
|
std::string query("SELECT name FROM name_filter");
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
|
// false through to true? shouldn't it be falls through to false?
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row : results) {
|
for (auto row = results.begin();row != results.end();++row)
|
||||||
std::string current_row = Strings::ToLower(row[0]);
|
{
|
||||||
if (name.find(current_row) != std::string::npos) {
|
std::string current_row = row[0];
|
||||||
|
|
||||||
|
for(size_t x = 0; x < current_row.size(); ++x)
|
||||||
|
current_row[x] = tolower(current_row[x]);
|
||||||
|
|
||||||
|
if(str_name.find(current_row) != std::string::npos)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::AddToNameFilter(std::string name) {
|
bool Database::AddToNameFilter(const char* name) {
|
||||||
auto query = fmt::format(
|
|
||||||
"INSERT INTO name_filter (name) values ('{}')",
|
std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name);
|
||||||
name
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.RowsAffected()) {
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (results.RowsAffected() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,16 +1320,16 @@ bool Database::UpdateName(const char* oldname, const char* newname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the name is used or an error occurs, it returns false, otherwise it returns true
|
// If the name is used or an error occurs, it returns false, otherwise it returns true
|
||||||
bool Database::CheckUsedName(std::string name) {
|
bool Database::CheckUsedName(const char* name) {
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
|
||||||
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
|
|
||||||
name
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() || results.RowCount()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1281,6 +1381,44 @@ bool Database::MoveCharacterToZone(const char *charname, uint32 zone_id)
|
|||||||
return results.RowsAffected() != 0;
|
return results.RowsAffected() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
|
||||||
|
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.RowsAffected() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
|
||||||
|
//Utilize the "hacker" table, but also give zone information.
|
||||||
|
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.RowsAffected() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const std::string &hacked, const char* zone) {
|
||||||
|
//Utilize the "hacker" table, but also give zone information.
|
||||||
|
auto query = fmt::format("INSERT INTO hackers(account, name, hacked, zone) values('{}', '{}', '{}', '{}')",
|
||||||
|
accountname, charactername, hacked, zone);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.RowsAffected() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
||||||
{
|
{
|
||||||
uint16 race_cap = 0;
|
uint16 race_cap = 0;
|
||||||
@@ -1349,25 +1487,41 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
|
|||||||
return base_cap;
|
return base_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id)
|
uint32 Database::GetCharacterInfo(
|
||||||
|
const char *iName,
|
||||||
|
uint32 *oAccID,
|
||||||
|
uint32 *oZoneID,
|
||||||
|
uint32 *oInstanceID,
|
||||||
|
float *oX,
|
||||||
|
float *oY,
|
||||||
|
float *oZ
|
||||||
|
)
|
||||||
{
|
{
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat(
|
||||||
"SELECT `id`, `account_id`, `zone_id`, `zone_instance` FROM `character_data` WHERE `name` = '{}'",
|
"SELECT `id`, `account_id`, `zone_id`, `zone_instance`, `x`, `y`, `z` FROM `character_data` WHERE `name` = '%s'",
|
||||||
Strings::Escape(character_name)
|
EscapeString(iName).c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.RowCount()) {
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto character_id = std::stoul(row[0]);
|
uint32 charid = atoi(row[0]);
|
||||||
*account_id = std::stoul(row[1]);
|
if (oAccID) { *oAccID = atoi(row[1]); }
|
||||||
*zone_id = std::stoul(row[2]);
|
if (oZoneID) { *oZoneID = atoi(row[2]); }
|
||||||
*instance_id = std::stoul(row[3]);
|
if (oInstanceID) { *oInstanceID = atoi(row[3]); }
|
||||||
|
if (oX) { *oX = atof(row[4]); }
|
||||||
|
if (oY) { *oY = atof(row[5]); }
|
||||||
|
if (oZ) { *oZ = atof(row[6]); }
|
||||||
|
|
||||||
return character_id;
|
return charid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
|
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
|
||||||
@@ -1426,7 +1580,7 @@ void Database::AddReport(std::string who, std::string against, std::string lines
|
|||||||
auto escape_str = new char[lines.size() * 2 + 1];
|
auto escape_str = new char[lines.size() * 2 + 1];
|
||||||
DoEscapeString(escape_str, lines.c_str(), lines.size());
|
DoEscapeString(escape_str, lines.c_str(), lines.size());
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", Strings::Escape(who).c_str(), Strings::Escape(against).c_str(), escape_str);
|
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", EscapeString(who).c_str(), EscapeString(against).c_str(), escape_str);
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
safe_delete_array(escape_str);
|
safe_delete_array(escape_str);
|
||||||
}
|
}
|
||||||
@@ -1491,40 +1645,33 @@ uint32 Database::GetGroupID(const char* name){
|
|||||||
return atoi(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
/* Is this really getting used properly... A half implementation ? Akkadius */
|
||||||
|
char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) {
|
||||||
|
strcpy(leaderbuf, "");
|
||||||
uint32 group_id = 0;
|
uint32 group_id = 0;
|
||||||
|
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT `groupid` FROM `group_id` WHERE `name` = '%s'", name);
|
||||||
"SELECT `groupid` FROM `group_id` WHERE `name` = '{}'",
|
|
||||||
character_name
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (results.Success() && results.RowCount()) {
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
auto row = results.begin();
|
if (row[0])
|
||||||
group_id = std::stoul(row[0]);
|
group_id = atoi(row[0]);
|
||||||
}
|
|
||||||
|
|
||||||
if (!group_id) {
|
if (group_id == 0)
|
||||||
return std::string();
|
return leaderbuf;
|
||||||
}
|
|
||||||
|
|
||||||
query = fmt::format(
|
query = StringFormat("SELECT `leadername` FROM `group_leaders` WHERE `gid` = '%u' LIMIT 1", group_id);
|
||||||
"SELECT `leadername` FROM `group_leaders` WHERE `gid` = {} LIMIT 1",
|
|
||||||
group_id
|
|
||||||
);
|
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
if (results.Success() && results.RowCount()) {
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
auto row = results.begin();
|
if (row[0])
|
||||||
return row[0];
|
strcpy(leaderbuf, row[0]);
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
return leaderbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
||||||
std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", Strings::Escape(name).c_str(), gid);
|
std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", EscapeString(name).c_str(), gid);
|
||||||
auto result = QueryDatabase(query);
|
auto result = QueryDatabase(query);
|
||||||
|
|
||||||
if(result.RowsAffected() != 0) {
|
if(result.RowsAffected() != 0) {
|
||||||
@@ -1532,7 +1679,7 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
query = StringFormat("REPLACE INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')",
|
query = StringFormat("REPLACE INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')",
|
||||||
gid, Strings::Escape(name).c_str());
|
gid, EscapeString(name).c_str());
|
||||||
result = QueryDatabase(query);
|
result = QueryDatabase(query);
|
||||||
|
|
||||||
if(!result.Success()) {
|
if(!result.Success()) {
|
||||||
@@ -2115,32 +2262,28 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Database::GetIPExemption(std::string account_ip) {
|
int Database::GetIPExemption(std::string account_ip) {
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str());
|
||||||
"SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
|
|
||||||
account_ip
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.RowCount()) {
|
|
||||||
return RuleI(World, MaxClientsPerIP);
|
if (results.Success() && results.RowCount() > 0) {
|
||||||
|
auto row = results.begin();
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
return RuleI(World, MaxClientsPerIP);
|
||||||
return std::stoi(row[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
||||||
auto query = fmt::format(
|
std::string query = fmt::format(
|
||||||
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
|
"SELECT `exemption_id` FROM `ip_exemptions` WHERE `exemption_ip` = '{}'",
|
||||||
account_ip
|
account_ip
|
||||||
);
|
);
|
||||||
|
|
||||||
uint32 exemption_id = 0;
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (results.Success() && results.RowCount()) {
|
uint32 exemption_id = 0;
|
||||||
|
if (results.Success() && results.RowCount() > 0) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
exemption_id = std::stoul(row[0]);
|
exemption_id = atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
@@ -2149,14 +2292,13 @@ void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
|||||||
exemption_amount
|
exemption_amount
|
||||||
);
|
);
|
||||||
|
|
||||||
if (exemption_id) {
|
if (exemption_id != 0) {
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
"UPDATE `ip_exemptions` SET `exemption_amount` = {} WHERE `exemption_ip` = '{}'",
|
"UPDATE `ip_exemptions` SET `exemption_amount` = {} WHERE `exemption_ip` = '{}'",
|
||||||
exemption_amount,
|
exemption_amount,
|
||||||
account_ip
|
account_ip
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2179,9 +2321,9 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool Database::CopyCharacter(
|
bool Database::CopyCharacter(
|
||||||
const std::string& source_character_name,
|
std::string source_character_name,
|
||||||
const std::string& destination_character_name,
|
std::string destination_character_name,
|
||||||
const std::string& destination_account_name
|
std::string destination_account_name
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto results = QueryDatabase(
|
auto results = QueryDatabase(
|
||||||
@@ -2193,7 +2335,6 @@ bool Database::CopyCharacter(
|
|||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0) {
|
||||||
LogError("No character found with name [{}]", source_character_name);
|
LogError("No character found with name [{}]", source_character_name);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
@@ -2208,7 +2349,6 @@ bool Database::CopyCharacter(
|
|||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0) {
|
||||||
LogError("No account found with name [{}]", destination_account_name);
|
LogError("No account found with name [{}]", destination_account_name);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
row = results.begin();
|
row = results.begin();
|
||||||
@@ -2240,7 +2380,7 @@ bool Database::CopyCharacter(
|
|||||||
results = QueryDatabase(
|
results = QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"SELECT {} FROM {} WHERE {} = {}",
|
"SELECT {} FROM {} WHERE {} = {}",
|
||||||
Strings::Implode(",", Strings::Wrap(columns, "`")),
|
implode(",", wrap(columns, "`")),
|
||||||
table_name,
|
table_name,
|
||||||
character_id_column_name,
|
character_id_column_name,
|
||||||
source_character_id
|
source_character_id
|
||||||
@@ -2276,7 +2416,7 @@ bool Database::CopyCharacter(
|
|||||||
std::vector<std::string> insert_rows;
|
std::vector<std::string> insert_rows;
|
||||||
|
|
||||||
for (auto &r: new_rows) {
|
for (auto &r: new_rows) {
|
||||||
std::string insert_row = "(" + Strings::Implode(",", Strings::Wrap(r, "'")) + ")";
|
std::string insert_row = "(" + implode(",", wrap(r, "'")) + ")";
|
||||||
insert_rows.emplace_back(insert_row);
|
insert_rows.emplace_back(insert_row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2294,8 +2434,8 @@ bool Database::CopyCharacter(
|
|||||||
fmt::format(
|
fmt::format(
|
||||||
"INSERT INTO {} ({}) VALUES {}",
|
"INSERT INTO {} ({}) VALUES {}",
|
||||||
table_name,
|
table_name,
|
||||||
Strings::Implode(",", Strings::Wrap(columns, "`")),
|
implode(",", wrap(columns, "`")),
|
||||||
Strings::Implode(",", insert_rows)
|
implode(",", insert_rows)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2318,7 +2458,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
uri request_uri(url);
|
uri request_uri(url);
|
||||||
|
|
||||||
LogHTTP(
|
LogHTTP(
|
||||||
"parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
|
"[SourceDatabaseTableFromUrl] parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
|
||||||
url,
|
url,
|
||||||
request_uri.get_path(),
|
request_uri.get_path(),
|
||||||
request_uri.get_host(),
|
request_uri.get_host(),
|
||||||
@@ -2347,8 +2487,8 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
|
|
||||||
if (auto res = cli.Get(request_uri.get_path().c_str())) {
|
if (auto res = cli.Get(request_uri.get_path().c_str())) {
|
||||||
if (res->status == 200) {
|
if (res->status == 200) {
|
||||||
for (auto &s: Strings::Split(res->body, ';')) {
|
for (auto &s: SplitString(res->body, ';')) {
|
||||||
if (!Strings::Trim(s).empty()) {
|
if (!trim(s).empty()) {
|
||||||
auto results = QueryDatabase(s);
|
auto results = QueryDatabase(s);
|
||||||
if (!results.ErrorMessage().empty()) {
|
if (!results.ErrorMessage().empty()) {
|
||||||
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
|
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
|
||||||
@@ -2372,20 +2512,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch (std::invalid_argument iae) {
|
catch (std::invalid_argument iae) {
|
||||||
LogError("URI parser error [{}]", iae.what());
|
LogError("[SourceDatabaseTableFromUrl] URI parser error [{}]", iae.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
|
|
||||||
{
|
|
||||||
auto zones = ZoneRepository::GetWhere(
|
|
||||||
*this,
|
|
||||||
fmt::format(
|
|
||||||
"zoneidnumber = {} AND (version = {} OR version = 0) ORDER BY version DESC LIMIT 1",
|
|
||||||
zone_id,
|
|
||||||
instance_version
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return !zones.empty() ? zones[0].min_status : 0;
|
|
||||||
}
|
|
||||||
|
|||||||
+33
-27
@@ -88,6 +88,7 @@ public:
|
|||||||
|
|
||||||
/* Character Creation */
|
/* Character Creation */
|
||||||
|
|
||||||
|
bool AddToNameFilter(const char *name);
|
||||||
bool CreateCharacter(
|
bool CreateCharacter(
|
||||||
uint32 account_id,
|
uint32 account_id,
|
||||||
char *name,
|
char *name,
|
||||||
@@ -108,27 +109,30 @@ public:
|
|||||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||||
bool ReserveName(uint32 account_id, char *name);
|
bool ReserveName(uint32 account_id, char *name);
|
||||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||||
|
bool SetHackerFlag(const char *accountname, const char *charactername, const char *hacked);
|
||||||
|
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const char *hacked, const char *zone);
|
||||||
|
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
|
||||||
bool UpdateName(const char *oldname, const char *newname);
|
bool UpdateName(const char *oldname, const char *newname);
|
||||||
bool CopyCharacter(
|
bool CopyCharacter(
|
||||||
const std::string& source_character_name,
|
std::string source_character_name,
|
||||||
const std::string& destination_character_name,
|
std::string destination_character_name,
|
||||||
const std::string& destination_account_name
|
std::string destination_account_name
|
||||||
);
|
);
|
||||||
|
|
||||||
/* General Information Queries */
|
/* General Information Queries */
|
||||||
|
|
||||||
bool AddBannedIP(std::string banned_ip, std::string notes); //Add IP address to the banned_ips table.
|
bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the banned_ips table.
|
||||||
bool AddToNameFilter(std::string name);
|
bool AddGMIP(char* ip_address, char* name);
|
||||||
bool CheckBannedIPs(std::string login_ip); //Check incoming connection against banned IP table.
|
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
||||||
bool CheckGMIPs(std::string login_ip, uint32 account_id);
|
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||||
bool CheckNameFilter(std::string name, bool surname = false);
|
bool CheckNameFilter(const char* name, bool surname = false);
|
||||||
bool CheckUsedName(std::string name);
|
bool CheckUsedName(const char* name);
|
||||||
|
|
||||||
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0);
|
||||||
uint32 GetAccountIDByChar(uint32 char_id);
|
uint32 GetAccountIDByChar(uint32 char_id);
|
||||||
uint32 GetAccountIDByName(std::string account_name, std::string loginserver, int16* status = 0, uint32* lsid = 0);
|
uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
|
||||||
uint32 GetCharacterID(const char *name);
|
uint32 GetCharacterID(const char *name);
|
||||||
uint32 GetCharacterInfo(std::string character_name, uint32 *account_id, uint32 *zone_id, uint32 *instance_id);
|
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
|
||||||
uint32 GetGuildIDByCharID(uint32 char_id);
|
uint32 GetGuildIDByCharID(uint32 char_id);
|
||||||
uint32 GetGroupIDByCharID(uint32 char_id);
|
uint32 GetGroupIDByCharID(uint32 char_id);
|
||||||
uint32 GetRaidIDByCharID(uint32 char_id);
|
uint32 GetRaidIDByCharID(uint32 char_id);
|
||||||
@@ -138,34 +142,35 @@ public:
|
|||||||
std::string GetCharNameByID(uint32 char_id);
|
std::string GetCharNameByID(uint32 char_id);
|
||||||
std::string GetNPCNameByID(uint32 npc_id);
|
std::string GetNPCNameByID(uint32 npc_id);
|
||||||
std::string GetCleanNPCNameByID(uint32 npc_id);
|
std::string GetCleanNPCNameByID(uint32 npc_id);
|
||||||
void LoginIP(uint32 account_id, std::string login_ip);
|
void LoginIP(uint32 AccountID, const char* LoginIP);
|
||||||
|
|
||||||
/* Instancing */
|
/* Instancing */
|
||||||
|
|
||||||
bool AddClientToInstance(uint16 instance_id, uint32 character_id);
|
bool AddClientToInstance(uint16 instance_id, uint32 char_id);
|
||||||
bool CheckInstanceByCharID(uint16 instance_id, uint32 character_id);
|
bool CharacterInInstanceGroup(uint16 instance_id, uint32 char_id);
|
||||||
bool CheckInstanceExists(uint16 instance_id);
|
bool CheckInstanceExists(uint16 instance_id);
|
||||||
bool CheckInstanceExpired(uint16 instance_id);
|
bool CheckInstanceExpired(uint16 instance_id);
|
||||||
bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration);
|
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 GlobalInstance(uint16 instance_id);
|
||||||
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id);
|
||||||
bool RemoveClientsFromInstance(uint16 instance_id);
|
bool RemoveClientsFromInstance(uint16 instance_id);
|
||||||
bool VerifyInstanceAlive(uint16 instance_id, uint32 character_id);
|
bool VerifyInstanceAlive(uint16 instance_id, uint32 char_id);
|
||||||
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id);
|
||||||
|
|
||||||
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version);
|
||||||
std::vector<uint16> GetInstanceIDs(uint32 zone_id, uint32 character_id);
|
uint16 GetInstanceVersion(uint16 instance_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);
|
uint32 VersionFromInstanceID(uint16 instance_id);
|
||||||
|
uint32 ZoneIDFromInstanceID(uint16 instance_id);
|
||||||
|
|
||||||
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
void AssignGroupToInstance(uint32 gid, uint32 instance_id);
|
||||||
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
void AssignRaidToInstance(uint32 rid, uint32 instance_id);
|
||||||
|
void BuryCorpsesInInstance(uint16 instance_id);
|
||||||
void DeleteInstance(uint16 instance_id);
|
void DeleteInstance(uint16 instance_id);
|
||||||
void FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 charid, uint32 group_id);
|
void FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid);
|
||||||
void FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 charid, uint32 raid_id);
|
void FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid);
|
||||||
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids);
|
void GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list);
|
||||||
void PurgeExpiredInstances();
|
void PurgeExpiredInstances();
|
||||||
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
void SetInstanceDuration(uint16 instance_id, uint32 new_duration);
|
||||||
|
|
||||||
@@ -185,8 +190,6 @@ public:
|
|||||||
|
|
||||||
int16 CheckStatus(uint32 account_id);
|
int16 CheckStatus(uint32 account_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 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 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);
|
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
||||||
@@ -203,7 +206,7 @@ public:
|
|||||||
|
|
||||||
/* Groups */
|
/* Groups */
|
||||||
|
|
||||||
std::string GetGroupLeaderForLogin(std::string character_name);
|
char* GetGroupLeaderForLogin(const char* name,char* leaderbuf);
|
||||||
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);
|
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);
|
uint32 GetGroupID(const char* name);
|
||||||
@@ -242,11 +245,14 @@ public:
|
|||||||
|
|
||||||
/* General Queries */
|
/* General Queries */
|
||||||
|
|
||||||
|
bool GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, float* safe_heading = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr);
|
||||||
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 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 GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0);
|
||||||
bool LoadPTimers(uint32 charid, PTimerList &into);
|
bool LoadPTimers(uint32 charid, PTimerList &into);
|
||||||
|
|
||||||
uint8 GetPEQZone(uint32 zone_id, uint32 version);
|
uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version);
|
||||||
uint8 GetMinStatus(uint32 zone_id, uint32 instance_version);
|
|
||||||
|
uint8 GetPEQZone(uint32 zoneID, uint32 version);
|
||||||
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
uint8 GetRaceSkill(uint8 skillid, uint8 in_race);
|
||||||
uint8 GetServerType();
|
uint8 GetServerType();
|
||||||
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level);
|
||||||
|
|||||||
@@ -23,11 +23,10 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include "database_dump_service.h"
|
#include "database_dump_service.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../strings.h"
|
#include "../string_util.h"
|
||||||
#include "../eqemu_config.h"
|
#include "../eqemu_config.h"
|
||||||
#include "../database_schema.h"
|
#include "../database_schema.h"
|
||||||
#include "../file.h"
|
#include "../file_util.h"
|
||||||
#include "../process/process.h"
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
@@ -41,6 +40,38 @@
|
|||||||
|
|
||||||
#define DATABASE_DUMP_PATH "backups/"
|
#define DATABASE_DUMP_PATH "backups/"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cmd
|
||||||
|
* @param return_result
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string DatabaseDumpService::execute(const std::string &cmd, bool return_result = true)
|
||||||
|
{
|
||||||
|
const char *file_name = "db-exec-result.txt";
|
||||||
|
|
||||||
|
if (return_result) {
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
std::system((cmd + " > " + file_name + " 2>&1").c_str());
|
||||||
|
#else
|
||||||
|
std::system((cmd + " > " + file_name).c_str());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::system((cmd).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
if (return_result) {
|
||||||
|
std::ifstream file(file_name);
|
||||||
|
result = {std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
|
||||||
|
std::remove(file_name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -57,7 +88,7 @@ bool DatabaseDumpService::IsMySQLInstalled()
|
|||||||
*/
|
*/
|
||||||
bool DatabaseDumpService::IsTarAvailable()
|
bool DatabaseDumpService::IsTarAvailable()
|
||||||
{
|
{
|
||||||
std::string version_output = Process::execute("tar --version");
|
std::string version_output = execute("tar --version");
|
||||||
|
|
||||||
return version_output.find("GNU tar") != std::string::npos;
|
return version_output.find("GNU tar") != std::string::npos;
|
||||||
}
|
}
|
||||||
@@ -68,7 +99,7 @@ bool DatabaseDumpService::IsTarAvailable()
|
|||||||
*/
|
*/
|
||||||
bool DatabaseDumpService::Is7ZipAvailable()
|
bool DatabaseDumpService::Is7ZipAvailable()
|
||||||
{
|
{
|
||||||
std::string version_output = Process::execute("7z --help");
|
std::string version_output = execute("7z --help");
|
||||||
|
|
||||||
return version_output.find("7-Zip") != std::string::npos;
|
return version_output.find("7-Zip") != std::string::npos;
|
||||||
}
|
}
|
||||||
@@ -86,9 +117,9 @@ bool DatabaseDumpService::HasCompressionBinary()
|
|||||||
*/
|
*/
|
||||||
std::string DatabaseDumpService::GetMySQLVersion()
|
std::string DatabaseDumpService::GetMySQLVersion()
|
||||||
{
|
{
|
||||||
std::string version_output = Process::execute("mysql --version");
|
std::string version_output = execute("mysql --version");
|
||||||
|
|
||||||
return Strings::Trim(version_output);
|
return trim(version_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,53 +149,95 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetPlayerTablesList()
|
std::string DatabaseDumpService::GetPlayerTablesList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetPlayerTables(), " ");
|
std::string tables_list;
|
||||||
}
|
std::vector<std::string> tables = DatabaseSchema::GetPlayerTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
std::string DatabaseDumpService::GetBotTablesList()
|
tables_list += table + " ";
|
||||||
{
|
}
|
||||||
return Strings::Join(DatabaseSchema::GetBotTables(), " ");
|
|
||||||
}
|
return trim(tables_list);
|
||||||
|
|
||||||
std::string DatabaseDumpService::GetMercTablesList()
|
|
||||||
{
|
|
||||||
return Strings::Join(DatabaseSchema::GetMercTables(), " ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetLoginTableList()
|
std::string DatabaseDumpService::GetLoginTableList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetLoginTables(), " ");
|
std::string tables_list;
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetLoginTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetQueryServTables()
|
std::string DatabaseDumpService::GetQueryServTables()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetQueryServerTables(), " ");
|
std::string tables_list;
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetQueryServerTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetSystemTablesList()
|
std::string DatabaseDumpService::GetSystemTablesList()
|
||||||
{
|
{
|
||||||
auto system_tables = DatabaseSchema::GetServerTables();
|
std::string tables_list;
|
||||||
auto version_tables = DatabaseSchema::GetVersionTables();
|
|
||||||
|
|
||||||
system_tables.insert(
|
std::vector<std::string> tables = DatabaseSchema::GetServerTables();
|
||||||
std::end(system_tables),
|
for (const auto &table : tables) {
|
||||||
std::begin(version_tables),
|
tables_list += table + " ";
|
||||||
std::end(version_tables)
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return Strings::Join(system_tables, " ");
|
tables = DatabaseSchema::GetVersionTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetStateTablesList()
|
std::string DatabaseDumpService::GetStateTablesList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetStateTables(), " ");
|
std::string tables_list;
|
||||||
|
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetStateTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
std::string DatabaseDumpService::GetContentTablesList()
|
std::string DatabaseDumpService::GetContentTablesList()
|
||||||
{
|
{
|
||||||
return Strings::Join(DatabaseSchema::GetContentTables(), " ");
|
std::string tables_list;
|
||||||
|
|
||||||
|
std::vector<std::string> tables = DatabaseSchema::GetContentTables();
|
||||||
|
for (const auto &table : tables) {
|
||||||
|
tables_list += table + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(tables_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -245,16 +318,6 @@ void DatabaseDumpService::Dump()
|
|||||||
dump_descriptor += "-player";
|
dump_descriptor += "-player";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDumpBotTables()) {
|
|
||||||
tables_to_dump += GetBotTablesList() + " ";
|
|
||||||
dump_descriptor += "-bots";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpMercTables()) {
|
|
||||||
tables_to_dump += GetMercTablesList() + " ";
|
|
||||||
dump_descriptor += "-mercs";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpSystemTables()) {
|
if (IsDumpSystemTables()) {
|
||||||
tables_to_dump += GetSystemTablesList() + " ";
|
tables_to_dump += GetSystemTablesList() + " ";
|
||||||
dump_descriptor += "-system";
|
dump_descriptor += "-system";
|
||||||
@@ -301,12 +364,12 @@ void DatabaseDumpService::Dump()
|
|||||||
pipe_file
|
pipe_file
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
if (!FileUtil::exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||||
File::Makedir(GetSetDumpPath());
|
FileUtil::mkdir(GetSetDumpPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDumpDropTableSyntaxOnly()) {
|
if (IsDumpDropTableSyntaxOnly()) {
|
||||||
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
|
std::vector<std::string> tables = SplitString(tables_to_dump, ' ');
|
||||||
|
|
||||||
for (auto &table : tables) {
|
for (auto &table : tables) {
|
||||||
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
|
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
|
||||||
@@ -317,14 +380,14 @@ void DatabaseDumpService::Dump()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::string execution_result = Process::execute(execute_command);
|
std::string execution_result = execute(execute_command, IsDumpOutputToConsole());
|
||||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
if (!execution_result.empty()) {
|
||||||
std::cout << execution_result;
|
std::cout << execution_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tables_to_dump.empty()) {
|
if (!tables_to_dump.empty()) {
|
||||||
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
|
LogInfo("Dumping Tables [{}]", tables_to_dump);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||||
@@ -334,7 +397,7 @@ void DatabaseDumpService::Dump()
|
|||||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsTarAvailable()) {
|
if (IsTarAvailable()) {
|
||||||
Process::execute(
|
execute(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
||||||
GetDumpFileNameWithPath(),
|
GetDumpFileNameWithPath(),
|
||||||
@@ -345,7 +408,7 @@ void DatabaseDumpService::Dump()
|
|||||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
||||||
}
|
}
|
||||||
else if (Is7ZipAvailable()) {
|
else if (Is7ZipAvailable()) {
|
||||||
Process::execute(
|
execute(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"7z a -t7z {}.zip {}.sql",
|
"7z a -t7z {}.zip {}.sql",
|
||||||
GetDumpFileNameWithPath(),
|
GetDumpFileNameWithPath(),
|
||||||
@@ -373,7 +436,6 @@ void DatabaseDumpService::Dump()
|
|||||||
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
||||||
// LogDebug("[{}] bot", (IsDumpBotTables() ? "true" : "false"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpSystemTables() const
|
bool DatabaseDumpService::IsDumpSystemTables() const
|
||||||
@@ -515,23 +577,3 @@ void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
|
|||||||
{
|
{
|
||||||
DatabaseDumpService::dump_state_tables = dump_state_tables;
|
DatabaseDumpService::dump_state_tables = dump_state_tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpBotTables() const
|
|
||||||
{
|
|
||||||
return dump_bot_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpBotTables(bool dump_bot_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_bot_tables = dump_bot_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpMercTables() const
|
|
||||||
{
|
|
||||||
return dump_merc_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -53,10 +53,6 @@ public:
|
|||||||
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
||||||
bool IsDumpStateTables() const;
|
bool IsDumpStateTables() const;
|
||||||
void SetDumpStateTables(bool dump_state_tables);
|
void SetDumpStateTables(bool dump_state_tables);
|
||||||
bool IsDumpBotTables() const;
|
|
||||||
void SetDumpBotTables(bool dump_bot_tables);
|
|
||||||
bool IsDumpMercTables() const;
|
|
||||||
void SetDumpMercTables(bool dump_bot_tables);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool dump_all_tables = false;
|
bool dump_all_tables = false;
|
||||||
@@ -71,17 +67,14 @@ private:
|
|||||||
bool dump_with_compression = false;
|
bool dump_with_compression = false;
|
||||||
bool dump_output_to_console = false;
|
bool dump_output_to_console = false;
|
||||||
bool dump_drop_table_syntax_only = false;
|
bool dump_drop_table_syntax_only = false;
|
||||||
bool dump_bot_tables = false;
|
|
||||||
bool dump_merc_tables = false;
|
|
||||||
std::string dump_path;
|
std::string dump_path;
|
||||||
std::string dump_file_name;
|
std::string dump_file_name;
|
||||||
|
|
||||||
|
std::string execute(const std::string &cmd, bool return_result);
|
||||||
bool IsMySQLInstalled();
|
bool IsMySQLInstalled();
|
||||||
std::string GetMySQLVersion();
|
std::string GetMySQLVersion();
|
||||||
std::string GetBaseMySQLDumpCommand();
|
std::string GetBaseMySQLDumpCommand();
|
||||||
std::string GetPlayerTablesList();
|
std::string GetPlayerTablesList();
|
||||||
std::string GetBotTablesList();
|
|
||||||
std::string GetMercTablesList();
|
|
||||||
std::string GetSystemTablesList();
|
std::string GetSystemTablesList();
|
||||||
std::string GetStateTablesList();
|
std::string GetStateTablesList();
|
||||||
std::string GetContentTablesList();
|
std::string GetContentTablesList();
|
||||||
|
|||||||
@@ -18,12 +18,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "extprofile.h"
|
#include "extprofile.h"
|
||||||
#include "path_manager.h"
|
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -476,17 +475,8 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
CheckDatabaseConvertPPDeblob();
|
CheckDatabaseConvertPPDeblob();
|
||||||
CheckDatabaseConvertCorpseDeblob();
|
CheckDatabaseConvertCorpseDeblob();
|
||||||
|
|
||||||
auto *r = RuleManager::Instance();
|
|
||||||
r->LoadRules(this, "default", false);
|
|
||||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
|
||||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
|
||||||
r->SetRule("Bots:Enabled", "true", this, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run EQEmu Server script (Checks for database updates) */
|
/* Run EQEmu Server script (Checks for database updates) */
|
||||||
|
if(system("perl eqemu_server.pl ran_from_world"));
|
||||||
const std::string file = fmt::format("{}/eqemu_server.pl", path.GetServerPath());
|
|
||||||
system(fmt::format("perl {} ran_from_world", file).c_str());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -971,7 +961,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
|||||||
std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)"
|
std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)"
|
||||||
"VALUES (%u, '%s')",
|
"VALUES (%u, '%s')",
|
||||||
character_id,
|
character_id,
|
||||||
Strings::Escape(inspectmessage).c_str()
|
EscapeString(inspectmessage).c_str()
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(rquery);
|
auto results = QueryDatabase(rquery);
|
||||||
}
|
}
|
||||||
@@ -1208,8 +1198,8 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
|||||||
")",
|
")",
|
||||||
character_id,
|
character_id,
|
||||||
account_id,
|
account_id,
|
||||||
Strings::Escape(pp->name).c_str(),
|
EscapeString(pp->name).c_str(),
|
||||||
Strings::Escape(pp->last_name).c_str(),
|
EscapeString(pp->last_name).c_str(),
|
||||||
pp->gender,
|
pp->gender,
|
||||||
pp->race,
|
pp->race,
|
||||||
pp->class_,
|
pp->class_,
|
||||||
@@ -1233,8 +1223,8 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
|||||||
pp->ability_number,
|
pp->ability_number,
|
||||||
pp->ability_time_minutes,
|
pp->ability_time_minutes,
|
||||||
pp->ability_time_hours,
|
pp->ability_time_hours,
|
||||||
Strings::Escape(pp->title).c_str(),
|
EscapeString(pp->title).c_str(),
|
||||||
Strings::Escape(pp->suffix).c_str(),
|
EscapeString(pp->suffix).c_str(),
|
||||||
pp->exp,
|
pp->exp,
|
||||||
pp->points,
|
pp->points,
|
||||||
pp->mana,
|
pp->mana,
|
||||||
@@ -1462,7 +1452,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
|||||||
for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){
|
for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){
|
||||||
if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){
|
if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){
|
||||||
if (first_entry != 1){
|
if (first_entry != 1){
|
||||||
rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
||||||
first_entry = 1;
|
first_entry = 1;
|
||||||
}
|
}
|
||||||
rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]);
|
||||||
|
|||||||
+307
-246
@@ -18,18 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
#include "../common/repositories/character_corpses_repository.h"
|
|
||||||
#include "../common/repositories/dynamic_zone_members_repository.h"
|
#include "../common/repositories/dynamic_zone_members_repository.h"
|
||||||
#include "../common/repositories/dynamic_zones_repository.h"
|
#include "../common/repositories/dynamic_zones_repository.h"
|
||||||
#include "../common/repositories/group_id_repository.h"
|
|
||||||
#include "../common/repositories/instance_list_repository.h"
|
|
||||||
#include "../common/repositories/instance_list_player_repository.h"
|
|
||||||
#include "../common/repositories/raid_members_repository.h"
|
|
||||||
#include "../common/repositories/respawn_times_repository.h"
|
|
||||||
#include "../common/repositories/spawn_condition_values_repository.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
@@ -49,83 +41,115 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool Database::AddClientToInstance(uint16 instance_id, uint32 character_id)
|
/**
|
||||||
|
* @param instance_id
|
||||||
|
* @param char_id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id)
|
||||||
{
|
{
|
||||||
auto e = InstanceListPlayerRepository::NewEntity();
|
std::string query = StringFormat(
|
||||||
|
"REPLACE INTO `instance_list_player` (id, charid) "
|
||||||
|
"VALUES "
|
||||||
|
"(%lu, %lu)",
|
||||||
|
(unsigned long) instance_id,
|
||||||
|
(unsigned long) char_id
|
||||||
|
);
|
||||||
|
|
||||||
e.id = instance_id;
|
auto results = QueryDatabase(query);
|
||||||
e.charid = character_id;
|
|
||||||
|
|
||||||
return InstanceListPlayerRepository::ReplaceOne(*this, e);
|
return results.Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckInstanceByCharID(uint16 instance_id, uint32 character_id)
|
bool Database::CharacterInInstanceGroup(uint16 instance_id, uint32 char_id)
|
||||||
{
|
{
|
||||||
if (!instance_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto l = InstanceListPlayerRepository::GetWhere(
|
std::string query = StringFormat("SELECT charid FROM instance_list_player where id=%u AND charid=%u", instance_id, char_id);
|
||||||
*this,
|
auto results = QueryDatabase(query);
|
||||||
fmt::format(
|
|
||||||
"id = {} AND charid = {}",
|
if (!results.Success())
|
||||||
instance_id,
|
return false;
|
||||||
character_id
|
|
||||||
)
|
if (results.RowCount() != 1)
|
||||||
);
|
|
||||||
if (l.empty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckInstanceExists(uint16 instance_id)
|
bool Database::CheckInstanceExists(uint16 instance_id) {
|
||||||
{
|
std::string query = StringFormat(
|
||||||
if (!instance_id) {
|
"SELECT "
|
||||||
return false;
|
"`id` "
|
||||||
}
|
"FROM "
|
||||||
|
"`instance_list` "
|
||||||
|
"WHERE "
|
||||||
|
"`id` = %u",
|
||||||
|
instance_id
|
||||||
|
);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
if (!results.Success())
|
||||||
if (!i.id) {
|
return false;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckInstanceExpired(uint16 instance_id)
|
bool Database::CheckInstanceExpired(uint16 instance_id)
|
||||||
{
|
{
|
||||||
if (!instance_id) {
|
|
||||||
|
int32 start_time = 0;
|
||||||
|
int32 duration = 0;
|
||||||
|
uint32 never_expires = 0;
|
||||||
|
|
||||||
|
std::string query = StringFormat(
|
||||||
|
"SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u",
|
||||||
|
instance_id
|
||||||
|
);
|
||||||
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
if (results.RowCount() == 0) {
|
||||||
if (!i.id) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i.never_expires) {
|
auto row = results.begin();
|
||||||
|
|
||||||
|
start_time = atoi(row[0]);
|
||||||
|
duration = atoi(row[1]);
|
||||||
|
never_expires = atoi(row[2]);
|
||||||
|
|
||||||
|
if (never_expires == 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeval tv{};
|
timeval tv{};
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
|
|
||||||
return (i.start_time + i.duration) <= tv.tv_sec;
|
return (start_time + duration) <= tv.tv_sec;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration)
|
||||||
{
|
{
|
||||||
auto e = InstanceListRepository::NewEntity();
|
std::string query = StringFormat(
|
||||||
|
"INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||||
|
" values (%u, %u, %u, UNIX_TIMESTAMP(), %u)",
|
||||||
|
instance_id,
|
||||||
|
zone_id,
|
||||||
|
version,
|
||||||
|
duration
|
||||||
|
);
|
||||||
|
|
||||||
e.id = instance_id;
|
auto results = QueryDatabase(query);
|
||||||
e.zone = zone_id;
|
|
||||||
e.version = version;
|
|
||||||
e.start_time = std::time(nullptr);
|
|
||||||
e.duration = duration;
|
|
||||||
|
|
||||||
return InstanceListRepository::InsertOne(*this, e).id;
|
return results.Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||||
@@ -133,8 +157,8 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||||
uint32 max = 32000;
|
uint32 max = 32000;
|
||||||
|
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat(
|
||||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
"SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u",
|
||||||
max_reserved_instance_id,
|
max_reserved_instance_id,
|
||||||
max_reserved_instance_id
|
max_reserved_instance_id
|
||||||
);
|
);
|
||||||
@@ -178,7 +202,7 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", max_reserved_instance_id);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -192,9 +216,8 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
max_reserved_instance_id++;
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
for (auto row : results) {
|
if (max_reserved_instance_id < atoi(row[0])) {
|
||||||
if (max_reserved_instance_id < std::stoul(row[0])) {
|
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = max_reserved_instance_id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -212,45 +235,57 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
bool Database::GlobalInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
if (!instance_id) {
|
std::string query = StringFormat(
|
||||||
return false;
|
"SELECT "
|
||||||
}
|
"is_global "
|
||||||
|
"FROM "
|
||||||
|
"instance_list "
|
||||||
|
"WHERE "
|
||||||
|
"id = %u "
|
||||||
|
"LIMIT 1 ",
|
||||||
|
instance_id
|
||||||
|
);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
if (!results.Success())
|
||||||
if (!i.id) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return i.is_global;
|
if (results.RowCount() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return (atoi(row[0]) == 1) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id)
|
bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id)
|
||||||
{
|
{
|
||||||
return InstanceListPlayerRepository::DeleteWhere(
|
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu",
|
||||||
*this,
|
(unsigned long)instance_id, (unsigned long)char_id);
|
||||||
fmt::format(
|
auto results = QueryDatabase(query);
|
||||||
"id = {} AND charid = {}",
|
|
||||||
instance_id,
|
return results.Success();
|
||||||
char_id
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Database::RemoveClientsFromInstance(uint16 instance_id)
|
bool Database::RemoveClientsFromInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
return InstanceListPlayerRepository::DeleteOne(*this, instance_id);
|
std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu", (unsigned long)instance_id);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
return results.Success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
|
bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 char_id)
|
||||||
{
|
{
|
||||||
//we are not saved to this instance so set our instance to 0
|
//we are not saved to this instance so set our instance to 0
|
||||||
if (!IsGlobalInstance(instance_id) && !CheckInstanceByCharID(instance_id, character_id)) {
|
if (!GlobalInstance(instance_id) && !CharacterInInstanceGroup(instance_id, char_id))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (CheckInstanceExpired(instance_id)) {
|
if (CheckInstanceExpired(instance_id))
|
||||||
|
{
|
||||||
DeleteInstance(instance_id);
|
DeleteInstance(instance_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -260,102 +295,99 @@ bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 character_id)
|
|||||||
|
|
||||||
bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id)
|
bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id)
|
||||||
{
|
{
|
||||||
auto l = InstanceListRepository::GetWhere(
|
|
||||||
*this,
|
std::string query = StringFormat("SELECT id FROM instance_list where id=%u AND zone=%u", instance_id, zone_id);
|
||||||
fmt::format(
|
auto results = QueryDatabase(query);
|
||||||
"id = {} AND zone = {}",
|
|
||||||
instance_id,
|
if (!results.Success())
|
||||||
zone_id
|
return false;
|
||||||
)
|
|
||||||
);
|
if (results.RowCount() == 0)
|
||||||
if (l.empty()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 version)
|
uint16 Database::GetInstanceID(uint32 zone, uint32 character_id, int16 version)
|
||||||
{
|
{
|
||||||
if (!zone_id) {
|
if (!zone)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
const auto query = fmt::format(
|
std::string query = StringFormat(
|
||||||
"SELECT instance_list.id FROM "
|
"SELECT "
|
||||||
"instance_list, instance_list_player WHERE "
|
"instance_list.id "
|
||||||
"instance_list.zone = {} AND "
|
"FROM "
|
||||||
"instance_list.version = {} AND "
|
"instance_list, "
|
||||||
"instance_list.id = instance_list_player.id AND "
|
"instance_list_player "
|
||||||
"instance_list_player.charid = {} "
|
"WHERE "
|
||||||
"LIMIT 1;",
|
"instance_list.zone = %u "
|
||||||
zone_id,
|
"AND instance_list.version = %u "
|
||||||
|
"AND instance_list.id = instance_list_player.id "
|
||||||
|
"AND instance_list_player.charid = %u "
|
||||||
|
"LIMIT 1; ",
|
||||||
|
zone,
|
||||||
version,
|
version,
|
||||||
character_id
|
character_id
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return atoi(row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Database::GetInstanceVersion(uint16 instance_id) {
|
||||||
|
if (instance_id == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
return atoi(row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
||||||
|
{
|
||||||
|
uint32 start_time = 0;
|
||||||
|
uint32 duration = 0;
|
||||||
|
uint32 never_expires = 0;
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
|
is_perma = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
{
|
||||||
|
is_perma = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return static_cast<uint16>(std::stoul(row[0]));
|
start_time = atoi(row[0]);
|
||||||
}
|
duration = atoi(row[1]);
|
||||||
|
never_expires = atoi(row[2]);
|
||||||
|
|
||||||
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
|
if (never_expires == 1)
|
||||||
{
|
{
|
||||||
std::vector<uint16> l;
|
|
||||||
|
|
||||||
if (!zone_id) {
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto query = fmt::format(
|
|
||||||
"SELECT instance_list.id FROM "
|
|
||||||
"instance_list, instance_list_player WHERE "
|
|
||||||
"instance_list.zone = {} AND "
|
|
||||||
"instance_list.id = instance_list_player.id AND "
|
|
||||||
"instance_list_player.charid = {}",
|
|
||||||
zone_id,
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row : results) {
|
|
||||||
l.push_back(static_cast<uint16>(std::stoul(row[0])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Database::GetInstanceVersion(uint16 instance_id) {
|
|
||||||
if (!instance_id) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
|
||||||
if (!i.id) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
|
||||||
{
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
|
||||||
if (!i.id) {
|
|
||||||
is_perma = false;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i.never_expires) {
|
|
||||||
is_perma = true;
|
is_perma = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -364,175 +396,204 @@ uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma)
|
|||||||
|
|
||||||
timeval tv;
|
timeval tv;
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
return ((i.start_time + i.duration) - tv.tv_sec);
|
return ((start_time + duration) - tv.tv_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetInstanceZoneID(uint16 instance_id)
|
uint32 Database::VersionFromInstanceID(uint16 instance_id)
|
||||||
{
|
{
|
||||||
if (!instance_id) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id);
|
||||||
if (!i.id) {
|
auto results = QueryDatabase(query);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i.zone;
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return atoi(row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Database::ZoneIDFromInstanceID(uint16 instance_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT zone FROM instance_list where id=%u", instance_id);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id)
|
||||||
{
|
{
|
||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
|
||||||
auto version = GetInstanceVersion(instance_id);
|
|
||||||
|
|
||||||
auto l = GroupIdRepository::GetWhere(
|
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
|
||||||
*this,
|
uint16 version = VersionFromInstanceID(instance_id);
|
||||||
fmt::format(
|
|
||||||
"groupid = {}",
|
std::string query = StringFormat("SELECT `charid` FROM `group_id` WHERE `groupid` = %u", group_id);
|
||||||
group_id
|
auto results = QueryDatabase(query);
|
||||||
)
|
|
||||||
);
|
if (!results.Success())
|
||||||
if (l.empty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& e : l) {
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
{
|
||||||
AddClientToInstance(instance_id, e.charid);
|
uint32 charid = atoi(row[0]);
|
||||||
}
|
if (GetInstanceID(zone_id, charid, version) == 0)
|
||||||
|
AddClientToInstance(instance_id, charid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
||||||
{
|
{
|
||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
|
||||||
auto version = GetInstanceVersion(instance_id);
|
|
||||||
|
|
||||||
auto l = RaidMembersRepository::GetWhere(
|
uint32 zone_id = ZoneIDFromInstanceID(instance_id);
|
||||||
*this,
|
uint16 version = VersionFromInstanceID(instance_id);
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT `charid` FROM `raid_members` WHERE `raidid` = %u", raid_id);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
{
|
||||||
|
uint32 charid = atoi(row[0]);
|
||||||
|
if (GetInstanceID(zone_id, charid, version) == 0)
|
||||||
|
AddClientToInstance(instance_id, charid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::BuryCorpsesInInstance(uint16 instance_id) {
|
||||||
|
QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"raidid = {}",
|
"UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id = {}",
|
||||||
raid_id
|
instance_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (l.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& e : l) {
|
|
||||||
if (!GetInstanceID(zone_id, e.charid, version)) {
|
|
||||||
AddClientToInstance(instance_id, e.charid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::DeleteInstance(uint16 instance_id)
|
void Database::DeleteInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
std::string query;
|
std::string query;
|
||||||
|
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id);
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
query = StringFormat("DELETE FROM respawn_times WHERE instance_id=%u", instance_id);
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id);
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
DynamicZoneMembersRepository::DeleteByInstance(*this, instance_id);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||||
|
|
||||||
CharacterCorpsesRepository::BuryInstance(*this, instance_id);
|
BuryCorpsesInInstance(instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::FlagInstanceByGroupLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 group_id)
|
void Database::FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid)
|
||||||
{
|
{
|
||||||
auto instance_id = GetInstanceID(zone_id, character_id, version);
|
uint16 id = GetInstanceID(zone, charid, version);
|
||||||
if (instance_id) {
|
if (id != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
char ln[128];
|
char ln[128];
|
||||||
memset(ln, 0, 128);
|
memset(ln, 0, 128);
|
||||||
GetGroupLeadershipInfo(group_id, ln);
|
GetGroupLeadershipInfo(gid, ln);
|
||||||
|
uint32 l_charid = GetCharacterID((const char*)ln);
|
||||||
|
uint16 l_id = GetInstanceID(zone, l_charid, version);
|
||||||
|
|
||||||
auto group_leader_id = GetCharacterID((const char*)ln);
|
if (l_id == 0)
|
||||||
auto group_leader_instance_id = GetInstanceID(zone_id, group_leader_id, version);
|
|
||||||
|
|
||||||
if (!group_leader_instance_id) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
AddClientToInstance(group_leader_instance_id, character_id);
|
AddClientToInstance(l_id, charid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::FlagInstanceByRaidLeader(uint32 zone_id, int16 version, uint32 character_id, uint32 raid_id)
|
void Database::FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid)
|
||||||
{
|
{
|
||||||
uint16 instance_id = GetInstanceID(zone_id, character_id, version);
|
uint16 id = GetInstanceID(zone, charid, version);
|
||||||
if (instance_id) {
|
if (id != 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
auto raid_leader_id = GetCharacterID(GetRaidLeaderName(raid_id));
|
uint32 l_charid = GetCharacterID(GetRaidLeaderName(rid));
|
||||||
auto raid_leader_instance_id = GetInstanceID(zone_id, raid_leader_id, version);
|
uint16 l_id = GetInstanceID(zone, l_charid, version);
|
||||||
|
|
||||||
if (!raid_leader_instance_id) {
|
if (l_id == 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
AddClientToInstance(raid_leader_instance_id, character_id);
|
AddClientToInstance(l_id, charid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &character_ids)
|
void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &charid_list) {
|
||||||
{
|
|
||||||
auto l = InstanceListPlayerRepository::GetWhere(*this, fmt::format("id = {}", instance_id));
|
|
||||||
if (l.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& e : l) {
|
std::string query = StringFormat("SELECT `charid` FROM `instance_list_player` WHERE `id` = %u", instance_id);
|
||||||
character_ids.push_back(e.charid);
|
auto results = QueryDatabase(query);
|
||||||
}
|
|
||||||
|
if (!results.Success())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
charid_list.push_back(atoi(row[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::PurgeExpiredInstances()
|
void Database::PurgeExpiredInstances()
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delay purging by a day so that we can continue using adjacent free instance id's
|
* Delay purging by a day so that we can continue using adjacent free instance id's
|
||||||
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
* from the table without risking the chance we immediately re-allocate a zone that freshly expired but
|
||||||
* has not been fully de-allocated
|
* has not been fully de-allocated
|
||||||
*/
|
*/
|
||||||
auto l = InstanceListRepository::GetWhere(
|
std::string query =
|
||||||
*this,
|
SQL(
|
||||||
"(start_time + duration) <= (UNIX_TIMESTAMP() - 86400) AND never_expires = 0"
|
SELECT
|
||||||
|
id
|
||||||
|
FROM
|
||||||
|
instance_list
|
||||||
|
where
|
||||||
|
(start_time + duration) <= (UNIX_TIMESTAMP() - 86400)
|
||||||
|
and never_expires = 0
|
||||||
);
|
);
|
||||||
if (l.empty()) {
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> instance_ids;
|
std::vector<std::string> instance_ids;
|
||||||
for (const auto& e : l) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
instance_ids.emplace_back(std::to_string(e.id));
|
instance_ids.emplace_back(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto imploded_instance_ids = Strings::Implode(",", instance_ids);
|
std::string imploded_instance_ids = implode(",", instance_ids);
|
||||||
|
|
||||||
InstanceListRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM instance_list WHERE id IN ({})", imploded_instance_ids));
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM instance_list_player WHERE id IN ({})", imploded_instance_ids));
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM respawn_times WHERE instance_id IN ({})", imploded_instance_ids));
|
||||||
SpawnConditionValuesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
QueryDatabase(fmt::format("DELETE FROM spawn_condition_values WHERE instance_id IN ({})", imploded_instance_ids));
|
||||||
CharacterCorpsesRepository::BuryInstances(*this, imploded_instance_ids);
|
QueryDatabase(fmt::format("UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", imploded_instance_ids));
|
||||||
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
DynamicZoneMembersRepository::DeleteByManyInstances(*this, imploded_instance_ids);
|
||||||
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
DynamicZonesRepository::DeleteWhere(*this, fmt::format("instance_id IN ({})", imploded_instance_ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||||
{
|
{
|
||||||
auto i = InstanceListRepository::FindOne(*this, instance_id);
|
std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), "
|
||||||
if (!i.id) {
|
"duration=%u WHERE id=%u", new_duration, instance_id);
|
||||||
return;
|
auto results = QueryDatabase(query);
|
||||||
}
|
|
||||||
|
|
||||||
i.start_time = std::time(nullptr);
|
|
||||||
i.duration = new_duration;
|
|
||||||
|
|
||||||
InstanceListRepository::UpdateOne(*this, i);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ namespace DatabaseSchema {
|
|||||||
{"character_pet_buffs", "char_id"},
|
{"character_pet_buffs", "char_id"},
|
||||||
{"character_pet_info", "char_id"},
|
{"character_pet_info", "char_id"},
|
||||||
{"character_pet_inventory", "char_id"},
|
{"character_pet_inventory", "char_id"},
|
||||||
{"character_peqzone_flags", "id"},
|
|
||||||
{"character_potionbelt", "id"},
|
{"character_potionbelt", "id"},
|
||||||
{"character_skills", "id"},
|
{"character_skills", "id"},
|
||||||
{"character_spells", "id"},
|
{"character_spells", "id"},
|
||||||
@@ -83,6 +82,7 @@ namespace DatabaseSchema {
|
|||||||
{"player_titlesets", "char_id"},
|
{"player_titlesets", "char_id"},
|
||||||
{"quest_globals", "charid"},
|
{"quest_globals", "charid"},
|
||||||
{"timers", "char_id"},
|
{"timers", "char_id"},
|
||||||
|
{"titles", "char_id"},
|
||||||
{"trader", "char_id"},
|
{"trader", "char_id"},
|
||||||
{"zone_flags", "charID"}
|
{"zone_flags", "charID"}
|
||||||
};
|
};
|
||||||
@@ -130,7 +130,6 @@ namespace DatabaseSchema {
|
|||||||
"character_pet_buffs",
|
"character_pet_buffs",
|
||||||
"character_pet_info",
|
"character_pet_info",
|
||||||
"character_pet_inventory",
|
"character_pet_inventory",
|
||||||
"character_peqzone_flags",
|
|
||||||
"character_potionbelt",
|
"character_potionbelt",
|
||||||
"character_skills",
|
"character_skills",
|
||||||
"character_spells",
|
"character_spells",
|
||||||
@@ -159,6 +158,7 @@ namespace DatabaseSchema {
|
|||||||
"spell_buckets",
|
"spell_buckets",
|
||||||
"spell_globals",
|
"spell_globals",
|
||||||
"timers",
|
"timers",
|
||||||
|
"titles",
|
||||||
"trader",
|
"trader",
|
||||||
"trader_audit",
|
"trader_audit",
|
||||||
"zone_flags"
|
"zone_flags"
|
||||||
@@ -189,14 +189,13 @@ namespace DatabaseSchema {
|
|||||||
"char_create_point_allocations",
|
"char_create_point_allocations",
|
||||||
"damageshieldtypes",
|
"damageshieldtypes",
|
||||||
"doors",
|
"doors",
|
||||||
"dynamic_zone_templates",
|
|
||||||
"faction_association",
|
|
||||||
"faction_base_data",
|
"faction_base_data",
|
||||||
"faction_list",
|
"faction_list",
|
||||||
"faction_list_mod",
|
"faction_list_mod",
|
||||||
"fishing",
|
"fishing",
|
||||||
"forage",
|
"forage",
|
||||||
"global_loot",
|
"global_loot",
|
||||||
|
"goallists",
|
||||||
"graveyard",
|
"graveyard",
|
||||||
"grid",
|
"grid",
|
||||||
"grid_entries",
|
"grid_entries",
|
||||||
@@ -225,6 +224,7 @@ namespace DatabaseSchema {
|
|||||||
"pets_beastlord_data",
|
"pets_beastlord_data",
|
||||||
"pets_equipmentset",
|
"pets_equipmentset",
|
||||||
"pets_equipmentset_entries",
|
"pets_equipmentset_entries",
|
||||||
|
"proximities",
|
||||||
"skill_caps",
|
"skill_caps",
|
||||||
"spawn2",
|
"spawn2",
|
||||||
"spawn_conditions",
|
"spawn_conditions",
|
||||||
@@ -270,7 +270,6 @@ namespace DatabaseSchema {
|
|||||||
"perl_event_export_settings",
|
"perl_event_export_settings",
|
||||||
"profanity_list",
|
"profanity_list",
|
||||||
"rule_sets",
|
"rule_sets",
|
||||||
"titles",
|
|
||||||
"rule_values",
|
"rule_values",
|
||||||
"variables",
|
"variables",
|
||||||
};
|
};
|
||||||
@@ -318,21 +317,20 @@ namespace DatabaseSchema {
|
|||||||
"completed_shared_task_activity_state",
|
"completed_shared_task_activity_state",
|
||||||
"completed_shared_task_members",
|
"completed_shared_task_members",
|
||||||
"completed_shared_tasks",
|
"completed_shared_tasks",
|
||||||
"discord_webhooks",
|
|
||||||
"dynamic_zone_members",
|
"dynamic_zone_members",
|
||||||
"dynamic_zones",
|
"dynamic_zones",
|
||||||
|
"eventlog",
|
||||||
"expedition_lockouts",
|
"expedition_lockouts",
|
||||||
"expeditions",
|
"expeditions",
|
||||||
"gm_ips",
|
"gm_ips",
|
||||||
"group_id",
|
"group_id",
|
||||||
"group_leaders",
|
"group_leaders",
|
||||||
|
"hackers",
|
||||||
"instance_list",
|
"instance_list",
|
||||||
"ip_exemptions",
|
"ip_exemptions",
|
||||||
"item_tick",
|
"item_tick",
|
||||||
"lfguild",
|
"lfguild",
|
||||||
"merc_buffs",
|
|
||||||
"merchantlist_temp",
|
"merchantlist_temp",
|
||||||
"mercs",
|
|
||||||
"object_contents",
|
"object_contents",
|
||||||
"raid_details",
|
"raid_details",
|
||||||
"raid_leaders",
|
"raid_leaders",
|
||||||
@@ -341,8 +339,6 @@ namespace DatabaseSchema {
|
|||||||
"respawn_times",
|
"respawn_times",
|
||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"server_scheduled_events",
|
||||||
"player_event_log_settings",
|
|
||||||
"player_event_logs",
|
|
||||||
"shared_task_activity_state",
|
"shared_task_activity_state",
|
||||||
"shared_task_dynamic_zones",
|
"shared_task_dynamic_zones",
|
||||||
"shared_task_members",
|
"shared_task_members",
|
||||||
@@ -379,60 +375,6 @@ namespace DatabaseSchema {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Gets all player bot tables
|
|
||||||
* @note These tables have no content in the PEQ daily dump
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetBotTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"bot_buffs",
|
|
||||||
"bot_command_settings",
|
|
||||||
"bot_create_combinations",
|
|
||||||
"bot_data",
|
|
||||||
"bot_group_members",
|
|
||||||
"bot_groups",
|
|
||||||
"bot_guild_members",
|
|
||||||
"bot_heal_rotation_members",
|
|
||||||
"bot_heal_rotation_targets",
|
|
||||||
"bot_heal_rotations",
|
|
||||||
"bot_inspect_messages",
|
|
||||||
"bot_inventories",
|
|
||||||
"bot_owner_options",
|
|
||||||
"bot_pet_buffs",
|
|
||||||
"bot_pet_inventories",
|
|
||||||
"bot_pets",
|
|
||||||
"bot_spell_casting_chances",
|
|
||||||
"bot_spell_settings",
|
|
||||||
"bot_spells_entries",
|
|
||||||
"bot_stances",
|
|
||||||
"bot_timers"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::string> GetMercTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"merc_armorinfo",
|
|
||||||
"merc_inventory",
|
|
||||||
"merc_merchant_entries",
|
|
||||||
"merc_merchant_template_entries",
|
|
||||||
"merc_merchant_templates",
|
|
||||||
"merc_name_types",
|
|
||||||
"merc_npc_types",
|
|
||||||
"merc_spell_list_entries",
|
|
||||||
"merc_spell_lists",
|
|
||||||
"merc_stance_entries",
|
|
||||||
"merc_stats",
|
|
||||||
"merc_subtypes",
|
|
||||||
"merc_templates",
|
|
||||||
"merc_types",
|
|
||||||
"merc_weaponinfo"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //EQEMU_DATABASE_SCHEMA_H
|
#endif //EQEMU_DATABASE_SCHEMA_H
|
||||||
|
|||||||
+9
-17
@@ -70,20 +70,17 @@ DBcore::~DBcore()
|
|||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping()
|
||||||
{
|
{
|
||||||
if (!m_query_lock.try_lock()) {
|
if (!MDatabase.trylock()) {
|
||||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mysql_ping(&mysql);
|
mysql_ping(&mysql);
|
||||||
m_query_lock.unlock();
|
MDatabase.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
||||||
{
|
{
|
||||||
m_query_lock.lock();
|
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||||
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
|
||||||
m_query_lock.unlock();
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::DoesTableExist(std::string table_name)
|
bool DBcore::DoesTableExist(std::string table_name)
|
||||||
@@ -98,11 +95,15 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
|
LockMutex lock(&MDatabase);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
Open();
|
Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// request query. != 0 indicates some kind of error.
|
// request query. != 0 indicates some kind of error.
|
||||||
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
||||||
unsigned int errorNumber = mysql_errno(&mysql);
|
unsigned int errorNumber = mysql_errno(&mysql);
|
||||||
@@ -166,7 +167,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||||
if ((strncasecmp(query, "select", 6) == 0)) {
|
if ((strncasecmp(query, "select", 6) == 0)) {
|
||||||
LogMySQLQuery(
|
LogMySQLQuery(
|
||||||
"{0} -- ({1} row{2} returned) ({3}s)",
|
"{0} ({1} row{2} returned) ({3}s)",
|
||||||
query,
|
query,
|
||||||
requestResult.RowCount(),
|
requestResult.RowCount(),
|
||||||
requestResult.RowCount() == 1 ? "" : "s",
|
requestResult.RowCount() == 1 ? "" : "s",
|
||||||
@@ -175,7 +176,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogMySQLQuery(
|
LogMySQLQuery(
|
||||||
"{0} -- ({1} row{2} affected) ({3}s)",
|
"{0} ({1} row{2} affected) ({3}s)",
|
||||||
query,
|
query,
|
||||||
requestResult.RowsAffected(),
|
requestResult.RowsAffected(),
|
||||||
requestResult.RowsAffected() == 1 ? "" : "s",
|
requestResult.RowsAffected() == 1 ? "" : "s",
|
||||||
@@ -298,12 +299,3 @@ void DBcore::SetOriginHost(const std::string &origin_host)
|
|||||||
{
|
{
|
||||||
DBcore::origin_host = origin_host;
|
DBcore::origin_host = origin_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DBcore::Escape(const std::string& s)
|
|
||||||
{
|
|
||||||
const std::size_t s_len = s.length();
|
|
||||||
std::vector<char> temp((s_len * 2) + 1, '\0');
|
|
||||||
mysql_real_escape_string(&mysql, temp.data(), s.c_str(), s_len);
|
|
||||||
|
|
||||||
return temp.data();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
@@ -28,7 +27,6 @@ public:
|
|||||||
void TransactionBegin();
|
void TransactionBegin();
|
||||||
void TransactionCommit();
|
void TransactionCommit();
|
||||||
void TransactionRollback();
|
void TransactionRollback();
|
||||||
std::string Escape(const std::string& s);
|
|
||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
void ping();
|
void ping();
|
||||||
MYSQL *getMySQL() { return &mysql; }
|
MYSQL *getMySQL() { return &mysql; }
|
||||||
@@ -59,8 +57,6 @@ private:
|
|||||||
Mutex MDatabase;
|
Mutex MDatabase;
|
||||||
eStatus pStatus;
|
eStatus pStatus;
|
||||||
|
|
||||||
std::mutex m_query_lock{};
|
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
char *pHost;
|
char *pHost;
|
||||||
|
|||||||
@@ -1,171 +0,0 @@
|
|||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <cereal/archives/binary.hpp>
|
|
||||||
#include "discord.h"
|
|
||||||
#include "../http/httplib.h"
|
|
||||||
#include "../json/json.h"
|
|
||||||
#include "../strings.h"
|
|
||||||
#include "../eqemu_logsys.h"
|
|
||||||
#include "../events/player_event_logs.h"
|
|
||||||
|
|
||||||
constexpr int MAX_RETRIES = 10;
|
|
||||||
|
|
||||||
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
|
||||||
{
|
|
||||||
if (!ValidateWebhookUrl(webhook_url)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// split
|
|
||||||
auto s = Strings::Split(webhook_url, '/');
|
|
||||||
|
|
||||||
// url
|
|
||||||
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
|
|
||||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
|
||||||
|
|
||||||
// client
|
|
||||||
httplib::Client cli(base_url);
|
|
||||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
|
||||||
cli.set_read_timeout(15, 0); // 15 seconds
|
|
||||||
cli.set_write_timeout(15, 0); // 15 seconds
|
|
||||||
httplib::Headers headers = {
|
|
||||||
{"Content-Type", "application/json"}
|
|
||||||
};
|
|
||||||
|
|
||||||
// payload
|
|
||||||
Json::Value p;
|
|
||||||
p["content"] = message;
|
|
||||||
std::stringstream payload;
|
|
||||||
payload << p;
|
|
||||||
|
|
||||||
bool retry = true;
|
|
||||||
int retries = 0;
|
|
||||||
int retry_timer = 1000;
|
|
||||||
while (retry) {
|
|
||||||
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
|
|
||||||
if (res->status != 200 && res->status != 204) {
|
|
||||||
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
|
|
||||||
}
|
|
||||||
if (res->status == 429) {
|
|
||||||
if (!res->body.empty()) {
|
|
||||||
std::stringstream ss(res->body);
|
|
||||||
Json::Value response;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ss >> response;
|
|
||||||
}
|
|
||||||
catch (std::exception const &ex) {
|
|
||||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
|
||||||
}
|
|
||||||
|
|
||||||
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
|
|
||||||
}
|
|
||||||
if (res->status == 204) {
|
|
||||||
retry = false;
|
|
||||||
}
|
|
||||||
if (retries > MAX_RETRIES) {
|
|
||||||
LogDiscord("Retries exceeded for message [{}]", message);
|
|
||||||
retry = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
retries++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Discord::SendPlayerEventMessage(
|
|
||||||
const PlayerEvent::PlayerEventContainer &e,
|
|
||||||
const std::string &webhook_url
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!ValidateWebhookUrl(webhook_url)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto s = Strings::Split(webhook_url, '/');
|
|
||||||
|
|
||||||
// url
|
|
||||||
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
|
|
||||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
|
||||||
|
|
||||||
// client
|
|
||||||
httplib::Client cli(base_url);
|
|
||||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
|
||||||
cli.set_read_timeout(15, 0); // 15 seconds
|
|
||||||
cli.set_write_timeout(15, 0); // 15 seconds
|
|
||||||
httplib::Headers headers = {
|
|
||||||
{"Content-Type", "application/json"}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
|
|
||||||
if (payload.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool retry = true;
|
|
||||||
int retries = 0;
|
|
||||||
int retry_timer = 1000;
|
|
||||||
while (retry) {
|
|
||||||
if (auto res = cli.Post(endpoint, payload, "application/json")) {
|
|
||||||
if (res->status != 200 && res->status != 204) {
|
|
||||||
LogError("Code [{}] Error [{}]", res->status, res->body);
|
|
||||||
}
|
|
||||||
if (res->status == 429) {
|
|
||||||
if (!res->body.empty()) {
|
|
||||||
std::stringstream ss(res->body);
|
|
||||||
Json::Value response;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ss >> response;
|
|
||||||
}
|
|
||||||
catch (std::exception const &ex) {
|
|
||||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
|
||||||
}
|
|
||||||
|
|
||||||
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
|
|
||||||
}
|
|
||||||
if (res->status == 204) {
|
|
||||||
retry = false;
|
|
||||||
}
|
|
||||||
if (retries > MAX_RETRIES) {
|
|
||||||
LogDiscord("Retries exceeded for player event message");
|
|
||||||
retry = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
retries++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
|
|
||||||
{
|
|
||||||
if (category_id == Logs::LogCategory::MySQLQuery) {
|
|
||||||
return fmt::format("```sql\n{}\n```", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return message + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Discord::ValidateWebhookUrl(const std::string &webhook_url)
|
|
||||||
{
|
|
||||||
// validate
|
|
||||||
if (webhook_url.empty()) {
|
|
||||||
LogDiscord("[webhook_url] is empty");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate
|
|
||||||
if (!Strings::Contains(webhook_url, "http://") && !Strings::Contains(webhook_url, "https://")) {
|
|
||||||
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#ifndef EQEMU_DISCORD_H
|
|
||||||
#define EQEMU_DISCORD_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "../types.h"
|
|
||||||
#include "../http/httplib.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../events/player_events.h"
|
|
||||||
|
|
||||||
class Discord {
|
|
||||||
public:
|
|
||||||
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
|
||||||
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
|
|
||||||
static void SendPlayerEventMessage(const PlayerEvent::PlayerEventContainer& e, const std::string &webhook_url);
|
|
||||||
static bool ValidateWebhookUrl(const std::string &webhook_url);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EQEMU_DISCORD_H
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
#include "discord_manager.h"
|
|
||||||
#include "../../common/discord/discord.h"
|
|
||||||
#include "../events/player_event_logs.h"
|
|
||||||
|
|
||||||
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
|
||||||
{
|
|
||||||
webhook_queue_lock.lock();
|
|
||||||
webhook_message_queue[webhook_id].emplace_back(message);
|
|
||||||
webhook_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int MAX_MESSAGE_LENGTH = 1900;
|
|
||||||
|
|
||||||
void DiscordManager::ProcessMessageQueue()
|
|
||||||
{
|
|
||||||
if (webhook_message_queue.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
webhook_queue_lock.lock();
|
|
||||||
for (auto &q: webhook_message_queue) {
|
|
||||||
LogDiscord("Processing [{}] messages in queue for webhook ID [{}]...", q.second.size(), q.first);
|
|
||||||
|
|
||||||
if (q.first >= MAX_DISCORD_WEBHOOK_ID) {
|
|
||||||
LogDiscord("Out of bounds webhook ID [{}] max [{}]", q.first, MAX_DISCORD_WEBHOOK_ID);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto webhook = LogSys.GetDiscordWebhooks()[q.first];
|
|
||||||
std::string message;
|
|
||||||
|
|
||||||
for (auto &m: q.second) {
|
|
||||||
// next message would become too large
|
|
||||||
bool next_message_too_large = ((int) m.length() + (int) message.length()) > MAX_MESSAGE_LENGTH;
|
|
||||||
if (next_message_too_large) {
|
|
||||||
Discord::SendWebhookMessage(
|
|
||||||
message,
|
|
||||||
webhook.webhook_url
|
|
||||||
);
|
|
||||||
message = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
message += m;
|
|
||||||
|
|
||||||
// one single message was too large
|
|
||||||
// this should rarely happen but the message will need to be split
|
|
||||||
if ((int) message.length() > MAX_MESSAGE_LENGTH) {
|
|
||||||
for (unsigned mi = 0; mi < message.length(); mi += MAX_MESSAGE_LENGTH) {
|
|
||||||
Discord::SendWebhookMessage(
|
|
||||||
message.substr(mi, MAX_MESSAGE_LENGTH),
|
|
||||||
webhook.webhook_url
|
|
||||||
);
|
|
||||||
}
|
|
||||||
message = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// final flush
|
|
||||||
if (!message.empty()) {
|
|
||||||
Discord::SendWebhookMessage(
|
|
||||||
message,
|
|
||||||
webhook.webhook_url
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
webhook_message_queue.clear();
|
|
||||||
webhook_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
|
|
||||||
{
|
|
||||||
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
|
|
||||||
if (!w.empty()) {
|
|
||||||
Discord::SendPlayerEventMessage(e, w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#ifndef EQEMU_DISCORD_MANAGER_H
|
|
||||||
#define EQEMU_DISCORD_MANAGER_H
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include "../../common/types.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../events/player_events.h"
|
|
||||||
|
|
||||||
class DiscordManager {
|
|
||||||
public:
|
|
||||||
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
|
||||||
void ProcessMessageQueue();
|
|
||||||
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
|
||||||
private:
|
|
||||||
std::mutex webhook_queue_lock{};
|
|
||||||
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -79,7 +79,6 @@ void DynamicZoneBase::LoadRepositoryResult(DynamicZonesRepository::DynamicZoneIn
|
|||||||
m_max_players = dz_entry.max_players;
|
m_max_players = dz_entry.max_players;
|
||||||
m_instance_id = dz_entry.instance_id;
|
m_instance_id = dz_entry.instance_id;
|
||||||
m_type = static_cast<DynamicZoneType>(dz_entry.type);
|
m_type = static_cast<DynamicZoneType>(dz_entry.type);
|
||||||
m_dz_switch_id = dz_entry.dz_switch_id;
|
|
||||||
m_compass.zone_id = dz_entry.compass_zone_id;
|
m_compass.zone_id = dz_entry.compass_zone_id;
|
||||||
m_compass.x = dz_entry.compass_x;
|
m_compass.x = dz_entry.compass_x;
|
||||||
m_compass.y = dz_entry.compass_y;
|
m_compass.y = dz_entry.compass_y;
|
||||||
@@ -130,7 +129,6 @@ uint32_t DynamicZoneBase::SaveToDatabase()
|
|||||||
insert_dz.max_players = m_max_players;
|
insert_dz.max_players = m_max_players;
|
||||||
insert_dz.instance_id = m_instance_id,
|
insert_dz.instance_id = m_instance_id,
|
||||||
insert_dz.type = static_cast<int>(m_type);
|
insert_dz.type = static_cast<int>(m_type);
|
||||||
insert_dz.dz_switch_id = m_dz_switch_id;
|
|
||||||
insert_dz.compass_zone_id = m_compass.zone_id;
|
insert_dz.compass_zone_id = m_compass.zone_id;
|
||||||
insert_dz.compass_x = m_compass.x;
|
insert_dz.compass_x = m_compass.x;
|
||||||
insert_dz.compass_y = m_compass.y;
|
insert_dz.compass_y = m_compass.y;
|
||||||
@@ -318,17 +316,6 @@ void DynamicZoneBase::SetZoneInLocation(float x, float y, float z, float heading
|
|||||||
SetZoneInLocation({ 0, x, y, z, heading }, update_db);
|
SetZoneInLocation({ 0, x, y, z, heading }, update_db);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicZoneBase::SetSwitchID(int dz_switch_id, bool update_db)
|
|
||||||
{
|
|
||||||
m_dz_switch_id = dz_switch_id;
|
|
||||||
|
|
||||||
if (update_db)
|
|
||||||
{
|
|
||||||
DynamicZonesRepository::UpdateSwitchID(GetDatabase(), m_id, dz_switch_id);
|
|
||||||
SendServerPacket(CreateServerDzSwitchIDPacket().get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update_db)
|
void DynamicZoneBase::SetLeader(const DynamicZoneMember& new_leader, bool update_db)
|
||||||
{
|
{
|
||||||
m_leader = new_leader;
|
m_leader = new_leader;
|
||||||
@@ -416,17 +403,6 @@ std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzLocationPacket(
|
|||||||
return pack;
|
return pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerDzSwitchIDPacket()
|
|
||||||
{
|
|
||||||
constexpr uint32_t pack_size = sizeof(ServerDzSwitchID_Struct);
|
|
||||||
auto pack = std::make_unique<ServerPacket>(ServerOP_DzSetSwitchID, pack_size);
|
|
||||||
auto buf = reinterpret_cast<ServerDzSwitchID_Struct*>(pack->pBuffer);
|
|
||||||
buf->dz_id = GetID();
|
|
||||||
buf->dz_switch_id = GetSwitchID();
|
|
||||||
|
|
||||||
return pack;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberStatusPacket(
|
std::unique_ptr<ServerPacket> DynamicZoneBase::CreateServerMemberStatusPacket(
|
||||||
uint32_t character_id, DynamicZoneMemberStatus status)
|
uint32_t character_id, DynamicZoneMemberStatus status)
|
||||||
{
|
{
|
||||||
@@ -585,9 +561,8 @@ std::string DynamicZoneBase::GetDynamicZoneTypeName(DynamicZoneType dz_type)
|
|||||||
return "Mission";
|
return "Mission";
|
||||||
case DynamicZoneType::Quest:
|
case DynamicZoneType::Quest:
|
||||||
return "Quest";
|
return "Quest";
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
}
|
||||||
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
|
EQ::Net::DynamicPacket DynamicZoneBase::GetSerializedDzPacket()
|
||||||
@@ -622,28 +597,3 @@ void DynamicZoneBase::LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_
|
|||||||
cereal::BinaryInputArchive archive(ss);
|
cereal::BinaryInputArchive archive(ss);
|
||||||
archive(*this);
|
archive(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicZoneBase::LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template)
|
|
||||||
{
|
|
||||||
m_zone_id = dz_template.zone_id;
|
|
||||||
m_zone_version = dz_template.zone_version;
|
|
||||||
m_name = dz_template.name;
|
|
||||||
m_min_players = dz_template.min_players;
|
|
||||||
m_max_players = dz_template.max_players;
|
|
||||||
m_duration = std::chrono::seconds(dz_template.duration_seconds);
|
|
||||||
m_dz_switch_id = dz_template.dz_switch_id;
|
|
||||||
m_compass.zone_id = dz_template.compass_zone_id;
|
|
||||||
m_compass.x = dz_template.compass_x;
|
|
||||||
m_compass.y = dz_template.compass_y;
|
|
||||||
m_compass.z = dz_template.compass_z;
|
|
||||||
m_safereturn.zone_id = dz_template.return_zone_id;
|
|
||||||
m_safereturn.x = dz_template.return_x;
|
|
||||||
m_safereturn.y = dz_template.return_y;
|
|
||||||
m_safereturn.z = dz_template.return_z;
|
|
||||||
m_safereturn.heading = dz_template.return_h;
|
|
||||||
m_has_zonein = dz_template.override_zone_in;
|
|
||||||
m_zonein.x = dz_template.zone_in_x;
|
|
||||||
m_zonein.y = dz_template.zone_in_y;
|
|
||||||
m_zonein.z = dz_template.zone_in_z;
|
|
||||||
m_zonein.heading = dz_template.zone_in_h;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "net/packet.h"
|
#include "net/packet.h"
|
||||||
#include "repositories/dynamic_zones_repository.h"
|
#include "repositories/dynamic_zones_repository.h"
|
||||||
#include "repositories/dynamic_zone_members_repository.h"
|
#include "repositories/dynamic_zone_members_repository.h"
|
||||||
#include "repositories/dynamic_zone_templates_repository.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -75,7 +74,6 @@ public:
|
|||||||
|
|
||||||
virtual void SetSecondsRemaining(uint32_t seconds_remaining) = 0;
|
virtual void SetSecondsRemaining(uint32_t seconds_remaining) = 0;
|
||||||
|
|
||||||
int GetDuration() const { return static_cast<int>(m_duration.count()); }
|
|
||||||
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
||||||
uint32_t GetID() const { return m_id; }
|
uint32_t GetID() const { return m_id; }
|
||||||
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); }
|
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); }
|
||||||
@@ -87,7 +85,6 @@ public:
|
|||||||
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
|
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
|
||||||
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
|
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
|
||||||
uint32_t GetZoneVersion() const { return m_zone_version; }
|
uint32_t GetZoneVersion() const { return m_zone_version; }
|
||||||
int GetSwitchID() const { return m_dz_switch_id; }
|
|
||||||
DynamicZoneType GetType() const { return m_type; }
|
DynamicZoneType GetType() const { return m_type; }
|
||||||
const std::string& GetLeaderName() const { return m_leader.name; }
|
const std::string& GetLeaderName() const { return m_leader.name; }
|
||||||
const std::string& GetName() const { return m_name; }
|
const std::string& GetName() const { return m_name; }
|
||||||
@@ -115,7 +112,6 @@ public:
|
|||||||
bool IsValid() const { return m_instance_id != 0; }
|
bool IsValid() const { return m_instance_id != 0; }
|
||||||
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const { return zone_id == m_zone_id && instance_id == m_instance_id; }
|
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const { return zone_id == m_zone_id && instance_id == m_instance_id; }
|
||||||
void LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size);
|
void LoadSerializedDzPacket(char* cereal_data, uint32_t cereal_size);
|
||||||
void LoadTemplate(const DynamicZoneTemplatesRepository::DynamicZoneTemplates& dz_template);
|
|
||||||
void RemoveAllMembers();
|
void RemoveAllMembers();
|
||||||
bool RemoveMember(uint32_t character_id);
|
bool RemoveMember(uint32_t character_id);
|
||||||
bool RemoveMember(const std::string& character_name);
|
bool RemoveMember(const std::string& character_name);
|
||||||
@@ -131,7 +127,6 @@ public:
|
|||||||
void SetName(const std::string& name) { m_name = name; }
|
void SetName(const std::string& name) { m_name = name; }
|
||||||
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
||||||
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
|
void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
|
||||||
void SetSwitchID(int dz_switch_id, bool update_db = false);
|
|
||||||
void SetType(DynamicZoneType type) { m_type = type; }
|
void SetType(DynamicZoneType type) { m_type = type; }
|
||||||
void SetUUID(std::string uuid) { m_uuid = std::move(uuid); }
|
void SetUUID(std::string uuid) { m_uuid = std::move(uuid); }
|
||||||
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
|
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
|
||||||
@@ -146,7 +141,6 @@ protected:
|
|||||||
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
|
virtual void ProcessMemberAddRemove(const DynamicZoneMember& member, bool removed);
|
||||||
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
|
virtual bool ProcessMemberStatusChange(uint32_t member_id, DynamicZoneMemberStatus status);
|
||||||
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
|
virtual void ProcessRemoveAllMembers(bool silent = false) { m_members.clear(); }
|
||||||
virtual void ProcessSetSwitchID(int dz_switch_id) { m_dz_switch_id = dz_switch_id; }
|
|
||||||
virtual bool SendServerPacket(ServerPacket* packet) = 0;
|
virtual bool SendServerPacket(ServerPacket* packet) = 0;
|
||||||
|
|
||||||
void AddInternalMember(const DynamicZoneMember& member);
|
void AddInternalMember(const DynamicZoneMember& member);
|
||||||
@@ -159,7 +153,6 @@ protected:
|
|||||||
|
|
||||||
std::unique_ptr<ServerPacket> CreateServerDzCreatePacket(uint16_t origin_zone_id, uint16_t origin_instance_id);
|
std::unique_ptr<ServerPacket> CreateServerDzCreatePacket(uint16_t origin_zone_id, uint16_t origin_instance_id);
|
||||||
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
|
std::unique_ptr<ServerPacket> CreateServerDzLocationPacket(uint16_t server_opcode, const DynamicZoneLocation& location);
|
||||||
std::unique_ptr<ServerPacket> CreateServerDzSwitchIDPacket();
|
|
||||||
std::unique_ptr<ServerPacket> CreateServerMemberAddRemovePacket(const DynamicZoneMember& member, bool removed);
|
std::unique_ptr<ServerPacket> CreateServerMemberAddRemovePacket(const DynamicZoneMember& member, bool removed);
|
||||||
std::unique_ptr<ServerPacket> CreateServerMemberStatusPacket(uint32_t character_id, DynamicZoneMemberStatus status);
|
std::unique_ptr<ServerPacket> CreateServerMemberStatusPacket(uint32_t character_id, DynamicZoneMemberStatus status);
|
||||||
std::unique_ptr<ServerPacket> CreateServerMemberSwapPacket(const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member);
|
std::unique_ptr<ServerPacket> CreateServerMemberSwapPacket(const DynamicZoneMember& remove_member, const DynamicZoneMember& add_member);
|
||||||
@@ -171,7 +164,6 @@ protected:
|
|||||||
uint32_t m_zone_version = 0;
|
uint32_t m_zone_version = 0;
|
||||||
uint32_t m_min_players = 0;
|
uint32_t m_min_players = 0;
|
||||||
uint32_t m_max_players = 0;
|
uint32_t m_max_players = 0;
|
||||||
int m_dz_switch_id = 0;
|
|
||||||
bool m_never_expires = false;
|
bool m_never_expires = false;
|
||||||
bool m_has_zonein = false;
|
bool m_has_zonein = false;
|
||||||
bool m_has_member_statuses = false;
|
bool m_has_member_statuses = false;
|
||||||
@@ -198,7 +190,6 @@ public:
|
|||||||
m_zone_version,
|
m_zone_version,
|
||||||
m_min_players,
|
m_min_players,
|
||||||
m_max_players,
|
m_max_players,
|
||||||
m_dz_switch_id,
|
|
||||||
m_never_expires,
|
m_never_expires,
|
||||||
m_has_zonein,
|
m_has_zonein,
|
||||||
m_has_member_statuses,
|
m_has_member_statuses,
|
||||||
|
|||||||
+5
-387
@@ -18,12 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu_constants.h"
|
#include "emu_constants.h"
|
||||||
#include "bodytypes.h"
|
|
||||||
#include "data_verification.h"
|
|
||||||
#include "eqemu_logsys.h"
|
|
||||||
#include "eqemu_logsys_log_aliases.h"
|
|
||||||
#include "languages.h"
|
#include "languages.h"
|
||||||
#include "rulesys.h"
|
|
||||||
|
|
||||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||||
static const int16 local_array[] = {
|
static const int16 local_array[] = {
|
||||||
@@ -152,9 +148,8 @@ const char *EQ::constants::GetStanceName(StanceType stance_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
||||||
if (EQ::ValueWithin(stance_type, EQ::constants::stancePassive, EQ::constants::stanceBurnAE)) {
|
if (stance_type >= EQ::constants::stancePassive && stance_type <= EQ::constants::stanceBurnAE)
|
||||||
return (stance_type - EQ::constants::stancePassive);
|
return (stance_type - EQ::constants::stancePassive);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -191,391 +186,14 @@ const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
|||||||
{ LANG_HADAL, "Hadal" },
|
{ LANG_HADAL, "Hadal" },
|
||||||
{ LANG_UNKNOWN, "Unknown" }
|
{ LANG_UNKNOWN, "Unknown" }
|
||||||
};
|
};
|
||||||
|
|
||||||
return language_map;
|
return language_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQ::constants::GetLanguageName(int language_id)
|
std::string EQ::constants::GetLanguageName(int language_id)
|
||||||
{
|
{
|
||||||
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
if (language_id >= LANG_COMMON_TONGUE && language_id <= LANG_UNKNOWN) {
|
||||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
auto languages = EQ::constants::GetLanguageMap();
|
||||||
|
return languages[language_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
|
||||||
{
|
|
||||||
static const std::map<int8, std::string> flymode_map = {
|
|
||||||
{ GravityBehavior::Ground, "Ground" },
|
|
||||||
{ GravityBehavior::Flying, "Flying" },
|
|
||||||
{ GravityBehavior::Levitating, "Levitating" },
|
|
||||||
{ GravityBehavior::Water, "Water" },
|
|
||||||
{ GravityBehavior::Floating, "Floating" },
|
|
||||||
{ GravityBehavior::LevitateWhileRunning, "Levitating While Running" },
|
|
||||||
};
|
|
||||||
|
|
||||||
return flymode_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
|
|
||||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = {
|
|
||||||
{ ConsiderLevel::Ally, "Ally" },
|
|
||||||
{ ConsiderLevel::Warmly, "Warmly" },
|
|
||||||
{ ConsiderLevel::Kindly, "Kindly" },
|
|
||||||
{ ConsiderLevel::Amiably, "Amiably" },
|
|
||||||
{ ConsiderLevel::Indifferently, "Indifferently" },
|
|
||||||
{ ConsiderLevel::Apprehensively, "Apprehensively" },
|
|
||||||
{ ConsiderLevel::Dubiously, "Dubiously" },
|
|
||||||
{ ConsiderLevel::Threateningly, "Threateningly" },
|
|
||||||
{ ConsiderLevel::Scowls, "Scowls" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return consider_level_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
|
|
||||||
{
|
|
||||||
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
|
|
||||||
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> damage_type_map = {
|
|
||||||
{ EnvironmentalDamage::Lava, "Lava" },
|
|
||||||
{ EnvironmentalDamage::Drowning, "Drowning" },
|
|
||||||
{ EnvironmentalDamage::Falling, "Falling" },
|
|
||||||
{ EnvironmentalDamage::Trap, "Trap" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return damage_type_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
|
|
||||||
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> stuck_behavior_map = {
|
|
||||||
{ StuckBehavior::RunToTarget, "Run To Target" },
|
|
||||||
{ StuckBehavior::WarpToTarget, "Warp To Target" },
|
|
||||||
{ StuckBehavior::TakeNoAction, "Take No Action" },
|
|
||||||
{ StuckBehavior::EvadeCombat, "Evade Combat" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return stuck_behavior_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
|
|
||||||
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> spawn_animation_map = {
|
|
||||||
{ SpawnAnimations::Standing, "Standing" },
|
|
||||||
{ SpawnAnimations::Sitting, "Sitting" },
|
|
||||||
{ SpawnAnimations::Crouching, "Crouching" },
|
|
||||||
{ SpawnAnimations::Laying, "Laying" },
|
|
||||||
{ SpawnAnimations::Looting, "Looting" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return spawn_animation_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
|
|
||||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> weather_type_map = {
|
|
||||||
{WeatherTypes::None, "None"},
|
|
||||||
{WeatherTypes::Raining, "Raining"},
|
|
||||||
{WeatherTypes::Snowing, "Snowing"}
|
|
||||||
};
|
|
||||||
|
|
||||||
return weather_type_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
|
||||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> emote_event_type_map = {
|
|
||||||
{ EmoteEventTypes::LeaveCombat, "Leave Combat" },
|
|
||||||
{ EmoteEventTypes::EnterCombat, "Enter Combat" },
|
|
||||||
{ EmoteEventTypes::OnDeath, "On Death" },
|
|
||||||
{ EmoteEventTypes::AfterDeath, "After Death" },
|
|
||||||
{ EmoteEventTypes::Hailed, "Hailed" },
|
|
||||||
{ EmoteEventTypes::KilledPC, "Killed PC" },
|
|
||||||
{ EmoteEventTypes::KilledNPC, "Killed NPC" },
|
|
||||||
{ EmoteEventTypes::OnSpawn, "On Spawn" },
|
|
||||||
{ EmoteEventTypes::OnDespawn, "On Despawn" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return emote_event_type_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
|
||||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
|
||||||
{
|
|
||||||
static const std::map<uint8, std::string> emote_type_map = {
|
|
||||||
{ EmoteTypes::Emote, "Emote" },
|
|
||||||
{ EmoteTypes::Shout, "Shout" },
|
|
||||||
{ EmoteTypes::Proximity, "Proximity" }
|
|
||||||
};
|
|
||||||
|
|
||||||
return emote_type_map;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
|
||||||
{
|
|
||||||
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
|
||||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-267
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "eq_limits.h"
|
#include "eq_limits.h"
|
||||||
#include "emu_versions.h"
|
#include "emu_versions.h"
|
||||||
#include "bodytypes.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -33,6 +32,10 @@ namespace EQ
|
|||||||
using RoF2::IINVALID;
|
using RoF2::IINVALID;
|
||||||
using RoF2::INULL;
|
using RoF2::INULL;
|
||||||
|
|
||||||
|
namespace inventory {
|
||||||
|
|
||||||
|
} /*inventory*/
|
||||||
|
|
||||||
namespace invtype {
|
namespace invtype {
|
||||||
using namespace RoF2::invtype::enum_;
|
using namespace RoF2::invtype::enum_;
|
||||||
|
|
||||||
@@ -217,186 +220,12 @@ namespace EQ
|
|||||||
stanceBurnAE
|
stanceBurnAE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BotSpellIDs : int {
|
|
||||||
Warrior = 3001,
|
|
||||||
Cleric,
|
|
||||||
Paladin,
|
|
||||||
Ranger,
|
|
||||||
Shadowknight,
|
|
||||||
Druid,
|
|
||||||
Monk,
|
|
||||||
Bard,
|
|
||||||
Rogue,
|
|
||||||
Shaman,
|
|
||||||
Necromancer,
|
|
||||||
Wizard,
|
|
||||||
Magician,
|
|
||||||
Enchanter,
|
|
||||||
Beastlord,
|
|
||||||
Berserker
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GravityBehavior : int8 {
|
|
||||||
Ground,
|
|
||||||
Flying,
|
|
||||||
Levitating,
|
|
||||||
Water,
|
|
||||||
Floating,
|
|
||||||
LevitateWhileRunning
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EnvironmentalDamage : uint8 {
|
|
||||||
Lava = 250,
|
|
||||||
Drowning,
|
|
||||||
Falling,
|
|
||||||
Trap
|
|
||||||
};
|
|
||||||
|
|
||||||
enum StuckBehavior : uint8 {
|
|
||||||
RunToTarget,
|
|
||||||
WarpToTarget,
|
|
||||||
TakeNoAction,
|
|
||||||
EvadeCombat
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SpawnAnimations : uint8 {
|
|
||||||
Standing,
|
|
||||||
Sitting,
|
|
||||||
Crouching,
|
|
||||||
Laying,
|
|
||||||
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,
|
|
||||||
Snowing
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EmoteEventTypes : uint8 {
|
|
||||||
LeaveCombat,
|
|
||||||
EnterCombat,
|
|
||||||
OnDeath,
|
|
||||||
AfterDeath,
|
|
||||||
Hailed,
|
|
||||||
KilledPC,
|
|
||||||
KilledNPC,
|
|
||||||
OnSpawn,
|
|
||||||
OnDespawn
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EmoteTypes : uint8 {
|
|
||||||
Emote,
|
|
||||||
Shout,
|
|
||||||
Proximity
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *GetStanceName(StanceType stance_type);
|
const char *GetStanceName(StanceType stance_type);
|
||||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||||
|
|
||||||
extern const std::map<int, std::string>& GetLanguageMap();
|
extern const std::map<int, std::string>& GetLanguageMap();
|
||||||
std::string GetLanguageName(int language_id);
|
std::string GetLanguageName(int 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);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetEnvironmentalDamageMap();
|
|
||||||
std::string GetEnvironmentalDamageName(uint8 damage_type);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetStuckBehaviorMap();
|
|
||||||
std::string GetStuckBehaviorName(uint8 behavior_id);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetEmoteEventTypeMap();
|
|
||||||
std::string GetEmoteEventTypeName(uint8 emote_event_type);
|
|
||||||
|
|
||||||
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
|
||||||
std::string GetEmoteTypeName(uint8 emote_type);
|
|
||||||
|
|
||||||
const int STANCE_TYPE_FIRST = stancePassive;
|
const int STANCE_TYPE_FIRST = stancePassive;
|
||||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||||
@@ -499,98 +328,13 @@ namespace EQ
|
|||||||
Guild
|
Guild
|
||||||
};
|
};
|
||||||
}; // namespace consent
|
}; // namespace consent
|
||||||
|
|
||||||
} /*EQEmu*/
|
} /*EQEmu*/
|
||||||
|
|
||||||
enum ServerLockType : int {
|
|
||||||
List,
|
|
||||||
Lock,
|
|
||||||
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,
|
|
||||||
Special = 255
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AugmentActions : int {
|
|
||||||
Insert,
|
|
||||||
Remove,
|
|
||||||
Swap,
|
|
||||||
Destroy
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ConsiderLevel : uint8 {
|
|
||||||
Ally = 1,
|
|
||||||
Warmly,
|
|
||||||
Kindly,
|
|
||||||
Amiably,
|
|
||||||
Indifferently,
|
|
||||||
Apprehensively,
|
|
||||||
Dubiously,
|
|
||||||
Threateningly,
|
|
||||||
Scowls
|
|
||||||
};
|
|
||||||
|
|
||||||
enum TargetDescriptionType : uint8 {
|
|
||||||
LCSelf,
|
|
||||||
UCSelf,
|
|
||||||
LCYou,
|
|
||||||
UCYou,
|
|
||||||
LCYour,
|
|
||||||
UCYour
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ReloadWorld : uint8 {
|
|
||||||
NoRepop = 0,
|
|
||||||
Repop,
|
|
||||||
ForceRepop
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BucketComparison : uint8 {
|
|
||||||
BucketEqualTo = 0,
|
|
||||||
BucketNotEqualTo,
|
|
||||||
BucketGreaterThanOrEqualTo,
|
|
||||||
BucketLesserThanOrEqualTo,
|
|
||||||
BucketGreaterThan,
|
|
||||||
BucketLesserThan,
|
|
||||||
BucketIsAny,
|
|
||||||
BucketIsNotAny,
|
|
||||||
BucketIsBetween,
|
|
||||||
BucketIsNotBetween
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EntityFilterType {
|
|
||||||
All,
|
|
||||||
Bots,
|
|
||||||
Clients,
|
|
||||||
NPCs
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ApplySpellType {
|
|
||||||
Solo,
|
|
||||||
Group,
|
|
||||||
Raid
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||||
|
|
||||||
|
/* hack list to prevent circular references
|
||||||
|
|
||||||
|
eq_limits.h:EQ::inventory::LookupEntry::InventoryTypeSize[n];
|
||||||
|
|
||||||
|
*/
|
||||||
|
|||||||
+3
-7
@@ -35,7 +35,7 @@ N(OP_AltCurrencyMerchantRequest),
|
|||||||
N(OP_AltCurrencyPurchase),
|
N(OP_AltCurrencyPurchase),
|
||||||
N(OP_AltCurrencyReclaim),
|
N(OP_AltCurrencyReclaim),
|
||||||
N(OP_AltCurrencySell),
|
N(OP_AltCurrencySell),
|
||||||
N(OP_AltCurrencySellSelection), // Used by eqstr_us.txt 8066, 8068, 8069
|
N(OP_AltCurrencySellSelection),
|
||||||
N(OP_Animation),
|
N(OP_Animation),
|
||||||
N(OP_AnnoyingZoneUnknown),
|
N(OP_AnnoyingZoneUnknown),
|
||||||
N(OP_ApplyPoison),
|
N(OP_ApplyPoison),
|
||||||
@@ -71,7 +71,6 @@ N(OP_Camp),
|
|||||||
N(OP_CancelSneakHide),
|
N(OP_CancelSneakHide),
|
||||||
N(OP_CancelTask),
|
N(OP_CancelTask),
|
||||||
N(OP_CancelTrade),
|
N(OP_CancelTrade),
|
||||||
N(OP_CashReward),
|
|
||||||
N(OP_CastSpell),
|
N(OP_CastSpell),
|
||||||
N(OP_ChangeSize),
|
N(OP_ChangeSize),
|
||||||
N(OP_ChannelMessage),
|
N(OP_ChannelMessage),
|
||||||
@@ -130,8 +129,8 @@ N(OP_DisciplineTimer),
|
|||||||
N(OP_DisciplineUpdate),
|
N(OP_DisciplineUpdate),
|
||||||
N(OP_DiscordMerchantInventory),
|
N(OP_DiscordMerchantInventory),
|
||||||
N(OP_DoGroupLeadershipAbility),
|
N(OP_DoGroupLeadershipAbility),
|
||||||
N(OP_DuelDecline),
|
N(OP_DuelResponse),
|
||||||
N(OP_DuelAccept),
|
N(OP_DuelResponse2),
|
||||||
N(OP_DumpName),
|
N(OP_DumpName),
|
||||||
N(OP_Dye),
|
N(OP_Dye),
|
||||||
N(OP_DynamicWall),
|
N(OP_DynamicWall),
|
||||||
@@ -304,7 +303,6 @@ N(OP_LockoutTimerInfo),
|
|||||||
N(OP_Login),
|
N(OP_Login),
|
||||||
N(OP_LoginAccepted),
|
N(OP_LoginAccepted),
|
||||||
N(OP_LoginComplete),
|
N(OP_LoginComplete),
|
||||||
N(OP_LoginExpansionPacketData), //added for Rof2 client to send expansion data packet. Requires login_opcodes_sod.conf to be updated.
|
|
||||||
N(OP_LoginUnknown1),
|
N(OP_LoginUnknown1),
|
||||||
N(OP_LoginUnknown2),
|
N(OP_LoginUnknown2),
|
||||||
N(OP_Logout),
|
N(OP_Logout),
|
||||||
@@ -457,7 +455,6 @@ N(OP_ServerListResponse),
|
|||||||
N(OP_SessionReady),
|
N(OP_SessionReady),
|
||||||
N(OP_SetChatServer),
|
N(OP_SetChatServer),
|
||||||
N(OP_SetChatServer2),
|
N(OP_SetChatServer2),
|
||||||
N(OP_SetFace),
|
|
||||||
N(OP_SetGroupTarget),
|
N(OP_SetGroupTarget),
|
||||||
N(OP_SetGuildMOTD),
|
N(OP_SetGuildMOTD),
|
||||||
N(OP_SetGuildRank),
|
N(OP_SetGuildRank),
|
||||||
@@ -561,7 +558,6 @@ N(OP_WhoAllRequest),
|
|||||||
N(OP_WhoAllResponse),
|
N(OP_WhoAllResponse),
|
||||||
N(OP_World_Client_CRC1),
|
N(OP_World_Client_CRC1),
|
||||||
N(OP_World_Client_CRC2),
|
N(OP_World_Client_CRC2),
|
||||||
N(OP_World_Client_CRC3),
|
|
||||||
N(OP_WorldClientReady),
|
N(OP_WorldClientReady),
|
||||||
N(OP_WorldComplete),
|
N(OP_WorldComplete),
|
||||||
N(OP_WorldLogout),
|
N(OP_WorldLogout),
|
||||||
|
|||||||
+9
-45
@@ -79,8 +79,6 @@
|
|||||||
#define ANIM_DEATH 0x73
|
#define ANIM_DEATH 0x73
|
||||||
#define ANIM_LOOT 0x69
|
#define ANIM_LOOT 0x69
|
||||||
|
|
||||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eaStanding = 0,
|
eaStanding = 0,
|
||||||
eaSitting, //1
|
eaSitting, //1
|
||||||
@@ -686,6 +684,14 @@ namespace Zones {
|
|||||||
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ZoneChange_Struct->success values
|
||||||
|
#define ZONE_ERROR_NOMSG 0
|
||||||
|
#define ZONE_ERROR_NOTREADY -1
|
||||||
|
#define ZONE_ERROR_VALIDPC -2
|
||||||
|
#define ZONE_ERROR_STORYZONE -3
|
||||||
|
#define ZONE_ERROR_NOEXPANSION -6
|
||||||
|
#define ZONE_ERROR_NOEXPERIENCE -7
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FilterNone = 0,
|
FilterNone = 0,
|
||||||
@@ -712,7 +718,7 @@ typedef enum {
|
|||||||
FilterPetMisses = 21, //0=show, 1=hide
|
FilterPetMisses = 21, //0=show, 1=hide
|
||||||
FilterFocusEffects = 22, //0=show, 1=hide
|
FilterFocusEffects = 22, //0=show, 1=hide
|
||||||
FilterPetSpells = 23, //0=show, 1=hide
|
FilterPetSpells = 23, //0=show, 1=hide
|
||||||
FilterHealOverTime = 24, //0=show, 1=mine only, 2=hide
|
FilterHealOverTime = 24, //0=show, 1=hide
|
||||||
FilterUnknown25 = 25,
|
FilterUnknown25 = 25,
|
||||||
FilterUnknown26 = 26,
|
FilterUnknown26 = 26,
|
||||||
FilterUnknown27 = 27,
|
FilterUnknown27 = 27,
|
||||||
@@ -1003,46 +1009,4 @@ enum StartZoneIndex {
|
|||||||
SharVahl
|
SharVahl
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FVNoDropFlagRule
|
|
||||||
{
|
|
||||||
Disabled = 0,
|
|
||||||
Enabled = 1,
|
|
||||||
AdminOnly = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Anonymity : uint8
|
|
||||||
{
|
|
||||||
NotAnonymous,
|
|
||||||
Anonymous,
|
|
||||||
Roleplaying
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ZoningMessage : int8 {
|
|
||||||
ZoneNoMessage = 0,
|
|
||||||
ZoneSuccess = 1,
|
|
||||||
ZoneNotReady = -1,
|
|
||||||
ZoneValidPC = -2,
|
|
||||||
ZoneStoryZone = -3,
|
|
||||||
ZoneNoExpansion = -6,
|
|
||||||
ZoneNoExperience = -7
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class RecipeCountType : uint8
|
|
||||||
{
|
|
||||||
Component,
|
|
||||||
Container,
|
|
||||||
Fail,
|
|
||||||
Salvage,
|
|
||||||
Success
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ALT_CURRENCY_ID_RADIANT 4
|
|
||||||
#define ALT_CURRENCY_ID_EBON 5
|
|
||||||
|
|
||||||
enum ResurrectionActions
|
|
||||||
{
|
|
||||||
Decline,
|
|
||||||
Accept
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
static bool global_dictionary_init = false;
|
static bool global_dictionary_init = false;
|
||||||
void EQ::InitializeDynamicLookups() {
|
void EQ::InitializeDynamicLookups() {
|
||||||
if (global_dictionary_init)
|
if (global_dictionary_init == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
constants::InitializeDynamicLookups();
|
constants::InitializeDynamicLookups();
|
||||||
|
|||||||
+19
-41
@@ -29,7 +29,7 @@
|
|||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 BUFF_COUNT = 42;
|
static const uint32 BUFF_COUNT = 25;
|
||||||
static const uint32 PET_BUFF_COUNT = 30;
|
static const uint32 PET_BUFF_COUNT = 30;
|
||||||
static const uint32 MAX_MERC = 100;
|
static const uint32 MAX_MERC = 100;
|
||||||
static const uint32 MAX_MERC_GRADES = 10;
|
static const uint32 MAX_MERC_GRADES = 10;
|
||||||
@@ -378,14 +378,14 @@ struct NewZone_Struct {
|
|||||||
// Titanium doesn't have a translator, but we can still safely add stuff under here without issues since client memcpy's only what it knows
|
// Titanium doesn't have a translator, but we can still safely add stuff under here without issues since client memcpy's only what it knows
|
||||||
// Just wastes some bandwidth sending to tit clients /shrug
|
// Just wastes some bandwidth sending to tit clients /shrug
|
||||||
/*0700*/ float fog_density;
|
/*0700*/ float fog_density;
|
||||||
/*0704*/ uint32 suspend_buffs;
|
/*0704*/ uint32 SuspendBuffs;
|
||||||
/*0708*/ uint32 fast_regen_hp;
|
/*0708*/ uint32 FastRegenHP;
|
||||||
/*0712*/ uint32 fast_regen_mana;
|
/*0712*/ uint32 FastRegenMana;
|
||||||
/*0716*/ uint32 fast_regen_endurance;
|
/*0716*/ uint32 FastRegenEndurance;
|
||||||
/*0720*/ uint32 npc_aggro_max_dist;
|
/*0720*/ uint32 NPCAggroMaxDist;
|
||||||
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
|
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
|
||||||
/*0728*/ uint32 lava_damage; // Seen 50
|
/*0728*/ uint32 LavaDamage; // Seen 50
|
||||||
/*0732*/ uint32 min_lava_damage; // Seen 10
|
/*0732*/ uint32 MinLavaDamage; // Seen 10
|
||||||
/*0736*/
|
/*0736*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -448,7 +448,6 @@ struct ManaChange_Struct
|
|||||||
/*08*/ uint32 spell_id;
|
/*08*/ uint32 spell_id;
|
||||||
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
|
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
|
||||||
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
|
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
|
||||||
/*16*/ int32 slot; // -1 normal, otherwise clear ETA and GCD
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwapSpell_Struct
|
struct SwapSpell_Struct
|
||||||
@@ -2192,19 +2191,11 @@ struct QuestReward_Struct
|
|||||||
/*068*/
|
/*068*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CashReward_Struct
|
|
||||||
{
|
|
||||||
/*000*/ uint32 copper;
|
|
||||||
/*004*/ uint32 silver;
|
|
||||||
/*008*/ uint32 gold;
|
|
||||||
/*012*/ uint32 platinum;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Size: 8
|
// Size: 8
|
||||||
struct Camera_Struct
|
struct Camera_Struct
|
||||||
{
|
{
|
||||||
uint32 duration; // Duration in ms
|
uint32 duration; // Duration in ms
|
||||||
float intensity;
|
uint32 intensity; // Between 1023410176 and 1090519040
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZonePoint_Entry {
|
struct ZonePoint_Entry {
|
||||||
@@ -2324,12 +2315,9 @@ struct FaceChange_Struct {
|
|||||||
/*004*/ uint8 hairstyle;
|
/*004*/ uint8 hairstyle;
|
||||||
/*005*/ uint8 beard;
|
/*005*/ uint8 beard;
|
||||||
/*006*/ uint8 face;
|
/*006*/ uint8 face;
|
||||||
/*007*/ uint8 unused_padding;
|
/*007*/ uint32 drakkin_heritage;
|
||||||
/*008*/ uint32 drakkin_heritage;
|
/*011*/ uint32 drakkin_tattoo;
|
||||||
/*012*/ uint32 drakkin_tattoo;
|
/*015*/ uint32 drakkin_details;
|
||||||
/*016*/ uint32 drakkin_details;
|
|
||||||
/*020*/ uint32 entity_id;
|
|
||||||
/*024*/
|
|
||||||
//there are only 10 faces for barbs changing woad just
|
//there are only 10 faces for barbs changing woad just
|
||||||
//increase the face value by ten so if there were 8 woad
|
//increase the face value by ten so if there were 8 woad
|
||||||
//designs then there would be 80 barb faces
|
//designs then there would be 80 barb faces
|
||||||
@@ -2773,7 +2761,7 @@ struct EnvDamage2_Struct {
|
|||||||
/*0004*/ uint16 unknown4;
|
/*0004*/ uint16 unknown4;
|
||||||
/*0006*/ uint32 damage;
|
/*0006*/ uint32 damage;
|
||||||
/*0010*/ uint8 unknown10[12];
|
/*0010*/ uint8 unknown10[12];
|
||||||
/*0022*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
|
/*0022*/ uint8 dmgtype; //FA = Lava; FC = Falling
|
||||||
/*0023*/ uint8 unknown2[4];
|
/*0023*/ uint8 unknown2[4];
|
||||||
/*0027*/ uint16 constant; //Always FFFF
|
/*0027*/ uint16 constant; //Always FFFF
|
||||||
/*0029*/ uint16 unknown29;
|
/*0029*/ uint16 unknown29;
|
||||||
@@ -3637,14 +3625,9 @@ struct MerchantList {
|
|||||||
uint32 item;
|
uint32 item;
|
||||||
int16 faction_required;
|
int16 faction_required;
|
||||||
int8 level_required;
|
int8 level_required;
|
||||||
uint8 min_status;
|
|
||||||
uint8 max_status;
|
|
||||||
uint16 alt_currency_cost;
|
uint16 alt_currency_cost;
|
||||||
uint32 classes_required;
|
uint32 classes_required;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
std::string bucket_name;
|
|
||||||
std::string bucket_value;
|
|
||||||
uint8 bucket_comparison;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TempMerchantList {
|
struct TempMerchantList {
|
||||||
@@ -4547,7 +4530,7 @@ struct ItemVerifyReply_Struct {
|
|||||||
struct ItemRecastDelay_Struct {
|
struct ItemRecastDelay_Struct {
|
||||||
/*000*/ uint32 recast_delay; // in seconds
|
/*000*/ uint32 recast_delay; // in seconds
|
||||||
/*004*/ uint32 recast_type;
|
/*004*/ uint32 recast_type;
|
||||||
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5008,7 +4991,7 @@ struct DynamicZoneCompassEntry_Struct
|
|||||||
/*000*/ uint16 dz_zone_id; // target dz id pair
|
/*000*/ uint16 dz_zone_id; // target dz id pair
|
||||||
/*002*/ uint16 dz_instance_id;
|
/*002*/ uint16 dz_instance_id;
|
||||||
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
|
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
|
||||||
/*008*/ uint32 dz_switch_id;
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/ float y;
|
/*012*/ float y;
|
||||||
/*016*/ float x;
|
/*016*/ float x;
|
||||||
/*020*/ float z;
|
/*020*/ float z;
|
||||||
@@ -5165,10 +5148,10 @@ struct AltCurrencySelectItemReply_Struct {
|
|||||||
/*000*/ uint32 unknown000;
|
/*000*/ uint32 unknown000;
|
||||||
/*004*/ uint8 unknown004; //0xff
|
/*004*/ uint8 unknown004; //0xff
|
||||||
/*005*/ uint8 unknown005; //0xff
|
/*005*/ uint8 unknown005; //0xff
|
||||||
/*006*/ uint16 unknown006; //0xffff
|
/*006*/ uint8 unknown006; //0xff
|
||||||
/*008*/ uint16 unknown008; //0xffff
|
/*007*/ uint8 unknown007; //0xff
|
||||||
/*010*/ char item_name[64];
|
/*008*/ char item_name[64];
|
||||||
/*074*/ uint16 unknown074;
|
/*072*/ uint32 unknown074;
|
||||||
/*076*/ uint32 cost;
|
/*076*/ uint32 cost;
|
||||||
/*080*/ uint32 unknown080;
|
/*080*/ uint32 unknown080;
|
||||||
/*084*/ uint32 unknown084;
|
/*084*/ uint32 unknown084;
|
||||||
@@ -5598,11 +5581,6 @@ struct SayLinkBodyFrame_Struct {
|
|||||||
/*056*/
|
/*056*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Checksum_Struct {
|
|
||||||
uint64 checksum;
|
|
||||||
uint8 data[2048];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct UpdateMovementEntry {
|
struct UpdateMovementEntry {
|
||||||
/* 00 */ float Y;
|
/* 00 */ float Y;
|
||||||
/* 04 */ float X;
|
/* 04 */ float X;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "op_codes.h"
|
#include "op_codes.h"
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|||||||
@@ -243,11 +243,6 @@ class EQStream : public EQStreamInterface {
|
|||||||
|
|
||||||
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
||||||
|
|
||||||
virtual OpcodeManager* GetOpcodeManager() const
|
|
||||||
{
|
|
||||||
return (*OpMgr);
|
|
||||||
};
|
|
||||||
|
|
||||||
void CheckTimeout(uint32 now, uint32 timeout=30);
|
void CheckTimeout(uint32 now, uint32 timeout=30);
|
||||||
bool HasOutgoingData();
|
bool HasOutgoingData();
|
||||||
void Process(const unsigned char *data, const uint32 length);
|
void Process(const unsigned char *data, const uint32 length);
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ public:
|
|||||||
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
||||||
virtual EQStreamState GetState() = 0;
|
virtual EQStreamState GetState() = 0;
|
||||||
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
|
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
|
||||||
virtual OpcodeManager* GetOpcodeManager() const = 0;
|
|
||||||
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
|
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
|
||||||
virtual Stats GetStats() const = 0;
|
virtual Stats GetStats() const = 0;
|
||||||
virtual void ResetStats() = 0;
|
virtual void ResetStats() = 0;
|
||||||
|
|||||||
@@ -38,8 +38,12 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||||
if (p == nullptr) {
|
if(p == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (p->GetOpcode() != OP_SpecialMesg) {
|
||||||
|
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||||
|
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
EQApplicationPacket *newp = p->Copy();
|
EQApplicationPacket *newp = p->Copy();
|
||||||
@@ -108,8 +112,3 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
|
|
||||||
{
|
|
||||||
return (*m_opcodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,15 +34,13 @@ public:
|
|||||||
virtual Stats GetStats() const;
|
virtual Stats GetStats() const;
|
||||||
virtual void ResetStats();
|
virtual void ResetStats();
|
||||||
virtual EQStreamManagerInterface* GetManager() const;
|
virtual EQStreamManagerInterface* GetManager() const;
|
||||||
virtual OpcodeManager* GetOpcodeManager() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
||||||
const StructStrategy *const m_structs; //we do not own this object.
|
const StructStrategy *const m_structs; //we do not own this object.
|
||||||
//this is a pointer to a pointer to make it less likely that a packet will
|
//this is a pointer to a pointer to make it less likely that a packet will
|
||||||
//reference an invalid opcode manager when they are being reloaded.
|
//reference an invalid opcode manager when they are being reloaded.
|
||||||
OpcodeManager **const m_opcodes;
|
OpcodeManager **const m_opcodes; //we do not own this object.
|
||||||
//we do not own this object.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*EQSTREAMPROXY_H_*/
|
#endif /*EQSTREAMPROXY_H_*/
|
||||||
|
|||||||
@@ -100,10 +100,6 @@ void EQEmuConfig::parse_config()
|
|||||||
WorldHTTPEnabled = true;
|
WorldHTTPEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_root["server"].get("disable_config_checks", "false").asString() == "true") {
|
|
||||||
DisableConfigChecks = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UCS
|
* UCS
|
||||||
*/
|
*/
|
||||||
|
|||||||
+5
-16
@@ -20,9 +20,7 @@
|
|||||||
|
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
#include "linked_list.h"
|
#include "linked_list.h"
|
||||||
#include "path_manager.h"
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
struct LoginConfig {
|
struct LoginConfig {
|
||||||
std::string LoginHost;
|
std::string LoginHost;
|
||||||
@@ -60,7 +58,6 @@ class EQEmuConfig
|
|||||||
uint16 WorldHTTPPort;
|
uint16 WorldHTTPPort;
|
||||||
std::string WorldHTTPMimeFile;
|
std::string WorldHTTPMimeFile;
|
||||||
std::string SharedKey;
|
std::string SharedKey;
|
||||||
bool DisableConfigChecks;
|
|
||||||
|
|
||||||
// From <chatserver/>
|
// From <chatserver/>
|
||||||
std::string ChatHost;
|
std::string ChatHost;
|
||||||
@@ -154,31 +151,23 @@ class EQEmuConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load the config
|
// Load the config
|
||||||
static bool LoadConfig(const std::string& path = "")
|
static bool LoadConfig()
|
||||||
{
|
{
|
||||||
if (_config != nullptr) {
|
if (_config != nullptr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_config = new EQEmuConfig;
|
_config = new EQEmuConfig;
|
||||||
|
|
||||||
return parseFile(path);
|
return parseFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load config file and parse data
|
// Load config file and parse data
|
||||||
static bool parseFile(const std::string& file_path = ".")
|
static bool parseFile() {
|
||||||
{
|
|
||||||
if (_config == nullptr) {
|
if (_config == nullptr) {
|
||||||
return LoadConfig(file_path);
|
return LoadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string file = fmt::format(
|
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
|
||||||
"{}/{}",
|
|
||||||
(file_path.empty() ? path.GetServerPath() : file_path),
|
|
||||||
EQEmuConfig::ConfigFile
|
|
||||||
);
|
|
||||||
|
|
||||||
std::ifstream fconfig(file, std::ifstream::binary);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fconfig >> _config->_root;
|
fconfig >> _config->_root;
|
||||||
_config->parse_config();
|
_config->parse_config();
|
||||||
|
|||||||
+294
-354
@@ -21,20 +21,20 @@
|
|||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
#include "repositories/discord_webhooks_repository.h"
|
#include "misc.h"
|
||||||
#include "repositories/logsys_categories_repository.h"
|
#include "repositories/logsys_categories_repository.h"
|
||||||
#include "termcolor/rang.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iomanip>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
std::ofstream process_log;
|
std::ofstream process_log;
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
@@ -46,17 +46,50 @@ std::ofstream process_log;
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linux ANSI console color defines
|
||||||
|
*/
|
||||||
|
#define LC_RESET "\033[0m"
|
||||||
|
#define LC_BLACK "\033[30m" /* Black */
|
||||||
|
#define LC_RED "\033[31m" /* Red */
|
||||||
|
#define LC_GREEN "\033[32m" /* Green */
|
||||||
|
#define LC_YELLOW "\033[33m" /* Yellow */
|
||||||
|
#define LC_BLUE "\033[34m" /* Blue */
|
||||||
|
#define LC_MAGENTA "\033[35m" /* Magenta */
|
||||||
|
#define LC_CYAN "\033[36m" /* Cyan */
|
||||||
|
#define LC_WHITE "\033[37m" /* White */
|
||||||
|
|
||||||
|
namespace Console {
|
||||||
|
enum Color {
|
||||||
|
Black = 0,
|
||||||
|
Blue = 1,
|
||||||
|
Green = 2,
|
||||||
|
Cyan = 3,
|
||||||
|
Red = 4,
|
||||||
|
Magenta = 5,
|
||||||
|
Brown = 6,
|
||||||
|
LightGray = 7,
|
||||||
|
DarkGray = 8,
|
||||||
|
LightBlue = 9,
|
||||||
|
LightGreen = 10,
|
||||||
|
LightCyan = 11,
|
||||||
|
LightRed = 12,
|
||||||
|
LightMagenta = 13,
|
||||||
|
Yellow = 14,
|
||||||
|
White = 15
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EQEmuLogSys Constructor
|
* EQEmuLogSys Constructor
|
||||||
*/
|
*/
|
||||||
EQEmuLogSys::EQEmuLogSys()
|
EQEmuLogSys::EQEmuLogSys()
|
||||||
{
|
{
|
||||||
m_on_log_gmsay_hook = [](uint16 log_type, const char *func, const std::string &) {};
|
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
|
||||||
m_on_log_console_hook = [](uint16 log_type, const std::string &) {};
|
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,23 +102,28 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
/**
|
/**
|
||||||
* Get Executable platform currently running this code (Zone/World/etc)
|
* Get Executable platform currently running this code (Zone/World/etc)
|
||||||
*/
|
*/
|
||||||
m_log_platform = GetExecutablePlatformInt();
|
log_platform = GetExecutablePlatformInt();
|
||||||
|
|
||||||
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
|
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
|
||||||
log_settings[log_category_id].log_to_console = 0;
|
log_settings[log_category_id].log_to_console = 0;
|
||||||
log_settings[log_category_id].log_to_file = 0;
|
log_settings[log_category_id].log_to_file = 0;
|
||||||
log_settings[log_category_id].log_to_gmsay = 0;
|
log_settings[log_category_id].log_to_gmsay = 0;
|
||||||
log_settings[log_category_id].log_to_discord = 0;
|
|
||||||
log_settings[log_category_id].is_category_enabled = 0;
|
log_settings[log_category_id].is_category_enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_file_logs_enabled = false;
|
file_logs_enabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Defaults
|
* Set Defaults
|
||||||
*/
|
*/
|
||||||
|
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HotReload].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HotReload].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
@@ -94,18 +132,16 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Cheat].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HTTP].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::HTTP].log_to_gmsay = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::ChecksumVerification].log_to_console = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::ChecksumVerification].log_to_gmsay = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::CombatRecord].log_to_gmsay = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::Discord].log_to_console = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::QuestErrors].log_to_gmsay = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::QuestErrors].log_to_console = static_cast<uint8>(Logs::General);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RFC 5424
|
* RFC 5424
|
||||||
*/
|
*/
|
||||||
|
log_settings[Logs::Emergency].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::Alert].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::Critical].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
log_settings[Logs::Notice].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,8 +151,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
const bool log_to_console = log_settings[log_category_id].log_to_console > 0;
|
const bool log_to_console = log_settings[log_category_id].log_to_console > 0;
|
||||||
const bool log_to_file = log_settings[log_category_id].log_to_file > 0;
|
const bool log_to_file = log_settings[log_category_id].log_to_file > 0;
|
||||||
const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0;
|
const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0;
|
||||||
const bool log_to_discord = log_settings[log_category_id].log_to_discord > 0;
|
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
|
||||||
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
|
|
||||||
if (is_category_enabled) {
|
if (is_category_enabled) {
|
||||||
log_settings[log_category_id].is_category_enabled = 1;
|
log_settings[log_category_id].is_category_enabled = 1;
|
||||||
}
|
}
|
||||||
@@ -125,37 +160,99 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
/**
|
/**
|
||||||
* Declare process file names for log writing=
|
* Declare process file names for log writing=
|
||||||
*/
|
*/
|
||||||
if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld) {
|
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) {
|
||||||
m_platform_file_name = "world";
|
platform_file_name = "world";
|
||||||
}
|
}
|
||||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
|
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) {
|
||||||
m_platform_file_name = "query_server";
|
platform_file_name = "query_server";
|
||||||
}
|
}
|
||||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) {
|
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
|
||||||
m_platform_file_name = "zone";
|
platform_file_name = "zone";
|
||||||
}
|
}
|
||||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformUCS) {
|
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) {
|
||||||
m_platform_file_name = "ucs";
|
platform_file_name = "ucs";
|
||||||
}
|
}
|
||||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLogin) {
|
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) {
|
||||||
m_platform_file_name = "login";
|
platform_file_name = "login";
|
||||||
}
|
}
|
||||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLaunch) {
|
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) {
|
||||||
m_platform_file_name = "launcher";
|
platform_file_name = "launcher";
|
||||||
}
|
}
|
||||||
else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformHC) {
|
else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) {
|
||||||
m_platform_file_name = "hc";
|
platform_file_name = "hc";
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param log_category
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
log_category == Logs::Emergency ||
|
||||||
|
log_category == Logs::Alert ||
|
||||||
|
log_category == Logs::Critical ||
|
||||||
|
log_category == Logs::Error ||
|
||||||
|
log_category == Logs::Warning ||
|
||||||
|
log_category == Logs::Notice ||
|
||||||
|
log_category == Logs::Info ||
|
||||||
|
log_category == Logs::Debug
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param log_category
|
||||||
|
* @param in_message
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string EQEmuLogSys::FormatOutMessageString(
|
||||||
|
uint16 log_category,
|
||||||
|
const std::string &in_message
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string return_string = "[" + GetPlatformName() + "] ";
|
||||||
|
|
||||||
|
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param debug_level
|
||||||
|
* @param log_category
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void EQEmuLogSys::ProcessGMSay(
|
||||||
|
uint16 debug_level,
|
||||||
|
uint16 log_category,
|
||||||
|
const std::string &message
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
|
||||||
|
*/
|
||||||
|
if (log_category == Logs::LogCategory::Netcode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes that actually support hooks
|
||||||
|
*/
|
||||||
|
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||||
|
EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld
|
||||||
|
) {
|
||||||
|
on_log_gmsay_hook(log_category, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param debug_level
|
* @param debug_level
|
||||||
* @param log_category
|
* @param log_category
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
void EQEmuLogSys::ProcessLogWrite(
|
void EQEmuLogSys::ProcessLogWrite(
|
||||||
|
uint16 debug_level,
|
||||||
uint16 log_category,
|
uint16 log_category,
|
||||||
const std::string &message
|
const std::string &message
|
||||||
)
|
)
|
||||||
@@ -166,20 +263,79 @@ void EQEmuLogSys::ProcessLogWrite(
|
|||||||
std::ofstream crash_log;
|
std::ofstream crash_log;
|
||||||
EQEmuLogSys::MakeDirectory("logs/crashes");
|
EQEmuLogSys::MakeDirectory("logs/crashes");
|
||||||
crash_log.open(
|
crash_log.open(
|
||||||
StringFormat("logs/crashes/crash_%s_%i.log", m_platform_file_name.c_str(), getpid()),
|
StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()),
|
||||||
std::ios_base::app | std::ios_base::out
|
std::ios_base::app | std::ios_base::out
|
||||||
);
|
);
|
||||||
crash_log << time_stamp << " " << message << "\n";
|
crash_log << time_stamp << " " << message << "\n";
|
||||||
crash_log.close();
|
crash_log.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process_log) {
|
|
||||||
char time_stamp[80];
|
char time_stamp[80];
|
||||||
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
|
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
|
||||||
|
|
||||||
|
if (process_log) {
|
||||||
process_log << time_stamp << " " << message << std::endl;
|
process_log << time_stamp << " " << message << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param log_category
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category)
|
||||||
|
{
|
||||||
|
switch (log_category) {
|
||||||
|
case Logs::Status:
|
||||||
|
case Logs::Normal:
|
||||||
|
return Console::Color::Yellow;
|
||||||
|
case Logs::MySQLError:
|
||||||
|
case Logs::Error:
|
||||||
|
return Console::Color::LightRed;
|
||||||
|
case Logs::MySQLQuery:
|
||||||
|
case Logs::Debug:
|
||||||
|
return Console::Color::LightGreen;
|
||||||
|
case Logs::Quests:
|
||||||
|
return Console::Color::LightCyan;
|
||||||
|
case Logs::Commands:
|
||||||
|
case Logs::Mercenaries:
|
||||||
|
return Console::Color::LightMagenta;
|
||||||
|
case Logs::Crash:
|
||||||
|
return Console::Color::LightRed;
|
||||||
|
default:
|
||||||
|
return Console::Color::Yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param log_category
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
|
||||||
|
{
|
||||||
|
switch (log_category) {
|
||||||
|
case Logs::Status:
|
||||||
|
case Logs::Normal:
|
||||||
|
return LC_YELLOW;
|
||||||
|
case Logs::MySQLError:
|
||||||
|
case Logs::Warning:
|
||||||
|
case Logs::Critical:
|
||||||
|
case Logs::Error:
|
||||||
|
return LC_RED;
|
||||||
|
case Logs::MySQLQuery:
|
||||||
|
case Logs::Debug:
|
||||||
|
return LC_GREEN;
|
||||||
|
case Logs::Quests:
|
||||||
|
return LC_CYAN;
|
||||||
|
case Logs::Commands:
|
||||||
|
case Logs::Mercenaries:
|
||||||
|
return LC_MAGENTA;
|
||||||
|
case Logs::Crash:
|
||||||
|
return LC_RED;
|
||||||
|
default:
|
||||||
|
return LC_YELLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param log_category
|
* @param log_category
|
||||||
* @return
|
* @return
|
||||||
@@ -187,8 +343,10 @@ void EQEmuLogSys::ProcessLogWrite(
|
|||||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
||||||
{
|
{
|
||||||
switch (log_category) {
|
switch (log_category) {
|
||||||
|
case Logs::Status:
|
||||||
|
case Logs::Normal:
|
||||||
|
return Chat::Yellow;
|
||||||
case Logs::MySQLError:
|
case Logs::MySQLError:
|
||||||
case Logs::QuestErrors:
|
|
||||||
case Logs::Error:
|
case Logs::Error:
|
||||||
return Chat::Red;
|
return Chat::Red;
|
||||||
case Logs::MySQLQuery:
|
case Logs::MySQLQuery:
|
||||||
@@ -206,146 +364,30 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param debug_level
|
* @param debug_level
|
||||||
* @param log_category
|
* @param log_category
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
void EQEmuLogSys::ProcessConsoleMessage(
|
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||||
uint16 log_category,
|
|
||||||
const std::string &message,
|
|
||||||
const char *file,
|
|
||||||
const char *func,
|
|
||||||
int line
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
bool is_error = (
|
#ifdef _WINDOWS
|
||||||
log_category == Logs::LogCategory::Error ||
|
HANDLE console_handle;
|
||||||
log_category == Logs::LogCategory::MySQLError ||
|
console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
log_category == Logs::LogCategory::Crash ||
|
CONSOLE_FONT_INFOEX info = { 0 };
|
||||||
log_category == Logs::LogCategory::QuestErrors
|
info.cbSize = sizeof(info);
|
||||||
);
|
info.dwFontSize.Y = 12; // leave X as zero
|
||||||
bool is_warning = (
|
info.FontWeight = FW_NORMAL;
|
||||||
log_category == Logs::LogCategory::Warning
|
wcscpy(info.FaceName, L"Lucida Console");
|
||||||
);
|
SetCurrentConsoleFontEx(console_handle, NULL, &info);
|
||||||
|
SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category));
|
||||||
|
std::cout << message << "\n";
|
||||||
|
SetConsoleTextAttribute(console_handle, Console::Color::White);
|
||||||
|
#else
|
||||||
|
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
on_log_console_hook(debug_level, log_category, message);
|
||||||
<< ""
|
|
||||||
<< rang::fgB::black
|
|
||||||
<< rang::style::bold
|
|
||||||
<< fmt::format("{:>6}", GetPlatformName().substr(0, 6))
|
|
||||||
<< rang::style::reset
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< " | "
|
|
||||||
<< ((is_error || is_warning) ? rang::fgB::red : rang::fgB::gray)
|
|
||||||
<< rang::style::bold
|
|
||||||
<< fmt::format("{:^10}", fmt::format("{}", Logs::LogCategoryName[log_category]).substr(0, 10))
|
|
||||||
<< rang::style::reset
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< " | "
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< rang::style::bold
|
|
||||||
<< fmt::format("{}", func)
|
|
||||||
<< rang::style::reset
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< " ";
|
|
||||||
|
|
||||||
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<< ""
|
|
||||||
<< rang::fgB::green
|
|
||||||
<< rang::style::bold
|
|
||||||
<< fmt::format("{:}", fmt::format("{}:{}:{}", std::filesystem::path(file).filename().string(), func, line))
|
|
||||||
<< rang::style::reset
|
|
||||||
<< " | ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_category == Logs::LogCategory::MySQLQuery) {
|
|
||||||
auto s = Strings::Split(message, "--");
|
|
||||||
if (s.size() > 1) {
|
|
||||||
std::string query = Strings::Trim(s[0]);
|
|
||||||
std::string meta = Strings::Trim(s[1]);
|
|
||||||
|
|
||||||
std::cout <<
|
|
||||||
rang::fgB::green
|
|
||||||
<<
|
|
||||||
query
|
|
||||||
<<
|
|
||||||
rang::style::reset;
|
|
||||||
|
|
||||||
std::cout <<
|
|
||||||
rang::fgB::black
|
|
||||||
<<
|
|
||||||
" -- "
|
|
||||||
<<
|
|
||||||
meta
|
|
||||||
<<
|
|
||||||
rang::style::reset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Strings::Contains(message, "[")) {
|
|
||||||
for (auto &e: Strings::Split(message, " ")) {
|
|
||||||
if (Strings::Contains(e, "[") && Strings::Contains(e, "]")) {
|
|
||||||
e = Strings::Replace(e, "[", "");
|
|
||||||
e = Strings::Replace(e, "]", "");
|
|
||||||
|
|
||||||
bool is_upper = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < strlen(e.c_str()); i++) {
|
|
||||||
if (isupper(e[i])) {
|
|
||||||
is_upper = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_upper) {
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< "["
|
|
||||||
<< rang::style::bold
|
|
||||||
<< rang::fgB::yellow
|
|
||||||
<< e
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< "] "
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<< (is_error ? rang::fgB::red : rang::fgB::gray)
|
|
||||||
<< e
|
|
||||||
<< " ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<< (is_error ? rang::fgB::red : rang::fgB::gray)
|
|
||||||
<< message
|
|
||||||
<< " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!origination_info.zone_short_name.empty()) {
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<<
|
|
||||||
rang::fgB::black
|
|
||||||
<<
|
|
||||||
"-- "
|
|
||||||
<<
|
|
||||||
fmt::format(
|
|
||||||
"[{}] ({}) inst_id [{}]",
|
|
||||||
origination_info.zone_short_name,
|
|
||||||
origination_info.zone_long_name,
|
|
||||||
origination_info.instance_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
(!is_error ? std::cout : std::cerr) << rang::style::reset << std::endl;
|
|
||||||
|
|
||||||
m_on_log_console_hook(log_category, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -357,6 +399,33 @@ constexpr const char *str_end(const char *str)
|
|||||||
return *str ? str_end(str + 1) : str;
|
return *str ? str_end(str + 1) : str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param str
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
constexpr bool str_slant(const char *str)
|
||||||
|
{
|
||||||
|
return *str == '/' ? true : (*str ? str_slant(str + 1) : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param str
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
constexpr const char *r_slant(const char *str)
|
||||||
|
{
|
||||||
|
return *str == '/' ? (str + 1) : r_slant(str - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param str
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
constexpr const char *base_file_name(const char *str)
|
||||||
|
{
|
||||||
|
return str_slant(str) ? r_slant(str_end(str)) : str;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core logging function
|
* Core logging function
|
||||||
*
|
*
|
||||||
@@ -375,55 +444,47 @@ void EQEmuLogSys::Out(
|
|||||||
...
|
...
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto l = GetLogsEnabled(debug_level, log_category);
|
bool log_to_console = true;
|
||||||
|
if (log_settings[log_category].log_to_console < debug_level) {
|
||||||
|
log_to_console = false;
|
||||||
|
}
|
||||||
|
|
||||||
// bail out if nothing to log
|
bool log_to_file = true;
|
||||||
if (!l.log_enabled) {
|
if (log_settings[log_category].log_to_file < debug_level) {
|
||||||
|
log_to_file = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool log_to_gmsay = true;
|
||||||
|
if (log_settings[log_category].log_to_gmsay < debug_level) {
|
||||||
|
log_to_gmsay = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
|
||||||
|
if (nothing_to_log) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string prefix;
|
std::string prefix;
|
||||||
|
|
||||||
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
||||||
prefix = fmt::format("[{0}::{1}:{2}] ", std::filesystem::path(file).filename().string(), func, line);
|
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove this when we remove all legacy logs
|
|
||||||
bool ignore_log_legacy_format = (
|
|
||||||
log_category == Logs::Netcode ||
|
|
||||||
log_category == Logs::PacketServerClient ||
|
|
||||||
log_category == Logs::PacketClientServer ||
|
|
||||||
log_category == Logs::PacketServerToServer
|
|
||||||
);
|
|
||||||
|
|
||||||
// remove this when we remove all legacy logs
|
|
||||||
std::string output_message = message;
|
|
||||||
if (!ignore_log_legacy_format) {
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, message);
|
va_start(args, message);
|
||||||
output_message = vStringFormat(message, args);
|
std::string output_message = vStringFormat(message, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
|
||||||
|
|
||||||
if (l.log_to_console_enabled) {
|
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
|
||||||
EQEmuLogSys::ProcessConsoleMessage(
|
|
||||||
log_category,
|
if (log_to_console) {
|
||||||
output_message,
|
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
|
||||||
file,
|
|
||||||
func,
|
|
||||||
line
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (l.log_to_gmsay_enabled) {
|
if (log_to_gmsay) {
|
||||||
m_on_log_gmsay_hook(log_category, func, output_message);
|
EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message);
|
||||||
}
|
}
|
||||||
if (l.log_to_file_enabled) {
|
if (log_to_file) {
|
||||||
EQEmuLogSys::ProcessLogWrite(
|
EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message);
|
||||||
log_category,
|
|
||||||
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (l.log_to_discord_enabled && m_on_log_discord_hook) {
|
|
||||||
m_on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,7 +497,7 @@ void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
|
|||||||
struct tm *time_info;
|
struct tm *time_info;
|
||||||
time(&raw_time);
|
time(&raw_time);
|
||||||
time_info = localtime(&raw_time);
|
time_info = localtime(&raw_time);
|
||||||
strftime(time_stamp, 80, "[%m-%d-%Y %H:%M:%S]", time_info);
|
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -475,45 +536,53 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
/**
|
/**
|
||||||
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
|
* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one...
|
||||||
*/
|
*/
|
||||||
if (!m_file_logs_enabled) {
|
if (!file_logs_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zone
|
* Zone
|
||||||
*/
|
*/
|
||||||
if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) {
|
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) {
|
||||||
if (!log_name.empty()) {
|
if (!log_name.empty()) {
|
||||||
m_platform_file_name = log_name;
|
platform_file_name = log_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_platform_file_name.empty()) {
|
if (platform_file_name.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Starting File Log [{}/zone/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
|
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
|
||||||
|
|
||||||
// Make directory if not exists
|
/**
|
||||||
EQEmuLogSys::MakeDirectory(fmt::format("{}/zone", GetLogPath()));
|
* Make directory if not exists
|
||||||
|
*/
|
||||||
|
EQEmuLogSys::MakeDirectory("logs/zone");
|
||||||
|
|
||||||
// Open file pointer
|
/**
|
||||||
|
* Open file pointer
|
||||||
|
*/
|
||||||
process_log.open(
|
process_log.open(
|
||||||
fmt::format("{}/zone/{}_{}.log", GetLogPath(), m_platform_file_name, getpid()),
|
StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()),
|
||||||
std::ios_base::app | std::ios_base::out
|
std::ios_base::app | std::ios_base::out
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// All other processes
|
/**
|
||||||
if (m_platform_file_name.empty()) {
|
* All other processes
|
||||||
|
*/
|
||||||
|
if (platform_file_name.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Starting File Log [{}/{}_{}.log]", GetLogPath(), m_platform_file_name.c_str(), getpid());
|
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
|
||||||
|
|
||||||
// Open file pointer
|
/**
|
||||||
|
* Open file pointer
|
||||||
|
*/
|
||||||
process_log.open(
|
process_log.open(
|
||||||
fmt::format("{}/{}_{}.log", GetLogPath(), m_platform_file_name.c_str(), getpid()),
|
StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()),
|
||||||
std::ios_base::app | std::ios_base::out
|
std::ios_base::app | std::ios_base::out
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -528,8 +597,6 @@ void EQEmuLogSys::SilenceConsoleLogging()
|
|||||||
log_settings[log_index].log_to_console = 0;
|
log_settings[log_index].log_to_console = 0;
|
||||||
log_settings[log_index].is_category_enabled = 0;
|
log_settings[log_index].is_category_enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -545,8 +612,6 @@ void EQEmuLogSys::EnableConsoleLogging()
|
|||||||
|
|
||||||
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||||
{
|
{
|
||||||
InjectTablesIfNotExist();
|
|
||||||
|
|
||||||
auto categories = LogsysCategoriesRepository::GetWhere(
|
auto categories = LogsysCategoriesRepository::GetWhere(
|
||||||
*m_database,
|
*m_database,
|
||||||
"TRUE ORDER BY log_category_id"
|
"TRUE ORDER BY log_category_id"
|
||||||
@@ -565,17 +630,13 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
|
log_settings[c.log_category_id].log_to_console = static_cast<uint8>(c.log_to_console);
|
||||||
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
|
log_settings[c.log_category_id].log_to_file = static_cast<uint8>(c.log_to_file);
|
||||||
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
|
log_settings[c.log_category_id].log_to_gmsay = static_cast<uint8>(c.log_to_gmsay);
|
||||||
log_settings[c.log_category_id].log_to_discord = static_cast<uint8>(c.log_to_discord);
|
|
||||||
log_settings[c.log_category_id].discord_webhook_id = c.discord_webhook_id;
|
|
||||||
|
|
||||||
// Determine if any output method is enabled for the category
|
// Determine if any output method is enabled for the category
|
||||||
// and set it to 1 so it can used to check if category is enabled
|
// and set it to 1 so it can used to check if category is enabled
|
||||||
const bool log_to_console = log_settings[c.log_category_id].log_to_console > 0;
|
const bool log_to_console = log_settings[c.log_category_id].log_to_console > 0;
|
||||||
const bool log_to_file = log_settings[c.log_category_id].log_to_file > 0;
|
const bool log_to_file = log_settings[c.log_category_id].log_to_file > 0;
|
||||||
const bool log_to_gmsay = log_settings[c.log_category_id].log_to_gmsay > 0;
|
const bool log_to_gmsay = log_settings[c.log_category_id].log_to_gmsay > 0;
|
||||||
const bool log_to_discord = log_settings[c.log_category_id].log_to_discord > 0 &&
|
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay;
|
||||||
log_settings[c.log_category_id].discord_webhook_id > 0;
|
|
||||||
const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay || log_to_discord;
|
|
||||||
|
|
||||||
if (is_category_enabled) {
|
if (is_category_enabled) {
|
||||||
log_settings[c.log_category_id].is_category_enabled = 1;
|
log_settings[c.log_category_id].is_category_enabled = 1;
|
||||||
@@ -585,7 +646,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
// If we go through this whole loop and nothing is set to any debug level, there
|
// If we go through this whole loop and nothing is set to any debug level, there
|
||||||
// is no point to create a file or keep anything open
|
// is no point to create a file or keep anything open
|
||||||
if (log_settings[c.log_category_id].log_to_file > 0) {
|
if (log_settings[c.log_category_id].log_to_file > 0) {
|
||||||
LogSys.m_file_logs_enabled = true;
|
LogSys.file_logs_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
db_categories.emplace_back(c.log_category_id);
|
db_categories.emplace_back(c.log_category_id);
|
||||||
@@ -593,32 +654,18 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
|
|
||||||
// Auto inject categories that don't exist in the database...
|
// Auto inject categories that don't exist in the database...
|
||||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||||
|
if (std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end()) {
|
||||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
|
||||||
bool is_deprecated_category = Strings::Contains(fmt::format("{}", Logs::LogCategoryName[i]), "Deprecated");
|
|
||||||
if (!is_missing_in_database && is_deprecated_category) {
|
|
||||||
LogInfo(
|
LogInfo(
|
||||||
"Logging category [{}] ({}) is now deprecated, deleting from database",
|
"Automatically adding new log category [{0}]",
|
||||||
Logs::LogCategoryName[i],
|
Logs::LogCategoryName[i]
|
||||||
i
|
|
||||||
);
|
|
||||||
LogsysCategoriesRepository::DeleteOne(*m_database, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_missing_in_database && !is_deprecated_category) {
|
|
||||||
LogInfo(
|
|
||||||
"Automatically adding new log category [{}] ({})",
|
|
||||||
Logs::LogCategoryName[i],
|
|
||||||
i
|
|
||||||
);
|
);
|
||||||
|
|
||||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||||
new_category.log_category_id = i;
|
new_category.log_category_id = i;
|
||||||
new_category.log_category_description = Strings::Escape(Logs::LogCategoryName[i]);
|
new_category.log_category_description = EscapeString(Logs::LogCategoryName[i]);
|
||||||
new_category.log_to_console = log_settings[i].log_to_console;
|
new_category.log_to_console = log_settings[i].log_to_console;
|
||||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
||||||
new_category.log_to_file = log_settings[i].log_to_file;
|
new_category.log_to_file = log_settings[i].log_to_file;
|
||||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
|
||||||
|
|
||||||
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
|
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
|
||||||
}
|
}
|
||||||
@@ -626,19 +673,6 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
|
|
||||||
LogInfo("Loaded [{}] log categories", categories.size());
|
LogInfo("Loaded [{}] log categories", categories.size());
|
||||||
|
|
||||||
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
|
||||||
if (!webhooks.empty()) {
|
|
||||||
for (auto &w: webhooks) {
|
|
||||||
m_discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url};
|
|
||||||
}
|
|
||||||
LogInfo("Loaded [{}] Discord webhooks", webhooks.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// force override this setting
|
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::Crash].log_to_gmsay = static_cast<uint8>(Logs::General);
|
|
||||||
log_settings[Logs::Crash].log_to_file = static_cast<uint8>(Logs::General);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,97 +682,3 @@ EQEmuLogSys *EQEmuLogSys::SetDatabase(Database *db)
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQEmuLogSys::InjectTablesIfNotExist()
|
|
||||||
{
|
|
||||||
// do not run injections for zone as its unnecessary hits every time a zone boots
|
|
||||||
// other processes less frequently ran can pick up injection
|
|
||||||
if (m_log_platform == EQEmuExePlatform::ExePlatformZone) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// inject discord_webhooks
|
|
||||||
if (!m_database->DoesTableExist("discord_webhooks")) {
|
|
||||||
LogInfo("Creating table [discord_webhooks]");
|
|
||||||
m_database->QueryDatabase(
|
|
||||||
SQL(
|
|
||||||
CREATE TABLE discord_webhooks
|
|
||||||
(
|
|
||||||
id INT auto_increment primary key NULL,
|
|
||||||
webhook_name varchar(100) NULL,
|
|
||||||
webhook_url varchar(255) NULL,
|
|
||||||
created_at DATETIME NULL,
|
|
||||||
deleted_at DATETIME NULL
|
|
||||||
) ENGINE=InnoDB
|
|
||||||
DEFAULT CHARSET=utf8mb4
|
|
||||||
COLLATE=utf8mb4_general_ci;
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// inject logsys_categories
|
|
||||||
if (!m_database->DoesTableExist("logsys_categories")) {
|
|
||||||
LogInfo("Creating table [logsys_categories]");
|
|
||||||
m_database->QueryDatabase(
|
|
||||||
SQL(
|
|
||||||
CREATE TABLE `logsys_categories` (
|
|
||||||
`log_category_id` int(11) NOT NULL,
|
|
||||||
`log_category_description` varchar(150) DEFAULT NULL,
|
|
||||||
`log_to_console` smallint(11) DEFAULT 0,
|
|
||||||
`log_to_file` smallint(11) DEFAULT 0,
|
|
||||||
`log_to_gmsay` smallint(11) DEFAULT 0,
|
|
||||||
`log_to_discord` smallint(11) DEFAULT 0,
|
|
||||||
`discord_webhook_id` int(11) DEFAULT 0,
|
|
||||||
PRIMARY KEY (`log_category_id`)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const EQEmuLogSys::DiscordWebhooks *EQEmuLogSys::GetDiscordWebhooks() const
|
|
||||||
{
|
|
||||||
return m_discord_webhooks;
|
|
||||||
}
|
|
||||||
|
|
||||||
EQEmuLogSys::LogEnabled EQEmuLogSys::GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
|
||||||
{
|
|
||||||
auto e = LogEnabled{};
|
|
||||||
|
|
||||||
e.log_to_console_enabled = log_settings[log_category].log_to_console > 0 &&
|
|
||||||
log_settings[log_category].log_to_console >= debug_level;
|
|
||||||
e.log_to_file_enabled = log_settings[log_category].log_to_file > 0 &&
|
|
||||||
log_settings[log_category].log_to_file >= debug_level;
|
|
||||||
e.log_to_gmsay_enabled = log_settings[log_category].log_to_gmsay > 0 &&
|
|
||||||
log_settings[log_category].log_to_gmsay >= debug_level &&
|
|
||||||
log_category != Logs::LogCategory::Netcode &&
|
|
||||||
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
|
|
||||||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
|
|
||||||
e.log_to_discord_enabled = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
|
|
||||||
log_settings[log_category].log_to_discord > 0 &&
|
|
||||||
log_settings[log_category].log_to_discord >= debug_level &&
|
|
||||||
log_settings[log_category].discord_webhook_id > 0 &&
|
|
||||||
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
|
|
||||||
e.log_enabled =
|
|
||||||
e.log_to_console_enabled || e.log_to_file_enabled || e.log_to_gmsay_enabled || e.log_to_discord_enabled;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQEmuLogSys::IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
|
||||||
{
|
|
||||||
return GetLogsEnabled(debug_level, log_category).log_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &EQEmuLogSys::GetLogPath() const
|
|
||||||
{
|
|
||||||
return m_log_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
|
|
||||||
{
|
|
||||||
EQEmuLogSys::m_log_path = log_path;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+62
-123
@@ -39,7 +39,8 @@
|
|||||||
namespace Logs {
|
namespace Logs {
|
||||||
enum DebugLevel {
|
enum DebugLevel {
|
||||||
General = 1, // 1 - Low-Level general debugging, useful info on single line
|
General = 1, // 1 - Low-Level general debugging, useful info on single line
|
||||||
Detail // 2 - Use this for very chatty logging you want to leave in but don't want on by default
|
Moderate, // 2 - Informational based, used in functions, when particular things load
|
||||||
|
Detail // 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +54,7 @@ namespace Logs {
|
|||||||
AI,
|
AI,
|
||||||
Aggro,
|
Aggro,
|
||||||
Attack,
|
Attack,
|
||||||
DeprecatedCS, // deprecated
|
PacketClientServer,
|
||||||
Combat,
|
Combat,
|
||||||
Commands,
|
Commands,
|
||||||
Crash,
|
Crash,
|
||||||
@@ -64,36 +65,36 @@ namespace Logs {
|
|||||||
Inventory,
|
Inventory,
|
||||||
Launcher,
|
Launcher,
|
||||||
Netcode,
|
Netcode,
|
||||||
Normal, // deprecated
|
Normal,
|
||||||
Object,
|
Object,
|
||||||
Pathing,
|
Pathing,
|
||||||
QSServer, // deprecated
|
QSServer,
|
||||||
Quests,
|
Quests,
|
||||||
Rules,
|
Rules,
|
||||||
Skills,
|
Skills,
|
||||||
Spawns,
|
Spawns,
|
||||||
Spells,
|
Spells,
|
||||||
Status, // deprecated
|
Status,
|
||||||
TCPConnection,
|
TCPConnection,
|
||||||
Tasks,
|
Tasks,
|
||||||
Tradeskills,
|
Tradeskills,
|
||||||
Trading,
|
Trading,
|
||||||
Tribute,
|
Tribute,
|
||||||
UCSServer, // deprecated
|
UCSServer,
|
||||||
WebInterfaceServer, // deprecated
|
WebInterfaceServer,
|
||||||
WorldServer, // deprecated
|
WorldServer,
|
||||||
ZoneServer, // deprecated
|
ZoneServer,
|
||||||
MySQLError,
|
MySQLError,
|
||||||
MySQLQuery,
|
MySQLQuery,
|
||||||
Mercenaries,
|
Mercenaries,
|
||||||
QuestDebug,
|
QuestDebug,
|
||||||
DeprecatedSC, // deprecated
|
PacketServerClient,
|
||||||
DeprecatedCSU, // deprecated
|
PacketClientServerUnhandled,
|
||||||
DeprecatedSCD, // deprecated
|
PacketServerClientWithDump,
|
||||||
DeprecatedCSD, // deprecated
|
PacketClientServerWithDump,
|
||||||
Loginserver, // deprecated
|
Loginserver,
|
||||||
ClientLogin,
|
ClientLogin,
|
||||||
HeadlessClient, // deprecated
|
HeadlessClient,
|
||||||
HPUpdate,
|
HPUpdate,
|
||||||
FixZ,
|
FixZ,
|
||||||
Food,
|
Food,
|
||||||
@@ -103,10 +104,10 @@ namespace Logs {
|
|||||||
MobAppearance,
|
MobAppearance,
|
||||||
Info,
|
Info,
|
||||||
Warning,
|
Warning,
|
||||||
Critical, // deprecated
|
Critical,
|
||||||
Emergency, // deprecated
|
Emergency,
|
||||||
Alert, // deprecated
|
Alert,
|
||||||
Notice, // deprecated
|
Notice,
|
||||||
AIScanClose,
|
AIScanClose,
|
||||||
AIYellForHelp,
|
AIYellForHelp,
|
||||||
AICastBeneficialClose,
|
AICastBeneficialClose,
|
||||||
@@ -126,17 +127,6 @@ namespace Logs {
|
|||||||
DiaWind,
|
DiaWind,
|
||||||
HTTP,
|
HTTP,
|
||||||
Saylink,
|
Saylink,
|
||||||
ChecksumVerification,
|
|
||||||
CombatRecord,
|
|
||||||
Hate,
|
|
||||||
Discord,
|
|
||||||
Faction,
|
|
||||||
PacketServerClient,
|
|
||||||
PacketClientServer,
|
|
||||||
PacketServerToServer,
|
|
||||||
Bugs,
|
|
||||||
QuestErrors,
|
|
||||||
PlayerEvents,
|
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -149,7 +139,7 @@ namespace Logs {
|
|||||||
"AI",
|
"AI",
|
||||||
"Aggro",
|
"Aggro",
|
||||||
"Attack",
|
"Attack",
|
||||||
"Deprecated",
|
"Packet :: Client -> Server",
|
||||||
"Combat",
|
"Combat",
|
||||||
"Commands",
|
"Commands",
|
||||||
"Crash",
|
"Crash",
|
||||||
@@ -160,52 +150,52 @@ namespace Logs {
|
|||||||
"Inventory",
|
"Inventory",
|
||||||
"Launcher",
|
"Launcher",
|
||||||
"Netcode",
|
"Netcode",
|
||||||
"Normal (Deprecated)",
|
"Normal",
|
||||||
"Object",
|
"Object",
|
||||||
"Pathing",
|
"Pathing",
|
||||||
"QS Server (Deprecated)",
|
"QS Server",
|
||||||
"Quests",
|
"Quests",
|
||||||
"Rules",
|
"Rules",
|
||||||
"Skills",
|
"Skills",
|
||||||
"Spawns",
|
"Spawns",
|
||||||
"Spells",
|
"Spells",
|
||||||
"Status (Deprecated)",
|
"Status",
|
||||||
"TCP Connection",
|
"TCP Connection",
|
||||||
"Tasks",
|
"Tasks",
|
||||||
"Tradeskills",
|
"Tradeskills",
|
||||||
"Trading",
|
"Trading",
|
||||||
"Tribute",
|
"Tribute",
|
||||||
"UCS Server (Deprecated)",
|
"UCS Server",
|
||||||
"Web Interface (Deprecated)",
|
"WebInterface Server",
|
||||||
"World Server (Deprecated)",
|
"World Server",
|
||||||
"Zone Server (Deprecated)",
|
"Zone Server",
|
||||||
"QueryErr",
|
"MySQL Error",
|
||||||
"Query",
|
"MySQL Query",
|
||||||
"Mercenaries",
|
"Mercenaries",
|
||||||
"Quest Debug",
|
"Quest Debug",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Server -> Client",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Client -> Server Unhandled",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Server -> Client (Dump)",
|
||||||
"Legacy Packet Logging (Deprecated)",
|
"Packet :: Client -> Server (Dump)",
|
||||||
"Login Server (Deprecated)",
|
"Login Server",
|
||||||
"Client Login",
|
"Client Login",
|
||||||
"Headless Client (Deprecated)",
|
"Headless Client",
|
||||||
"HP Update",
|
"HP Update",
|
||||||
"FixZ",
|
"FixZ",
|
||||||
"Food",
|
"Food",
|
||||||
"Traps",
|
"Traps",
|
||||||
"NPC Roam Box",
|
"NPC Roam Box",
|
||||||
"NPC Scaling",
|
"NPC Scaling",
|
||||||
"MobAppearance",
|
"Mob Appearance",
|
||||||
"Info",
|
"Info",
|
||||||
"Warning",
|
"Warning",
|
||||||
"Critical (Deprecated)",
|
"Critical",
|
||||||
"Emergency (Deprecated)",
|
"Emergency",
|
||||||
"Alert (Deprecated)",
|
"Alert",
|
||||||
"Notice (Deprecated)",
|
"Notice",
|
||||||
"AI Scan",
|
"AI Scan Close",
|
||||||
"AI Yell",
|
"AI Yell For Help",
|
||||||
"AI CastBeneficial",
|
"AI Cast Beneficial Close",
|
||||||
"AOE Cast",
|
"AOE Cast",
|
||||||
"Entity Management",
|
"Entity Management",
|
||||||
"Flee",
|
"Flee",
|
||||||
@@ -222,17 +212,6 @@ namespace Logs {
|
|||||||
"DialogueWindow",
|
"DialogueWindow",
|
||||||
"HTTP",
|
"HTTP",
|
||||||
"Saylink",
|
"Saylink",
|
||||||
"ChecksumVer",
|
|
||||||
"CombatRecord",
|
|
||||||
"Hate",
|
|
||||||
"Discord",
|
|
||||||
"Faction",
|
|
||||||
"Packet S->C",
|
|
||||||
"Packet C->S",
|
|
||||||
"Packet S->S",
|
|
||||||
"Bugs",
|
|
||||||
"QuestErrors",
|
|
||||||
"PlayerEvents",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,8 +219,6 @@ namespace Logs {
|
|||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
constexpr uint16 MAX_DISCORD_WEBHOOK_ID = 300;
|
|
||||||
|
|
||||||
class EQEmuLogSys {
|
class EQEmuLogSys {
|
||||||
public:
|
public:
|
||||||
EQEmuLogSys();
|
EQEmuLogSys();
|
||||||
@@ -304,19 +281,9 @@ public:
|
|||||||
uint8 log_to_file;
|
uint8 log_to_file;
|
||||||
uint8 log_to_console;
|
uint8 log_to_console;
|
||||||
uint8 log_to_gmsay;
|
uint8 log_to_gmsay;
|
||||||
uint8 log_to_discord;
|
|
||||||
int discord_webhook_id;
|
|
||||||
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
|
uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OriginationInfo {
|
|
||||||
std::string zone_short_name;
|
|
||||||
std::string zone_long_name;
|
|
||||||
int instance_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
OriginationInfo origination_info{};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internally used memory reference for all log settings per category
|
* Internally used memory reference for all log settings per category
|
||||||
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
||||||
@@ -324,78 +291,50 @@ public:
|
|||||||
*/
|
*/
|
||||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||||
|
|
||||||
struct LogEnabled {
|
bool file_logs_enabled = false;
|
||||||
bool log_to_file_enabled;
|
|
||||||
bool log_to_console_enabled;
|
|
||||||
bool log_to_gmsay_enabled;
|
|
||||||
bool log_to_discord_enabled;
|
|
||||||
bool log_enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
int log_platform = 0;
|
||||||
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
std::string platform_file_name;
|
||||||
|
|
||||||
struct DiscordWebhooks {
|
|
||||||
int id;
|
|
||||||
std::string webhook_name;
|
|
||||||
std::string webhook_url;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DiscordWebhooks *GetDiscordWebhooks() const;
|
|
||||||
|
|
||||||
// gmsay
|
// gmsay
|
||||||
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
||||||
|
|
||||||
EQEmuLogSys *SetGMSayHandler(const std::function<void(uint16 log_type, const char *func, const std::string &)>& f)
|
EQEmuLogSys * SetGMSayHandler(std::function<void(uint16 log_type, const std::string &)> f) {
|
||||||
{
|
on_log_gmsay_hook = f;
|
||||||
m_on_log_gmsay_hook = f;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
EQEmuLogSys *SetDiscordHandler(std::function<void(uint16 log_category, int webhook_id, const std::string &)> f)
|
|
||||||
{
|
|
||||||
m_on_log_discord_hook = f;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console
|
// console
|
||||||
void SetConsoleHandler(
|
void SetConsoleHandler(
|
||||||
std::function<void(
|
std::function<void(
|
||||||
|
uint16 debug_level,
|
||||||
uint16 log_type,
|
uint16 log_type,
|
||||||
const std::string &
|
const std::string &
|
||||||
)> f
|
)> f
|
||||||
) { m_on_log_console_hook = f; }
|
) { on_log_console_hook = f; }
|
||||||
void SilenceConsoleLogging();
|
void SilenceConsoleLogging();
|
||||||
void EnableConsoleLogging();
|
void EnableConsoleLogging();
|
||||||
|
|
||||||
// database
|
// database
|
||||||
EQEmuLogSys *SetDatabase(Database *db);
|
EQEmuLogSys *SetDatabase(Database *db);
|
||||||
|
|
||||||
[[nodiscard]] const std::string &GetLogPath() const;
|
|
||||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// reference to database
|
// reference to database
|
||||||
Database *m_database;
|
Database *m_database;
|
||||||
std::function<void(uint16 log_category, const char *func, const std::string &)> m_on_log_gmsay_hook;
|
|
||||||
std::function<void(uint16 log_category, int webhook_id, const std::string &)> m_on_log_discord_hook;
|
|
||||||
std::function<void(uint16 log_category, const std::string &)> m_on_log_console_hook;
|
|
||||||
DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{};
|
|
||||||
bool m_file_logs_enabled = false;
|
|
||||||
int m_log_platform = 0;
|
|
||||||
std::string m_platform_file_name;
|
|
||||||
std::string m_log_path;
|
|
||||||
|
|
||||||
void ProcessConsoleMessage(
|
std::function<void(uint16 log_category, const std::string &)> on_log_gmsay_hook;
|
||||||
uint16 log_category,
|
std::function<void(uint16 debug_level, uint16 log_category, const std::string &)> on_log_console_hook;
|
||||||
const std::string &message,
|
|
||||||
const char *file,
|
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
|
||||||
const char *func,
|
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
|
||||||
int line
|
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||||
);
|
|
||||||
void ProcessLogWrite(uint16 log_category, const std::string &message);
|
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
void InjectTablesIfNotExist();
|
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
bool IsRfc5424LogCategory(uint16 log_category);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EQEmuLogSys LogSys;
|
extern EQEmuLogSys LogSys;
|
||||||
|
|||||||
+597
-303
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -1,14 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <any>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include "event_loop.h"
|
#include "event_loop.h"
|
||||||
|
#include "../any.h"
|
||||||
|
|
||||||
namespace EQ {
|
namespace EQ {
|
||||||
class Task
|
class Task
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(const std::any&)> ResolveFn;
|
typedef std::function<void(const EQ::Any&)> ResolveFn;
|
||||||
typedef std::function<void(const std::exception&)> RejectFn;
|
typedef std::function<void(const std::exception&)> RejectFn;
|
||||||
typedef std::function<void()> FinallyFn;
|
typedef std::function<void()> FinallyFn;
|
||||||
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
|
typedef std::function<void(ResolveFn, RejectFn)> TaskFn;
|
||||||
@@ -19,7 +19,7 @@ namespace EQ {
|
|||||||
RejectFn on_catch;
|
RejectFn on_catch;
|
||||||
FinallyFn on_finally;
|
FinallyFn on_finally;
|
||||||
bool has_result;
|
bool has_result;
|
||||||
std::any result;
|
EQ::Any result;
|
||||||
bool has_error;
|
bool has_error;
|
||||||
std::exception error;
|
std::exception error;
|
||||||
};
|
};
|
||||||
@@ -63,7 +63,7 @@ namespace EQ {
|
|||||||
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
||||||
TaskBaton *baton = (TaskBaton*)req->data;
|
TaskBaton *baton = (TaskBaton*)req->data;
|
||||||
|
|
||||||
baton->fn([baton](const std::any& result) {
|
baton->fn([baton](const EQ::Any& result) {
|
||||||
baton->has_error = false;
|
baton->has_error = false;
|
||||||
baton->has_result = true;
|
baton->has_result = true;
|
||||||
baton->result = result;
|
baton->result = result;
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ namespace EQ
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Fn, typename... Args>
|
template<typename Fn, typename... Args>
|
||||||
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::invoke_result<Fn, Args...>::type> {
|
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::result_of<Fn(Args...)>::type> {
|
||||||
using return_type = typename std::invoke_result<Fn, Args...>::type;
|
using return_type = typename std::result_of<Fn(Args...)>::type;
|
||||||
|
|
||||||
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
||||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,214 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../repositories/base/base_player_event_logs_repository.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <cereal/types/vector.hpp>
|
|
||||||
|
|
||||||
struct DiscordField {
|
|
||||||
std::string name;
|
|
||||||
std::string value;
|
|
||||||
bool is_inline;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(name),
|
|
||||||
CEREAL_NVP(value),
|
|
||||||
cereal::make_nvp("inline", is_inline)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordAuthor {
|
|
||||||
std::string name;
|
|
||||||
std::string icon_url;
|
|
||||||
std::string url;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(name),
|
|
||||||
CEREAL_NVP(icon_url),
|
|
||||||
CEREAL_NVP(url)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordEmbed {
|
|
||||||
std::vector<DiscordField> fields;
|
|
||||||
std::string title;
|
|
||||||
std::string description;
|
|
||||||
std::string timestamp;
|
|
||||||
DiscordAuthor author;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(fields),
|
|
||||||
CEREAL_NVP(title),
|
|
||||||
CEREAL_NVP(description),
|
|
||||||
CEREAL_NVP(timestamp),
|
|
||||||
CEREAL_NVP(author)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordWebhook {
|
|
||||||
std::vector<DiscordEmbed> embeds;
|
|
||||||
std::string content;
|
|
||||||
std::string avatar_url;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(embeds),
|
|
||||||
CEREAL_NVP(avatar_url),
|
|
||||||
CEREAL_NVP(content)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PlayerEventDiscordFormatter {
|
|
||||||
public:
|
|
||||||
static std::string GetCurrentTimestamp();
|
|
||||||
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
|
|
||||||
static std::string
|
|
||||||
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
|
|
||||||
static void BuildDiscordField(
|
|
||||||
std::vector<DiscordField> *f,
|
|
||||||
const std::string &name,
|
|
||||||
const std::string &value,
|
|
||||||
bool is_inline = true
|
|
||||||
);
|
|
||||||
static void BuildBaseEmbed(
|
|
||||||
std::vector<DiscordEmbed> *e,
|
|
||||||
const std::vector<DiscordField> &f,
|
|
||||||
PlayerEvent::PlayerEventContainer c
|
|
||||||
);
|
|
||||||
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
|
|
||||||
|
|
||||||
static std::string FormatAAGainedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::AAGainedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatAAPurchasedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::AAPurchasedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDeathEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DeathEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatFishSuccessEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::FishSuccessEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatForageSuccessEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ForageSuccessEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDestroyItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DestroyItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDiscoverItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DiscoverItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDroppedItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DroppedItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLevelGainedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LevelGainedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLevelLostEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LevelLostEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLootItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LootItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatGroundSpawnPickupEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::GroundSpawnPickupEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatMerchantPurchaseEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::MerchantPurchaseEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatMerchantSellEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::MerchantSellEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatNPCHandinEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::HandinEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatSkillUpEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::SkillUpEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskAcceptEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskAcceptEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskCompleteEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskCompleteEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskUpdateEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskUpdateEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTradeEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TradeEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTraderPurchaseEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TraderPurchaseEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTraderSellEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TraderSellEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatResurrectAcceptEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ResurrectAcceptEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatSplitMoneyEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::SplitMoneyEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatCombineEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::CombineEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatZoningEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ZoningEvent &e
|
|
||||||
);
|
|
||||||
static DiscordWebhook BuildDiscordWebhook(
|
|
||||||
const PlayerEvent::PlayerEventContainer &p,
|
|
||||||
std::vector<DiscordEmbed> &embeds
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
@@ -1,712 +0,0 @@
|
|||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include "player_event_logs.h"
|
|
||||||
#include "player_event_discord_formatter.h"
|
|
||||||
#include "../platform.h"
|
|
||||||
#include "../rulesys.h"
|
|
||||||
|
|
||||||
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
|
||||||
|
|
||||||
// general initialization routine
|
|
||||||
void PlayerEventLogs::Init()
|
|
||||||
{
|
|
||||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
|
||||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
|
||||||
|
|
||||||
ValidateDatabaseConnection();
|
|
||||||
|
|
||||||
// initialize settings array
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
m_settings[i].id = i;
|
|
||||||
m_settings[i].event_name = PlayerEvent::EventName[i];
|
|
||||||
m_settings[i].event_enabled = 1;
|
|
||||||
m_settings[i].retention_days = 0;
|
|
||||||
m_settings[i].discord_webhook_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSettingsDefaults();
|
|
||||||
|
|
||||||
// initialize settings from database
|
|
||||||
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
|
||||||
std::vector<int> db{};
|
|
||||||
db.reserve(s.size());
|
|
||||||
for (auto &e: s) {
|
|
||||||
if (e.id >= PlayerEvent::MAX) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_settings[e.id] = e;
|
|
||||||
db.emplace_back(e.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert entries that don't exist in database
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
|
||||||
bool is_deprecated = Strings::Contains(PlayerEvent::EventName[i], "Deprecated");
|
|
||||||
bool is_implemented = !Strings::Contains(PlayerEvent::EventName[i], "Unimplemented");
|
|
||||||
|
|
||||||
// remove when deprecated
|
|
||||||
if (is_deprecated && is_in_database) {
|
|
||||||
LogInfo("[Deprecated] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
|
||||||
}
|
|
||||||
// remove when unimplemented if present
|
|
||||||
if (!is_implemented && is_in_database) {
|
|
||||||
LogInfo("[Unimplemented] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
|
||||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
|
||||||
LogInfo(
|
|
||||||
"[New] PlayerEvent [{}] ({})",
|
|
||||||
PlayerEvent::EventName[i],
|
|
||||||
i
|
|
||||||
);
|
|
||||||
|
|
||||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
|
||||||
c.id = i;
|
|
||||||
c.event_name = PlayerEvent::EventName[i];
|
|
||||||
c.event_enabled = m_settings[i].event_enabled;
|
|
||||||
c.retention_days = m_settings[i].retention_days;
|
|
||||||
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
|
||||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
|
||||||
|
|
||||||
// on initial boot process truncation
|
|
||||||
if (processing_in_world || processing_in_qs) {
|
|
||||||
ProcessRetentionTruncation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the database object, during initialization
|
|
||||||
PlayerEventLogs *PlayerEventLogs::SetDatabase(Database *db)
|
|
||||||
{
|
|
||||||
m_database = db;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validates whether the connection is valid or not, used in initialization
|
|
||||||
bool PlayerEventLogs::ValidateDatabaseConnection()
|
|
||||||
{
|
|
||||||
if (!m_database) {
|
|
||||||
LogError("No database connection");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determines if the passed in event is enabled or not
|
|
||||||
// this is used to gate logic or events from firing off
|
|
||||||
// this is used prior to building the events, we don't want to
|
|
||||||
// build the events, send them through the stack in a function call
|
|
||||||
// only to discard them immediately afterwards, very wasteful on resources
|
|
||||||
// the quest api currently does this
|
|
||||||
bool PlayerEventLogs::IsEventEnabled(PlayerEvent::EventType event)
|
|
||||||
{
|
|
||||||
return m_settings[event].event_enabled ? m_settings[event].event_enabled : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this processes any current player events on the queue
|
|
||||||
void PlayerEventLogs::ProcessBatchQueue()
|
|
||||||
{
|
|
||||||
m_batch_queue_lock.lock();
|
|
||||||
if (m_record_batch_queue.empty()) {
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BenchTimer benchmark;
|
|
||||||
|
|
||||||
// flush many
|
|
||||||
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
|
||||||
LogPlayerEventsDetail(
|
|
||||||
"Processing batch player event log queue of [{}] took [{}]",
|
|
||||||
m_record_batch_queue.size(),
|
|
||||||
benchmark.elapsed()
|
|
||||||
);
|
|
||||||
|
|
||||||
// empty
|
|
||||||
m_record_batch_queue = {};
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// adds a player event to the queue
|
|
||||||
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
|
||||||
{
|
|
||||||
m_batch_queue_lock.lock();
|
|
||||||
m_record_batch_queue.emplace_back(log);
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
|
|
||||||
if (m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
|
||||||
ProcessBatchQueue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fills common event data in the SendEvent function
|
|
||||||
void PlayerEventLogs::FillPlayerEvent(
|
|
||||||
const PlayerEvent::PlayerEvent &p,
|
|
||||||
PlayerEventLogsRepository::PlayerEventLogs &n
|
|
||||||
)
|
|
||||||
{
|
|
||||||
n.account_id = p.account_id;
|
|
||||||
n.character_id = p.character_id;
|
|
||||||
n.zone_id = p.zone_id;
|
|
||||||
n.instance_id = p.instance_id;
|
|
||||||
n.x = p.x;
|
|
||||||
n.y = p.y;
|
|
||||||
n.z = p.z;
|
|
||||||
n.heading = p.heading;
|
|
||||||
}
|
|
||||||
|
|
||||||
// builds the dynamic packet used to ship the player event over the wire
|
|
||||||
// supports serializing the struct so it can be rebuilt on the other end
|
|
||||||
std::unique_ptr<ServerPacket>
|
|
||||||
PlayerEventLogs::BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e)
|
|
||||||
{
|
|
||||||
EQ::Net::DynamicPacket dyn_pack;
|
|
||||||
dyn_pack.PutSerialize(0, e);
|
|
||||||
auto pack_size = sizeof(ServerSendPlayerEvent_Struct) + dyn_pack.Length();
|
|
||||||
auto pack = std::make_unique<ServerPacket>(ServerOP_PlayerEvent, static_cast<uint32_t>(pack_size));
|
|
||||||
auto buf = reinterpret_cast<ServerSendPlayerEvent_Struct *>(pack->pBuffer);
|
|
||||||
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
|
|
||||||
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
|
|
||||||
|
|
||||||
return pack;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PlayerEventLogSettingsRepository::PlayerEventLogSettings *PlayerEventLogs::GetSettings() const
|
|
||||||
{
|
|
||||||
return m_settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
|
|
||||||
{
|
|
||||||
// out of bounds check
|
|
||||||
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure webhook id is set
|
|
||||||
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure there is a matching webhook to begin with
|
|
||||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_type_id)
|
|
||||||
{
|
|
||||||
// out of bounds check
|
|
||||||
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure webhook id is set
|
|
||||||
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure there is a matching webhook to begin with
|
|
||||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
|
||||||
return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// GM_COMMAND | [x] Implemented Formatter
|
|
||||||
// ZONING | [x] Implemented Formatter
|
|
||||||
// AA_GAIN | [x] Implemented Formatter
|
|
||||||
// AA_PURCHASE | [x] Implemented Formatter
|
|
||||||
// FORAGE_SUCCESS | [x] Implemented Formatter
|
|
||||||
// FORAGE_FAILURE | [x] Implemented Formatter
|
|
||||||
// FISH_SUCCESS | [x] Implemented Formatter
|
|
||||||
// FISH_FAILURE | [x] Implemented Formatter
|
|
||||||
// ITEM_DESTROY | [x] Implemented Formatter
|
|
||||||
// WENT_ONLINE | [x] Implemented Formatter
|
|
||||||
// WENT_OFFLINE | [x] Implemented Formatter
|
|
||||||
// LEVEL_GAIN | [x] Implemented Formatter
|
|
||||||
// LEVEL_LOSS | [x] Implemented Formatter
|
|
||||||
// LOOT_ITEM | [x] Implemented Formatter
|
|
||||||
// MERCHANT_PURCHASE | [x] Implemented Formatter
|
|
||||||
// MERCHANT_SELL | [x] Implemented Formatter
|
|
||||||
// GROUP_JOIN | [] Implemented Formatter
|
|
||||||
// GROUP_LEAVE | [] Implemented Formatter
|
|
||||||
// RAID_JOIN | [] Implemented Formatter
|
|
||||||
// RAID_LEAVE | [] Implemented Formatter
|
|
||||||
// GROUNDSPAWN_PICKUP | [x] Implemented Formatter
|
|
||||||
// NPC_HANDIN | [x] Implemented Formatter
|
|
||||||
// SKILL_UP | [x] Implemented Formatter
|
|
||||||
// TASK_ACCEPT | [x] Implemented Formatter
|
|
||||||
// TASK_UPDATE | [x] Implemented Formatter
|
|
||||||
// TASK_COMPLETE | [x] Implemented Formatter
|
|
||||||
// TRADE | [] Implemented Formatter
|
|
||||||
// GIVE_ITEM | [] Implemented Formatter
|
|
||||||
// SAY | [x] Implemented Formatter
|
|
||||||
// REZ_ACCEPTED | [x] Implemented Formatter
|
|
||||||
// DEATH | [x] Implemented Formatter
|
|
||||||
// COMBINE_FAILURE | [x] Implemented Formatter
|
|
||||||
// COMBINE_SUCCESS | [x] Implemented Formatter
|
|
||||||
// DROPPED_ITEM | [x] Implemented Formatter
|
|
||||||
// SPLIT_MONEY | [x] Implemented Formatter
|
|
||||||
// DZ_JOIN | [] Implemented Formatter
|
|
||||||
// DZ_LEAVE | [] Implemented Formatter
|
|
||||||
// TRADER_PURCHASE | [x] Implemented Formatter
|
|
||||||
// TRADER_SELL | [x] Implemented Formatter
|
|
||||||
// BANDOLIER_CREATE | [] Implemented Formatter
|
|
||||||
// BANDOLIER_SWAP | [] Implemented Formatter
|
|
||||||
// DISCOVER_ITEM | [X] Implemented Formatter
|
|
||||||
|
|
||||||
std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e)
|
|
||||||
{
|
|
||||||
std::string payload;
|
|
||||||
switch (e.player_event_log.event_type_id) {
|
|
||||||
case PlayerEvent::AA_GAIN: {
|
|
||||||
PlayerEvent::AAGainedEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatAAGainedEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::AA_PURCHASE: {
|
|
||||||
PlayerEvent::AAPurchasedEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatAAPurchasedEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::COMBINE_FAILURE:
|
|
||||||
case PlayerEvent::COMBINE_SUCCESS: {
|
|
||||||
PlayerEvent::CombineEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatCombineEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::DEATH: {
|
|
||||||
PlayerEvent::DeathEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDeathEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::DISCOVER_ITEM: {
|
|
||||||
PlayerEvent::DiscoverItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDiscoverItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::DROPPED_ITEM: {
|
|
||||||
PlayerEvent::DroppedItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FISH_FAILURE: {
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FISH_SUCCESS: {
|
|
||||||
PlayerEvent::FishSuccessEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FORAGE_FAILURE: {
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::FORAGE_SUCCESS: {
|
|
||||||
PlayerEvent::ForageSuccessEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatForageSuccessEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::ITEM_DESTROY: {
|
|
||||||
PlayerEvent::DestroyItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatDestroyItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::LEVEL_GAIN: {
|
|
||||||
PlayerEvent::LevelGainedEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatLevelGainedEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::LEVEL_LOSS: {
|
|
||||||
PlayerEvent::LevelLostEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatLevelLostEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::LOOT_ITEM: {
|
|
||||||
PlayerEvent::LootItemEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatLootItemEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::GROUNDSPAWN_PICKUP: {
|
|
||||||
PlayerEvent::GroundSpawnPickupEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatGroundSpawnPickupEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::NPC_HANDIN: {
|
|
||||||
PlayerEvent::HandinEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatNPCHandinEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::SAY: {
|
|
||||||
PlayerEvent::SayEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatEventSay(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::GM_COMMAND: {
|
|
||||||
PlayerEvent::GMCommandEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatGMCommand(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::SKILL_UP: {
|
|
||||||
PlayerEvent::SkillUpEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatSkillUpEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::SPLIT_MONEY: {
|
|
||||||
PlayerEvent::SplitMoneyEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatSplitMoneyEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TASK_ACCEPT: {
|
|
||||||
PlayerEvent::TaskAcceptEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTaskAcceptEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TASK_COMPLETE: {
|
|
||||||
PlayerEvent::TaskCompleteEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTaskCompleteEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TASK_UPDATE: {
|
|
||||||
PlayerEvent::TaskUpdateEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTaskUpdateEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TRADE: {
|
|
||||||
PlayerEvent::TradeEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTradeEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TRADER_PURCHASE: {
|
|
||||||
PlayerEvent::TraderPurchaseEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTraderPurchaseEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::TRADER_SELL: {
|
|
||||||
PlayerEvent::TraderSellEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatTraderSellEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::REZ_ACCEPTED: {
|
|
||||||
PlayerEvent::ResurrectAcceptEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::WENT_ONLINE:
|
|
||||||
case PlayerEvent::WENT_OFFLINE: {
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::MERCHANT_PURCHASE: {
|
|
||||||
PlayerEvent::MerchantPurchaseEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatMerchantPurchaseEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::MERCHANT_SELL: {
|
|
||||||
PlayerEvent::MerchantSellEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatMerchantSellEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case PlayerEvent::ZONING: {
|
|
||||||
PlayerEvent::ZoningEvent n{};
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
ss << e.player_event_log.event_data;
|
|
||||||
cereal::JSONInputArchive ar(ss);
|
|
||||||
n.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
payload = PlayerEventDiscordFormatter::FormatZoningEvent(e, n);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
LogInfo(
|
|
||||||
"Player event [{}] ({}) Discord formatter not implemented",
|
|
||||||
e.player_event_log.event_type_name,
|
|
||||||
e.player_event_log.event_type_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
// general process function, used in world or UCS depending on rule Logging:PlayerEventsQSProcess
|
|
||||||
void PlayerEventLogs::Process()
|
|
||||||
{
|
|
||||||
if (m_process_batch_events_timer.Check()) {
|
|
||||||
ProcessBatchQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_process_retention_truncation_timer.Check()) {
|
|
||||||
ProcessRetentionTruncation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
|
||||||
{
|
|
||||||
LogInfo("Running truncation");
|
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
if (m_settings[i].retention_days > 0) {
|
|
||||||
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
|
||||||
*m_database,
|
|
||||||
fmt::format(
|
|
||||||
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
|
|
||||||
i,
|
|
||||||
m_settings[i].retention_days
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (deleted_count > 0) {
|
|
||||||
LogInfo(
|
|
||||||
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
|
|
||||||
deleted_count,
|
|
||||||
PlayerEvent::EventName[i],
|
|
||||||
i,
|
|
||||||
m_settings[i].retention_days
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerEventLogs::ReloadSettings()
|
|
||||||
{
|
|
||||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
|
||||||
m_settings[e.id] = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
#define EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
|
|
||||||
#include "../repositories/player_event_log_settings_repository.h"
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../servertalk.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../timer.h"
|
|
||||||
#include "../json/json_archive_single_line.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class PlayerEventLogs {
|
|
||||||
public:
|
|
||||||
void Init();
|
|
||||||
void ReloadSettings();
|
|
||||||
PlayerEventLogs *SetDatabase(Database *db);
|
|
||||||
bool ValidateDatabaseConnection();
|
|
||||||
bool IsEventEnabled(PlayerEvent::EventType event);
|
|
||||||
|
|
||||||
void Process();
|
|
||||||
|
|
||||||
// batch queue
|
|
||||||
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
|
||||||
|
|
||||||
// main event record generic function
|
|
||||||
// can ingest any struct event types
|
|
||||||
template<typename T>
|
|
||||||
std::unique_ptr<ServerPacket> RecordEvent(
|
|
||||||
PlayerEvent::EventType t,
|
|
||||||
const PlayerEvent::PlayerEvent &p,
|
|
||||||
T e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto n = PlayerEventLogsRepository::NewEntity();
|
|
||||||
FillPlayerEvent(p, n);
|
|
||||||
n.event_type_id = t;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
cereal::JSONOutputArchiveSingleLine ar(ss);
|
|
||||||
e.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
n.event_type_name = PlayerEvent::EventName[t];
|
|
||||||
n.event_data = Strings::Contains(ss.str(), "noop") ? "{}" : ss.str();
|
|
||||||
n.created_at = std::time(nullptr);
|
|
||||||
|
|
||||||
auto c = PlayerEvent::PlayerEventContainer{
|
|
||||||
.player_event = p,
|
|
||||||
.player_event_log = n
|
|
||||||
};
|
|
||||||
|
|
||||||
return BuildPlayerEventPacket(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
|
|
||||||
bool IsEventDiscordEnabled(int32_t event_type_id);
|
|
||||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
|
||||||
|
|
||||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
|
||||||
private:
|
|
||||||
Database *m_database; // reference to database
|
|
||||||
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
|
||||||
|
|
||||||
// batch queue is used to record events in batch
|
|
||||||
std::vector<PlayerEventLogsRepository::PlayerEventLogs> m_record_batch_queue{};
|
|
||||||
static void FillPlayerEvent(const PlayerEvent::PlayerEvent &p, PlayerEventLogsRepository::PlayerEventLogs &n);
|
|
||||||
static std::unique_ptr<ServerPacket>
|
|
||||||
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
|
||||||
|
|
||||||
// timers
|
|
||||||
Timer m_process_batch_events_timer; // events processing timer
|
|
||||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
|
||||||
|
|
||||||
// processing
|
|
||||||
std::mutex m_batch_queue_lock{};
|
|
||||||
void ProcessBatchQueue();
|
|
||||||
void ProcessRetentionTruncation();
|
|
||||||
void SetSettingsDefaults();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern PlayerEventLogs player_event_logs;
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
@@ -1,971 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENTS_H
|
|
||||||
#define EQEMU_PLAYER_EVENTS_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cereal/cereal.hpp>
|
|
||||||
#include "../types.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
|
|
||||||
namespace PlayerEvent {
|
|
||||||
|
|
||||||
enum EventType {
|
|
||||||
GM_COMMAND = 1,
|
|
||||||
ZONING,
|
|
||||||
AA_GAIN,
|
|
||||||
AA_PURCHASE,
|
|
||||||
FORAGE_SUCCESS,
|
|
||||||
FORAGE_FAILURE,
|
|
||||||
FISH_SUCCESS,
|
|
||||||
FISH_FAILURE,
|
|
||||||
ITEM_DESTROY,
|
|
||||||
WENT_ONLINE,
|
|
||||||
WENT_OFFLINE,
|
|
||||||
LEVEL_GAIN,
|
|
||||||
LEVEL_LOSS,
|
|
||||||
LOOT_ITEM,
|
|
||||||
MERCHANT_PURCHASE,
|
|
||||||
MERCHANT_SELL,
|
|
||||||
GROUP_JOIN, // unimplemented
|
|
||||||
GROUP_LEAVE, // unimplemented
|
|
||||||
RAID_JOIN, // unimplemented
|
|
||||||
RAID_LEAVE, // unimplemented
|
|
||||||
GROUNDSPAWN_PICKUP,
|
|
||||||
NPC_HANDIN,
|
|
||||||
SKILL_UP,
|
|
||||||
TASK_ACCEPT,
|
|
||||||
TASK_UPDATE,
|
|
||||||
TASK_COMPLETE,
|
|
||||||
TRADE,
|
|
||||||
GIVE_ITEM, // unimplemented
|
|
||||||
SAY,
|
|
||||||
REZ_ACCEPTED,
|
|
||||||
DEATH,
|
|
||||||
COMBINE_FAILURE,
|
|
||||||
COMBINE_SUCCESS,
|
|
||||||
DROPPED_ITEM,
|
|
||||||
SPLIT_MONEY,
|
|
||||||
DZ_JOIN, // unimplemented
|
|
||||||
DZ_LEAVE, // unimplemented
|
|
||||||
TRADER_PURCHASE,
|
|
||||||
TRADER_SELL,
|
|
||||||
BANDOLIER_CREATE, // unimplemented
|
|
||||||
BANDOLIER_SWAP, // unimplemented
|
|
||||||
DISCOVER_ITEM,
|
|
||||||
POSSIBLE_HACK,
|
|
||||||
KILLED_NPC,
|
|
||||||
KILLED_NAMED_NPC,
|
|
||||||
KILLED_RAID_NPC,
|
|
||||||
ITEM_CREATION,
|
|
||||||
MAX // dont remove
|
|
||||||
};
|
|
||||||
|
|
||||||
// Don't ever remove items, even if they are deprecated
|
|
||||||
// If event is deprecated just tag (Deprecated) in the name
|
|
||||||
// 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[PlayerEvent::MAX] = {
|
|
||||||
"None",
|
|
||||||
"GM Command",
|
|
||||||
"Zoning",
|
|
||||||
"AA Gain",
|
|
||||||
"AA Purchase",
|
|
||||||
"Forage Success",
|
|
||||||
"Forage Failure",
|
|
||||||
"Fish Success",
|
|
||||||
"Fish Failure",
|
|
||||||
"Item Destroy",
|
|
||||||
"Went Online",
|
|
||||||
"Went Offline",
|
|
||||||
"Level Gain",
|
|
||||||
"Level Loss",
|
|
||||||
"Loot Item",
|
|
||||||
"Merchant Purchase",
|
|
||||||
"Merchant Sell",
|
|
||||||
"Group Join (Unimplemented)",
|
|
||||||
"Group Leave (Unimplemented)",
|
|
||||||
"Raid Join (Unimplemented)",
|
|
||||||
"Raid Leave (Unimplemented)",
|
|
||||||
"Groundspawn Pickup",
|
|
||||||
"NPC Handin",
|
|
||||||
"Skill Up",
|
|
||||||
"Task Accept",
|
|
||||||
"Task Update",
|
|
||||||
"Task Complete",
|
|
||||||
"Trade",
|
|
||||||
"Given Item (Unimplemented)",
|
|
||||||
"Say",
|
|
||||||
"Rez Accepted",
|
|
||||||
"Death",
|
|
||||||
"Combine Failure",
|
|
||||||
"Combine Success",
|
|
||||||
"Dropped Item",
|
|
||||||
"Split Money",
|
|
||||||
"DZ Join (Unimplemented)",
|
|
||||||
"DZ Leave (Unimplemented)",
|
|
||||||
"Trader Purchase",
|
|
||||||
"Trader Sell",
|
|
||||||
"Bandolier Create (Unimplemented)",
|
|
||||||
"Bandolier Swap (Unimplemented)",
|
|
||||||
"Discover Item",
|
|
||||||
"Possible Hack",
|
|
||||||
"Killed NPC",
|
|
||||||
"Killed Named NPC",
|
|
||||||
"Killed Raid NPC",
|
|
||||||
"Item Creation"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic struct used by all events
|
|
||||||
struct PlayerEvent {
|
|
||||||
int64 account_id;
|
|
||||||
std::string account_name;
|
|
||||||
int64 character_id;
|
|
||||||
std::string character_name;
|
|
||||||
int64 guild_id;
|
|
||||||
std::string guild_name;
|
|
||||||
int zone_id;
|
|
||||||
std::string zone_short_name;
|
|
||||||
std::string zone_long_name;
|
|
||||||
int instance_id;
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float heading;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(account_id),
|
|
||||||
CEREAL_NVP(account_name),
|
|
||||||
CEREAL_NVP(character_id),
|
|
||||||
CEREAL_NVP(character_name),
|
|
||||||
CEREAL_NVP(guild_id),
|
|
||||||
CEREAL_NVP(guild_name),
|
|
||||||
CEREAL_NVP(zone_id),
|
|
||||||
CEREAL_NVP(zone_short_name),
|
|
||||||
CEREAL_NVP(zone_long_name),
|
|
||||||
CEREAL_NVP(instance_id),
|
|
||||||
CEREAL_NVP(x),
|
|
||||||
CEREAL_NVP(y),
|
|
||||||
CEREAL_NVP(z),
|
|
||||||
CEREAL_NVP(heading)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// contains metadata in use for things like log/discord formatters
|
|
||||||
// along with the actual event to be persisted
|
|
||||||
struct PlayerEventContainer {
|
|
||||||
PlayerEvent player_event;
|
|
||||||
PlayerEventLogsRepository::PlayerEventLogs player_event_log;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(player_event),
|
|
||||||
CEREAL_NVP(player_event_log)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in events with no extra data
|
|
||||||
struct EmptyEvent {
|
|
||||||
std::string noop; // noop, gets discard upstream
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(noop)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
struct ItemCreationEvent {
|
|
||||||
int64 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 to_slot;
|
|
||||||
int16 charges;
|
|
||||||
uint32 aug1;
|
|
||||||
uint32 aug2;
|
|
||||||
uint32 aug3;
|
|
||||||
uint32 aug4;
|
|
||||||
uint32 aug5;
|
|
||||||
uint32 aug6;
|
|
||||||
bool attuned;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(to_slot),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(aug1),
|
|
||||||
CEREAL_NVP(aug2),
|
|
||||||
CEREAL_NVP(aug3),
|
|
||||||
CEREAL_NVP(aug4),
|
|
||||||
CEREAL_NVP(aug5),
|
|
||||||
CEREAL_NVP(aug6),
|
|
||||||
CEREAL_NVP(attuned)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
struct TradeItem {
|
|
||||||
int64 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int32 slot;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(slot)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
class TradeItemEntry {
|
|
||||||
public:
|
|
||||||
uint16 slot;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 charges;
|
|
||||||
uint32 aug_1_item_id;
|
|
||||||
std::string aug_1_item_name;
|
|
||||||
uint32 aug_2_item_id;
|
|
||||||
std::string aug_2_item_name;
|
|
||||||
uint32 aug_3_item_id;
|
|
||||||
std::string aug_3_item_name;
|
|
||||||
uint32 aug_4_item_id;
|
|
||||||
std::string aug_4_item_name;
|
|
||||||
uint32 aug_5_item_id;
|
|
||||||
std::string aug_5_item_name;
|
|
||||||
uint32 aug_6_item_id;
|
|
||||||
std::string aug_6_item_name;
|
|
||||||
bool in_bag;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(slot),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(aug_1_item_id),
|
|
||||||
CEREAL_NVP(aug_2_item_id),
|
|
||||||
CEREAL_NVP(aug_3_item_id),
|
|
||||||
CEREAL_NVP(aug_4_item_id),
|
|
||||||
CEREAL_NVP(aug_5_item_id),
|
|
||||||
CEREAL_NVP(in_bag)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Events
|
|
||||||
*/
|
|
||||||
struct Money {
|
|
||||||
int32 platinum;
|
|
||||||
int32 gold;
|
|
||||||
int32 silver;
|
|
||||||
int32 copper;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(platinum),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(copper)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TradeEvent {
|
|
||||||
uint32 character_1_id;
|
|
||||||
std::string character_1_name;
|
|
||||||
uint32 character_2_id;
|
|
||||||
std::string character_2_name;
|
|
||||||
Money character_1_give_money;
|
|
||||||
Money character_2_give_money;
|
|
||||||
std::vector<TradeItemEntry> character_1_give_items;
|
|
||||||
std::vector<TradeItemEntry> character_2_give_items;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(character_1_id),
|
|
||||||
CEREAL_NVP(character_1_name),
|
|
||||||
CEREAL_NVP(character_2_id),
|
|
||||||
CEREAL_NVP(character_2_name),
|
|
||||||
CEREAL_NVP(character_1_give_money),
|
|
||||||
CEREAL_NVP(character_2_give_money),
|
|
||||||
CEREAL_NVP(character_1_give_items),
|
|
||||||
CEREAL_NVP(character_2_give_items)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GMCommandEvent {
|
|
||||||
std::string message;
|
|
||||||
std::string target;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message),
|
|
||||||
CEREAL_NVP(target)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZoningEvent {
|
|
||||||
std::string from_zone_long_name;
|
|
||||||
std::string from_zone_short_name;
|
|
||||||
int32 from_zone_id;
|
|
||||||
int32 from_instance_id;
|
|
||||||
int32 from_instance_version;
|
|
||||||
std::string to_zone_long_name;
|
|
||||||
std::string to_zone_short_name;
|
|
||||||
int32 to_zone_id;
|
|
||||||
int32 to_instance_id;
|
|
||||||
int32 to_instance_version;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_zone_long_name),
|
|
||||||
CEREAL_NVP(from_zone_short_name),
|
|
||||||
CEREAL_NVP(from_zone_id),
|
|
||||||
CEREAL_NVP(from_instance_id),
|
|
||||||
CEREAL_NVP(from_instance_version),
|
|
||||||
CEREAL_NVP(to_zone_long_name),
|
|
||||||
CEREAL_NVP(to_zone_short_name),
|
|
||||||
CEREAL_NVP(to_zone_id),
|
|
||||||
CEREAL_NVP(to_instance_id),
|
|
||||||
CEREAL_NVP(to_instance_version)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAGainedEvent {
|
|
||||||
uint32 aa_gained;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(CEREAL_NVP(aa_gained));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAPurchasedEvent {
|
|
||||||
int32 aa_id;
|
|
||||||
int32 aa_cost;
|
|
||||||
int32 aa_previous_id;
|
|
||||||
int32 aa_next_id;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(aa_id),
|
|
||||||
CEREAL_NVP(aa_cost),
|
|
||||||
CEREAL_NVP(aa_previous_id),
|
|
||||||
CEREAL_NVP(aa_next_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ForageSuccessEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FishSuccessEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DestroyItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
std::string reason;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(reason),
|
|
||||||
CEREAL_NVP(charges)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LevelGainedEvent {
|
|
||||||
uint32 from_level;
|
|
||||||
uint8 to_level;
|
|
||||||
int levels_gained;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_level),
|
|
||||||
CEREAL_NVP(to_level),
|
|
||||||
CEREAL_NVP(levels_gained)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LevelLostEvent {
|
|
||||||
uint32 from_level;
|
|
||||||
uint8 to_level;
|
|
||||||
int levels_lost;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_level),
|
|
||||||
CEREAL_NVP(to_level),
|
|
||||||
CEREAL_NVP(levels_lost)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LootItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string corpse_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(corpse_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MerchantPurchaseEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string merchant_name;
|
|
||||||
uint32 merchant_type;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
uint32 cost;
|
|
||||||
uint32 alternate_currency_id;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
uint64 player_currency_balance;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(merchant_name),
|
|
||||||
CEREAL_NVP(merchant_type),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(cost),
|
|
||||||
CEREAL_NVP(alternate_currency_id),
|
|
||||||
CEREAL_NVP(player_money_balance),
|
|
||||||
CEREAL_NVP(player_currency_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MerchantSellEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string merchant_name;
|
|
||||||
uint32 merchant_type;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 charges;
|
|
||||||
uint32 cost;
|
|
||||||
uint32 alternate_currency_id;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
uint64 player_currency_balance;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(merchant_name),
|
|
||||||
CEREAL_NVP(merchant_type),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(cost),
|
|
||||||
CEREAL_NVP(alternate_currency_id),
|
|
||||||
CEREAL_NVP(player_money_balance),
|
|
||||||
CEREAL_NVP(player_currency_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SkillUpEvent {
|
|
||||||
uint32 skill_id;
|
|
||||||
int value;
|
|
||||||
int16 max_skill;
|
|
||||||
std::string against_who;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(skill_id),
|
|
||||||
CEREAL_NVP(value),
|
|
||||||
CEREAL_NVP(max_skill),
|
|
||||||
CEREAL_NVP(against_who)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TaskAcceptEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string npc_name;
|
|
||||||
uint32 task_id;
|
|
||||||
std::string task_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(npc_name),
|
|
||||||
CEREAL_NVP(task_id),
|
|
||||||
CEREAL_NVP(task_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TaskUpdateEvent {
|
|
||||||
uint32 task_id;
|
|
||||||
std::string task_name;
|
|
||||||
uint32 activity_id;
|
|
||||||
uint32 done_count;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(task_id),
|
|
||||||
CEREAL_NVP(task_name),
|
|
||||||
CEREAL_NVP(activity_id),
|
|
||||||
CEREAL_NVP(done_count)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TaskCompleteEvent {
|
|
||||||
uint32 task_id;
|
|
||||||
std::string task_name;
|
|
||||||
uint32 activity_id;
|
|
||||||
uint32 done_count;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(task_id),
|
|
||||||
CEREAL_NVP(task_name),
|
|
||||||
CEREAL_NVP(activity_id),
|
|
||||||
CEREAL_NVP(done_count)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GroundSpawnPickupEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SayEvent {
|
|
||||||
std::string message;
|
|
||||||
std::string target;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message),
|
|
||||||
CEREAL_NVP(target)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ResurrectAcceptEvent {
|
|
||||||
std::string resurrecter_name;
|
|
||||||
std::string spell_name;
|
|
||||||
uint32 spell_id;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(resurrecter_name),
|
|
||||||
CEREAL_NVP(spell_name),
|
|
||||||
CEREAL_NVP(spell_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CombineEvent {
|
|
||||||
uint32 recipe_id;
|
|
||||||
std::string recipe_name;
|
|
||||||
uint32 made_count;
|
|
||||||
uint32 tradeskill_id;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(recipe_id),
|
|
||||||
CEREAL_NVP(recipe_name),
|
|
||||||
CEREAL_NVP(made_count),
|
|
||||||
CEREAL_NVP(tradeskill_id)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DroppedItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int16 slot_id;
|
|
||||||
uint32 charges;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(slot_id),
|
|
||||||
CEREAL_NVP(charges)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DeathEvent {
|
|
||||||
uint32 killer_id;
|
|
||||||
std::string killer_name;
|
|
||||||
int64 damage;
|
|
||||||
uint32 spell_id;
|
|
||||||
std::string spell_name;
|
|
||||||
int skill_id;
|
|
||||||
std::string skill_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(killer_id),
|
|
||||||
CEREAL_NVP(killer_name),
|
|
||||||
CEREAL_NVP(damage),
|
|
||||||
CEREAL_NVP(spell_id),
|
|
||||||
CEREAL_NVP(spell_name),
|
|
||||||
CEREAL_NVP(skill_id),
|
|
||||||
CEREAL_NVP(skill_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SplitMoneyEvent {
|
|
||||||
uint32 copper;
|
|
||||||
uint32 silver;
|
|
||||||
uint32 gold;
|
|
||||||
uint32 platinum;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(copper),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(platinum),
|
|
||||||
CEREAL_NVP(player_money_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraderPurchaseEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint32 trader_id;
|
|
||||||
std::string trader_name;
|
|
||||||
uint32 price;
|
|
||||||
uint32 charges;
|
|
||||||
uint32 total_cost;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(trader_id),
|
|
||||||
CEREAL_NVP(trader_name),
|
|
||||||
CEREAL_NVP(price),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(total_cost),
|
|
||||||
CEREAL_NVP(player_money_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraderSellEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint32 buyer_id;
|
|
||||||
std::string buyer_name;
|
|
||||||
uint32 price;
|
|
||||||
uint32 charges;
|
|
||||||
uint32 total_cost;
|
|
||||||
uint64 player_money_balance;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(buyer_id),
|
|
||||||
CEREAL_NVP(buyer_name),
|
|
||||||
CEREAL_NVP(price),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(total_cost),
|
|
||||||
CEREAL_NVP(player_money_balance)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscoverItemEvent {
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class HandinEntry {
|
|
||||||
public:
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 charges;
|
|
||||||
bool attuned;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(attuned)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class HandinMoney {
|
|
||||||
public:
|
|
||||||
uint32 copper;
|
|
||||||
uint32 silver;
|
|
||||||
uint32 gold;
|
|
||||||
uint32 platinum;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(copper),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(platinum)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct HandinEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string npc_name;
|
|
||||||
std::vector<HandinEntry> handin_items;
|
|
||||||
HandinMoney handin_money;
|
|
||||||
std::vector<HandinEntry> return_items;
|
|
||||||
HandinMoney return_money;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(npc_name),
|
|
||||||
CEREAL_NVP(handin_items),
|
|
||||||
CEREAL_NVP(handin_money),
|
|
||||||
CEREAL_NVP(return_items),
|
|
||||||
CEREAL_NVP(return_money)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PossibleHackEvent {
|
|
||||||
std::string message;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct KilledNPCEvent {
|
|
||||||
uint32 npc_id;
|
|
||||||
std::string npc_name;
|
|
||||||
uint32 combat_time_seconds;
|
|
||||||
uint64 total_damage_per_second_taken;
|
|
||||||
uint64 total_heal_per_second_taken;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(npc_id),
|
|
||||||
CEREAL_NVP(npc_name),
|
|
||||||
CEREAL_NVP(combat_time_seconds),
|
|
||||||
CEREAL_NVP(total_damage_per_second_taken),
|
|
||||||
CEREAL_NVP(total_heal_per_second_taken)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENTS_H
|
|
||||||
|
|
||||||
#define RecordPlayerEventLog(event_type, event_data) do {\
|
|
||||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
|
||||||
worldserver.SendPacket(\
|
|
||||||
player_event_logs.RecordEvent(\
|
|
||||||
event_type,\
|
|
||||||
GetPlayerEvent(),\
|
|
||||||
event_data\
|
|
||||||
).get()\
|
|
||||||
);\
|
|
||||||
}\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
|
||||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
|
||||||
worldserver.SendPacket(\
|
|
||||||
player_event_logs.RecordEvent(\
|
|
||||||
event_type,\
|
|
||||||
(c)->GetPlayerEvent(),\
|
|
||||||
event_data\
|
|
||||||
).get()\
|
|
||||||
);\
|
|
||||||
}\
|
|
||||||
} while (0)
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "expedition_lockout_timer.h"
|
#include "expedition_lockout_timer.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/util/uuid.h"
|
#include "../common/util/uuid.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|||||||
+24
-24
@@ -20,31 +20,31 @@
|
|||||||
#include "races.h"
|
#include "races.h"
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
|
|
||||||
const char *FactionValueToString(FACTION_VALUE faction_value)
|
const char *FactionValueToString(FACTION_VALUE fv)
|
||||||
{
|
{
|
||||||
switch (faction_value) {
|
switch (fv) {
|
||||||
case FACTION_ALLY:
|
case FACTION_ALLY:
|
||||||
return "Ally";
|
return ("Ally");
|
||||||
case FACTION_WARMLY:
|
case FACTION_WARMLY:
|
||||||
return "Warmly";
|
return ("Warmly");
|
||||||
case FACTION_KINDLY:
|
case FACTION_KINDLY:
|
||||||
return "Kindly";
|
return ("Kindly");
|
||||||
case FACTION_AMIABLY:
|
case FACTION_AMIABLE:
|
||||||
return "Amiably";
|
return ("Amiable");
|
||||||
case FACTION_INDIFFERENTLY:
|
case FACTION_INDIFFERENT:
|
||||||
return "Indifferently";
|
return ("Indifferent");
|
||||||
case FACTION_APPREHENSIVELY:
|
case FACTION_APPREHENSIVE:
|
||||||
return "Apprehensively";
|
return ("Apprehensive");
|
||||||
case FACTION_DUBIOUSLY:
|
case FACTION_DUBIOUS:
|
||||||
return "Dubiously";
|
return ("Dubious");
|
||||||
case FACTION_THREATENINGLY:
|
case FACTION_THREATENLY:
|
||||||
return "Threateningly";
|
return ("Threatenly");
|
||||||
case FACTION_SCOWLS:
|
case FACTION_SCOWLS:
|
||||||
return "Scowls";
|
return ("Scowls, ready to attack.");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return "Unknown";
|
return ("Unknown Faction Con");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -70,19 +70,19 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
|
|||||||
return FACTION_KINDLY;
|
return FACTION_KINDLY;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
|
||||||
return FACTION_AMIABLY;
|
return FACTION_AMIABLE;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
|
||||||
return FACTION_INDIFFERENTLY;
|
return FACTION_INDIFFERENT;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
|
||||||
return FACTION_APPREHENSIVELY;
|
return FACTION_APPREHENSIVE;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
|
||||||
return FACTION_DUBIOUSLY;
|
return FACTION_DUBIOUS;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
|
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
|
||||||
return FACTION_THREATENINGLY;
|
return FACTION_THREATENLY;
|
||||||
}
|
}
|
||||||
return FACTION_SCOWLS;
|
return FACTION_SCOWLS;
|
||||||
}
|
}
|
||||||
@@ -96,12 +96,12 @@ bool IsOfEqualRace(int r1, int r2)
|
|||||||
// TODO: add more values
|
// TODO: add more values
|
||||||
switch (r1) {
|
switch (r1) {
|
||||||
case DARK_ELF:
|
case DARK_ELF:
|
||||||
if (r2 == RACE_NERIAK_CITIZEN_77) {
|
if (r2 == 77) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BARBARIAN:
|
case BARBARIAN:
|
||||||
if (r2 == RACE_HALAS_CITIZEN_90) {
|
if (r2 == 90) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-23
@@ -27,13 +27,13 @@ enum FACTION_VALUE {
|
|||||||
FACTION_ALLY = 1,
|
FACTION_ALLY = 1,
|
||||||
FACTION_WARMLY = 2,
|
FACTION_WARMLY = 2,
|
||||||
FACTION_KINDLY = 3,
|
FACTION_KINDLY = 3,
|
||||||
FACTION_AMIABLY = 4,
|
FACTION_AMIABLE = 4,
|
||||||
|
|
||||||
FACTION_INDIFFERENTLY = 5,
|
FACTION_INDIFFERENT = 5,
|
||||||
|
|
||||||
FACTION_APPREHENSIVELY = 6,
|
FACTION_APPREHENSIVE = 6,
|
||||||
FACTION_DUBIOUSLY = 7,
|
FACTION_DUBIOUS = 7,
|
||||||
FACTION_THREATENINGLY = 8,
|
FACTION_THREATENLY = 8,
|
||||||
FACTION_SCOWLS = 9
|
FACTION_SCOWLS = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,23 +75,6 @@ struct NPCFaction
|
|||||||
uint8 temp;
|
uint8 temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Faction Associations give a much more live like faction system
|
const char *FactionValueToString(FACTION_VALUE fv);
|
||||||
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
|
|
||||||
|
|
||||||
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
|
|
||||||
#define MAX_FACTION_ASSOC 10
|
|
||||||
|
|
||||||
// this is the ID of a faction association and it's multiplier
|
|
||||||
struct FactionAssociationHit {
|
|
||||||
int id;
|
|
||||||
float multiplier;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FactionAssociations {
|
|
||||||
// maybe there should be more data here, fine for now
|
|
||||||
FactionAssociationHit hits[MAX_FACTION_ASSOC];
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *FactionValueToString(FACTION_VALUE faction_value);
|
|
||||||
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -204,7 +204,7 @@ enum { //some random constants
|
|||||||
#define MIN_LEVEL_ALCHEMY 25
|
#define MIN_LEVEL_ALCHEMY 25
|
||||||
|
|
||||||
//chance ratio that a
|
//chance ratio that a
|
||||||
#define THREATENINGLY_AGGRO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
|
#define THREATENLY_ARRGO_CHANCE 32 // 32/128 (25%) chance that a mob will arrgo on con Threatenly
|
||||||
|
|
||||||
//max factions per npc faction list
|
//max factions per npc faction list
|
||||||
#define MAX_NPC_FACTIONS 20
|
#define MAX_NPC_FACTIONS 20
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "file.h"
|
#include "file_util.h"
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
@@ -35,48 +35,33 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name
|
* @param name
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool File::Exists(const std::string &name)
|
bool FileUtil::exists(const std::string &name)
|
||||||
{
|
{
|
||||||
return fs::exists(fs::path{name});
|
std::ifstream f(name.c_str());
|
||||||
|
|
||||||
|
return f.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param directory_name
|
* @param directory_name
|
||||||
*/
|
*/
|
||||||
void File::Makedir(const std::string &directory_name)
|
void FileUtil::mkdir(const std::string& directory_name)
|
||||||
{
|
{
|
||||||
fs::create_directory(directory_name);
|
|
||||||
fs::permissions(directory_name, fs::perms::owner_all);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string File::FindEqemuConfigPath()
|
#ifdef _WINDOWS
|
||||||
{
|
struct _stat st;
|
||||||
if (File::Exists(fs::path{File::GetCwd() + "/eqemu_config.json"}.string())) {
|
if (_stat(directory_name.c_str(), &st) == 0) // exists
|
||||||
return File::GetCwd();
|
return;
|
||||||
|
_mkdir(directory_name.c_str());
|
||||||
|
#else
|
||||||
|
struct stat st{};
|
||||||
|
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (File::Exists(fs::path{File::GetCwd() + "/../eqemu_config.json"}.string())) {
|
::mkdir(directory_name.c_str(), 0755);
|
||||||
return canonical(fs::path{File::GetCwd() + "/../"}).string();
|
#endif
|
||||||
}
|
|
||||||
else if (File::Exists(fs::path{File::GetCwd() + "/login.json"}.string())) {
|
|
||||||
return File::GetCwd();
|
|
||||||
}
|
|
||||||
else if (File::Exists(fs::path{File::GetCwd() + "/../login.json"}.string())) {
|
|
||||||
return canonical(fs::path{File::GetCwd() + "/../"}).string();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string File::GetCwd()
|
|
||||||
{
|
|
||||||
return fs::current_path().string();
|
|
||||||
}
|
}
|
||||||
@@ -18,21 +18,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_FILE_H
|
#ifndef EQEMU_FILE_UTIL_H
|
||||||
#define EQEMU_FILE_H
|
#define EQEMU_FILE_UTIL_H
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
class FileUtil {
|
||||||
|
|
||||||
class File {
|
|
||||||
public:
|
public:
|
||||||
static bool Exists(const std::string &name);
|
static bool exists(const std::string &name);
|
||||||
static void Makedir(const std::string& directory_name);
|
static void mkdir(const std::string& directory_name);
|
||||||
static std::string FindEqemuConfigPath();
|
|
||||||
static std::string GetCwd();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Exists(const std::string& name);
|
|
||||||
|
|
||||||
#endif //EQEMU_FILE_H
|
#endif //EQEMU_FILE_UTIL_H
|
||||||
+22
-70
@@ -20,7 +20,7 @@
|
|||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
//#include "misc_functions.h"
|
//#include "misc_functions.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@@ -63,9 +63,7 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
|
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
|
||||||
|
|
||||||
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
|
query = "SELECT guild_id,rank,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
|
||||||
|
|
||||||
query = "SELECT guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace FROM guild_ranks";
|
|
||||||
results = m_db->QueryDatabase(query);
|
results = m_db->QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
@@ -133,7 +131,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(row[2]), row[3], row[4], row[5], row[6]);
|
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(row[2]), row[3], row[4], row[5], row[6]);
|
||||||
|
|
||||||
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
query = StringFormat("SELECT guild_id, rank, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
||||||
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
||||||
results = m_db->QueryDatabase(query);
|
results = m_db->QueryDatabase(query);
|
||||||
|
|
||||||
@@ -270,7 +268,7 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
|||||||
m_db->DoEscapeString(title_esc, rankInfo.name.c_str(), rankInfo.name.length());
|
m_db->DoEscapeString(title_esc, rankInfo.name.c_str(), rankInfo.name.length());
|
||||||
|
|
||||||
query = StringFormat("INSERT INTO guild_ranks "
|
query = StringFormat("INSERT INTO guild_ranks "
|
||||||
"(guild_id,`rank`,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace)"
|
"(guild_id,rank,title,can_hear,can_speak,can_invite,can_remove,can_promote,can_demote,can_motd,can_warpeace)"
|
||||||
" VALUES(%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%d)",
|
" VALUES(%d,%d,'%s',%d,%d,%d,%d,%d,%d,%d,%d)",
|
||||||
guild_id, rank, title_esc,
|
guild_id, rank, title_esc,
|
||||||
rankInfo.permissions[GUILD_HEAR],
|
rankInfo.permissions[GUILD_HEAR],
|
||||||
@@ -740,7 +738,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
|||||||
std::string query;
|
std::string query;
|
||||||
|
|
||||||
if(guild_id != GUILD_NONE) {
|
if(guild_id != GUILD_NONE) {
|
||||||
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,`rank`,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
|
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -760,7 +758,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
|
bool BaseGuildManager::DBSetGuildRank(uint32 charid, uint8 rank) {
|
||||||
std::string query = StringFormat("UPDATE guild_members SET `rank`=%d WHERE char_id=%d", rank, charid);
|
std::string query = StringFormat("UPDATE guild_members SET rank=%d WHERE char_id=%d", rank, charid);
|
||||||
return(QueryWithLogging(query, "setting a guild member's rank"));
|
return(QueryWithLogging(query, "setting a guild member's rank"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,11 +864,20 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//factored out so I dont have to copy this crap.
|
||||||
|
#ifdef BOTS
|
||||||
|
#define GuildMemberBaseQuery \
|
||||||
|
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
|
||||||
|
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
|
||||||
|
" g.`banker`, g.`public_note`, g.`alt`" \
|
||||||
|
" FROM `vw_bot_character_mobs` AS c LEFT JOIN `vw_guild_members` AS g ON c.`id` = g.`char_id` AND c.`mob_type` = g.`mob_type` "
|
||||||
|
#else
|
||||||
#define GuildMemberBaseQuery \
|
#define GuildMemberBaseQuery \
|
||||||
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
|
"SELECT c.`id`, c.`name`, c.`class`, c.`level`, c.`last_login`, c.`zone_id`," \
|
||||||
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
|
" g.`guild_id`, g.`rank`, g.`tribute_enable`, g.`total_tribute`, g.`last_tribute`," \
|
||||||
" g.`banker`, g.`public_note`, g.`alt` " \
|
" g.`banker`, g.`public_note`, g.`alt` " \
|
||||||
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
||||||
|
#endif
|
||||||
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
||||||
//fields from `characer_`
|
//fields from `characer_`
|
||||||
into.char_id = atoi(row[0]);
|
into.char_id = atoi(row[0]);
|
||||||
@@ -960,7 +967,12 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//load up the rank info for each guild.
|
//load up the rank info for each guild.
|
||||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
|
std::string query;
|
||||||
|
#ifdef BOTS
|
||||||
|
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C' AND c.deleted_at IS NULL", char_id);
|
||||||
|
#else
|
||||||
|
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
|
||||||
|
#endif
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1196,7 +1208,7 @@ BaseGuildManager::RankInfo::RankInfo() {
|
|||||||
|
|
||||||
BaseGuildManager::GuildInfo::GuildInfo() {
|
BaseGuildManager::GuildInfo::GuildInfo() {
|
||||||
leader_char_id = 0;
|
leader_char_id = 0;
|
||||||
minstatus = AccountStatus::Player;
|
minstatus = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
||||||
@@ -1213,66 +1225,6 @@ uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
|||||||
return results.RowCount();
|
return results.RowCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGuildManager::GetGuildNameByID(uint32 guild_id) const {
|
|
||||||
if(guild_id == GUILD_NONE) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
|
||||||
res = m_guilds.find(guild_id);
|
|
||||||
if(res == m_guilds.end()) {
|
|
||||||
return "Invalid Guild";
|
|
||||||
}
|
|
||||||
|
|
||||||
return res->second->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string BaseGuildManager::GetGuildRankName(uint32 guild_id, uint8 rank) const
|
|
||||||
{
|
|
||||||
if(rank > GUILD_MAX_RANK) {
|
|
||||||
return "Invalid Rank";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
|
||||||
res = m_guilds.find(guild_id);
|
|
||||||
if(res == m_guilds.end()) {
|
|
||||||
return "Invalid Guild Rank";
|
|
||||||
}
|
|
||||||
|
|
||||||
return res->second->ranks[rank].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id)
|
|
||||||
{
|
|
||||||
if(!m_db) {
|
|
||||||
return GUILD_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string query = fmt::format(
|
|
||||||
"SELECT `guild_id` FROM `guild_members` WHERE char_id = {} LIMIT 1",
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = m_db->QueryDatabase(query);
|
|
||||||
if(!results.Success() || !results.RowCount()) {
|
|
||||||
return GUILD_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
auto guild_id = std::stoul(row[0]);
|
|
||||||
return guild_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BaseGuildManager::IsCharacterInGuild(uint32 character_id, uint32 guild_id)
|
|
||||||
{
|
|
||||||
auto current_guild_id = GetGuildIDByCharacterID(character_id);
|
|
||||||
|
|
||||||
if (current_guild_id == GUILD_NONE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (guild_id && current_guild_id != guild_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -76,12 +76,8 @@ class BaseGuildManager
|
|||||||
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
bool GetGuildChannel(uint32 GuildID, char *ChannelBuffer) const;
|
||||||
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
const char *GetRankName(uint32 guild_id, uint8 rank) const;
|
||||||
const char *GetGuildName(uint32 guild_id) const;
|
const char *GetGuildName(uint32 guild_id) const;
|
||||||
std::string GetGuildNameByID(uint32 guild_id) const;
|
|
||||||
std::string GetGuildRankName(uint32 guild_id, uint8 rank) const;
|
|
||||||
bool IsCharacterInGuild(uint32 character_id, uint32 guild_id = 0);
|
|
||||||
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
bool GetGuildNameByID(uint32 guild_id, std::string &into) const;
|
||||||
uint32 GetGuildIDByName(const char *GuildName);
|
uint32 GetGuildIDByName(const char *GuildName);
|
||||||
uint32 GetGuildIDByCharacterID(uint32 character_id);
|
|
||||||
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
bool IsGuildLeader(uint32 guild_id, uint32 char_id) const;
|
||||||
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
uint8 GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 char_id) const;
|
||||||
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
bool CheckGMStatus(uint32 guild_id, uint8 status) const;
|
||||||
|
|||||||
+1418
-2141
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@
|
|||||||
//#include "races.h"
|
//#include "races.h"
|
||||||
//#include "rulesys.h"
|
//#include "rulesys.h"
|
||||||
//#include "shareddb.h"
|
//#include "shareddb.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
#include "../common/light_source.h"
|
#include "../common/light_source.h"
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove item from inventory (with memory delete)
|
// Remove item from inventory (with memory delete)
|
||||||
bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
|
bool EQ::InventoryProfile::DeleteItem(int16 slot_id, uint8 quantity) {
|
||||||
// Pop item out of inventory map (or queue)
|
// Pop item out of inventory map (or queue)
|
||||||
ItemInstance *item_to_delete = PopItem(slot_id);
|
ItemInstance *item_to_delete = PopItem(slot_id);
|
||||||
|
|
||||||
@@ -590,68 +590,6 @@ bool EQ::InventoryProfile::HasSpaceForItem(const ItemData *ItemToTry, int16 Quan
|
|||||||
// Checks that user has at least 'quantity' number of items in a given inventory slot
|
// Checks that user has at least 'quantity' number of items in a given inventory slot
|
||||||
// Returns first slot it was found in, or SLOT_INVALID if not found
|
// Returns first slot it was found in, or SLOT_INVALID if not found
|
||||||
|
|
||||||
bool EQ::InventoryProfile::HasAugmentEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
bool has_equipped = false;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->ContainsAugmentByID(item_id)) {
|
|
||||||
has_equipped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return has_equipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::InventoryProfile::CountAugmentEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
int quantity = 0;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->ContainsAugmentByID(item_id)) {
|
|
||||||
quantity += item->CountAugmentByID(item_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQ::InventoryProfile::HasItemEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
bool has_equipped = false;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->GetID() == item_id) {
|
|
||||||
has_equipped = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return has_equipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::InventoryProfile::CountItemEquippedByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
int quantity = 0;
|
|
||||||
ItemInstance* item = nullptr;
|
|
||||||
|
|
||||||
for (int slot_id = EQ::invslot::EQUIPMENT_BEGIN; slot_id <= EQ::invslot::EQUIPMENT_END; ++slot_id) {
|
|
||||||
item = GetItem(slot_id);
|
|
||||||
if (item && item->GetID() == item_id) {
|
|
||||||
quantity += item->IsStackable() ? item->GetCharges() : 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This function has a flaw in that it only returns the last stack that it looked at
|
//This function has a flaw in that it only returns the last stack that it looked at
|
||||||
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
|
//when quantity is greater than 1 and not all of quantity can be found in 1 stack.
|
||||||
int16 EQ::InventoryProfile::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
int16 EQ::InventoryProfile::HasItem(uint32 item_id, uint8 quantity, uint8 where)
|
||||||
@@ -1718,17 +1656,3 @@ int16 EQ::InventoryProfile::_HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 lo
|
|||||||
|
|
||||||
return EQ::invslot::SLOT_INVALID;
|
return EQ::invslot::SLOT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32> EQ::InventoryProfile::GetAugmentIDsBySlotID(int16 slot_id)
|
|
||||||
{
|
|
||||||
std::vector<uint32> augments;
|
|
||||||
const auto* item = GetItem(slot_id);
|
|
||||||
|
|
||||||
if (item) {
|
|
||||||
for (uint8 i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
|
|
||||||
augments.push_back(item->GetAugment(i) ? item->GetAugmentItemID(i) : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return augments;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -26,11 +26,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "item_instance.h"
|
#include "item_instance.h"
|
||||||
#include "classes.h"
|
|
||||||
#include "races.h"
|
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
//FatherNitwit: location bits for searching specific
|
//FatherNitwit: location bits for searching specific
|
||||||
@@ -132,10 +129,10 @@ namespace EQ
|
|||||||
|
|
||||||
// Swap items in inventory
|
// Swap items in inventory
|
||||||
enum SwapItemFailState : int8 { swapInvalid = -1, swapPass = 0, swapNotAllowed, swapNullData, swapRaceClass, swapDeity, swapLevel };
|
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_0, uint8 class_id = NO_CLASS, uint16 deity_id = deity::DeityType::DeityUnknown, uint8 level = 0);
|
bool SwapItem(int16 source_slot, int16 destination_slot, SwapItemFailState& fail_state, uint16 race_id = 0, uint8 class_id = 0, uint16 deity_id = 0, uint8 level = 0);
|
||||||
|
|
||||||
// Remove item from inventory
|
// Remove item from inventory
|
||||||
bool DeleteItem(int16 slot_id, int16 quantity = 0);
|
bool DeleteItem(int16 slot_id, uint8 quantity = 0);
|
||||||
|
|
||||||
// Checks All items in a bag for No Drop
|
// Checks All items in a bag for No Drop
|
||||||
bool CheckNoDrop(int16 slot_id, bool recurse = true);
|
bool CheckNoDrop(int16 slot_id, bool recurse = true);
|
||||||
@@ -143,21 +140,6 @@ namespace EQ
|
|||||||
// Remove item from inventory (and take control of memory)
|
// Remove item from inventory (and take control of memory)
|
||||||
ItemInstance* PopItem(int16 slot_id);
|
ItemInstance* PopItem(int16 slot_id);
|
||||||
|
|
||||||
// Check if player has a specific item equipped by Item ID
|
|
||||||
bool HasItemEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Check how many of a specific item the player has equipped by Item ID
|
|
||||||
int CountItemEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Check if player has a specific augment equipped by Item ID
|
|
||||||
bool HasAugmentEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Check how many of a specific augment the player has equipped by Item ID
|
|
||||||
int CountAugmentEquippedByID(uint32 item_id);
|
|
||||||
|
|
||||||
// Get a list of augments from a specific slot ID
|
|
||||||
std::vector<uint32> GetAugmentIDsBySlotID(int16 slot_id);
|
|
||||||
|
|
||||||
// Check whether there is space for the specified number of the specified item.
|
// Check whether there is space for the specified number of the specified item.
|
||||||
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
|
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
|
||||||
|
|
||||||
@@ -208,7 +190,7 @@ namespace EQ
|
|||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||||
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||||
static const int GetItemStatValue(uint32 item_id, std::string identifier);
|
static int GetItemStatValue(uint32 item_id, const char* identifier);
|
||||||
protected:
|
protected:
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Protected Methods
|
// Protected Methods
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "inventory_slot.h"
|
#include "inventory_slot.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
|
|
||||||
int8 EQ::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
|
int8 EQ::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
|
||||||
|
|||||||
@@ -18,17 +18,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <csignal>
|
|
||||||
#include <vector>
|
|
||||||
#include "ip_util.h"
|
#include "ip_util.h"
|
||||||
#include "http/httplib.h"
|
|
||||||
#include "http/uri.h"
|
|
||||||
#include "eqemu_logsys.h"
|
|
||||||
#include "event/event_loop.h"
|
|
||||||
#include "net/dns.h"
|
|
||||||
#include "event/task_scheduler.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ip
|
* @param ip
|
||||||
@@ -80,148 +70,3 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
|||||||
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
|
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets local address - pings google to inspect what interface was used locally
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string IpUtil::GetLocalIPAddress()
|
|
||||||
{
|
|
||||||
char my_ip_address[16];
|
|
||||||
unsigned int my_port;
|
|
||||||
struct sockaddr_in server_address{};
|
|
||||||
struct sockaddr_in my_address{};
|
|
||||||
int sockfd;
|
|
||||||
|
|
||||||
// Connect to server
|
|
||||||
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set server_addr
|
|
||||||
memset(&server_address, 0, sizeof(server_address));
|
|
||||||
server_address.sin_family = AF_INET;
|
|
||||||
server_address.sin_addr.s_addr = inet_addr("172.217.160.99");
|
|
||||||
server_address.sin_port = htons(80);
|
|
||||||
|
|
||||||
// Connect to server
|
|
||||||
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
|
|
||||||
close(sockfd);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
return fmt::format("{}", my_ip_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets public address
|
|
||||||
* Uses various websites as options to return raw public IP back to the client
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string IpUtil::GetPublicIPAddress()
|
|
||||||
{
|
|
||||||
std::vector<std::string> endpoints = {
|
|
||||||
"http://ifconfig.me",
|
|
||||||
"http://api.ipify.org",
|
|
||||||
"http://ipinfo.io/ip",
|
|
||||||
"http://ipecho.net/plain",
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto &s: endpoints) {
|
|
||||||
// http get request
|
|
||||||
uri u(s);
|
|
||||||
|
|
||||||
httplib::Client r(
|
|
||||||
fmt::format(
|
|
||||||
"{}://{}",
|
|
||||||
u.get_scheme(),
|
|
||||||
u.get_host()
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
httplib::Headers headers = {
|
|
||||||
{"Content-type", "text/plain; charset=utf-8"},
|
|
||||||
{"User-Agent", "curl/7.81.0"}
|
|
||||||
};
|
|
||||||
|
|
||||||
r.set_connection_timeout(1, 0);
|
|
||||||
r.set_read_timeout(1, 0);
|
|
||||||
r.set_write_timeout(1, 0);
|
|
||||||
|
|
||||||
if (auto res = r.Get(fmt::format("/{}", u.get_path()).c_str(), headers)) {
|
|
||||||
if (res->status == 200) {
|
|
||||||
if (res->body.find('.') != std::string::npos) {
|
|
||||||
return res->body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string IpUtil::DNSLookupSync(const std::string &addr, int port)
|
|
||||||
{
|
|
||||||
auto task_runner = new EQ::Event::TaskScheduler();
|
|
||||||
auto res = task_runner->Enqueue(
|
|
||||||
[&]() -> std::string {
|
|
||||||
bool running = true;
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
EQ::Net::DNSLookup(
|
|
||||||
addr, port, false, [&](const std::string &addr) {
|
|
||||||
ret = addr;
|
|
||||||
if (addr.empty()) {
|
|
||||||
ret = "";
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
auto &loop = EQ::EventLoop::Get();
|
|
||||||
while (running) {
|
|
||||||
if (!ret.empty()) {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
|
||||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() > 1500) {
|
|
||||||
LogInfo(
|
|
||||||
"Deadline exceeded [{}]",
|
|
||||||
1500
|
|
||||||
);
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop.Process();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string result = res.get();
|
|
||||||
safe_delete(task_runner);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IpUtil::IsIPAddress(const std::string &ip_address)
|
|
||||||
{
|
|
||||||
struct sockaddr_in sa{};
|
|
||||||
int result = inet_pton(AF_INET, ip_address.c_str(), &(sa.sin_addr));
|
|
||||||
return result != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,6 @@ public:
|
|||||||
static uint32_t IPToUInt(const std::string &ip);
|
static uint32_t IPToUInt(const std::string &ip);
|
||||||
static bool IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask);
|
static bool IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask);
|
||||||
static bool IsIpInPrivateRfc1918(const std::string &ip);
|
static bool IsIpInPrivateRfc1918(const std::string &ip);
|
||||||
static std::string GetLocalIPAddress();
|
|
||||||
static std::string GetPublicIPAddress();
|
|
||||||
static std::string DNSLookupSync(
|
|
||||||
const std::string &addr,
|
|
||||||
int port
|
|
||||||
);
|
|
||||||
static bool IsIPAddress(const std::string &ip_address);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "eqemu_exception.h"
|
#include "eqemu_exception.h"
|
||||||
#include "eqemu_config.h"
|
#include "eqemu_config.h"
|
||||||
#include "path_manager.h"
|
|
||||||
|
|
||||||
namespace EQ {
|
namespace EQ {
|
||||||
struct IPCMutex::Implementation {
|
struct IPCMutex::Implementation {
|
||||||
@@ -41,11 +40,12 @@ namespace EQ {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
IPCMutex::IPCMutex(const std::string& name) : locked_(false) {
|
IPCMutex::IPCMutex(std::string name) : locked_(false) {
|
||||||
imp_ = new Implementation;
|
imp_ = new Implementation;
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
auto Config = EQEmuConfig::get();
|
auto Config = EQEmuConfig::get();
|
||||||
std::string final_name = fmt::format("{}/EQEmuMutex_{}", Config->SharedMemDir, name);
|
std::string final_name = Config->SharedMemDir + "EQEmuMutex_";
|
||||||
|
final_name += name;
|
||||||
|
|
||||||
imp_->mut_ = CreateMutex(nullptr,
|
imp_->mut_ = CreateMutex(nullptr,
|
||||||
FALSE,
|
FALSE,
|
||||||
@@ -55,7 +55,9 @@ namespace EQ {
|
|||||||
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
|
EQ_EXCEPT("IPC Mutex", "Could not create mutex.");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::string final_name = fmt::format("{}/{}.lock", path.GetSharedMemoryPath(), name);
|
auto Config = EQEmuConfig::get();
|
||||||
|
std::string final_name = Config->SharedMemDir + name;
|
||||||
|
final_name += ".lock";
|
||||||
|
|
||||||
#ifdef __DARWIN
|
#ifdef __DARWIN
|
||||||
#if __DARWIN_C_LEVEL < 200809L
|
#if __DARWIN_C_LEVEL < 200809L
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ namespace EQ {
|
|||||||
Creates a named binary semaphore, basically a semaphore that is init S <- 1
|
Creates a named binary semaphore, basically a semaphore that is init S <- 1
|
||||||
\param name The name of this mutex.
|
\param name The name of this mutex.
|
||||||
*/
|
*/
|
||||||
IPCMutex(const std::string& name);
|
IPCMutex(std::string name);
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
~IPCMutex();
|
~IPCMutex();
|
||||||
|
|||||||
+2
-24
@@ -169,33 +169,11 @@ uint8 EQ::item::ConvertAugTypeBitToAugType(uint32 aug_type_bit)
|
|||||||
|
|
||||||
bool EQ::ItemData::IsEquipable(uint16 race_id, uint16 class_id) const
|
bool EQ::ItemData::IsEquipable(uint16 race_id, uint16 class_id) const
|
||||||
{
|
{
|
||||||
if (!(Races & GetPlayerRaceBit(race_id))) {
|
if (!(Races & GetPlayerRaceBit(race_id)))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!(Classes & GetPlayerClassBit(GetPlayerClassValue(class_id)))) {
|
if (!(Classes & GetPlayerClassBit(GetPlayerClassValue(class_id))))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQ::ItemData::IsClassEquipable(uint16 class_id) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!(Classes & GetPlayerClassBit(GetPlayerClassValue(class_id)))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQ::ItemData::IsRaceEquipable(uint16 race_id) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!(Races & GetPlayerRaceBit(race_id))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-11
@@ -370,7 +370,7 @@ namespace EQ
|
|||||||
uint32 Slots; // Bitfield for which slots this item can be used in
|
uint32 Slots; // Bitfield for which slots this item can be used in
|
||||||
uint32 Price; // Item cost (?)
|
uint32 Price; // Item cost (?)
|
||||||
uint32 Icon; // Icon Number
|
uint32 Icon; // Icon Number
|
||||||
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
|
uint32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
|
||||||
bool LoreFlag; // This will be true if LoreGroup is non-zero
|
bool LoreFlag; // This will be true if LoreGroup is non-zero
|
||||||
bool PendingLoreFlag;
|
bool PendingLoreFlag;
|
||||||
bool ArtifactFlag;
|
bool ArtifactFlag;
|
||||||
@@ -473,14 +473,14 @@ namespace EQ
|
|||||||
uint32 LDoNSold;
|
uint32 LDoNSold;
|
||||||
uint32 BaneDmgRaceAmt;
|
uint32 BaneDmgRaceAmt;
|
||||||
uint32 AugRestrict;
|
uint32 AugRestrict;
|
||||||
int32 Endur;
|
uint32 Endur;
|
||||||
int32 DotShielding;
|
uint32 DotShielding;
|
||||||
int32 Attack;
|
uint32 Attack;
|
||||||
int32 Regen;
|
uint32 Regen;
|
||||||
int32 ManaRegen;
|
uint32 ManaRegen;
|
||||||
int32 EnduranceRegen;
|
uint32 EnduranceRegen;
|
||||||
int32 Haste;
|
uint32 Haste;
|
||||||
int32 DamageShield;
|
uint32 DamageShield;
|
||||||
uint32 RecastDelay;
|
uint32 RecastDelay;
|
||||||
int RecastType;
|
int RecastType;
|
||||||
uint32 AugDistiller;
|
uint32 AugDistiller;
|
||||||
@@ -533,8 +533,6 @@ namespace EQ
|
|||||||
//BardName
|
//BardName
|
||||||
|
|
||||||
bool IsEquipable(uint16 Race, uint16 Class) const;
|
bool IsEquipable(uint16 Race, uint16 Class) const;
|
||||||
bool IsClassEquipable(uint16 Class) const;
|
|
||||||
bool IsRaceEquipable(uint16 Race) const;
|
|
||||||
bool IsClassCommon() const;
|
bool IsClassCommon() const;
|
||||||
bool IsClassBag() const;
|
bool IsClassBag() const;
|
||||||
bool IsClassBook() const;
|
bool IsClassBook() const;
|
||||||
|
|||||||
+27
-126
@@ -23,7 +23,7 @@
|
|||||||
//#include "races.h"
|
//#include "races.h"
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
#include "shareddb.h"
|
#include "shareddb.h"
|
||||||
#include "strings.h"
|
#include "string_util.h"
|
||||||
|
|
||||||
//#include "../common/light_source.h"
|
//#include "../common/light_source.h"
|
||||||
|
|
||||||
@@ -263,43 +263,20 @@ bool EQ::ItemInstance::IsCharged() const
|
|||||||
// Can item be equipped?
|
// Can item be equipped?
|
||||||
bool EQ::ItemInstance::IsEquipable(uint16 race, uint16 class_) const
|
bool EQ::ItemInstance::IsEquipable(uint16 race, uint16 class_) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->Slots) {
|
if (!m_item || (m_item->Slots == 0))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return m_item->IsEquipable(race, class_);
|
return m_item->IsEquipable(race, class_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can item be equipped by Class?
|
|
||||||
bool EQ::ItemInstance::IsClassEquipable(uint16 class_) const
|
|
||||||
{
|
|
||||||
if (!m_item || !m_item->Slots) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_item->IsClassEquipable(class_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can item be equipped by Race?
|
|
||||||
bool EQ::ItemInstance::IsRaceEquipable(uint16 race) const
|
|
||||||
{
|
|
||||||
if (!m_item || !m_item->Slots) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_item->IsRaceEquipable(race);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can equip at this slot?
|
// Can equip at this slot?
|
||||||
bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
|
bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->Slots) {
|
if (!m_item)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (slot_id < EQ::invslot::EQUIPMENT_BEGIN || slot_id > EQ::invslot::EQUIPMENT_END) {
|
if (slot_id < EQ::invslot::EQUIPMENT_BEGIN || slot_id > EQ::invslot::EQUIPMENT_END)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return ((m_item->Slots & (1 << slot_id)) != 0);
|
return ((m_item->Slots & (1 << slot_id)) != 0);
|
||||||
}
|
}
|
||||||
@@ -332,52 +309,29 @@ bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
|
|||||||
return (index <= EQ::invslot::EQUIPMENT_END);
|
return (index <= EQ::invslot::EQUIPMENT_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augtype) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
|
||||||
|
|
||||||
auto i = invaug::SOCKET_BEGIN;
|
int index = invaug::SOCKET_BEGIN;
|
||||||
for (; i <= invaug::SOCKET_END; ++i) {
|
for (; index <= invaug::SOCKET_END; ++index) {
|
||||||
if (GetItem(i)) {
|
if (GetItem(index)) { continue; }
|
||||||
continue;
|
if (augtype == -1 || (m_item->AugSlotType[index] && ((1 << (m_item->AugSlotType[index] - 1)) & augtype)))
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
augment_type == -1 ||
|
|
||||||
(
|
|
||||||
m_item->AugSlotType[i] &&
|
|
||||||
((1 << (m_item->AugSlotType[i] - 1)) & augment_type)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
return (index <= invaug::SOCKET_END) ? index : INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) {
|
||||||
(
|
|
||||||
!GetItem(slot) &&
|
|
||||||
m_item->AugSlotVisible[slot]
|
|
||||||
) &&
|
|
||||||
augment_type == -1 ||
|
|
||||||
(
|
|
||||||
m_item->AugSlotType[slot] &&
|
|
||||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,11 +500,10 @@ bool EQ::ItemInstance::IsNoneEmptyContainer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve augment inside item
|
// Retrieve augment inside item
|
||||||
EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
|
EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 slot) const
|
||||||
{
|
{
|
||||||
if (m_item && m_item->IsClassCommon()) {
|
if (m_item && m_item->IsClassCommon())
|
||||||
return GetItem(augment_index);
|
return GetItem(slot);
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -573,7 +526,7 @@ EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugty
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return GetAugment(i);
|
return this->GetAugment(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,13 +629,12 @@ bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *C
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 EQ::ItemInstance::GetAugmentItemID(uint8 augment_index) const
|
uint32 EQ::ItemInstance::GetAugmentItemID(uint8 slot) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return GetItemID(augment_index);
|
return GetItemID(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an augment to the item
|
// Add an augment to the item
|
||||||
@@ -737,45 +689,6 @@ bool EQ::ItemInstance::IsAugmented()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::ContainsAugmentByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!item_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) {
|
|
||||||
if (GetAugmentItemID(augment_slot) == item_id) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::ItemInstance::CountAugmentByID(uint32 item_id)
|
|
||||||
{
|
|
||||||
int quantity = 0;
|
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!item_id) {
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8 augment_slot = invaug::SOCKET_BEGIN; augment_slot <= invaug::SOCKET_END; ++augment_slot) {
|
|
||||||
if (GetAugmentItemID(augment_slot) == item_id) {
|
|
||||||
quantity++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has attack/delay?
|
// Has attack/delay?
|
||||||
bool EQ::ItemInstance::IsWeapon() const
|
bool EQ::ItemInstance::IsWeapon() const
|
||||||
{
|
{
|
||||||
@@ -1145,7 +1058,7 @@ int EQ::ItemInstance::GetItemElementalFlag(bool augments) const
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemElementalDamage(bool augments) const
|
int EQ::ItemInstance::GetItemElementalDamage(bool augments) const
|
||||||
{
|
{
|
||||||
int64 damage = 0;
|
int damage = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
damage = item->ElemDmgAmt;
|
damage = item->ElemDmgAmt;
|
||||||
@@ -1210,7 +1123,7 @@ int EQ::ItemInstance::GetItemRequiredLevel(bool augments) const
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
|
int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
|
||||||
{
|
{
|
||||||
int64 damage = 0;
|
int damage = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
damage = item->Damage;
|
damage = item->Damage;
|
||||||
@@ -1226,7 +1139,7 @@ int EQ::ItemInstance::GetItemWeaponDamage(bool augments) const
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemBackstabDamage(bool augments) const
|
int EQ::ItemInstance::GetItemBackstabDamage(bool augments) const
|
||||||
{
|
{
|
||||||
int64 damage = 0;
|
int damage = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
damage = item->BackstabDmg;
|
damage = item->BackstabDmg;
|
||||||
@@ -1263,7 +1176,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bool augments) const
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
||||||
{
|
{
|
||||||
int race = RACE_DOUG_0;
|
int race = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
race = item->BaneDmgRace;
|
race = item->BaneDmgRace;
|
||||||
@@ -1284,7 +1197,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
|
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
|
||||||
{
|
{
|
||||||
int64 damage = 0;
|
int damage = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
if (item->BaneDmgBody == against)
|
if (item->BaneDmgBody == against)
|
||||||
@@ -1301,7 +1214,7 @@ int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) con
|
|||||||
|
|
||||||
int EQ::ItemInstance::GetItemBaneDamageRace(uint16 against, bool augments) const
|
int EQ::ItemInstance::GetItemBaneDamageRace(uint16 against, bool augments) const
|
||||||
{
|
{
|
||||||
int64 damage = 0;
|
int damage = 0;
|
||||||
const auto item = GetItem();
|
const auto item = GetItem();
|
||||||
if (item) {
|
if (item) {
|
||||||
if (item->BaneDmgRace == against)
|
if (item->BaneDmgRace == against)
|
||||||
@@ -1769,18 +1682,6 @@ int EQ::ItemInstance::GetItemHaste(bool augments) const
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EQ::ItemInstance::RemoveTaskDeliveredItems()
|
|
||||||
{
|
|
||||||
int count = IsStackable() ? GetCharges() : 1;
|
|
||||||
count -= GetTaskDeliveredCount();
|
|
||||||
if (IsStackable())
|
|
||||||
{
|
|
||||||
SetCharges(count);
|
|
||||||
}
|
|
||||||
SetTaskDeliveredCount(0);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// class EvolveInfo
|
// class EvolveInfo
|
||||||
//
|
//
|
||||||
|
|||||||
+4
-18
@@ -92,8 +92,6 @@ namespace EQ
|
|||||||
|
|
||||||
// Can item be equipped by/at?
|
// Can item be equipped by/at?
|
||||||
bool IsEquipable(uint16 race, uint16 class_) const;
|
bool IsEquipable(uint16 race, uint16 class_) const;
|
||||||
bool IsClassEquipable(uint16 class_) const;
|
|
||||||
bool IsRaceEquipable(uint16 race) const;
|
|
||||||
bool IsEquipable(int16 slot_id) const;
|
bool IsEquipable(int16 slot_id) const;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -101,8 +99,8 @@ namespace EQ
|
|||||||
//
|
//
|
||||||
bool IsAugmentable() const;
|
bool IsAugmentable() const;
|
||||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||||
int8 AvailableAugmentSlot(int32 augment_type) const;
|
int8 AvailableAugmentSlot(int32 augtype) const;
|
||||||
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
||||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||||
|
|
||||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||||
@@ -127,15 +125,13 @@ namespace EQ
|
|||||||
//
|
//
|
||||||
// Augments
|
// Augments
|
||||||
//
|
//
|
||||||
ItemInstance* GetAugment(uint8 augment_index) const;
|
ItemInstance* GetAugment(uint8 slot) const;
|
||||||
uint32 GetAugmentItemID(uint8 augment_index) const;
|
uint32 GetAugmentItemID(uint8 slot) const;
|
||||||
void PutAugment(uint8 slot, const ItemInstance& inst);
|
void PutAugment(uint8 slot, const ItemInstance& inst);
|
||||||
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
|
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
|
||||||
void DeleteAugment(uint8 slot);
|
void DeleteAugment(uint8 slot);
|
||||||
ItemInstance* RemoveAugment(uint8 index);
|
ItemInstance* RemoveAugment(uint8 index);
|
||||||
bool IsAugmented();
|
bool IsAugmented();
|
||||||
bool ContainsAugmentByID(uint32 item_id);
|
|
||||||
int CountAugmentByID(uint32 item_id);
|
|
||||||
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
||||||
bool UpdateOrnamentationInfo();
|
bool UpdateOrnamentationInfo();
|
||||||
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
||||||
@@ -150,8 +146,6 @@ namespace EQ
|
|||||||
const ItemData* GetItem() const;
|
const ItemData* GetItem() const;
|
||||||
const ItemData* GetUnscaledItem() const;
|
const ItemData* GetUnscaledItem() const;
|
||||||
|
|
||||||
const uint8 GetItemType() const { return m_item ? m_item->ItemType : 255; } // Return 255 so you know there's no valid item
|
|
||||||
|
|
||||||
int16 GetCharges() const { return m_charges; }
|
int16 GetCharges() const { return m_charges; }
|
||||||
void SetCharges(int16 charges) { m_charges = charges; }
|
void SetCharges(int16 charges) { m_charges = charges; }
|
||||||
|
|
||||||
@@ -233,13 +227,6 @@ namespace EQ
|
|||||||
void StopTimer(std::string name);
|
void StopTimer(std::string name);
|
||||||
void ClearTimers();
|
void ClearTimers();
|
||||||
|
|
||||||
int GetTaskDeliveredCount() const { return m_task_delivered_count; }
|
|
||||||
void SetTaskDeliveredCount(int count) { m_task_delivered_count = count; }
|
|
||||||
// This function should only be used by trade return apis
|
|
||||||
// Removes delivered task items from stack count and returns remaining count
|
|
||||||
// Return value should be used to determine if an item still exists (for stackable and non-stackable)
|
|
||||||
int RemoveTaskDeliveredItems();
|
|
||||||
|
|
||||||
// Get a total of a stat, including augs
|
// Get a total of a stat, including augs
|
||||||
// These functions should be used in place of other code manually totaling
|
// These functions should be used in place of other code manually totaling
|
||||||
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
|
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
|
||||||
@@ -324,7 +311,6 @@ namespace EQ
|
|||||||
uint32 m_new_id_file;
|
uint32 m_new_id_file;
|
||||||
uint32 m_ornament_hero_model;
|
uint32 m_ornament_hero_model;
|
||||||
uint32 m_recast_timestamp;
|
uint32 m_recast_timestamp;
|
||||||
int m_task_delivered_count = 0;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Items inside of this item (augs or contents);
|
// Items inside of this item (augs or contents);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -30,19 +30,11 @@ struct LootTableEntries_Struct {
|
|||||||
float probability;
|
float probability;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ContentFlags {
|
|
||||||
int16 min_expansion;
|
|
||||||
int16 max_expansion;
|
|
||||||
char content_flags[100];
|
|
||||||
char content_flags_disabled[100];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LootTable_Struct {
|
struct LootTable_Struct {
|
||||||
uint32 mincash;
|
uint32 mincash;
|
||||||
uint32 maxcash;
|
uint32 maxcash;
|
||||||
uint32 avgcoin;
|
uint32 avgcoin;
|
||||||
uint32 NumEntries;
|
uint32 NumEntries;
|
||||||
ContentFlags content_flags;
|
|
||||||
LootTableEntries_Struct Entries[0];
|
LootTableEntries_Struct Entries[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,7 +52,6 @@ struct LootDropEntries_Struct {
|
|||||||
|
|
||||||
struct LootDrop_Struct {
|
struct LootDrop_Struct {
|
||||||
uint32 NumEntries;
|
uint32 NumEntries;
|
||||||
ContentFlags content_flags;
|
|
||||||
LootDropEntries_Struct Entries[0];
|
LootDropEntries_Struct Entries[0];
|
||||||
};
|
};
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <string.h> /* for memcpy() */
|
#include <string.h> /* for memcpy() */
|
||||||
#include "../common/md5.h"
|
#include "../common/md5.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/seperator.h"
|
#include "../common/seperator.h"
|
||||||
|
|
||||||
MD5::MD5() {
|
MD5::MD5() {
|
||||||
@@ -194,7 +194,7 @@ void MD5::Final(uint8 digest[16], MD5Context *ctx) {
|
|||||||
|
|
||||||
/* The heart of the MD5 algorithm. */
|
/* The heart of the MD5 algorithm. */
|
||||||
void MD5::Transform(uint32 hash[4], const uint32 input[16]) {
|
void MD5::Transform(uint32 hash[4], const uint32 input[16]) {
|
||||||
uint32 a = hash[0], b = hash[1], c = hash[2], d = hash[3];
|
register uint32 a = hash[0], b = hash[1], c = hash[2], d = hash[3];
|
||||||
|
|
||||||
MD5STEP(F1, a, b, c, d, input[ 0]+0xd76aa478, 7);
|
MD5STEP(F1, a, b, c, d, input[ 0]+0xd76aa478, 7);
|
||||||
MD5STEP(F1, d, a, b, c, input[ 1]+0xe8c7b756, 12);
|
MD5STEP(F1, d, a, b, c, input[ 1]+0xe8c7b756, 12);
|
||||||
|
|||||||
@@ -71,13 +71,13 @@ namespace EQ
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Write(T val) {
|
void Write(T val) {
|
||||||
static_assert(std::is_standard_layout<T>::value, "MemoryBuffer::Write<T>(T val) only works on pod and string types.");
|
static_assert(std::is_pod<T>::value, "MemoryBuffer::Write<T>(T val) only works on pod and string types.");
|
||||||
Write((const char*)&val, sizeof(T));
|
Write((const char*)&val, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T Read() {
|
T Read() {
|
||||||
static_assert(std::is_standard_layout<T>::value, "MemoryBuffer::Read<T>() only works on pod and string types.");
|
static_assert(std::is_pod<T>::value, "MemoryBuffer::Read<T>() only works on pod and string types.");
|
||||||
T temp;
|
T temp;
|
||||||
Read((uchar*)&temp, sizeof(T));
|
Read((uchar*)&temp, sizeof(T));
|
||||||
return temp;
|
return temp;
|
||||||
|
|||||||
@@ -33,9 +33,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
namespace EQ {
|
namespace EQ {
|
||||||
|
|
||||||
struct MemoryMappedFile::Implementation {
|
struct MemoryMappedFile::Implementation {
|
||||||
|
|||||||
@@ -10,14 +10,8 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
class MySQLRequestRow
|
class MySQLRequestRow : public std::iterator<std::input_iterator_tag, MYSQL_ROW>
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
using iterator_category = std::input_iterator_tag;
|
|
||||||
using value_type = MYSQL_ROW;
|
|
||||||
using difference_type = std::ptrdiff_t;
|
|
||||||
using pointer = MYSQL_ROW*;
|
|
||||||
using reference = MYSQL_ROW&;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MYSQL_RES* m_Result;
|
MYSQL_RES* m_Result;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "console_server.h"
|
#include "console_server.h"
|
||||||
#include "../strings.h"
|
#include "../string_util.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
|
EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
|
||||||
@@ -52,11 +52,11 @@ void EQ::Net::ConsoleServer::ConnectionDisconnected(ConsoleServerConnection *c)
|
|||||||
|
|
||||||
void EQ::Net::ConsoleServer::ProcessCommand(ConsoleServerConnection *c, const std::string &cmd)
|
void EQ::Net::ConsoleServer::ProcessCommand(ConsoleServerConnection *c, const std::string &cmd)
|
||||||
{
|
{
|
||||||
auto split = Strings::Split(cmd, ' ');
|
auto split = SplitString(cmd, ' ');
|
||||||
|
|
||||||
if (split.size() > 0) {
|
if (split.size() > 0) {
|
||||||
auto command = split[0];
|
auto command = split[0];
|
||||||
command = Strings::ToLower(command);
|
ToLowerString(command);
|
||||||
|
|
||||||
if (command == "help" || command == "?") {
|
if (command == "help" || command == "?") {
|
||||||
c->SendLine("Commands:");
|
c->SendLine("Commands:");
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent,
|
|||||||
memset(m_line, 0, MaxConsoleLineLength);
|
memset(m_line, 0, MaxConsoleLineLength);
|
||||||
m_accept_messages = false;
|
m_accept_messages = false;
|
||||||
m_user_id = 0;
|
m_user_id = 0;
|
||||||
m_admin = AccountStatus::Player;
|
m_admin = 0;
|
||||||
|
|
||||||
m_connection->OnRead(std::bind(&ConsoleServerConnection::OnRead, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
m_connection->OnRead(std::bind(&ConsoleServerConnection::OnRead, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
m_connection->OnDisconnect(std::bind(&ConsoleServerConnection::OnDisconnect, this, std::placeholders::_1));
|
m_connection->OnDisconnect(std::bind(&ConsoleServerConnection::OnDisconnect, this, std::placeholders::_1));
|
||||||
@@ -29,7 +29,7 @@ EQ::Net::ConsoleServerConnection::ConsoleServerConnection(ConsoleServer *parent,
|
|||||||
if (addr.find("127.0.0.1") != std::string::npos || addr.find("::0") != std::string::npos) {
|
if (addr.find("127.0.0.1") != std::string::npos || addr.find("::0") != std::string::npos) {
|
||||||
SendLine("Connection established from localhost, assuming admin");
|
SendLine("Connection established from localhost, assuming admin");
|
||||||
m_status = ConsoleStatusLoggedIn;
|
m_status = ConsoleStatusLoggedIn;
|
||||||
m_admin = AccountStatus::Max;
|
m_admin = 255;
|
||||||
SendPrompt();
|
SendPrompt();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -116,42 +116,43 @@ bool EQ::Net::ConsoleServerConnection::SendChannelMessage(const ServerChannelMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (scm->chan_num) {
|
switch (scm->chan_num) {
|
||||||
case ChatChannel_Guild: {
|
case 4: {
|
||||||
QueueMessage(fmt::format("{} tells the guild [{}], '{}'", scm->from, scm->guilddbid, scm->message));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ChatChannel_Auction: {
|
|
||||||
if (RuleB(Chat, ServerWideAuction)) {
|
if (RuleB(Chat, ServerWideAuction)) {
|
||||||
QueueMessage(fmt::format("{} auctions, '{}'", scm->from, scm->message));
|
QueueMessage(fmt::format("{0} auctions, '{1}'", scm->from, scm->message));
|
||||||
break;
|
break;
|
||||||
} else { // I think we want default action in this case?
|
} else { // I think we want default action in this case?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ChatChannel_OOC: {
|
|
||||||
|
case 5: {
|
||||||
if (RuleB(Chat, ServerWideOOC)) {
|
if (RuleB(Chat, ServerWideOOC)) {
|
||||||
QueueMessage(fmt::format("{} says ooc, '{}'", scm->from, scm->message));
|
QueueMessage(fmt::format("{0} says ooc, '{1}'", scm->from, scm->message));
|
||||||
break;
|
break;
|
||||||
} else { // I think we want default action in this case?
|
} else { // I think we want default action in this case?
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ChatChannel_Broadcast: {
|
|
||||||
QueueMessage(fmt::format("{} BROADCASTS, '{}'", scm->from, scm->message));
|
case 6: {
|
||||||
|
QueueMessage(fmt::format("{0} BROADCASTS, '{1}'", scm->from, scm->message));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ChatChannel_Tell: {
|
|
||||||
QueueMessage(fmt::format("[{}] tells {}, '{}'", scm->from, scm->to, scm->message));
|
case 7: {
|
||||||
|
QueueMessage(fmt::format("[{0}] tells you, '{1}'", scm->from, scm->message));
|
||||||
if (onTell) {
|
if (onTell) {
|
||||||
onTell();
|
onTell();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ChatChannel_GMSAY: {
|
|
||||||
QueueMessage(fmt::format("{} GMSAYS, '{}'", scm->from, scm->message));
|
case 11: {
|
||||||
|
QueueMessage(fmt::format("{0} GMSAYS, '{1}'", scm->from, scm->message));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "../event/task.h"
|
#include "../event/task.h"
|
||||||
#include "../data_verification.h"
|
#include "../data_verification.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
#include "../eqemu_logsys.h"
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -309,8 +308,6 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
|||||||
m_combined[1] = OP_Combined;
|
m_combined[1] = OP_Combined;
|
||||||
m_last_session_stats = Clock::now();
|
m_last_session_stats = Clock::now();
|
||||||
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
||||||
|
|
||||||
LogNetcode("New session [{}] with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//new connection made as client
|
//new connection made as client
|
||||||
@@ -633,8 +630,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
DynamicPacket p;
|
DynamicPacket p;
|
||||||
p.PutSerialize(0, reply);
|
p.PutSerialize(0, reply);
|
||||||
InternalSend(p);
|
InternalSend(p);
|
||||||
|
|
||||||
LogNetcode("[OP_SessionRequest] Session [{}] started with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -652,12 +647,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
||||||
m_max_packet_size = reply.max_packet_size;
|
m_max_packet_size = reply.max_packet_size;
|
||||||
ChangeStatus(StatusConnected);
|
ChangeStatus(StatusConnected);
|
||||||
|
|
||||||
LogNetcode(
|
|
||||||
"[OP_SessionResponse] Session [{}] refresh with encode key [{}]",
|
|
||||||
m_connect_code,
|
|
||||||
HostToNetwork(m_encode_key)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -782,12 +771,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
|||||||
SendDisconnect();
|
SendDisconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode(
|
|
||||||
"[OP_SessionDisconnect] Session [{}] disconnect with encode key [{}]",
|
|
||||||
m_connect_code,
|
|
||||||
HostToNetwork(m_encode_key)
|
|
||||||
);
|
|
||||||
|
|
||||||
ChangeStatus(StatusDisconnecting);
|
ChangeStatus(StatusDisconnecting);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -852,7 +835,6 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p.Length() < (size_t)m_crc_bytes) {
|
if (p.Length() < (size_t)m_crc_bytes) {
|
||||||
LogNetcode("Session [{}] ignored packet (crc bytes invalid on session)", m_connect_code);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1412,7 +1394,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
|
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
|
||||||
|
|
||||||
size_t used = 0;
|
size_t used = 0;
|
||||||
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size() - 1; // -1 for compress flag
|
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size();
|
||||||
DynamicPacket first_packet;
|
DynamicPacket first_packet;
|
||||||
first_packet.PutSerialize(0, first_header);
|
first_packet.PutSerialize(0, first_header);
|
||||||
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
||||||
|
|||||||
@@ -65,15 +65,6 @@ EQ::Net::EQStream::~EQStream()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||||
|
|
||||||
LogPacketServerClient(
|
|
||||||
"[{}] [{:#06x}] Size [{}] {}",
|
|
||||||
OpcodeManager::EmuToName(p->GetOpcode()),
|
|
||||||
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
|
|
||||||
p->Size(),
|
|
||||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (m_opcode_manager && *m_opcode_manager) {
|
if (m_opcode_manager && *m_opcode_manager) {
|
||||||
uint16 opcode = 0;
|
uint16 opcode = 0;
|
||||||
if (p->GetOpcodeBypass() != 0) {
|
if (p->GetOpcodeBypass() != 0) {
|
||||||
|
|||||||
@@ -57,10 +57,6 @@ namespace EQ
|
|||||||
virtual void SetOpcodeManager(OpcodeManager **opm) {
|
virtual void SetOpcodeManager(OpcodeManager **opm) {
|
||||||
m_opcode_manager = opm;
|
m_opcode_manager = opm;
|
||||||
}
|
}
|
||||||
virtual OpcodeManager * GetOpcodeManager() const
|
|
||||||
{
|
|
||||||
return (*m_opcode_manager);
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual Stats GetStats() const;
|
virtual Stats GetStats() const;
|
||||||
virtual void ResetStats();
|
virtual void ResetStats();
|
||||||
|
|||||||
@@ -319,16 +319,6 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
|||||||
size_t message_len = length;
|
size_t message_len = length;
|
||||||
EQ::Net::StaticPacket packet(&data[0], message_len);
|
EQ::Net::StaticPacket packet(&data[0], message_len);
|
||||||
|
|
||||||
const auto is_detail_enabled = LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
|
|
||||||
if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
|
|
||||||
LogPacketServerToServer(
|
|
||||||
"[{:#06x}] Size [{}] {}",
|
|
||||||
opcode,
|
|
||||||
packet.Length(),
|
|
||||||
(is_detail_enabled ? "\n" + packet.ToString() : "")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cb = m_message_callbacks.find(opcode);
|
auto cb = m_message_callbacks.find(opcode);
|
||||||
if (cb != m_message_callbacks.end()) {
|
if (cb != m_message_callbacks.end()) {
|
||||||
cb->second(opcode, packet);
|
cb->second(opcode, packet);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "../emu_constants.h"
|
|
||||||
|
|
||||||
struct MethodHandlerEntry
|
struct MethodHandlerEntry
|
||||||
{
|
{
|
||||||
@@ -175,13 +174,13 @@ Json::Value EQ::Net::WebsocketServer::Login(WebsocketServerConnection *connectio
|
|||||||
auto r = _impl->login_handler(connection, user, pass);
|
auto r = _impl->login_handler(connection, user, pass);
|
||||||
|
|
||||||
if (r.logged_in) {
|
if (r.logged_in) {
|
||||||
connection->SetAuthorized(true, r.account_name, r.account_id, AccountStatus::Max);
|
connection->SetAuthorized(true, r.account_name, r.account_id, 255);
|
||||||
ret["status"] = "Ok";
|
ret["status"] = "Ok";
|
||||||
}
|
}
|
||||||
else if (user == "admin" && (connection->RemoteIP() == "127.0.0.1" || connection->RemoteIP() == "::")) {
|
else if (user == "admin" && (connection->RemoteIP() == "127.0.0.1" || connection->RemoteIP() == "::")) {
|
||||||
r.logged_in = true;
|
r.logged_in = true;
|
||||||
r.account_id = 0;
|
r.account_id = 0;
|
||||||
connection->SetAuthorized(true, r.account_name, r.account_id, AccountStatus::Max);
|
connection->SetAuthorized(true, r.account_name, r.account_id, 255);
|
||||||
ret["status"] = "Ok";
|
ret["status"] = "Ok";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ IN(OP_GMTraining, GMTrainee_Struct);
|
|||||||
IN(OP_GMEndTraining, GMTrainEnd_Struct);
|
IN(OP_GMEndTraining, GMTrainEnd_Struct);
|
||||||
IN(OP_GMTrainSkill, GMSkillChange_Struct);
|
IN(OP_GMTrainSkill, GMSkillChange_Struct);
|
||||||
IN(OP_RequestDuel, Duel_Struct);
|
IN(OP_RequestDuel, Duel_Struct);
|
||||||
IN(OP_DuelDecline, DuelResponse_Struct);
|
IN(OP_DuelResponse, DuelResponse_Struct);
|
||||||
IN(OP_DuelAccept, Duel_Struct);
|
IN(OP_DuelResponse2, Duel_Struct);
|
||||||
IN(OP_SpawnAppearance, SpawnAppearance_Struct);
|
IN(OP_SpawnAppearance, SpawnAppearance_Struct);
|
||||||
IN(OP_BazaarInspect, BazaarInspect_Struct);
|
IN(OP_BazaarInspect, BazaarInspect_Struct);
|
||||||
IN(OP_Death, Death_Struct);
|
IN(OP_Death, Death_Struct);
|
||||||
|
|||||||
@@ -240,8 +240,8 @@ void load_opcode_names()
|
|||||||
opcode_map[0x00a1] = "LiveOP_SaveOnZoneReq";
|
opcode_map[0x00a1] = "LiveOP_SaveOnZoneReq";
|
||||||
opcode_map[0x0185] = "LiveOP_Logout";
|
opcode_map[0x0185] = "LiveOP_Logout";
|
||||||
opcode_map[0x0298] = "LiveOP_RequestDuel";
|
opcode_map[0x0298] = "LiveOP_RequestDuel";
|
||||||
opcode_map[0x0a5d] = "LiveOP_DuelDecline";
|
opcode_map[0x0a5d] = "LiveOP_DuelResponse";
|
||||||
opcode_map[0x016e] = "LiveOP_DuelAccept";
|
opcode_map[0x016e] = "LiveOP_DuelResponse2";
|
||||||
opcode_map[0x007c] = "LiveOP_InstillDoubt";
|
opcode_map[0x007c] = "LiveOP_InstillDoubt";
|
||||||
opcode_map[0x00ac] = "LiveOP_SafeFallSuccess";
|
opcode_map[0x00ac] = "LiveOP_SafeFallSuccess";
|
||||||
opcode_map[0x02fb] = "LiveOP_DisciplineUpdate";
|
opcode_map[0x02fb] = "LiveOP_DisciplineUpdate";
|
||||||
|
|||||||
@@ -184,9 +184,6 @@ uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
|||||||
MOpcodes.lock();
|
MOpcodes.lock();
|
||||||
res = emu_to_eq[emu_op];
|
res = emu_to_eq[emu_op];
|
||||||
MOpcodes.unlock();
|
MOpcodes.unlock();
|
||||||
|
|
||||||
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
|
||||||
|
|
||||||
#ifdef DEBUG_TRANSLATE
|
#ifdef DEBUG_TRANSLATE
|
||||||
fprintf(stderr, "M Translate Emu %s (%d) to EQ 0x%.4x\n", OpcodeNames[emu_op], emu_op, res);
|
fprintf(stderr, "M Translate Emu %s (%d) to EQ 0x%.4x\n", OpcodeNames[emu_op], emu_op, res);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+66
-25
@@ -28,12 +28,10 @@
|
|||||||
|
|
||||||
#include "../eq_packet_structs.h"
|
#include "../eq_packet_structs.h"
|
||||||
#include "../misc_functions.h"
|
#include "../misc_functions.h"
|
||||||
#include "../strings.h"
|
#include "../string_util.h"
|
||||||
#include "../inventory_profile.h"
|
#include "../inventory_profile.h"
|
||||||
#include "rof_structs.h"
|
#include "rof_structs.h"
|
||||||
#include "../rulesys.h"
|
#include "../rulesys.h"
|
||||||
#include "../path_manager.h"
|
|
||||||
#include "../races.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -77,8 +75,12 @@ namespace RoF
|
|||||||
{
|
{
|
||||||
//create our opcode manager if we havent already
|
//create our opcode manager if we havent already
|
||||||
if (opcodes == nullptr) {
|
if (opcodes == nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
//TODO: get this file name from the config file
|
||||||
|
auto Config = EQEmuConfig::get();
|
||||||
|
std::string opfile = Config->PatchDir;
|
||||||
|
opfile += "patch_";
|
||||||
|
opfile += name;
|
||||||
|
opfile += ".conf";
|
||||||
//load up the opcode manager.
|
//load up the opcode manager.
|
||||||
//TODO: figure out how to support shared memory with multiple patches...
|
//TODO: figure out how to support shared memory with multiple patches...
|
||||||
opcodes = new RegularOpcodeManager();
|
opcodes = new RegularOpcodeManager();
|
||||||
@@ -116,7 +118,12 @@ namespace RoF
|
|||||||
//we need to go to every stream and replace it's manager.
|
//we need to go to every stream and replace it's manager.
|
||||||
|
|
||||||
if (opcodes != nullptr) {
|
if (opcodes != nullptr) {
|
||||||
std::string opfile = fmt::format("{}/patch_{}.conf", path.GetPatchPath(), name);
|
//TODO: get this file name from the config file
|
||||||
|
auto Config = EQEmuConfig::get();
|
||||||
|
std::string opfile = Config->PatchDir;
|
||||||
|
opfile += "patch_";
|
||||||
|
opfile += name;
|
||||||
|
opfile += ".conf";
|
||||||
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
if (!opcodes->ReloadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
LogNetcode("[OPCODES] Error reloading opcodes file [{}] for patch [{}]", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
@@ -665,7 +672,7 @@ namespace RoF
|
|||||||
|
|
||||||
ENCODE(OP_DeleteCharge)
|
ENCODE(OP_DeleteCharge)
|
||||||
{
|
{
|
||||||
Log(Logs::Detail, Logs::Netcode, "RoF::ENCODE(OP_DeleteCharge)");
|
Log(Logs::Moderate, Logs::Netcode, "RoF::ENCODE(OP_DeleteCharge)");
|
||||||
|
|
||||||
ENCODE_FORWARD(OP_MoveItem);
|
ENCODE_FORWARD(OP_MoveItem);
|
||||||
}
|
}
|
||||||
@@ -729,6 +736,30 @@ namespace RoF
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_DzCompass)
|
||||||
|
{
|
||||||
|
SETUP_VAR_ENCODE(DynamicZoneCompass_Struct);
|
||||||
|
ALLOC_VAR_ENCODE(structs::DynamicZoneCompass_Struct,
|
||||||
|
sizeof(structs::DynamicZoneCompass_Struct) +
|
||||||
|
sizeof(structs::DynamicZoneCompassEntry_Struct) * emu->count
|
||||||
|
);
|
||||||
|
|
||||||
|
OUT(client_id);
|
||||||
|
OUT(count);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < emu->count; ++i)
|
||||||
|
{
|
||||||
|
OUT(entries[i].dz_zone_id);
|
||||||
|
OUT(entries[i].dz_instance_id);
|
||||||
|
OUT(entries[i].dz_type);
|
||||||
|
OUT(entries[i].x);
|
||||||
|
OUT(entries[i].y);
|
||||||
|
OUT(entries[i].z);
|
||||||
|
}
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_DzExpeditionEndsWarning)
|
ENCODE(OP_DzExpeditionEndsWarning)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
|
ENCODE_LENGTH_EXACT(ExpeditionExpireWarning);
|
||||||
@@ -1593,7 +1624,7 @@ namespace RoF
|
|||||||
ENCODE_LENGTH_EXACT(LootingItem_Struct);
|
ENCODE_LENGTH_EXACT(LootingItem_Struct);
|
||||||
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
|
SETUP_DIRECT_ENCODE(LootingItem_Struct, structs::LootingItem_Struct);
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::Netcode, "RoF::ENCODE(OP_LootItem)");
|
Log(Logs::Moderate, Logs::Netcode, "RoF::ENCODE(OP_LootItem)");
|
||||||
|
|
||||||
OUT(lootee);
|
OUT(lootee);
|
||||||
OUT(looter);
|
OUT(looter);
|
||||||
@@ -1603,6 +1634,20 @@ namespace RoF
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_ManaChange)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(ManaChange_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(ManaChange_Struct, structs::ManaChange_Struct);
|
||||||
|
|
||||||
|
OUT(new_mana);
|
||||||
|
OUT(stamina);
|
||||||
|
OUT(spell_id);
|
||||||
|
OUT(keepcasting);
|
||||||
|
eq->slot = -1; // this is spell gem slot. It's -1 in normal operation
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_MercenaryDataResponse)
|
ENCODE(OP_MercenaryDataResponse)
|
||||||
{
|
{
|
||||||
//consume the packet
|
//consume the packet
|
||||||
@@ -1751,7 +1796,7 @@ namespace RoF
|
|||||||
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
ENCODE_LENGTH_EXACT(MoveItem_Struct);
|
||||||
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
SETUP_DIRECT_ENCODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::Netcode, "RoF::ENCODE(OP_MoveItem)");
|
Log(Logs::Moderate, Logs::Netcode, "RoF::ENCODE(OP_MoveItem)");
|
||||||
|
|
||||||
eq->from_slot = ServerToRoFSlot(emu->from_slot);
|
eq->from_slot = ServerToRoFSlot(emu->from_slot);
|
||||||
eq->to_slot = ServerToRoFSlot(emu->to_slot);
|
eq->to_slot = ServerToRoFSlot(emu->to_slot);
|
||||||
@@ -1807,10 +1852,10 @@ namespace RoF
|
|||||||
OUT_str(zone_short_name2);
|
OUT_str(zone_short_name2);
|
||||||
OUT(zone_id);
|
OUT(zone_id);
|
||||||
OUT(zone_instance);
|
OUT(zone_instance);
|
||||||
OUT(suspend_buffs);
|
OUT(SuspendBuffs);
|
||||||
OUT(fast_regen_hp);
|
OUT(FastRegenHP);
|
||||||
OUT(fast_regen_mana);
|
OUT(FastRegenMana);
|
||||||
OUT(fast_regen_endurance);
|
OUT(FastRegenEndurance);
|
||||||
OUT(underworld_teleport_index);
|
OUT(underworld_teleport_index);
|
||||||
|
|
||||||
eq->FogDensity = emu->fog_density;
|
eq->FogDensity = emu->fog_density;
|
||||||
@@ -1818,8 +1863,8 @@ namespace RoF
|
|||||||
/*fill in some unknowns with observed values, hopefully it will help */
|
/*fill in some unknowns with observed values, hopefully it will help */
|
||||||
eq->unknown800 = -1;
|
eq->unknown800 = -1;
|
||||||
eq->unknown844 = 600;
|
eq->unknown844 = 600;
|
||||||
OUT(lava_damage);
|
OUT(LavaDamage);
|
||||||
OUT(min_lava_damage);
|
OUT(MinLavaDamage);
|
||||||
eq->unknown888 = 1;
|
eq->unknown888 = 1;
|
||||||
eq->unknown889 = 0;
|
eq->unknown889 = 0;
|
||||||
eq->unknown890 = 1;
|
eq->unknown890 = 1;
|
||||||
@@ -3831,9 +3876,7 @@ namespace RoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
float SpawnSize = emu->size;
|
float SpawnSize = emu->size;
|
||||||
if (!((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if (!((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522)))
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522))
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PacketSize += 60;
|
PacketSize += 60;
|
||||||
|
|
||||||
@@ -3965,9 +4008,7 @@ namespace RoF
|
|||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown18
|
||||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
|
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0xffffffff); // unknown19
|
||||||
|
|
||||||
if ((emu->NPC == 0) || (emu->race <= RACE_GNOME_12) || (emu->race == RACE_IKSAR_128) ||
|
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
|
||||||
(emu->race == RACE_VAH_SHIR_130) || (emu->race == RACE_FROGLOK_330) || (emu->race == RACE_DRAKKIN_522)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
for (k = EQ::textures::textureBegin; k < EQ::textures::materialCount; ++k)
|
||||||
{
|
{
|
||||||
@@ -4822,7 +4863,7 @@ namespace RoF
|
|||||||
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
|
DECODE_LENGTH_EXACT(structs::LootingItem_Struct);
|
||||||
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
|
SETUP_DIRECT_DECODE(LootingItem_Struct, structs::LootingItem_Struct);
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::Netcode, "RoF::DECODE(OP_LootItem)");
|
Log(Logs::Moderate, Logs::Netcode, "RoF::DECODE(OP_LootItem)");
|
||||||
|
|
||||||
IN(lootee);
|
IN(lootee);
|
||||||
IN(looter);
|
IN(looter);
|
||||||
@@ -4837,7 +4878,7 @@ namespace RoF
|
|||||||
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
DECODE_LENGTH_EXACT(structs::MoveItem_Struct);
|
||||||
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
SETUP_DIRECT_DECODE(MoveItem_Struct, structs::MoveItem_Struct);
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::Netcode, "RoF::DECODE(OP_MoveItem)");
|
Log(Logs::Moderate, Logs::Netcode, "RoF::DECODE(OP_MoveItem)");
|
||||||
|
|
||||||
emu->from_slot = RoFToServerSlot(eq->from_slot);
|
emu->from_slot = RoFToServerSlot(eq->from_slot);
|
||||||
emu->to_slot = RoFToServerSlot(eq->to_slot);
|
emu->to_slot = RoFToServerSlot(eq->to_slot);
|
||||||
@@ -6096,7 +6137,7 @@ namespace RoF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = Strings::Split(serverSayLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
@@ -6135,7 +6176,7 @@ namespace RoF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = Strings::Split(rofSayLink, '\x12');
|
auto segments = SplitString(rofSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user