mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 17:26:30 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9dcc88f29 | |||
| 7fb1d2a1b5 | |||
| 82e247f77b | |||
| ebaa0bf90f | |||
| 54a7f73e50 | |||
| 84630ce228 | |||
| c09a48d58c | |||
| 5e7316edb9 | |||
| ac6291f80b | |||
| 21a39db1c6 |
@@ -1,21 +0,0 @@
|
|||||||
// 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}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
-25
@@ -17,40 +17,27 @@
|
|||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
.bash_history
|
|
||||||
|
|
||||||
# CMake
|
# CMake
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
Makefile
|
Makefile
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
install_manifest.txt
|
install_manifest.txt
|
||||||
[Bb]uild*/
|
Build/
|
||||||
|
build/
|
||||||
|
Build32/
|
||||||
|
build32/
|
||||||
|
Build64/
|
||||||
|
build64/
|
||||||
|
Build_32/
|
||||||
|
build_32/
|
||||||
|
Build_64/
|
||||||
|
build_64/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
log/
|
log/
|
||||||
logs/
|
logs/
|
||||||
vcpkg/
|
vcpkg/
|
||||||
perl/
|
|
||||||
|
|
||||||
.idea/*
|
.idea/*
|
||||||
*cbp
|
*cbp
|
||||||
|
|
||||||
submodules/*
|
|
||||||
cmake-build-debug/
|
|
||||||
|
|
||||||
.nfs.*
|
|
||||||
|
|
||||||
# Visual Studio and CMAKE Generated Files
|
|
||||||
/.vs/
|
|
||||||
*.vcxproj
|
|
||||||
*.vcxproj.filters
|
|
||||||
*.vcxproj.user
|
|
||||||
*.cmake
|
|
||||||
*.ilk
|
|
||||||
*.pdb
|
|
||||||
*.sln
|
|
||||||
*.dir/
|
|
||||||
libs/
|
|
||||||
bin/
|
|
||||||
/Win32
|
|
||||||
/x64
|
|
||||||
/client_files/**/CMakeFiles/
|
|
||||||
|
|||||||
+7
-7
@@ -1,3 +1,6 @@
|
|||||||
|
[submodule "submodules/websocketpp"]
|
||||||
|
path = submodules/websocketpp
|
||||||
|
url = https://github.com/zaphoyd/websocketpp.git
|
||||||
[submodule "submodules/glm"]
|
[submodule "submodules/glm"]
|
||||||
path = submodules/glm
|
path = submodules/glm
|
||||||
url = https://github.com/g-truc/glm.git
|
url = https://github.com/g-truc/glm.git
|
||||||
@@ -10,12 +13,9 @@
|
|||||||
[submodule "submodules/cereal"]
|
[submodule "submodules/cereal"]
|
||||||
path = submodules/cereal
|
path = submodules/cereal
|
||||||
url = https://github.com/USCiLab/cereal.git
|
url = https://github.com/USCiLab/cereal.git
|
||||||
[submodule "submodules/websocketpp"]
|
|
||||||
path = submodules/websocketpp
|
|
||||||
url = https://github.com/zaphoyd/websocketpp.git
|
|
||||||
[submodule "submodules/recastnavigation"]
|
[submodule "submodules/recastnavigation"]
|
||||||
path = submodules/recastnavigation
|
path = submodules/recastnavigation
|
||||||
url = https://github.com/EQEmu/recastnavigation.git
|
url = https://github.com/recastnavigation/recastnavigation.git
|
||||||
[submodule "submodules/expected"]
|
[submodule "submodules/concurrentqueue"]
|
||||||
path = submodules/expected
|
path = submodules/concurrentqueue
|
||||||
url = https://github.com/TartanLlama/expected.git
|
url = https://github.com/cameron314/concurrentqueue.git
|
||||||
|
|||||||
+19
-11
@@ -1,18 +1,26 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
dist: bionic
|
dist: trusty
|
||||||
|
|
||||||
addons:
|
before_install:
|
||||||
apt:
|
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
packages:
|
- sudo apt-get update -qq
|
||||||
- libmysqlclient-dev
|
- mkdir $HOME/usr
|
||||||
- libperl-dev
|
- export PATH="$HOME/usr/bin:$PATH"
|
||||||
- libboost-dev
|
- wget https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.sh
|
||||||
- liblua5.1-0-dev
|
- chmod +x cmake-3.11.2-Linux-x86_64.sh
|
||||||
- zlib1g-dev
|
- ./cmake-3.11.2-Linux-x86_64.sh --prefix=$HOME/usr --exclude-subdir --skip-license
|
||||||
- uuid-dev
|
|
||||||
- libssl-dev
|
|
||||||
|
|
||||||
|
install:
|
||||||
|
- sudo apt-get install -qq g++-7
|
||||||
|
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 90
|
||||||
|
- sudo apt-get install libmysqlclient-dev
|
||||||
|
- sudo apt-get install libperl-dev
|
||||||
|
- sudo apt-get install libboost-dev
|
||||||
|
- sudo apt-get install liblua5.1-0-dev
|
||||||
|
- sudo apt-get install zlib1g-dev
|
||||||
|
- sudo apt-get install uuid-dev
|
||||||
|
- sudo apt-get install libssl-dev
|
||||||
script:
|
script:
|
||||||
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
- cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON
|
||||||
- make -j2
|
- make -j2
|
||||||
|
|||||||
Vendored
-16
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "Linux",
|
|
||||||
"includePath": [
|
|
||||||
"${workspaceFolder}/**",
|
|
||||||
"/usr/include/mysql"
|
|
||||||
],
|
|
||||||
"defines": [],
|
|
||||||
"compilerPath": "/usr/bin/gcc",
|
|
||||||
"cStandard": "c11",
|
|
||||||
"cppStandard": "c++17"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"version": 4
|
|
||||||
}
|
|
||||||
Vendored
-155
@@ -1,155 +0,0 @@
|
|||||||
{
|
|
||||||
// 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": "cd build && make",
|
|
||||||
"group": {
|
|
||||||
"kind": "build",
|
|
||||||
"isDefault": true
|
|
||||||
},
|
|
||||||
"problemMatcher": [
|
|
||||||
"$gcc"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "make clean",
|
|
||||||
"type": "shell",
|
|
||||||
"command": "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/bin && 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/bin && 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/bin && 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/bin && 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 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 build/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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# Guide To Building From Source Without Installer
|
|
||||||
|
|
||||||
This guide is far from exhaustive, you should expect to have some experience with building C++ code before considering compiling the code from scratch. You should instead consider using the installer scripts if you don't want to hack on the code directly.
|
|
||||||
|
|
||||||
### CMake
|
|
||||||
|
|
||||||
EQEmu uses CMake as the build system on all platforms. You will need CMake 3.2 or higher to build from source.
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
The following libraries are required to build from source:
|
|
||||||
- [boost](https://www.boost.org/ "boost")
|
|
||||||
- [zlib](https://www.zlib.net/ "zlib") (If not included the source will build [zlib-ng](https://github.com/zlib-ng/zlib-ng "zlib-ng") instead)
|
|
||||||
- [libmysql](https://dev.mysql.com/downloads/connector/c/ "libmysql") or [libmariadb](https://github.com/MariaDB/mariadb-connector-c "libmariadb")
|
|
||||||
|
|
||||||
The following libraries are not strictly required but in many cased recommended.
|
|
||||||
- [OpenSSL](https://www.openssl.org/ "OpenSSL") or [mbedTLS](https://tls.mbed.org/ "mbedTLS") (Required for the loginserver and headless client)
|
|
||||||
- [libsodium](https://github.com/jedisct1/libsodium "libsodium") (Required for strong password hashing on the loginserver)
|
|
||||||
- [Lua 5.1](https://www.lua.org/ "Lua 5.1") or [LuaJit](http://luajit.org/ "LuaJit") (Required for Lua Quest Scripting)
|
|
||||||
- [Perl](https://www.perl.org/ "Perl") (Required for Perl Quest Scripting)
|
|
||||||
|
|
||||||
##### Windows
|
|
||||||
For windows it is suggested you make use of [vcpkg](https://github.com/microsoft/vcpkg "vcpkg") if you wish to build your own dependencies.
|
|
||||||
|
|
||||||
If you wish to use Perl then you should use whichever version of Perl you have installed on the target system.
|
|
||||||
|
|
||||||
You can also download a vcpkg export from our releases section for Visual Studio [x86](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip "x86") or [x64](https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip "x64") that includes a toolchain file you can pass to CMake.
|
|
||||||
|
|
||||||
##### Linux
|
|
||||||
For Linux you simply can install the dependencies from your package manager, below is an example of doing it on Ubuntu using apt-get.
|
|
||||||
|
|
||||||
sudo apt-get install libmysqlclient-dev libperl-dev libboost-dev liblua5.1-0-dev zlib1g-dev uuid-dev libssl-dev
|
|
||||||
|
|
||||||
### Running CMake
|
|
||||||
|
|
||||||
##### Windows
|
|
||||||
The following is a modified command our automated build server uses to run CMake via the release vcpkg export and its toolchain file.
|
|
||||||
|
|
||||||
Assuming it is starting in c:/projects/eqemu and the x64 dependencies were extracted to c:/projects/eqemu/vcpkg.
|
|
||||||
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
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
|
|
||||||
Similarly to Windows running CMake on Linux is simple it just omits the toolchain file and uses a different generator.
|
|
||||||
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake -G "Unix Makefiles" -DEQEMU_BUILD_TESTS=ON -DEQEMU_ENABLE_BOTS=ON -DEQEMU_BUILD_LOGIN=ON ..
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
##### Windows
|
|
||||||
Inside the build directory a file EQEmu.sln should be produced by a successful run of the CMake command. You can either open this with Visual Studio or build it directly with MSBuild via the command line.
|
|
||||||
|
|
||||||
msbuild EQEmu.sln /p:Configuration=Release
|
|
||||||
|
|
||||||
##### Linux
|
|
||||||
From the build directory you can simply call make to build.
|
|
||||||
|
|
||||||
For example.
|
|
||||||
|
|
||||||
make -j4
|
|
||||||
+279
-276
@@ -1,28 +1,122 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
#EQEmu CMake
|
||||||
|
#Variables used:
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
#EQEMU_DISABLE_CRT_SECURE_WARNINGS
|
||||||
|
#EQEMU_FAST_FLOATINGPOINT
|
||||||
|
#EQEMU_ENABLE_CRASH_LOGGING
|
||||||
|
#EQEMU_DISABLE_SAFESEH
|
||||||
|
#EQEMU_BUILD_MSVC_MP
|
||||||
|
#EQEMU_DEBUG_LEVEL
|
||||||
|
#EQEMU_LOG_LEVEL_STATUS
|
||||||
|
#EQEMU_LOG_LEVEL_NORMAL
|
||||||
|
#EQEMU_LOG_LEVEL_ERROR
|
||||||
|
#EQEMU_LOG_LEVEL_DEBUG
|
||||||
|
#EQEMU_LOG_LEVEL_QUEST
|
||||||
|
#EQEMU_LOG_LEVEL_COMMANDS
|
||||||
|
#EQEMU_LOG_LEVEL_CRASH
|
||||||
|
#EQEMU_DEPOP_INVALIDATES_CACHE
|
||||||
|
#EQEMU_ENABLE_BOTS
|
||||||
|
#EQEMU_DISABLE_LOGSYS
|
||||||
|
#EQEMU_COMMANDS_LOGGING
|
||||||
|
#EQEMU_BUILD_SERVER
|
||||||
|
#EQEMU_BUILD_LOGIN
|
||||||
|
#EQEMU_BUILD_TESTS
|
||||||
|
#EQEMU_BUILD_PERL
|
||||||
|
#EQEMU_BUILD_LUA
|
||||||
|
#EQEMU_SANITIZE_LUA_LIBS
|
||||||
|
#EQEMU_BUILD_CLIENT_FILES
|
||||||
|
#EQEMU_USE_MAP_MMFS
|
||||||
|
#EQEMU_MAP_DIR
|
||||||
|
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
IF(POLICY CMP0074)
|
IF(POLICY CMP0074)
|
||||||
CMAKE_POLICY(SET CMP0074 NEW)
|
cmake_policy(SET CMP0074 NEW)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
#FindMySQL is located here so lets make it so CMake can find it
|
||||||
|
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
|
#Our project name is EQEmu
|
||||||
PROJECT(EQEmu)
|
PROJECT(EQEmu)
|
||||||
|
|
||||||
|
#Default build type is set to RelWithDebInfo for generators that honor that like makefiles
|
||||||
IF(NOT CMAKE_BUILD_TYPE)
|
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 11)
|
SET(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" "${CMAKE_PREFIX_PATH}")
|
||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
#Add our various windows definitions
|
||||||
|
IF(MSVC OR MINGW)
|
||||||
|
ADD_DEFINITIONS(-D_WINDOWS)
|
||||||
|
IF(CMAKE_CL_64)
|
||||||
|
ADD_DEFINITIONS(-DWIN64)
|
||||||
|
ELSE(CMAKE_CL_64)
|
||||||
|
ADD_DEFINITIONS(-DWIN32)
|
||||||
|
ENDIF(CMAKE_CL_64)
|
||||||
|
ENDIF(MSVC OR MINGW)
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
IF(CMAKE_CL_64)
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x64")
|
||||||
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x64")
|
||||||
|
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x64")
|
||||||
|
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x64")
|
||||||
|
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
|
||||||
|
IF(MSVC_VERSION GREATER 1800)
|
||||||
|
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v140/dynamic")
|
||||||
|
ELSEIF(MSVC_VERSION EQUAL 1800)
|
||||||
|
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v120/dynamic")
|
||||||
|
ELSE()
|
||||||
|
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v110/dynamic")
|
||||||
|
ENDIF()
|
||||||
|
ELSE(CMAKE_CL_64)
|
||||||
|
SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x86")
|
||||||
|
SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x86")
|
||||||
|
SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x86")
|
||||||
|
SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include")
|
||||||
|
SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x86")
|
||||||
|
IF(MSVC_VERSION GREATER 1800)
|
||||||
|
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v140/dynamic")
|
||||||
|
ELSEIF(MSVC_VERSION EQUAL 1800)
|
||||||
|
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v120/dynamic")
|
||||||
|
ELSE()
|
||||||
|
SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v110/dynamic")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF(CMAKE_CL_64)
|
||||||
|
|
||||||
|
#disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere
|
||||||
|
OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON)
|
||||||
|
IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
|
||||||
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
ENDIF(EQEMU_DISABLE_CRT_SECURE_WARNINGS)
|
||||||
|
|
||||||
|
#fast FP if you'd like it
|
||||||
|
OPTION(EQEMU_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
|
||||||
|
IF(EQEMU_FAST_FLOATINGPOINT)
|
||||||
|
ADD_DEFINITIONS(/fp:fast)
|
||||||
|
ENDIF(EQEMU_FAST_FLOATINGPOINT)
|
||||||
|
|
||||||
|
#crash logging currently only works on windows x86/x64
|
||||||
|
OPTION(EQEMU_ENABLE_CRASH_LOGGING "Enable crash logging" ON)
|
||||||
|
IF(EQEMU_ENABLE_CRASH_LOGGING)
|
||||||
|
ADD_DEFINITIONS(-DCRASH_LOGGING)
|
||||||
|
ENDIF(EQEMU_ENABLE_CRASH_LOGGING)
|
||||||
|
|
||||||
|
OPTION(EQEMU_BUILD_MSVC_MP "Enable build with multiple processes." ON)
|
||||||
|
IF(EQEMU_BUILD_MSVC_MP)
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
|
ENDIF(EQEMU_BUILD_MSVC_MP)
|
||||||
|
|
||||||
|
#We want to compile /MT not /MD so we change that
|
||||||
|
FOREACH(flag_var CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||||
|
IF(${flag_var} MATCHES "/MD")
|
||||||
|
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||||
|
ENDIF(${flag_var} MATCHES "/MD")
|
||||||
|
ENDFOREACH(flag_var)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
ELSE(MSVC)
|
ELSE(MSVC)
|
||||||
|
#Normally set by perl but we don't use the perl flags anymore so we set it.
|
||||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|
||||||
@@ -39,284 +133,179 @@ IF(UNIX)
|
|||||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
ENDIF(UNIX)
|
ENDIF(UNIX)
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
#debug level, 5 is default. Most people wont ever change this but it's there if you want to
|
||||||
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level:
|
||||||
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
0 - Quiet mode Errors to file Status and Normal ignored
|
||||||
|
1 - Status and Normal to console, Errors to logfile
|
||||||
|
2 - Status, Normal, and Error to console and logfile
|
||||||
|
3 - Light debug release errors and status
|
||||||
|
4 - Moderate debug release errors and status
|
||||||
|
5 - Maximum debug release errors and status
|
||||||
|
10 - More errors than you ever wanted to see"
|
||||||
|
)
|
||||||
|
|
||||||
#MSVC can fetch dependencies automatically.
|
SET(EQEMU_LOG_LEVEL_STATUS 2 CACHE STRING "EQEmu logging level for [Status]:
|
||||||
IF(MSVC)
|
0 - Disabled
|
||||||
INCLUDE("${CMAKE_SOURCE_DIR}/cmake/DependencyHelperMSVC.cmake")
|
1 - Ouput to File Enabled
|
||||||
ENDIF()
|
2 - Output to stdout Enabled
|
||||||
|
3 - Output to File and stdout Enabled
|
||||||
|
8 - Output to stderr Enabled
|
||||||
|
9 - Output to File and stderr Enabled
|
||||||
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
|
)
|
||||||
|
|
||||||
#Find everything we need
|
SET(EQEMU_LOG_LEVEL_NORMAL 3 CACHE STRING "EQEmu logging level for [Normal]:
|
||||||
FIND_PACKAGE(Boost REQUIRED)
|
0 - Disabled
|
||||||
FIND_PACKAGE(MySQL)
|
1 - Ouput to File Enabled
|
||||||
FIND_PACKAGE(MariaDB)
|
2 - Output to stdout Enabled
|
||||||
FIND_PACKAGE(ZLIB)
|
3 - Output to File and stdout Enabled
|
||||||
FIND_PACKAGE(OpenSSL)
|
8 - Output to stderr Enabled
|
||||||
FIND_PACKAGE(Lua51)
|
9 - Output to File and stderr Enabled
|
||||||
FIND_PACKAGE(PerlLibs)
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
FIND_PACKAGE(Sodium)
|
)
|
||||||
FIND_PACKAGE(mbedTLS)
|
|
||||||
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
SET(EQEMU_LOG_LEVEL_ERROR 2 CACHE STRING "EQEmu logging level for [Error]:
|
||||||
MESSAGE(STATUS "* Library Detection *")
|
0 - Disabled
|
||||||
MESSAGE(STATUS "**************************************************")
|
1 - Ouput to File Enabled
|
||||||
|
2 - Output to stdout Enabled
|
||||||
|
3 - Output to File and stdout Enabled
|
||||||
|
8 - Output to stderr Enabled
|
||||||
|
9 - Output to File and stderr Enabled
|
||||||
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
|
)
|
||||||
|
|
||||||
IF(MYSQL_FOUND)
|
SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]:
|
||||||
MESSAGE(STATUS "* MySQL: FOUND *")
|
0 - Disabled
|
||||||
ELSE()
|
1 - Ouput to File Enabled
|
||||||
MESSAGE(STATUS "* MySQL: MISSING *")
|
2 - Output to stdout Enabled
|
||||||
ENDIF()
|
3 - Output to File and stdout Enabled
|
||||||
|
8 - Output to stderr Enabled
|
||||||
|
9 - Output to File and stderr Enabled
|
||||||
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
|
)
|
||||||
|
|
||||||
IF(MARIADB_FOUND)
|
SET(EQEMU_LOG_LEVEL_QUEST 2 CACHE STRING "EQEmu logging level for [Quest]:
|
||||||
MESSAGE(STATUS "* MariaDB: FOUND *")
|
0 - Disabled
|
||||||
ELSE()
|
1 - Ouput to File Enabled
|
||||||
MESSAGE(STATUS "* MariaDB: MISSING *")
|
2 - Output to stdout Enabled
|
||||||
ENDIF()
|
3 - Output to File and stdout Enabled
|
||||||
|
8 - Output to stderr Enabled
|
||||||
|
9 - Output to File and stderr Enabled
|
||||||
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
|
)
|
||||||
|
|
||||||
IF(ZLIB_FOUND)
|
SET(EQEMU_LOG_LEVEL_COMMANDS 1 CACHE STRING "EQEmu logging level for [Commands]:
|
||||||
MESSAGE(STATUS "* ZLIB: FOUND *")
|
0 - Disabled
|
||||||
ELSE()
|
1 - Ouput to File Enabled
|
||||||
MESSAGE(STATUS "* ZLIB: MISSING *")
|
2 - Output to stdout Enabled
|
||||||
ENDIF()
|
3 - Output to File and stdout Enabled
|
||||||
|
8 - Output to stderr Enabled
|
||||||
|
9 - Output to File and stderr Enabled
|
||||||
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
|
)
|
||||||
|
|
||||||
IF(Lua51_FOUND)
|
SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]:
|
||||||
MESSAGE(STATUS "* Lua: FOUND *")
|
0 - Disabled
|
||||||
ELSE()
|
1 - Ouput to File Enabled
|
||||||
MESSAGE(STATUS "* Lua: MISSING *")
|
2 - Output to stdout Enabled
|
||||||
ENDIF()
|
3 - Output to File and stdout Enabled
|
||||||
|
8 - Output to stderr Enabled
|
||||||
|
9 - Output to File and stderr Enabled
|
||||||
|
11 - Output to File, stdout and stderr Enabled"
|
||||||
|
)
|
||||||
|
|
||||||
IF(PerlLibs_FOUND)
|
MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_STATUS EQEMU_LOG_LEVEL_NORMAL EQEMU_LOG_LEVEL_ERROR EQEMU_LOG_LEVEL_DEBUG EQEMU_LOG_LEVEL_QUEST EQEMU_LOG_LEVEL_COMMANDS EQEMU_LOG_LEVEL_CRASH)
|
||||||
MESSAGE(STATUS "* Perl: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* Perl: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(SODIUM_FOUND)
|
#NPC Types Cache Behavior
|
||||||
MESSAGE(STATUS "* libsodium: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* libsodium: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(OpenSSL_FOUND)
|
|
||||||
MESSAGE(STATUS "* OpenSSL: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* OpenSSL: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(MBEDTLS_FOUND)
|
|
||||||
MESSAGE(STATUS "* mbedTLS: FOUND *")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "* mbedTLS: MISSING *")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
|
|
||||||
#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_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON)
|
||||||
|
|
||||||
|
#Bots are a compile time option so on/off
|
||||||
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
|
OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF)
|
||||||
|
|
||||||
|
#Disable entire _mlog system (excludes trade/command logs)
|
||||||
|
OPTION(EQEMU_DISABLE_LOGSYS "Disable Logging INI System" ON)
|
||||||
|
|
||||||
|
#Enable GM Command log system
|
||||||
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_LOGIN "Build the login server." ON)
|
|
||||||
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
|
||||||
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
|
||||||
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
|
||||||
|
|
||||||
IF(EQEMU_COMMANDS_LOGGING)
|
IF(EQEMU_COMMANDS_LOGGING)
|
||||||
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
ADD_DEFINITIONS(-DCOMMANDS_LOGGING)
|
||||||
ENDIF(EQEMU_COMMANDS_LOGGING)
|
ENDIF(EQEMU_COMMANDS_LOGGING)
|
||||||
|
|
||||||
|
IF(EQEMU_DISABLE_LOGSYS)
|
||||||
|
ADD_DEFINITIONS(-DDISABLE_LOGSYS)
|
||||||
|
ENDIF(EQEMU_DISABLE_LOGSYS)
|
||||||
|
|
||||||
IF(EQEMU_ENABLE_BOTS)
|
IF(EQEMU_ENABLE_BOTS)
|
||||||
ADD_DEFINITIONS(-DBOTS)
|
ADD_DEFINITIONS(-DBOTS)
|
||||||
ENDIF(EQEMU_ENABLE_BOTS)
|
ENDIF(EQEMU_ENABLE_BOTS)
|
||||||
|
|
||||||
#database
|
#What to build
|
||||||
IF(MySQL_FOUND AND MariaDB_FOUND)
|
OPTION(EQEMU_BUILD_SERVER "Build the game server." ON)
|
||||||
SET(DATABASE_LIBRARY_SELECTION MySQL CACHE STRING "Database library to use:
|
OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF)
|
||||||
MySQL
|
OPTION(EQEMU_BUILD_HC "Build the headless client." OFF)
|
||||||
MariaDB"
|
OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF)
|
||||||
)
|
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
||||||
|
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
||||||
|
OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||||
|
|
||||||
IF(DATABASE_LIBRARY_SELECTION STREQUAL "MySQL")
|
#C++11 stuff
|
||||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
IF(NOT MSVC)
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
ELSEIF(DATABASE_LIBRARY_SELECTION STREQUAL "MariaDB")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
|
||||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "Unknown database library set, should be one of: MySQL, MariaDB")
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ELSEIF(MariaDB_FOUND)
|
ENDIF(NOT MSVC)
|
||||||
SET(DATABASE_LIBRARY_TYPE "MariaDB")
|
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MariaDB_LIBRARIES})
|
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MariaDB_INCLUDE_DIR})
|
|
||||||
ELSEIF(MySQL_FOUND)
|
|
||||||
SET(DATABASE_LIBRARY_TYPE " MySQL")
|
|
||||||
SET(DATABASE_LIBRARY_LIBS ${MySQL_LIBRARIES})
|
|
||||||
SET(DATABASE_LIBRARY_INCLUDE ${MySQL_INCLUDE_DIR})
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "One of MySQL or MariaDB is a required dependency.")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#security
|
#Various definitions
|
||||||
#prefer openssl to mbedtls (arbitrary)
|
IF(EQEMU_BUILD_PERL)
|
||||||
IF(OpenSSL_FOUND AND MBEDTLS_FOUND)
|
|
||||||
SET(TLS_LIBRARY_SELECTION OpenSSL CACHE STRING "TLS library to use:
|
|
||||||
OpenSSL
|
|
||||||
mbedTLS"
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(TLS_LIBRARY_SELECTION STREQUAL "OpenSSL")
|
|
||||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
|
||||||
ELSEIF(TLS_LIBRARY_SELECTION STREQUAL "mbedTLS")
|
|
||||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "Unknown TLS library set, should be one of: OpenSSL, mbedTLS")
|
|
||||||
ENDIF()
|
|
||||||
ELSEIF(OpenSSL_FOUND)
|
|
||||||
SET(TLS_LIBRARY_TYPE " OpenSSL")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${OPENSSL_LIBRARIES})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${OPENSSL_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_OPENSSL)
|
|
||||||
ELSEIF(MBEDTLS_FOUND)
|
|
||||||
SET(TLS_LIBRARY_TYPE " mbedTLS")
|
|
||||||
SET(TLS_LIBRARY_ENABLED ON)
|
|
||||||
SET(TLS_LIBRARY_LIBS ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRARY})
|
|
||||||
SET(TLS_LIBRARY_INCLUDE ${MBEDTLS_INCLUDE_DIR})
|
|
||||||
ADD_DEFINITIONS(-DEQEMU_USE_MBEDTLS)
|
|
||||||
ELSE()
|
|
||||||
SET(TLS_LIBRARY_TYPE "Disabled")
|
|
||||||
SET(TLS_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(SODIUM_FOUND)
|
|
||||||
SET(SODIUM_LIBRARY_TYPE "Libsodium")
|
|
||||||
SET(SODIUM_LIBRARY_ENABLED ON)
|
|
||||||
SET(SODIUM_LIBRARY_LIBS ${SODIUM_LIBRARIES})
|
|
||||||
SET(SODIUM_LIBRARY_INCLUDE ${SODIUM_INCLUDE_DIRS})
|
|
||||||
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
|
||||||
ELSE()
|
|
||||||
SET(SODIUM_LIBRARY_TYPE " Disabled")
|
|
||||||
SET(SODIUM_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(Lua51_FOUND)
|
|
||||||
SET(LUA_LIBRARY_TYPE " Lua 5.1")
|
|
||||||
SET(LUA_LIBRARY_ENABLED ON)
|
|
||||||
SET(LUA_LIBRARY_LIBS ${LUA_LIBRARY} luabind)
|
|
||||||
SET(LUA_LIBRARY_INCLUDE ${LUA_INCLUDE_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
|
||||||
ELSE()
|
|
||||||
SET(LUA_LIBRARY_TYPE "Disabled")
|
|
||||||
SET(LUA_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(PerlLibs_FOUND)
|
|
||||||
SET(PERL_LIBRARY_TYPE " Perl")
|
|
||||||
SET(PERL_LIBRARY_ENABLED ON)
|
|
||||||
SET(PERL_LIBRARY_LIBS ${PERL_LIBRARY})
|
|
||||||
SET(PERL_LIBRARY_INCLUDE ${PERL_INCLUDE_PATH})
|
|
||||||
ELSE()
|
|
||||||
SET(PERL_LIBRARY_TYPE "Disabled")
|
|
||||||
SET(PERL_LIBRARY_ENABLED OFF)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#use zlib if exists
|
|
||||||
IF(ZLIB_FOUND)
|
|
||||||
OPTION(EQEMU_BUILD_ZLIB "Build internal version of zlib." ON)
|
|
||||||
IF(EQEMU_BUILD_ZLIB)
|
|
||||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
|
||||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
|
||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
|
||||||
ELSE()
|
|
||||||
SET(ZLIB_LIBRARY_TYPE " zlib")
|
|
||||||
SET(ZLIB_LIBRARY_LIBS ${ZLIB_LIBRARY})
|
|
||||||
SET(ZLIB_LIBRARY_INCLUDE ${ZLIB_INCLUDE_DIRS})
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
SET(ZLIB_LIBRARY_TYPE "zlib-ng")
|
|
||||||
SET(ZLIB_LIBRARY_LIBS "zlibstatic")
|
|
||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "")
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
MESSAGE(STATUS "* Library Usage *")
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
MESSAGE(STATUS "* Database: ${DATABASE_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* TLS: ${TLS_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* Sodium: ${SODIUM_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* Lua: ${LUA_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* Perl: ${PERL_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "* zlib: ${ZLIB_LIBRARY_TYPE} *")
|
|
||||||
MESSAGE(STATUS "**************************************************")
|
|
||||||
|
|
||||||
#setup server libs and headers
|
|
||||||
SET(SERVER_LIBS common ${DATABASE_LIBRARY_LIBS} ${ZLIB_LIBRARY_LIBS} ${Boost_LIBRARIES} uv_a fmt RecastNavigation::Detour)
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${DATABASE_LIBRARY_INCLUDE}")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_LIBRARY_INCLUDE}")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${Boost_INCLUDE_DIRS}")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/expected/include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/websocketpp")
|
|
||||||
|
|
||||||
OPTION(EQEMU_BUILD_LOGGING "Build Logging (To speed up compilation)" ON)
|
|
||||||
IF(EQEMU_BUILD_LOGGING)
|
|
||||||
ADD_DEFINITIONS(-DBUILD_LOGGING)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(TLS_LIBRARY_ENABLED)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${TLS_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${TLS_LIBRARY_INCLUDE}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(SODIUM_LIBRARY_ENABLED)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_LIBRARY_INCLUDE}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(LUA_LIBRARY_ENABLED)
|
|
||||||
OPTION(EQEMU_BUILD_LUA "Build Lua parser." ON)
|
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LUA)
|
|
||||||
ADD_DEFINITIONS(-DLUA_EQEMU)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${LUA_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${LUA_LIBRARY_INCLUDE}")
|
|
||||||
|
|
||||||
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
|
||||||
IF(EQEMU_SANITIZE_LUA_LIBS)
|
|
||||||
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(PERL_LIBRARY_ENABLED)
|
|
||||||
OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON)
|
|
||||||
IF(EQEMU_BUILD_PERL)
|
|
||||||
SET(SERVER_LIBS ${SERVER_LIBS} ${PERL_LIBRARY_LIBS})
|
|
||||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
|
||||||
ADD_DEFINITIONS(-DEMBPERL)
|
ADD_DEFINITIONS(-DEMBPERL)
|
||||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||||
|
ENDIF(EQEMU_BUILD_PERL)
|
||||||
|
IF(EQEMU_BUILD_LUA)
|
||||||
|
ADD_DEFINITIONS(-DLUA_EQEMU)
|
||||||
|
ENDIF(EQEMU_BUILD_LUA)
|
||||||
|
|
||||||
|
#Disabled until reevaluation performed
|
||||||
|
#OPTION(EQEMU_USE_MAP_MMFS "Create and use Zone Map MMF files." OFF)
|
||||||
|
#IF(EQEMU_USE_MAP_MMFS)
|
||||||
|
# ADD_DEFINITIONS(-DUSE_MAP_MMFS)
|
||||||
|
#ENDIF(EQEMU_USE_MAP_MMFS)
|
||||||
|
|
||||||
|
SET(EQEMU_MAP_DIR "./Maps" CACHE STRING "The dir that maps, water maps, and paths are located in.")
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
|
||||||
|
ADD_DEFINITIONS(-DINVERSEXY)
|
||||||
|
ADD_DEFINITIONS(-DFIELD_ITEMS)
|
||||||
|
ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}")
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_STATUS=${EQEMU_LOG_LEVEL_STATUS})
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_NORMAL=${EQEMU_LOG_LEVEL_NORMAL})
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_ERROR=${EQEMU_LOG_LEVEL_ERROR})
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
||||||
|
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
||||||
|
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||||
|
ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT)
|
||||||
|
ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL)
|
||||||
|
|
||||||
|
#Find everything we need
|
||||||
|
FIND_PACKAGE(ZLIB REQUIRED)
|
||||||
|
FIND_PACKAGE(MySQL REQUIRED)
|
||||||
|
IF(EQEMU_BUILD_PERL)
|
||||||
|
FIND_PACKAGE(PerlLibs REQUIRED)
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${PERL_INCLUDE_PATH}")
|
||||||
|
ENDIF(EQEMU_BUILD_PERL)
|
||||||
|
|
||||||
|
SET(SERVER_LIBS common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} uv_a fmt RecastNavigation::Detour)
|
||||||
|
|
||||||
|
FIND_PACKAGE(Sodium REQUIRED)
|
||||||
|
IF(SODIUM_FOUND)
|
||||||
|
OPTION(EQEMU_ENABLE_SECURITY "Use Encryption For TCP Connections" ON)
|
||||||
|
IF(EQEMU_ENABLE_SECURITY)
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${SODIUM_INCLUDE_DIRS}")
|
||||||
|
ADD_DEFINITIONS(-DENABLE_SECURITY)
|
||||||
|
SET(SERVER_LIBS ${SERVER_LIBS} ${SODIUM_LIBRARIES})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
@@ -332,13 +321,35 @@ IF(UNIX)
|
|||||||
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
SET(SERVER_LIBS ${SERVER_LIBS} "uuid")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LOGIN AND NOT TLS_LIBRARY_ENABLED)
|
IF(EQEMU_BUILD_LUA)
|
||||||
MESSAGE(FATAL_ERROR "Login server requires a TLS Library to build.")
|
FIND_PACKAGE(EQLua51 REQUIRED)
|
||||||
ENDIF()
|
SET(Boost_USE_STATIC_LIBS OFF)
|
||||||
|
SET(Boost_USE_MULTITHREADED ON)
|
||||||
|
SET(Boost_USE_STATIC_RUNTIME OFF)
|
||||||
|
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
|
||||||
|
|
||||||
IF(EQEMU_BUILD_HC AND NOT TLS_LIBRARY_ENABLED)
|
FIND_PACKAGE(Boost REQUIRED)
|
||||||
MESSAGE(FATAL_ERROR "Headless client requires a TLS Library to build.")
|
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}")
|
||||||
ENDIF()
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
|
||||||
|
|
||||||
|
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
|
||||||
|
IF(EQEMU_SANITIZE_LUA_LIBS)
|
||||||
|
ADD_DEFINITIONS(-DSANITIZE_LUA_LIBS)
|
||||||
|
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
|
||||||
|
ENDIF(EQEMU_BUILD_LUA)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/glm")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/cereal/include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/fmt/include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/libuv/include" )
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DebugUtils/Include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Detour/Include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourCrowd/Include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/DetourTileCache/Include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/recastnavigation/Recast/Include")
|
||||||
|
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/submodules/concurrentqueue")
|
||||||
|
|
||||||
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||||
ADD_SUBDIRECTORY(common)
|
ADD_SUBDIRECTORY(common)
|
||||||
@@ -346,18 +357,11 @@ IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_H
|
|||||||
ADD_SUBDIRECTORY(submodules/fmt)
|
ADD_SUBDIRECTORY(submodules/fmt)
|
||||||
ADD_SUBDIRECTORY(submodules/libuv)
|
ADD_SUBDIRECTORY(submodules/libuv)
|
||||||
|
|
||||||
IF(EQEMU_BUILD_ZLIB)
|
|
||||||
SET(ZLIB_COMPAT ON CACHE BOOL "Compile with zlib compatible API")
|
|
||||||
SET(ZLIB_ENABLE_TESTS OFF CACHE BOOL "Build test binaries")
|
|
||||||
ADD_SUBDIRECTORY(libs/zlibng)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
|
SET(RECASTNAVIGATION_DEMO OFF CACHE BOOL "Build demo")
|
||||||
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
|
SET(RECASTNAVIGATION_TESTS OFF CACHE BOOL "Build tests")
|
||||||
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
|
SET(RECASTNAVIGATION_EXAMPLES OFF CACHE BOOL "Build examples")
|
||||||
ADD_SUBDIRECTORY(submodules/recastnavigation)
|
ADD_SUBDIRECTORY(submodules/recastnavigation)
|
||||||
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS OR EQEMU_BUILD_HC)
|
||||||
|
|
||||||
IF(EQEMU_BUILD_SERVER)
|
IF(EQEMU_BUILD_SERVER)
|
||||||
ADD_SUBDIRECTORY(shared_memory)
|
ADD_SUBDIRECTORY(shared_memory)
|
||||||
ADD_SUBDIRECTORY(world)
|
ADD_SUBDIRECTORY(world)
|
||||||
@@ -366,7 +370,6 @@ IF(EQEMU_BUILD_SERVER)
|
|||||||
ADD_SUBDIRECTORY(queryserv)
|
ADD_SUBDIRECTORY(queryserv)
|
||||||
ADD_SUBDIRECTORY(eqlaunch)
|
ADD_SUBDIRECTORY(eqlaunch)
|
||||||
ENDIF(EQEMU_BUILD_SERVER)
|
ENDIF(EQEMU_BUILD_SERVER)
|
||||||
|
|
||||||
IF(EQEMU_BUILD_LOGIN)
|
IF(EQEMU_BUILD_LOGIN)
|
||||||
ADD_SUBDIRECTORY(loginserver)
|
ADD_SUBDIRECTORY(loginserver)
|
||||||
ENDIF(EQEMU_BUILD_LOGIN)
|
ENDIF(EQEMU_BUILD_LOGIN)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# EQEmulator Core Server
|
# EQEmulator Core Server
|
||||||
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
|Travis CI (Linux)|Appveyor w/ Bots (Windows) |Appveyor w/o Bots (Windows) |
|
||||||
|:---:|:---:|:---:|
|
|:---:|:---:|:---:|
|
||||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server-87crp/branch/master) |[](https://ci.appveyor.com/project/KimLS/server-w0pq2/branch/master) |
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|:---:|:---:|:---:|
|
|:---:|:---:|:---:|
|
||||||
|**Install Count**|||
|
|**Install Count**|||
|
||||||
### > Windows
|
### > Windows
|
||||||
* [Install](https://eqemu.gitbook.io/server/categories/how-to-guides/installation/server-installation-windows)
|
* [Install](https://github.com/EQEmu/Server/wiki/Windows-Server)
|
||||||
|
|
||||||
### > Debian/Ubuntu/CentOS/Fedora
|
### > Debian/Ubuntu/CentOS/Fedora
|
||||||
* 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)
|
||||||
@@ -52,7 +52,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://eqemu.gitbook.io/)
|
- [EQEmulator Wiki](https://github.com/EQEmu/Server/wiki)
|
||||||
|
|
||||||
## Related Repositories
|
## Related Repositories
|
||||||
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
* [ProjectEQ Quests](https://github.com/ProjectEQ/projecteqquests)
|
||||||
@@ -70,9 +70,3 @@ forum, although pull requests will be much quicker and easier on all parties.
|
|||||||
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
|
* GPL Perl - GPL / ActiveState (under the assumption that this is a free project)
|
||||||
* CPPUnit - GLP StringUtilities - Apache
|
* CPPUnit - GLP StringUtilities - Apache
|
||||||
* LUA - MIT
|
* LUA - MIT
|
||||||
|
|
||||||
## Contributors
|
|
||||||
|
|
||||||
<a href="https://github.com/EQEmu/server/graphs/contributors">
|
|
||||||
<img src="https://contributors-img.firebaseapp.com/image?repo=EQEmu/server" />
|
|
||||||
</a>
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# Security Policy - Reporting Vulnerabilities
|
|
||||||
|
|
||||||
When reporting active hacks, exploits and other vulnerabilities, please describe how to reproduce said report and if you can provide context into a possible solution
|
|
||||||
+478
-558
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
add_subdirectory(import)
|
add_subdirectory(import)
|
||||||
add_subdirectory(export)
|
add_subdirectory(export)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
SET(export_sources
|
SET(export_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|||||||
@@ -39,19 +39,20 @@ int main(int argc, char **argv) {
|
|||||||
LogSys.LoadLogSettingsDefaults();
|
LogSys.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
LogInfo("Client Files Export Utility");
|
Log(Logs::General, Logs::Status, "Client Files Export Utility");
|
||||||
if(!EQEmuConfig::LoadConfig()) {
|
if(!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Unable to load configuration file");
|
Log(Logs::General, Logs::Error, "Unable to load configuration file.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Config = EQEmuConfig::get();
|
auto Config = EQEmuConfig::get();
|
||||||
|
|
||||||
SharedDatabase database;
|
SharedDatabase database;
|
||||||
LogInfo("Connecting to database");
|
Log(Logs::General, Logs::Status, "Connecting to database...");
|
||||||
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
||||||
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
||||||
LogError("Unable to connect to the database, cannot continue without a database connection");
|
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
|
||||||
|
"database connection");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,11 +94,11 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ExportSpells(SharedDatabase *db) {
|
void ExportSpells(SharedDatabase *db) {
|
||||||
LogInfo("Exporting Spells");
|
Log(Logs::General, Logs::Status, "Exporting Spells...");
|
||||||
|
|
||||||
FILE *f = fopen("export/spells_us.txt", "w");
|
FILE *f = fopen("export/spells_us.txt", "w");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open export/spells_us.txt to write, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,11 +165,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase *db) {
|
void ExportSkillCaps(SharedDatabase *db) {
|
||||||
LogInfo("Exporting Skill Caps");
|
Log(Logs::General, Logs::Status, "Exporting Skill Caps...");
|
||||||
|
|
||||||
FILE *f = fopen("export/SkillCaps.txt", "w");
|
FILE *f = fopen("export/SkillCaps.txt", "w");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open export/SkillCaps.txt to write, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,11 +194,11 @@ void ExportSkillCaps(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ExportBaseData(SharedDatabase *db) {
|
void ExportBaseData(SharedDatabase *db) {
|
||||||
LogInfo("Exporting Base Data");
|
Log(Logs::General, Logs::Status, "Exporting Base Data...");
|
||||||
|
|
||||||
FILE *f = fopen("export/BaseData.txt", "w");
|
FILE *f = fopen("export/BaseData.txt", "w");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open export/BaseData.txt to write, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,11 +225,11 @@ void ExportBaseData(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ExportDBStrings(SharedDatabase *db) {
|
void ExportDBStrings(SharedDatabase *db) {
|
||||||
LogInfo("Exporting DB Strings");
|
Log(Logs::General, Logs::Status, "Exporting DB Strings...");
|
||||||
|
|
||||||
FILE *f = fopen("export/dbstr_us.txt", "w");
|
FILE *f = fopen("export/dbstr_us.txt", "w");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open export/dbstr_us.txt to write, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open export/dbstr_us.txt to write, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
SET(import_sources
|
SET(import_sources
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|||||||
@@ -37,19 +37,19 @@ int main(int argc, char **argv) {
|
|||||||
LogSys.LoadLogSettingsDefaults();
|
LogSys.LoadLogSettingsDefaults();
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
LogInfo("Client Files Import Utility");
|
Log(Logs::General, Logs::Status, "Client Files Import Utility");
|
||||||
if(!EQEmuConfig::LoadConfig()) {
|
if(!EQEmuConfig::LoadConfig()) {
|
||||||
LogError("Unable to load configuration file.");
|
Log(Logs::General, Logs::Error, "Unable to load configuration file.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Config = EQEmuConfig::get();
|
auto Config = EQEmuConfig::get();
|
||||||
|
|
||||||
SharedDatabase database;
|
SharedDatabase database;
|
||||||
LogInfo("Connecting to database");
|
Log(Logs::General, Logs::Status, "Connecting to database...");
|
||||||
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
if(!database.Connect(Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(),
|
||||||
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
Config->DatabasePassword.c_str(), Config->DatabaseDB.c_str(), Config->DatabasePort)) {
|
||||||
LogError("Unable to connect to the database, cannot continue without a "
|
Log(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a "
|
||||||
"database connection");
|
"database connection");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -97,10 +97,10 @@ bool IsStringField(int i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImportSpells(SharedDatabase *db) {
|
void ImportSpells(SharedDatabase *db) {
|
||||||
LogInfo("Importing Spells");
|
Log(Logs::General, Logs::Status, "Importing Spells...");
|
||||||
FILE *f = fopen("import/spells_us.txt", "r");
|
FILE *f = fopen("import/spells_us.txt", "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open import/spells_us.txt to read, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,23 +173,23 @@ void ImportSpells(SharedDatabase *db) {
|
|||||||
|
|
||||||
spells_imported++;
|
spells_imported++;
|
||||||
if(spells_imported % 1000 == 0) {
|
if(spells_imported % 1000 == 0) {
|
||||||
LogInfo("[{}] spells imported", spells_imported);
|
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(spells_imported % 1000 != 0) {
|
if(spells_imported % 1000 != 0) {
|
||||||
LogInfo("[{}] spells imported", spells_imported);
|
Log(Logs::General, Logs::Status, "%d spells imported.", spells_imported);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportSkillCaps(SharedDatabase *db) {
|
void ImportSkillCaps(SharedDatabase *db) {
|
||||||
LogInfo("Importing Skill Caps");
|
Log(Logs::General, Logs::Status, "Importing Skill Caps...");
|
||||||
|
|
||||||
FILE *f = fopen("import/SkillCaps.txt", "r");
|
FILE *f = fopen("import/SkillCaps.txt", "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open import/SkillCaps.txt to read, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,11 +220,11 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImportBaseData(SharedDatabase *db) {
|
void ImportBaseData(SharedDatabase *db) {
|
||||||
LogInfo("Importing Base Data");
|
Log(Logs::General, Logs::Status, "Importing Base Data...");
|
||||||
|
|
||||||
FILE *f = fopen("import/BaseData.txt", "r");
|
FILE *f = fopen("import/BaseData.txt", "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open import/BaseData.txt to read, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,11 +265,11 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImportDBStrings(SharedDatabase *db) {
|
void ImportDBStrings(SharedDatabase *db) {
|
||||||
LogInfo("Importing DB Strings");
|
Log(Logs::General, Logs::Status, "Importing DB Strings...");
|
||||||
|
|
||||||
FILE *f = fopen("import/dbstr_us.txt", "r");
|
FILE *f = fopen("import/dbstr_us.txt", "r");
|
||||||
if(!f) {
|
if(!f) {
|
||||||
LogError("Unable to open import/dbstr_us.txt to read, skipping.");
|
Log(Logs::General, Logs::Error, "Unable to open import/dbstr_us.txt to read, skipping.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG "Automatically fetch vcpkg dependencies for MSCV" ON)
|
|
||||||
OPTION(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL "Automatically fetch perl dependencies for MSCV" ON)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
|
||||||
MARK_AS_ADVANCED(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
|
||||||
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x86.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64 "https://github.com/EQEmu/Server/releases/download/v1.2/vcpkg-export-x64.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-32bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64 "http://strawberryperl.com/download/5.24.4.1/strawberry-perl-5.24.4.1-64bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP "vcpkg-export-x86.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP "vcpkg-export-x64.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR "vcpkg-export-x86")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR "vcpkg-export-x64")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP "strawberry-perl-5.24.4.1-32bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP "strawberry-perl-5.24.4.1-64bit-portable.zip")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR "x86")
|
|
||||||
SET(EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR "x64")
|
|
||||||
|
|
||||||
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64})
|
|
||||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X64})
|
|
||||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_ZIP})
|
|
||||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X64_DIR})
|
|
||||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_ZIP})
|
|
||||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X64_DIR})
|
|
||||||
ELSE()
|
|
||||||
SET(EQEMU_VCPKG_URL ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86})
|
|
||||||
SET(EQEMU_PERL_URL ${EQEMU_MSVC_DEPENDENCIES_PERL_X86})
|
|
||||||
SET(EQEMU_VCPKG_ZIP ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_ZIP})
|
|
||||||
SET(EQEMU_VCPKG_DIR ${EQEMU_MSVC_DEPENDENCIES_VCPKG_X86_DIR})
|
|
||||||
SET(EQEMU_PERL_ZIP ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_ZIP})
|
|
||||||
SET(EQEMU_PERL_DIR ${EQEMU_MSVC_DEPENDENCIES_PERL_X86_DIR})
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_VCPKG)
|
|
||||||
MESSAGE(STATUS "Resolving vcpkg dependencies...")
|
|
||||||
|
|
||||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP})
|
|
||||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/vcpkg)
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Downloading existing vcpkg dependencies from releases...")
|
|
||||||
FILE(DOWNLOAD ${EQEMU_VCPKG_URL} ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
|
||||||
SHOW_PROGRESS
|
|
||||||
STATUS DOWNLOAD_STATUS)
|
|
||||||
|
|
||||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
|
||||||
IF(NOT STATUS_CODE EQUAL 0)
|
|
||||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_VCPKG_URL}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Extracting files...")
|
|
||||||
EXECUTE_PROCESS(
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_ZIP}
|
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/vcpkg
|
|
||||||
)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
INCLUDE(${PROJECT_SOURCE_DIR}/vcpkg/${EQEMU_VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(EQEMU_FETCH_MSVC_DEPENDENCIES_PERL)
|
|
||||||
#Try to find perl first, (so you can use your active install first)
|
|
||||||
FIND_PACKAGE(PerlLibs)
|
|
||||||
|
|
||||||
IF(NOT PerlLibs_FOUND)
|
|
||||||
MESSAGE(STATUS "Resolving perl dependencies...")
|
|
||||||
|
|
||||||
IF(NOT EXISTS ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP})
|
|
||||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl)
|
|
||||||
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR})
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Downloading portable perl...")
|
|
||||||
FILE(DOWNLOAD ${EQEMU_PERL_URL} ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
|
||||||
SHOW_PROGRESS
|
|
||||||
STATUS DOWNLOAD_STATUS)
|
|
||||||
|
|
||||||
LIST(GET DOWNLOAD_STATUS 0 STATUS_CODE)
|
|
||||||
IF(NOT STATUS_CODE EQUAL 0)
|
|
||||||
MESSAGE(FATAL_ERROR "Was unable to download dependencies from ${EQEMU_PERL_URL}")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Extracting files...")
|
|
||||||
EXECUTE_PROCESS(
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E tar xzf ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_ZIP}
|
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}
|
|
||||||
)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
SET(PERL_EXECUTABLE ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/bin/perl.exe CACHE FILEPATH "Path to perl program" FORCE)
|
|
||||||
SET(PERL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE CACHE PATH "Path to perl include files" FORCE)
|
|
||||||
SET(PERL_LIBRARY ${PROJECT_SOURCE_DIR}/perl/${EQEMU_PERL_DIR}/perl/lib/CORE/libperl524.a CACHE FILEPATH "Path to perl library" FORCE)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
#CMake - Cross Platform Makefile Generator
|
||||||
|
#Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
|
||||||
|
#All rights reserved.
|
||||||
|
#
|
||||||
|
#Redistribution and use in source and binary forms, with or without
|
||||||
|
#modification, are permitted provided that the following conditions
|
||||||
|
#are met:
|
||||||
|
#
|
||||||
|
#* Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
#
|
||||||
|
#* Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
#* Neither the names of Kitware, Inc., the Insight Software Consortium,
|
||||||
|
# nor the names of their contributors may be used to endorse or promote
|
||||||
|
# products derived from this software without specific prior written
|
||||||
|
# permission.
|
||||||
|
#
|
||||||
|
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
# This module defines
|
||||||
|
# LUA51_FOUND, if false, do not try to link to Lua
|
||||||
|
# LUA_LIBRARIES
|
||||||
|
# LUA_INCLUDE_DIR, where to find lua.h
|
||||||
|
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||||
|
|
||||||
|
IF(LUA_ROOT)
|
||||||
|
FIND_PATH(LUA_INCLUDE_DIR
|
||||||
|
NAMES lua.h
|
||||||
|
HINTS
|
||||||
|
ENV LUA_DIR
|
||||||
|
PATHS
|
||||||
|
${LUA_ROOT}
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include src
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_LIBRARY(LUA_LIBRARY
|
||||||
|
NAMES lua51 lua5.1 lua-5.1 lua
|
||||||
|
HINTS
|
||||||
|
ENV LUA_DIR
|
||||||
|
PATHS
|
||||||
|
${LUA_ROOT}
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
PATH_SUFFIXES lib bin
|
||||||
|
)
|
||||||
|
ELSE(LUA_ROOT)
|
||||||
|
FIND_PATH(LUA_INCLUDE_DIR
|
||||||
|
NAMES lua.h
|
||||||
|
HINTS
|
||||||
|
ENV LUA_DIR
|
||||||
|
PATHS
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_LIBRARY(LUA_LIBRARY
|
||||||
|
NAMES lua51 lua5.1 lua-5.1 lua
|
||||||
|
HINTS
|
||||||
|
ENV LUA_DIR
|
||||||
|
PATHS
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
PATH_SUFFIXES lib bin
|
||||||
|
)
|
||||||
|
ENDIF(LUA_ROOT)
|
||||||
|
|
||||||
|
IF(LUA_LIBRARY)
|
||||||
|
# include the math library for Unix
|
||||||
|
IF(UNIX AND NOT APPLE)
|
||||||
|
FIND_LIBRARY(LUA_MATH_LIBRARY m)
|
||||||
|
SET(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||||
|
# For Windows and Mac, don't need to explicitly include the math library
|
||||||
|
ELSE()
|
||||||
|
SET( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||||
|
FILE(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||||
|
|
||||||
|
STRING(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||||
|
UNSET(lua_version_str)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
||||||
|
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||||
|
VERSION_VAR LUA_VERSION_STRING)
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||||
|
|
||||||
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
||||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
|
||||||
# Modified from the FindLua51 that comes with CMake
|
|
||||||
|
|
||||||
#[=======================================================================[.rst:
|
|
||||||
FindLua51
|
|
||||||
---------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Locate Lua51 library This module defines
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
LUA51_FOUND, if false, do not try to link to Lua
|
|
||||||
LUA_LIBRARIES
|
|
||||||
LUA_INCLUDE_DIR, where to find lua.h
|
|
||||||
LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note that the expected include convention is
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
#include "lua.h"
|
|
||||||
|
|
||||||
and not
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
#include <lua/lua.h>
|
|
||||||
|
|
||||||
This is because, the lua location is not standardized and may exist in
|
|
||||||
locations other than lua/
|
|
||||||
#]=======================================================================]
|
|
||||||
|
|
||||||
find_path(LUA_INCLUDE_DIR lua.h
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include/luajit include
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw # Fink
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt/csw # Blastwave
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(LUA_LIBRARY
|
|
||||||
NAMES lua51 lua5.1 lua-5.1 lua luajit
|
|
||||||
HINTS
|
|
||||||
ENV LUA_DIR
|
|
||||||
PATH_SUFFIXES lib
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/sw
|
|
||||||
/opt/local
|
|
||||||
/opt/csw
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LUA_LIBRARY)
|
|
||||||
# include the math library for Unix
|
|
||||||
if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU)
|
|
||||||
find_library(LUA_MATH_LIBRARY m)
|
|
||||||
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
|
||||||
# For Windows and Mac, don't need to explicitly include the math library
|
|
||||||
else()
|
|
||||||
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
|
||||||
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
|
||||||
|
|
||||||
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
|
||||||
unset(lua_version_str)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set LUA51_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua51
|
|
||||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
|
||||||
VERSION_VAR LUA_VERSION_STRING)
|
|
||||||
|
|
||||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
|
||||||
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
# - Find mariadbclient
|
|
||||||
#
|
|
||||||
# -*- cmake -*-
|
|
||||||
#
|
|
||||||
# Find the native MariaDB includes and library
|
|
||||||
#
|
|
||||||
# MariaDB_INCLUDE_DIR - where to find mysql.h, etc.
|
|
||||||
# MariaDB_LIBRARIES - List of libraries when using MariaDB.
|
|
||||||
# MariaDB_FOUND - True if MariaDB found.
|
|
||||||
# The following can be used as a hint as to where to search:
|
|
||||||
# MARIADB_ROOT
|
|
||||||
|
|
||||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
|
||||||
# Already in cache, be silent
|
|
||||||
SET(MariaDB_FIND_QUIETLY TRUE)
|
|
||||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARIES)
|
|
||||||
|
|
||||||
# Include dir
|
|
||||||
IF(MARIADB_ROOT)
|
|
||||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
|
||||||
NAMES mariadb_version.h
|
|
||||||
PATHS ${MARIADB_ROOT}/include
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_SYSTEM_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
|
||||||
NAMES mariadb_version.h
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ELSE(MARIADB_ROOT)
|
|
||||||
FIND_PATH(MariaDB_INCLUDE_DIR
|
|
||||||
NAMES mariadb_version.h
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ENDIF(MARIADB_ROOT)
|
|
||||||
|
|
||||||
# Library
|
|
||||||
SET(MariaDB_NAMES libmariadb)
|
|
||||||
IF(MARIADB_ROOT)
|
|
||||||
FIND_LIBRARY(MariaDB_LIBRARY
|
|
||||||
NAMES ${MariaDB_NAMES}
|
|
||||||
PATHS ${MARIADB_ROOT}/lib
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_SYSTEM_ENVIRONMENT_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(MariaDB_LIBRARY
|
|
||||||
NAMES ${MariaDB_NAMES}
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ELSE(MARIADB_ROOT)
|
|
||||||
FIND_LIBRARY(MariaDB_LIBRARY
|
|
||||||
NAMES ${MariaDB_NAMES} mariadbclient_r mariadbclient
|
|
||||||
PATHS /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
|
|
||||||
PATH_SUFFIXES mysql mariadb
|
|
||||||
)
|
|
||||||
ENDIF(MARIADB_ROOT)
|
|
||||||
|
|
||||||
IF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
|
||||||
SET(MariaDB_FOUND TRUE)
|
|
||||||
SET(MariaDB_LIBRARIES ${MariaDB_LIBRARY})
|
|
||||||
ELSE (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
|
||||||
SET(MariaDB_FOUND FALSE)
|
|
||||||
SET(MariaDB_LIBRARIES)
|
|
||||||
ENDIF (MariaDB_INCLUDE_DIR AND MariaDB_LIBRARY)
|
|
||||||
|
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set MariaDB_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MariaDB DEFAULT_MSG MariaDB_LIBRARY MariaDB_INCLUDE_DIR)
|
|
||||||
|
|
||||||
IF(MariaDB_FOUND)
|
|
||||||
SET( MariaDB_LIBRARY_RELEASE ${MariaDB_LIBRARY} )
|
|
||||||
SET( MariaDB_LIBRARY_DEBUG ${MariaDB_LIBRARY} )
|
|
||||||
SET( MariaDB_LIBRARIES ${MariaDB_LIBRARY_RELEASE} ${MariaDB_LIBRARY_DEBUG} )
|
|
||||||
ELSE(MariaDB_FOUND)
|
|
||||||
SET( MariaDB_LIBRARIES )
|
|
||||||
ENDIF(MariaDB_FOUND)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
|
||||||
MariaDB_LIBRARY_DEBUG
|
|
||||||
MariaDB_LIBRARY_RELEASE
|
|
||||||
MariaDB_INCLUDE_DIR
|
|
||||||
)
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
# - Try to find mbedTLS
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# Read-Only variables
|
|
||||||
# MBEDTLS_FOUND - system has mbedTLS
|
|
||||||
# MBEDTLS_INCLUDE_DIR - the mbedTLS include directory
|
|
||||||
# MBEDTLS_LIBRARY_DIR - the mbedTLS library directory
|
|
||||||
# MBEDTLS_LIBRARIES - Link these to use mbedTLS
|
|
||||||
# MBEDTLS_LIBRARY - path to mbedTLS library
|
|
||||||
# MBEDX509_LIBRARY - path to mbedTLS X.509 library
|
|
||||||
# MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
|
|
||||||
#
|
|
||||||
# Hint
|
|
||||||
# MBEDTLS_ROOT_DIR can be pointed to a local mbedTLS installation.
|
|
||||||
|
|
||||||
SET(_MBEDTLS_ROOT_HINTS
|
|
||||||
${MBEDTLS_ROOT_DIR}
|
|
||||||
ENV MBEDTLS_ROOT_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
SET(_MBEDTLS_ROOT_HINTS_AND_PATHS
|
|
||||||
HINTS ${_MBEDTLS_ROOT_HINTS}
|
|
||||||
PATHS ${_MBEDTLS_ROOT_PATHS}
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_PATH(MBEDTLS_INCLUDE_DIR
|
|
||||||
NAMES mbedtls/version.h
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES include
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
|
|
||||||
# Already in cache, be silent
|
|
||||||
SET(MBEDTLS_FIND_QUIETLY TRUE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
FIND_LIBRARY(MBEDTLS_LIBRARY
|
|
||||||
NAMES mbedtls libmbedtls
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES library
|
|
||||||
)
|
|
||||||
FIND_LIBRARY(MBEDX509_LIBRARY
|
|
||||||
NAMES mbedx509 libmbedx509
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES library
|
|
||||||
)
|
|
||||||
FIND_LIBRARY(MBEDCRYPTO_LIBRARY
|
|
||||||
NAMES mbedcrypto libmbedcrypto
|
|
||||||
${_MBEDTLS_ROOT_HINTS_AND_PATHS}
|
|
||||||
PATH_SUFFIXES library
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARY AND MBEDX509_LIBRARY AND MBEDCRYPTO_LIBRARY)
|
|
||||||
SET(MBEDTLS_FOUND TRUE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(MBEDTLS_FOUND)
|
|
||||||
# split mbedTLS into -L and -l linker options, so we can set them for pkg-config
|
|
||||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_DIR ${MBEDTLS_LIBRARY} PATH)
|
|
||||||
GET_FILENAME_COMPONENT(MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY} NAME_WE)
|
|
||||||
GET_FILENAME_COMPONENT(MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY} NAME_WE)
|
|
||||||
GET_FILENAME_COMPONENT(MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY} NAME_WE)
|
|
||||||
STRING(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
|
|
||||||
STRING(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
|
|
||||||
STRING(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
|
|
||||||
SET(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
|
|
||||||
|
|
||||||
IF(NOT MBEDTLS_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Found mbedTLS:")
|
|
||||||
FILE(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
|
|
||||||
STRING(REGEX MATCH "MBEDTLS_VERSION_STRING +\"[0-9|.]+\"" MBEDTLSMATCH ${MBEDTLSCONTENT})
|
|
||||||
IF (MBEDTLSMATCH)
|
|
||||||
STRING(REGEX REPLACE "MBEDTLS_VERSION_STRING +\"([0-9|.]+)\"" "\\1" MBEDTLS_VERSION ${MBEDTLSMATCH})
|
|
||||||
MESSAGE(STATUS " version ${MBEDTLS_VERSION}")
|
|
||||||
ENDIF(MBEDTLSMATCH)
|
|
||||||
MESSAGE(STATUS " TLS: ${MBEDTLS_LIBRARY}")
|
|
||||||
MESSAGE(STATUS " X509: ${MBEDX509_LIBRARY}")
|
|
||||||
MESSAGE(STATUS " Crypto: ${MBEDCRYPTO_LIBRARY}")
|
|
||||||
ENDIF(NOT MBEDTLS_FIND_QUIETLY)
|
|
||||||
ELSE(MBEDTLS_FOUND)
|
|
||||||
IF(MBEDTLS_FIND_REQUIRED)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find mbedTLS")
|
|
||||||
ENDIF(MBEDTLS_FIND_REQUIRED)
|
|
||||||
ENDIF(MBEDTLS_FOUND)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
|
||||||
MBEDTLS_INCLUDE_DIR
|
|
||||||
MBEDTLS_LIBRARY_DIR
|
|
||||||
MBEDTLS_LIBRARIES
|
|
||||||
MBEDTLS_LIBRARY
|
|
||||||
MBEDX509_LIBRARY
|
|
||||||
MBEDCRYPTO_LIBRARY
|
|
||||||
)
|
|
||||||
+30
-43
@@ -1,15 +1,13 @@
|
|||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
SET(common_sources
|
SET(common_sources
|
||||||
base_packet.cpp
|
base_packet.cpp
|
||||||
classes.cpp
|
classes.cpp
|
||||||
cli/eqemu_command_handler.cpp
|
|
||||||
compression.cpp
|
compression.cpp
|
||||||
condition.cpp
|
condition.cpp
|
||||||
crash.cpp
|
crash.cpp
|
||||||
crc16.cpp
|
crc16.cpp
|
||||||
crc32.cpp
|
crc32.cpp
|
||||||
database/database_dump_service.cpp
|
|
||||||
database.cpp
|
database.cpp
|
||||||
database_conversions.cpp
|
database_conversions.cpp
|
||||||
database_instances.cpp
|
database_instances.cpp
|
||||||
@@ -32,13 +30,11 @@ SET(common_sources
|
|||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
faction.cpp
|
faction.cpp
|
||||||
file_util.cpp
|
|
||||||
guild_base.cpp
|
guild_base.cpp
|
||||||
guilds.cpp
|
guilds.cpp
|
||||||
inventory_profile.cpp
|
inventory_profile.cpp
|
||||||
inventory_slot.cpp
|
inventory_slot.cpp
|
||||||
ipc_mutex.cpp
|
ipc_mutex.cpp
|
||||||
ip_util.cpp
|
|
||||||
item_data.cpp
|
item_data.cpp
|
||||||
item_instance.cpp
|
item_instance.cpp
|
||||||
json_config.cpp
|
json_config.cpp
|
||||||
@@ -75,6 +71,7 @@ SET(common_sources
|
|||||||
textures.cpp
|
textures.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
unix.cpp
|
unix.cpp
|
||||||
|
xml_parser.cpp
|
||||||
platform.cpp
|
platform.cpp
|
||||||
json/jsoncpp.cpp
|
json/jsoncpp.cpp
|
||||||
net/console_server.cpp
|
net/console_server.cpp
|
||||||
@@ -82,6 +79,7 @@ SET(common_sources
|
|||||||
net/crc32.cpp
|
net/crc32.cpp
|
||||||
net/daybreak_connection.cpp
|
net/daybreak_connection.cpp
|
||||||
net/eqstream.cpp
|
net/eqstream.cpp
|
||||||
|
net/eqstream_concurrent.cpp
|
||||||
net/packet.cpp
|
net/packet.cpp
|
||||||
net/servertalk_client_connection.cpp
|
net/servertalk_client_connection.cpp
|
||||||
net/servertalk_legacy_client_connection.cpp
|
net/servertalk_legacy_client_connection.cpp
|
||||||
@@ -89,8 +87,6 @@ SET(common_sources
|
|||||||
net/servertalk_server_connection.cpp
|
net/servertalk_server_connection.cpp
|
||||||
net/tcp_connection.cpp
|
net/tcp_connection.cpp
|
||||||
net/tcp_server.cpp
|
net/tcp_server.cpp
|
||||||
net/websocket_server.cpp
|
|
||||||
net/websocket_server_connection.cpp
|
|
||||||
patches/patches.cpp
|
patches/patches.cpp
|
||||||
patches/sod.cpp
|
patches/sod.cpp
|
||||||
patches/sod_limits.cpp
|
patches/sod_limits.cpp
|
||||||
@@ -105,8 +101,13 @@ SET(common_sources
|
|||||||
patches/uf.cpp
|
patches/uf.cpp
|
||||||
patches/uf_limits.cpp
|
patches/uf_limits.cpp
|
||||||
StackWalker/StackWalker.cpp
|
StackWalker/StackWalker.cpp
|
||||||
|
tinyxml/tinystr.cpp
|
||||||
|
tinyxml/tinyxml.cpp
|
||||||
|
tinyxml/tinyxmlerror.cpp
|
||||||
|
tinyxml/tinyxmlparser.cpp
|
||||||
util/directory.cpp
|
util/directory.cpp
|
||||||
util/uuid.cpp)
|
util/uuid.cpp
|
||||||
|
)
|
||||||
|
|
||||||
SET(common_headers
|
SET(common_headers
|
||||||
any.h
|
any.h
|
||||||
@@ -119,13 +120,8 @@ SET(common_headers
|
|||||||
crash.h
|
crash.h
|
||||||
crc16.h
|
crc16.h
|
||||||
crc32.h
|
crc32.h
|
||||||
cli/argh.h
|
|
||||||
cli/eqemu_command_handler.h
|
|
||||||
cli/terminal_color.hpp
|
|
||||||
database/database_dump_service.h
|
|
||||||
data_verification.h
|
data_verification.h
|
||||||
database.h
|
database.h
|
||||||
database_schema.h
|
|
||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
emu_constants.h
|
emu_constants.h
|
||||||
@@ -141,7 +137,7 @@ SET(common_headers
|
|||||||
eqemu_config.h
|
eqemu_config.h
|
||||||
eqemu_config_elements.h
|
eqemu_config_elements.h
|
||||||
eqemu_logsys.h
|
eqemu_logsys.h
|
||||||
eqemu_logsys_log_aliases.h
|
eqemu_logsys_fmt.h
|
||||||
eq_limits.h
|
eq_limits.h
|
||||||
eq_packet.h
|
eq_packet.h
|
||||||
eq_stream_ident.h
|
eq_stream_ident.h
|
||||||
@@ -151,21 +147,17 @@ SET(common_headers
|
|||||||
eqtime.h
|
eqtime.h
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
expected.h
|
|
||||||
extprofile.h
|
extprofile.h
|
||||||
faction.h
|
faction.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
|
||||||
global_define.h
|
global_define.h
|
||||||
guild_base.h
|
guild_base.h
|
||||||
guilds.h
|
guilds.h
|
||||||
http/httplib.h
|
|
||||||
inventory_profile.h
|
inventory_profile.h
|
||||||
inventory_slot.h
|
inventory_slot.h
|
||||||
ipc_mutex.h
|
ipc_mutex.h
|
||||||
ip_util.h
|
|
||||||
item_data.h
|
item_data.h
|
||||||
item_fieldlist.h
|
item_fieldlist.h
|
||||||
item_instance.h
|
item_instance.h
|
||||||
@@ -216,6 +208,7 @@ SET(common_headers
|
|||||||
unix.h
|
unix.h
|
||||||
useperl.h
|
useperl.h
|
||||||
version.h
|
version.h
|
||||||
|
xml_parser.h
|
||||||
zone_numbers.h
|
zone_numbers.h
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/task.h
|
event/task.h
|
||||||
@@ -230,6 +223,8 @@ SET(common_headers
|
|||||||
net/dns.h
|
net/dns.h
|
||||||
net/endian.h
|
net/endian.h
|
||||||
net/eqstream.h
|
net/eqstream.h
|
||||||
|
net/eqstream_concurrent.h
|
||||||
|
net/eqstream_concurrent_message.h
|
||||||
net/packet.h
|
net/packet.h
|
||||||
net/servertalk_client_connection.h
|
net/servertalk_client_connection.h
|
||||||
net/servertalk_legacy_client_connection.h
|
net/servertalk_legacy_client_connection.h
|
||||||
@@ -238,8 +233,6 @@ SET(common_headers
|
|||||||
net/servertalk_server_connection.h
|
net/servertalk_server_connection.h
|
||||||
net/tcp_connection.h
|
net/tcp_connection.h
|
||||||
net/tcp_server.h
|
net/tcp_server.h
|
||||||
net/websocket_server.h
|
|
||||||
net/websocket_server_connection.h
|
|
||||||
patches/patches.h
|
patches/patches.h
|
||||||
patches/sod.h
|
patches/sod.h
|
||||||
patches/sod_limits.h
|
patches/sod_limits.h
|
||||||
@@ -268,17 +261,13 @@ 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
|
||||||
shared/shared_memory.h
|
|
||||||
shared/shared_memory_error.h
|
|
||||||
shared/shared_memory_handle.h
|
|
||||||
shared/shared_memory_list.h
|
|
||||||
shared/shared_memory_map.h
|
|
||||||
shared/shared_memory_string.h
|
|
||||||
shared/shared_memory_vector.h
|
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
|
tinyxml/tinystr.h
|
||||||
|
tinyxml/tinyxml.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
|
||||||
@@ -308,6 +297,9 @@ SOURCE_GROUP(Net FILES
|
|||||||
net/eqmq.h
|
net/eqmq.h
|
||||||
net/eqstream.cpp
|
net/eqstream.cpp
|
||||||
net/eqstream.h
|
net/eqstream.h
|
||||||
|
net/eqstream_concurrent.cpp
|
||||||
|
net/eqstream_concurrent.h
|
||||||
|
net/eqstream_concurrent_message.h
|
||||||
net/packet.cpp
|
net/packet.cpp
|
||||||
net/packet.h
|
net/packet.h
|
||||||
net/servertalk_client_connection.cpp
|
net/servertalk_client_connection.cpp
|
||||||
@@ -323,10 +315,6 @@ SOURCE_GROUP(Net FILES
|
|||||||
net/tcp_connection.h
|
net/tcp_connection.h
|
||||||
net/tcp_server.cpp
|
net/tcp_server.cpp
|
||||||
net/tcp_server.h
|
net/tcp_server.h
|
||||||
net/websocket_server.cpp
|
|
||||||
net/websocket_server.h
|
|
||||||
net/websocket_server_connection.cpp
|
|
||||||
net/websocket_server_connection.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Patches FILES
|
SOURCE_GROUP(Patches FILES
|
||||||
@@ -373,21 +361,20 @@ SOURCE_GROUP(Patches FILES
|
|||||||
patches/uf_limits.cpp
|
patches/uf_limits.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(shared FILES
|
|
||||||
shared/shared_memory.h
|
|
||||||
shared/shared_memory_error.h
|
|
||||||
shared/shared_memory_handle.h
|
|
||||||
shared/shared_memory_list.h
|
|
||||||
shared/shared_memory_map.h
|
|
||||||
shared/shared_memory_string.h
|
|
||||||
shared/shared_memory_vector.h
|
|
||||||
)
|
|
||||||
|
|
||||||
SOURCE_GROUP(StackWalker FILES
|
SOURCE_GROUP(StackWalker FILES
|
||||||
StackWalker/StackWalker.h
|
StackWalker/StackWalker.h
|
||||||
StackWalker/StackWalker.cpp
|
StackWalker/StackWalker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SOURCE_GROUP(TinyXML FILES
|
||||||
|
tinyxml/tinystr.h
|
||||||
|
tinyxml/tinyxml.h
|
||||||
|
tinyxml/tinystr.cpp
|
||||||
|
tinyxml/tinyxml.cpp
|
||||||
|
tinyxml/tinyxmlerror.cpp
|
||||||
|
tinyxml/tinyxmlparser.cpp
|
||||||
|
)
|
||||||
|
|
||||||
SOURCE_GROUP(Util FILES
|
SOURCE_GROUP(Util FILES
|
||||||
util/memory_stream.h
|
util/memory_stream.h
|
||||||
util/directory.cpp
|
util/directory.cpp
|
||||||
@@ -396,7 +383,7 @@ SOURCE_GROUP(Util FILES
|
|||||||
util/uuid.h
|
util/uuid.h
|
||||||
)
|
)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker)
|
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML)
|
||||||
|
|
||||||
ADD_LIBRARY(common ${common_sources} ${common_headers})
|
ADD_LIBRARY(common ${common_sources} ${common_headers})
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ public:
|
|||||||
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
|
uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; }
|
||||||
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; }
|
uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; }
|
||||||
void ReadString(char *str) { uint32 len = static_cast<uint32>(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; }
|
void ReadString(char *str) { uint32 len = static_cast<uint32>(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; }
|
||||||
void ReadString(std::string &str) { str = reinterpret_cast<char *>(pBuffer + _rpos); _rpos += str.length() + 1; }
|
|
||||||
void ReadString(char *str, uint32 Offset, uint32 MaxLength) const;
|
void ReadString(char *str, uint32 Offset, uint32 MaxLength) const;
|
||||||
|
|
||||||
uint32 GetWritePosition() { return _wpos; }
|
uint32 GetWritePosition() { return _wpos; }
|
||||||
|
|||||||
@@ -573,20 +573,6 @@ bool IsNonSpellFighterClass(uint8 class_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHybridClass(uint8 class_id)
|
|
||||||
{
|
|
||||||
switch (class_id) {
|
|
||||||
case PALADIN:
|
|
||||||
case RANGER:
|
|
||||||
case SHADOWKNIGHT:
|
|
||||||
case BARD:
|
|
||||||
case BEASTLORD:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsCasterClass(uint8 class_id)
|
bool IsCasterClass(uint8 class_id)
|
||||||
{
|
{
|
||||||
switch (class_id) {
|
switch (class_id) {
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ uint8 GetClassIDFromPlayerClassBit(uint32 player_class_bit);
|
|||||||
bool IsFighterClass(uint8 class_id);
|
bool IsFighterClass(uint8 class_id);
|
||||||
bool IsSpellFighterClass(uint8 class_id);
|
bool IsSpellFighterClass(uint8 class_id);
|
||||||
bool IsNonSpellFighterClass(uint8 class_id);
|
bool IsNonSpellFighterClass(uint8 class_id);
|
||||||
bool IsHybridClass(uint8 class_id);
|
|
||||||
bool IsCasterClass(uint8 class_id);
|
bool IsCasterClass(uint8 class_id);
|
||||||
bool IsINTCasterClass(uint8 class_id);
|
bool IsINTCasterClass(uint8 class_id);
|
||||||
bool IsWISCasterClass(uint8 class_id);
|
bool IsWISCasterClass(uint8 class_id);
|
||||||
|
|||||||
@@ -1,434 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <sstream>
|
|
||||||
#include <limits>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
#include <map>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace argh
|
|
||||||
{
|
|
||||||
// Terminology:
|
|
||||||
// A command line is composed of 2 types of args:
|
|
||||||
// 1. Positional args, i.e. free standing values
|
|
||||||
// 2. Options: args beginning with '-'. We identify two kinds:
|
|
||||||
// 2.1: Flags: boolean options => (exist ? true : false)
|
|
||||||
// 2.2: Parameters: a name followed by a non-option value
|
|
||||||
|
|
||||||
#if !defined(__GNUC__) || (__GNUC__ >= 5)
|
|
||||||
using string_stream = std::istringstream;
|
|
||||||
#else
|
|
||||||
// Until GCC 5, istringstream did not have a move constructor.
|
|
||||||
// stringstream_proxy is used instead, as a workaround.
|
|
||||||
class stringstream_proxy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
stringstream_proxy() = default;
|
|
||||||
|
|
||||||
// Construct with a value.
|
|
||||||
stringstream_proxy(std::string const& value) :
|
|
||||||
stream_(value)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Copy constructor.
|
|
||||||
stringstream_proxy(const stringstream_proxy& other) :
|
|
||||||
stream_(other.stream_.str())
|
|
||||||
{
|
|
||||||
stream_.setstate(other.stream_.rdstate());
|
|
||||||
}
|
|
||||||
|
|
||||||
void setstate(std::ios_base::iostate state) { stream_.setstate(state); }
|
|
||||||
|
|
||||||
// Stream out the value of the parameter.
|
|
||||||
// If the conversion was not possible, the stream will enter the fail state,
|
|
||||||
// and operator bool will return false.
|
|
||||||
template<typename T>
|
|
||||||
stringstream_proxy& operator >> (T& thing)
|
|
||||||
{
|
|
||||||
stream_ >> thing;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get the string value.
|
|
||||||
std::string str() const { return stream_.str(); }
|
|
||||||
|
|
||||||
std::stringbuf* rdbuf() const { return stream_.rdbuf(); }
|
|
||||||
|
|
||||||
// Check the state of the stream.
|
|
||||||
// False when the most recent stream operation failed
|
|
||||||
operator bool() const { return !!stream_; }
|
|
||||||
|
|
||||||
~stringstream_proxy() = default;
|
|
||||||
private:
|
|
||||||
std::istringstream stream_;
|
|
||||||
};
|
|
||||||
using string_stream = stringstream_proxy;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class parser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0,
|
|
||||||
PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1,
|
|
||||||
NO_SPLIT_ON_EQUALSIGN = 1 << 2,
|
|
||||||
SINGLE_DASH_IS_MULTIFLAG = 1 << 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
parser() = default;
|
|
||||||
|
|
||||||
parser(std::initializer_list<char const* const> pre_reg_names)
|
|
||||||
{ add_params(pre_reg_names); }
|
|
||||||
|
|
||||||
parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
|
|
||||||
{ parse(argv, mode); }
|
|
||||||
|
|
||||||
parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION)
|
|
||||||
{ parse(argc, argv, mode); }
|
|
||||||
|
|
||||||
void add_param(std::string const& name);
|
|
||||||
void add_params(std::initializer_list<char const* const> init_list);
|
|
||||||
|
|
||||||
void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
|
|
||||||
void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION);
|
|
||||||
|
|
||||||
std::multiset<std::string> const& flags() const { return flags_; }
|
|
||||||
std::map<std::string, std::string> const& params() const { return params_; }
|
|
||||||
std::vector<std::string> const& pos_args() const { return pos_args_; }
|
|
||||||
|
|
||||||
// begin() and end() for using range-for over positional args.
|
|
||||||
std::vector<std::string>::const_iterator begin() const { return pos_args_.cbegin(); }
|
|
||||||
std::vector<std::string>::const_iterator end() const { return pos_args_.cend(); }
|
|
||||||
size_t size() const { return pos_args_.size(); }
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Accessors
|
|
||||||
|
|
||||||
// flag (boolean) accessors: return true if the flag appeared, otherwise false.
|
|
||||||
bool operator[](std::string const& name) const;
|
|
||||||
|
|
||||||
// multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false.
|
|
||||||
bool operator[](std::initializer_list<char const* const> init_list) const;
|
|
||||||
|
|
||||||
// returns positional arg string by order. Like argv[] but without the options
|
|
||||||
std::string const& operator[](size_t ind) const;
|
|
||||||
|
|
||||||
// returns a std::istream that can be used to convert a positional arg to a typed value.
|
|
||||||
string_stream operator()(size_t ind) const;
|
|
||||||
|
|
||||||
// same as above, but with a default value in case the arg is missing (index out of range).
|
|
||||||
template<typename T>
|
|
||||||
string_stream operator()(size_t ind, T&& def_val) const;
|
|
||||||
|
|
||||||
// parameter accessors, give a name get an std::istream that can be used to convert to a typed value.
|
|
||||||
// call .str() on result to get as string
|
|
||||||
string_stream operator()(std::string const& name) const;
|
|
||||||
|
|
||||||
// accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value.
|
|
||||||
// call .str() on result to get as string
|
|
||||||
// returns the first value in the list to be found.
|
|
||||||
string_stream operator()(std::initializer_list<char const* const> init_list) const;
|
|
||||||
|
|
||||||
// same as above, but with a default value in case the param was missing.
|
|
||||||
// Non-string def_val types must have an operator<<() (output stream operator)
|
|
||||||
// If T only has an input stream operator, pass the string version of the type as in "3" instead of 3.
|
|
||||||
template<typename T>
|
|
||||||
string_stream operator()(std::string const& name, T&& def_val) const;
|
|
||||||
|
|
||||||
// same as above but for a list of names. returns the first value to be found.
|
|
||||||
template<typename T>
|
|
||||||
string_stream operator()(std::initializer_list<char const* const> init_list, T&& def_val) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
string_stream bad_stream() const;
|
|
||||||
std::string trim_leading_dashes(std::string const& name) const;
|
|
||||||
bool is_number(std::string const& arg) const;
|
|
||||||
bool is_option(std::string const& arg) const;
|
|
||||||
bool got_flag(std::string const& name) const;
|
|
||||||
bool is_param(std::string const& name) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::string> args_;
|
|
||||||
std::map<std::string, std::string> params_;
|
|
||||||
std::vector<std::string> pos_args_;
|
|
||||||
std::multiset<std::string> flags_;
|
|
||||||
std::set<std::string> registeredParams_;
|
|
||||||
std::string empty_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void parser::parse(const char * const argv[], int mode)
|
|
||||||
{
|
|
||||||
int argc = 0;
|
|
||||||
for (auto argvp = argv; *argvp; ++argc, ++argvp);
|
|
||||||
parse(argc, argv, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/)
|
|
||||||
{
|
|
||||||
// convert to strings
|
|
||||||
args_.resize(argc);
|
|
||||||
std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; });
|
|
||||||
|
|
||||||
// parse line
|
|
||||||
for (auto i = 0u; i < args_.size(); ++i)
|
|
||||||
{
|
|
||||||
if (!is_option(args_[i]))
|
|
||||||
{
|
|
||||||
pos_args_.emplace_back(args_[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto name = trim_leading_dashes(args_[i]);
|
|
||||||
|
|
||||||
if (!(mode & NO_SPLIT_ON_EQUALSIGN))
|
|
||||||
{
|
|
||||||
auto equalPos = name.find('=');
|
|
||||||
if (equalPos != std::string::npos)
|
|
||||||
{
|
|
||||||
params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the option is unregistered and should be a multi-flag
|
|
||||||
if (1 == (args_[i].size() - name.size()) && // single dash
|
|
||||||
argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode
|
|
||||||
!is_param(name)) // unregistered
|
|
||||||
{
|
|
||||||
std::string keep_param;
|
|
||||||
|
|
||||||
if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param
|
|
||||||
{
|
|
||||||
keep_param += name.back();
|
|
||||||
name.resize(name.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto const& c : name)
|
|
||||||
{
|
|
||||||
flags_.emplace(std::string{ c });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!keep_param.empty())
|
|
||||||
{
|
|
||||||
name = keep_param;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue; // do not consider other options for this arg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// any potential option will get as its value the next arg, unless that arg is an option too
|
|
||||||
// in that case it will be determined a flag.
|
|
||||||
if (i == args_.size() - 1 || is_option(args_[i + 1]))
|
|
||||||
{
|
|
||||||
flags_.emplace(name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped
|
|
||||||
// otherwise we have 2 modes:
|
|
||||||
// PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag.
|
|
||||||
// The following value (the next arg) will be a free parameter.
|
|
||||||
//
|
|
||||||
// PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg
|
|
||||||
// will be the value of that option.
|
|
||||||
|
|
||||||
assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION)
|
|
||||||
|| !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION));
|
|
||||||
|
|
||||||
bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION;
|
|
||||||
|
|
||||||
if (is_param(name) || preferParam)
|
|
||||||
{
|
|
||||||
params_.insert({ name, args_[i + 1] });
|
|
||||||
++i; // skip next value, it is not a free parameter
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flags_.emplace(name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline string_stream parser::bad_stream() const
|
|
||||||
{
|
|
||||||
string_stream bad;
|
|
||||||
bad.setstate(std::ios_base::failbit);
|
|
||||||
return bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool parser::is_number(std::string const& arg) const
|
|
||||||
{
|
|
||||||
// inefficient but simple way to determine if a string is a number (which can start with a '-')
|
|
||||||
std::istringstream istr(arg);
|
|
||||||
double number;
|
|
||||||
istr >> number;
|
|
||||||
return !(istr.fail() || istr.bad());
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool parser::is_option(std::string const& arg) const
|
|
||||||
{
|
|
||||||
assert(0 != arg.size());
|
|
||||||
if (is_number(arg))
|
|
||||||
return false;
|
|
||||||
return '-' == arg[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline std::string parser::trim_leading_dashes(std::string const& name) const
|
|
||||||
{
|
|
||||||
auto pos = name.find_first_not_of('-');
|
|
||||||
return std::string::npos != pos ? name.substr(pos) : name;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool argh::parser::got_flag(std::string const& name) const
|
|
||||||
{
|
|
||||||
return flags_.end() != flags_.find(trim_leading_dashes(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool argh::parser::is_param(std::string const& name) const
|
|
||||||
{
|
|
||||||
return registeredParams_.count(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool parser::operator[](std::string const& name) const
|
|
||||||
{
|
|
||||||
return got_flag(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline bool parser::operator[](std::initializer_list<char const* const> init_list) const
|
|
||||||
{
|
|
||||||
return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); });
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline std::string const& parser::operator[](size_t ind) const
|
|
||||||
{
|
|
||||||
if (ind < pos_args_.size())
|
|
||||||
return pos_args_[ind];
|
|
||||||
return empty_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline string_stream parser::operator()(std::string const& name) const
|
|
||||||
{
|
|
||||||
auto optIt = params_.find(trim_leading_dashes(name));
|
|
||||||
if (params_.end() != optIt)
|
|
||||||
return string_stream(optIt->second);
|
|
||||||
return bad_stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline string_stream parser::operator()(std::initializer_list<char const* const> init_list) const
|
|
||||||
{
|
|
||||||
for (auto& name : init_list)
|
|
||||||
{
|
|
||||||
auto optIt = params_.find(trim_leading_dashes(name));
|
|
||||||
if (params_.end() != optIt)
|
|
||||||
return string_stream(optIt->second);
|
|
||||||
}
|
|
||||||
return bad_stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
string_stream parser::operator()(std::string const& name, T&& def_val) const
|
|
||||||
{
|
|
||||||
auto optIt = params_.find(trim_leading_dashes(name));
|
|
||||||
if (params_.end() != optIt)
|
|
||||||
return string_stream(optIt->second);
|
|
||||||
|
|
||||||
std::ostringstream ostr;
|
|
||||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
|
||||||
ostr << def_val;
|
|
||||||
return string_stream(ostr.str()); // use default
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// same as above but for a list of names. returns the first value to be found.
|
|
||||||
template<typename T>
|
|
||||||
string_stream parser::operator()(std::initializer_list<char const* const> init_list, T&& def_val) const
|
|
||||||
{
|
|
||||||
for (auto& name : init_list)
|
|
||||||
{
|
|
||||||
auto optIt = params_.find(trim_leading_dashes(name));
|
|
||||||
if (params_.end() != optIt)
|
|
||||||
return string_stream(optIt->second);
|
|
||||||
}
|
|
||||||
std::ostringstream ostr;
|
|
||||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
|
||||||
ostr << def_val;
|
|
||||||
return string_stream(ostr.str()); // use default
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline string_stream parser::operator()(size_t ind) const
|
|
||||||
{
|
|
||||||
if (pos_args_.size() <= ind)
|
|
||||||
return bad_stream();
|
|
||||||
|
|
||||||
return string_stream(pos_args_[ind]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
string_stream parser::operator()(size_t ind, T&& def_val) const
|
|
||||||
{
|
|
||||||
if (pos_args_.size() <= ind)
|
|
||||||
{
|
|
||||||
std::ostringstream ostr;
|
|
||||||
ostr.precision(std::numeric_limits<long double>::max_digits10);
|
|
||||||
ostr << def_val;
|
|
||||||
return string_stream(ostr.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_stream(pos_args_[ind]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void parser::add_param(std::string const& name)
|
|
||||||
{
|
|
||||||
registeredParams_.insert(trim_leading_dashes(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
inline void parser::add_params(std::initializer_list<char const* const> init_list)
|
|
||||||
{
|
|
||||||
for (auto& name : init_list)
|
|
||||||
registeredParams_.insert(trim_leading_dashes(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include "eqemu_command_handler.h"
|
|
||||||
#include "terminal_color.hpp"
|
|
||||||
#include "../platform.h"
|
|
||||||
|
|
||||||
namespace EQEmuCommand {
|
|
||||||
|
|
||||||
std::map<std::string, void (*)(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
argh::parser &cmd,
|
|
||||||
std::string &description
|
|
||||||
)> function_map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param cmd
|
|
||||||
*/
|
|
||||||
void DisplayDebug(argh::parser &cmd)
|
|
||||||
{
|
|
||||||
if (cmd[{"-d", "--debug"}]) {
|
|
||||||
std::cout << "Positional args:\n";
|
|
||||||
for (auto &pos_arg : cmd.pos_args())
|
|
||||||
std::cout << '\t' << pos_arg << std::endl;
|
|
||||||
|
|
||||||
std::cout << "\nFlags:\n";
|
|
||||||
for (auto &flag : cmd.flags())
|
|
||||||
std::cout << '\t' << flag << std::endl;
|
|
||||||
|
|
||||||
std::cout << "\nParameters:\n";
|
|
||||||
for (auto ¶m : cmd.params())
|
|
||||||
std::cout << '\t' << param.first << " : " << param.second << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param arguments
|
|
||||||
* @param options
|
|
||||||
* @param cmd
|
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
|
||||||
void ValidateCmdInput(
|
|
||||||
std::vector<std::string> &arguments,
|
|
||||||
std::vector<std::string> &options,
|
|
||||||
argh::parser &cmd,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
bool arguments_filled = true;
|
|
||||||
|
|
||||||
int index = 2;
|
|
||||||
for (auto &arg : arguments) {
|
|
||||||
if (cmd(arg).str().empty() && cmd(index).str().empty()) {
|
|
||||||
arguments_filled = false;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!arguments_filled || argc == 2) {
|
|
||||||
std::string arguments_string;
|
|
||||||
for (auto &arg : arguments) {
|
|
||||||
arguments_string += " " + arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string options_string;
|
|
||||||
for (auto &opt : options) {
|
|
||||||
options_string += " " + opt + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream command_string;
|
|
||||||
|
|
||||||
command_string <<
|
|
||||||
termcolor::colorize <<
|
|
||||||
termcolor::yellow <<
|
|
||||||
"\nCommand" <<
|
|
||||||
termcolor::reset << "\n\n" <<
|
|
||||||
termcolor::green << argv[1] << arguments_string << termcolor::reset << "\n" <<
|
|
||||||
termcolor::yellow << (!options_string.empty() ? "\nOptions\n\n" : "") <<
|
|
||||||
termcolor::reset << termcolor::cyan << options_string << termcolor::reset;
|
|
||||||
|
|
||||||
std::cout << command_string.str() << std::endl;
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param in_function_map
|
|
||||||
* @param cmd
|
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
|
||||||
void HandleMenu(
|
|
||||||
std::map<std::string, void (*)(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
argh::parser &cmd,
|
|
||||||
std::string &description
|
|
||||||
)> &in_function_map,
|
|
||||||
argh::parser &cmd,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string description;
|
|
||||||
bool ran_command = false;
|
|
||||||
for (auto &it: in_function_map) {
|
|
||||||
if (it.first == argv[1]) {
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
|
||||||
ran_command = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd[{"-h", "--help"}]) {
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout <<
|
|
||||||
"> " <<
|
|
||||||
termcolor::yellow <<
|
|
||||||
"EQEmulator [" + GetPlatformName() + "] CLI Menu" <<
|
|
||||||
termcolor::reset
|
|
||||||
<< std::endl
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get max command length for padding length
|
|
||||||
*/
|
|
||||||
int max_command_length = 0;
|
|
||||||
|
|
||||||
for (auto &it: in_function_map) {
|
|
||||||
std::stringstream command;
|
|
||||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
|
||||||
if (command.str().length() > max_command_length) {
|
|
||||||
max_command_length = command.str().length() + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display command menu
|
|
||||||
*/
|
|
||||||
std::string command_section;
|
|
||||||
for (auto &it: in_function_map) {
|
|
||||||
description = "";
|
|
||||||
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print section header
|
|
||||||
*/
|
|
||||||
std::string command_prefix = it.first.substr(0, it.first.find(":"));
|
|
||||||
if (command_section != command_prefix) {
|
|
||||||
command_section = command_prefix;
|
|
||||||
std::cout << termcolor::reset << command_prefix << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print commands
|
|
||||||
*/
|
|
||||||
std::stringstream command;
|
|
||||||
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
|
|
||||||
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ran_command) {
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EQEMU_EQEMU_COMMAND_HANDLER_H
|
|
||||||
#define EQEMU_EQEMU_COMMAND_HANDLER_H
|
|
||||||
|
|
||||||
#include "argh.h"
|
|
||||||
|
|
||||||
namespace EQEmuCommand {
|
|
||||||
|
|
||||||
extern std::map<std::string, void (*)(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
argh::parser &cmd,
|
|
||||||
std::string &description
|
|
||||||
)> function_map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param arguments
|
|
||||||
* @param options
|
|
||||||
* @param cmd
|
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
|
||||||
void ValidateCmdInput(
|
|
||||||
std::vector<std::string> &arguments,
|
|
||||||
std::vector<std::string> &options,
|
|
||||||
argh::parser &cmd,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param cmd
|
|
||||||
*/
|
|
||||||
void DisplayDebug(argh::parser &cmd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param in_function_map
|
|
||||||
* @param cmd
|
|
||||||
* @param argc
|
|
||||||
* @param argv
|
|
||||||
*/
|
|
||||||
void HandleMenu(
|
|
||||||
std::map<std::string, void (*)(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
argh::parser &cmd,
|
|
||||||
std::string &description
|
|
||||||
)> &in_function_map,
|
|
||||||
argh::parser &cmd,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EQEMU_EQEMU_COMMAND_HANDLER_H
|
|
||||||
@@ -1,557 +0,0 @@
|
|||||||
//!
|
|
||||||
//! termcolor
|
|
||||||
//! ~~~~~~~~~
|
|
||||||
//!
|
|
||||||
//! termcolor is a header-only c++ library for printing colored messages
|
|
||||||
//! to the terminal. Written just for fun with a help of the Force.
|
|
||||||
//!
|
|
||||||
//! :copyright: (c) 2013 by Ihor Kalnytskyi
|
|
||||||
//! :license: BSD, see LICENSE for details
|
|
||||||
//!
|
|
||||||
|
|
||||||
#ifndef TERMCOLOR_HPP_
|
|
||||||
#define TERMCOLOR_HPP_
|
|
||||||
|
|
||||||
// the following snippet of code detects the current OS and
|
|
||||||
// defines the appropriate macro that is used to wrap some
|
|
||||||
// platform specific things
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
# define TERMCOLOR_OS_WINDOWS
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
# define TERMCOLOR_OS_MACOS
|
|
||||||
#elif defined(__unix__) || defined(__unix)
|
|
||||||
# define TERMCOLOR_OS_LINUX
|
|
||||||
#else
|
|
||||||
# error unsupported platform
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// This headers provides the `isatty()`/`fileno()` functions,
|
|
||||||
// which are used for testing whether a standart stream refers
|
|
||||||
// to the terminal. As for Windows, we also need WinApi funcs
|
|
||||||
// for changing colors attributes of the terminal.
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
# include <unistd.h>
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
# include <io.h>
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace termcolor
|
|
||||||
{
|
|
||||||
// Forward declaration of the `_internal` namespace.
|
|
||||||
// All comments are below.
|
|
||||||
namespace _internal
|
|
||||||
{
|
|
||||||
// An index to be used to access a private storage of I/O streams. See
|
|
||||||
// colorize / nocolorize I/O manipulators for details.
|
|
||||||
static int colorize_index = std::ios_base::xalloc();
|
|
||||||
|
|
||||||
inline FILE* get_standard_stream(const std::ostream& stream);
|
|
||||||
inline bool is_colorized(std::ostream& stream);
|
|
||||||
inline bool is_atty(const std::ostream& stream);
|
|
||||||
|
|
||||||
#if defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& colorize(std::ostream& stream)
|
|
||||||
{
|
|
||||||
stream.iword(_internal::colorize_index) = 1L;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& nocolorize(std::ostream& stream)
|
|
||||||
{
|
|
||||||
stream.iword(_internal::colorize_index) = 0L;
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& reset(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;00m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1, -1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& bold(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;1m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& dark(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;2m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& underline(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;4m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& blink(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;5m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& reverse(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;7m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& concealed(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;8m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& grey(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;30m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
0 // grey (black)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& red(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;31m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& green(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;32m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_GREEN
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& yellow(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;33m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_GREEN | FOREGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& blue(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;34m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_BLUE
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& magenta(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;35m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_BLUE | FOREGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& cyan(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;36m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_BLUE | FOREGROUND_GREEN
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& white(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;37m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream,
|
|
||||||
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_grey(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;40m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
0 // grey (black)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_red(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;41m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_green(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;42m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_GREEN
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_yellow(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;43m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_GREEN | BACKGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_blue(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;44m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_BLUE
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_magenta(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;45m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_BLUE | BACKGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_cyan(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;46m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_GREEN | BACKGROUND_BLUE
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
std::ostream& on_white(std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (_internal::is_colorized(stream))
|
|
||||||
{
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
stream << "\e[1;47m";
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
_internal::win_change_attributes(stream, -1,
|
|
||||||
BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Since C++ hasn't a way to hide something in the header from
|
|
||||||
//! the outer access, I have to introduce this namespace which
|
|
||||||
//! is used for internal purpose and should't be access from
|
|
||||||
//! the user code.
|
|
||||||
namespace _internal
|
|
||||||
{
|
|
||||||
//! Since C++ hasn't a true way to extract stream handler
|
|
||||||
//! from the a given `std::ostream` object, I have to write
|
|
||||||
//! this kind of hack.
|
|
||||||
inline
|
|
||||||
FILE* get_standard_stream(const std::ostream& stream)
|
|
||||||
{
|
|
||||||
if (&stream == &std::cout)
|
|
||||||
return stdout;
|
|
||||||
else if ((&stream == &std::cerr) || (&stream == &std::clog))
|
|
||||||
return stderr;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Say whether a given stream should be colorized or not. It's always
|
|
||||||
// true for ATTY streams and may be true for streams marked with
|
|
||||||
// colorize flag.
|
|
||||||
inline
|
|
||||||
bool is_colorized(std::ostream& stream)
|
|
||||||
{
|
|
||||||
return is_atty(stream) || static_cast<bool>(stream.iword(colorize_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Test whether a given `std::ostream` object refers to
|
|
||||||
//! a terminal.
|
|
||||||
inline
|
|
||||||
bool is_atty(const std::ostream& stream)
|
|
||||||
{
|
|
||||||
FILE* std_stream = get_standard_stream(stream);
|
|
||||||
|
|
||||||
// Unfortunately, fileno() ends with segmentation fault
|
|
||||||
// if invalid file descriptor is passed. So we need to
|
|
||||||
// handle this case gracefully and assume it's not a tty
|
|
||||||
// if standard stream is not detected, and 0 is returned.
|
|
||||||
if (!std_stream)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX)
|
|
||||||
return ::isatty(fileno(std_stream));
|
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
return ::_isatty(_fileno(std_stream));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TERMCOLOR_OS_WINDOWS)
|
|
||||||
//! Change Windows Terminal colors attribute. If some
|
|
||||||
//! parameter is `-1` then attribute won't changed.
|
|
||||||
inline void win_change_attributes(std::ostream& stream, int foreground, int background)
|
|
||||||
{
|
|
||||||
// yeah, i know.. it's ugly, it's windows.
|
|
||||||
static WORD defaultAttributes = 0;
|
|
||||||
|
|
||||||
// Windows doesn't have ANSI escape sequences and so we use special
|
|
||||||
// API to change Terminal output color. That means we can't
|
|
||||||
// manipulate colors by means of "std::stringstream" and hence
|
|
||||||
// should do nothing in this case.
|
|
||||||
if (!_internal::is_atty(stream))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// get terminal handle
|
|
||||||
HANDLE hTerminal = INVALID_HANDLE_VALUE;
|
|
||||||
if (&stream == &std::cout)
|
|
||||||
hTerminal = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
else if (&stream == &std::cerr)
|
|
||||||
hTerminal = GetStdHandle(STD_ERROR_HANDLE);
|
|
||||||
|
|
||||||
// save default terminal attributes if it unsaved
|
|
||||||
if (!defaultAttributes)
|
|
||||||
{
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
|
||||||
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
|
||||||
return;
|
|
||||||
defaultAttributes = info.wAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore all default settings
|
|
||||||
if (foreground == -1 && background == -1)
|
|
||||||
{
|
|
||||||
SetConsoleTextAttribute(hTerminal, defaultAttributes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get current settings
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
|
||||||
if (!GetConsoleScreenBufferInfo(hTerminal, &info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (foreground != -1)
|
|
||||||
{
|
|
||||||
info.wAttributes &= ~(info.wAttributes & 0x0F);
|
|
||||||
info.wAttributes |= static_cast<WORD>(foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (background != -1)
|
|
||||||
{
|
|
||||||
info.wAttributes &= ~(info.wAttributes & 0xF0);
|
|
||||||
info.wAttributes |= static_cast<WORD>(background);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetConsoleTextAttribute(hTerminal, info.wAttributes);
|
|
||||||
}
|
|
||||||
#endif // TERMCOLOR_OS_WINDOWS
|
|
||||||
|
|
||||||
} // namespace _internal
|
|
||||||
|
|
||||||
} // namespace termcolor
|
|
||||||
|
|
||||||
|
|
||||||
#undef TERMCOLOR_OS_WINDOWS
|
|
||||||
#undef TERMCOLOR_OS_MACOS
|
|
||||||
#undef TERMCOLOR_OS_LINUX
|
|
||||||
|
|
||||||
#endif // TERMCOLOR_HPP_
|
|
||||||
+1
-54
@@ -111,60 +111,7 @@ void set_exception_handler() {
|
|||||||
SetUnhandledExceptionFilter(windows_exception_handler);
|
SetUnhandledExceptionFilter(windows_exception_handler);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/fcntl.h>
|
|
||||||
|
|
||||||
void print_trace()
|
|
||||||
{
|
|
||||||
auto uid = geteuid();
|
|
||||||
|
|
||||||
std::string temp_output_file = "/tmp/dump-output";
|
|
||||||
|
|
||||||
char pid_buf[30];
|
|
||||||
sprintf(pid_buf, "%d", getpid());
|
|
||||||
char name_buf[512];
|
|
||||||
name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
|
|
||||||
int child_pid = fork();
|
|
||||||
if (!child_pid) {
|
|
||||||
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
|
|
||||||
|
|
||||||
dup2(fd, 1); // redirect output to stderr
|
|
||||||
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
|
|
||||||
if (uid == 0) {
|
|
||||||
execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
execlp("sudo", "gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
abort(); /* If gdb failed to start */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
waitpid(child_pid, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream input(temp_output_file);
|
|
||||||
for (std::string line; getline(input, line);) {
|
|
||||||
LogCrash("{}", line);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::remove(temp_output_file.c_str());
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// crash is off or an unhandled platform
|
// crash is off or an unhandled platform
|
||||||
void set_exception_handler()
|
void set_exception_handler() {
|
||||||
{
|
|
||||||
signal(SIGABRT, reinterpret_cast<void (*)(int)>(print_trace));
|
|
||||||
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
|
|
||||||
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
|
|
||||||
signal(SIGSEGV, reinterpret_cast<void (*)(int)>(print_trace));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+32
-36
@@ -1,57 +1,53 @@
|
|||||||
/**
|
/* EQEMu: Everquest Server Emulator
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; version 2 of the License.
|
the Free Software Foundation; version 2 of the License.
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
* are required to give you total support for your newly bought product;
|
are required to give you total support for your newly bought product;
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*/
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace EQEmu {
|
namespace EQEmu
|
||||||
template<typename T>
|
{
|
||||||
T Clamp(const T &value, const T &lower, const T &upper)
|
template <typename T>
|
||||||
{
|
T Clamp(const T& value, const T& lower, const T& upper) {
|
||||||
return std::max(lower, std::min(value, upper));
|
return std::max(lower, std::min(value, upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T ClampLower(const T &value, const T &lower)
|
T ClampLower(const T& value, const T& lower) {
|
||||||
{
|
|
||||||
return std::max(lower, value);
|
return std::max(lower, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T ClampUpper(const T &value, const T &upper)
|
T ClampUpper(const T& value, const T& upper) {
|
||||||
{
|
|
||||||
return std::min(value, upper);
|
return std::min(value, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool ValueWithin(const T &value, const T &lower, const T &upper)
|
bool ValueWithin(const T& value, const T& lower, const T& upper) {
|
||||||
{
|
|
||||||
return value >= lower && value <= upper;
|
return value >= lower && value <= upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3>
|
template <typename T1, typename T2, typename T3>
|
||||||
bool ValueWithin(const T1 &value, const T2 &lower, const T3 &upper)
|
bool ValueWithin(const T1& value, const T2& lower, const T3& upper) {
|
||||||
{
|
return value >= (T1)lower && value <= (T1)upper;
|
||||||
return value >= (T1) lower && value <= (T1) upper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /*EQEmu*/
|
} /*EQEmu*/
|
||||||
|
|
||||||
|
|||||||
+129
-283
@@ -45,7 +45,6 @@
|
|||||||
#include "eq_packet_structs.h"
|
#include "eq_packet_structs.h"
|
||||||
#include "extprofile.h"
|
#include "extprofile.h"
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
#include "database_schema.h"
|
|
||||||
|
|
||||||
extern Client client;
|
extern Client client;
|
||||||
|
|
||||||
@@ -65,11 +64,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("Failed to connect to database: Error: {}", errbuf);
|
Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogInfo("Using database [{}] at [{}]:[{}]", database, host,port);
|
Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host,port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +86,7 @@ Database::~Database()
|
|||||||
Return the account id or zero if no account matches.
|
Return the account id or zero if no account matches.
|
||||||
Zero will also be returned if there is a database error.
|
Zero will also be returned if there is a database error.
|
||||||
*/
|
*/
|
||||||
uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) {
|
uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) {
|
||||||
|
|
||||||
if(strlen(name) >= 50 || strlen(password) >= 50)
|
if(strlen(name) >= 50 || strlen(password) >= 50)
|
||||||
return(0);
|
return(0);
|
||||||
@@ -98,10 +97,9 @@ uint32 Database::CheckLogin(const char* name, const char* password, const char *
|
|||||||
DoEscapeString(tmpUN, name, strlen(name));
|
DoEscapeString(tmpUN, name, strlen(name));
|
||||||
DoEscapeString(tmpPW, password, strlen(password));
|
DoEscapeString(tmpPW, password, strlen(password));
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT id, status FROM account WHERE `name`='%s' AND ls_id='%s' AND password is not null "
|
std::string query = StringFormat("SELECT id, status FROM account WHERE name='%s' AND password is not null "
|
||||||
"and length(password) > 0 and (password='%s' or password=MD5('%s'))",
|
"and length(password) > 0 and (password='%s' or password=MD5('%s'))",
|
||||||
tmpUN, EscapeString(loginserver).c_str(), tmpPW, tmpPW);
|
tmpUN, tmpPW, tmpPW);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
@@ -125,7 +123,7 @@ uint32 Database::CheckLogin(const char* name, const char* password, const char *
|
|||||||
//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(const char* loginIP)
|
bool Database::CheckBannedIPs(const char* loginIP)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat("SELECT ip_address FROM banned_ips WHERE ip_address='%s'", loginIP);
|
std::string query = StringFormat("SELECT ip_address FROM Banned_IPs WHERE ip_address='%s'", loginIP);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
@@ -141,7 +139,7 @@ bool Database::CheckBannedIPs(const char* loginIP)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
|
bool Database::AddBannedIP(char* bannedIP, const char* notes) {
|
||||||
std::string query = StringFormat("INSERT into banned_ips SET ip_address='%s', notes='%s'", bannedIP, notes);
|
std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -173,87 +171,61 @@ void Database::LoginIP(uint32 AccountID, const char* LoginIP) {
|
|||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Database::CheckStatus(uint32 account_id)
|
int16 Database::CheckStatus(uint32 account_id) {
|
||||||
{
|
std::string query = StringFormat("SELECT `status`, UNIX_TIMESTAMP(`suspendeduntil`) as `suspendeduntil`, UNIX_TIMESTAMP() as `current`"
|
||||||
std::string query = StringFormat(
|
" FROM `account` WHERE `id` = %i", account_id);
|
||||||
"SELECT `status`, TIMESTAMPDIFF(SECOND, NOW(), `suspendeduntil`) FROM `account` WHERE `id` = %i",
|
|
||||||
account_id);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (results.RowCount() != 1)
|
if (results.RowCount() != 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
int16 status = atoi(row[0]);
|
int16 status = atoi(row[0]);
|
||||||
int32 date_diff = 0;
|
int32 suspendeduntil = 0;
|
||||||
|
|
||||||
if (row[1] != nullptr)
|
// MariaDB initalizes with NULL if unix_timestamp() is out of range
|
||||||
date_diff = atoi(row[1]);
|
if (row[1] != nullptr) {
|
||||||
|
suspendeduntil = atoi(row[1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (date_diff > 0)
|
int32 current = atoi(row[2]);
|
||||||
|
|
||||||
|
if(suspendeduntil > current)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) {
|
||||||
* @param name
|
|
||||||
* @param password
|
|
||||||
* @param status
|
|
||||||
* @param loginserver
|
|
||||||
* @param lsaccount_id
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
uint32 Database::CreateAccount(
|
|
||||||
const char *name,
|
|
||||||
const char *password,
|
|
||||||
int16 status,
|
|
||||||
const char *loginserver,
|
|
||||||
uint32 lsaccount_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string query;
|
std::string query;
|
||||||
|
|
||||||
if (password) {
|
if (password)
|
||||||
query = StringFormat(
|
query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name,password,status, lsaccount_id);
|
||||||
"INSERT INTO account SET name='%s', password='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",
|
else
|
||||||
name,
|
query = StringFormat("INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id);
|
||||||
password,
|
|
||||||
status,
|
|
||||||
loginserver,
|
|
||||||
lsaccount_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
query = StringFormat(
|
|
||||||
"INSERT INTO account SET name='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",
|
|
||||||
name,
|
|
||||||
status,
|
|
||||||
loginserver,
|
|
||||||
lsaccount_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("Account Attempting to be created: [{0}:{1}] status: {2}", loginserver, name, status);
|
Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s' status: %i", name, status);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.LastInsertedID() == 0) {
|
if (results.LastInsertedID() == 0)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return results.LastInsertedID();
|
return results.LastInsertedID();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::DeleteAccount(const char* name, const char *loginserver) {
|
bool Database::DeleteAccount(const char* name) {
|
||||||
std::string query = StringFormat("DELETE FROM account WHERE `name`='%s' AND ls_id='%s'", name, loginserver);
|
std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name);
|
||||||
LogInfo("Account Attempting to be deleted:'[{}]:[{}]'", loginserver, name);
|
Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name);
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -294,44 +266,13 @@ bool Database::SetAccountStatus(const char* name, int16 status) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param account_name
|
|
||||||
* @param status
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool Database::SetAccountStatus(const std::string& account_name, int16 status)
|
|
||||||
{
|
|
||||||
LogInfo("Account [{}] is attempting to be set to status [{}]", account_name, status);
|
|
||||||
|
|
||||||
std::string query = fmt::format(
|
|
||||||
SQL(
|
|
||||||
UPDATE account SET status = {} WHERE name = '{}'
|
|
||||||
),
|
|
||||||
status,
|
|
||||||
account_name
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowsAffected() == 0) {
|
|
||||||
LogWarning("Account [{}] does not exist!", account_name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This initially creates the character during character create */
|
/* This initially creates the character during character create */
|
||||||
bool Database::ReserveName(uint32 account_id, char* name) {
|
bool Database::ReserveName(uint32 account_id, char* name) {
|
||||||
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
|
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
if (row[0] && atoi(row[0]) > 0){
|
if (row[0] && atoi(row[0]) > 0){
|
||||||
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
Log(Logs::General, Logs::World_Server, "Account: %i tried to request name: %s, but it is already taken...", account_id, name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,81 +280,70 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
|||||||
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
|
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success() || results.ErrorMessage() != ""){ return false; }
|
if (!results.Success() || results.ErrorMessage() != ""){ return false; }
|
||||||
|
|
||||||
// Put character into the default guild if rule is being used.
|
|
||||||
int guild_id = RuleI(Character, DefaultGuild);
|
|
||||||
|
|
||||||
if (guild_id != 0) {
|
|
||||||
int character_id=results.LastInsertedID();
|
|
||||||
if (character_id > -1) {
|
|
||||||
query = StringFormat("INSERT INTO `guild_members` SET `char_id` = %i, `guild_id` = '%i'", character_id, guild_id);
|
|
||||||
results = QueryDatabase(query);
|
|
||||||
if (!results.Success() || results.ErrorMessage() != ""){
|
|
||||||
LogInfo("Could not put character [{}] into default Guild", name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* @param character_name
|
Delete the character with the name "name"
|
||||||
* @return
|
returns false on failure, true otherwise
|
||||||
*/
|
*/
|
||||||
bool Database::DeleteCharacter(char *character_name) {
|
bool Database::DeleteCharacter(char *name) {
|
||||||
uint32 character_id = 0;
|
uint32 charid = 0;
|
||||||
if(!character_name || !strlen(character_name)) {
|
if(!name || !strlen(name)) {
|
||||||
LogInfo("DeleteCharacter: request to delete without a name (empty char slot)");
|
Log(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Log(Logs::General, Logs::World_Server, "Database::DeleteCharacter name : '%s'", name);
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
|
/* Get id from character_data before deleting record so we can clean up the rest of the tables */
|
||||||
|
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", name);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); }
|
||||||
character_id = atoi(row[0]);
|
if (charid <= 0){
|
||||||
}
|
Log(Logs::General, Logs::Error, "Database::DeleteCharacter :: Character (%s) not found, stopping delete...", name);
|
||||||
|
|
||||||
if (character_id <= 0) {
|
|
||||||
LogError("DeleteCharacter | Invalid Character ID [{}]", character_name);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string delete_type = "hard-deleted";
|
query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
if (RuleB(Character, SoftDeletes)) {
|
query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
delete_type = "soft-deleted";
|
query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
std::string query = fmt::format(
|
query = StringFormat("DELETE FROM `character_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
SQL(
|
query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
UPDATE
|
query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
character_data
|
query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
SET
|
query = StringFormat("DELETE FROM `timers` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
name = SUBSTRING(CONCAT(name, '-deleted-', UNIX_TIMESTAMP()), 1, 64),
|
query = StringFormat("DELETE FROM `inventory` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
deleted_at = NOW()
|
query = StringFormat("DELETE FROM `char_recipe_list` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
WHERE
|
query = StringFormat("DELETE FROM `adventure_stats` WHERE `player_id` ='%d'", charid); QueryDatabase(query);
|
||||||
id = '{}'
|
query = StringFormat("DELETE FROM `zone_flags` WHERE `charID` = '%d'", charid); QueryDatabase(query);
|
||||||
),
|
query = StringFormat("DELETE FROM `titles` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
character_id
|
query = StringFormat("DELETE FROM `player_titlesets` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
);
|
query = StringFormat("DELETE FROM `keyring` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `faction_values` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
QueryDatabase(query);
|
query = StringFormat("DELETE FROM `instance_list_player` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_data` WHERE `id` = '%d'", charid); QueryDatabase(query);
|
||||||
return true;
|
query = StringFormat("DELETE FROM `character_skills` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
}
|
query = StringFormat("DELETE FROM `character_languages` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_bind` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
LogInfo("DeleteCharacter | Character [{}] ({}) is being [{}]", character_name, character_id, delete_type);
|
query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_currency` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
for (const auto& iter : DatabaseSchema::GetCharacterTables()) {
|
query = StringFormat("DELETE FROM `character_data` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
std::string table_name = iter.first;
|
query = StringFormat("DELETE FROM `character_spells` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
std::string character_id_column_name = iter.second;
|
query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_disciplines` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
QueryDatabase(fmt::format("DELETE FROM {} WHERE {} = {}", table_name, character_id_column_name, character_id));
|
query = StringFormat("DELETE FROM `character_material` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
}
|
query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_bandolier` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_potionbelt` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); QueryDatabase(query);
|
||||||
|
query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); QueryDatabase(query);
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", character_id); // note: only use of GetMobTypeById()
|
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid); // note: only use of GetMobTypeById()
|
||||||
QueryDatabase(query);
|
#else
|
||||||
|
query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d'", charid);
|
||||||
#endif
|
#endif
|
||||||
|
QueryDatabase(query);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -695,7 +625,6 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
pp->RestTimer // " RestTimer) "
|
pp->RestTimer // " RestTimer) "
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
/* Save Bind Points */
|
/* Save Bind Points */
|
||||||
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
||||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
|
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
|
||||||
@@ -758,7 +687,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu
|
|||||||
charid = GetCharacterID(pp->name);
|
charid = GetCharacterID(pp->name);
|
||||||
|
|
||||||
if(!charid) {
|
if(!charid) {
|
||||||
LogError("StoreCharacter: no character id");
|
Log(Logs::General, Logs::Error, "StoreCharacter: no character id");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,12 +788,11 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
|
|||||||
return atoi(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver, int16* status, uint32* lsid) {
|
uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* lsid) {
|
||||||
if (!isAlphaNumeric(accname))
|
if (!isAlphaNumeric(accname))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1",
|
std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' LIMIT 1", accname);
|
||||||
EscapeString(accname).c_str(), EscapeString(loginserver).c_str());
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -925,38 +853,6 @@ void Database::GetCharName(uint32 char_id, char* name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Database::GetCharNameByID(uint32 char_id) {
|
|
||||||
std::string query = fmt::format("SELECT `name` FROM `character_data` WHERE id = {}", char_id);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
return row[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Database::GetNPCNameByID(uint32 npc_id) {
|
|
||||||
std::string query = fmt::format("SELECT `name` FROM `npc_types` WHERE id = {}", npc_id);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
if (!results.Success()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
|
||||||
return row[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Database::LoadVariables() {
|
bool Database::LoadVariables() {
|
||||||
auto results = QueryDatabase(StringFormat("SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache.last_update));
|
auto results = QueryDatabase(StringFormat("SELECT varname, value, unix_timestamp() FROM variables where unix_timestamp(ts) >= %d", varcache.last_update));
|
||||||
|
|
||||||
@@ -1025,6 +921,18 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Database::GetMiniLoginAccount(char* ip)
|
||||||
|
{
|
||||||
|
std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
return atoi(row[0]);
|
||||||
|
}
|
||||||
|
|
||||||
// Get zone starting points from DB
|
// Get zone starting points from DB
|
||||||
bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) {
|
bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) {
|
||||||
|
|
||||||
@@ -1286,46 +1194,25 @@ bool Database::AddToNameFilter(const char* name) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) {
|
||||||
* @param in_loginserver_id
|
|
||||||
* @param in_loginserver_account_id
|
|
||||||
* @param in_account_name
|
|
||||||
* @param in_status
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
uint32 Database::GetAccountIDFromLSID(
|
|
||||||
const std::string &in_loginserver_id,
|
|
||||||
uint32 in_loginserver_account_id,
|
|
||||||
char *in_account_name,
|
|
||||||
int16 *in_status
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32 account_id = 0;
|
uint32 account_id = 0;
|
||||||
auto query = fmt::format(
|
std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID);
|
||||||
"SELECT id, `name`, status FROM account WHERE lsaccount_id = {0} AND ls_id = '{1}'",
|
|
||||||
in_loginserver_account_id,
|
|
||||||
in_loginserver_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.RowCount() != 1) {
|
if (results.RowCount() != 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
account_id = std::stoi(row[0]);
|
account_id = atoi(row[0]);
|
||||||
|
|
||||||
if (in_account_name) {
|
if (oAccountName)
|
||||||
strcpy(in_account_name, row[1]);
|
strcpy(oAccountName, row[1]);
|
||||||
}
|
if (oStatus)
|
||||||
if (in_status) {
|
*oStatus = atoi(row[2]);
|
||||||
*in_status = std::stoi(row[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return account_id;
|
return account_id;
|
||||||
@@ -1333,7 +1220,7 @@ uint32 Database::GetAccountIDFromLSID(
|
|||||||
|
|
||||||
void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
|
void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT `name`, status FROM account WHERE id=%i", id);
|
std::string query = StringFormat("SELECT name, status FROM account WHERE id=%i", id);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()){
|
if (!results.Success()){
|
||||||
@@ -1558,9 +1445,9 @@ uint32 Database::GetCharacterInfo(
|
|||||||
return charid;
|
return charid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::UpdateLiveChar(char* charname, uint32 account_id) {
|
bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) {
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;", charname, account_id);
|
std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()){
|
if (!results.Success()){
|
||||||
@@ -1627,7 +1514,7 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism
|
|||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
LogError("Error deleting character from group id: {}", results.ErrorMessage().c_str());
|
Log(Logs::General, Logs::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1670,7 +1557,7 @@ uint32 Database::GetGroupID(const char* name){
|
|||||||
if (results.RowCount() == 0)
|
if (results.RowCount() == 0)
|
||||||
{
|
{
|
||||||
// Commenting this out until logging levels can prevent this from going to console
|
// Commenting this out until logging levels can prevent this from going to console
|
||||||
//LogDebug(, "Character not in a group: [{}]", name);
|
//Log(Logs::General, Logs::None,, "Character not in a group: %s", name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1717,7 +1604,7 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) {
|
|||||||
result = QueryDatabase(query);
|
result = QueryDatabase(query);
|
||||||
|
|
||||||
if(!result.Success()) {
|
if(!result.Success()) {
|
||||||
LogDebug("Error in Database::SetGroupLeaderName: [{}]", result.ErrorMessage().c_str());
|
Log(Logs::General, Logs::None, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1923,7 +1810,7 @@ const char* Database::GetRaidLeaderName(uint32 raid_id)
|
|||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
LogDebug("Unable to get Raid Leader Name for Raid ID: [{}]", raid_id);
|
Log(Logs::General, Logs::Debug, "Unable to get Raid Leader Name for Raid ID: %u", raid_id);
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2190,49 +2077,9 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
|
|||||||
return atoi(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) {
|
||||||
{
|
// log_settings previously initialized to '0' by EQEmuLogSys::LoadLogSettingsDefaults()
|
||||||
std::string query = fmt::format(
|
|
||||||
SQL(
|
|
||||||
SELECT groupid
|
|
||||||
FROM group_id
|
|
||||||
WHERE charid = '{}'
|
|
||||||
),
|
|
||||||
character_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::GetRaidIDByCharID(uint32 character_id) {
|
|
||||||
std::string query = fmt::format(
|
|
||||||
SQL(
|
|
||||||
SELECT raidid
|
|
||||||
FROM raid_members
|
|
||||||
WHERE charid = '{}'
|
|
||||||
),
|
|
||||||
character_id
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
return atoi(row[0]);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param log_settings
|
|
||||||
*/
|
|
||||||
void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings)
|
|
||||||
{
|
|
||||||
std::string query =
|
std::string query =
|
||||||
"SELECT "
|
"SELECT "
|
||||||
"log_category_id, "
|
"log_category_id, "
|
||||||
@@ -2245,9 +2092,10 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings)
|
|||||||
"ORDER BY log_category_id";
|
"ORDER BY log_category_id";
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
int log_category_id = 0;
|
int log_category_id = 0;
|
||||||
|
|
||||||
int *categories_in_database = new int[1000];
|
int categories_in_database[1000] = {};
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
log_category_id = atoi(row[0]);
|
log_category_id = atoi(row[0]);
|
||||||
@@ -2287,14 +2135,15 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings)
|
|||||||
* Auto inject categories that don't exist in the database...
|
* Auto inject categories that don't exist in the database...
|
||||||
*/
|
*/
|
||||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||||
if (categories_in_database[log_index] != 1) {
|
if (!categories_in_database[log_index]) {
|
||||||
|
|
||||||
LogInfo(
|
Log(Logs::General,
|
||||||
"New Log Category [{0}] doesn't exist... Automatically adding to [logsys_categories] table...",
|
Logs::Status,
|
||||||
|
"New Log Category '%s' doesn't exist... Automatically adding to `logsys_categories` table...",
|
||||||
Logs::LogCategoryName[log_index]
|
Logs::LogCategoryName[log_index]
|
||||||
);
|
);
|
||||||
|
|
||||||
auto inject_query = fmt::format(
|
std::string inject_query = StringFormat(
|
||||||
"INSERT INTO logsys_categories "
|
"INSERT INTO logsys_categories "
|
||||||
"(log_category_id, "
|
"(log_category_id, "
|
||||||
"log_category_description, "
|
"log_category_description, "
|
||||||
@@ -2302,19 +2151,17 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings)
|
|||||||
"log_to_file, "
|
"log_to_file, "
|
||||||
"log_to_gmsay) "
|
"log_to_gmsay) "
|
||||||
"VALUES "
|
"VALUES "
|
||||||
"({0}, '{1}', {2}, {3}, {4})",
|
"(%i, '%s', %i, %i, %i)",
|
||||||
log_index,
|
log_index,
|
||||||
EscapeString(Logs::LogCategoryName[log_index]),
|
EscapeString(Logs::LogCategoryName[log_index]).c_str(),
|
||||||
std::to_string(log_settings[log_index].log_to_console),
|
log_settings[log_category_id].log_to_console,
|
||||||
std::to_string(log_settings[log_index].log_to_file),
|
log_settings[log_category_id].log_to_file,
|
||||||
std::to_string(log_settings[log_index].log_to_gmsay)
|
log_settings[log_category_id].log_to_gmsay
|
||||||
);
|
);
|
||||||
|
|
||||||
QueryDatabase(inject_query);
|
QueryDatabase(inject_query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] categories_in_database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::CountInvSnapshots() {
|
int Database::CountInvSnapshots() {
|
||||||
@@ -2351,7 +2198,7 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
|||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success() || results.RowCount() == 0){
|
if (!results.Success() || results.RowCount() == 0){
|
||||||
LogInfo("Loading EQ time of day failed. Using defaults");
|
Log(Logs::Detail, Logs::World_Server, "Loading EQ time of day failed. Using defaults.");
|
||||||
eqTime.minute = 0;
|
eqTime.minute = 0;
|
||||||
eqTime.hour = 9;
|
eqTime.hour = 9;
|
||||||
eqTime.day = 1;
|
eqTime.day = 1;
|
||||||
@@ -2405,4 +2252,3 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-15
@@ -94,8 +94,6 @@ class PTimerList;
|
|||||||
# define _ISNAN_(a) std::isnan(a)
|
# define _ISNAN_(a) std::isnan(a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SQL(...) #__VA_ARGS__
|
|
||||||
|
|
||||||
class Database : public DBcore {
|
class Database : public DBcore {
|
||||||
public:
|
public:
|
||||||
Database();
|
Database();
|
||||||
@@ -107,7 +105,7 @@ public:
|
|||||||
|
|
||||||
bool AddToNameFilter(const char* name);
|
bool AddToNameFilter(const char* name);
|
||||||
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
|
bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face);
|
||||||
bool DeleteCharacter(char* character_name);
|
bool DeleteCharacter(char* name);
|
||||||
bool MoveCharacterToZone(const char* charname, const char* zonename);
|
bool MoveCharacterToZone(const char* charname, const char* zonename);
|
||||||
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
|
bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid);
|
||||||
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
|
bool MoveCharacterToZone(uint32 iCharID, const char* iZonename);
|
||||||
@@ -120,7 +118,7 @@ public:
|
|||||||
|
|
||||||
/* General Information Queries */
|
/* General Information Queries */
|
||||||
|
|
||||||
bool AddBannedIP(char* bannedIP, const char* 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 AddGMIP(char* ip_address, char* name);
|
bool AddGMIP(char* ip_address, char* name);
|
||||||
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table.
|
||||||
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
bool CheckGMIPs(const char* loginIP, uint32 account_id);
|
||||||
@@ -129,17 +127,13 @@ public:
|
|||||||
|
|
||||||
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(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0);
|
uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0);
|
||||||
uint32 GetCharacterID(const char *name);
|
uint32 GetCharacterID(const char *name);
|
||||||
uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0);
|
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 GetRaidIDByCharID(uint32 char_id);
|
|
||||||
|
|
||||||
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0);
|
||||||
void GetCharName(uint32 char_id, char* name);
|
void GetCharName(uint32 char_id, char* name);
|
||||||
const char *GetCharNameByID(uint32 char_id);
|
|
||||||
const char *GetNPCNameByID(uint32 npc_id);
|
|
||||||
void LoginIP(uint32 AccountID, const char* LoginIP);
|
void LoginIP(uint32 AccountID, const char* LoginIP);
|
||||||
|
|
||||||
/* Instancing */
|
/* Instancing */
|
||||||
@@ -180,18 +174,18 @@ public:
|
|||||||
|
|
||||||
/* Account Related */
|
/* Account Related */
|
||||||
|
|
||||||
bool DeleteAccount(const char *name, const char* loginserver);
|
bool DeleteAccount(const char* name);
|
||||||
bool GetLiveChar(uint32 account_id, char* cname);
|
bool GetLiveChar(uint32 account_id, char* cname);
|
||||||
bool SetAccountStatus(const char* name, int16 status);
|
bool SetAccountStatus(const char* name, int16 status);
|
||||||
bool SetAccountStatus(const std::string& account_name, int16 status);
|
|
||||||
bool SetLocalPassword(uint32 accid, const char* password);
|
bool SetLocalPassword(uint32 accid, const char* password);
|
||||||
bool UpdateLiveChar(char* charname, uint32 account_id);
|
bool UpdateLiveChar(char* charname, uint32 lsaccount_id);
|
||||||
|
|
||||||
int16 CheckStatus(uint32 account_id);
|
int16 CheckStatus(uint32 account_id);
|
||||||
|
|
||||||
uint32 CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus = 0);
|
uint32 CheckLogin(const char* name, const char* password, 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, uint32 lsaccount_id = 0);
|
||||||
uint32 GetAccountIDFromLSID(const std::string& in_loginserver_id, uint32 in_loginserver_account_id, char* in_account_name = 0, int16* in_status = 0);
|
uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0);
|
||||||
|
uint32 GetMiniLoginAccount(char* ip);
|
||||||
uint8 GetAgreementFlag(uint32 acctid);
|
uint8 GetAgreementFlag(uint32 acctid);
|
||||||
|
|
||||||
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus);
|
||||||
|
|||||||
@@ -1,569 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <iterator>
|
|
||||||
#include "database_dump_service.h"
|
|
||||||
#include "../eqemu_logsys.h"
|
|
||||||
#include "../string_util.h"
|
|
||||||
#include "../eqemu_config.h"
|
|
||||||
#include "../database_schema.h"
|
|
||||||
#include "../file_util.h"
|
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
|
|
||||||
#if _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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
|
|
||||||
*/
|
|
||||||
bool DatabaseDumpService::IsMySQLInstalled()
|
|
||||||
{
|
|
||||||
std::string version_output = GetMySQLVersion();
|
|
||||||
|
|
||||||
return version_output.find("mysql") != std::string::npos && version_output.find("Ver") != std::string::npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Linux
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
bool DatabaseDumpService::IsTarAvailable()
|
|
||||||
{
|
|
||||||
std::string version_output = execute("tar --version");
|
|
||||||
|
|
||||||
return version_output.find("GNU tar") != std::string::npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Windows
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
bool DatabaseDumpService::Is7ZipAvailable()
|
|
||||||
{
|
|
||||||
std::string version_output = execute("7z --help");
|
|
||||||
|
|
||||||
return version_output.find("7-Zip") != std::string::npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool DatabaseDumpService::HasCompressionBinary()
|
|
||||||
{
|
|
||||||
return IsTarAvailable() || Is7ZipAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetMySQLVersion()
|
|
||||||
{
|
|
||||||
std::string version_output = execute("mysql --version");
|
|
||||||
|
|
||||||
return trim(version_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
|
||||||
{
|
|
||||||
auto config = EQEmuConfig::get();
|
|
||||||
|
|
||||||
return fmt::format(
|
|
||||||
"mysqldump -u {} -p{} -h {} {}",
|
|
||||||
config->DatabaseUsername,
|
|
||||||
config->DatabasePassword,
|
|
||||||
config->DatabaseHost,
|
|
||||||
config->DatabaseDB
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetPlayerTablesList()
|
|
||||||
{
|
|
||||||
std::string tables_list;
|
|
||||||
std::vector<std::string> tables = DatabaseSchema::GetPlayerTables();
|
|
||||||
for (const auto &table : tables) {
|
|
||||||
tables_list += table + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim(tables_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetLoginTableList()
|
|
||||||
{
|
|
||||||
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 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 tables_list;
|
|
||||||
|
|
||||||
std::vector<std::string> tables = DatabaseSchema::GetServerTables();
|
|
||||||
for (const auto &table : tables) {
|
|
||||||
tables_list += table + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
tables = DatabaseSchema::GetVersionTables();
|
|
||||||
for (const auto &table : tables) {
|
|
||||||
tables_list += table + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim(tables_list);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetStateTablesList()
|
|
||||||
{
|
|
||||||
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 tables_list;
|
|
||||||
|
|
||||||
std::vector<std::string> tables = DatabaseSchema::GetContentTables();
|
|
||||||
for (const auto &table : tables) {
|
|
||||||
tables_list += table + " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim(tables_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string GetDumpDate()
|
|
||||||
{
|
|
||||||
|
|
||||||
time_t now = time(nullptr);
|
|
||||||
struct tm time_struct{};
|
|
||||||
char buf[80];
|
|
||||||
time_struct = *localtime(&now);
|
|
||||||
strftime(buf, sizeof(buf), "%Y-%m-%d", &time_struct);
|
|
||||||
|
|
||||||
std::string time = buf;
|
|
||||||
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetSetDumpPath()
|
|
||||||
{
|
|
||||||
return !GetDumpPath().empty() ? GetDumpPath() : DATABASE_DUMP_PATH;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string DatabaseDumpService::GetDumpFileNameWithPath()
|
|
||||||
{
|
|
||||||
return GetSetDumpPath() + GetDumpFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::Dump()
|
|
||||||
{
|
|
||||||
if (!IsMySQLInstalled()) {
|
|
||||||
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpDropTableSyntaxOnly()) {
|
|
||||||
SetDumpOutputToConsole(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpOutputToConsole()) {
|
|
||||||
LogSys.SilenceConsoleLogging();
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("MySQL installed [{}]", GetMySQLVersion());
|
|
||||||
|
|
||||||
SetDumpFileName(EQEmuConfig::get()->DatabaseDB + '-' + GetDumpDate());
|
|
||||||
|
|
||||||
auto config = EQEmuConfig::get();
|
|
||||||
|
|
||||||
LogInfo(
|
|
||||||
"Database [{}] Host [{}] Username [{}]",
|
|
||||||
config->DatabaseDB,
|
|
||||||
config->DatabaseHost,
|
|
||||||
config->DatabaseUsername
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string options = "--allow-keywords --extended-insert";
|
|
||||||
|
|
||||||
if (IsDumpWithNoData()) {
|
|
||||||
options += " --no-data";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsDumpTableLock()) {
|
|
||||||
options += " --skip-lock-tables";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string tables_to_dump;
|
|
||||||
std::string dump_descriptor;
|
|
||||||
|
|
||||||
if (!IsDumpAllTables()) {
|
|
||||||
if (IsDumpPlayerTables()) {
|
|
||||||
tables_to_dump += GetPlayerTablesList() + " ";
|
|
||||||
dump_descriptor += "-player";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpSystemTables()) {
|
|
||||||
tables_to_dump += GetSystemTablesList() + " ";
|
|
||||||
dump_descriptor += "-system";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpStateTables()) {
|
|
||||||
tables_to_dump += GetStateTablesList() + " ";
|
|
||||||
dump_descriptor += "-state";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpContentTables()) {
|
|
||||||
tables_to_dump += GetContentTablesList() + " ";
|
|
||||||
dump_descriptor += "-content";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpLoginServerTables()) {
|
|
||||||
tables_to_dump += GetLoginTableList() + " ";
|
|
||||||
dump_descriptor += "-login";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpQueryServerTables()) {
|
|
||||||
tables_to_dump += GetQueryServTables();
|
|
||||||
dump_descriptor += "-queryserv";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dump_descriptor.empty()) {
|
|
||||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we are dumping to stdout then we don't generate a file
|
|
||||||
*/
|
|
||||||
std::string pipe_file;
|
|
||||||
if (!IsDumpOutputToConsole()) {
|
|
||||||
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string execute_command = fmt::format(
|
|
||||||
"{} {} {} {}",
|
|
||||||
GetBaseMySQLDumpCommand(),
|
|
||||||
options,
|
|
||||||
tables_to_dump,
|
|
||||||
pipe_file
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!FileUtil::exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
|
||||||
FileUtil::mkdir(GetSetDumpPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDumpDropTableSyntaxOnly()) {
|
|
||||||
std::vector<std::string> tables = SplitString(tables_to_dump, ' ');
|
|
||||||
|
|
||||||
for (auto &table : tables) {
|
|
||||||
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tables_to_dump.empty()) {
|
|
||||||
std::cerr << "No tables were specified" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::string execution_result = execute(execute_command, IsDumpOutputToConsole());
|
|
||||||
if (!execution_result.empty()) {
|
|
||||||
std::cout << execution_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tables_to_dump.empty()) {
|
|
||||||
LogInfo("Dumping Tables [{}]", tables_to_dump);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
|
||||||
|
|
||||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
|
||||||
if (HasCompressionBinary()) {
|
|
||||||
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
|
||||||
|
|
||||||
if (IsTarAvailable()) {
|
|
||||||
execute(
|
|
||||||
fmt::format(
|
|
||||||
"tar -zcvf {}.tar.gz -C {} {}.sql",
|
|
||||||
GetDumpFileNameWithPath(),
|
|
||||||
GetSetDumpPath(),
|
|
||||||
GetDumpFileName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
|
||||||
}
|
|
||||||
else if (Is7ZipAvailable()) {
|
|
||||||
execute(
|
|
||||||
fmt::format(
|
|
||||||
"7z a -t7z {}.zip {}.sql",
|
|
||||||
GetDumpFileNameWithPath(),
|
|
||||||
GetDumpFileNameWithPath()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogInfo("Compression requested, but no available compression binary was found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogWarning("Compression requested but binary not found... Skipping...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
|
||||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
|
||||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] query-serv", (IsDumpQueryServerTables() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] has-compression-binary", (HasCompressionBinary() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] content", (IsDumpContentTables() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] no-data", (IsDumpWithNoData() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] login", (IsDumpLoginServerTables() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] player", (IsDumpPlayerTables() ? "true" : "false"));
|
|
||||||
// LogDebug("[{}] system", (IsDumpSystemTables() ? "true" : "false"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpSystemTables() const
|
|
||||||
{
|
|
||||||
return dump_system_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpSystemTables(bool dump_system_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_system_tables = dump_system_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpContentTables() const
|
|
||||||
{
|
|
||||||
return dump_content_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpContentTables(bool dump_content_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_content_tables = dump_content_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpPlayerTables() const
|
|
||||||
{
|
|
||||||
return dump_player_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpPlayerTables(bool dump_player_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_player_tables = dump_player_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpLoginServerTables() const
|
|
||||||
{
|
|
||||||
return dump_login_server_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpLoginServerTables(bool dump_login_server_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_login_server_tables = dump_login_server_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpWithNoData() const
|
|
||||||
{
|
|
||||||
return dump_with_no_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpWithNoData(bool dump_with_no_data)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_with_no_data = dump_with_no_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpAllTables() const
|
|
||||||
{
|
|
||||||
return dump_all_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpAllTables(bool dump_all_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_all_tables = dump_all_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpTableLock() const
|
|
||||||
{
|
|
||||||
return dump_table_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpTableLock(bool dump_table_lock)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_table_lock = dump_table_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpWithCompression() const
|
|
||||||
{
|
|
||||||
return dump_with_compression;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpWithCompression(bool dump_with_compression)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_with_compression = dump_with_compression;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &DatabaseDumpService::GetDumpPath() const
|
|
||||||
{
|
|
||||||
return dump_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpPath(const std::string &dump_path)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_path = dump_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpFileName(const std::string &dump_file_name)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_file_name = dump_file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &DatabaseDumpService::GetDumpFileName() const
|
|
||||||
{
|
|
||||||
return dump_file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpQueryServerTables() const
|
|
||||||
{
|
|
||||||
return dump_query_server_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpQueryServerTables(bool dump_query_server_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_query_server_tables = dump_query_server_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpOutputToConsole() const
|
|
||||||
{
|
|
||||||
return dump_output_to_console;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpOutputToConsole(bool dump_output_to_console)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_output_to_console = dump_output_to_console;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpDropTableSyntaxOnly() const
|
|
||||||
{
|
|
||||||
return dump_drop_table_syntax_only;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_drop_table_syntax_only = dump_drop_table_syntax_only;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseDumpService::IsDumpStateTables() const
|
|
||||||
{
|
|
||||||
return dump_state_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::SetDumpStateTables(bool dump_state_tables)
|
|
||||||
{
|
|
||||||
DatabaseDumpService::dump_state_tables = dump_state_tables;
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EQEMU_DATABASE_DUMP_SERVICE_H
|
|
||||||
#define EQEMU_DATABASE_DUMP_SERVICE_H
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseDumpService {
|
|
||||||
public:
|
|
||||||
void Dump();
|
|
||||||
bool IsDumpAllTables() const;
|
|
||||||
void SetDumpAllTables(bool dump_all_tables);
|
|
||||||
bool IsDumpWithNoData() const;
|
|
||||||
void SetDumpWithNoData(bool dump_with_no_data);
|
|
||||||
bool IsDumpSystemTables() const;
|
|
||||||
void SetDumpSystemTables(bool dump_system_tables);
|
|
||||||
bool IsDumpContentTables() const;
|
|
||||||
void SetDumpContentTables(bool dump_content_tables);
|
|
||||||
bool IsDumpPlayerTables() const;
|
|
||||||
void SetDumpPlayerTables(bool dump_player_tables);
|
|
||||||
bool IsDumpLoginServerTables() const;
|
|
||||||
void SetDumpLoginServerTables(bool dump_login_server_tables);
|
|
||||||
bool IsDumpTableLock() const;
|
|
||||||
void SetDumpTableLock(bool dump_table_lock);
|
|
||||||
bool IsDumpWithCompression() const;
|
|
||||||
void SetDumpWithCompression(bool dump_with_compression);
|
|
||||||
const std::string &GetDumpPath() const;
|
|
||||||
void SetDumpPath(const std::string &dump_path);
|
|
||||||
const std::string &GetDumpFileName() const;
|
|
||||||
void SetDumpFileName(const std::string &dump_file_name);
|
|
||||||
bool IsDumpQueryServerTables() const;
|
|
||||||
void SetDumpQueryServerTables(bool dump_query_server_tables);
|
|
||||||
bool IsDumpOutputToConsole() const;
|
|
||||||
void SetDumpOutputToConsole(bool dump_output_to_console);
|
|
||||||
bool IsDumpDropTableSyntaxOnly() const;
|
|
||||||
void SetDumpDropTableSyntaxOnly(bool dump_drop_table_syntax_only);
|
|
||||||
bool IsDumpStateTables() const;
|
|
||||||
void SetDumpStateTables(bool dump_state_tables);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool dump_all_tables = false;
|
|
||||||
bool dump_state_tables = false;
|
|
||||||
bool dump_system_tables = false;
|
|
||||||
bool dump_content_tables = false;
|
|
||||||
bool dump_player_tables = false;
|
|
||||||
bool dump_query_server_tables = false;
|
|
||||||
bool dump_login_server_tables = false;
|
|
||||||
bool dump_with_no_data = false;
|
|
||||||
bool dump_table_lock = false;
|
|
||||||
bool dump_with_compression = false;
|
|
||||||
bool dump_output_to_console = false;
|
|
||||||
bool dump_drop_table_syntax_only = false;
|
|
||||||
std::string dump_path;
|
|
||||||
std::string dump_file_name;
|
|
||||||
|
|
||||||
std::string execute(const std::string &cmd, bool return_result);
|
|
||||||
bool IsMySQLInstalled();
|
|
||||||
std::string GetMySQLVersion();
|
|
||||||
std::string GetBaseMySQLDumpCommand();
|
|
||||||
std::string GetPlayerTablesList();
|
|
||||||
std::string GetSystemTablesList();
|
|
||||||
std::string GetStateTablesList();
|
|
||||||
std::string GetContentTablesList();
|
|
||||||
std::string GetLoginTableList();
|
|
||||||
bool IsTarAvailable();
|
|
||||||
bool Is7ZipAvailable();
|
|
||||||
bool HasCompressionBinary();
|
|
||||||
std::string GetDumpFileNameWithPath();
|
|
||||||
std::string GetSetDumpPath();
|
|
||||||
std::string GetQueryServTables();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EQEMU_DATABASE_DUMP_SERVICE_H
|
|
||||||
@@ -476,7 +476,7 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
CheckDatabaseConvertCorpseDeblob();
|
CheckDatabaseConvertCorpseDeblob();
|
||||||
|
|
||||||
/* 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"));
|
system("perl eqemu_server.pl ran_from_world");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,20 +101,14 @@ bool Database::CheckInstanceExpired(uint16 instance_id)
|
|||||||
int32 duration = 0;
|
int32 duration = 0;
|
||||||
uint32 never_expires = 0;
|
uint32 never_expires = 0;
|
||||||
|
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id);
|
||||||
"SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u",
|
|
||||||
instance_id
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success())
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
@@ -122,28 +116,23 @@ bool Database::CheckInstanceExpired(uint16 instance_id)
|
|||||||
duration = atoi(row[1]);
|
duration = atoi(row[1]);
|
||||||
never_expires = atoi(row[2]);
|
never_expires = atoi(row[2]);
|
||||||
|
|
||||||
if (never_expires == 1) {
|
if (never_expires == 1)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
timeval tv{};
|
timeval tv;
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
|
|
||||||
return (start_time + duration) <= tv.tv_sec;
|
if ((start_time + duration) <= tv.tv_sec)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
||||||
"INSERT INTO instance_list (id, zone, version, start_time, duration)"
|
" values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)",
|
||||||
" values (%u, %u, %u, UNIX_TIMESTAMP(), %u)",
|
(unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration);
|
||||||
instance_id,
|
|
||||||
zone_id,
|
|
||||||
version,
|
|
||||||
duration
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
return results.Success();
|
return results.Success();
|
||||||
@@ -151,84 +140,66 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
|||||||
|
|
||||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||||
{
|
{
|
||||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
uint32 count = RuleI(Zone, ReservedInstances);
|
||||||
uint32 max = 32000;
|
uint32 max = 65535;
|
||||||
|
|
||||||
std::string query = StringFormat(
|
|
||||||
"SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u",
|
|
||||||
max_reserved_instance_id,
|
|
||||||
max_reserved_instance_id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
|
||||||
query = (
|
|
||||||
SQL(
|
|
||||||
SELECT i.id + 1 AS next_available
|
|
||||||
FROM instance_list i
|
|
||||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
|
||||||
WHERE i2.id IS NULL
|
|
||||||
ORDER BY i.id
|
|
||||||
LIMIT 0, 1;
|
|
||||||
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success())
|
||||||
|
{
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0)
|
||||||
instance_id = max_reserved_instance_id;
|
{
|
||||||
return true;
|
instance_id = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if (atoi(row[0]) <= max) {
|
if (atoi(row[0]) <= max)
|
||||||
|
{
|
||||||
instance_id = atoi(row[0]);
|
instance_id = atoi(row[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance_id < max_reserved_instance_id) {
|
query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count);
|
||||||
instance_id = max_reserved_instance_id;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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())
|
||||||
|
{
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0)
|
||||||
|
{
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
count++;
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
if (max_reserved_instance_id < atoi(row[0])) {
|
{
|
||||||
instance_id = max_reserved_instance_id;
|
if (count < atoi(row[0]))
|
||||||
|
{
|
||||||
|
instance_id = count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_reserved_instance_id > max) {
|
if (count > max)
|
||||||
|
{
|
||||||
instance_id = 0;
|
instance_id = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
max_reserved_instance_id++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = count;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,36 +548,17 @@ void Database::GetCharactersInInstance(uint16 instance_id, std::list<uint32> &ch
|
|||||||
|
|
||||||
void Database::PurgeExpiredInstances()
|
void Database::PurgeExpiredInstances()
|
||||||
{
|
{
|
||||||
|
std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0");
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* has not been fully de-allocated
|
|
||||||
*/
|
|
||||||
std::string query =
|
|
||||||
SQL(
|
|
||||||
SELECT
|
|
||||||
id
|
|
||||||
FROM
|
|
||||||
instance_list
|
|
||||||
where
|
|
||||||
(start_time + duration) <= (UNIX_TIMESTAMP() - 86400)
|
|
||||||
and never_expires = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
if (!results.Success()) {
|
if (!results.Success())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0) {
|
if (results.RowCount() == 0)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
DeleteInstance(atoi(row[0]));
|
DeleteInstance(atoi(row[0]));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||||
|
|||||||
@@ -1,369 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EQEMU_DATABASE_SCHEMA_H
|
|
||||||
#define EQEMU_DATABASE_SCHEMA_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace DatabaseSchema {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Character-specific tables
|
|
||||||
*
|
|
||||||
* Does not included related meta-data tables such as 'guilds', 'accounts'
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::map<std::string, std::string> GetCharacterTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
{"adventure_stats", "player_id"},
|
|
||||||
{"buyer", "charid"},
|
|
||||||
{"char_recipe_list", "char_id"},
|
|
||||||
{"character_activities", "charid"},
|
|
||||||
{"character_alt_currency", "char_id"},
|
|
||||||
{"character_alternate_abilities", "id"},
|
|
||||||
{"character_auras", "id"},
|
|
||||||
{"character_bandolier", "id"},
|
|
||||||
{"character_bind", "id"},
|
|
||||||
{"character_buffs", "character_id"},
|
|
||||||
{"character_corpses", "id"},
|
|
||||||
{"character_currency", "id"},
|
|
||||||
{"character_data", "id"},
|
|
||||||
{"character_disciplines", "id"},
|
|
||||||
{"character_enabledtasks", "charid"},
|
|
||||||
{"character_inspect_messages", "id"},
|
|
||||||
{"character_item_recast", "id"},
|
|
||||||
{"character_languages", "id"},
|
|
||||||
{"character_leadership_abilities", "id"},
|
|
||||||
{"character_material", "id"},
|
|
||||||
{"character_memmed_spells", "id"},
|
|
||||||
{"character_pet_buffs", "char_id"},
|
|
||||||
{"character_pet_info", "char_id"},
|
|
||||||
{"character_pet_inventory", "char_id"},
|
|
||||||
{"character_potionbelt", "id"},
|
|
||||||
{"character_skills", "id"},
|
|
||||||
{"character_spells", "id"},
|
|
||||||
{"character_tasks", "charid"},
|
|
||||||
{"character_tribute", "id"},
|
|
||||||
{"completed_tasks", "charid"},
|
|
||||||
{"data_buckets", "id"},
|
|
||||||
{"faction_values", "char_id"},
|
|
||||||
{"friends", "charid"},
|
|
||||||
{"guild_members", "char_id"},
|
|
||||||
{"guilds", "id"},
|
|
||||||
{"instance_list_player", "id"},
|
|
||||||
{"inventory", "charid"},
|
|
||||||
{"inventory_snapshots", "charid"},
|
|
||||||
{"keyring", "char_id"},
|
|
||||||
{"mail", "charid"},
|
|
||||||
{"player_titlesets", "char_id"},
|
|
||||||
{"quest_globals", "charid"},
|
|
||||||
{"timers", "char_id"},
|
|
||||||
{"titles", "char_id"},
|
|
||||||
{"trader", "char_id"},
|
|
||||||
{"zone_flags", "charID"}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Gets all player and meta-data tables
|
|
||||||
* @note These tables have no content in the PEQ daily dump
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetPlayerTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"account",
|
|
||||||
"account_ip",
|
|
||||||
"account_flags",
|
|
||||||
"account_rewards",
|
|
||||||
"adventure_details",
|
|
||||||
"adventure_stats",
|
|
||||||
"buyer",
|
|
||||||
"char_recipe_list",
|
|
||||||
"character_activities",
|
|
||||||
"character_alt_currency",
|
|
||||||
"character_alternate_abilities",
|
|
||||||
"character_auras",
|
|
||||||
"character_bandolier",
|
|
||||||
"character_bind",
|
|
||||||
"character_buffs",
|
|
||||||
"character_corpse_items",
|
|
||||||
"character_corpses",
|
|
||||||
"character_currency",
|
|
||||||
"character_data",
|
|
||||||
"character_disciplines",
|
|
||||||
"character_enabledtasks",
|
|
||||||
"character_inspect_messages",
|
|
||||||
"character_item_recast",
|
|
||||||
"character_languages",
|
|
||||||
"character_leadership_abilities",
|
|
||||||
"character_material",
|
|
||||||
"character_memmed_spells",
|
|
||||||
"character_pet_buffs",
|
|
||||||
"character_pet_info",
|
|
||||||
"character_pet_inventory",
|
|
||||||
"character_potionbelt",
|
|
||||||
"character_skills",
|
|
||||||
"character_spells",
|
|
||||||
"character_tasks",
|
|
||||||
"character_tribute",
|
|
||||||
"completed_tasks",
|
|
||||||
"data_buckets",
|
|
||||||
"discovered_items",
|
|
||||||
"faction_values",
|
|
||||||
"friends",
|
|
||||||
"guild_bank",
|
|
||||||
"guild_members",
|
|
||||||
"guild_ranks",
|
|
||||||
"guild_relations",
|
|
||||||
"guilds",
|
|
||||||
"instance_list_player",
|
|
||||||
"inventory",
|
|
||||||
"inventory_snapshots",
|
|
||||||
"keyring",
|
|
||||||
"mail",
|
|
||||||
"petitions",
|
|
||||||
"player_titlesets",
|
|
||||||
"quest_globals",
|
|
||||||
"sharedbank",
|
|
||||||
"spell_buckets",
|
|
||||||
"spell_globals",
|
|
||||||
"timers",
|
|
||||||
"titles",
|
|
||||||
"trader",
|
|
||||||
"trader_audit",
|
|
||||||
"zone_flags"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets content tables
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetContentTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"aa_ability",
|
|
||||||
"aa_actions",
|
|
||||||
"aa_effects",
|
|
||||||
"aa_rank_effects",
|
|
||||||
"aa_rank_prereqs",
|
|
||||||
"aa_ranks",
|
|
||||||
"aa_required_level_cost",
|
|
||||||
"adventure_template",
|
|
||||||
"adventure_template_entry",
|
|
||||||
"adventure_template_entry_flavor",
|
|
||||||
"altadv_vars",
|
|
||||||
"alternate_currency",
|
|
||||||
"auras",
|
|
||||||
"base_data",
|
|
||||||
"blocked_spells",
|
|
||||||
"books",
|
|
||||||
"char_create_combinations",
|
|
||||||
"char_create_point_allocations",
|
|
||||||
"class_skill",
|
|
||||||
"damageshieldtypes",
|
|
||||||
"doors",
|
|
||||||
"faction_base_data",
|
|
||||||
"faction_list",
|
|
||||||
"faction_list_mod",
|
|
||||||
"fear_hints",
|
|
||||||
"fishing",
|
|
||||||
"forage",
|
|
||||||
"global_loot",
|
|
||||||
"goallists",
|
|
||||||
"graveyard",
|
|
||||||
"grid",
|
|
||||||
"grid_entries",
|
|
||||||
"ground_spawns",
|
|
||||||
"horses",
|
|
||||||
"instance_list",
|
|
||||||
"items",
|
|
||||||
"ldon_trap_entries",
|
|
||||||
"ldon_trap_templates",
|
|
||||||
"lootdrop",
|
|
||||||
"lootdrop_entries",
|
|
||||||
"loottable",
|
|
||||||
"loottable_entries",
|
|
||||||
"merchantlist",
|
|
||||||
"npc_emotes",
|
|
||||||
"npc_faction",
|
|
||||||
"npc_faction_entries",
|
|
||||||
"npc_scale_global_base",
|
|
||||||
"npc_spells",
|
|
||||||
"npc_spells_effects",
|
|
||||||
"npc_spells_effects_entries",
|
|
||||||
"npc_spells_entries",
|
|
||||||
"npc_types",
|
|
||||||
"npc_types_metadata",
|
|
||||||
"npc_types_tint",
|
|
||||||
"object",
|
|
||||||
"pets",
|
|
||||||
"pets_equipmentset",
|
|
||||||
"pets_equipmentset_entries",
|
|
||||||
"proximities",
|
|
||||||
"races",
|
|
||||||
"skill_caps",
|
|
||||||
"spawn2",
|
|
||||||
"spawn_condition_values",
|
|
||||||
"spawn_conditions",
|
|
||||||
"spawn_events",
|
|
||||||
"spawnentry",
|
|
||||||
"spawngroup",
|
|
||||||
"spells_new",
|
|
||||||
"start_zones",
|
|
||||||
"starting_items",
|
|
||||||
"task_activities",
|
|
||||||
"tasks",
|
|
||||||
"tasksets",
|
|
||||||
"tradeskill_recipe",
|
|
||||||
"tradeskill_recipe_entries",
|
|
||||||
"traps",
|
|
||||||
"tribute_levels",
|
|
||||||
"tributes",
|
|
||||||
"veteran_reward_templates",
|
|
||||||
"zone",
|
|
||||||
"zone_points",
|
|
||||||
"zone_server",
|
|
||||||
"zoneserver_auth",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets server tables
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetServerTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"chatchannels",
|
|
||||||
"command_settings",
|
|
||||||
"db_str",
|
|
||||||
"eqtime",
|
|
||||||
"launcher",
|
|
||||||
"launcher_zones",
|
|
||||||
"level_exp_mods",
|
|
||||||
"logsys_categories",
|
|
||||||
"name_filter",
|
|
||||||
"perl_event_export_settings",
|
|
||||||
"profanity_list",
|
|
||||||
"rule_sets",
|
|
||||||
"rule_values",
|
|
||||||
"variables",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets QueryServer tables
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetQueryServerTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"qs_merchant_transaction_record",
|
|
||||||
"qs_merchant_transaction_record_entries",
|
|
||||||
"qs_player_aa_rate_hourly",
|
|
||||||
"qs_player_delete_record",
|
|
||||||
"qs_player_delete_record_entries",
|
|
||||||
"qs_player_events",
|
|
||||||
"qs_player_handin_record",
|
|
||||||
"qs_player_handin_record_entries",
|
|
||||||
"qs_player_move_record",
|
|
||||||
"qs_player_move_record_entries",
|
|
||||||
"qs_player_npc_kill_record",
|
|
||||||
"qs_player_npc_kill_record_entries",
|
|
||||||
"qs_player_speech",
|
|
||||||
"qs_player_trade_record",
|
|
||||||
"qs_player_trade_record_entries",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets state tables
|
|
||||||
* Tables that keep track of server state
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetStateTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"adventure_members",
|
|
||||||
"banned_ips",
|
|
||||||
"bug_reports",
|
|
||||||
"bugs",
|
|
||||||
"eventlog",
|
|
||||||
"gm_ips",
|
|
||||||
"group_id",
|
|
||||||
"group_leaders",
|
|
||||||
"hackers",
|
|
||||||
"ip_exemptions",
|
|
||||||
"item_tick",
|
|
||||||
"lfguild",
|
|
||||||
"merchantlist_temp",
|
|
||||||
"object_contents",
|
|
||||||
"raid_details",
|
|
||||||
"raid_leaders",
|
|
||||||
"raid_members",
|
|
||||||
"reports",
|
|
||||||
"respawn_times",
|
|
||||||
"saylink",
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets login tables
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetLoginTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"login_accounts",
|
|
||||||
"login_api_tokens",
|
|
||||||
"login_server_admins",
|
|
||||||
"login_server_list_types",
|
|
||||||
"login_world_servers",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets login tables
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::vector<std::string> GetVersionTables()
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
"db_version",
|
|
||||||
"inventory_versions",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //EQEMU_DATABASE_SCHEMA_H
|
|
||||||
+54
-102
@@ -2,9 +2,8 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "misc_functions.h"
|
#include "../common/misc_functions.h"
|
||||||
#include "eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
#include "timer.h"
|
|
||||||
|
|
||||||
#include "dbcore.h"
|
#include "dbcore.h"
|
||||||
|
|
||||||
@@ -15,25 +14,22 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define strncasecmp _strnicmp
|
#define strncasecmp _strnicmp
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#else
|
#else
|
||||||
|
#include "unix.h"
|
||||||
#include "unix.h"
|
#include <pthread.h>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _EQDEBUG
|
#ifdef _EQDEBUG
|
||||||
#define DEBUG_MYSQL_QUERIES 0
|
#define DEBUG_MYSQL_QUERIES 0
|
||||||
#else
|
#else
|
||||||
#define DEBUG_MYSQL_QUERIES 0
|
#define DEBUG_MYSQL_QUERIES 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore() {
|
||||||
{
|
|
||||||
mysql_init(&mysql);
|
mysql_init(&mysql);
|
||||||
pHost = 0;
|
pHost = 0;
|
||||||
pUser = 0;
|
pUser = 0;
|
||||||
@@ -44,8 +40,7 @@ DBcore::DBcore()
|
|||||||
pStatus = Closed;
|
pStatus = Closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBcore::~DBcore()
|
DBcore::~DBcore() {
|
||||||
{
|
|
||||||
mysql_close(&mysql);
|
mysql_close(&mysql);
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
@@ -54,8 +49,7 @@ DBcore::~DBcore()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping() {
|
||||||
{
|
|
||||||
if (!MDatabase.trylock()) {
|
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;
|
||||||
@@ -69,35 +63,34 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO
|
|||||||
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce)
|
MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce)
|
||||||
{
|
{
|
||||||
BenchTimer timer;
|
|
||||||
timer.reset();
|
|
||||||
|
|
||||||
LockMutex lock(&MDatabase);
|
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);
|
||||||
|
|
||||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
if (errorNumber == CR_SERVER_GONE_ERROR)
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
}
|
|
||||||
|
|
||||||
// error appears to be a disconnect error, may need to try again.
|
// error appears to be a disconnect error, may need to try again.
|
||||||
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) {
|
if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR)
|
||||||
|
{
|
||||||
|
|
||||||
if (retryOnFailureOnce) {
|
if (retryOnFailureOnce)
|
||||||
LogInfo("Database Error: Lost connection, attempting to recover");
|
{
|
||||||
|
std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl;
|
||||||
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
|
MySQLRequestResult requestResult = QueryDatabase(query, querylen, false);
|
||||||
|
|
||||||
if (requestResult.Success()) {
|
if (requestResult.Success())
|
||||||
LogInfo("Reconnection to database successful");
|
{
|
||||||
|
std::cout << "Reconnection to database successful." << std::endl;
|
||||||
return requestResult;
|
return requestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,96 +102,63 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
|
|
||||||
/**
|
/* Implement Logging at the Root */
|
||||||
* Error logging
|
if (mysql_errno(&mysql) > 0 && strlen(query) > 0){
|
||||||
*/
|
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)
|
||||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query);
|
||||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(&mysql), mysql_error(&mysql), query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// successful query. get results.
|
// successful query. get results.
|
||||||
MYSQL_RES *res = mysql_store_result(&mysql);
|
MYSQL_RES* res = mysql_store_result(&mysql);
|
||||||
uint32 rowCount = 0;
|
uint32 rowCount = 0;
|
||||||
|
|
||||||
if (res != nullptr) {
|
if (res != nullptr)
|
||||||
rowCount = (uint32) mysql_num_rows(res);
|
rowCount = (uint32)mysql_num_rows(res);
|
||||||
}
|
|
||||||
|
|
||||||
MySQLRequestResult requestResult(
|
MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql));
|
||||||
res,
|
|
||||||
(uint32) mysql_affected_rows(&mysql),
|
|
||||||
rowCount,
|
|
||||||
(uint32) mysql_field_count(&mysql),
|
|
||||||
(uint32) mysql_insert_id(&mysql)
|
|
||||||
);
|
|
||||||
|
|
||||||
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(
|
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s");
|
||||||
"{0} ({1} row{2} returned) ({3}s)",
|
|
||||||
query,
|
|
||||||
requestResult.RowCount(),
|
|
||||||
requestResult.RowCount() == 1 ? "" : "s",
|
|
||||||
std::to_string(timer.elapsed())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogMySQLQuery(
|
Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s");
|
||||||
"{0} ({1} row{2} affected) ({3}s)",
|
|
||||||
query,
|
|
||||||
requestResult.RowsAffected(),
|
|
||||||
requestResult.RowsAffected() == 1 ? "" : "s",
|
|
||||||
std::to_string(timer.elapsed())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestResult;
|
return requestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::TransactionBegin()
|
void DBcore::TransactionBegin() {
|
||||||
{
|
|
||||||
QueryDatabase("START TRANSACTION");
|
QueryDatabase("START TRANSACTION");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::TransactionCommit()
|
void DBcore::TransactionCommit() {
|
||||||
{
|
|
||||||
QueryDatabase("COMMIT");
|
QueryDatabase("COMMIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::TransactionRollback()
|
void DBcore::TransactionRollback() {
|
||||||
{
|
|
||||||
QueryDatabase("ROLLBACK");
|
QueryDatabase("ROLLBACK");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 DBcore::DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen)
|
uint32 DBcore::DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen) {
|
||||||
{
|
|
||||||
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
||||||
// LockMutex lock(&MDatabase);
|
// LockMutex lock(&MDatabase);
|
||||||
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::Open(
|
bool DBcore::Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase,uint32 iPort, uint32* errnum, char* errbuf, bool iCompress, bool iSSL) {
|
||||||
const char *iHost,
|
|
||||||
const char *iUser,
|
|
||||||
const char *iPassword,
|
|
||||||
const char *iDatabase,
|
|
||||||
uint32 iPort,
|
|
||||||
uint32 *errnum,
|
|
||||||
char *errbuf,
|
|
||||||
bool iCompress,
|
|
||||||
bool iSSL
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LockMutex lock(&MDatabase);
|
LockMutex lock(&MDatabase);
|
||||||
safe_delete(pHost);
|
safe_delete(pHost);
|
||||||
safe_delete(pUser);
|
safe_delete(pUser);
|
||||||
@@ -214,45 +174,37 @@ bool DBcore::Open(
|
|||||||
return Open(errnum, errbuf);
|
return Open(errnum, errbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
bool DBcore::Open(uint32* errnum, char* errbuf) {
|
||||||
{
|
if (errbuf)
|
||||||
if (errbuf) {
|
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
|
||||||
LockMutex lock(&MDatabase);
|
LockMutex lock(&MDatabase);
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected)
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
if (GetStatus() == Error) {
|
if (GetStatus() == Error) {
|
||||||
mysql_close(&mysql);
|
mysql_close(&mysql);
|
||||||
mysql_init(&mysql); // Initialize structure again
|
mysql_init(&mysql); // Initialize structure again
|
||||||
}
|
}
|
||||||
if (!pHost) {
|
if (!pHost)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
Added CLIENT_FOUND_ROWS flag to the connect
|
Added CLIENT_FOUND_ROWS flag to the connect
|
||||||
otherwise DB update calls would say 0 rows affected when the value already equalled
|
otherwise DB update calls would say 0 rows affected when the value already equalled
|
||||||
what the function was tring to set it to, therefore the function would think it failed
|
what the function was tring to set it to, therefore the function would think it failed
|
||||||
*/
|
*/
|
||||||
uint32 flags = CLIENT_FOUND_ROWS;
|
uint32 flags = CLIENT_FOUND_ROWS;
|
||||||
if (pCompress) {
|
if (pCompress)
|
||||||
flags |= CLIENT_COMPRESS;
|
flags |= CLIENT_COMPRESS;
|
||||||
}
|
if (pSSL)
|
||||||
if (pSSL) {
|
|
||||||
flags |= CLIENT_SSL;
|
flags |= CLIENT_SSL;
|
||||||
}
|
|
||||||
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
||||||
pStatus = Connected;
|
pStatus = Connected;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (errnum) {
|
if (errnum)
|
||||||
*errnum = mysql_errno(&mysql);
|
*errnum = mysql_errno(&mysql);
|
||||||
}
|
if (errbuf)
|
||||||
if (errbuf) {
|
|
||||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
}
|
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,10 +77,6 @@ namespace EQEmu
|
|||||||
|
|
||||||
} // namespace invtype
|
} // namespace invtype
|
||||||
|
|
||||||
namespace DevTools {
|
|
||||||
const int32 GM_ACCOUNT_STATUS_LEVEL = 150;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace popupresponse {
|
namespace popupresponse {
|
||||||
const int32 SERVER_INTERNAL_USE_BASE = 2000000000;
|
const int32 SERVER_INTERNAL_USE_BASE = 2000000000;
|
||||||
const int32 MOB_INFO_DISMISS = 2000000001;
|
const int32 MOB_INFO_DISMISS = 2000000001;
|
||||||
@@ -311,21 +307,6 @@ namespace EQEmu
|
|||||||
|
|
||||||
} // namespace bug
|
} // namespace bug
|
||||||
|
|
||||||
enum WaypointStatus : int {
|
|
||||||
RoamBoxPauseInProgress = -3,
|
|
||||||
QuestControlNoGrid = -2,
|
|
||||||
QuestControlGrid = -1
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace consent {
|
|
||||||
enum eConsentType : uint8 {
|
|
||||||
Normal = 0,
|
|
||||||
Group,
|
|
||||||
Raid,
|
|
||||||
Guild
|
|
||||||
};
|
|
||||||
}; // namespace consent
|
|
||||||
|
|
||||||
} /*EQEmu*/
|
} /*EQEmu*/
|
||||||
|
|
||||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||||
|
|||||||
+191
-132
@@ -87,114 +87,199 @@ typedef enum {
|
|||||||
_eaMaxAppearance
|
_eaMaxAppearance
|
||||||
} EmuAppearance;
|
} EmuAppearance;
|
||||||
|
|
||||||
namespace Chat {
|
// msg_type's for custom usercolors
|
||||||
const uint16 White = 0;
|
#define MT_Say 256
|
||||||
const uint16 DimGray = 1;
|
#define MT_Tell 257
|
||||||
const uint16 Default = 1;
|
#define MT_Group 258
|
||||||
const uint16 Green = 2;
|
#define MT_Guild 259
|
||||||
const uint16 BrightBlue = 3;
|
#define MT_OOC 260
|
||||||
const uint16 LightBlue = 4;
|
#define MT_Auction 261
|
||||||
const uint16 Magenta = 5;
|
#define MT_Shout 262
|
||||||
const uint16 Gray = 6;
|
#define MT_Emote 263
|
||||||
const uint16 LightGray = 7;
|
#define MT_Spells 264
|
||||||
const uint16 NPCQuestSay = 10;
|
#define MT_YouHitOther 265
|
||||||
const uint16 DarkGray = 12;
|
#define MT_OtherHitsYou 266
|
||||||
const uint16 Red = 13;
|
#define MT_YouMissOther 267
|
||||||
const uint16 Lime = 14;
|
#define MT_OtherMissesYou 268
|
||||||
const uint16 Yellow = 15;
|
#define MT_Broadcasts 269
|
||||||
const uint16 Blue = 16;
|
#define MT_Skills 270
|
||||||
const uint16 LightNavy = 17;
|
#define MT_Disciplines 271
|
||||||
const uint16 Cyan = 18;
|
#define MT_Unused1 272
|
||||||
const uint16 Black = 20;
|
#define MT_DefaultText 273
|
||||||
|
#define MT_Unused2 274
|
||||||
|
#define MT_MerchantOffer 275
|
||||||
|
#define MT_MerchantBuySell 276
|
||||||
|
#define MT_YourDeath 277
|
||||||
|
#define MT_OtherDeath 278
|
||||||
|
#define MT_OtherHits 279
|
||||||
|
#define MT_OtherMisses 280
|
||||||
|
#define MT_Who 281
|
||||||
|
#define MT_YellForHelp 282
|
||||||
|
#define MT_NonMelee 283
|
||||||
|
#define MT_WornOff 284
|
||||||
|
#define MT_MoneySplit 285
|
||||||
|
#define MT_LootMessages 286
|
||||||
|
#define MT_DiceRoll 287
|
||||||
|
#define MT_OtherSpells 288
|
||||||
|
#define MT_SpellFailure 289
|
||||||
|
#define MT_Chat 290
|
||||||
|
#define MT_Channel1 291
|
||||||
|
#define MT_Channel2 292
|
||||||
|
#define MT_Channel3 293
|
||||||
|
#define MT_Channel4 294
|
||||||
|
#define MT_Channel5 295
|
||||||
|
#define MT_Channel6 296
|
||||||
|
#define MT_Channel7 297
|
||||||
|
#define MT_Channel8 298
|
||||||
|
#define MT_Channel9 299
|
||||||
|
#define MT_Channel10 300
|
||||||
|
#define MT_CritMelee 301
|
||||||
|
#define MT_SpellCrits 302
|
||||||
|
#define MT_TooFarAway 303
|
||||||
|
#define MT_NPCRampage 304
|
||||||
|
#define MT_NPCFlurry 305
|
||||||
|
#define MT_NPCEnrage 306
|
||||||
|
#define MT_SayEcho 307
|
||||||
|
#define MT_TellEcho 308
|
||||||
|
#define MT_GroupEcho 309
|
||||||
|
#define MT_GuildEcho 310
|
||||||
|
#define MT_OOCEcho 311
|
||||||
|
#define MT_AuctionEcho 312
|
||||||
|
#define MT_ShoutECho 313
|
||||||
|
#define MT_EmoteEcho 314
|
||||||
|
#define MT_Chat1Echo 315
|
||||||
|
#define MT_Chat2Echo 316
|
||||||
|
#define MT_Chat3Echo 317
|
||||||
|
#define MT_Chat4Echo 318
|
||||||
|
#define MT_Chat5Echo 319
|
||||||
|
#define MT_Chat6Echo 320
|
||||||
|
#define MT_Chat7Echo 321
|
||||||
|
#define MT_Chat8Echo 322
|
||||||
|
#define MT_Chat9Echo 323
|
||||||
|
#define MT_Chat10Echo 324
|
||||||
|
#define MT_DoTDamage 325
|
||||||
|
#define MT_ItemLink 326
|
||||||
|
#define MT_RaidSay 327
|
||||||
|
#define MT_MyPet 328
|
||||||
|
#define MT_DS 329
|
||||||
|
#define MT_Leadership 330
|
||||||
|
#define MT_PetFlurry 331
|
||||||
|
#define MT_PetCrit 332
|
||||||
|
#define MT_FocusEffect 333
|
||||||
|
#define MT_Experience 334
|
||||||
|
#define MT_System 335
|
||||||
|
#define MT_PetSpell 336
|
||||||
|
#define MT_PetResponse 337
|
||||||
|
#define MT_ItemSpeech 338
|
||||||
|
#define MT_StrikeThrough 339
|
||||||
|
#define MT_Stun 340
|
||||||
|
|
||||||
/**
|
// TODO: Really should combine above and below into one
|
||||||
* User colors
|
|
||||||
|
//from showeq
|
||||||
|
enum ChatColor
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
CC_Default = 0,
|
||||||
|
CC_DarkGrey = 1,
|
||||||
|
CC_DarkGreen = 2,
|
||||||
|
CC_DarkBlue = 3,
|
||||||
|
CC_Purple = 5,
|
||||||
|
CC_LightGrey = 6,
|
||||||
*/
|
*/
|
||||||
const uint16 Say = 256;
|
|
||||||
const uint16 Tell = 257;
|
CC_WhiteSmoke = 0, // FF|F0F0F0
|
||||||
const uint16 Group = 258;
|
CC_Green = 2, // FF|008000
|
||||||
const uint16 Guild = 259;
|
CC_BrightBlue = 3, // FF|0040FF
|
||||||
const uint16 OOC = 260;
|
CC_Magenta = 5, // FF|F000F0
|
||||||
const uint16 Auction = 261;
|
CC_Gray = 6, // FF|808080
|
||||||
const uint16 Shout = 262;
|
CC_LightGray = 7, // FF|E0E0E0
|
||||||
const uint16 Emote = 263;
|
//CC_WhiteSmoke2 = 10, // FF|F0F0F0
|
||||||
const uint16 Spells = 264;
|
CC_DarkGray = 12, // FF|A0A0A0
|
||||||
const uint16 YouHitOther = 265;
|
CC_Red = 13, // FF|F00000
|
||||||
const uint16 OtherHitYou = 266;
|
CC_Lime = 14, // FF|00F000
|
||||||
const uint16 YouMissOther = 267;
|
CC_Yellow = 15, // FF|F0F000
|
||||||
const uint16 OtherMissYou = 268;
|
CC_Blue = 16, // FF|0000F0
|
||||||
const uint16 Broadcasts = 269;
|
CC_LightNavy = 17, // FF|0000AF
|
||||||
const uint16 Skills = 270;
|
CC_Cyan = 18, // FF|00F0F0
|
||||||
const uint16 Disciplines = 271;
|
CC_Black = 20, // FF|000000
|
||||||
const uint16 Unused1 = 272;
|
|
||||||
const uint16 DefaultText = 273;
|
// any index <= 255 that is not defined above
|
||||||
const uint16 Unused2 = 274;
|
CC_DimGray = 1, // FF|606060
|
||||||
const uint16 MerchantOffer = 275;
|
CC_Default = 1,
|
||||||
const uint16 MerchantExchange = 276;
|
|
||||||
const uint16 YourDeath = 277;
|
CC_User_Say = 256,
|
||||||
const uint16 OtherDeath = 278;
|
CC_User_Tell = 257,
|
||||||
const uint16 OtherHitOther = 279;
|
CC_User_Group = 258,
|
||||||
const uint16 OtherMissOther = 280;
|
CC_User_Guild = 259,
|
||||||
const uint16 Who = 281;
|
CC_User_OOC = 260,
|
||||||
const uint16 YellForHelp = 282;
|
CC_User_Auction = 261,
|
||||||
const uint16 NonMelee = 283;
|
CC_User_Shout = 262,
|
||||||
const uint16 SpellWornOff = 284;
|
CC_User_Emote = 263,
|
||||||
const uint16 MoneySplit = 285;
|
CC_User_Spells = 264,
|
||||||
const uint16 Loot = 286;
|
CC_User_YouHitOther = 265,
|
||||||
const uint16 DiceRoll = 287;
|
CC_User_OtherHitYou = 266,
|
||||||
const uint16 OtherSpells = 288;
|
CC_User_YouMissOther = 267,
|
||||||
const uint16 SpellFailure = 289;
|
CC_User_OtherMissYou = 268,
|
||||||
const uint16 ChatChannel = 290;
|
CC_User_Duels = 269,
|
||||||
const uint16 Chat1 = 291;
|
CC_User_Skills = 270,
|
||||||
const uint16 Chat2 = 292;
|
CC_User_Disciplines = 271,
|
||||||
const uint16 Chat3 = 293;
|
CC_User_Default = 273,
|
||||||
const uint16 Chat4 = 294;
|
CC_User_MerchantOffer = 275,
|
||||||
const uint16 Chat5 = 295;
|
CC_User_MerchantExchange = 276,
|
||||||
const uint16 Chat6 = 296;
|
CC_User_YourDeath = 277,
|
||||||
const uint16 Chat7 = 297;
|
CC_User_OtherDeath = 278,
|
||||||
const uint16 Chat8 = 298;
|
CC_User_OtherHitOther = 279,
|
||||||
const uint16 Chat9 = 299;
|
CC_User_OtherMissOther = 280,
|
||||||
const uint16 Chat10 = 300;
|
CC_User_Who = 281,
|
||||||
const uint16 MeleeCrit = 301;
|
CC_User_Yell = 282,
|
||||||
const uint16 SpellCrit = 302;
|
CC_User_NonMelee = 283,
|
||||||
const uint16 TooFarAway = 303;
|
CC_User_SpellWornOff = 284,
|
||||||
const uint16 NPCRampage = 304;
|
CC_User_MoneySplit = 285,
|
||||||
const uint16 NPCFlurry = 305;
|
CC_User_Loot = 286,
|
||||||
const uint16 NPCEnrage = 306;
|
CC_User_Random = 287,
|
||||||
const uint16 EchoSay = 307;
|
CC_User_OtherSpells = 288,
|
||||||
const uint16 EchoTell = 308;
|
CC_User_SpellFailure = 289,
|
||||||
const uint16 EchoGroup = 309;
|
CC_User_ChatChannel = 290,
|
||||||
const uint16 EchoGuild = 310;
|
CC_User_Chat1 = 291,
|
||||||
const uint16 EchoOOC = 311;
|
CC_User_Chat2 = 292,
|
||||||
const uint16 EchoAuction = 312;
|
CC_User_Chat3 = 293,
|
||||||
const uint16 EchoShout = 313;
|
CC_User_Chat4 = 294,
|
||||||
const uint16 EchoEmote = 314;
|
CC_User_Chat5 = 295,
|
||||||
const uint16 EchoChat1 = 315;
|
CC_User_Chat6 = 296,
|
||||||
const uint16 EchoChat2 = 316;
|
CC_User_Chat7 = 297,
|
||||||
const uint16 EchoChat3 = 317;
|
CC_User_Chat8 = 298,
|
||||||
const uint16 EchoChat4 = 318;
|
CC_User_Chat9 = 299,
|
||||||
const uint16 EchoChat5 = 319;
|
CC_User_Chat10 = 300,
|
||||||
const uint16 EchoChat6 = 320;
|
CC_User_MeleeCrit = 301,
|
||||||
const uint16 EchoChat7 = 321;
|
CC_User_SpellCrit = 302,
|
||||||
const uint16 EchoChat8 = 322;
|
CC_User_TooFarAway = 303,
|
||||||
const uint16 EchoChat9 = 323;
|
CC_User_NPCRampage = 304,
|
||||||
const uint16 EchoChat10 = 324;
|
CC_User_NPCFurry = 305,
|
||||||
const uint16 DotDamage = 325;
|
CC_User_NPCEnrage = 306,
|
||||||
const uint16 ItemLink = 326;
|
CC_User_EchoSay = 307,
|
||||||
const uint16 RaidSay = 327;
|
CC_User_EchoTell = 308,
|
||||||
const uint16 MyPet = 328;
|
CC_User_EchoGroup = 309,
|
||||||
const uint16 DamageShield = 329;
|
CC_User_EchoGuild = 310,
|
||||||
const uint16 LeaderShip = 330;
|
CC_User_EchoOOC = 311,
|
||||||
const uint16 PetFlurry = 331;
|
CC_User_EchoAuction = 312,
|
||||||
const uint16 PetCritical = 332;
|
CC_User_EchoShout = 313,
|
||||||
const uint16 FocusEffect = 333;
|
CC_User_EchoEmote = 314,
|
||||||
const uint16 Experience = 334;
|
CC_User_EchoChat1 = 315,
|
||||||
const uint16 System = 335;
|
CC_User_EchoChat2 = 316,
|
||||||
const uint16 PetSpell = 336;
|
CC_User_EchoChat3 = 317,
|
||||||
const uint16 PetResponse = 337;
|
CC_User_EchoChat4 = 318,
|
||||||
const uint16 ItemSpeech = 338;
|
CC_User_EchoChat5 = 319,
|
||||||
const uint16 StrikeThrough = 339;
|
CC_User_EchoChat6 = 320,
|
||||||
const uint16 Stun = 340;
|
CC_User_EchoChat7 = 321,
|
||||||
|
CC_User_EchoChat8 = 322,
|
||||||
|
CC_User_EchoChat9 = 323,
|
||||||
|
CC_User_EchoChat10 = 324,
|
||||||
|
CC_User_UnusedAtThisTime = 325,
|
||||||
|
CC_User_ItemTags = 326,
|
||||||
|
CC_User_RaidSay = 327,
|
||||||
|
CC_User_MyPet = 328,
|
||||||
|
CC_User_DamageShield = 329,
|
||||||
};
|
};
|
||||||
|
|
||||||
//ZoneChange_Struct->success values
|
//ZoneChange_Struct->success values
|
||||||
@@ -438,30 +523,4 @@ static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // chang
|
|||||||
|
|
||||||
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
|
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
|
||||||
|
|
||||||
enum ChatChannelNames : uint16
|
|
||||||
{
|
|
||||||
ChatChannel_Guild = 0,
|
|
||||||
ChatChannel_Group = 2,
|
|
||||||
ChatChannel_Shout = 3,
|
|
||||||
ChatChannel_Auction = 4,
|
|
||||||
ChatChannel_OOC = 5,
|
|
||||||
ChatChannel_Broadcast = 6,
|
|
||||||
ChatChannel_Tell = 7,
|
|
||||||
ChatChannel_Say = 8,
|
|
||||||
ChatChannel_Petition = 10,
|
|
||||||
ChatChannel_GMSAY = 11,
|
|
||||||
ChatChannel_TellEcho = 14,
|
|
||||||
ChatChannel_Raid = 15,
|
|
||||||
|
|
||||||
ChatChannel_UNKNOWN_Guild = 17,
|
|
||||||
ChatChannel_UNKNOWN_GMSAY = 18,
|
|
||||||
ChatChannel_UCSRelay = 20,
|
|
||||||
ChatChannel_Emotes = 22
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace ZoneBlockedSpellTypes {
|
|
||||||
const uint8 ZoneWide = 1;
|
|
||||||
const uint8 Region = 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
+37
-57
@@ -35,8 +35,6 @@ static const uint32 MAX_MERC = 100;
|
|||||||
static const uint32 MAX_MERC_GRADES = 10;
|
static const uint32 MAX_MERC_GRADES = 10;
|
||||||
static const uint32 MAX_MERC_STANCES = 10;
|
static const uint32 MAX_MERC_STANCES = 10;
|
||||||
static const uint32 BLOCKED_BUFF_COUNT = 20;
|
static const uint32 BLOCKED_BUFF_COUNT = 20;
|
||||||
static const uint32 QUESTREWARD_COUNT = 8;
|
|
||||||
static const uint32 ADVANCED_LORE_LENGTH = 8192;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1190,20 +1188,6 @@ struct SpecialMesg_Struct
|
|||||||
/*24*/ char message[1]; // What is being said?
|
/*24*/ char message[1]; // What is being said?
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpecialMesgHeader_Struct
|
|
||||||
{
|
|
||||||
/*00*/ char SpeakMode; // 2 shouts, 4 %1 %2, 3 %2, 5 tells group, 0 copy, default says
|
|
||||||
/*01*/ char JournalMode; // 1 and 2 go to journal
|
|
||||||
/*02*/ char language;
|
|
||||||
/*03*/ uint32 msg_type; // Color of text (see MT_*** below)
|
|
||||||
/*07*/ uint32 target_spawn_id; // Who is it being said to?
|
|
||||||
/*11*/ // speaker's name
|
|
||||||
/*xx*/ // unknown, location, client doesn't care
|
|
||||||
/*xx*/ // unknown
|
|
||||||
/*xx*/ // unknown
|
|
||||||
/*xx*/ // message
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** When somebody changes what they're wearing or give a pet a weapon (model changes)
|
** When somebody changes what they're wearing or give a pet a weapon (model changes)
|
||||||
** Length: 19 Bytes
|
** Length: 19 Bytes
|
||||||
@@ -1361,23 +1345,20 @@ struct BecomeCorpse_Struct {
|
|||||||
struct PlayerPositionUpdateServer_Struct
|
struct PlayerPositionUpdateServer_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 spawn_id;
|
/*0000*/ uint16 spawn_id;
|
||||||
/*0002*/ uint16 vehicle_id;
|
/*0002*/ int32 delta_heading:10, // change in heading
|
||||||
/*0004*/ signed padding0004 : 12;
|
x_pos:19, // x coord
|
||||||
signed y_pos : 19; // y coord
|
padding0002:3; // ***Placeholder
|
||||||
unsigned padding : 1;
|
/*0006*/ int32 y_pos:19, // y coord
|
||||||
/*0008*/ signed delta_z : 13; // change in z
|
animation:10, // animation
|
||||||
signed delta_x : 13; // change in x
|
padding0006:3; // ***Placeholder
|
||||||
signed padding0008 : 6;
|
/*0010*/ int32 z_pos:19, // z coord
|
||||||
/*0012*/ signed x_pos : 19; // x coord
|
delta_y:13; // change in y
|
||||||
unsigned heading : 12; // heading
|
/*0014*/ int32 delta_x:13, // change in x
|
||||||
signed padding0016 : 1;
|
heading:12, // heading
|
||||||
/*0016*/ signed delta_heading : 10; // change in heading
|
padding0014:7; // ***Placeholder
|
||||||
signed z_pos : 19; // z coord
|
/*0018*/ int32 delta_z:13, // change in z
|
||||||
signed padding0020 : 3;
|
padding0018:19; // ***Placeholder
|
||||||
/*0020*/ signed animation : 10; // animation
|
/*0022*/
|
||||||
signed delta_y : 13; // change in y
|
|
||||||
signed padding0024 : 9;
|
|
||||||
/*0024*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1388,23 +1369,21 @@ struct PlayerPositionUpdateServer_Struct
|
|||||||
*/
|
*/
|
||||||
struct PlayerPositionUpdateClient_Struct
|
struct PlayerPositionUpdateClient_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
/*0000*/ uint16 spawn_id;
|
||||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
/*0002*/ uint16 sequence; //increments one each packet
|
||||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
/*0004*/ float y_pos; // y coord
|
||||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
/*0008*/ float delta_z; // Change in z
|
||||||
/*0010*/ float delta_x; // Change in x
|
/*0012*/ float delta_x; // Change in x
|
||||||
/*0014*/ unsigned heading : 12; // Directional heading
|
/*0016*/ float delta_y; // Change in y
|
||||||
unsigned padding0040 : 20; // ***Placeholder
|
/*0020*/ int32 animation:10, // animation
|
||||||
/*0018*/ float x_pos; // x coord (2nd loc value)
|
delta_heading:10, // change in heading
|
||||||
/*0022*/ float delta_z; // Change in z
|
padding0020:12; // ***Placeholder (mostly 1)
|
||||||
/*0026*/ float z_pos; // z coord (3rd loc value)
|
/*0024*/ float x_pos; // x coord
|
||||||
/*0030*/ float y_pos; // y coord (1st loc value)
|
/*0028*/ float z_pos; // z coord
|
||||||
/*0034*/ unsigned animation : 10; // ***Placeholder
|
/*0032*/ uint16 heading:12, // Directional heading
|
||||||
unsigned padding0024 : 22; // animation
|
padding0004:4; // ***Placeholder
|
||||||
/*0038*/ float delta_y; // Change in y
|
/*0034*/ uint8 unknown0006[2]; // ***Placeholder
|
||||||
/*0042*/ signed delta_heading : 10; // change in heading
|
/*0036*/
|
||||||
unsigned padding0041 : 22; // ***Placeholder
|
|
||||||
/*0046*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SpawnPositionUpdate_Struct
|
struct SpawnPositionUpdate_Struct
|
||||||
@@ -2182,7 +2161,14 @@ struct QuestReward_Struct
|
|||||||
/*024*/ uint32 silver; // Gives silver to the client
|
/*024*/ uint32 silver; // Gives silver to the client
|
||||||
/*028*/ uint32 gold; // Gives gold to the client
|
/*028*/ uint32 gold; // Gives gold to the client
|
||||||
/*032*/ uint32 platinum; // Gives platinum to the client
|
/*032*/ uint32 platinum; // Gives platinum to the client
|
||||||
/*036*/ int32 item_id[QUESTREWARD_COUNT]; // -1 for nothing
|
/*036*/ uint32 item_id;
|
||||||
|
/*040*/ uint32 unknown040;
|
||||||
|
/*044*/ uint32 unknown044;
|
||||||
|
/*048*/ uint32 unknown048;
|
||||||
|
/*052*/ uint32 unknown052;
|
||||||
|
/*056*/ uint32 unknown056;
|
||||||
|
/*060*/ uint32 unknown060;
|
||||||
|
/*064*/ uint32 unknown064;
|
||||||
/*068*/
|
/*068*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2967,12 +2953,6 @@ struct ItemViewRequest_Struct {
|
|||||||
/*046*/ char unknown046[2];
|
/*046*/ char unknown046[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ItemAdvancedLoreText_Struct {
|
|
||||||
int32 item_id;
|
|
||||||
char item_name[64];
|
|
||||||
char advanced_lore[ADVANCED_LORE_LENGTH];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LDONItemViewRequest_Struct {
|
struct LDONItemViewRequest_Struct {
|
||||||
uint32 item_id;
|
uint32 item_id;
|
||||||
uint8 unknown004[4];
|
uint8 unknown004[4];
|
||||||
|
|||||||
+104
-104
@@ -84,14 +84,14 @@ void EQStream::init(bool resetSession) {
|
|||||||
|
|
||||||
OpMgr = nullptr;
|
OpMgr = nullptr;
|
||||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||||
LogNetcode(_L "init Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
||||||
{
|
{
|
||||||
EQRawApplicationPacket *ap=nullptr;
|
EQRawApplicationPacket *ap=nullptr;
|
||||||
LogNetcode(_L "Creating new application packet, length [{}]" __L, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size);
|
||||||
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
|
// _raw(NET__APP_CREATE_HEX, 0xFFFF, p);
|
||||||
ap = p->MakeAppPacket();
|
ap = p->MakeAppPacket();
|
||||||
return ap;
|
return ap;
|
||||||
@@ -100,7 +100,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p)
|
|||||||
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
|
EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len)
|
||||||
{
|
{
|
||||||
EQRawApplicationPacket *ap=nullptr;
|
EQRawApplicationPacket *ap=nullptr;
|
||||||
LogNetcode(_L "Creating new application packet, length [{}]" __L, len);
|
Log(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len);
|
||||||
ap = new EQRawApplicationPacket(buf, len);
|
ap = new EQRawApplicationPacket(buf, len);
|
||||||
return ap;
|
return ap;
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) {
|
if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) {
|
||||||
LogNetcode(_L "Session not initialized, packet ignored" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L);
|
||||||
// _raw(NET__DEBUG, 0xFFFF, p);
|
// _raw(NET__DEBUG, 0xFFFF, p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
while(processed < p->size) {
|
while(processed < p->size) {
|
||||||
subpacket_length=*(p->pBuffer+processed);
|
subpacket_length=*(p->pBuffer+processed);
|
||||||
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length);
|
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length);
|
||||||
LogNetcode(_L "Extracting combined packet of length [{}]" __L, subpacket_length);
|
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length);
|
||||||
// _raw(NET__NET_CREATE_HEX, 0xFFFF, subp);
|
// _raw(NET__NET_CREATE_HEX, 0xFFFF, subp);
|
||||||
subp->copyInfo(p);
|
subp->copyInfo(p);
|
||||||
ProcessPacket(subp);
|
ProcessPacket(subp);
|
||||||
@@ -156,12 +156,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
while(processed<p->size) {
|
while(processed<p->size) {
|
||||||
EQRawApplicationPacket *ap=nullptr;
|
EQRawApplicationPacket *ap=nullptr;
|
||||||
if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) {
|
if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) {
|
||||||
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
|
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
|
||||||
ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length);
|
ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length);
|
||||||
processed+=subpacket_length+1;
|
processed+=subpacket_length+1;
|
||||||
} else {
|
} else {
|
||||||
subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1));
|
subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1));
|
||||||
LogNetcode(_L "Extracting combined app packet of length [{}], short len" __L, subpacket_length);
|
Log(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length);
|
||||||
ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length);
|
ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length);
|
||||||
processed+=subpacket_length+3;
|
processed+=subpacket_length+3;
|
||||||
}
|
}
|
||||||
@@ -176,29 +176,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
case OP_Packet: {
|
case OP_Packet: {
|
||||||
if(!p->pBuffer || (p->Size() < 4))
|
if(!p->pBuffer || (p->Size() < 4))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_Packet that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||||
SeqOrder check=CompareSequence(NextInSeq,seq);
|
SeqOrder check=CompareSequence(NextInSeq,seq);
|
||||||
if (check == SeqFuture) {
|
if (check == SeqFuture) {
|
||||||
LogNetcode(_L "Future OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||||
// _raw(NET__DEBUG, seq, p);
|
// _raw(NET__DEBUG, seq, p);
|
||||||
|
|
||||||
PacketQueue[seq]=p->Copy();
|
PacketQueue[seq]=p->Copy();
|
||||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||||
|
|
||||||
//SendOutOfOrderAck(seq);
|
//SendOutOfOrderAck(seq);
|
||||||
|
|
||||||
} else if (check == SeqPast) {
|
} else if (check == SeqPast) {
|
||||||
LogNetcode(_L "Duplicate OP_Packet: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||||
// _raw(NET__DEBUG, seq, p);
|
// _raw(NET__DEBUG, seq, p);
|
||||||
SendOutOfOrderAck(seq); //we already got this packet but it was out of order
|
SendOutOfOrderAck(seq); //we already got this packet but it was out of order
|
||||||
} else {
|
} else {
|
||||||
// In case we did queue one before as well.
|
// In case we did queue one before as well.
|
||||||
EQProtocolPacket *qp=RemoveQueue(seq);
|
EQProtocolPacket *qp=RemoveQueue(seq);
|
||||||
if (qp) {
|
if (qp) {
|
||||||
LogNetcode("[NET_TRACE] OP_Packet: Removing older queued packet with sequence [{}]", seq);
|
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq);
|
||||||
delete qp;
|
delete qp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
// Check for an embedded OP_AppCombinded (protocol level 0x19)
|
// Check for an embedded OP_AppCombinded (protocol level 0x19)
|
||||||
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
||||||
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2);
|
EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2);
|
||||||
LogNetcode(_L "seq [{}], Extracting combined packet of length [{}]" __L, seq, subp->size);
|
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size);
|
||||||
// _raw(NET__NET_CREATE_HEX, seq, subp);
|
// _raw(NET__NET_CREATE_HEX, seq, subp);
|
||||||
subp->copyInfo(p);
|
subp->copyInfo(p);
|
||||||
ProcessPacket(subp);
|
ProcessPacket(subp);
|
||||||
@@ -226,29 +226,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
case OP_Fragment: {
|
case OP_Fragment: {
|
||||||
if(!p->pBuffer || (p->Size() < 4))
|
if(!p->pBuffer || (p->Size() < 4))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_Fragment that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||||
SeqOrder check=CompareSequence(NextInSeq,seq);
|
SeqOrder check=CompareSequence(NextInSeq,seq);
|
||||||
if (check == SeqFuture) {
|
if (check == SeqFuture) {
|
||||||
LogNetcode(_L "Future OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||||
// _raw(NET__DEBUG, seq, p);
|
// _raw(NET__DEBUG, seq, p);
|
||||||
|
|
||||||
PacketQueue[seq]=p->Copy();
|
PacketQueue[seq]=p->Copy();
|
||||||
LogNetcode(_L "OP_Fragment Queue size=[{}]" __L, PacketQueue.size());
|
Log(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size());
|
||||||
|
|
||||||
//SendOutOfOrderAck(seq);
|
//SendOutOfOrderAck(seq);
|
||||||
|
|
||||||
} else if (check == SeqPast) {
|
} else if (check == SeqPast) {
|
||||||
LogNetcode(_L "Duplicate OP_Fragment: Expecting Seq=[{}], but got Seq=[{}]" __L, NextInSeq, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq);
|
||||||
// _raw(NET__DEBUG, seq, p);
|
// _raw(NET__DEBUG, seq, p);
|
||||||
SendOutOfOrderAck(seq);
|
SendOutOfOrderAck(seq);
|
||||||
} else {
|
} else {
|
||||||
// In case we did queue one before as well.
|
// In case we did queue one before as well.
|
||||||
EQProtocolPacket *qp=RemoveQueue(seq);
|
EQProtocolPacket *qp=RemoveQueue(seq);
|
||||||
if (qp) {
|
if (qp) {
|
||||||
LogNetcode("[NET_TRACE] OP_Fragment: Removing older queued packet with sequence [{}]", seq);
|
Log(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq);
|
||||||
delete qp;
|
delete qp;
|
||||||
}
|
}
|
||||||
SetNextAckToSend(seq);
|
SetNextAckToSend(seq);
|
||||||
@@ -256,18 +256,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
if (oversize_buffer) {
|
if (oversize_buffer) {
|
||||||
memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2);
|
memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2);
|
||||||
oversize_offset+=p->size-2;
|
oversize_offset+=p->size-2;
|
||||||
LogNetcode(_L "Fragment of oversized of length [{}], seq [{}]: now at [{}]/[{}]" __L, p->size-2, seq, oversize_offset, oversize_length);
|
Log(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length);
|
||||||
if (oversize_offset==oversize_length) {
|
if (oversize_offset==oversize_length) {
|
||||||
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) {
|
||||||
EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset);
|
EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset);
|
||||||
LogNetcode(_L "seq [{}], Extracting combined oversize packet of length [{}]" __L, seq, subp->size);
|
Log(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size);
|
||||||
//// _raw(NET__NET_CREATE_HEX, subp);
|
//// _raw(NET__NET_CREATE_HEX, subp);
|
||||||
subp->copyInfo(p);
|
subp->copyInfo(p);
|
||||||
ProcessPacket(subp);
|
ProcessPacket(subp);
|
||||||
delete subp;
|
delete subp;
|
||||||
} else {
|
} else {
|
||||||
EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset);
|
EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset);
|
||||||
LogNetcode(_L "seq [{}], completed combined oversize packet of length [{}]" __L, seq, ap->size);
|
Log(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size);
|
||||||
if (ap) {
|
if (ap) {
|
||||||
ap->copyInfo(p);
|
ap->copyInfo(p);
|
||||||
InboundQueuePush(ap);
|
InboundQueuePush(ap);
|
||||||
@@ -282,20 +282,20 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
oversize_buffer=new unsigned char[oversize_length];
|
oversize_buffer=new unsigned char[oversize_length];
|
||||||
memcpy(oversize_buffer,p->pBuffer+6,p->size-6);
|
memcpy(oversize_buffer,p->pBuffer+6,p->size-6);
|
||||||
oversize_offset=p->size-6;
|
oversize_offset=p->size-6;
|
||||||
LogNetcode(_L "First fragment of oversized of seq [{}]: now at [{}]/[{}]" __L, seq, oversize_offset, oversize_length);
|
Log(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_KeepAlive: {
|
case OP_KeepAlive: {
|
||||||
NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size));
|
NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size));
|
||||||
LogNetcode(_L "Received and queued reply to keep alive" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_Ack: {
|
case OP_Ack: {
|
||||||
if(!p->pBuffer || (p->Size() < 4))
|
if(!p->pBuffer || (p->Size() < 4))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_Ack that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||||
@@ -309,11 +309,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
case OP_SessionRequest: {
|
case OP_SessionRequest: {
|
||||||
if(p->Size() < sizeof(SessionRequest))
|
if(p->Size() < sizeof(SessionRequest))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_SessionRequest that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (GetState()==ESTABLISHED) {
|
if (GetState()==ESTABLISHED) {
|
||||||
LogNetcode(_L "Received OP_SessionRequest in ESTABLISHED state ([{}]) streamactive ([{}]) attempt ([{}])" __L, GetState(),streamactive,sessionAttempts);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts);
|
||||||
|
|
||||||
// client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case
|
// client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case
|
||||||
// streamactive means we identified the opcode for the stream, we cannot re-establish this connection
|
// streamactive means we identified the opcode for the stream, we cannot re-establish this connection
|
||||||
@@ -331,7 +331,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
SessionRequest *Request=(SessionRequest *)p->pBuffer;
|
SessionRequest *Request=(SessionRequest *)p->pBuffer;
|
||||||
Session=ntohl(Request->Session);
|
Session=ntohl(Request->Session);
|
||||||
SetMaxLen(ntohl(Request->MaxLength));
|
SetMaxLen(ntohl(Request->MaxLength));
|
||||||
LogNetcode(_L "Received OP_SessionRequest: session [{}], maxlen [{}]" __L, (unsigned long)Session, MaxLen);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen);
|
||||||
SetState(ESTABLISHED);
|
SetState(ESTABLISHED);
|
||||||
Key=0x11223344;
|
Key=0x11223344;
|
||||||
SendSessionResponse();
|
SendSessionResponse();
|
||||||
@@ -340,7 +340,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
case OP_SessionResponse: {
|
case OP_SessionResponse: {
|
||||||
if(p->Size() < sizeof(SessionResponse))
|
if(p->Size() < sizeof(SessionResponse))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_SessionResponse that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +356,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
compressed=(Response->Format&FLAG_COMPRESSED);
|
compressed=(Response->Format&FLAG_COMPRESSED);
|
||||||
encoded=(Response->Format&FLAG_ENCODED);
|
encoded=(Response->Format&FLAG_ENCODED);
|
||||||
|
|
||||||
LogNetcode(_L "Received OP_SessionResponse: session [{}], maxlen [{}], key [{}], compressed? [{}], encoded? [{}]" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no");
|
||||||
|
|
||||||
// Kinda kludgy, but trie for now
|
// Kinda kludgy, but trie for now
|
||||||
if (StreamType==UnknownStream) {
|
if (StreamType==UnknownStream) {
|
||||||
@@ -379,17 +379,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
EQStreamState state = GetState();
|
EQStreamState state = GetState();
|
||||||
if(state == ESTABLISHED) {
|
if(state == ESTABLISHED) {
|
||||||
//client initiated disconnect?
|
//client initiated disconnect?
|
||||||
LogNetcode(_L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L);
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
SetState(CLOSED);
|
SetState(CLOSED);
|
||||||
} else if(state == CLOSING) {
|
} else if(state == CLOSING) {
|
||||||
//we were waiting for this anyways, ignore pending messages, send the reply and be closed.
|
//we were waiting for this anyways, ignore pending messages, send the reply and be closed.
|
||||||
LogNetcode(_L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L);
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
SetState(CLOSED);
|
SetState(CLOSED);
|
||||||
} else {
|
} else {
|
||||||
//we are expecting this (or have already gotten it, but dont care either way)
|
//we are expecting this (or have already gotten it, but dont care either way)
|
||||||
LogNetcode(_L "Received expected OP_SessionDisconnect. Moving to closed state" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L);
|
||||||
SetState(CLOSED);
|
SetState(CLOSED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,14 +397,14 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
case OP_OutOfOrderAck: {
|
case OP_OutOfOrderAck: {
|
||||||
if(!p->pBuffer || (p->Size() < 4))
|
if(!p->pBuffer || (p->Size() < 4))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_OutOfOrderAck that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
|
||||||
MOutboundQueue.lock();
|
MOutboundQueue.lock();
|
||||||
|
|
||||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||||
LogNetcode(_L "Pre-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
|
//if the packet they got out of order is between our last acked packet and the last sent packet, then its valid.
|
||||||
@@ -414,7 +414,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
|
|
||||||
uint16 sqsize = SequencedQueue.size();
|
uint16 sqsize = SequencedQueue.size();
|
||||||
uint16 index = seq - SequencedBase;
|
uint16 index = seq - SequencedBase;
|
||||||
LogNetcode(_L "OP_OutOfOrderAck marking packet acked in queue (queue index = [{}], queue size = [{}])" __L, index, sqsize);
|
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize);
|
||||||
if (index < sqsize) {
|
if (index < sqsize) {
|
||||||
SequencedQueue[index]->acked = true;
|
SequencedQueue[index]->acked = true;
|
||||||
// flag packets for a resend
|
// flag packets for a resend
|
||||||
@@ -423,7 +423,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) {
|
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) {
|
||||||
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) {
|
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && (((*sitr)->sent_time + timeout) < Timer::GetCurrentTime())) {
|
||||||
(*sitr)->sent_time = 0;
|
(*sitr)->sent_time = 0;
|
||||||
LogNetcode(_L "OP_OutOfOrderAck Flagging packet [{}] for retransmission" __L, SequencedBase + count);
|
Log(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck Flagging packet %d for retransmission" __L, SequencedBase + count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,11 +432,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
retransmittimer = Timer::GetCurrentTime();
|
retransmittimer = Timer::GetCurrentTime();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LogNetcode(_L "Received OP_OutOfOrderAck for out-of-window [{}]. Window ([{}]->[{}])" __L, seq, SequencedBase, NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||||
LogNetcode(_L "Post-OOA Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
MOutboundQueue.unlock();
|
MOutboundQueue.unlock();
|
||||||
@@ -445,7 +445,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
case OP_SessionStatRequest: {
|
case OP_SessionStatRequest: {
|
||||||
if(p->Size() < sizeof(ClientSessionStats))
|
if(p->Size() < sizeof(ClientSessionStats))
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Received OP_SessionStatRequest that was of malformed size" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
|
ClientSessionStats *ClientStats=(ClientSessionStats *)p->pBuffer;
|
||||||
@@ -468,7 +468,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
retransmittimeout += 300;
|
retransmittimeout += 300;
|
||||||
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
|
if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX)
|
||||||
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
|
retransmittimeout = RETRANSMIT_TIMEOUT_MAX;
|
||||||
LogNetcode(_L "Retransmit timeout recalculated to [{}]ms" __L, retransmittimeout);
|
Log(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,11 +485,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_SessionStatResponse: {
|
case OP_SessionStatResponse: {
|
||||||
LogNetcode(_L "Received OP_SessionStatResponse. Ignoring" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_OutOfSession: {
|
case OP_OutOfSession: {
|
||||||
LogNetcode(_L "Received OP_OutOfSession. Ignoring" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -520,7 +520,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(OpMgr == nullptr || *OpMgr == nullptr) {
|
if(OpMgr == nullptr || *OpMgr == nullptr) {
|
||||||
LogNetcode(_L "Packet enqueued into a stream with no opcode manager, dropping" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L);
|
||||||
delete pack;
|
delete pack;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -559,18 +559,18 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
|||||||
|
|
||||||
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
|
// Convert the EQApplicationPacket to 1 or more EQProtocolPackets
|
||||||
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
|
if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2)
|
||||||
LogNetcode(_L "Making oversized packet, len [{}]" __L, p->Size());
|
Log(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->Size());
|
||||||
|
|
||||||
auto tmpbuff = new unsigned char[p->size + 3];
|
auto tmpbuff = new unsigned char[p->size + 3];
|
||||||
length=p->serialize(opcode, tmpbuff);
|
length=p->serialize(opcode, tmpbuff);
|
||||||
if (length != p->Size())
|
if (length != p->Size())
|
||||||
LogNetcode(_L "Packet adjustment, len [{}] to [{}]" __L, p->Size(), length);
|
Log(Logs::Detail, Logs::Netcode, _L "Packet adjustment, len %d to %d" __L, p->Size(), length);
|
||||||
|
|
||||||
auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4);
|
auto out = new EQProtocolPacket(OP_Fragment, nullptr, MaxLen - 4);
|
||||||
*(uint32 *)(out->pBuffer+2)=htonl(length);
|
*(uint32 *)(out->pBuffer+2)=htonl(length);
|
||||||
used=MaxLen-10;
|
used=MaxLen-10;
|
||||||
memcpy(out->pBuffer+6,tmpbuff,used);
|
memcpy(out->pBuffer+6,tmpbuff,used);
|
||||||
LogNetcode(_L "First fragment: used [{}]/[{}]. Payload size [{}] in the packet" __L, used, length, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Payload size %d in the packet" __L, used, length, p->size);
|
||||||
SequencedPush(out);
|
SequencedPush(out);
|
||||||
|
|
||||||
|
|
||||||
@@ -581,7 +581,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p)
|
|||||||
out->size=chunksize+2;
|
out->size=chunksize+2;
|
||||||
SequencedPush(out);
|
SequencedPush(out);
|
||||||
used+=chunksize;
|
used+=chunksize;
|
||||||
LogNetcode(_L "Subsequent fragment: len [{}], used [{}]/[{}]" __L, chunksize, used, length);
|
Log(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, length);
|
||||||
}
|
}
|
||||||
delete p;
|
delete p;
|
||||||
delete[] tmpbuff;
|
delete[] tmpbuff;
|
||||||
@@ -623,7 +623,7 @@ void EQStream::SequencedPush(EQProtocolPacket *p)
|
|||||||
void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
||||||
{
|
{
|
||||||
MOutboundQueue.lock();
|
MOutboundQueue.lock();
|
||||||
LogNetcode(_L "Pushing non-sequenced packet of length [{}]" __L, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size);
|
||||||
NonSequencedQueue.push(p);
|
NonSequencedQueue.push(p);
|
||||||
MOutboundQueue.unlock();
|
MOutboundQueue.unlock();
|
||||||
}
|
}
|
||||||
@@ -631,14 +631,14 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p)
|
|||||||
void EQStream::SendAck(uint16 seq)
|
void EQStream::SendAck(uint16 seq)
|
||||||
{
|
{
|
||||||
uint16 Seq=htons(seq);
|
uint16 Seq=htons(seq);
|
||||||
LogNetcode(_L "Sending ack with sequence [{}]" __L, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq);
|
||||||
SetLastAckSent(seq);
|
SetLastAckSent(seq);
|
||||||
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
|
NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQStream::SendOutOfOrderAck(uint16 seq)
|
void EQStream::SendOutOfOrderAck(uint16 seq)
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Sending out of order ack with sequence [{}]" __L, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq);
|
||||||
uint16 Seq=htons(seq);
|
uint16 Seq=htons(seq);
|
||||||
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
|
NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16)));
|
||||||
}
|
}
|
||||||
@@ -688,24 +688,24 @@ void EQStream::Write(int eq_fd)
|
|||||||
// If we don't have a packet to try to combine into, use this one as the base
|
// If we don't have a packet to try to combine into, use this one as the base
|
||||||
// And remove it form the queue
|
// And remove it form the queue
|
||||||
p = NonSequencedQueue.front();
|
p = NonSequencedQueue.front();
|
||||||
LogNetcode(_L "Starting combined packet with non-seq packet of len [{}]" __L, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size);
|
||||||
NonSequencedQueue.pop();
|
NonSequencedQueue.pop();
|
||||||
} else if (!p->combine(NonSequencedQueue.front())) {
|
} else if (!p->combine(NonSequencedQueue.front())) {
|
||||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||||
// So just send the base packet (we'll try this packet again later)
|
// So just send the base packet (we'll try this packet again later)
|
||||||
LogNetcode(_L "Combined packet full at len [{}], next non-seq packet is len [{}]" __L, p->size, (NonSequencedQueue.front())->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size);
|
||||||
ReadyToSend.push(p);
|
ReadyToSend.push(p);
|
||||||
BytesWritten+=p->size;
|
BytesWritten+=p->size;
|
||||||
p=nullptr;
|
p=nullptr;
|
||||||
|
|
||||||
if (BytesWritten > threshold) {
|
if (BytesWritten > threshold) {
|
||||||
// Sent enough this round, lets stop to be fair
|
// Sent enough this round, lets stop to be fair
|
||||||
LogNetcode(_L "Exceeded write threshold in nonseq ([{}] > [{}])" __L, BytesWritten, threshold);
|
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Combine worked, so just remove this packet and it's spot in the queue
|
// Combine worked, so just remove this packet and it's spot in the queue
|
||||||
LogNetcode(_L "Combined non-seq packet of len [{}], yeilding [{}] combined" __L, (NonSequencedQueue.front())->size, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size);
|
||||||
delete NonSequencedQueue.front();
|
delete NonSequencedQueue.front();
|
||||||
NonSequencedQueue.pop();
|
NonSequencedQueue.pop();
|
||||||
}
|
}
|
||||||
@@ -718,7 +718,7 @@ void EQStream::Write(int eq_fd)
|
|||||||
uint16 seq_send = SequencedBase + count; //just for logging...
|
uint16 seq_send = SequencedBase + count; //just for logging...
|
||||||
|
|
||||||
if(SequencedQueue.empty()) {
|
if(SequencedQueue.empty()) {
|
||||||
LogNetcode(_L "Tried to write a packet with an empty queue ([{}] is past next out [{}])" __L, seq_send, NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq);
|
||||||
SeqEmpty=true;
|
SeqEmpty=true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -728,35 +728,35 @@ void EQStream::Write(int eq_fd)
|
|||||||
++sitr;
|
++sitr;
|
||||||
++count;
|
++count;
|
||||||
if (p) {
|
if (p) {
|
||||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||||
ReadyToSend.push(p);
|
ReadyToSend.push(p);
|
||||||
BytesWritten += p->size;
|
BytesWritten += p->size;
|
||||||
p = nullptr;
|
p = nullptr;
|
||||||
}
|
}
|
||||||
LogNetcode(_L "Not retransmitting seq packet [{}] because already marked as acked" __L, seq_send);
|
Log(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send);
|
||||||
} else if (!p) {
|
} else if (!p) {
|
||||||
// If we don't have a packet to try to combine into, use this one as the base
|
// If we don't have a packet to try to combine into, use this one as the base
|
||||||
// Copy it first as it will still live until it is acked
|
// Copy it first as it will still live until it is acked
|
||||||
p=(*sitr)->Copy();
|
p=(*sitr)->Copy();
|
||||||
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
|
||||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||||
++sitr;
|
++sitr;
|
||||||
++count;
|
++count;
|
||||||
} else if (!p->combine(*sitr)) {
|
} else if (!p->combine(*sitr)) {
|
||||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||||
// So just send the base packet (we'll try this packet again later)
|
// So just send the base packet (we'll try this packet again later)
|
||||||
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send + 1, (*sitr)->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send + 1, (*sitr)->size);
|
||||||
ReadyToSend.push(p);
|
ReadyToSend.push(p);
|
||||||
BytesWritten+=p->size;
|
BytesWritten+=p->size;
|
||||||
p=nullptr;
|
p=nullptr;
|
||||||
if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) {
|
if ((*sitr)->opcode != OP_Fragment && BytesWritten > threshold) {
|
||||||
// Sent enough this round, lets stop to be fair
|
// Sent enough this round, lets stop to be fair
|
||||||
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
|
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Combine worked
|
// Combine worked
|
||||||
LogNetcode(_L "Combined seq packet [{}] of len [{}], yeilding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size);
|
||||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||||
++sitr;
|
++sitr;
|
||||||
++count;
|
++count;
|
||||||
@@ -766,7 +766,7 @@ void EQStream::Write(int eq_fd)
|
|||||||
++sitr;
|
++sitr;
|
||||||
++count;
|
++count;
|
||||||
if (p) {
|
if (p) {
|
||||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||||
ReadyToSend.push(p);
|
ReadyToSend.push(p);
|
||||||
BytesWritten += p->size;
|
BytesWritten += p->size;
|
||||||
p = nullptr;
|
p = nullptr;
|
||||||
@@ -776,25 +776,25 @@ void EQStream::Write(int eq_fd)
|
|||||||
// Copy it first as it will still live until it is acked
|
// Copy it first as it will still live until it is acked
|
||||||
p=(*sitr)->Copy();
|
p=(*sitr)->Copy();
|
||||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||||
LogNetcode(_L "Starting combined packet with seq packet [{}] of len [{}]" __L, seq_send, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size);
|
||||||
++sitr;
|
++sitr;
|
||||||
++count;
|
++count;
|
||||||
} else if (!p->combine(*sitr)) {
|
} else if (!p->combine(*sitr)) {
|
||||||
// Trying to combine this packet with the base didn't work (too big maybe)
|
// Trying to combine this packet with the base didn't work (too big maybe)
|
||||||
// So just send the base packet (we'll try this packet again later)
|
// So just send the base packet (we'll try this packet again later)
|
||||||
LogNetcode(_L "Combined packet full at len [{}], next seq packet [{}] is len [{}]" __L, p->size, seq_send, (*sitr)->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size);
|
||||||
ReadyToSend.push(p);
|
ReadyToSend.push(p);
|
||||||
BytesWritten+=p->size;
|
BytesWritten+=p->size;
|
||||||
p=nullptr;
|
p=nullptr;
|
||||||
|
|
||||||
if (BytesWritten > threshold) {
|
if (BytesWritten > threshold) {
|
||||||
// Sent enough this round, lets stop to be fair
|
// Sent enough this round, lets stop to be fair
|
||||||
LogNetcode(_L "Exceeded write threshold in seq ([{}] > [{}])" __L, BytesWritten, threshold);
|
Log(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Combine worked
|
// Combine worked
|
||||||
LogNetcode(_L "Combined seq packet [{}] of len [{}], yielding [{}] combined" __L, seq_send, (*sitr)->size, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yielding %d combined." __L, seq_send, (*sitr)->size, p->size);
|
||||||
(*sitr)->sent_time = Timer::GetCurrentTime();
|
(*sitr)->sent_time = Timer::GetCurrentTime();
|
||||||
++sitr;
|
++sitr;
|
||||||
++count;
|
++count;
|
||||||
@@ -802,7 +802,7 @@ void EQStream::Write(int eq_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||||
LogNetcode(_L "Post send Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No more sequenced packets
|
// No more sequenced packets
|
||||||
@@ -814,7 +814,7 @@ void EQStream::Write(int eq_fd)
|
|||||||
|
|
||||||
// We have a packet still, must have run out of both seq and non-seq, so send it
|
// We have a packet still, must have run out of both seq and non-seq, so send it
|
||||||
if (p) {
|
if (p) {
|
||||||
LogNetcode(_L "Final combined packet not full, len [{}]" __L, p->size);
|
Log(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size);
|
||||||
ReadyToSend.push(p);
|
ReadyToSend.push(p);
|
||||||
BytesWritten+=p->size;
|
BytesWritten+=p->size;
|
||||||
}
|
}
|
||||||
@@ -831,7 +831,7 @@ void EQStream::Write(int eq_fd)
|
|||||||
if(SeqEmpty && NonSeqEmpty) {
|
if(SeqEmpty && NonSeqEmpty) {
|
||||||
//no more data to send
|
//no more data to send
|
||||||
if(CheckState(CLOSING)) {
|
if(CheckState(CLOSING)) {
|
||||||
LogNetcode(_L "All outgoing data flushed, closing stream" __L );
|
Log(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L );
|
||||||
//we are waiting for the queues to empty, now we can do our disconnect.
|
//we are waiting for the queues to empty, now we can do our disconnect.
|
||||||
//this packet will not actually go out until the next call to Write().
|
//this packet will not actually go out until the next call to Write().
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
@@ -910,7 +910,7 @@ void EQStream::SendSessionRequest()
|
|||||||
Request->Session=htonl(time(nullptr));
|
Request->Session=htonl(time(nullptr));
|
||||||
Request->MaxLength=htonl(512);
|
Request->MaxLength=htonl(512);
|
||||||
|
|
||||||
LogNetcode(_L "Sending OP_SessionRequest: session [{}], maxlen=[{}]" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
|
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength));
|
||||||
|
|
||||||
NonSequencedPush(out);
|
NonSequencedPush(out);
|
||||||
}
|
}
|
||||||
@@ -924,7 +924,7 @@ void EQStream::_SendDisconnect()
|
|||||||
*(uint32 *)out->pBuffer=htonl(Session);
|
*(uint32 *)out->pBuffer=htonl(Session);
|
||||||
NonSequencedPush(out);
|
NonSequencedPush(out);
|
||||||
|
|
||||||
LogNetcode(_L "Sending OP_SessionDisconnect: session [{}]" __L, (unsigned long)Session);
|
Log(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
|
void EQStream::InboundQueuePush(EQRawApplicationPacket *p)
|
||||||
@@ -976,7 +976,7 @@ EQRawApplicationPacket *p=nullptr;
|
|||||||
if(OpMgr != nullptr && *OpMgr != nullptr) {
|
if(OpMgr != nullptr && *OpMgr != nullptr) {
|
||||||
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
|
EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode);
|
||||||
if(emu_op == OP_Unknown) {
|
if(emu_op == OP_Unknown) {
|
||||||
LogNetcode("Unable to convert EQ opcode {:#04x} to an Application opcode", p->opcode);
|
Log(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->SetOpcode(emu_op);
|
p->SetOpcode(emu_op);
|
||||||
@@ -1004,7 +1004,7 @@ void EQStream::InboundQueueClear()
|
|||||||
{
|
{
|
||||||
EQApplicationPacket *p=nullptr;
|
EQApplicationPacket *p=nullptr;
|
||||||
|
|
||||||
LogNetcode(_L "Clearing inbound queue" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L);
|
||||||
|
|
||||||
MInboundQueue.lock();
|
MInboundQueue.lock();
|
||||||
if (!InboundQueue.empty()) {
|
if (!InboundQueue.empty()) {
|
||||||
@@ -1047,7 +1047,7 @@ void EQStream::OutboundQueueClear()
|
|||||||
{
|
{
|
||||||
EQProtocolPacket *p=nullptr;
|
EQProtocolPacket *p=nullptr;
|
||||||
|
|
||||||
LogNetcode(_L "Clearing outbound queue" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L);
|
||||||
|
|
||||||
MOutboundQueue.lock();
|
MOutboundQueue.lock();
|
||||||
while(!NonSequencedQueue.empty()) {
|
while(!NonSequencedQueue.empty()) {
|
||||||
@@ -1069,7 +1069,7 @@ void EQStream::PacketQueueClear()
|
|||||||
{
|
{
|
||||||
EQProtocolPacket *p=nullptr;
|
EQProtocolPacket *p=nullptr;
|
||||||
|
|
||||||
LogNetcode(_L "Clearing future packet queue" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L);
|
||||||
|
|
||||||
if(!PacketQueue.empty()) {
|
if(!PacketQueue.empty()) {
|
||||||
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
|
std::map<unsigned short,EQProtocolPacket *>::iterator itr;
|
||||||
@@ -1101,7 +1101,7 @@ void EQStream::Process(const unsigned char *buffer, const uint32 length)
|
|||||||
delete p;
|
delete p;
|
||||||
ProcessQueue();
|
ProcessQueue();
|
||||||
} else {
|
} else {
|
||||||
LogNetcode(_L "Incoming packet failed checksum" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1132,23 +1132,23 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
|||||||
SeqOrder ord = CompareSequence(SequencedBase, seq);
|
SeqOrder ord = CompareSequence(SequencedBase, seq);
|
||||||
if(ord == SeqInOrder) {
|
if(ord == SeqInOrder) {
|
||||||
//they are not acking anything new...
|
//they are not acking anything new...
|
||||||
LogNetcode(_L "Received an ack with no window advancement (seq [{}])" __L, seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq);
|
||||||
} else if(ord == SeqPast) {
|
} else if(ord == SeqPast) {
|
||||||
//they are nacking blocks going back before our buffer, wtf?
|
//they are nacking blocks going back before our buffer, wtf?
|
||||||
LogNetcode(_L "Received an ack with backward window advancement (they gave [{}], our window starts at [{}]). This is bad" __L, seq, SequencedBase);
|
Log(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase);
|
||||||
} else {
|
} else {
|
||||||
LogNetcode(_L "Received an ack up through sequence [{}]. Our base is [{}]" __L, seq, SequencedBase);
|
Log(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase);
|
||||||
|
|
||||||
|
|
||||||
//this is a good ack, we get to ack some blocks.
|
//this is a good ack, we get to ack some blocks.
|
||||||
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
|
seq++; //we stop at the block right after their ack, counting on the wrap of both numbers.
|
||||||
while(SequencedBase != seq) {
|
while(SequencedBase != seq) {
|
||||||
if(SequencedQueue.empty()) {
|
if(SequencedQueue.empty()) {
|
||||||
LogNetcode(_L "OUT OF PACKETS acked packet with sequence [{}]. Next send is [{}] before this" __L, (unsigned long)SequencedBase, SequencedQueue.size());
|
Log(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, SequencedQueue.size());
|
||||||
SequencedBase = NextOutSeq;
|
SequencedBase = NextOutSeq;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LogNetcode(_L "Removing acked packet with sequence [{}]" __L, (unsigned long)SequencedBase);
|
Log(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu." __L, (unsigned long)SequencedBase);
|
||||||
//clean out the acked packet
|
//clean out the acked packet
|
||||||
delete SequencedQueue.front();
|
delete SequencedQueue.front();
|
||||||
SequencedQueue.pop_front();
|
SequencedQueue.pop_front();
|
||||||
@@ -1156,7 +1156,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
|||||||
SequencedBase++;
|
SequencedBase++;
|
||||||
}
|
}
|
||||||
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||||
LogNetcode(_L "Post-Ack on [{}] Invalid Sequenced queue: BS [{}] + SQ [{}] != NOS [{}]" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1166,7 +1166,7 @@ std::deque<EQProtocolPacket *>::iterator itr, tmp;
|
|||||||
void EQStream::SetNextAckToSend(uint32 seq)
|
void EQStream::SetNextAckToSend(uint32 seq)
|
||||||
{
|
{
|
||||||
MAcks.lock();
|
MAcks.lock();
|
||||||
LogNetcode(_L "Set Next Ack To Send to [{}]" __L, (unsigned long)seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq);
|
||||||
NextAckToSend=seq;
|
NextAckToSend=seq;
|
||||||
MAcks.unlock();
|
MAcks.unlock();
|
||||||
}
|
}
|
||||||
@@ -1174,7 +1174,7 @@ void EQStream::SetNextAckToSend(uint32 seq)
|
|||||||
void EQStream::SetLastAckSent(uint32 seq)
|
void EQStream::SetLastAckSent(uint32 seq)
|
||||||
{
|
{
|
||||||
MAcks.lock();
|
MAcks.lock();
|
||||||
LogNetcode(_L "Set Last Ack Sent to [{}]" __L, (unsigned long)seq);
|
Log(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq);
|
||||||
LastAckSent=seq;
|
LastAckSent=seq;
|
||||||
MAcks.unlock();
|
MAcks.unlock();
|
||||||
}
|
}
|
||||||
@@ -1187,10 +1187,10 @@ void EQStream::ProcessQueue()
|
|||||||
|
|
||||||
EQProtocolPacket *qp=nullptr;
|
EQProtocolPacket *qp=nullptr;
|
||||||
while((qp=RemoveQueue(NextInSeq))!=nullptr) {
|
while((qp=RemoveQueue(NextInSeq))!=nullptr) {
|
||||||
LogNetcode(_L "Processing Queued Packet: Seq=[{}]" __L, NextInSeq);
|
Log(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq);
|
||||||
ProcessPacket(qp);
|
ProcessPacket(qp);
|
||||||
delete qp;
|
delete qp;
|
||||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1201,21 +1201,21 @@ EQProtocolPacket *qp=nullptr;
|
|||||||
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
|
if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) {
|
||||||
qp=itr->second;
|
qp=itr->second;
|
||||||
PacketQueue.erase(itr);
|
PacketQueue.erase(itr);
|
||||||
LogNetcode(_L "OP_Packet Queue size=[{}]" __L, PacketQueue.size());
|
Log(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size());
|
||||||
}
|
}
|
||||||
return qp;
|
return qp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQStream::SetStreamType(EQStreamType type)
|
void EQStream::SetStreamType(EQStreamType type)
|
||||||
{
|
{
|
||||||
LogNetcode(_L "Changing stream type from [{}] to [{}]" __L, StreamTypeString(StreamType), StreamTypeString(type));
|
Log(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type));
|
||||||
StreamType=type;
|
StreamType=type;
|
||||||
switch (StreamType) {
|
switch (StreamType) {
|
||||||
case LoginStream:
|
case LoginStream:
|
||||||
app_opcode_size=1;
|
app_opcode_size=1;
|
||||||
compressed=false;
|
compressed=false;
|
||||||
encoded=false;
|
encoded=false;
|
||||||
LogNetcode(_L "Login stream has app opcode size [{}], is not compressed or encoded" __L, app_opcode_size);
|
Log(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size);
|
||||||
break;
|
break;
|
||||||
case ChatOrMailStream:
|
case ChatOrMailStream:
|
||||||
case ChatStream:
|
case ChatStream:
|
||||||
@@ -1223,7 +1223,7 @@ void EQStream::SetStreamType(EQStreamType type)
|
|||||||
app_opcode_size=1;
|
app_opcode_size=1;
|
||||||
compressed=false;
|
compressed=false;
|
||||||
encoded=true;
|
encoded=true;
|
||||||
LogNetcode(_L "Chat/Mail stream has app opcode size [{}], is not compressed, and is encoded" __L, app_opcode_size);
|
Log(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size);
|
||||||
break;
|
break;
|
||||||
case ZoneStream:
|
case ZoneStream:
|
||||||
case WorldStream:
|
case WorldStream:
|
||||||
@@ -1231,7 +1231,7 @@ void EQStream::SetStreamType(EQStreamType type)
|
|||||||
app_opcode_size=2;
|
app_opcode_size=2;
|
||||||
compressed=true;
|
compressed=true;
|
||||||
encoded=false;
|
encoded=false;
|
||||||
LogNetcode(_L "World/Zone stream has app opcode size [{}], is compressed, and is not encoded" __L, app_opcode_size);
|
Log(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1281,7 +1281,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq)
|
|||||||
|
|
||||||
void EQStream::SetState(EQStreamState state) {
|
void EQStream::SetState(EQStreamState state) {
|
||||||
MState.lock();
|
MState.lock();
|
||||||
LogNetcode(_L "Changing state from [{}] to [{}]" __L, State, state);
|
Log(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state);
|
||||||
State=state;
|
State=state;
|
||||||
MState.unlock();
|
MState.unlock();
|
||||||
}
|
}
|
||||||
@@ -1293,29 +1293,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) {
|
|||||||
|
|
||||||
EQStreamState orig_state = GetState();
|
EQStreamState orig_state = GetState();
|
||||||
if (orig_state == CLOSING && !outgoing_data) {
|
if (orig_state == CLOSING && !outgoing_data) {
|
||||||
LogNetcode(_L "Out of data in closing state, disconnecting" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L);
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
SetState(DISCONNECTING);
|
SetState(DISCONNECTING);
|
||||||
} else if (LastPacket && (now-LastPacket) > timeout) {
|
} else if (LastPacket && (now-LastPacket) > timeout) {
|
||||||
switch(orig_state) {
|
switch(orig_state) {
|
||||||
case CLOSING:
|
case CLOSING:
|
||||||
//if we time out in the closing state, they are not acking us, just give up
|
//if we time out in the closing state, they are not acking us, just give up
|
||||||
LogNetcode(_L "Timeout expired in closing state. Moving to closed state" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L);
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
SetState(CLOSED);
|
SetState(CLOSED);
|
||||||
break;
|
break;
|
||||||
case DISCONNECTING:
|
case DISCONNECTING:
|
||||||
//we timed out waiting for them to send us the disconnect reply, just give up.
|
//we timed out waiting for them to send us the disconnect reply, just give up.
|
||||||
LogNetcode(_L "Timeout expired in disconnecting state. Moving to closed state" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L);
|
||||||
SetState(CLOSED);
|
SetState(CLOSED);
|
||||||
break;
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
LogNetcode(_L "Timeout expired in closed state??" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L);
|
||||||
break;
|
break;
|
||||||
case ESTABLISHED:
|
case ESTABLISHED:
|
||||||
//we timed out during normal operation. Try to be nice about it.
|
//we timed out during normal operation. Try to be nice about it.
|
||||||
//we will almost certainly time out again waiting for the disconnect reply, but oh well.
|
//we will almost certainly time out again waiting for the disconnect reply, but oh well.
|
||||||
LogNetcode(_L "Timeout expired in established state. Closing connection" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L);
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
SetState(DISCONNECTING);
|
SetState(DISCONNECTING);
|
||||||
break;
|
break;
|
||||||
@@ -1342,7 +1342,7 @@ void EQStream::Decay()
|
|||||||
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) {
|
for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) {
|
||||||
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) {
|
if (!(*sitr)->acked && (*sitr)->sent_time > 0 && ((*sitr)->sent_time + retransmittimeout) < Timer::GetCurrentTime()) {
|
||||||
(*sitr)->sent_time = 0;
|
(*sitr)->sent_time = 0;
|
||||||
LogNetcode(_L "Timeout exceeded for seq [{}]. Flagging packet for retransmission" __L, SequencedBase + count);
|
Log(Logs::Detail, Logs::Netcode, _L "Timeout exceeded for seq %d. Flagging packet for retransmission" __L, SequencedBase + count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MOutboundQueue.unlock();
|
MOutboundQueue.unlock();
|
||||||
@@ -1384,12 +1384,12 @@ void EQStream::AdjustRates(uint32 average_delta)
|
|||||||
void EQStream::Close() {
|
void EQStream::Close() {
|
||||||
if(HasOutgoingData()) {
|
if(HasOutgoingData()) {
|
||||||
//there is pending data, wait for it to go out.
|
//there is pending data, wait for it to go out.
|
||||||
LogNetcode(_L "Stream requested to Close(), but there is pending data, waiting for it" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L);
|
||||||
SetState(CLOSING);
|
SetState(CLOSING);
|
||||||
} else {
|
} else {
|
||||||
//otherwise, we are done, we can drop immediately.
|
//otherwise, we are done, we can drop immediately.
|
||||||
_SendDisconnect();
|
_SendDisconnect();
|
||||||
LogNetcode(_L "Stream closing immediate due to Close()" __L);
|
Log(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L);
|
||||||
SetState(DISCONNECTING);
|
SetState(DISCONNECTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1417,19 +1417,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) {
|
|||||||
} else if(p->opcode == sig->first_eq_opcode) {
|
} else if(p->opcode == sig->first_eq_opcode) {
|
||||||
//opcode matches, check length..
|
//opcode matches, check length..
|
||||||
if(p->size == sig->first_length) {
|
if(p->size == sig->first_length) {
|
||||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length matched [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||||
res = MatchSuccessful;
|
res = MatchSuccessful;
|
||||||
} else if(sig->first_length == 0) {
|
} else if(sig->first_length == 0) {
|
||||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x} and length ([{}]) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size);
|
||||||
res = MatchSuccessful;
|
res = MatchSuccessful;
|
||||||
} else {
|
} else {
|
||||||
//opcode matched but length did not.
|
//opcode matched but length did not.
|
||||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode matched {:#04x}, but length [{}] did not match expected [{}]", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
|
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length);
|
||||||
res = MatchFailed;
|
res = MatchFailed;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//first opcode did not match..
|
//first opcode did not match..
|
||||||
LogNetcode("[StreamIdentify] [{}]:[{}]: First opcode {:#04x} did not match expected {:#04x}", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
|
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode);
|
||||||
res = MatchFailed;
|
res = MatchFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -46,7 +46,7 @@ void EQStreamIdentifier::Process() {
|
|||||||
|
|
||||||
//first see if this stream has expired
|
//first see if this stream has expired
|
||||||
if(r.expire.Check(false)) {
|
if(r.expire.Check(false)) {
|
||||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before timeout", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", r.stream->GetRemoteAddr().c_str(), ntohs(r.stream->GetRemotePort()));
|
||||||
r.stream->Close();
|
r.stream->Close();
|
||||||
|
|
||||||
cur = m_streams.erase(cur);
|
cur = m_streams.erase(cur);
|
||||||
@@ -62,23 +62,23 @@ void EQStreamIdentifier::Process() {
|
|||||||
}
|
}
|
||||||
if(r.stream->GetState() != ESTABLISHED) {
|
if(r.stream->GetState() != ESTABLISHED) {
|
||||||
//the stream closed before it was identified.
|
//the stream closed before it was identified.
|
||||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}] before it closed", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||||
switch(r.stream->GetState())
|
switch(r.stream->GetState())
|
||||||
{
|
{
|
||||||
case ESTABLISHED:
|
case ESTABLISHED:
|
||||||
LogNetcode("[StreamIdentify] Stream state was Established");
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established");
|
||||||
break;
|
break;
|
||||||
case CLOSING:
|
case CLOSING:
|
||||||
LogNetcode("[StreamIdentify] Stream state was Closing");
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing");
|
||||||
break;
|
break;
|
||||||
case DISCONNECTING:
|
case DISCONNECTING:
|
||||||
LogNetcode("[StreamIdentify] Stream state was Disconnecting");
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting");
|
||||||
break;
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
LogNetcode("[StreamIdentify] Stream state was Closed");
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogNetcode("[StreamIdentify] Stream state was Unestablished or unknown");
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
r.stream->ReleaseFromUse();
|
r.stream->ReleaseFromUse();
|
||||||
@@ -102,13 +102,13 @@ void EQStreamIdentifier::Process() {
|
|||||||
switch(res) {
|
switch(res) {
|
||||||
case EQStreamInterface::MatchNotReady:
|
case EQStreamInterface::MatchNotReady:
|
||||||
//the stream has not received enough packets to compare with this signature
|
//the stream has not received enough packets to compare with this signature
|
||||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[StreamIdentify] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||||
all_ready = false;
|
all_ready = false;
|
||||||
break;
|
break;
|
||||||
case EQStreamInterface::MatchSuccessful: {
|
case EQStreamInterface::MatchSuccessful: {
|
||||||
//yay, a match.
|
//yay, a match.
|
||||||
|
|
||||||
LogNetcode("[StreamIdentify] Identified stream [{}:{}] with signature [{}]", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||||
|
|
||||||
// before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further
|
// before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further
|
||||||
r.stream->SetActive(true);
|
r.stream->SetActive(true);
|
||||||
@@ -122,7 +122,7 @@ void EQStreamIdentifier::Process() {
|
|||||||
}
|
}
|
||||||
case EQStreamInterface::MatchFailed:
|
case EQStreamInterface::MatchFailed:
|
||||||
//do nothing...
|
//do nothing...
|
||||||
LogNetcode("[StreamIdentify] [{}:{}] Tried patch [{}] and it did not match", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
Log(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ void EQStreamIdentifier::Process() {
|
|||||||
//if we checked all patches and did not find a match.
|
//if we checked all patches and did not find a match.
|
||||||
if(all_ready && !found_one) {
|
if(all_ready && !found_one) {
|
||||||
//the stream cannot be identified.
|
//the stream cannot be identified.
|
||||||
LogNetcode("[StreamIdentify] Unable to identify stream from [{}:{}], no match found", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()));
|
||||||
r.stream->ReleaseFromUse();
|
r.stream->ReleaseFromUse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-3
@@ -7,6 +7,7 @@
|
|||||||
#include "emu_versions.h"
|
#include "emu_versions.h"
|
||||||
#include "eq_packet.h"
|
#include "eq_packet.h"
|
||||||
#include "net/daybreak_connection.h"
|
#include "net/daybreak_connection.h"
|
||||||
|
#include "event/event_loop.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESTABLISHED,
|
ESTABLISHED,
|
||||||
@@ -23,6 +24,7 @@ struct EQStreamManagerInterfaceOptions
|
|||||||
{
|
{
|
||||||
EQStreamManagerInterfaceOptions() {
|
EQStreamManagerInterfaceOptions() {
|
||||||
opcode_size = 2;
|
opcode_size = 2;
|
||||||
|
loop = &EQ::EventLoop::GetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
EQStreamManagerInterfaceOptions(int port, bool encoded, bool compressed) {
|
EQStreamManagerInterfaceOptions(int port, bool encoded, bool compressed) {
|
||||||
@@ -40,22 +42,33 @@ struct EQStreamManagerInterfaceOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
daybreak_options.port = port;
|
daybreak_options.port = port;
|
||||||
|
loop = &EQ::EventLoop::GetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
int opcode_size;
|
int opcode_size;
|
||||||
bool track_opcode_stats;
|
|
||||||
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
||||||
|
EQ::EventLoop *loop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EQStreamPriority : int32_t {
|
||||||
|
High,
|
||||||
|
Normal,
|
||||||
|
Low
|
||||||
|
};
|
||||||
|
|
||||||
|
class EQStreamInterface;
|
||||||
class EQStreamManagerInterface
|
class EQStreamManagerInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EQStreamManagerInterface(const EQStreamManagerInterfaceOptions &options) { m_options = options; }
|
EQStreamManagerInterface(const EQStreamManagerInterfaceOptions &options) { m_options = options; }
|
||||||
virtual ~EQStreamManagerInterface() { };
|
virtual ~EQStreamManagerInterface() { };
|
||||||
|
|
||||||
EQStreamManagerInterfaceOptions GetOptions() { return m_options; }
|
|
||||||
const EQStreamManagerInterfaceOptions& GetOptions() const { return m_options; }
|
const EQStreamManagerInterfaceOptions& GetOptions() const { return m_options; }
|
||||||
virtual void SetOptions(const EQStreamManagerInterfaceOptions& options) = 0;
|
EQStreamManagerInterfaceOptions& MutateOptions() { return m_options; }
|
||||||
|
|
||||||
|
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) = 0;
|
||||||
|
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) = 0;
|
||||||
|
virtual void SetPriority(EQStreamPriority priority) = 0;
|
||||||
protected:
|
protected:
|
||||||
EQStreamManagerInterfaceOptions m_options;
|
EQStreamManagerInterfaceOptions m_options;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (p->GetOpcode() != OP_SpecialMesg) {
|
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::Server_Client_Packet, "[%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());
|
Log(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
EQApplicationPacket *newp = p->Copy();
|
EQApplicationPacket *newp = p->Copy();
|
||||||
|
|||||||
+9
-43
@@ -26,8 +26,7 @@
|
|||||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||||
|
|
||||||
void EQEmuConfig::parse_config()
|
void EQEmuConfig::parse_config() {
|
||||||
{
|
|
||||||
|
|
||||||
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
ShortName = _root["server"]["world"].get("shortname", "").asString();
|
||||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||||
@@ -41,11 +40,10 @@ void EQEmuConfig::parse_config()
|
|||||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||||
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||||
LoginLegacy = false;
|
LoginLegacy = false;
|
||||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") LoginLegacy = true;
|
||||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||||
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
char str[32];
|
char str[32];
|
||||||
loginlist.Clear();
|
loginlist.Clear();
|
||||||
do {
|
do {
|
||||||
@@ -61,7 +59,7 @@ void EQEmuConfig::parse_config()
|
|||||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||||
|
|
||||||
loginconfig->LoginLegacy = false;
|
loginconfig->LoginLegacy = false;
|
||||||
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
|
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") loginconfig->LoginLegacy = true;
|
||||||
loginlist.Insert(loginconfig);
|
loginlist.Insert(loginconfig);
|
||||||
} while (LoginCount < 100);
|
} while (LoginCount < 100);
|
||||||
}
|
}
|
||||||
@@ -70,67 +68,46 @@ void EQEmuConfig::parse_config()
|
|||||||
//<locked> from xml converts to json as locked: "", so i default to "false".
|
//<locked> from xml converts to json as locked: "", so i default to "false".
|
||||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||||
Locked = false;
|
Locked = false;
|
||||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
if (_root["server"]["world"].get("locked", "false").asString() == "true") Locked = true;
|
||||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||||
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||||
|
|
||||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||||
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||||
TelnetEnabled = false;
|
TelnetEnabled = false;
|
||||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") TelnetEnabled = true;
|
||||||
|
|
||||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||||
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||||
WorldHTTPEnabled = false;
|
WorldHTTPEnabled = false;
|
||||||
|
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") WorldHTTPEnabled = true;
|
||||||
|
|
||||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
|
||||||
WorldHTTPEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UCS
|
|
||||||
*/
|
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||||
|
|
||||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||||
|
|
||||||
/**
|
|
||||||
* Database
|
|
||||||
*/
|
|
||||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||||
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||||
|
|
||||||
/**
|
|
||||||
* QS
|
|
||||||
*/
|
|
||||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||||
|
|
||||||
/**
|
|
||||||
* Zones
|
|
||||||
*/
|
|
||||||
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||||
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||||
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||||
|
|
||||||
/**
|
|
||||||
* Files
|
|
||||||
*/
|
|
||||||
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
|
||||||
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
|
||||||
MailOpCodesFile = _root["server"]["files"].get("mail_opcodes", "mail_opcodes.conf").asString();
|
|
||||||
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
|
||||||
|
|
||||||
/**
|
|
||||||
* Directories
|
|
||||||
*/
|
|
||||||
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
|
||||||
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
|
||||||
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
|
||||||
@@ -139,15 +116,8 @@ void EQEmuConfig::parse_config()
|
|||||||
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
|
||||||
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs
|
|
||||||
*/
|
|
||||||
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
|
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
|
||||||
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
|
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
|
||||||
|
|
||||||
/**
|
|
||||||
* Launcher
|
|
||||||
*/
|
|
||||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||||
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||||
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||||
@@ -260,9 +230,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
|||||||
if (var_name == "OpCodesFile") {
|
if (var_name == "OpCodesFile") {
|
||||||
return (OpCodesFile);
|
return (OpCodesFile);
|
||||||
}
|
}
|
||||||
if (var_name == "MailOpCodesFile") {
|
|
||||||
return (MailOpCodesFile);
|
|
||||||
}
|
|
||||||
if (var_name == "PluginPlFile") {
|
if (var_name == "PluginPlFile") {
|
||||||
return (PluginPlFile);
|
return (PluginPlFile);
|
||||||
}
|
}
|
||||||
@@ -345,7 +312,6 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
std::cout << "QSDatabasePort = " << QSDatabasePort << std::endl;
|
||||||
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
std::cout << "SpellsFile = " << SpellsFile << std::endl;
|
||||||
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
std::cout << "OpCodesFile = " << OpCodesFile << std::endl;
|
||||||
std::cout << "MailOpcodesFile = " << MailOpCodesFile << std::endl;
|
|
||||||
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
|
std::cout << "PluginPlFile = " << PluginPlFile << std::endl;
|
||||||
std::cout << "MapDir = " << MapDir << std::endl;
|
std::cout << "MapDir = " << MapDir << std::endl;
|
||||||
std::cout << "QuestDir = " << QuestDir << std::endl;
|
std::cout << "QuestDir = " << QuestDir << std::endl;
|
||||||
@@ -356,6 +322,6 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "LogDir = " << LogDir << std::endl;
|
std::cout << "LogDir = " << LogDir << std::endl;
|
||||||
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
|
std::cout << "ZonePortLow = " << ZonePortLow << std::endl;
|
||||||
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
|
std::cout << "ZonePortHigh = " << ZonePortHigh << std::endl;
|
||||||
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
|
||||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ class EQEmuConfig
|
|||||||
// From <files/>
|
// From <files/>
|
||||||
std::string SpellsFile;
|
std::string SpellsFile;
|
||||||
std::string OpCodesFile;
|
std::string OpCodesFile;
|
||||||
std::string MailOpCodesFile;
|
|
||||||
std::string PluginPlFile;
|
std::string PluginPlFile;
|
||||||
|
|
||||||
// From <directories/>
|
// From <directories/>
|
||||||
@@ -165,7 +164,7 @@ class EQEmuConfig
|
|||||||
fconfig >> _config->_root;
|
fconfig >> _config->_root;
|
||||||
_config->parse_config();
|
_config->parse_config();
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+56
-153
@@ -19,7 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
#include "rulesys.h"
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
@@ -82,19 +81,30 @@ namespace Console {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GameChatColor {
|
||||||
|
yellow = 15,
|
||||||
|
red = 13,
|
||||||
|
light_green = 14,
|
||||||
|
light_cyan = 258,
|
||||||
|
light_purple = 5
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EQEmuLogSys Constructor
|
* EQEmuLogSys Constructor
|
||||||
*/
|
*/
|
||||||
EQEmuLogSys::EQEmuLogSys()
|
EQEmuLogSys::EQEmuLogSys()
|
||||||
{
|
{
|
||||||
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
|
on_log_gmsay_hook = [](uint16 log_type, const std::string &) {};
|
||||||
on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {};
|
bool file_logs_enabled = false;
|
||||||
|
int log_platform = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EQEmuLogSys Deconstructor
|
* EQEmuLogSys Deconstructor
|
||||||
*/
|
*/
|
||||||
EQEmuLogSys::~EQEmuLogSys() = default;
|
EQEmuLogSys::~EQEmuLogSys()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void EQEmuLogSys::LoadLogSettingsDefaults()
|
void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||||
{
|
{
|
||||||
@@ -115,28 +125,15 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
/**
|
/**
|
||||||
* Set Defaults
|
* Set Defaults
|
||||||
*/
|
*/
|
||||||
log_settings[Logs::WorldServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::World_Server].log_to_console = Logs::General;
|
||||||
log_settings[Logs::ZoneServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Zone_Server].log_to_console = Logs::General;
|
||||||
log_settings[Logs::QSServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::QS_Server].log_to_console = Logs::General;
|
||||||
log_settings[Logs::UCSServer].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::UCS_Server].log_to_console = Logs::General;
|
||||||
log_settings[Logs::Crash].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Crash].log_to_console = Logs::General;
|
||||||
log_settings[Logs::MySQLError].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::MySQLError].log_to_console = Logs::General;
|
||||||
log_settings[Logs::Loginserver].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Login_Server].log_to_console = Logs::General;
|
||||||
log_settings[Logs::HeadlessClient].log_to_console = static_cast<uint8>(Logs::General);
|
log_settings[Logs::Headless_Client].log_to_console = Logs::General;
|
||||||
log_settings[Logs::NPCScaling].log_to_gmsay = static_cast<uint8>(Logs::General);
|
log_settings[Logs::NPCScaling].log_to_gmsay = 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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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::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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Category enabled status on defaults
|
* Set Category enabled status on defaults
|
||||||
@@ -177,41 +174,20 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 log_category
|
||||||
* @param in_message
|
* @param in_message
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::string EQEmuLogSys::FormatOutMessageString(
|
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
|
||||||
uint16 log_category,
|
|
||||||
const std::string &in_message
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
std::string return_string;
|
std::string ret;
|
||||||
|
ret.push_back('[');
|
||||||
if (IsRfc5424LogCategory(log_category)) {
|
ret.append(Logs::LogCategoryName[log_category]);
|
||||||
return_string = "[" + GetPlatformName() + "] ";
|
ret.push_back(']');
|
||||||
}
|
ret.push_back(' ');
|
||||||
|
ret.append(in_message);
|
||||||
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,11 +195,7 @@ std::string EQEmuLogSys::FormatOutMessageString(
|
|||||||
* @param log_category
|
* @param log_category
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
void EQEmuLogSys::ProcessGMSay(
|
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||||
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
|
* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash
|
||||||
@@ -245,11 +217,7 @@ void EQEmuLogSys::ProcessGMSay(
|
|||||||
* @param log_category
|
* @param log_category
|
||||||
* @param message
|
* @param message
|
||||||
*/
|
*/
|
||||||
void EQEmuLogSys::ProcessLogWrite(
|
void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||||
uint16 debug_level,
|
|
||||||
uint16 log_category,
|
|
||||||
const std::string &message
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (log_category == Logs::Crash) {
|
if (log_category == Logs::Crash) {
|
||||||
char time_stamp[80];
|
char time_stamp[80];
|
||||||
@@ -311,8 +279,6 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category)
|
|||||||
case Logs::Normal:
|
case Logs::Normal:
|
||||||
return LC_YELLOW;
|
return LC_YELLOW;
|
||||||
case Logs::MySQLError:
|
case Logs::MySQLError:
|
||||||
case Logs::Warning:
|
|
||||||
case Logs::Critical:
|
|
||||||
case Logs::Error:
|
case Logs::Error:
|
||||||
return LC_RED;
|
return LC_RED;
|
||||||
case Logs::MySQLQuery:
|
case Logs::MySQLQuery:
|
||||||
@@ -339,22 +305,22 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
|||||||
switch (log_category) {
|
switch (log_category) {
|
||||||
case Logs::Status:
|
case Logs::Status:
|
||||||
case Logs::Normal:
|
case Logs::Normal:
|
||||||
return Chat::Yellow;
|
return GameChatColor::yellow;
|
||||||
case Logs::MySQLError:
|
case Logs::MySQLError:
|
||||||
case Logs::Error:
|
case Logs::Error:
|
||||||
return Chat::Red;
|
return GameChatColor::red;
|
||||||
case Logs::MySQLQuery:
|
case Logs::MySQLQuery:
|
||||||
case Logs::Debug:
|
case Logs::Debug:
|
||||||
return Chat::Lime;
|
return GameChatColor::light_green;
|
||||||
case Logs::Quests:
|
case Logs::Quests:
|
||||||
return Chat::Group;
|
return GameChatColor::light_cyan;
|
||||||
case Logs::Commands:
|
case Logs::Commands:
|
||||||
case Logs::Mercenaries:
|
case Logs::Mercenaries:
|
||||||
return Chat::Magenta;
|
return GameChatColor::light_purple;
|
||||||
case Logs::Crash:
|
case Logs::Crash:
|
||||||
return Chat::Red;
|
return GameChatColor::red;
|
||||||
default:
|
default:
|
||||||
return Chat::Yellow;
|
return GameChatColor::yellow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,44 +346,6 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
|
|||||||
#else
|
#else
|
||||||
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
|
std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
on_log_console_hook(debug_level, log_category, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param str
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
constexpr const char *str_end(const char *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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -428,15 +356,7 @@ constexpr const char *base_file_name(const char *str)
|
|||||||
* @param message
|
* @param message
|
||||||
* @param ...
|
* @param ...
|
||||||
*/
|
*/
|
||||||
void EQEmuLogSys::Out(
|
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
|
||||||
Logs::DebugLevel debug_level,
|
|
||||||
uint16 log_category,
|
|
||||||
const char *file,
|
|
||||||
const char *func,
|
|
||||||
int line,
|
|
||||||
const char *message,
|
|
||||||
...
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
bool log_to_console = true;
|
bool log_to_console = true;
|
||||||
if (log_settings[log_category].log_to_console < debug_level) {
|
if (log_settings[log_category].log_to_console < debug_level) {
|
||||||
@@ -458,18 +378,12 @@ void EQEmuLogSys::Out(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string prefix;
|
|
||||||
|
|
||||||
if (RuleB(Logging, PrintFileFunctionAndLine)) {
|
|
||||||
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, message);
|
va_start(args, message);
|
||||||
std::string output_message = vStringFormat(message, args);
|
std::string output_message = vStringFormat(message.c_str(), args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
|
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message);
|
||||||
|
|
||||||
if (log_to_console) {
|
if (log_to_console) {
|
||||||
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
|
EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message);
|
||||||
@@ -505,7 +419,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name)
|
|||||||
return;
|
return;
|
||||||
_mkdir(directory_name.c_str());
|
_mkdir(directory_name.c_str());
|
||||||
#else
|
#else
|
||||||
struct stat st{};
|
struct stat st;
|
||||||
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -546,7 +460,12 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
|
EQEmuLogSys::Out(
|
||||||
|
Logs::General,
|
||||||
|
Logs::Status,
|
||||||
|
"Starting File Log 'logs/%s_%i.log'",
|
||||||
|
platform_file_name.c_str(),
|
||||||
|
getpid());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make directory if not exists
|
* Make directory if not exists
|
||||||
@@ -566,11 +485,17 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
/**
|
/**
|
||||||
* All other processes
|
* All other processes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (platform_file_name.empty()) {
|
if (platform_file_name.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid());
|
EQEmuLogSys::Out(
|
||||||
|
Logs::General,
|
||||||
|
Logs::Status,
|
||||||
|
"Starting File Log 'logs/%s_%i.log'",
|
||||||
|
platform_file_name.c_str(),
|
||||||
|
getpid());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open file pointer
|
* Open file pointer
|
||||||
@@ -581,25 +506,3 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Silence console logging
|
|
||||||
*/
|
|
||||||
void EQEmuLogSys::SilenceConsoleLogging()
|
|
||||||
{
|
|
||||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
|
||||||
log_settings[log_index].log_to_console = 0;
|
|
||||||
log_settings[log_index].is_category_enabled = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables console logging
|
|
||||||
*/
|
|
||||||
void EQEmuLogSys::EnableConsoleLogging()
|
|
||||||
{
|
|
||||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
|
||||||
log_settings[log_index].log_to_console = Logs::General;
|
|
||||||
log_settings[log_index].is_category_enabled = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+30
-141
@@ -25,14 +25,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#ifdef utf16_to_utf8
|
|
||||||
#undef utf16_to_utf8
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace Logs {
|
namespace Logs {
|
||||||
@@ -53,7 +45,7 @@ namespace Logs {
|
|||||||
AI,
|
AI,
|
||||||
Aggro,
|
Aggro,
|
||||||
Attack,
|
Attack,
|
||||||
PacketClientServer,
|
Client_Server_Packet,
|
||||||
Combat,
|
Combat,
|
||||||
Commands,
|
Commands,
|
||||||
Crash,
|
Crash,
|
||||||
@@ -67,54 +59,40 @@ namespace Logs {
|
|||||||
Normal,
|
Normal,
|
||||||
Object,
|
Object,
|
||||||
Pathing,
|
Pathing,
|
||||||
QSServer,
|
QS_Server,
|
||||||
Quests,
|
Quests,
|
||||||
Rules,
|
Rules,
|
||||||
Skills,
|
Skills,
|
||||||
Spawns,
|
Spawns,
|
||||||
Spells,
|
Spells,
|
||||||
Status,
|
Status,
|
||||||
TCPConnection,
|
TCP_Connection,
|
||||||
Tasks,
|
Tasks,
|
||||||
Tradeskills,
|
Tradeskills,
|
||||||
Trading,
|
Trading,
|
||||||
Tribute,
|
Tribute,
|
||||||
UCSServer,
|
UCS_Server,
|
||||||
WebInterfaceServer,
|
WebInterface_Server,
|
||||||
WorldServer,
|
World_Server,
|
||||||
ZoneServer,
|
Zone_Server,
|
||||||
MySQLError,
|
MySQLError,
|
||||||
MySQLQuery,
|
MySQLQuery,
|
||||||
Mercenaries,
|
Mercenaries,
|
||||||
QuestDebug,
|
QuestDebug,
|
||||||
PacketServerClient,
|
Server_Client_Packet,
|
||||||
PacketClientServerUnhandled,
|
Client_Server_Packet_Unhandled,
|
||||||
PacketServerClientWithDump,
|
Server_Client_Packet_With_Dump,
|
||||||
PacketClientServerWithDump,
|
Client_Server_Packet_With_Dump,
|
||||||
Loginserver,
|
Login_Server,
|
||||||
ClientLogin,
|
Client_Login,
|
||||||
HeadlessClient,
|
Headless_Client,
|
||||||
HPUpdate,
|
HP_Update,
|
||||||
FixZ,
|
FixZ,
|
||||||
Food,
|
Food,
|
||||||
Traps,
|
Traps,
|
||||||
NPCRoamBox,
|
NPCRoamBox,
|
||||||
NPCScaling,
|
NPCScaling,
|
||||||
MobAppearance,
|
MobAppearance,
|
||||||
Info,
|
|
||||||
Warning,
|
|
||||||
Critical,
|
|
||||||
Emergency,
|
|
||||||
Alert,
|
|
||||||
Notice,
|
|
||||||
AIScanClose,
|
|
||||||
AIYellForHelp,
|
|
||||||
AICastBeneficialClose,
|
|
||||||
AoeCast,
|
|
||||||
EntityManagement,
|
|
||||||
Flee,
|
|
||||||
Aura,
|
|
||||||
HotReload,
|
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,25 +152,19 @@ namespace Logs {
|
|||||||
"Traps",
|
"Traps",
|
||||||
"NPC Roam Box",
|
"NPC Roam Box",
|
||||||
"NPC Scaling",
|
"NPC Scaling",
|
||||||
"Mob Appearance",
|
"Mob Appearance"
|
||||||
"Info",
|
|
||||||
"Warning",
|
|
||||||
"Critical",
|
|
||||||
"Emergency",
|
|
||||||
"Alert",
|
|
||||||
"Notice",
|
|
||||||
"AI Scan Close",
|
|
||||||
"AI Yell For Help",
|
|
||||||
"AI Cast Beneficial Close",
|
|
||||||
"AOE Cast",
|
|
||||||
"Entity Management",
|
|
||||||
"Flee",
|
|
||||||
"Aura",
|
|
||||||
"HotReload",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "eqemu_logsys_log_aliases.h"
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
|
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||||
|
LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define LogF(debug_level, log_category, message, ...) do {\
|
||||||
|
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||||
|
OutF(LogSys, debug_level, log_category, message, ##__VA_ARGS__);\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
class EQEmuLogSys {
|
class EQEmuLogSys {
|
||||||
public:
|
public:
|
||||||
@@ -205,10 +177,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void CloseFileLogs();
|
void CloseFileLogs();
|
||||||
void LoadLogSettingsDefaults();
|
void LoadLogSettingsDefaults();
|
||||||
|
|
||||||
/**
|
|
||||||
* @param directory_name
|
|
||||||
*/
|
|
||||||
void MakeDirectory(const std::string &directory_name);
|
void MakeDirectory(const std::string &directory_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -220,25 +188,12 @@ public:
|
|||||||
* - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
|
* - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would
|
||||||
* be checked against to see if that piped output is set to actually process it for the category and debug level
|
* be checked against to see if that piped output is set to actually process it for the category and debug level
|
||||||
*/
|
*/
|
||||||
void Out(
|
void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...);
|
||||||
Logs::DebugLevel debug_level,
|
|
||||||
uint16 log_category,
|
|
||||||
const char *file,
|
|
||||||
const char *func,
|
|
||||||
int line,
|
|
||||||
const char *message,
|
|
||||||
...
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used in file logs to prepend a timestamp entry for logs
|
* Used in file logs to prepend a timestamp entry for logs
|
||||||
* @param time_stamp
|
|
||||||
*/
|
*/
|
||||||
void SetCurrentTimeStamp(char* time_stamp);
|
void SetCurrentTimeStamp(char* time_stamp);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param log_name
|
|
||||||
*/
|
|
||||||
void StartFileLogs(const std::string &log_name = "");
|
void StartFileLogs(const std::string &log_name = "");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,14 +218,14 @@ public:
|
|||||||
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
* These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults
|
||||||
* Database loaded via Database::LoadLogSettings(log_settings)
|
* Database loaded via Database::LoadLogSettings(log_settings)
|
||||||
*/
|
*/
|
||||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
LogSettings log_settings[Logs::LogCategory::MaxCategoryID];
|
||||||
|
|
||||||
bool file_logs_enabled = false;
|
bool file_logs_enabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets Executable platform (Zone/World/UCS) etc.
|
* Sets Executable platform (Zone/World/UCS) etc.
|
||||||
*/
|
*/
|
||||||
int log_platform = 0;
|
int log_platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File name used in writing logs
|
* File name used in writing logs
|
||||||
@@ -285,25 +240,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
uint16 GetGMSayColorFromCategory(uint16 log_category);
|
||||||
|
|
||||||
/**
|
void OnLogHookCallBackZone(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
|
||||||
* @param f
|
|
||||||
*/
|
|
||||||
void SetGMSayHandler(std::function<void(uint16 log_type, const std::string&)> f) { on_log_gmsay_hook = f; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param f
|
|
||||||
*/
|
|
||||||
void SetConsoleHandler(std::function<void(uint16 debug_level, uint16 log_type, const std::string&)> f) { on_log_console_hook = f; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Silence console logging
|
|
||||||
*/
|
|
||||||
void SilenceConsoleLogging();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turn on all console logging
|
|
||||||
*/
|
|
||||||
void EnableConsoleLogging();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -311,7 +248,6 @@ private:
|
|||||||
* Callback pointer to zone process for hooking logs to zone using GMSay
|
* Callback pointer to zone process for hooking logs to zone using GMSay
|
||||||
*/
|
*/
|
||||||
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook;
|
std::function<void(uint16 log_category, const std::string&)> on_log_gmsay_hook;
|
||||||
std::function<void(uint16 debug_level, uint16 log_category, const std::string&)> on_log_console_hook;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats log messages like '[Category] This is a log message'
|
* Formats log messages like '[Category] This is a log message'
|
||||||
@@ -320,7 +256,6 @@ private:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Linux console color messages mapped by category
|
* Linux console color messages mapped by category
|
||||||
*
|
|
||||||
* @param log_category
|
* @param log_category
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -331,57 +266,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param debug_level
|
|
||||||
* @param log_category
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
|
void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param debug_level
|
|
||||||
* @param log_category
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
|
void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param debug_level
|
|
||||||
* @param log_category
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
|
void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param log_category
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool IsRfc5424LogCategory(uint16 log_category);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern EQEmuLogSys LogSys;
|
extern EQEmuLogSys LogSys;
|
||||||
|
|
||||||
/**
|
|
||||||
template<typename... Args>
|
|
||||||
void OutF(
|
|
||||||
EQEmuLogSys &ls,
|
|
||||||
Logs::DebugLevel debug_level,
|
|
||||||
uint16 log_category,
|
|
||||||
const char *file,
|
|
||||||
const char *func,
|
|
||||||
int line,
|
|
||||||
const char *fmt,
|
|
||||||
const Args &... args
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::string log_str = fmt::format(fmt, args...);
|
|
||||||
ls.Out(debug_level, log_category, file, func, line, log_str.c_str());
|
|
||||||
}
|
|
||||||
**/
|
|
||||||
|
|
||||||
#define OutF(ls, debug_level, log_category, file, func, line, formatStr, ...) \
|
|
||||||
do { \
|
|
||||||
ls.Out(debug_level, log_category, file, func, line, fmt::format(formatStr, ##__VA_ARGS__).c_str()); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* EQEmulator: Everquest Server Emulator
|
* EQEmulator: Everquest Server Emulator
|
||||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,15 +18,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_FILE_UTIL_H
|
#pragma once
|
||||||
#define EQEMU_FILE_UTIL_H
|
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
class FileUtil {
|
template <typename... Args>
|
||||||
public:
|
void OutF(EQEmuLogSys &ls, Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args)
|
||||||
static bool exists(const std::string &name);
|
{
|
||||||
static void mkdir(const std::string& directory_name);
|
std::string log_str = fmt::format(fmt, args...);
|
||||||
};
|
ls.Out(debug_level, log_category, log_str);
|
||||||
|
}
|
||||||
|
|
||||||
#endif //EQEMU_FILE_UTIL_H
|
|
||||||
@@ -1,920 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
|
||||||
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
|
||||||
|
|
||||||
#ifdef BUILD_LOGGING
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RFC 5424
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LogEmergency(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Emergency].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Emergency, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAlert(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Alert].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Alert, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCritical(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Critical].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Critical, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogError(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Error].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogWarning(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Warning].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNotice(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Notice].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Notice, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogInfo(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Info].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogDebug(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Debug].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Category
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LogAA(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AA].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAADetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AA].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::AA, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAI(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AI].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AI].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::AI, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAggro(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Aggro].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAggroDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Aggro].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Aggro, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAttack(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Attack].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAttackDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Attack].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Attack, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPacketClientServer(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPacketClientServerDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::PacketClientServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCombat(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Combat].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCombatDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Combat].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Combat, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCommands(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Commands].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCommandsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Commands].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Commands, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCrash(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Crash].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCrashDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Crash].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Crash, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogDoors(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Doors].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogDoorsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Doors].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Doors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogGuilds(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Guilds].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogGuildsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Guilds].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Guilds, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogInventory(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Inventory].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogInventoryDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Inventory].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Inventory, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLauncher(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Launcher].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLauncherDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Launcher].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Launcher, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNetcode(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Netcode].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNetcodeDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Netcode].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Netcode, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNormal(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Normal].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNormalDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Normal].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Normal, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogObject(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Object].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogObjectDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Object].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Object, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPathing(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Pathing].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPathingDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Pathing].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Pathing, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQSServer(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::QSServer].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQSServerDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::QSServer].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::QSServer, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuests(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Quests].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuestsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Quests].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Quests, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogRules(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Rules].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogRulesDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Rules].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Rules, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSkills(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Skills].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSkillsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Skills].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Skills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpawns(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Spawns].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpawnsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Spawns].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Spawns, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpells(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Spells].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpellsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Spells].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Spells, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTCPConnection(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::TCPConnection].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTCPConnectionDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::TCPConnection].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::TCPConnection, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTasks(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Tasks].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTasksDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Tasks].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Tasks, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTradeskills(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Tradeskills].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTradeskillsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Tradeskills].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Tradeskills, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTrading(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Trading].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTradingDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Trading].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Trading, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTribute(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Tribute].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTributeDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Tribute].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Tribute, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLError(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLErrorDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::MySQLError, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLQuery(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLQueryDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::MySQLQuery, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMercenaries(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Mercenaries].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMercenariesDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Mercenaries].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Mercenaries, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuestDebug(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::QuestDebug].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuestDebugDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::QuestDebug].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::QuestDebug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLoginserver(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Loginserver].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLoginserverDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Loginserver].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Loginserver, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogClientLogin(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::ClientLogin].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogClientLoginDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::ClientLogin].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::ClientLogin, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHeadlessClient(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::HeadlessClient].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHeadlessClientDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::HeadlessClient].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::HeadlessClient, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHPUpdate(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::HPUpdate].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHPUpdateDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::HPUpdate].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::HPUpdate, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFixZ(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::FixZ].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFixZDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::FixZ].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::FixZ, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFood(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Food].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFoodDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Food].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Food, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTraps(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Traps].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTrapsDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Traps].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Traps, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCRoamBox(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::NPCRoamBox].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCRoamBoxDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::NPCRoamBox].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::NPCRoamBox, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCScaling(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::NPCScaling].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCScalingDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::NPCScaling].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::NPCScaling, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMobAppearance(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::MobAppearance].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMobAppearanceDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::MobAppearance].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::MobAppearance, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogStatus(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogStatusDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIScanClose(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AIScanClose].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIScanCloseDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AIScanClose].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::AIScanClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIYellForHelp(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AIYellForHelp].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIYellForHelpDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AIYellForHelp].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::AIYellForHelp, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAICastBeneficialClose(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AICastBeneficialClose].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAICastBeneficialCloseDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AICastBeneficialClose].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAoeCast(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAoeCastDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogEntityManagement(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogEntityManagementDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFlee(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Flee].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFleeDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Flee].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Flee, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAura(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Aura].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::Aura, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAuraDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::Aura].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::Aura, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHotReload(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::HotReload].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::General, Logs::HotReload, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHotReloadDetail(message, ...) do {\
|
|
||||||
if (LogSys.log_settings[Logs::HotReload].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, Logs::Detail, Logs::HotReload, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
|
||||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogF(debug_level, log_category, message, ...) do {\
|
|
||||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
|
||||||
OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define LogEmergency(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAlert(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCritical(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogError(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogWarning(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNotice(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogInfo(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogDebug(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Category
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LogAA(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAADetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAI(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAggro(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAggroDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAttack(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAttackDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPacketClientServer(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPacketClientServerDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCombat(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCombatDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCommands(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCommandsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCrash(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogCrashDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogDoors(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogDoorsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogGuilds(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogGuildsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogInventory(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogInventoryDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLauncher(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLauncherDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNetcode(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNetcodeDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNormal(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNormalDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogObject(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogObjectDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPathing(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogPathingDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQSServer(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQSServerDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuests(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuestsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogRules(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogRulesDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSkills(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSkillsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpawns(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpawnsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpells(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogSpellsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTCPConnection(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTCPConnectionDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTasks(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTasksDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTradeskills(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTradeskillsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTrading(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTradingDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTribute(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTributeDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLError(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLErrorDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLQuery(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMySQLQueryDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMercenaries(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMercenariesDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuestDebug(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogQuestDebugDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLoginserver(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogLoginserverDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogClientLogin(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogClientLoginDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHeadlessClient(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHeadlessClientDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHPUpdate(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHPUpdateDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFixZ(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFixZDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFood(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFoodDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTraps(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogTrapsDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCRoamBox(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCRoamBoxDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCScaling(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogNPCScalingDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMobAppearance(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogMobAppearanceDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogStatus(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogStatusDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIScanClose(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIScanCloseDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIYellForHelp(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAIYellForHelpDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAICastBeneficialClose(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAICastBeneficialCloseDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAoeCast(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAoeCastDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogEntityManagement(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogEntityManagementDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFlee(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogFleeDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAura(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogAuraDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHotReload(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogHotReloadDetail(message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define Log(debug_level, log_category, message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define LogF(debug_level, log_category, message, ...) do {\
|
|
||||||
} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
|
||||||
@@ -8,35 +8,27 @@ namespace EQ
|
|||||||
class EventLoop
|
class EventLoop
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static EventLoop &Get() {
|
EventLoop() {
|
||||||
static thread_local EventLoop inst;
|
memset(&m_loop, 0, sizeof(uv_loop_t));
|
||||||
return inst;
|
uv_loop_init(&m_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
~EventLoop() {
|
~EventLoop() {
|
||||||
uv_loop_close(&m_loop);
|
uv_loop_close(&m_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EventLoop &GetDefault() {
|
||||||
|
static EventLoop inst;
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
void Process() {
|
void Process() {
|
||||||
uv_run(&m_loop, UV_RUN_NOWAIT);
|
uv_run(&m_loop, UV_RUN_NOWAIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run() {
|
|
||||||
uv_run(&m_loop, UV_RUN_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown() {
|
|
||||||
uv_stop(&m_loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_loop_t* Handle() { return &m_loop; }
|
uv_loop_t* Handle() { return &m_loop; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventLoop() {
|
|
||||||
memset(&m_loop, 0, sizeof(uv_loop_t));
|
|
||||||
uv_loop_init(&m_loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventLoop(const EventLoop&);
|
EventLoop(const EventLoop&);
|
||||||
EventLoop& operator=(const EventLoop&);
|
EventLoop& operator=(const EventLoop&);
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -24,7 +24,13 @@ namespace EQ {
|
|||||||
std::exception error;
|
std::exception error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Task(EQ::EventLoop *loop, TaskFn fn) {
|
||||||
|
m_loop = loop;
|
||||||
|
m_fn = fn;
|
||||||
|
}
|
||||||
|
|
||||||
Task(TaskFn fn) {
|
Task(TaskFn fn) {
|
||||||
|
m_loop = &EQ::EventLoop::GetDefault();
|
||||||
m_fn = fn;
|
m_fn = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +66,7 @@ namespace EQ {
|
|||||||
|
|
||||||
m_work->data = baton;
|
m_work->data = baton;
|
||||||
|
|
||||||
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
|
uv_queue_work(m_loop->Handle(), m_work, [](uv_work_t* req) {
|
||||||
TaskBaton *baton = (TaskBaton*)req->data;
|
TaskBaton *baton = (TaskBaton*)req->data;
|
||||||
|
|
||||||
baton->fn([baton](const EQEmu::Any& result) {
|
baton->fn([baton](const EQEmu::Any& result) {
|
||||||
@@ -92,6 +98,7 @@ namespace EQ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
EQ::EventLoop *m_loop;
|
||||||
TaskFn m_fn;
|
TaskFn m_fn;
|
||||||
ResolveFn m_then;
|
ResolveFn m_then;
|
||||||
RejectFn m_catch;
|
RejectFn m_catch;
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <vector>
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <functional>
|
|
||||||
#include <queue>
|
|
||||||
#include <future>
|
|
||||||
|
|
||||||
namespace EQ
|
|
||||||
{
|
|
||||||
namespace Event
|
|
||||||
{
|
|
||||||
class TaskScheduler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const int DefaultThreadCount = 4;
|
|
||||||
|
|
||||||
TaskScheduler() : _running(false)
|
|
||||||
{
|
|
||||||
Start(DefaultThreadCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
TaskScheduler(size_t threads) : _running(false)
|
|
||||||
{
|
|
||||||
Start(threads);
|
|
||||||
}
|
|
||||||
|
|
||||||
~TaskScheduler() {
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Start(size_t threads) {
|
|
||||||
if (true == _running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_running = true;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < threads; ++i) {
|
|
||||||
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop() {
|
|
||||||
if (false == _running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_lock);
|
|
||||||
_running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cv.notify_all();
|
|
||||||
|
|
||||||
for (auto &t : _threads) {
|
|
||||||
t.join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Fn, typename... Args>
|
|
||||||
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::result_of<Fn(Args...)>::type> {
|
|
||||||
using return_type = typename std::result_of<Fn(Args...)>::type;
|
|
||||||
|
|
||||||
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
|
||||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::future<return_type> res = task->get_future();
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_lock);
|
|
||||||
|
|
||||||
if (false == _running) {
|
|
||||||
throw std::runtime_error("Enqueue on stopped scheduler.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_tasks.emplace([task]() { (*task)(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
_cv.notify_one();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ProcessWork() {
|
|
||||||
for (;;) {
|
|
||||||
std::function<void()> work;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_lock);
|
|
||||||
_cv.wait(lock, [this] { return !_running || !_tasks.empty(); });
|
|
||||||
|
|
||||||
if (false == _running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
work = std::move(_tasks.front());
|
|
||||||
_tasks.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
work();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _running = true;
|
|
||||||
std::vector<std::thread> _threads;
|
|
||||||
std::mutex _lock;
|
|
||||||
std::condition_variable _cv;
|
|
||||||
std::queue<std::function<void()>> _tasks;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+20
-2
@@ -6,14 +6,31 @@ namespace EQ {
|
|||||||
class Timer
|
class Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Timer(std::function<void(Timer *)> cb)
|
Timer(EQ::EventLoop *loop, std::function<void(Timer *)> cb)
|
||||||
{
|
{
|
||||||
|
m_loop = loop;
|
||||||
m_timer = nullptr;
|
m_timer = nullptr;
|
||||||
m_cb = cb;
|
m_cb = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer(std::function<void(Timer *)> cb)
|
||||||
|
{
|
||||||
|
m_loop = &EQ::EventLoop::GetDefault();
|
||||||
|
m_timer = nullptr;
|
||||||
|
m_cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer(EQ::EventLoop *loop, uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb)
|
||||||
|
{
|
||||||
|
m_loop = loop;
|
||||||
|
m_timer = nullptr;
|
||||||
|
m_cb = cb;
|
||||||
|
Start(duration_ms, repeats);
|
||||||
|
}
|
||||||
|
|
||||||
Timer(uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb)
|
Timer(uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb)
|
||||||
{
|
{
|
||||||
|
m_loop = &EQ::EventLoop::GetDefault();
|
||||||
m_timer = nullptr;
|
m_timer = nullptr;
|
||||||
m_cb = cb;
|
m_cb = cb;
|
||||||
Start(duration_ms, repeats);
|
Start(duration_ms, repeats);
|
||||||
@@ -25,7 +42,7 @@ namespace EQ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Start(uint64_t duration_ms, bool repeats) {
|
void Start(uint64_t duration_ms, bool repeats) {
|
||||||
auto loop = EventLoop::Get().Handle();
|
auto loop = m_loop->Handle();
|
||||||
if (!m_timer) {
|
if (!m_timer) {
|
||||||
m_timer = new uv_timer_t;
|
m_timer = new uv_timer_t;
|
||||||
memset(m_timer, 0, sizeof(uv_timer_t));
|
memset(m_timer, 0, sizeof(uv_timer_t));
|
||||||
@@ -61,6 +78,7 @@ namespace EQ {
|
|||||||
m_cb(this);
|
m_cb(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EQ::EventLoop *m_loop;
|
||||||
uv_timer_t *m_timer;
|
uv_timer_t *m_timer;
|
||||||
std::function<void(Timer*)> m_cb;
|
std::function<void(Timer*)> m_cb;
|
||||||
};
|
};
|
||||||
|
|||||||
+11
-9
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include "faction.h"
|
#include "faction.h"
|
||||||
#include "races.h"
|
#include "races.h"
|
||||||
#include "rulesys.h"
|
|
||||||
|
|
||||||
const char *FactionValueToString(FACTION_VALUE fv)
|
const char *FactionValueToString(FACTION_VALUE fv)
|
||||||
{
|
{
|
||||||
@@ -60,31 +59,34 @@ FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value)
|
|||||||
if (fm) {
|
if (fm) {
|
||||||
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
|
character_value += fm->base + fm->class_mod + fm->race_mod + fm->deity_mod;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, AllyFactionMinimum)) {
|
if (character_value >= 1100) {
|
||||||
return FACTION_ALLY;
|
return FACTION_ALLY;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, WarmlyFactionMinimum)) {
|
if (character_value >= 750 && character_value <= 1099) {
|
||||||
return FACTION_WARMLY;
|
return FACTION_WARMLY;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, KindlyFactionMinimum)) {
|
if (character_value >= 500 && character_value <= 749) {
|
||||||
return FACTION_KINDLY;
|
return FACTION_KINDLY;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, AmiablyFactionMinimum)) {
|
if (character_value >= 100 && character_value <= 499) {
|
||||||
return FACTION_AMIABLE;
|
return FACTION_AMIABLE;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, IndifferentlyFactionMinimum)) {
|
if (character_value >= 0 && character_value <= 99) {
|
||||||
return FACTION_INDIFFERENT;
|
return FACTION_INDIFFERENT;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, ApprehensivelyFactionMinimum)) {
|
if (character_value >= -100 && character_value <= -1) {
|
||||||
return FACTION_APPREHENSIVE;
|
return FACTION_APPREHENSIVE;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, DubiouslyFactionMinimum)) {
|
if (character_value >= -500 && character_value <= -101) {
|
||||||
return FACTION_DUBIOUS;
|
return FACTION_DUBIOUS;
|
||||||
}
|
}
|
||||||
if (character_value >= RuleI(Faction, ThreateninglyFactionMinimum)) {
|
if (character_value >= -750 && character_value <= -501) {
|
||||||
return FACTION_THREATENLY;
|
return FACTION_THREATENLY;
|
||||||
}
|
}
|
||||||
|
if (character_value <= -751) {
|
||||||
return FACTION_SCOWLS;
|
return FACTION_SCOWLS;
|
||||||
|
}
|
||||||
|
return FACTION_INDIFFERENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function should check if some races have more than one race define
|
// this function should check if some races have more than one race define
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include "file_util.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#include <direct.h>
|
|
||||||
#include <conio.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <dos.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <process.h>
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool FileUtil::exists(const std::string &name)
|
|
||||||
{
|
|
||||||
std::ifstream f(name.c_str());
|
|
||||||
|
|
||||||
return f.good();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param directory_name
|
|
||||||
*/
|
|
||||||
void FileUtil::mkdir(const std::string& directory_name)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
struct _stat st;
|
|
||||||
if (_stat(directory_name.c_str(), &st) == 0) // exists
|
|
||||||
return;
|
|
||||||
_mkdir(directory_name.c_str());
|
|
||||||
#else
|
|
||||||
struct stat st{};
|
|
||||||
if (stat(directory_name.c_str(), &st) == 0) { // exists
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
::mkdir(directory_name.c_str(), 0755);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
+47
-47
@@ -46,7 +46,7 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
ClearGuilds();
|
ClearGuilds();
|
||||||
|
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to load guilds when we have no database object");
|
Log(Logs::Detail, Logs::Guilds, "Requested to load guilds when we have no database object.");
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,13 +77,13 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
uint8 rankn = atoi(row[1]);
|
uint8 rankn = atoi(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Found invalid (too high) rank %d for guild %d, skipping.", rankn, guild_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = m_guilds.find(guild_id);
|
res = m_guilds.find(guild_id);
|
||||||
if(res == m_guilds.end()) {
|
if(res == m_guilds.end()) {
|
||||||
LogGuilds("Found rank [{}] for non-existent guild [{}], skipping", rankn, guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Found rank %d for non-existent guild %d, skipping.", rankn, guild_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
|
|
||||||
bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to refresh guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to refresh guild %d when we have no database object.", guild_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
if (results.RowCount() == 0)
|
if (results.RowCount() == 0)
|
||||||
{
|
{
|
||||||
LogGuilds("Unable to find guild [{}] in the database", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Unable to find guild %d in the database.", guild_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
uint8 rankn = atoi(row[1]);
|
uint8 rankn = atoi(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Found invalid (too high) rank %d for guild %d, skipping.", rankn, guild_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
rank.permissions[GUILD_WARPEACE] = (row[10][0] == '1') ? true: false;
|
rank.permissions[GUILD_WARPEACE] = (row[10][0] == '1') ? true: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogGuilds("Successfully refreshed guild [{}] from the database", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Successfully refreshed guild %d from the database.", guild_id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -214,14 +214,14 @@ BaseGuildManager::GuildInfo *BaseGuildManager::_CreateGuild(uint32 guild_id, con
|
|||||||
|
|
||||||
bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to store guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to store guild %d when we have no database object.", guild_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||||
res = m_guilds.find(guild_id);
|
res = m_guilds.find(guild_id);
|
||||||
if(res == m_guilds.end()) {
|
if(res == m_guilds.end()) {
|
||||||
LogGuilds("Requested to store non-existent guild [{}]", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to store non-existent guild %d", guild_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
GuildInfo *info = res->second;
|
GuildInfo *info = res->second;
|
||||||
@@ -289,14 +289,14 @@ bool BaseGuildManager::_StoreGuildDB(uint32 guild_id) {
|
|||||||
safe_delete_array(title_esc);
|
safe_delete_array(title_esc);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogGuilds("Stored guild [{}] in the database", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Stored guild %d in the database", guild_id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 BaseGuildManager::_GetFreeGuildID() {
|
uint32 BaseGuildManager::_GetFreeGuildID() {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested find a free guild ID when we have no database object");
|
Log(Logs::Detail, Logs::Guilds, "Requested find a free guild ID when we have no database object.");
|
||||||
return(GUILD_NONE);
|
return(GUILD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,12 +330,12 @@ uint32 BaseGuildManager::_GetFreeGuildID() {
|
|||||||
|
|
||||||
if (results.RowCount() == 0)
|
if (results.RowCount() == 0)
|
||||||
{
|
{
|
||||||
LogGuilds("Located free guild ID [{}] in the database", index);
|
Log(Logs::Detail, Logs::Guilds, "Located free guild ID %d in the database", index);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogGuilds("Unable to find a free guild ID when requested");
|
Log(Logs::Detail, Logs::Guilds, "Unable to find a free guild ID when requested.");
|
||||||
return GUILD_NONE;
|
return GUILD_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,11 +505,11 @@ uint32 BaseGuildManager::DBCreateGuild(const char* name, uint32 leader) {
|
|||||||
|
|
||||||
//now store the resulting guild setup into the DB.
|
//now store the resulting guild setup into the DB.
|
||||||
if(!_StoreGuildDB(new_id)) {
|
if(!_StoreGuildDB(new_id)) {
|
||||||
LogGuilds("Error storing new guild. It may have been partially created which may need manual removal");
|
Log(Logs::Detail, Logs::Guilds, "Error storing new guild. It may have been partially created which may need manual removal.");
|
||||||
return(GUILD_NONE);
|
return(GUILD_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogGuilds("Created guild [{}] in the database", new_id);
|
Log(Logs::Detail, Logs::Guilds, "Created guild %d in the database.", new_id);
|
||||||
|
|
||||||
return(new_id);
|
return(new_id);
|
||||||
}
|
}
|
||||||
@@ -525,7 +525,7 @@ bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to delete guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to delete guild %d when we have no database object.", guild_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,14 +545,14 @@ bool BaseGuildManager::DBDeleteGuild(uint32 guild_id) {
|
|||||||
query = StringFormat("DELETE FROM guild_bank WHERE guildid=%lu", (unsigned long)guild_id);
|
query = StringFormat("DELETE FROM guild_bank WHERE guildid=%lu", (unsigned long)guild_id);
|
||||||
QueryWithLogging(query, "deleting guild bank");
|
QueryWithLogging(query, "deleting guild bank");
|
||||||
|
|
||||||
LogGuilds("Deleted guild [{}] from the database", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Deleted guild %d from the database.", guild_id);
|
||||||
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to rename guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to rename guild %d when we have no database object.", guild_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,13 +573,13 @@ bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
|||||||
|
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
{
|
{
|
||||||
LogGuilds("Error renaming guild [{}] [{}]: [{}]", guild_id, query.c_str(), results.Success());
|
Log(Logs::Detail, Logs::Guilds, "Error renaming guild %d '%s': %s", guild_id, query.c_str(), results.Success());
|
||||||
safe_delete_array(esc);
|
safe_delete_array(esc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
safe_delete_array(esc);
|
safe_delete_array(esc);
|
||||||
|
|
||||||
LogGuilds("Renamed guild [{}] ([{}]) to [{}] in database", info->name.c_str(), guild_id, name);
|
Log(Logs::Detail, Logs::Guilds, "Renamed guild %s (%d) to %s in database.", info->name.c_str(), guild_id, name);
|
||||||
|
|
||||||
info->name = name; //update our local record.
|
info->name = name; //update our local record.
|
||||||
|
|
||||||
@@ -588,7 +588,7 @@ bool BaseGuildManager::DBRenameGuild(uint32 guild_id, const char* name) {
|
|||||||
|
|
||||||
bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to set the leader for guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to set the leader for guild %d when we have no database object.", guild_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,7 +614,7 @@ bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
|||||||
if(!DBSetGuildRank(leader, GUILD_LEADER))
|
if(!DBSetGuildRank(leader, GUILD_LEADER))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LogGuilds("Set guild leader for guild [{}] to [{}] in the database", guild_id, leader);
|
Log(Logs::Detail, Logs::Guilds, "Set guild leader for guild %d to %d in the database", guild_id, leader);
|
||||||
|
|
||||||
info->leader_char_id = leader; //update our local record.
|
info->leader_char_id = leader; //update our local record.
|
||||||
|
|
||||||
@@ -623,7 +623,7 @@ bool BaseGuildManager::DBSetGuildLeader(uint32 guild_id, uint32 leader) {
|
|||||||
|
|
||||||
bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
|
bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const char *setter) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to set the MOTD for guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to set the MOTD for guild %d when we have no database object.", guild_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,7 +654,7 @@ bool BaseGuildManager::DBSetGuildMOTD(uint32 guild_id, const char* motd, const c
|
|||||||
safe_delete_array(esc);
|
safe_delete_array(esc);
|
||||||
safe_delete_array(esc_set);
|
safe_delete_array(esc_set);
|
||||||
|
|
||||||
LogGuilds("Set MOTD for guild [{}] in the database", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Set MOTD for guild %d in the database", guild_id);
|
||||||
|
|
||||||
info->motd = motd; //update our local record.
|
info->motd = motd; //update our local record.
|
||||||
info->motd_setter = setter; //update our local record.
|
info->motd_setter = setter; //update our local record.
|
||||||
@@ -688,7 +688,7 @@ bool BaseGuildManager::DBSetGuildURL(uint32 GuildID, const char* URL)
|
|||||||
}
|
}
|
||||||
safe_delete_array(esc);
|
safe_delete_array(esc);
|
||||||
|
|
||||||
LogGuilds("Set URL for guild [{}] in the database", GuildID);
|
Log(Logs::Detail, Logs::Guilds, "Set URL for guild %d in the database", GuildID);
|
||||||
|
|
||||||
info->url = URL; //update our local record.
|
info->url = URL; //update our local record.
|
||||||
|
|
||||||
@@ -722,7 +722,7 @@ bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
|
|||||||
}
|
}
|
||||||
safe_delete_array(esc);
|
safe_delete_array(esc);
|
||||||
|
|
||||||
LogGuilds("Set Channel for guild [{}] in the database", GuildID);
|
Log(Logs::Detail, Logs::Guilds, "Set Channel for guild %d in the database", GuildID);
|
||||||
|
|
||||||
info->channel = Channel; //update our local record.
|
info->channel = Channel; //update our local record.
|
||||||
|
|
||||||
@@ -731,7 +731,7 @@ bool BaseGuildManager::DBSetGuildChannel(uint32 GuildID, const char* Channel)
|
|||||||
|
|
||||||
bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested to set char to guild [{}] when we have no database object", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested to set char to guild %d when we have no database object.", guild_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,7 +753,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LogGuilds("Set char [{}] to guild [{}] and rank [{}] in the database", charid, guild_id, rank);
|
Log(Logs::Detail, Logs::Guilds, "Set char %d to guild %d and rank %d in the database.", charid, guild_id, rank);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,7 +845,7 @@ bool BaseGuildManager::DBSetPublicNote(uint32 charid, const char* note) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogGuilds("Set public not for char [{}]", charid);
|
Log(Logs::Detail, Logs::Guilds, "Set public not for char %d", charid);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -912,7 +912,7 @@ bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo
|
|||||||
return(false);
|
return(false);
|
||||||
|
|
||||||
//load up the rank info for each guild.
|
//load up the rank info for each guild.
|
||||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE g.guild_id=%d AND c.deleted_at IS NULL", guild_id);
|
std::string query = StringFormat(GuildMemberBaseQuery " WHERE g.guild_id=%d", guild_id);
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -924,14 +924,14 @@ bool BaseGuildManager::GetEntireGuild(uint32 guild_id, std::vector<CharGuildInfo
|
|||||||
members.push_back(ci);
|
members.push_back(ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogGuilds("Retreived entire guild member list for guild [{}] from the database", guild_id);
|
Log(Logs::Detail, Logs::Guilds, "Retreived entire guild member list for guild %d from the database", guild_id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested char info on [{}] when we have no database object", char_name);
|
Log(Logs::Detail, Logs::Guilds, "Requested char info on %s when we have no database object.", char_name);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +941,7 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
|||||||
m_db->DoEscapeString(esc, char_name, nl);
|
m_db->DoEscapeString(esc, char_name, nl);
|
||||||
|
|
||||||
//load up the rank info for each guild.
|
//load up the rank info for each guild.
|
||||||
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.name='%s' AND c.deleted_at IS NULL", esc);
|
std::string query = StringFormat(GuildMemberBaseQuery " WHERE c.name='%s'", esc);
|
||||||
safe_delete_array(esc);
|
safe_delete_array(esc);
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -953,7 +953,7 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
ProcessGuildMember(row, into);
|
ProcessGuildMember(row, into);
|
||||||
LogGuilds("Retreived guild member info for char [{}] from the database", char_name);
|
Log(Logs::Detail, Logs::Guilds, "Retreived guild member info for char %s from the database", char_name);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -962,16 +962,16 @@ bool BaseGuildManager::GetCharInfo(const char *char_name, CharGuildInfo &into) {
|
|||||||
|
|
||||||
bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
||||||
if(m_db == nullptr) {
|
if(m_db == nullptr) {
|
||||||
LogGuilds("Requested char info on [{}] when we have no database object", char_id);
|
Log(Logs::Detail, Logs::Guilds, "Requested char info on %d when we have no database object.", char_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//load up the rank info for each guild.
|
//load up the rank info for each guild.
|
||||||
std::string query;
|
std::string query;
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C' AND c.deleted_at IS NULL", char_id);
|
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.mob_type = 'C'", char_id);
|
||||||
#else
|
#else
|
||||||
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d AND c.deleted_at IS NULL", char_id);
|
query = StringFormat(GuildMemberBaseQuery " WHERE c.id=%d", char_id);
|
||||||
#endif
|
#endif
|
||||||
auto results = m_db->QueryDatabase(query);
|
auto results = m_db->QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
@@ -983,7 +983,7 @@ bool BaseGuildManager::GetCharInfo(uint32 char_id, CharGuildInfo &into) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
ProcessGuildMember(row, into);
|
ProcessGuildMember(row, into);
|
||||||
LogGuilds("Retreived guild member info for char [{}]", char_id);
|
Log(Logs::Detail, Logs::Guilds, "Retreived guild member info for char %d", char_id);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -1098,16 +1098,16 @@ bool BaseGuildManager::GuildExists(uint32 guild_id) const {
|
|||||||
|
|
||||||
bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
|
bool BaseGuildManager::IsGuildLeader(uint32 guild_id, uint32 char_id) const {
|
||||||
if(guild_id == GUILD_NONE) {
|
if(guild_id == GUILD_NONE) {
|
||||||
LogGuilds("Check leader for char [{}]: not a guild", char_id);
|
Log(Logs::Detail, Logs::Guilds, "Check leader for char %d: not a guild.", char_id);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||||
res = m_guilds.find(guild_id);
|
res = m_guilds.find(guild_id);
|
||||||
if(res == m_guilds.end()) {
|
if(res == m_guilds.end()) {
|
||||||
LogGuilds("Check leader for char [{}]: invalid guild", char_id);
|
Log(Logs::Detail, Logs::Guilds, "Check leader for char %d: invalid guild.", char_id);
|
||||||
return(false); //invalid guild
|
return(false); //invalid guild
|
||||||
}
|
}
|
||||||
LogGuilds("Check leader for guild [{}], char [{}]: leader id=[{}]", guild_id, char_id, res->second->leader_char_id);
|
Log(Logs::Detail, Logs::Guilds, "Check leader for guild %d, char %d: leader id=%d", guild_id, char_id, res->second->leader_char_id);
|
||||||
return(char_id == res->second->leader_char_id);
|
return(char_id == res->second->leader_char_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,20 +1137,20 @@ uint8 BaseGuildManager::GetDisplayedRank(uint32 guild_id, uint8 rank, uint32 cha
|
|||||||
|
|
||||||
bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
|
bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
|
||||||
if(status >= 250) {
|
if(status >= 250) {
|
||||||
LogGuilds("Check permission on guild [{}] with user status [{}] > 250, granted", guild_id, status);
|
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d with user status %d > 250, granted.", guild_id, status);
|
||||||
return(true); //250+ as allowed anything
|
return(true); //250+ as allowed anything
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||||
res = m_guilds.find(guild_id);
|
res = m_guilds.find(guild_id);
|
||||||
if(res == m_guilds.end()) {
|
if(res == m_guilds.end()) {
|
||||||
LogGuilds("Check permission on guild [{}] with user status [{}], no such guild, denied", guild_id, status);
|
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d with user status %d, no such guild, denied.", guild_id, status);
|
||||||
return(false); //invalid guild
|
return(false); //invalid guild
|
||||||
}
|
}
|
||||||
|
|
||||||
bool granted = (res->second->minstatus <= status);
|
bool granted = (res->second->minstatus <= status);
|
||||||
|
|
||||||
LogGuilds("Check permission on guild [{}] ([{}]) with user status [{}]. Min status [{}]: [{}]",
|
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %s (%d) with user status %d. Min status %d: %s",
|
||||||
res->second->name.c_str(), guild_id, status, res->second->minstatus, granted?"granted":"denied");
|
res->second->name.c_str(), guild_id, status, res->second->minstatus, granted?"granted":"denied");
|
||||||
|
|
||||||
return(granted);
|
return(granted);
|
||||||
@@ -1158,21 +1158,21 @@ bool BaseGuildManager::CheckGMStatus(uint32 guild_id, uint8 status) const {
|
|||||||
|
|
||||||
bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const {
|
bool BaseGuildManager::CheckPermission(uint32 guild_id, uint8 rank, GuildAction act) const {
|
||||||
if(rank > GUILD_MAX_RANK) {
|
if(rank > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Check permission on guild [{}] and rank [{}] for action [{}] ([{}]): Invalid rank, denied",
|
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d and rank %d for action %s (%d): Invalid rank, denied.",
|
||||||
guild_id, rank, GuildActionNames[act], act);
|
guild_id, rank, GuildActionNames[act], act);
|
||||||
return(false); //invalid rank
|
return(false); //invalid rank
|
||||||
}
|
}
|
||||||
std::map<uint32, GuildInfo *>::const_iterator res;
|
std::map<uint32, GuildInfo *>::const_iterator res;
|
||||||
res = m_guilds.find(guild_id);
|
res = m_guilds.find(guild_id);
|
||||||
if(res == m_guilds.end()) {
|
if(res == m_guilds.end()) {
|
||||||
LogGuilds("Check permission on guild [{}] and rank [{}] for action [{}] ([{}]): Invalid guild, denied",
|
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %d and rank %d for action %s (%d): Invalid guild, denied.",
|
||||||
guild_id, rank, GuildActionNames[act], act);
|
guild_id, rank, GuildActionNames[act], act);
|
||||||
return(false); //invalid guild
|
return(false); //invalid guild
|
||||||
}
|
}
|
||||||
|
|
||||||
bool granted = res->second->ranks[rank].permissions[act];
|
bool granted = res->second->ranks[rank].permissions[act];
|
||||||
|
|
||||||
LogGuilds("Check permission on guild [{}] ([{}]) and rank [{}] ([{}]) for action [{}] ([{}]): [{}]",
|
Log(Logs::Detail, Logs::Guilds, "Check permission on guild %s (%d) and rank %s (%d) for action %s (%d): %s",
|
||||||
res->second->name.c_str(), guild_id,
|
res->second->name.c_str(), guild_id,
|
||||||
res->second->ranks[rank].name.c_str(), rank,
|
res->second->ranks[rank].name.c_str(), rank,
|
||||||
GuildActionNames[act], act,
|
GuildActionNames[act], act,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1381,7 +1381,7 @@ int16 EQEmu::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == INVALID_INDEX) {
|
if (result == INVALID_INDEX) {
|
||||||
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
Log(Logs::General, Logs::Error, "InventoryProfile::_PutItem: Invalid slot_id specified (%i) with parent slot id (%i)", slot_id, parentSlot);
|
||||||
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
/**
|
|
||||||
* EQEmulator: Everquest Server Emulator
|
|
||||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; version 2 of the License.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
* are required to give you total support for your newly bought product;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ip_util.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
uint32_t IpUtil::IPToUInt(const std::string &ip)
|
|
||||||
{
|
|
||||||
int a, b, c, d;
|
|
||||||
uint32_t addr = 0;
|
|
||||||
|
|
||||||
if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = a << 24;
|
|
||||||
addr |= b << 16;
|
|
||||||
addr |= c << 8;
|
|
||||||
addr |= d;
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* @param network
|
|
||||||
* @param mask
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool IpUtil::IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask)
|
|
||||||
{
|
|
||||||
uint32_t ip_addr = IpUtil::IPToUInt(ip);
|
|
||||||
uint32_t network_addr = IpUtil::IPToUInt(network);
|
|
||||||
uint32_t mask_addr = IpUtil::IPToUInt(mask);
|
|
||||||
|
|
||||||
uint32_t net_lower = (network_addr & mask_addr);
|
|
||||||
uint32_t net_upper = (net_lower | (~mask_addr));
|
|
||||||
|
|
||||||
return ip_addr >= net_lower && ip_addr <= net_upper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
IpUtil::IsIpInRange(ip, "10.0.0.0", "255.0.0.0") ||
|
|
||||||
IpUtil::IsIpInRange(ip, "172.16.0.0", "255.240.0.0") ||
|
|
||||||
IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
+1
-1
@@ -413,7 +413,7 @@ namespace EQEmu
|
|||||||
int32 SkillModMax; // Max skill point modification
|
int32 SkillModMax; // Max skill point modification
|
||||||
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
||||||
uint32 BaneDmgRace; // Bane Damage Race
|
uint32 BaneDmgRace; // Bane Damage Race
|
||||||
int32 BaneDmgAmt; // Bane Damage Body Amount
|
int8 BaneDmgAmt; // Bane Damage Body Amount
|
||||||
uint32 BaneDmgBody; // Bane Damage Body
|
uint32 BaneDmgBody; // Bane Damage Body
|
||||||
bool Magic; // True=Magic Item, False=not
|
bool Magic; // True=Magic Item, False=not
|
||||||
int32 CastTime_;
|
int32 CastTime_;
|
||||||
|
|||||||
@@ -5277,7 +5277,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings)
|
|||||||
{
|
{
|
||||||
//! [StreamWriterBuilderDefaults]
|
//! [StreamWriterBuilderDefaults]
|
||||||
(*settings)["commentStyle"] = "All";
|
(*settings)["commentStyle"] = "All";
|
||||||
(*settings)["indentation"] = " ";
|
(*settings)["indentation"] = "\t";
|
||||||
(*settings)["enableYAMLCompatibility"] = false;
|
(*settings)["enableYAMLCompatibility"] = false;
|
||||||
(*settings)["dropNullPlaceholders"] = false;
|
(*settings)["dropNullPlaceholders"] = false;
|
||||||
(*settings)["useSpecialFloats"] = false;
|
(*settings)["useSpecialFloats"] = false;
|
||||||
|
|||||||
+17
-89
@@ -1,29 +1,26 @@
|
|||||||
#include "json_config.h"
|
#include "json_config.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
EQ::JsonConfigFile::JsonConfigFile() = default;
|
EQ::JsonConfigFile::JsonConfigFile()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
EQ::JsonConfigFile::JsonConfigFile(const Json::Value &value)
|
EQ::JsonConfigFile::JsonConfigFile(const Json::Value &value)
|
||||||
{
|
{
|
||||||
m_root = value;
|
m_root = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::JsonConfigFile::~JsonConfigFile() = default;
|
EQ::JsonConfigFile::~JsonConfigFile()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename)
|
||||||
* @param file_name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
EQ::JsonConfigFile EQ::JsonConfigFile::Load(
|
|
||||||
const std::string &file_name
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
JsonConfigFile ret;
|
JsonConfigFile ret;
|
||||||
ret.m_root = Json::Value();
|
ret.m_root = Json::Value();
|
||||||
|
|
||||||
std::ifstream ifs;
|
std::ifstream ifs;
|
||||||
ifs.open(file_name, std::ifstream::in);
|
ifs.open(filename, std::ifstream::in);
|
||||||
|
|
||||||
if (!ifs.good()) {
|
if (!ifs.good()) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -32,128 +29,59 @@ EQ::JsonConfigFile EQ::JsonConfigFile::Load(
|
|||||||
try {
|
try {
|
||||||
ifs >> ret.m_root;
|
ifs >> ret.m_root;
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
std::string EQ::JsonConfigFile::GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value) {
|
||||||
* @param file_name
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
void EQ::JsonConfigFile::Save(
|
|
||||||
const std::string &file_name
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::ofstream opened_config_file;
|
|
||||||
opened_config_file.open(file_name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grab and build config contents
|
|
||||||
*/
|
|
||||||
Json::StreamWriterBuilder write_builder;
|
|
||||||
write_builder["indentation"] = " ";
|
|
||||||
std::string document = Json::writeString(write_builder, m_root);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write current contents and close
|
|
||||||
*/
|
|
||||||
opened_config_file << document;
|
|
||||||
opened_config_file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param title
|
|
||||||
* @param parameter
|
|
||||||
* @param default_value
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
std::string EQ::JsonConfigFile::GetVariableString(
|
|
||||||
const std::string &title,
|
|
||||||
const std::string ¶meter,
|
|
||||||
const std::string &default_value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||||
return m_root[title][parameter].asString();
|
return m_root[title][parameter].asString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception) {
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int EQ::JsonConfigFile::GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value) {
|
||||||
* @param title
|
|
||||||
* @param parameter
|
|
||||||
* @param default_value
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int EQ::JsonConfigFile::GetVariableInt(
|
|
||||||
const std::string &title,
|
|
||||||
const std::string ¶meter,
|
|
||||||
const int default_value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||||
return m_root[title][parameter].asInt();
|
return m_root[title][parameter].asInt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception) {
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool EQ::JsonConfigFile::GetVariableBool(const std::string &title, const std::string ¶meter, const bool default_value) {
|
||||||
* @param title
|
|
||||||
* @param parameter
|
|
||||||
* @param default_value
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool EQ::JsonConfigFile::GetVariableBool(
|
|
||||||
const std::string &title,
|
|
||||||
const std::string ¶meter,
|
|
||||||
const bool default_value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||||
return m_root[title][parameter].asBool();
|
return m_root[title][parameter].asBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception) {
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
double EQ::JsonConfigFile::GetVariableDouble(const std::string &title, const std::string ¶meter, const double default_value) {
|
||||||
* @param title
|
|
||||||
* @param parameter
|
|
||||||
* @param default_value
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
double EQ::JsonConfigFile::GetVariableDouble(
|
|
||||||
const std::string &title,
|
|
||||||
const std::string ¶meter,
|
|
||||||
const double default_value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
if (m_root.isMember(title) && m_root[title].isMember(parameter)) {
|
||||||
return m_root[title][parameter].asDouble();
|
return m_root[title][parameter].asDouble();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &) {
|
catch (std::exception) {
|
||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,10 @@ namespace EQ
|
|||||||
class JsonConfigFile
|
class JsonConfigFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JsonConfigFile();
|
|
||||||
JsonConfigFile(const Json::Value &value);
|
JsonConfigFile(const Json::Value &value);
|
||||||
~JsonConfigFile();
|
~JsonConfigFile();
|
||||||
|
|
||||||
static JsonConfigFile Load(const std::string &file_name);
|
static JsonConfigFile Load(const std::string &filename);
|
||||||
void Save(const std::string &file_name);
|
|
||||||
|
|
||||||
std::string GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value);
|
std::string GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value);
|
||||||
int GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value);
|
int GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value);
|
||||||
@@ -21,6 +19,7 @@ namespace EQ
|
|||||||
|
|
||||||
Json::Value& RawHandle() { return m_root; }
|
Json::Value& RawHandle() { return m_root; }
|
||||||
private:
|
private:
|
||||||
|
JsonConfigFile();
|
||||||
Json::Value m_root;
|
Json::Value m_root;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -278,6 +278,12 @@ void LinkedListIterator<TYPE>::Replace(const TYPE& new_data)
|
|||||||
template<class TYPE>
|
template<class TYPE>
|
||||||
void LinkedListIterator<TYPE>::Reset()
|
void LinkedListIterator<TYPE>::Reset()
|
||||||
{
|
{
|
||||||
|
if (!(&list))
|
||||||
|
{
|
||||||
|
current_element=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (dir == FORWARD)
|
if (dir == FORWARD)
|
||||||
{
|
{
|
||||||
current_element = list.first;
|
current_element = list.first;
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#define ENC(c) (((c) & 0x3f) + ' ')
|
||||||
|
#define DEC(c) (((c) - ' ') & 0x3f)
|
||||||
|
|
||||||
std::map<int,std::string> DBFieldNames;
|
std::map<int,std::string> DBFieldNames;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -330,6 +333,64 @@ void LoadItemDBFieldNames() {
|
|||||||
DBFieldNames[113]="unknown115"; // ? (end quote)
|
DBFieldNames[113]="unknown115"; // ? (end quote)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void encode_length(unsigned long length, char *out)
|
||||||
|
{
|
||||||
|
char buf[4];
|
||||||
|
memcpy(buf,&length,sizeof(unsigned long));
|
||||||
|
encode_chunk(buf,3,out);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long encode(char *in, unsigned long length, char *out)
|
||||||
|
{
|
||||||
|
unsigned long used=0,len=0;
|
||||||
|
while(used<length) {
|
||||||
|
encode_chunk(in+used,length-used,out+len);
|
||||||
|
used+=3;
|
||||||
|
len+=4;
|
||||||
|
}
|
||||||
|
*(out+len)=0;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long decode_length(char *in)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
char buf[4];
|
||||||
|
decode_chunk(in,&buf[0]);
|
||||||
|
buf[3]=0;
|
||||||
|
memcpy(&length,buf,sizeof(unsigned long));
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode(char *in, char *out)
|
||||||
|
{
|
||||||
|
char *ptr=in;
|
||||||
|
char *outptr=out;
|
||||||
|
while(*ptr) {
|
||||||
|
decode_chunk(ptr,outptr);
|
||||||
|
ptr+=4;
|
||||||
|
outptr+=3;
|
||||||
|
}
|
||||||
|
*outptr=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode_chunk(char *in, int len, char *out)
|
||||||
|
{
|
||||||
|
*out=ENC(in[0] >> 2);
|
||||||
|
*(out+1)=ENC((in[0] << 4)|(((len<2 ? 0 : in[1]) >> 4) & 0xF));
|
||||||
|
*(out+2)=ENC(((len<2 ? 0 : in[1]) << 2)|(((len<3 ? 0 : in[2]) >> 6) & 0x3));
|
||||||
|
*(out+3)=ENC((len<3 ? 0 : in[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode_chunk(char *in, char *out)
|
||||||
|
{
|
||||||
|
*out = DEC(*in) << 2 | DEC(in[1]) >> 4;
|
||||||
|
*(out+1) = DEC(in[1]) << 4 | DEC(in[2]) >> 2;
|
||||||
|
*(out+2) = DEC(in[2]) << 6 | DEC(in[3]);
|
||||||
|
}
|
||||||
|
|
||||||
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
||||||
{
|
{
|
||||||
unsigned long i,j;
|
unsigned long i,j;
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
|||||||
|
|
||||||
void LoadItemDBFieldNames();
|
void LoadItemDBFieldNames();
|
||||||
|
|
||||||
|
void encode_length(unsigned long length, char *out);
|
||||||
|
unsigned long decode_length(char *in);
|
||||||
|
unsigned long encode(char *in, unsigned long length, char *out);
|
||||||
|
void decode(char *in, char *out);
|
||||||
|
void encode_chunk(char *in, int len, char *out);
|
||||||
|
void decode_chunk(char *in, char *out);
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int print_stacktrace();
|
int print_stacktrace();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,15 +32,15 @@
|
|||||||
//
|
//
|
||||||
#define VARSTRUCT_DECODE_TYPE(Type, Buffer) *(Type *)Buffer; Buffer += sizeof(Type);
|
#define VARSTRUCT_DECODE_TYPE(Type, Buffer) *(Type *)Buffer; Buffer += sizeof(Type);
|
||||||
#define VARSTRUCT_DECODE_STRING(String, Buffer) strcpy(String, Buffer); Buffer += strlen(String)+1;
|
#define VARSTRUCT_DECODE_STRING(String, Buffer) strcpy(String, Buffer); Buffer += strlen(String)+1;
|
||||||
#define VARSTRUCT_ENCODE_STRING(Buffer, String) { int length = sprintf(Buffer, "%s", String); Buffer += length + 1; }
|
#define VARSTRUCT_ENCODE_STRING(Buffer, String) { sprintf(Buffer, "%s", String); Buffer += strlen(String) + 1; }
|
||||||
#define VARSTRUCT_ENCODE_INTSTRING(Buffer, Number) { int length = sprintf(Buffer, "%i", Number); Buffer += length + 1; }
|
#define VARSTRUCT_ENCODE_INTSTRING(Buffer, Number) { sprintf(Buffer, "%i", Number); Buffer += strlen(Buffer) + 1; }
|
||||||
#define VARSTRUCT_ENCODE_TYPE(Type, Buffer, Value) { *(Type *)Buffer = Value; Buffer += sizeof(Type); }
|
#define VARSTRUCT_ENCODE_TYPE(Type, Buffer, Value) { *(Type *)Buffer = Value; Buffer += sizeof(Type); }
|
||||||
#define VARSTRUCT_SKIP_TYPE(Type, Buffer) Buffer += sizeof(Type);
|
#define VARSTRUCT_SKIP_TYPE(Type, Buffer) Buffer += sizeof(Type);
|
||||||
|
|
||||||
#define VERIFY_PACKET_LENGTH(OPCode, Packet, StructName) \
|
#define VERIFY_PACKET_LENGTH(OPCode, Packet, StructName) \
|
||||||
if(Packet->size != sizeof(StructName)) \
|
if(Packet->size != sizeof(StructName)) \
|
||||||
{ \
|
{ \
|
||||||
LogNetcode("Size mismatch in " #OPCode " expected [{}] got [{}]", sizeof(StructName), Packet->size); \
|
Log(Logs::Detail, Logs::Netcode, "Size mismatch in " #OPCode " expected %i got %i", sizeof(StructName), Packet->size); \
|
||||||
DumpPacket(Packet); \
|
DumpPacket(Packet); \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,21 +116,17 @@ bool EQ::Net::ConsoleServerConnection::SendChannelMessage(const ServerChannelMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (scm->chan_num) {
|
switch (scm->chan_num) {
|
||||||
case 4: {
|
|
||||||
if (RuleB(Chat, ServerWideAuction)) {
|
if (RuleB(Chat, ServerWideAuction)) {
|
||||||
|
case 4: {
|
||||||
QueueMessage(fmt::format("{0} auctions, '{1}'", 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?
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case 5: {
|
|
||||||
if (RuleB(Chat, ServerWideOOC)) {
|
if (RuleB(Chat, ServerWideOOC)) {
|
||||||
|
case 5: {
|
||||||
QueueMessage(fmt::format("{0} says ooc, '{1}'", 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?
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,20 +10,27 @@
|
|||||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
||||||
{
|
{
|
||||||
m_attached = nullptr;
|
m_attached = nullptr;
|
||||||
|
m_next_id = 1;
|
||||||
memset(&m_timer, 0, sizeof(uv_timer_t));
|
memset(&m_timer, 0, sizeof(uv_timer_t));
|
||||||
memset(&m_socket, 0, sizeof(uv_udp_t));
|
memset(&m_socket, 0, sizeof(uv_udp_t));
|
||||||
|
|
||||||
Attach(EQ::EventLoop::Get().Handle());
|
Attach(EventLoop::GetDefault().Handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
|
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
|
||||||
{
|
{
|
||||||
m_attached = nullptr;
|
m_attached = nullptr;
|
||||||
m_options = opts;
|
m_options = opts;
|
||||||
|
m_next_id = 1;
|
||||||
memset(&m_timer, 0, sizeof(uv_timer_t));
|
memset(&m_timer, 0, sizeof(uv_timer_t));
|
||||||
memset(&m_socket, 0, sizeof(uv_udp_t));
|
memset(&m_socket, 0, sizeof(uv_udp_t));
|
||||||
|
|
||||||
Attach(EQ::EventLoop::Get().Handle());
|
if (opts.loop == nullptr) {
|
||||||
|
Attach(EventLoop::GetDefault().Handle());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Attach(opts.loop->Handle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
|
EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
|
||||||
@@ -89,7 +96,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
|
|||||||
{
|
{
|
||||||
//todo dns resolution
|
//todo dns resolution
|
||||||
|
|
||||||
auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, addr, port));
|
auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, GetNextId(), addr, port));
|
||||||
connection->m_self = connection;
|
connection->m_self = connection;
|
||||||
|
|
||||||
if (m_on_new_connection) {
|
if (m_on_new_connection) {
|
||||||
@@ -227,7 +234,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
|||||||
StaticPacket p((void*)data, size);
|
StaticPacket p((void*)data, size);
|
||||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
auto request = p.GetSerialize<DaybreakConnect>(0);
|
||||||
|
|
||||||
connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, request, endpoint, port));
|
connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, GetNextId(), request, endpoint, port));
|
||||||
connection->m_self = connection;
|
connection->m_self = connection;
|
||||||
|
|
||||||
if (m_on_new_connection) {
|
if (m_on_new_connection) {
|
||||||
@@ -285,10 +292,18 @@ void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t EQ::Net::DaybreakConnectionManager::GetNextId()
|
||||||
|
{
|
||||||
|
auto id = m_next_id;
|
||||||
|
m_next_id++;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
//new connection made as server
|
//new connection made as server
|
||||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port)
|
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, uint64_t id, const DaybreakConnect &connect, const std::string &endpoint, int port)
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
|
m_id = id;
|
||||||
m_last_send = Clock::now();
|
m_last_send = Clock::now();
|
||||||
m_last_recv = Clock::now();
|
m_last_recv = Clock::now();
|
||||||
m_status = StatusConnected;
|
m_status = StatusConnected;
|
||||||
@@ -311,9 +326,10 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
|||||||
}
|
}
|
||||||
|
|
||||||
//new connection made as client
|
//new connection made as client
|
||||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port)
|
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, uint64_t id, const std::string &endpoint, int port)
|
||||||
{
|
{
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
|
m_id = id;
|
||||||
m_last_send = Clock::now();
|
m_last_send = Clock::now();
|
||||||
m_last_recv = Clock::now();
|
m_last_recv = Clock::now();
|
||||||
m_status = StatusConnecting;
|
m_status = StatusConnecting;
|
||||||
@@ -368,7 +384,6 @@ void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliab
|
|||||||
packet.PutUInt8(0, 0);
|
packet.PutUInt8(0, 0);
|
||||||
packet.PutPacket(1, p);
|
packet.PutPacket(1, p);
|
||||||
InternalQueuePacket(packet, stream, reliable);
|
InternalQueuePacket(packet, stream, reliable);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalQueuePacket(p, stream, reliable);
|
InternalQueuePacket(p, stream, reliable);
|
||||||
@@ -385,7 +400,7 @@ EQ::Net::DaybreakConnectionStats EQ::Net::DaybreakConnection::GetStats()
|
|||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ResetStats()
|
void EQ::Net::DaybreakConnection::ResetStats()
|
||||||
{
|
{
|
||||||
m_stats.Reset();
|
m_stats = DaybreakConnectionStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::Process()
|
void EQ::Net::DaybreakConnection::Process()
|
||||||
@@ -399,7 +414,7 @@ void EQ::Net::DaybreakConnection::Process()
|
|||||||
|
|
||||||
ProcessQueue();
|
ProcessQueue();
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception ex) {
|
||||||
if (m_owner->m_on_error_message) {
|
if (m_owner->m_on_error_message) {
|
||||||
m_owner->m_on_error_message(fmt::format("Error processing connection: {0}", ex.what()));
|
m_owner->m_on_error_message(fmt::format("Error processing connection: {0}", ex.what()));
|
||||||
}
|
}
|
||||||
@@ -418,7 +433,6 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
|
|
||||||
auto opcode = p.GetInt8(1);
|
auto opcode = p.GetInt8(1);
|
||||||
if (p.GetInt8(0) == 0 && (opcode == OP_KeepAlive || opcode == OP_OutboundPing)) {
|
if (p.GetInt8(0) == 0 && (opcode == OP_KeepAlive || opcode == OP_OutboundPing)) {
|
||||||
m_stats.bytes_after_decode += p.Length();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,8 +441,6 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
if (m_owner->m_on_error_message) {
|
if (m_owner->m_on_error_message) {
|
||||||
m_owner->m_on_error_message(fmt::format("Tossed packet that failed CRC of type {0:#x}", p.Length() >= 2 ? p.GetInt8(1) : 0));
|
m_owner->m_on_error_message(fmt::format("Tossed packet that failed CRC of type {0:#x}", p.Length() >= 2 ? p.GetInt8(1) : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stats.bytes_after_decode += p.Length();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,7 +469,6 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stats.bytes_after_decode += temp.Length();
|
|
||||||
ProcessDecodedPacket(StaticPacket(temp.Data(), temp.Length()));
|
ProcessDecodedPacket(StaticPacket(temp.Data(), temp.Length()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -476,12 +487,10 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stats.bytes_after_decode += temp.Length();
|
|
||||||
ProcessDecodedPacket(StaticPacket(temp.Data(), temp.Length()));
|
ProcessDecodedPacket(StaticPacket(temp.Data(), temp.Length()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_stats.bytes_after_decode += p.Length();
|
|
||||||
ProcessDecodedPacket(p);
|
ProcessDecodedPacket(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1000,7 +1009,7 @@ uint32_t Deflate(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t out_
|
|||||||
zstream.avail_in = in_len;
|
zstream.avail_in = in_len;
|
||||||
zstream.opaque = Z_NULL;
|
zstream.opaque = Z_NULL;
|
||||||
|
|
||||||
deflateInit(&zstream, Z_BEST_SPEED);
|
deflateInit(&zstream, Z_FINISH);
|
||||||
zstream.next_out = out;
|
zstream.next_out = out;
|
||||||
zstream.avail_out = out_len;
|
zstream.avail_out = out_len;
|
||||||
|
|
||||||
@@ -1047,14 +1056,12 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
|
|||||||
uint8_t new_buffer[2048] = { 0 };
|
uint8_t new_buffer[2048] = { 0 };
|
||||||
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
||||||
uint32_t new_length = 0;
|
uint32_t new_length = 0;
|
||||||
bool send_uncompressed = true;
|
|
||||||
|
|
||||||
if (length > 30) {
|
if (length > 30) {
|
||||||
new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048) + 1;
|
new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048) + 1;
|
||||||
new_buffer[0] = 0x5a;
|
new_buffer[0] = 0x5a;
|
||||||
send_uncompressed = (new_length > length);
|
|
||||||
}
|
}
|
||||||
if (send_uncompressed) {
|
else {
|
||||||
memcpy(new_buffer + 1, buffer, length);
|
memcpy(new_buffer + 1, buffer, length);
|
||||||
new_buffer[0] = 0xa5;
|
new_buffer[0] = 0xa5;
|
||||||
new_length = length + 1;
|
new_length = length + 1;
|
||||||
@@ -1098,6 +1105,10 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
}
|
}
|
||||||
m_stats.resent_packets++;
|
m_stats.resent_packets++;
|
||||||
|
|
||||||
|
m_stats.resent_time_min = std::min(m_stats.resent_time_min, (uint64_t)time_since_last_send.count());
|
||||||
|
m_stats.resent_time_max = std::max(m_stats.resent_time_max, (uint64_t)time_since_last_send.count());
|
||||||
|
m_stats.resent_time_average = (m_stats.resent_time_average / 2) + (time_since_last_send.count() / 2);
|
||||||
|
|
||||||
InternalBufferedSend(p);
|
InternalBufferedSend(p);
|
||||||
entry.second.last_sent = now;
|
entry.second.last_sent = now;
|
||||||
entry.second.times_resent++;
|
entry.second.times_resent++;
|
||||||
@@ -1127,6 +1138,10 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
}
|
}
|
||||||
m_stats.resent_packets++;
|
m_stats.resent_packets++;
|
||||||
|
|
||||||
|
m_stats.resent_time_min = std::min(m_stats.resent_time_min, (uint64_t)time_since_last_send.count());
|
||||||
|
m_stats.resent_time_max = std::max(m_stats.resent_time_max, (uint64_t)time_since_last_send.count());
|
||||||
|
m_stats.resent_time_average = (m_stats.resent_time_average / 2) + (time_since_last_send.count() / 2);
|
||||||
|
|
||||||
InternalBufferedSend(p);
|
InternalBufferedSend(p);
|
||||||
entry.second.last_sent = now;
|
entry.second.last_sent = now;
|
||||||
entry.second.times_resent++;
|
entry.second.times_resent++;
|
||||||
@@ -1294,9 +1309,6 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (PacketCanBeEncoded(p)) {
|
if (PacketCanBeEncoded(p)) {
|
||||||
|
|
||||||
m_stats.bytes_before_encode += p.Length();
|
|
||||||
|
|
||||||
DynamicPacket out;
|
DynamicPacket out;
|
||||||
out.PutPacket(0, p);
|
out.PutPacket(0, p);
|
||||||
|
|
||||||
@@ -1344,8 +1356,6 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stats.bytes_before_encode += p.Length();
|
|
||||||
|
|
||||||
uv_udp_send_t *send_req = new uv_udp_send_t;
|
uv_udp_send_t *send_req = new uv_udp_send_t;
|
||||||
sockaddr_in send_addr;
|
sockaddr_in send_addr;
|
||||||
uv_ip4_addr(m_endpoint.c_str(), m_port, &send_addr);
|
uv_ip4_addr(m_endpoint.c_str(), m_port, &send_addr);
|
||||||
@@ -1382,7 +1392,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto stream = &m_streams[stream_id];
|
auto stream = &m_streams[stream_id];
|
||||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
|
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size();
|
||||||
size_t length = p.Length();
|
size_t length = p.Length();
|
||||||
if (length > max_raw_size) {
|
if (length > max_raw_size) {
|
||||||
DaybreakReliableFragmentHeader first_header;
|
DaybreakReliableFragmentHeader first_header;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
{
|
{
|
||||||
|
class EventLoop;
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
enum DaybreakProtocolOpcode
|
enum DaybreakProtocolOpcode
|
||||||
@@ -90,25 +91,10 @@ namespace EQ
|
|||||||
resent_packets = 0;
|
resent_packets = 0;
|
||||||
resent_fragments = 0;
|
resent_fragments = 0;
|
||||||
resent_full = 0;
|
resent_full = 0;
|
||||||
|
resent_time_min = 0;
|
||||||
|
resent_time_max = 0;
|
||||||
|
resent_time_average = 0;
|
||||||
datarate_remaining = 0.0;
|
datarate_remaining = 0.0;
|
||||||
bytes_after_decode = 0;
|
|
||||||
bytes_before_encode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reset() {
|
|
||||||
recv_bytes = 0;
|
|
||||||
sent_bytes = 0;
|
|
||||||
min_ping = 0xFFFFFFFFFFFFFFFFUL;
|
|
||||||
max_ping = 0;
|
|
||||||
avg_ping = 0;
|
|
||||||
created = Clock::now();
|
|
||||||
dropped_datarate_packets = 0;
|
|
||||||
resent_packets = 0;
|
|
||||||
resent_fragments = 0;
|
|
||||||
resent_full = 0;
|
|
||||||
datarate_remaining = 0.0;
|
|
||||||
bytes_after_decode = 0;
|
|
||||||
bytes_before_encode = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t recv_bytes;
|
uint64_t recv_bytes;
|
||||||
@@ -128,9 +114,10 @@ namespace EQ
|
|||||||
uint64_t resent_packets;
|
uint64_t resent_packets;
|
||||||
uint64_t resent_fragments;
|
uint64_t resent_fragments;
|
||||||
uint64_t resent_full;
|
uint64_t resent_full;
|
||||||
|
uint64_t resent_time_min;
|
||||||
|
uint64_t resent_time_max;
|
||||||
|
uint64_t resent_time_average;
|
||||||
double datarate_remaining;
|
double datarate_remaining;
|
||||||
uint64_t bytes_after_decode;
|
|
||||||
uint64_t bytes_before_encode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DaybreakConnectionManager;
|
class DaybreakConnectionManager;
|
||||||
@@ -138,8 +125,8 @@ namespace EQ
|
|||||||
class DaybreakConnection
|
class DaybreakConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
|
DaybreakConnection(DaybreakConnectionManager *owner, uint64_t id, const DaybreakConnect &connect, const std::string &endpoint, int port);
|
||||||
DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
|
DaybreakConnection(DaybreakConnectionManager *owner, uint64_t id, const std::string &endpoint, int port);
|
||||||
~DaybreakConnection();
|
~DaybreakConnection();
|
||||||
|
|
||||||
const std::string& RemoteEndpoint() const { return m_endpoint; }
|
const std::string& RemoteEndpoint() const { return m_endpoint; }
|
||||||
@@ -158,6 +145,7 @@ namespace EQ
|
|||||||
const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||||
const DaybreakConnectionManager* GetManager() const { return m_owner; }
|
const DaybreakConnectionManager* GetManager() const { return m_owner; }
|
||||||
DaybreakConnectionManager* GetManager() { return m_owner; }
|
DaybreakConnectionManager* GetManager() { return m_owner; }
|
||||||
|
uint64_t GetId() const { return m_id; }
|
||||||
private:
|
private:
|
||||||
DaybreakConnectionManager *m_owner;
|
DaybreakConnectionManager *m_owner;
|
||||||
std::string m_endpoint;
|
std::string m_endpoint;
|
||||||
@@ -180,6 +168,7 @@ namespace EQ
|
|||||||
size_t m_rolling_ping;
|
size_t m_rolling_ping;
|
||||||
Timestamp m_close_time;
|
Timestamp m_close_time;
|
||||||
double m_outgoing_budget;
|
double m_outgoing_budget;
|
||||||
|
uint64_t m_id;
|
||||||
|
|
||||||
struct DaybreakSentPacket
|
struct DaybreakSentPacket
|
||||||
{
|
{
|
||||||
@@ -257,7 +246,7 @@ namespace EQ
|
|||||||
resend_delay_min = 150;
|
resend_delay_min = 150;
|
||||||
resend_delay_max = 5000;
|
resend_delay_max = 5000;
|
||||||
connect_delay_ms = 500;
|
connect_delay_ms = 500;
|
||||||
stale_connection_ms = 60000;
|
stale_connection_ms = 90000;
|
||||||
connect_stale_ms = 5000;
|
connect_stale_ms = 5000;
|
||||||
crc_length = 2;
|
crc_length = 2;
|
||||||
max_packet_size = 512;
|
max_packet_size = 512;
|
||||||
@@ -269,9 +258,10 @@ namespace EQ
|
|||||||
simulated_in_packet_loss = 0;
|
simulated_in_packet_loss = 0;
|
||||||
simulated_out_packet_loss = 0;
|
simulated_out_packet_loss = 0;
|
||||||
tic_rate_hertz = 60.0;
|
tic_rate_hertz = 60.0;
|
||||||
resend_timeout = 30000;
|
resend_timeout = 90000;
|
||||||
connection_close_time = 2000;
|
connection_close_time = 2000;
|
||||||
outgoing_data_rate = 0.0;
|
outgoing_data_rate = 0.0;
|
||||||
|
loop = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t max_packet_size;
|
size_t max_packet_size;
|
||||||
@@ -295,6 +285,7 @@ namespace EQ
|
|||||||
DaybreakEncodeType encode_passes[2];
|
DaybreakEncodeType encode_passes[2];
|
||||||
int port;
|
int port;
|
||||||
double outgoing_data_rate;
|
double outgoing_data_rate;
|
||||||
|
EQ::EventLoop *loop;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DaybreakConnectionManager
|
class DaybreakConnectionManager
|
||||||
@@ -323,6 +314,7 @@ namespace EQ
|
|||||||
uv_udp_t m_socket;
|
uv_udp_t m_socket;
|
||||||
uv_loop_t *m_attached;
|
uv_loop_t *m_attached;
|
||||||
DaybreakConnectionManagerOptions m_options;
|
DaybreakConnectionManagerOptions m_options;
|
||||||
|
uint64_t m_next_id;
|
||||||
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
|
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
|
||||||
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||||
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
|
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
|
||||||
@@ -332,6 +324,7 @@ namespace EQ
|
|||||||
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
|
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
|
||||||
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
|
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
|
||||||
void SendDisconnect(const std::string &addr, int port);
|
void SendDisconnect(const std::string &addr, int port);
|
||||||
|
uint64_t GetNextId();
|
||||||
|
|
||||||
friend class DaybreakConnection;
|
friend class DaybreakConnection;
|
||||||
};
|
};
|
||||||
|
|||||||
+6
-2
@@ -8,7 +8,7 @@ namespace EQ
|
|||||||
{
|
{
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
static void DNSLookup(const std::string &addr, int port, bool ipv6, std::function<void(const std::string&)> cb) {
|
static void DNSLookup(EQ::EventLoop *eloop, const std::string &addr, int port, bool ipv6, std::function<void(const std::string&)> cb) {
|
||||||
struct DNSBaton
|
struct DNSBaton
|
||||||
{
|
{
|
||||||
std::function<void(const std::string&)> cb;
|
std::function<void(const std::string&)> cb;
|
||||||
@@ -21,7 +21,7 @@ namespace EQ
|
|||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
auto loop = EQ::EventLoop::Get().Handle();
|
auto loop = eloop->Handle();
|
||||||
uv_getaddrinfo_t *resolver = new uv_getaddrinfo_t();
|
uv_getaddrinfo_t *resolver = new uv_getaddrinfo_t();
|
||||||
memset(resolver, 0, sizeof(uv_getaddrinfo_t));
|
memset(resolver, 0, sizeof(uv_getaddrinfo_t));
|
||||||
auto port_str = std::to_string(port);
|
auto port_str = std::to_string(port);
|
||||||
@@ -57,5 +57,9 @@ namespace EQ
|
|||||||
cb(addr);
|
cb(addr);
|
||||||
}, addr.c_str(), port_str.c_str(), &hints);
|
}, addr.c_str(), port_str.c_str(), &hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void DNSLookup(const std::string &addr, int port, bool ipv6, std::function<void(const std::string&)> cb) {
|
||||||
|
DNSLookup(&EQ::EventLoop::GetDefault(), addr, port, ipv6, cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-13
@@ -1,5 +1,6 @@
|
|||||||
#include "eqstream.h"
|
#include "eqstream.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../eqemu_logsys_fmt.h"
|
||||||
|
|
||||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
|
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
|
||||||
{
|
{
|
||||||
@@ -12,13 +13,6 @@ EQ::Net::EQStreamManager::~EQStreamManager()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
|
|
||||||
{
|
|
||||||
m_options = options;
|
|
||||||
auto &opts = m_daybreak.GetOptions();
|
|
||||||
opts = options.daybreak_options;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||||
{
|
{
|
||||||
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
||||||
@@ -71,7 +65,7 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
|
|||||||
opcode = p->GetOpcodeBypass();
|
opcode = p->GetOpcodeBypass();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_packet_sent_count[static_cast<int>(p->GetOpcode())]++; //Wont bother with bypass tracking of these since those are rare for testing anyway
|
m_packet_sent_count[p->GetOpcode()]++; //Wont bother with bypass tracking of these since those are rare for testing anyway
|
||||||
opcode = (*m_opcode_manager)->EmuToEQ(p->GetOpcode());
|
opcode = (*m_opcode_manager)->EmuToEQ(p->GetOpcode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +115,7 @@ EQApplicationPacket *EQ::Net::EQStream::PopPacket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EmuOpcode emu_op = (*m_opcode_manager)->EQToEmu(opcode);
|
EmuOpcode emu_op = (*m_opcode_manager)->EQToEmu(opcode);
|
||||||
m_packet_recv_count[static_cast<int>(emu_op)]++;
|
m_packet_recv_count[emu_op]++;
|
||||||
|
|
||||||
EQApplicationPacket *ret = new EQApplicationPacket(emu_op, (unsigned char*)p->Data() + m_owner->GetOptions().opcode_size, p->Length() - m_owner->GetOptions().opcode_size);
|
EQApplicationPacket *ret = new EQApplicationPacket(emu_op, (unsigned char*)p->Data() + m_owner->GetOptions().opcode_size, p->Length() - m_owner->GetOptions().opcode_size);
|
||||||
ret->SetProtocolOpcode(opcode);
|
ret->SetProtocolOpcode(opcode);
|
||||||
@@ -184,23 +178,23 @@ EQStreamInterface::MatchState EQ::Net::EQStream::CheckSignature(const Signature
|
|||||||
|
|
||||||
if (opcode == sig->first_eq_opcode) {
|
if (opcode == sig->first_eq_opcode) {
|
||||||
if (length == sig->first_length) {
|
if (length == sig->first_length) {
|
||||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode matched {2:#x} and length matched {3}",
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length matched {3}",
|
||||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length);
|
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length);
|
||||||
return MatchSuccessful;
|
return MatchSuccessful;
|
||||||
}
|
}
|
||||||
else if (length == 0) {
|
else if (length == 0) {
|
||||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode matched {2:#x} and length is ignored.",
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length is ignored.",
|
||||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode);
|
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode);
|
||||||
return MatchSuccessful;
|
return MatchSuccessful;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode matched {2:#x} but length {3} did not match expected {4}",
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} but length {3} did not match expected {4}",
|
||||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length, sig->first_length);
|
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length, sig->first_length);
|
||||||
return MatchFailed;
|
return MatchFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogF(Logs::General, Logs::Netcode, "[StreamIdentify] {0}:{1}: First opcode {1:#x} did not match expected {2:#x}",
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode {1:#x} did not match expected {2:#x}",
|
||||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), opcode, sig->first_eq_opcode);
|
m_connection->RemoteEndpoint(), m_connection->RemotePort(), opcode, sig->first_eq_opcode);
|
||||||
return MatchFailed;
|
return MatchFailed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ namespace EQ
|
|||||||
EQStreamManager(const EQStreamManagerInterfaceOptions &options);
|
EQStreamManager(const EQStreamManagerInterfaceOptions &options);
|
||||||
~EQStreamManager();
|
~EQStreamManager();
|
||||||
|
|
||||||
virtual void SetOptions(const EQStreamManagerInterfaceOptions& options);
|
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func) { m_on_new_connection = func; }
|
||||||
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
|
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
virtual void SetPriority(EQStreamPriority priority) { }
|
||||||
private:
|
private:
|
||||||
DaybreakConnectionManager m_daybreak;
|
DaybreakConnectionManager m_daybreak;
|
||||||
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
|
std::function<void(std::shared_ptr<EQStreamInterface>)> m_on_new_connection;
|
||||||
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
std::function<void(std::shared_ptr<EQStreamInterface>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||||
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
|
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||||
|
|
||||||
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
||||||
@@ -66,8 +66,8 @@ namespace EQ
|
|||||||
std::shared_ptr<DaybreakConnection> m_connection;
|
std::shared_ptr<DaybreakConnection> m_connection;
|
||||||
OpcodeManager **m_opcode_manager;
|
OpcodeManager **m_opcode_manager;
|
||||||
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
||||||
std::unordered_map<int, int> m_packet_recv_count;
|
std::unordered_map<EmuOpcode, int> m_packet_recv_count;
|
||||||
std::unordered_map<int, int> m_packet_sent_count;
|
std::unordered_map<EmuOpcode, int> m_packet_sent_count;
|
||||||
friend class EQStreamManager;
|
friend class EQStreamManager;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,685 @@
|
|||||||
|
#include "eqstream_concurrent.h"
|
||||||
|
#include "eqstream_concurrent_message.h"
|
||||||
|
#include "../event/event_loop.h"
|
||||||
|
#include "../event/timer.h"
|
||||||
|
#include "../string_util.h"
|
||||||
|
#include "../opcodemgr.h"
|
||||||
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../eqemu_logsys_fmt.h"
|
||||||
|
#include "daybreak_connection.h"
|
||||||
|
#include <thread>
|
||||||
|
#include <concurrentqueue.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <queue>
|
||||||
|
#include <deque>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
struct EQ::Net::ConcurrentEQStreamManager::Impl
|
||||||
|
{
|
||||||
|
std::thread background;
|
||||||
|
bool background_running;
|
||||||
|
moodycamel::ConcurrentQueue<ceqs_msg_t> foreground_queue;
|
||||||
|
moodycamel::ConcurrentQueue<ceqs_msg_t> background_queue;
|
||||||
|
std::unordered_map<uint64_t, std::shared_ptr<DaybreakConnection>> connections;
|
||||||
|
std::unique_ptr<EQ::Timer> foreground_loop_timer;
|
||||||
|
std::unique_ptr<EQ::Timer> background_loop_timer;
|
||||||
|
std::unique_ptr<EQ::Timer> background_update_stats_timer;
|
||||||
|
std::unordered_map<uint64_t, std::shared_ptr<ConcurrentEQStream>> streams;
|
||||||
|
std::function<void(std::shared_ptr<EQStreamInterface>)> on_new_connection;
|
||||||
|
std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> on_connection_state_change;
|
||||||
|
EQStreamPriority priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
EQ::Net::ConcurrentEQStreamManager::ConcurrentEQStreamManager(const EQStreamManagerInterfaceOptions &options)
|
||||||
|
: EQStreamManagerInterface(options)
|
||||||
|
{
|
||||||
|
_impl.reset(new Impl());
|
||||||
|
_impl->background = std::thread(std::bind(&ConcurrentEQStreamManager::_BackgroundThread, this));
|
||||||
|
_impl->foreground_loop_timer.reset(new EQ::Timer(options.loop, 16, true,
|
||||||
|
std::bind(&ConcurrentEQStreamManager::_ForegroundTimer, this, std::placeholders::_1)));
|
||||||
|
_impl->priority = EQStreamPriority::High;
|
||||||
|
}
|
||||||
|
|
||||||
|
EQ::Net::ConcurrentEQStreamManager::~ConcurrentEQStreamManager()
|
||||||
|
{
|
||||||
|
for (auto &s : _impl->streams) {
|
||||||
|
s.second->_Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_impl->foreground_loop_timer.release();
|
||||||
|
|
||||||
|
//Tell the background to shutdown and wait for it to actually do so
|
||||||
|
ceqs_terminate_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::TerminateBackground;
|
||||||
|
|
||||||
|
_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
_impl->background.join();
|
||||||
|
|
||||||
|
//Go through our incoming messages to make sure we clean up any packets in that need to be freed
|
||||||
|
ceqs_msg_t eqs_msg;
|
||||||
|
|
||||||
|
while (_impl->foreground_queue.try_dequeue(eqs_msg)) {
|
||||||
|
if (eqs_msg.type == ceqs_msg_type::PacketRecv) {
|
||||||
|
ceqs_packet_recv_msg_t *eqs_msg_in = (ceqs_packet_recv_msg_t*)&eqs_msg;
|
||||||
|
|
||||||
|
delete eqs_msg_in->packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_BackgroundThread() {
|
||||||
|
_impl->background_running = true;
|
||||||
|
EQ::EventLoop loop;
|
||||||
|
auto &eqs_opts = GetOptions();
|
||||||
|
auto opts = eqs_opts.daybreak_options;
|
||||||
|
opts.loop = &loop;
|
||||||
|
|
||||||
|
std::unique_ptr<DaybreakConnectionManager> dbcm(new DaybreakConnectionManager(opts));
|
||||||
|
dbcm->OnNewConnection(std::bind(&ConcurrentEQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
|
||||||
|
dbcm->OnConnectionStateChange(std::bind(&ConcurrentEQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
|
dbcm->OnPacketRecv(std::bind(&ConcurrentEQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
|
||||||
|
_impl->background_loop_timer.reset(new EQ::Timer(&loop, 16, true,
|
||||||
|
std::bind(&ConcurrentEQStreamManager::_BackgroundTimer, this, std::placeholders::_1)));
|
||||||
|
|
||||||
|
_impl->background_update_stats_timer.reset(new EQ::Timer(&loop, 500, true,
|
||||||
|
std::bind(&ConcurrentEQStreamManager::_BackgroundUpdateStatsTimer, this, std::placeholders::_1)));
|
||||||
|
|
||||||
|
while (true == _impl->background_running) {
|
||||||
|
loop.Process();
|
||||||
|
|
||||||
|
switch (_impl->priority) {
|
||||||
|
case EQStreamPriority::Low:
|
||||||
|
Sleep(10);
|
||||||
|
break;
|
||||||
|
case EQStreamPriority::Normal:
|
||||||
|
Sleep(5);
|
||||||
|
break;
|
||||||
|
case EQStreamPriority::High:
|
||||||
|
Sleep(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_impl->background_loop_timer.release();
|
||||||
|
_impl->background_update_stats_timer.release();
|
||||||
|
dbcm.release();
|
||||||
|
|
||||||
|
ceqs_msg_t eqs_msg;
|
||||||
|
while (_impl->background_queue.try_dequeue(eqs_msg)) {
|
||||||
|
if (eqs_msg.type == ceqs_msg_type::QueuePacket) {
|
||||||
|
ceqs_queue_packet_msg_t *eqs_msg_in = (ceqs_queue_packet_msg_t*)&eqs_msg;
|
||||||
|
delete eqs_msg_in->packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by background
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_BackgroundTimer(EQ::Timer * t)
|
||||||
|
{
|
||||||
|
ceqs_msg_t msg_queue[16];
|
||||||
|
size_t count = 0;
|
||||||
|
while ((count = _impl->background_queue.try_dequeue_bulk(msg_queue, 16)) != 0) {
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
_ProcessBackgroundMessage(msg_queue[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_BackgroundUpdateStatsTimer(EQ::Timer *t)
|
||||||
|
{
|
||||||
|
ceqs_msg_t msgs[16];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (auto &c : _impl->connections) {
|
||||||
|
auto &connection = c.second;
|
||||||
|
auto msg = (ceqs_update_stats_msg_t*)&msgs[i];
|
||||||
|
|
||||||
|
msg->type = ceqs_msg_type::UpdateStats;
|
||||||
|
msg->stream_id = connection->GetId();
|
||||||
|
msg->stats = connection->GetStats();
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i >= 16) {
|
||||||
|
_impl->foreground_queue.enqueue_bulk(msgs, 16);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
_impl->foreground_queue.enqueue_bulk(msgs, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by background
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_ProcessBackgroundMessage(const ceqs_msg_t &msg)
|
||||||
|
{
|
||||||
|
switch (msg.type) {
|
||||||
|
case ceqs_msg_type::QueuePacket:
|
||||||
|
{
|
||||||
|
ceqs_queue_packet_msg_t *msg_in = (ceqs_queue_packet_msg_t*)&msg;
|
||||||
|
|
||||||
|
auto iter = _impl->connections.find(msg_in->stream_id);
|
||||||
|
if (iter != _impl->connections.end()) {
|
||||||
|
iter->second->QueuePacket(*msg_in->packet, 0, msg_in->ack_req);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete msg_in->packet;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::TerminateBackground:
|
||||||
|
{
|
||||||
|
_impl->background_running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::CloseConnection:
|
||||||
|
{
|
||||||
|
ceqs_close_connection_msg_t *msg_in = (ceqs_close_connection_msg_t*)&msg;
|
||||||
|
auto iter = _impl->connections.find(msg_in->stream_id);
|
||||||
|
if (iter != _impl->connections.end()) {
|
||||||
|
iter->second->Close();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::ResetStats:
|
||||||
|
{
|
||||||
|
ceqs_reset_stats_msg_t *msg_in = (ceqs_reset_stats_msg_t*)&msg;
|
||||||
|
auto iter = _impl->connections.find(msg_in->stream_id);
|
||||||
|
if (iter != _impl->connections.end()) {
|
||||||
|
iter->second->ResetStats();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::SetPriority:
|
||||||
|
{
|
||||||
|
ceqs_set_priority_msg_t *msg_in = (ceqs_set_priority_msg_t*)&msg;
|
||||||
|
_impl->priority = msg_in->priority;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_ForegroundTimer(EQ::Timer *t)
|
||||||
|
{
|
||||||
|
ceqs_msg_t msg_queue[16];
|
||||||
|
size_t count = 0;
|
||||||
|
while ((count = _impl->foreground_queue.try_dequeue_bulk(msg_queue, 16)) != 0) {
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
_ProcessForegroundMessage(msg_queue[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_ProcessForegroundMessage(const ceqs_msg_t &msg)
|
||||||
|
{
|
||||||
|
switch (msg.type) {
|
||||||
|
case ceqs_msg_type::NewConnection:
|
||||||
|
{
|
||||||
|
ceqs_new_connection_msg_t *msg_in = (ceqs_new_connection_msg_t*)&msg;
|
||||||
|
|
||||||
|
std::shared_ptr<ConcurrentEQStream> stream(new ConcurrentEQStream(this,
|
||||||
|
msg_in->stream_id,
|
||||||
|
msg_in->endpoint,
|
||||||
|
msg_in->remote_port,
|
||||||
|
(DbProtocolStatus)msg_in->state));
|
||||||
|
|
||||||
|
_impl->streams.insert(std::make_pair(msg_in->stream_id, stream));
|
||||||
|
if (_impl->on_new_connection) {
|
||||||
|
_impl->on_new_connection(stream);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::ConnectionStateChange:
|
||||||
|
{
|
||||||
|
ceqs_connection_state_change_msg_t *msg_in = (ceqs_connection_state_change_msg_t*)&msg;
|
||||||
|
|
||||||
|
auto iter = _impl->streams.find(msg_in->stream_id);
|
||||||
|
if (iter != _impl->streams.end()) {
|
||||||
|
iter->second->_SetState((DbProtocolStatus)msg_in->to);
|
||||||
|
|
||||||
|
if ((DbProtocolStatus)msg_in->to == DbProtocolStatus::StatusDisconnected || (DbProtocolStatus)msg_in->to == DbProtocolStatus::StatusDisconnecting) {
|
||||||
|
_impl->streams.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::PacketRecv:
|
||||||
|
{
|
||||||
|
ceqs_packet_recv_msg_t *msg_in = (ceqs_packet_recv_msg_t*)&msg;
|
||||||
|
std::unique_ptr<EQ::Net::Packet> p(msg_in->packet);
|
||||||
|
|
||||||
|
auto iter = _impl->streams.find(msg_in->stream_id);
|
||||||
|
if (iter != _impl->streams.end()) {
|
||||||
|
iter->second->_RecvPacket(std::move(p));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ceqs_msg_type::UpdateStats:
|
||||||
|
{
|
||||||
|
ceqs_update_stats_msg_t *msg_in = (ceqs_update_stats_msg_t*)&msg;
|
||||||
|
auto iter = _impl->streams.find(msg_in->stream_id);
|
||||||
|
if (iter != _impl->streams.end()) {
|
||||||
|
iter->second->_UpdateStats(msg_in->stats);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_PushToBackgroundQueue(ceqs_msg_t *msg)
|
||||||
|
{
|
||||||
|
_impl->background_queue.enqueue(*msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::_PushToForegroundQueue(ceqs_msg_t *msg)
|
||||||
|
{
|
||||||
|
_impl->foreground_queue.enqueue(*msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func)
|
||||||
|
{
|
||||||
|
_impl->on_new_connection = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, DbProtocolStatus, DbProtocolStatus)> func)
|
||||||
|
{
|
||||||
|
_impl->on_connection_state_change = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::SetPriority(EQStreamPriority priority)
|
||||||
|
{
|
||||||
|
ceqs_set_priority_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::SetPriority;
|
||||||
|
msg.priority = priority;
|
||||||
|
_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by background
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||||
|
{
|
||||||
|
_impl->connections.insert(std::make_pair(connection->GetId(), connection));
|
||||||
|
ceqs_new_connection_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::NewConnection;
|
||||||
|
msg.stream_id = connection->GetId();
|
||||||
|
msg.remote_port = connection->RemotePort();
|
||||||
|
msg.state = connection->GetStatus();
|
||||||
|
strcpy(msg.endpoint, connection->RemoteEndpoint().c_str());
|
||||||
|
msg.endpoint[connection->RemoteEndpoint().length()] = 0;
|
||||||
|
|
||||||
|
//Make sure the foreground gets this message
|
||||||
|
_PushToForegroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by background
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||||
|
{
|
||||||
|
if (to == DbProtocolStatus::StatusDisconnecting || to == DbProtocolStatus::StatusDisconnected) {
|
||||||
|
auto iter = _impl->connections.find(connection->GetId());
|
||||||
|
if (iter != _impl->connections.end()) {
|
||||||
|
_impl->connections.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ceqs_connection_state_change_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::ConnectionStateChange;
|
||||||
|
msg.stream_id = connection->GetId();
|
||||||
|
msg.from = (int)from;
|
||||||
|
msg.to = (int)to;
|
||||||
|
|
||||||
|
//Make sure the foreground gets this message
|
||||||
|
_PushToForegroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by background
|
||||||
|
void EQ::Net::ConcurrentEQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
|
||||||
|
{
|
||||||
|
ceqs_packet_recv_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::PacketRecv;
|
||||||
|
msg.stream_id = connection->GetId();
|
||||||
|
msg.packet = new DynamicPacket();
|
||||||
|
msg.packet->PutPacket(0, p);
|
||||||
|
|
||||||
|
//Make sure the foreground gets this message
|
||||||
|
_PushToForegroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct EQ::Net::ConcurrentEQStream::Impl
|
||||||
|
{
|
||||||
|
ConcurrentEQStreamManager *parent;
|
||||||
|
uint64_t id;
|
||||||
|
std::string remote_endpoint;
|
||||||
|
int remote_port;
|
||||||
|
uint32_t remote_ip;
|
||||||
|
DbProtocolStatus state;
|
||||||
|
std::deque<std::unique_ptr<EQ::Net::Packet>> packet_queue;
|
||||||
|
OpcodeManager **opcode_manager;
|
||||||
|
DaybreakConnectionStats stats;
|
||||||
|
std::unordered_map<EmuOpcode, int> packet_recv_count;
|
||||||
|
std::unordered_map<EmuOpcode, int> packet_sent_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQ::Net::ConcurrentEQStream::ConcurrentEQStream(ConcurrentEQStreamManager *parent, uint64_t id, const std::string &remote_endpoint, int remote_port, DbProtocolStatus state)
|
||||||
|
{
|
||||||
|
_impl.reset(new Impl());
|
||||||
|
_impl->parent = parent;
|
||||||
|
_impl->id = id;
|
||||||
|
_impl->remote_endpoint = remote_endpoint;
|
||||||
|
_impl->remote_port = remote_port;
|
||||||
|
_impl->remote_ip = inet_addr(remote_endpoint.c_str());
|
||||||
|
_impl->state = state;
|
||||||
|
_impl->opcode_manager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQ::Net::ConcurrentEQStream::~ConcurrentEQStream()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
|
||||||
|
{
|
||||||
|
if (!_impl->parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_impl->opcode_manager && *_impl->opcode_manager) {
|
||||||
|
auto &options = _impl->parent->GetOptions();
|
||||||
|
uint16 opcode = 0;
|
||||||
|
if (p->GetOpcodeBypass() != 0) {
|
||||||
|
opcode = p->GetOpcodeBypass();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_impl->packet_sent_count[p->GetOpcode()]++;
|
||||||
|
opcode = (*_impl->opcode_manager)->EmuToEQ(p->GetOpcode());
|
||||||
|
}
|
||||||
|
|
||||||
|
EQ::Net::DynamicPacket *out = new EQ::Net::DynamicPacket();
|
||||||
|
switch (options.opcode_size) {
|
||||||
|
case 1:
|
||||||
|
out->PutUInt8(0, opcode);
|
||||||
|
out->PutData(1, p->pBuffer, p->size);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
out->PutUInt16(0, opcode);
|
||||||
|
out->PutData(2, p->pBuffer, p->size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ceqs_queue_packet_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::QueuePacket;
|
||||||
|
msg.stream_id = _impl->id;
|
||||||
|
msg.packet = out;
|
||||||
|
msg.ack_req = ack_req;
|
||||||
|
|
||||||
|
//Make sure the background gets this message
|
||||||
|
_impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
|
||||||
|
{
|
||||||
|
QueuePacket(*p, ack_req);
|
||||||
|
delete *p;
|
||||||
|
*p = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQApplicationPacket *EQ::Net::ConcurrentEQStream::PopPacket()
|
||||||
|
{
|
||||||
|
if (!_impl->parent) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_impl->packet_queue.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_impl->opcode_manager != nullptr && *_impl->opcode_manager != nullptr) {
|
||||||
|
auto &options = _impl->parent->GetOptions();
|
||||||
|
auto &p = _impl->packet_queue.front();
|
||||||
|
|
||||||
|
uint16 opcode = 0;
|
||||||
|
switch (options.opcode_size) {
|
||||||
|
case 1:
|
||||||
|
opcode = p->GetUInt8(0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
opcode = p->GetUInt16(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmuOpcode emu_op = (*_impl->opcode_manager)->EQToEmu(opcode);
|
||||||
|
_impl->packet_recv_count[emu_op]++;
|
||||||
|
|
||||||
|
EQApplicationPacket *ret = new EQApplicationPacket(emu_op, (unsigned char*)p->Data() + options.opcode_size, p->Length() - options.opcode_size);
|
||||||
|
ret->SetProtocolOpcode(opcode);
|
||||||
|
_impl->packet_queue.pop_front();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::Close()
|
||||||
|
{
|
||||||
|
if (!_impl->parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ceqs_close_connection_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::CloseConnection;
|
||||||
|
msg.stream_id = _impl->id;
|
||||||
|
|
||||||
|
_impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::ReleaseFromUse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::RemoveData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
std::string EQ::Net::ConcurrentEQStream::GetRemoteAddr() const
|
||||||
|
{
|
||||||
|
return _impl->remote_endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
uint32 EQ::Net::ConcurrentEQStream::GetRemoteIP() const
|
||||||
|
{
|
||||||
|
return _impl->remote_ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
uint16 EQ::Net::ConcurrentEQStream::GetRemotePort() const
|
||||||
|
{
|
||||||
|
return _impl->remote_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
bool EQ::Net::ConcurrentEQStream::CheckState(EQStreamState state)
|
||||||
|
{
|
||||||
|
return GetState() == state;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
std::string EQ::Net::ConcurrentEQStream::Describe() const
|
||||||
|
{
|
||||||
|
return "Concurrent EQStream";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::SetActive(bool val)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQStreamInterface::MatchState EQ::Net::ConcurrentEQStream::CheckSignature(const Signature *sig)
|
||||||
|
{
|
||||||
|
if (!_impl->parent) {
|
||||||
|
return MatchFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_impl->packet_queue.empty()) {
|
||||||
|
auto& options = _impl->parent->GetOptions();
|
||||||
|
auto p = _impl->packet_queue.front().get();
|
||||||
|
uint16 opcode = 0;
|
||||||
|
size_t length = p->Length() - options.opcode_size;
|
||||||
|
switch (options.opcode_size) {
|
||||||
|
case 1:
|
||||||
|
opcode = p->GetUInt8(0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
opcode = p->GetUInt16(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sig->ignore_eq_opcode != 0 && opcode == sig->ignore_eq_opcode) {
|
||||||
|
if (_impl->packet_queue.size() > 1) {
|
||||||
|
p = _impl->packet_queue[1].get();
|
||||||
|
opcode = 0;
|
||||||
|
length = p->Length() - options.opcode_size;
|
||||||
|
switch (options.opcode_size) {
|
||||||
|
case 1:
|
||||||
|
opcode = p->GetUInt8(0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
opcode = p->GetUInt16(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return MatchNotReady;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opcode == sig->first_eq_opcode) {
|
||||||
|
if (length == sig->first_length) {
|
||||||
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length matched {3}",
|
||||||
|
GetRemoteAddr(), GetRemotePort(), sig->first_eq_opcode, length);
|
||||||
|
return MatchSuccessful;
|
||||||
|
}
|
||||||
|
else if (length == 0) {
|
||||||
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length is ignored.",
|
||||||
|
GetRemoteAddr(), GetRemotePort(), sig->first_eq_opcode);
|
||||||
|
return MatchSuccessful;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} but length {3} did not match expected {4}",
|
||||||
|
GetRemoteAddr(), GetRemotePort(), sig->first_eq_opcode, length, sig->first_length);
|
||||||
|
return MatchFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode {1:#x} did not match expected {2:#x}",
|
||||||
|
GetRemoteAddr(), GetRemotePort(), opcode, sig->first_eq_opcode);
|
||||||
|
return MatchFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MatchNotReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQStreamState EQ::Net::ConcurrentEQStream::GetState()
|
||||||
|
{
|
||||||
|
switch (_impl->state) {
|
||||||
|
case StatusConnecting:
|
||||||
|
return UNESTABLISHED;
|
||||||
|
case StatusConnected:
|
||||||
|
return ESTABLISHED;
|
||||||
|
case StatusDisconnecting:
|
||||||
|
return DISCONNECTING;
|
||||||
|
default:
|
||||||
|
return CLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::SetOpcodeManager(OpcodeManager **opm)
|
||||||
|
{
|
||||||
|
_impl->opcode_manager = opm;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQStreamInterface::Stats EQ::Net::ConcurrentEQStream::GetStats() const
|
||||||
|
{
|
||||||
|
EQStreamInterface::Stats ret;
|
||||||
|
ret.DaybreakStats = _impl->stats;
|
||||||
|
|
||||||
|
for (int i = 0; i < _maxEmuOpcode; ++i) {
|
||||||
|
ret.RecvCount[i] = 0;
|
||||||
|
ret.SentCount[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &s : _impl->packet_sent_count) {
|
||||||
|
ret.SentCount[s.first] = s.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &r : _impl->packet_recv_count) {
|
||||||
|
ret.RecvCount[r.first] = r.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::ResetStats()
|
||||||
|
{
|
||||||
|
if (!_impl->parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ceqs_reset_stats_msg_t msg;
|
||||||
|
msg.type = ceqs_msg_type::ResetStats;
|
||||||
|
msg.stream_id = _impl->id;
|
||||||
|
|
||||||
|
_impl->parent->_PushToBackgroundQueue((ceqs_msg_t*)&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
EQStreamManagerInterface *EQ::Net::ConcurrentEQStream::GetManager() const
|
||||||
|
{
|
||||||
|
return _impl->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::_SetState(DbProtocolStatus state)
|
||||||
|
{
|
||||||
|
_impl->state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::_RecvPacket(std::unique_ptr<EQ::Net::Packet> p)
|
||||||
|
{
|
||||||
|
_impl->packet_queue.push_back(std::move(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::_UpdateStats(const DaybreakConnectionStats &stats)
|
||||||
|
{
|
||||||
|
_impl->stats = stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Called by foreground
|
||||||
|
void EQ::Net::ConcurrentEQStream::_Invalidate()
|
||||||
|
{
|
||||||
|
_impl->parent = nullptr;
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../eq_stream_intf.h"
|
||||||
|
#include "eqstream_concurrent_message.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace EQ
|
||||||
|
{
|
||||||
|
class Timer;
|
||||||
|
namespace Net
|
||||||
|
{
|
||||||
|
class ConcurrentEQStream;
|
||||||
|
class ConcurrentEQStreamManager : public EQStreamManagerInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcurrentEQStreamManager(const EQStreamManagerInterfaceOptions &options);
|
||||||
|
~ConcurrentEQStreamManager();
|
||||||
|
|
||||||
|
virtual void OnNewConnection(std::function<void(std::shared_ptr<EQStreamInterface>)> func);
|
||||||
|
virtual void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStreamInterface>, EQ::Net::DbProtocolStatus, EQ::Net::DbProtocolStatus)> func);
|
||||||
|
virtual void SetPriority(EQStreamPriority priority);
|
||||||
|
|
||||||
|
void _PushToBackgroundQueue(ceqs_msg_t* msg);
|
||||||
|
void _PushToForegroundQueue(ceqs_msg_t* msg);
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> _impl;
|
||||||
|
void _BackgroundThread();
|
||||||
|
void _BackgroundTimer(EQ::Timer *t);
|
||||||
|
void _BackgroundUpdateStatsTimer(EQ::Timer *t);
|
||||||
|
void _ProcessBackgroundMessage(const ceqs_msg_t &msg);
|
||||||
|
void _ForegroundTimer(EQ::Timer *t);
|
||||||
|
void _ProcessForegroundMessage(const ceqs_msg_t &msg);
|
||||||
|
|
||||||
|
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
||||||
|
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||||
|
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConcurrentEQStream : public EQStreamInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcurrentEQStream(ConcurrentEQStreamManager *parent, uint64_t id, const std::string &remote_endpoint, int remote_port, DbProtocolStatus state);
|
||||||
|
~ConcurrentEQStream();
|
||||||
|
|
||||||
|
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
|
||||||
|
virtual void FastQueuePacket(EQApplicationPacket **p, bool ack_req = true);
|
||||||
|
virtual EQApplicationPacket *PopPacket();
|
||||||
|
virtual void Close();
|
||||||
|
virtual void ReleaseFromUse();
|
||||||
|
virtual void RemoveData();
|
||||||
|
virtual std::string GetRemoteAddr() const;
|
||||||
|
virtual uint32 GetRemoteIP() const;
|
||||||
|
virtual uint16 GetRemotePort() const;
|
||||||
|
virtual bool CheckState(EQStreamState state);
|
||||||
|
virtual std::string Describe() const;
|
||||||
|
virtual void SetActive(bool val);
|
||||||
|
virtual MatchState CheckSignature(const Signature *sig);
|
||||||
|
virtual EQStreamState GetState();
|
||||||
|
virtual void SetOpcodeManager(OpcodeManager **opm);
|
||||||
|
virtual Stats GetStats() const;
|
||||||
|
virtual void ResetStats();
|
||||||
|
virtual EQStreamManagerInterface* GetManager() const;
|
||||||
|
|
||||||
|
void _SetState(DbProtocolStatus state);
|
||||||
|
void _RecvPacket(std::unique_ptr<EQ::Net::Packet> p);
|
||||||
|
void _UpdateStats(const DaybreakConnectionStats &stats);
|
||||||
|
void _Invalidate();
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
|
||||||
|
std::unique_ptr<Impl> _impl;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define EQSM_PAD_LEN 252
|
||||||
|
|
||||||
|
namespace EQ
|
||||||
|
{
|
||||||
|
namespace Net
|
||||||
|
{
|
||||||
|
class DynamicPacket;
|
||||||
|
enum ceqs_msg_type : uint32_t
|
||||||
|
{
|
||||||
|
//Sent by background
|
||||||
|
NewConnection,
|
||||||
|
ConnectionStateChange,
|
||||||
|
PacketRecv,
|
||||||
|
UpdateStats,
|
||||||
|
//Sent by foreground
|
||||||
|
QueuePacket,
|
||||||
|
TerminateBackground,
|
||||||
|
CloseConnection,
|
||||||
|
ResetStats,
|
||||||
|
SetPriority
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
char padding[EQSM_PAD_LEN];
|
||||||
|
} ceqs_msg_t;
|
||||||
|
|
||||||
|
//Sent by background
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
int remote_port;
|
||||||
|
int state;
|
||||||
|
char endpoint[64];
|
||||||
|
} ceqs_new_connection_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
} ceqs_connection_state_change_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
EQ::Net::DynamicPacket *packet;
|
||||||
|
} ceqs_packet_recv_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
DaybreakConnectionStats stats;
|
||||||
|
} ceqs_update_stats_msg_t;
|
||||||
|
|
||||||
|
//Sent by foreground
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
EQ::Net::DynamicPacket *packet;
|
||||||
|
bool ack_req;
|
||||||
|
} ceqs_queue_packet_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
} ceqs_close_connection_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
uint64_t stream_id;
|
||||||
|
} ceqs_reset_stats_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
} ceqs_terminate_msg_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ceqs_msg_type type;
|
||||||
|
EQStreamPriority priority;
|
||||||
|
} ceqs_set_priority_msg_t;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -89,9 +89,9 @@ namespace EQ {
|
|||||||
public:
|
public:
|
||||||
StaticPacket(void *data, size_t size) { m_data = data; m_data_length = size; m_max_data_length = size; }
|
StaticPacket(void *data, size_t size) { m_data = data; m_data_length = size; m_max_data_length = size; }
|
||||||
virtual ~StaticPacket() { }
|
virtual ~StaticPacket() { }
|
||||||
StaticPacket(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; m_max_data_length = o.m_max_data_length; }
|
StaticPacket(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; }
|
||||||
StaticPacket& operator=(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
|
StaticPacket& operator=(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
|
||||||
StaticPacket(StaticPacket &&o) noexcept { m_data = o.m_data; m_data_length = o.m_data_length; }
|
StaticPacket(StaticPacket &&o) { m_data = o.m_data; m_data_length = o.m_data_length; }
|
||||||
|
|
||||||
virtual const void *Data() const { return m_data; }
|
virtual const void *Data() const { return m_data; }
|
||||||
virtual void *Data() { return m_data; }
|
virtual void *Data() { return m_data; }
|
||||||
@@ -112,7 +112,7 @@ namespace EQ {
|
|||||||
public:
|
public:
|
||||||
DynamicPacket() { }
|
DynamicPacket() { }
|
||||||
virtual ~DynamicPacket() { }
|
virtual ~DynamicPacket() { }
|
||||||
DynamicPacket(DynamicPacket &&o) noexcept { m_data = std::move(o.m_data); }
|
DynamicPacket(DynamicPacket &&o) { m_data = std::move(o.m_data); }
|
||||||
DynamicPacket(const DynamicPacket &o) { m_data = o.m_data; }
|
DynamicPacket(const DynamicPacket &o) { m_data = o.m_data; }
|
||||||
DynamicPacket& operator=(const DynamicPacket &o) { m_data = o.m_data; return *this; }
|
DynamicPacket& operator=(const DynamicPacket &o) { m_data = o.m_data; return *this; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "servertalk_client_connection.h"
|
#include "servertalk_client_connection.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../eqemu_logsys_fmt.h"
|
||||||
|
|
||||||
EQ::Net::ServertalkClient::ServertalkClient(const std::string &addr, int port, bool ipv6, const std::string &identifier, const std::string &credentials)
|
EQ::Net::ServertalkClient::ServertalkClient(const std::string &addr, int port, bool ipv6, const std::string &identifier, const std::string &credentials)
|
||||||
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkClient::Connect, this))))
|
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkClient::Connect, this))))
|
||||||
@@ -78,15 +79,15 @@ void EQ::Net::ServertalkClient::Connect()
|
|||||||
m_connecting = true;
|
m_connecting = true;
|
||||||
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
||||||
if (connection == nullptr) {
|
if (connection == nullptr) {
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
LogF(Logs::General, Logs::TCP_Connection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||||
m_connecting = false;
|
m_connecting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Connected to {0}:{1}", m_addr, m_port);
|
LogF(Logs::General, Logs::TCP_Connection, "Connected to {0}:{1}", m_addr, m_port);
|
||||||
m_connection = connection;
|
m_connection = connection;
|
||||||
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
|
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
LogF(Logs::General, Logs::TCP_Connection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||||
m_encrypted = false;
|
m_encrypted = false;
|
||||||
m_connection.reset();
|
m_connection.reset();
|
||||||
});
|
});
|
||||||
@@ -213,7 +214,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogError("Could not process hello, size != {0}", 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
LogF(Logs::General, Logs::Error, "Could not process hello, size != {0}", 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -225,7 +226,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing hello from server: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing hello from server: {0}", ex.what());
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
|
|
||||||
if (m_on_connect_cb) {
|
if (m_on_connect_cb) {
|
||||||
@@ -252,7 +253,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing hello from server: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing hello from server: {0}", ex.what());
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
|
|
||||||
if (m_on_connect_cb) {
|
if (m_on_connect_cb) {
|
||||||
@@ -275,7 +276,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
|
|||||||
std::unique_ptr<unsigned char[]> decrypted_text(new unsigned char[message_len]);
|
std::unique_ptr<unsigned char[]> decrypted_text(new unsigned char[message_len]);
|
||||||
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key))
|
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key))
|
||||||
{
|
{
|
||||||
LogError("Error decrypting message from server");
|
LogF(Logs::General, Logs::Error, "Error decrypting message from server");
|
||||||
(*(uint64_t*)&m_nonce_theirs[0])++;
|
(*(uint64_t*)&m_nonce_theirs[0])++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -323,7 +324,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing message from server: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing message from server: {0}", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "servertalk_legacy_client_connection.h"
|
#include "servertalk_legacy_client_connection.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../eqemu_logsys_fmt.h"
|
||||||
|
|
||||||
EQ::Net::ServertalkLegacyClient::ServertalkLegacyClient(const std::string &addr, int port, bool ipv6)
|
EQ::Net::ServertalkLegacyClient::ServertalkLegacyClient(const std::string &addr, int port, bool ipv6)
|
||||||
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkLegacyClient::Connect, this))))
|
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkLegacyClient::Connect, this))))
|
||||||
@@ -58,15 +59,15 @@ void EQ::Net::ServertalkLegacyClient::Connect()
|
|||||||
m_connecting = true;
|
m_connecting = true;
|
||||||
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
||||||
if (connection == nullptr) {
|
if (connection == nullptr) {
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
LogF(Logs::General, Logs::TCP_Connection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||||
m_connecting = false;
|
m_connecting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Connected to {0}:{1}", m_addr, m_port);
|
LogF(Logs::General, Logs::TCP_Connection, "Connected to {0}:{1}", m_addr, m_port);
|
||||||
m_connection = connection;
|
m_connection = connection;
|
||||||
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
|
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
LogF(Logs::General, Logs::TCP_Connection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
|
||||||
m_connection.reset();
|
m_connection.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "servertalk_server_connection.h"
|
#include "servertalk_server_connection.h"
|
||||||
#include "servertalk_server.h"
|
#include "servertalk_server.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
|
#include "../eqemu_logsys_fmt.h"
|
||||||
#include "../util/uuid.h"
|
#include "../util/uuid.h"
|
||||||
|
|
||||||
EQ::Net::ServertalkServerConnection::ServertalkServerConnection(std::shared_ptr<EQ::Net::TCPConnection> c, EQ::Net::ServertalkServer *parent, bool encrypted, bool allow_downgrade)
|
EQ::Net::ServertalkServerConnection::ServertalkServerConnection(std::shared_ptr<EQ::Net::TCPConnection> c, EQ::Net::ServertalkServer *parent, bool encrypted, bool allow_downgrade)
|
||||||
@@ -201,7 +202,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
{
|
{
|
||||||
#ifdef ENABLE_SECURITY
|
#ifdef ENABLE_SECURITY
|
||||||
if (downgrade_security && m_allow_downgrade && m_encrypted) {
|
if (downgrade_security && m_allow_downgrade && m_encrypted) {
|
||||||
LogF(Logs::General, Logs::TCPConnection, "Downgraded encrypted connection to plaintext because otherside didn't support encryption {0}:{1}",
|
LogF(Logs::General, Logs::TCP_Connection, "Downgraded encrypted connection to plaintext because otherside didn't support encryption {0}:{1}",
|
||||||
m_connection->RemoteIP(), m_connection->RemotePort());
|
m_connection->RemoteIP(), m_connection->RemotePort());
|
||||||
m_encrypted = false;
|
m_encrypted = false;
|
||||||
}
|
}
|
||||||
@@ -220,7 +221,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
|
|
||||||
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)p.Data() + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, cipher_len, m_nonce_theirs, m_shared_key))
|
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)p.Data() + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, cipher_len, m_nonce_theirs, m_shared_key))
|
||||||
{
|
{
|
||||||
LogError("Error decrypting handshake from client, dropping connection.");
|
LogF(Logs::General, Logs::Error, "Error decrypting handshake from client, dropping connection.");
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -229,7 +230,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
std::string credentials = (const char*)&decrypted_text[0] + (m_identifier.length() + 1);
|
std::string credentials = (const char*)&decrypted_text[0] + (m_identifier.length() + 1);
|
||||||
|
|
||||||
if (!m_parent->CheckCredentials(credentials)) {
|
if (!m_parent->CheckCredentials(credentials)) {
|
||||||
LogError("Got incoming connection with invalid credentials during handshake, dropping connection.");
|
LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -239,7 +240,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing handshake from client: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what());
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +250,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
auto credentials = p.GetCString(m_identifier.length() + 1);
|
auto credentials = p.GetCString(m_identifier.length() + 1);
|
||||||
|
|
||||||
if (!m_parent->CheckCredentials(credentials)) {
|
if (!m_parent->CheckCredentials(credentials)) {
|
||||||
LogError("Got incoming connection with invalid credentials during handshake, dropping connection.");
|
LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -257,7 +258,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
m_parent->ConnectionIdentified(this);
|
m_parent->ConnectionIdentified(this);
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing handshake from client: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what());
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,7 +268,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
auto credentials = p.GetCString(m_identifier.length() + 1);
|
auto credentials = p.GetCString(m_identifier.length() + 1);
|
||||||
|
|
||||||
if (!m_parent->CheckCredentials(credentials)) {
|
if (!m_parent->CheckCredentials(credentials)) {
|
||||||
LogError("Got incoming connection with invalid credentials during handshake, dropping connection.");
|
LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection.");
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -275,7 +276,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b
|
|||||||
m_parent->ConnectionIdentified(this);
|
m_parent->ConnectionIdentified(this);
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing handshake from client: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what());
|
||||||
m_connection->Disconnect();
|
m_connection->Disconnect();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -295,7 +296,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
|||||||
|
|
||||||
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key))
|
if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key))
|
||||||
{
|
{
|
||||||
LogError("Error decrypting message from client");
|
LogF(Logs::General, Logs::Error, "Error decrypting message from client");
|
||||||
(*(uint64_t*)&m_nonce_theirs[0])++;
|
(*(uint64_t*)&m_nonce_theirs[0])++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -343,6 +344,6 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
LogError("Error parsing message from client: {0}", ex.what());
|
LogF(Logs::General, Logs::Error, "Error parsing message from client: {0}", ex.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ EQ::Net::TCPConnection::~TCPConnection() {
|
|||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::TCPConnection::Connect(const std::string &addr, int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb)
|
void EQ::Net::TCPConnection::Connect(EQ::EventLoop *loop, const std::string & addr, int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb)
|
||||||
{
|
{
|
||||||
struct EQTCPConnectBaton
|
struct EQTCPConnectBaton
|
||||||
{
|
{
|
||||||
@@ -23,10 +23,9 @@ void EQ::Net::TCPConnection::Connect(const std::string &addr, int port, bool ipv
|
|||||||
std::function<void(std::shared_ptr<EQ::Net::TCPConnection>)> cb;
|
std::function<void(std::shared_ptr<EQ::Net::TCPConnection>)> cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto loop = EQ::EventLoop::Get().Handle();
|
|
||||||
uv_tcp_t *socket = new uv_tcp_t;
|
uv_tcp_t *socket = new uv_tcp_t;
|
||||||
memset(socket, 0, sizeof(uv_tcp_t));
|
memset(socket, 0, sizeof(uv_tcp_t));
|
||||||
uv_tcp_init(loop, socket);
|
uv_tcp_init(loop->Handle(), socket);
|
||||||
|
|
||||||
sockaddr_storage iaddr;
|
sockaddr_storage iaddr;
|
||||||
if (ipv6) {
|
if (ipv6) {
|
||||||
@@ -64,6 +63,11 @@ void EQ::Net::TCPConnection::Connect(const std::string &addr, int port, bool ipv
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EQ::Net::TCPConnection::Connect(const std::string &addr, int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb)
|
||||||
|
{
|
||||||
|
Connect(&EventLoop::GetDefault(), addr, port, ipv6, cb);
|
||||||
|
}
|
||||||
|
|
||||||
void EQ::Net::TCPConnection::Start() {
|
void EQ::Net::TCPConnection::Start() {
|
||||||
uv_read_start((uv_stream_t*)m_socket, [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
uv_read_start((uv_stream_t*)m_socket, [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||||
buf->base = new char[suggested_size];
|
buf->base = new char[suggested_size];
|
||||||
@@ -203,10 +207,6 @@ int EQ::Net::TCPConnection::LocalPort() const
|
|||||||
|
|
||||||
std::string EQ::Net::TCPConnection::RemoteIP() const
|
std::string EQ::Net::TCPConnection::RemoteIP() const
|
||||||
{
|
{
|
||||||
if (!m_socket) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_storage addr;
|
sockaddr_storage addr;
|
||||||
int addr_len = sizeof(addr);
|
int addr_len = sizeof(addr);
|
||||||
uv_tcp_getpeername(m_socket, (sockaddr*)&addr, &addr_len);
|
uv_tcp_getpeername(m_socket, (sockaddr*)&addr, &addr_len);
|
||||||
@@ -224,10 +224,6 @@ std::string EQ::Net::TCPConnection::RemoteIP() const
|
|||||||
|
|
||||||
int EQ::Net::TCPConnection::RemotePort() const
|
int EQ::Net::TCPConnection::RemotePort() const
|
||||||
{
|
{
|
||||||
if (!m_socket) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_storage addr;
|
sockaddr_storage addr;
|
||||||
int addr_len = sizeof(addr);
|
int addr_len = sizeof(addr);
|
||||||
uv_tcp_getpeername(m_socket, (sockaddr*)&addr, &addr_len);
|
uv_tcp_getpeername(m_socket, (sockaddr*)&addr, &addr_len);
|
||||||
@@ -244,11 +240,3 @@ int EQ::Net::TCPConnection::RemotePort() const
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool EQ::Net::TCPConnection::IsConnected() const
|
|
||||||
{
|
|
||||||
return m_socket != nullptr;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
{
|
{
|
||||||
|
class EventLoop;
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
class TCPConnection
|
class TCPConnection
|
||||||
@@ -15,6 +16,7 @@ namespace EQ
|
|||||||
TCPConnection(uv_tcp_t *socket);
|
TCPConnection(uv_tcp_t *socket);
|
||||||
~TCPConnection();
|
~TCPConnection();
|
||||||
|
|
||||||
|
static void Connect(EQ::EventLoop *loop, const std::string &addr, int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb);
|
||||||
static void Connect(const std::string &addr, int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb);
|
static void Connect(const std::string &addr, int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb);
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
@@ -24,12 +26,10 @@ namespace EQ
|
|||||||
void Read(const char *data, size_t count);
|
void Read(const char *data, size_t count);
|
||||||
void Write(const char *data, size_t count);
|
void Write(const char *data, size_t count);
|
||||||
|
|
||||||
bool IsConnected() const;
|
|
||||||
std::string LocalIP() const;
|
std::string LocalIP() const;
|
||||||
int LocalPort() const;
|
int LocalPort() const;
|
||||||
std::string RemoteIP() const;
|
std::string RemoteIP() const;
|
||||||
int RemotePort() const;
|
int RemotePort() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TCPConnection();
|
TCPConnection();
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,13 @@ void on_close_tcp_server_handle(uv_handle_t* handle) {
|
|||||||
|
|
||||||
EQ::Net::TCPServer::TCPServer()
|
EQ::Net::TCPServer::TCPServer()
|
||||||
{
|
{
|
||||||
|
m_loop = &EventLoop::GetDefault();
|
||||||
|
m_socket = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
EQ::Net::TCPServer::TCPServer(EQ::EventLoop *loop)
|
||||||
|
{
|
||||||
|
m_loop = loop;
|
||||||
m_socket = nullptr;
|
m_socket = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +39,7 @@ void EQ::Net::TCPServer::Listen(const std::string &addr, int port, bool ipv6, st
|
|||||||
|
|
||||||
m_on_new_connection = cb;
|
m_on_new_connection = cb;
|
||||||
|
|
||||||
auto loop = EQ::EventLoop::Get().Handle();
|
auto loop = m_loop->Handle();
|
||||||
m_socket = new uv_tcp_t;
|
m_socket = new uv_tcp_t;
|
||||||
memset(m_socket, 0, sizeof(uv_tcp_t));
|
memset(m_socket, 0, sizeof(uv_tcp_t));
|
||||||
uv_tcp_init(loop, m_socket);
|
uv_tcp_init(loop, m_socket);
|
||||||
@@ -53,7 +60,7 @@ void EQ::Net::TCPServer::Listen(const std::string &addr, int port, bool ipv6, st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto loop = EQ::EventLoop::Get().Handle();
|
auto loop = server->loop;
|
||||||
uv_tcp_t *client = new uv_tcp_t;
|
uv_tcp_t *client = new uv_tcp_t;
|
||||||
memset(client, 0, sizeof(uv_tcp_t));
|
memset(client, 0, sizeof(uv_tcp_t));
|
||||||
uv_tcp_init(loop, client);
|
uv_tcp_init(loop, client);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tcp_connection.h"
|
#include "tcp_connection.h"
|
||||||
|
#include "../event/event_loop.h"
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
{
|
{
|
||||||
@@ -10,6 +11,7 @@ namespace EQ
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TCPServer();
|
TCPServer();
|
||||||
|
TCPServer(EQ::EventLoop *loop);
|
||||||
~TCPServer();
|
~TCPServer();
|
||||||
|
|
||||||
void Listen(int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb);
|
void Listen(int port, bool ipv6, std::function<void(std::shared_ptr<TCPConnection>)> cb);
|
||||||
@@ -19,6 +21,7 @@ namespace EQ
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void(std::shared_ptr<TCPConnection>)> m_on_new_connection;
|
std::function<void(std::shared_ptr<TCPConnection>)> m_on_new_connection;
|
||||||
|
EQ::EventLoop *m_loop;
|
||||||
uv_tcp_t *m_socket;
|
uv_tcp_t *m_socket;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,265 +0,0 @@
|
|||||||
#include "websocket_server.h"
|
|
||||||
#include "../event/event_loop.h"
|
|
||||||
#include "../event/timer.h"
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
struct MethodHandlerEntry
|
|
||||||
{
|
|
||||||
MethodHandlerEntry() {
|
|
||||||
status = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodHandlerEntry(EQ::Net::WebsocketServer::MethodHandler h, int s) {
|
|
||||||
handler = h;
|
|
||||||
status = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
EQ::Net::WebsocketServer::MethodHandler handler;
|
|
||||||
int status;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EQ::Net::WebsocketServer::Impl
|
|
||||||
{
|
|
||||||
std::unique_ptr<TCPServer> server;
|
|
||||||
std::unique_ptr<EQ::Timer> ping_timer;
|
|
||||||
std::map<std::shared_ptr<websocket_connection>, std::unique_ptr<WebsocketServerConnection>> connections;
|
|
||||||
std::map<std::string, MethodHandlerEntry> methods;
|
|
||||||
websocket_server ws_server;
|
|
||||||
LoginHandler login_handler;
|
|
||||||
std::array<std::unordered_set<WebsocketServerConnection*>, SubscriptionEventMax> subscriptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
EQ::Net::WebsocketServer::WebsocketServer(const std::string &addr, int port)
|
|
||||||
{
|
|
||||||
_impl.reset(new Impl());
|
|
||||||
_impl->server.reset(new EQ::Net::TCPServer());
|
|
||||||
_impl->server->Listen(addr, port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
|
||||||
auto wsc = _impl->ws_server.get_connection();
|
|
||||||
WebsocketServerConnection *c = new WebsocketServerConnection(this, connection, wsc);
|
|
||||||
_impl->connections.insert(std::make_pair(wsc, std::unique_ptr<WebsocketServerConnection>(c)));
|
|
||||||
});
|
|
||||||
|
|
||||||
_impl->ws_server.set_write_handler(
|
|
||||||
[this](websocketpp::connection_hdl hdl, char const *data, size_t size) -> websocketpp::lib::error_code {
|
|
||||||
auto c = _impl->ws_server.get_con_from_hdl(hdl);
|
|
||||||
auto iter = _impl->connections.find(c);
|
|
||||||
if (iter != _impl->connections.end()) {
|
|
||||||
iter->second->GetTCPConnection()->Write(data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return websocketpp::lib::error_code();
|
|
||||||
});
|
|
||||||
|
|
||||||
_impl->ping_timer.reset(new EQ::Timer(5000, true, [this](EQ::Timer *t) {
|
|
||||||
auto iter = _impl->connections.begin();
|
|
||||||
|
|
||||||
while (iter != _impl->connections.end()) {
|
|
||||||
try {
|
|
||||||
auto &connection = iter->second;
|
|
||||||
connection->GetWebsocketConnection()->ping("keepalive");
|
|
||||||
}
|
|
||||||
catch (std::exception &) {
|
|
||||||
iter->second->GetTCPConnection()->Disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
_impl->methods.insert(std::make_pair("login", MethodHandlerEntry(std::bind(&WebsocketServer::Login, this, std::placeholders::_1, std::placeholders::_2), 0)));
|
|
||||||
_impl->methods.insert(std::make_pair("subscribe", MethodHandlerEntry(std::bind(&WebsocketServer::Subscribe, this, std::placeholders::_1, std::placeholders::_2), 0)));
|
|
||||||
_impl->methods.insert(std::make_pair("unsubscribe", MethodHandlerEntry(std::bind(&WebsocketServer::Unsubscribe, this, std::placeholders::_1, std::placeholders::_2), 0)));
|
|
||||||
_impl->login_handler = [](const WebsocketServerConnection* connection, const std::string& user, const std::string& pass) {
|
|
||||||
WebsocketLoginStatus ret;
|
|
||||||
ret.account_name = "admin";
|
|
||||||
|
|
||||||
if (connection->RemoteIP() == "127.0.0.1" || connection->RemoteIP() == "::") {
|
|
||||||
ret.logged_in = true;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret.logged_in = false;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
_impl->ws_server.clear_access_channels(websocketpp::log::alevel::all);
|
|
||||||
}
|
|
||||||
|
|
||||||
EQ::Net::WebsocketServer::~WebsocketServer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::ReleaseConnection(WebsocketServerConnection *connection)
|
|
||||||
{
|
|
||||||
UnsubscribeAll(connection);
|
|
||||||
|
|
||||||
_impl->connections.erase(connection->GetWebsocketConnection());
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value EQ::Net::WebsocketServer::HandleRequest(WebsocketServerConnection *connection, const std::string &method, const Json::Value ¶ms)
|
|
||||||
{
|
|
||||||
Json::Value err;
|
|
||||||
if (method != "login") {
|
|
||||||
if (!connection->IsAuthorized()) {
|
|
||||||
throw WebsocketException("Not logged in");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto iter = _impl->methods.find(method);
|
|
||||||
if (iter != _impl->methods.end()) {
|
|
||||||
auto &s = iter->second;
|
|
||||||
if (s.status > connection->GetStatus()) {
|
|
||||||
throw WebsocketException("Status too low");
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.handler(connection, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw WebsocketException("Unknown Method");
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::SetMethodHandler(const std::string &method, MethodHandler handler, int required_status)
|
|
||||||
{
|
|
||||||
//Reserved method names
|
|
||||||
if (method == "subscribe" ||
|
|
||||||
method == "unsubscribe" ||
|
|
||||||
method == "login") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_impl->methods[method] = MethodHandlerEntry(handler, required_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::SetLoginHandler(LoginHandler handler)
|
|
||||||
{
|
|
||||||
_impl->login_handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::DispatchEvent(WebsocketSubscriptionEvent evt, Json::Value data, int required_status)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
Json::Value event_obj;
|
|
||||||
event_obj["type"] = "event";
|
|
||||||
event_obj["event"] = (int)evt;
|
|
||||||
event_obj["data"] = data;
|
|
||||||
|
|
||||||
std::stringstream payload;
|
|
||||||
payload << event_obj;
|
|
||||||
|
|
||||||
for (auto &iter : _impl->connections) {
|
|
||||||
auto &c = iter.second;
|
|
||||||
|
|
||||||
if (c->GetStatus() >= required_status && IsSubscribed(c.get(), evt)) {
|
|
||||||
c->GetWebsocketConnection()->send(payload.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value EQ::Net::WebsocketServer::Login(WebsocketServerConnection *connection, const Json::Value ¶ms)
|
|
||||||
{
|
|
||||||
Json::Value ret;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Json::Value ret;
|
|
||||||
|
|
||||||
auto user = params[0].asString();
|
|
||||||
auto pass = params[1].asString();
|
|
||||||
|
|
||||||
auto r = _impl->login_handler(connection, user, pass);
|
|
||||||
|
|
||||||
if (r.logged_in) {
|
|
||||||
connection->SetAuthorized(true, r.account_name, r.account_id, 255);
|
|
||||||
ret["status"] = "Ok";
|
|
||||||
}
|
|
||||||
else if (user == "admin" && (connection->RemoteIP() == "127.0.0.1" || connection->RemoteIP() == "::")) {
|
|
||||||
r.logged_in = true;
|
|
||||||
r.account_id = 0;
|
|
||||||
connection->SetAuthorized(true, r.account_name, r.account_id, 255);
|
|
||||||
ret["status"] = "Ok";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
connection->SetAuthorized(false, "", 0, 0);
|
|
||||||
ret["status"] = "Not Authorized";
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch (std::exception &) {
|
|
||||||
throw WebsocketException("Unable to process login request");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value EQ::Net::WebsocketServer::Subscribe(WebsocketServerConnection *connection, const Json::Value ¶ms)
|
|
||||||
{
|
|
||||||
Json::Value ret;
|
|
||||||
|
|
||||||
try {
|
|
||||||
auto evt = params[0].asInt();
|
|
||||||
if (evt < 0 || evt >= SubscriptionEventMax) {
|
|
||||||
throw WebsocketException("Not a valid subscription");
|
|
||||||
}
|
|
||||||
|
|
||||||
DoSubscribe(connection, (WebsocketSubscriptionEvent)evt);
|
|
||||||
ret["status"] = "Ok";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch (WebsocketException &ex) {
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
catch (std::exception &) {
|
|
||||||
throw WebsocketException("Unable to process unsubscribe request");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value EQ::Net::WebsocketServer::Unsubscribe(WebsocketServerConnection *connection, const Json::Value ¶ms)
|
|
||||||
{
|
|
||||||
Json::Value ret;
|
|
||||||
|
|
||||||
try {
|
|
||||||
auto evt = params[0].asInt();
|
|
||||||
if (evt < 0 || evt >= SubscriptionEventMax) {
|
|
||||||
throw WebsocketException("Not a valid subscription");
|
|
||||||
}
|
|
||||||
|
|
||||||
DoUnsubscribe(connection, (WebsocketSubscriptionEvent)evt);
|
|
||||||
ret["status"] = "Ok";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch (WebsocketException &ex) {
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
catch (std::exception &) {
|
|
||||||
throw WebsocketException("Unable to process unsubscribe request");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::DoSubscribe(WebsocketServerConnection *connection, WebsocketSubscriptionEvent sub) {
|
|
||||||
auto &s = _impl->subscriptions[sub];
|
|
||||||
|
|
||||||
auto iter = s.find(connection);
|
|
||||||
if (iter == s.end()) {
|
|
||||||
s.insert(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::DoUnsubscribe(WebsocketServerConnection *connection, WebsocketSubscriptionEvent sub) {
|
|
||||||
auto &s = _impl->subscriptions[sub];
|
|
||||||
s.erase(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQ::Net::WebsocketServer::IsSubscribed(WebsocketServerConnection *connection, WebsocketSubscriptionEvent sub) {
|
|
||||||
auto &s = _impl->subscriptions[sub];
|
|
||||||
return s.count(connection) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServer::UnsubscribeAll(WebsocketServerConnection *connection) {
|
|
||||||
for (auto i = 0; i < SubscriptionEventMax; ++i) {
|
|
||||||
DoUnsubscribe(connection, (WebsocketSubscriptionEvent)i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "websocket_server_connection.h"
|
|
||||||
|
|
||||||
#include "../json/json.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
namespace EQ
|
|
||||||
{
|
|
||||||
namespace Net
|
|
||||||
{
|
|
||||||
enum WebsocketSubscriptionEvent : int
|
|
||||||
{
|
|
||||||
SubscriptionEventNone,
|
|
||||||
SubscriptionEventLog,
|
|
||||||
SubscriptionEventMax
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WebsocketLoginStatus
|
|
||||||
{
|
|
||||||
bool logged_in;
|
|
||||||
std::string account_name;
|
|
||||||
uint32 account_id;
|
|
||||||
int status;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WebsocketException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WebsocketException(const std::string &msg)
|
|
||||||
: _msg(msg.empty() ? "Unknown Error" : msg) { }
|
|
||||||
|
|
||||||
~WebsocketException() throw() {}
|
|
||||||
|
|
||||||
virtual char const *what() const throw() {
|
|
||||||
return _msg.c_str();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
const std::string _msg;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WebsocketServer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef std::function<Json::Value(WebsocketServerConnection*, const Json::Value&)> MethodHandler;
|
|
||||||
typedef std::function<WebsocketLoginStatus(WebsocketServerConnection*, const std::string&, const std::string&)> LoginHandler;
|
|
||||||
|
|
||||||
WebsocketServer(const std::string &addr, int port);
|
|
||||||
~WebsocketServer();
|
|
||||||
|
|
||||||
void SetMethodHandler(const std::string& method, MethodHandler handler, int required_status);
|
|
||||||
void SetLoginHandler(LoginHandler handler);
|
|
||||||
void DispatchEvent(WebsocketSubscriptionEvent evt, Json::Value data = Json::Value(), int required_status = 0);
|
|
||||||
private:
|
|
||||||
void ReleaseConnection(WebsocketServerConnection *connection);
|
|
||||||
Json::Value HandleRequest(WebsocketServerConnection *connection, const std::string& method, const Json::Value ¶ms);
|
|
||||||
|
|
||||||
Json::Value Login(WebsocketServerConnection *connection, const Json::Value ¶ms);
|
|
||||||
Json::Value Subscribe(WebsocketServerConnection *connection, const Json::Value ¶ms);
|
|
||||||
Json::Value Unsubscribe(WebsocketServerConnection *connection, const Json::Value ¶ms);
|
|
||||||
void DoSubscribe(WebsocketServerConnection *connection, WebsocketSubscriptionEvent sub);
|
|
||||||
void DoUnsubscribe(WebsocketServerConnection *connection, WebsocketSubscriptionEvent sub);
|
|
||||||
bool IsSubscribed(WebsocketServerConnection *connection, WebsocketSubscriptionEvent sub);
|
|
||||||
void UnsubscribeAll(WebsocketServerConnection *connection);
|
|
||||||
|
|
||||||
struct Impl;
|
|
||||||
std::unique_ptr<Impl> _impl;
|
|
||||||
|
|
||||||
friend class WebsocketServerConnection;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
#include "websocket_server_connection.h"
|
|
||||||
#include "websocket_server.h"
|
|
||||||
#include "../timer.h"
|
|
||||||
#include "../util/uuid.h"
|
|
||||||
#include <sstream>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
struct EQ::Net::WebsocketServerConnection::Impl {
|
|
||||||
WebsocketServer *parent;
|
|
||||||
std::shared_ptr<TCPConnection> connection;
|
|
||||||
std::shared_ptr<websocket_connection> ws_connection;
|
|
||||||
std::string id;
|
|
||||||
bool authorized;
|
|
||||||
std::string account_name;
|
|
||||||
uint32 account_id;
|
|
||||||
int status;
|
|
||||||
};
|
|
||||||
|
|
||||||
EQ::Net::WebsocketServerConnection::WebsocketServerConnection(WebsocketServer *parent,
|
|
||||||
std::shared_ptr<TCPConnection> connection,
|
|
||||||
std::shared_ptr<websocket_connection> ws_connection)
|
|
||||||
{
|
|
||||||
_impl.reset(new Impl());
|
|
||||||
_impl->parent = parent;
|
|
||||||
_impl->connection = connection;
|
|
||||||
_impl->id = EQ::Util::UUID::Generate().ToString();
|
|
||||||
_impl->authorized = false;
|
|
||||||
_impl->account_id = 0;
|
|
||||||
_impl->status = 0;
|
|
||||||
_impl->ws_connection = ws_connection;
|
|
||||||
_impl->ws_connection->set_message_handler(std::bind(&WebsocketServerConnection::OnMessage, this, std::placeholders::_1, std::placeholders::_2));
|
|
||||||
_impl->ws_connection->start();
|
|
||||||
|
|
||||||
connection->OnDisconnect([this](EQ::Net::TCPConnection *connection) {
|
|
||||||
_impl->parent->ReleaseConnection(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection->OnRead([this](EQ::Net::TCPConnection *c, const unsigned char *buffer, size_t buffer_size) {
|
|
||||||
_impl->ws_connection->read_all((const char*)buffer, buffer_size);
|
|
||||||
});
|
|
||||||
|
|
||||||
connection->Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
EQ::Net::WebsocketServerConnection::~WebsocketServerConnection()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::Net::WebsocketServerConnection::GetID() const
|
|
||||||
{
|
|
||||||
return _impl->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EQ::Net::WebsocketServerConnection::IsAuthorized() const
|
|
||||||
{
|
|
||||||
return _impl->authorized;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::Net::WebsocketServerConnection::GetAccountName() const
|
|
||||||
{
|
|
||||||
return _impl->account_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 EQ::Net::WebsocketServerConnection::GetAccountID() const
|
|
||||||
{
|
|
||||||
return _impl->account_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::Net::WebsocketServerConnection::GetStatus() const
|
|
||||||
{
|
|
||||||
return _impl->status;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string EQ::Net::WebsocketServerConnection::RemoteIP() const
|
|
||||||
{
|
|
||||||
return _impl->connection->RemoteIP();
|
|
||||||
}
|
|
||||||
|
|
||||||
int EQ::Net::WebsocketServerConnection::RemotePort() const
|
|
||||||
{
|
|
||||||
return _impl->connection->RemotePort();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<EQ::Net::websocket_connection> EQ::Net::WebsocketServerConnection::GetWebsocketConnection()
|
|
||||||
{
|
|
||||||
return _impl->ws_connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<EQ::Net::TCPConnection> EQ::Net::WebsocketServerConnection::GetTCPConnection()
|
|
||||||
{
|
|
||||||
return _impl->connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServerConnection::OnMessage(websocketpp::connection_hdl hdl, websocket_message_ptr msg)
|
|
||||||
{
|
|
||||||
BenchTimer timer;
|
|
||||||
timer.reset();
|
|
||||||
|
|
||||||
if (msg->get_opcode() == websocketpp::frame::opcode::text) {
|
|
||||||
try {
|
|
||||||
auto &payload = msg->get_payload();
|
|
||||||
|
|
||||||
std::stringstream ss(payload);
|
|
||||||
Json::Value root;
|
|
||||||
|
|
||||||
ss >> root;
|
|
||||||
|
|
||||||
auto method = root["method"].asString();
|
|
||||||
auto params = root["params"];
|
|
||||||
std::string id = "";
|
|
||||||
|
|
||||||
auto idNode = root["id"];
|
|
||||||
if (!idNode.isNull() && idNode.isString()) {
|
|
||||||
id = idNode.asString();
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value response;
|
|
||||||
response["type"] = "method";
|
|
||||||
response["data"] = _impl->parent->HandleRequest(this, method, params);
|
|
||||||
response["method"] = method;
|
|
||||||
if(id != "") {
|
|
||||||
response["id"] = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendResponse(response, timer.elapsed());
|
|
||||||
}
|
|
||||||
catch (std::exception &ex) {
|
|
||||||
Json::Value error;
|
|
||||||
error["type"] = "method";
|
|
||||||
error["error"] = fmt::format("{0}", ex.what());
|
|
||||||
SendResponse(error, timer.elapsed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServerConnection::SendResponse(const Json::Value &response, double time_elapsed)
|
|
||||||
{
|
|
||||||
Json::Value root = response;
|
|
||||||
root["execution_time"] = std::to_string(time_elapsed);
|
|
||||||
|
|
||||||
std::stringstream payload;
|
|
||||||
payload << root;
|
|
||||||
|
|
||||||
_impl->ws_connection->send(payload.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::WebsocketServerConnection::SetAuthorized(bool v, const std::string account_name, uint32 account_id, int status)
|
|
||||||
{
|
|
||||||
_impl->authorized = v;
|
|
||||||
_impl->account_name = account_name;
|
|
||||||
_impl->account_id = account_id;
|
|
||||||
_impl->status = status;
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "tcp_server.h"
|
|
||||||
#include "../types.h"
|
|
||||||
#include "../json/json-forwards.h"
|
|
||||||
#include <websocketpp/config/core.hpp>
|
|
||||||
#include <websocketpp/server.hpp>
|
|
||||||
|
|
||||||
namespace EQ
|
|
||||||
{
|
|
||||||
namespace Net
|
|
||||||
{
|
|
||||||
typedef websocketpp::server<websocketpp::config::core> websocket_server;
|
|
||||||
typedef websocketpp::connection<websocketpp::config::core> websocket_connection;
|
|
||||||
typedef websocket_server::message_ptr websocket_message_ptr;
|
|
||||||
|
|
||||||
class WebsocketServer;
|
|
||||||
class WebsocketServerConnection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WebsocketServerConnection(WebsocketServer *parent,
|
|
||||||
std::shared_ptr<TCPConnection> connection,
|
|
||||||
std::shared_ptr<websocket_connection> ws_connection);
|
|
||||||
~WebsocketServerConnection();
|
|
||||||
|
|
||||||
std::string GetID() const;
|
|
||||||
bool IsAuthorized() const;
|
|
||||||
std::string GetAccountName() const;
|
|
||||||
uint32 GetAccountID() const;
|
|
||||||
int GetStatus() const;
|
|
||||||
std::string RemoteIP() const;
|
|
||||||
int RemotePort() const;
|
|
||||||
private:
|
|
||||||
std::shared_ptr<websocket_connection> GetWebsocketConnection();
|
|
||||||
std::shared_ptr<TCPConnection> GetTCPConnection();
|
|
||||||
void OnMessage(websocketpp::connection_hdl hdl, websocket_message_ptr msg);
|
|
||||||
void SendResponse(const Json::Value &response, double time_elapsed);
|
|
||||||
void SetAuthorized(bool v, const std::string account_name, uint32 account_id, int status);
|
|
||||||
|
|
||||||
struct Impl;
|
|
||||||
std::unique_ptr<Impl> _impl;
|
|
||||||
|
|
||||||
friend class WebsocketServer;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eqemu_logsys.h"
|
|
||||||
#include "emu_opcodes.h"
|
#include "emu_opcodes.h"
|
||||||
#include "opcodemgr.h"
|
#include "opcodemgr.h"
|
||||||
|
|
||||||
@@ -32,7 +31,7 @@ OpcodeManager::OpcodeManager() {
|
|||||||
bool OpcodeManager::LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors) {
|
bool OpcodeManager::LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors) {
|
||||||
FILE *opf = fopen(filename, "r");
|
FILE *opf = fopen(filename, "r");
|
||||||
if(opf == nullptr) {
|
if(opf == nullptr) {
|
||||||
LogError("Unable to open opcodes file [{}]", filename);
|
fprintf(stderr, "Unable to open opcodes file '%s'. Thats bad.\n", filename);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+46
-36
@@ -85,7 +85,7 @@ namespace RoF
|
|||||||
//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();
|
||||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ namespace RoF
|
|||||||
signature.first_length = sizeof(structs::ClientZoneEntry_Struct);
|
signature.first_length = sizeof(structs::ClientZoneEntry_Struct);
|
||||||
signature.first_eq_opcode = opcodes->EmuToEQ(OP_ZoneEntry);
|
signature.first_eq_opcode = opcodes->EmuToEQ(OP_ZoneEntry);
|
||||||
into.RegisterPatch(signature, pname.c_str(), &opcodes, &struct_strategy);
|
into.RegisterPatch(signature, pname.c_str(), &opcodes, &struct_strategy);
|
||||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reload()
|
void Reload()
|
||||||
@@ -125,10 +125,10 @@ namespace RoF
|
|||||||
opfile += name;
|
opfile += name;
|
||||||
opfile += ".conf";
|
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);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ namespace RoF
|
|||||||
|
|
||||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -589,7 +589,7 @@ namespace RoF
|
|||||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
||||||
if (ob.tellp() == last_pos)
|
if (ob.tellp() == last_pos)
|
||||||
LogNetcode("RoF::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
Log(Logs::General, Logs::Netcode, "RoF::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||||
|
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
@@ -624,7 +624,6 @@ namespace RoF
|
|||||||
SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct);
|
SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct);
|
||||||
|
|
||||||
OUT(spawn_id);
|
OUT(spawn_id);
|
||||||
OUT(vehicle_id);
|
|
||||||
OUT(x_pos);
|
OUT(x_pos);
|
||||||
OUT(delta_x);
|
OUT(delta_x);
|
||||||
OUT(delta_y);
|
OUT(delta_y);
|
||||||
@@ -1522,7 +1521,7 @@ namespace RoF
|
|||||||
|
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
||||||
if (ob.tellp() == last_pos) {
|
if (ob.tellp() == last_pos) {
|
||||||
LogNetcode("RoF::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
Log(Logs::General, Logs::Netcode, "RoF::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2603,7 +2602,7 @@ namespace RoF
|
|||||||
|
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
|
||||||
LogNetcode("[STRUCTS] Player Profile Packet is [{}] bytes", outapp->GetWritePosition());
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Player Profile Packet is %i bytes", outapp->GetWritePosition());
|
||||||
|
|
||||||
auto NewBuffer = new unsigned char[outapp->GetWritePosition()];
|
auto NewBuffer = new unsigned char[outapp->GetWritePosition()];
|
||||||
memcpy(NewBuffer, outapp->pBuffer, outapp->GetWritePosition());
|
memcpy(NewBuffer, outapp->pBuffer, outapp->GetWritePosition());
|
||||||
@@ -3200,35 +3199,47 @@ namespace RoF
|
|||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
SerializeBuffer buf(in->size);
|
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||||
buf.WriteInt8(in->ReadUInt8()); // speak mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // journal mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // language
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // message type
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // target spawn id
|
|
||||||
|
|
||||||
std::string name;
|
unsigned char *__emu_buffer = in->pBuffer;
|
||||||
in->ReadString(name); // NPC names max out at 63 chars
|
|
||||||
|
|
||||||
buf.WriteString(name);
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // loc
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
|
|
||||||
std::string old_message;
|
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
in->ReadString(old_message);
|
|
||||||
|
|
||||||
ServerToRoFSayLink(new_message, old_message);
|
ServerToRoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
buf.WriteString(new_message);
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
|
in->pBuffer = new unsigned char[in->size];
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
char *OutBuffer = (char *)in->pBuffer;
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||||
delete in;
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[0]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||||
|
|
||||||
|
delete[] __emu_buffer;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_Stun)
|
ENCODE(OP_Stun)
|
||||||
@@ -3454,7 +3465,7 @@ namespace RoF
|
|||||||
|
|
||||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3805,7 +3816,7 @@ namespace RoF
|
|||||||
//determine and verify length
|
//determine and verify length
|
||||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4053,7 +4064,7 @@ namespace RoF
|
|||||||
Buffer += 29;
|
Buffer += 29;
|
||||||
if (Buffer != (BufferStart + PacketSize))
|
if (Buffer != (BufferStart + PacketSize))
|
||||||
{
|
{
|
||||||
LogNetcode("[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now [{}] from end", Buffer - (BufferStart + PacketSize));
|
Log(Logs::General, Logs::Netcode, "[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now %i from end", Buffer - (BufferStart + PacketSize));
|
||||||
}
|
}
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending zone spawn for %s packet is %i bytes", emu->name, outapp->size);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending zone spawn for %s packet is %i bytes", emu->name, outapp->size);
|
||||||
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
||||||
@@ -4315,7 +4326,6 @@ namespace RoF
|
|||||||
SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct);
|
SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct);
|
||||||
|
|
||||||
IN(spawn_id);
|
IN(spawn_id);
|
||||||
IN(vehicle_id);
|
|
||||||
IN(sequence);
|
IN(sequence);
|
||||||
IN(x_pos);
|
IN(x_pos);
|
||||||
IN(y_pos);
|
IN(y_pos);
|
||||||
@@ -4623,7 +4633,7 @@ namespace RoF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LogNetcode("Unhandled OP_GuildBank action");
|
Log(Logs::Detail, Logs::Netcode, "Unhandled OP_GuildBank action");
|
||||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5680,7 +5690,7 @@ namespace RoF
|
|||||||
RoFSlot = server_corpse_slot;
|
RoFSlot = server_corpse_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert Server Corpse Slot [{}] to RoF Corpse Main Slot [{}]", server_corpse_slot, RoFSlot);
|
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to RoF Corpse Main Slot %i", server_corpse_slot, RoFSlot);
|
||||||
|
|
||||||
return RoFSlot;
|
return RoFSlot;
|
||||||
}
|
}
|
||||||
|
|||||||
+99
-48
@@ -37,7 +37,6 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cinttypes>
|
|
||||||
|
|
||||||
|
|
||||||
namespace RoF2
|
namespace RoF2
|
||||||
@@ -86,7 +85,7 @@ namespace RoF2
|
|||||||
//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();
|
||||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +111,7 @@ namespace RoF2
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reload()
|
void Reload()
|
||||||
@@ -129,10 +128,10 @@ namespace RoF2
|
|||||||
opfile += name;
|
opfile += name;
|
||||||
opfile += ".conf";
|
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);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +419,7 @@ namespace RoF2
|
|||||||
|
|
||||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -658,7 +657,7 @@ namespace RoF2
|
|||||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
|
||||||
if (ob.tellp() == last_pos)
|
if (ob.tellp() == last_pos)
|
||||||
LogNetcode("RoF2::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
Log(Logs::General, Logs::Netcode, "RoF2::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||||
|
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
@@ -687,6 +686,25 @@ namespace RoF2
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_ClientUpdate)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(PlayerPositionUpdateServer_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(PlayerPositionUpdateServer_Struct, structs::PlayerPositionUpdateServer_Struct);
|
||||||
|
|
||||||
|
OUT(spawn_id);
|
||||||
|
OUT(x_pos);
|
||||||
|
OUT(delta_x);
|
||||||
|
OUT(delta_y);
|
||||||
|
OUT(z_pos);
|
||||||
|
OUT(delta_heading);
|
||||||
|
OUT(y_pos);
|
||||||
|
OUT(delta_z);
|
||||||
|
OUT(animation);
|
||||||
|
OUT(heading);
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
ENCODE(OP_Consider)
|
ENCODE(OP_Consider)
|
||||||
{
|
{
|
||||||
ENCODE_LENGTH_EXACT(Consider_Struct);
|
ENCODE_LENGTH_EXACT(Consider_Struct);
|
||||||
@@ -1571,7 +1589,7 @@ namespace RoF2
|
|||||||
|
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
|
||||||
if (ob.tellp() == last_pos) {
|
if (ob.tellp() == last_pos) {
|
||||||
LogNetcode("RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
Log(Logs::General, Logs::Netcode, "RoF2::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2670,7 +2688,7 @@ namespace RoF2
|
|||||||
// Think we need 1 byte of padding at the end
|
// Think we need 1 byte of padding at the end
|
||||||
outapp->WriteUInt8(0); // Unknown
|
outapp->WriteUInt8(0); // Unknown
|
||||||
|
|
||||||
LogNetcode("[STRUCTS] Player Profile Packet is [{}] bytes", outapp->GetWritePosition());
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Player Profile Packet is %i bytes", outapp->GetWritePosition());
|
||||||
|
|
||||||
auto NewBuffer = new unsigned char[outapp->GetWritePosition()];
|
auto NewBuffer = new unsigned char[outapp->GetWritePosition()];
|
||||||
memcpy(NewBuffer, outapp->pBuffer, outapp->GetWritePosition());
|
memcpy(NewBuffer, outapp->pBuffer, outapp->GetWritePosition());
|
||||||
@@ -3248,35 +3266,47 @@ namespace RoF2
|
|||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
SerializeBuffer buf(in->size);
|
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||||
buf.WriteInt8(in->ReadUInt8()); // speak mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // journal mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // language
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // message type
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // target spawn id
|
|
||||||
|
|
||||||
std::string name;
|
unsigned char *__emu_buffer = in->pBuffer;
|
||||||
in->ReadString(name); // NPC names max out at 63 chars
|
|
||||||
|
|
||||||
buf.WriteString(name);
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // loc
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
|
|
||||||
std::string old_message;
|
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
in->ReadString(old_message);
|
|
||||||
|
|
||||||
ServerToRoF2SayLink(new_message, old_message);
|
ServerToRoF2SayLink(new_message, old_message);
|
||||||
|
|
||||||
buf.WriteString(new_message);
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
|
in->pBuffer = new unsigned char[in->size];
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
char *OutBuffer = (char *)in->pBuffer;
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||||
delete in;
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[0]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||||
|
|
||||||
|
delete[] __emu_buffer;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_Stun)
|
ENCODE(OP_Stun)
|
||||||
@@ -3502,7 +3532,7 @@ namespace RoF2
|
|||||||
|
|
||||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3549,7 +3579,7 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
eq->items[i].Unknown18 = 0;
|
eq->items[i].Unknown18 = 0;
|
||||||
if (i < 80) {
|
if (i < 80) {
|
||||||
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016" PRId64, emu->SerialNumber[i]);
|
snprintf(eq->items[i].SerialNumber, sizeof(eq->items[i].SerialNumber), "%016d", emu->SerialNumber[i]);
|
||||||
eq->ItemCost[i] = emu->ItemCost[i];
|
eq->ItemCost[i] = emu->ItemCost[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -3612,7 +3642,7 @@ namespace RoF2
|
|||||||
|
|
||||||
OUT(TraderID);
|
OUT(TraderID);
|
||||||
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
||||||
LogTrading("ENCODE(OP_TraderDelItem): TraderID [{}], SerialNumber: [{}]", emu->TraderID, emu->ItemID);
|
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderDelItem): TraderID %d, SerialNumber: %d", emu->TraderID, emu->ItemID);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@@ -3643,7 +3673,7 @@ namespace RoF2
|
|||||||
eq->Traders2 = emu->Traders;
|
eq->Traders2 = emu->Traders;
|
||||||
eq->Items2 = emu->Items;
|
eq->Items2 = emu->Items;
|
||||||
|
|
||||||
LogTrading("ENCODE(OP_TraderShop): BazaarWelcome_Struct Code [{}], Traders [{}], Items [{}]",
|
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): BazaarWelcome_Struct Code %d, Traders %d, Items %d",
|
||||||
eq->Code, eq->Traders, eq->Items);
|
eq->Code, eq->Traders, eq->Items);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@@ -3666,14 +3696,14 @@ namespace RoF2
|
|||||||
OUT(Quantity);
|
OUT(Quantity);
|
||||||
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
snprintf(eq->SerialNumber, sizeof(eq->SerialNumber), "%016d", emu->ItemID);
|
||||||
|
|
||||||
LogTrading("ENCODE(OP_TraderShop): Buy Action [{}], Price [{}], Trader [{}], ItemID [{}], Quantity [{}], ItemName, [{}]",
|
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||||
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, emu->ItemName);
|
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, emu->ItemName);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogTrading("ENCODE(OP_TraderShop): Encode Size Unknown ([{}])", psize);
|
Log(Logs::Detail, Logs::Trading, "ENCODE(OP_TraderShop): Encode Size Unknown (%d)", psize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3928,7 +3958,7 @@ namespace RoF2
|
|||||||
//determine and verify length
|
//determine and verify length
|
||||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4260,7 +4290,7 @@ namespace RoF2
|
|||||||
Buffer += 29;
|
Buffer += 29;
|
||||||
if (Buffer != (BufferStart + PacketSize))
|
if (Buffer != (BufferStart + PacketSize))
|
||||||
{
|
{
|
||||||
LogNetcode("[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now [{}] from end", Buffer - (BufferStart + PacketSize));
|
Log(Logs::General, Logs::Netcode, "[ERROR] SPAWN ENCODE LOGIC PROBLEM: Buffer pointer is now %i from end", Buffer - (BufferStart + PacketSize));
|
||||||
}
|
}
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending zone spawn for %s packet is %i bytes", emu->name, outapp->size);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Sending zone spawn for %s packet is %i bytes", emu->name, outapp->size);
|
||||||
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
||||||
@@ -4527,6 +4557,27 @@ namespace RoF2
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_ClientUpdate)
|
||||||
|
{
|
||||||
|
// for some odd reason, there is an extra byte on the end of this on occasion..
|
||||||
|
DECODE_LENGTH_ATLEAST(structs::PlayerPositionUpdateClient_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(PlayerPositionUpdateClient_Struct, structs::PlayerPositionUpdateClient_Struct);
|
||||||
|
|
||||||
|
IN(spawn_id);
|
||||||
|
IN(sequence);
|
||||||
|
IN(x_pos);
|
||||||
|
IN(y_pos);
|
||||||
|
IN(z_pos);
|
||||||
|
IN(heading);
|
||||||
|
IN(delta_x);
|
||||||
|
IN(delta_y);
|
||||||
|
IN(delta_z);
|
||||||
|
IN(delta_heading);
|
||||||
|
IN(animation);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Consider)
|
DECODE(OP_Consider)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::Consider_Struct);
|
DECODE_LENGTH_EXACT(structs::Consider_Struct);
|
||||||
@@ -4820,7 +4871,7 @@ namespace RoF2
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LogNetcode("Unhandled OP_GuildBank action");
|
Log(Logs::Detail, Logs::Netcode, "Unhandled OP_GuildBank action");
|
||||||
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4973,7 +5024,7 @@ namespace RoF2
|
|||||||
emu->to_slot = RoF2ToServerSlot(eq->to_slot);
|
emu->to_slot = RoF2ToServerSlot(eq->to_slot);
|
||||||
IN(number_in_stack);
|
IN(number_in_stack);
|
||||||
|
|
||||||
//LogNetcode("[RoF2] MoveItem Slot from [{}] to [{}], Number [{}]", emu->from_slot, emu->to_slot, emu->number_in_stack);
|
//Log(Logs::General, Logs::Netcode, "[RoF2] MoveItem Slot from %u to %u, Number %u", emu->from_slot, emu->to_slot, emu->number_in_stack);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -5206,7 +5257,7 @@ namespace RoF2
|
|||||||
IN(Code);
|
IN(Code);
|
||||||
IN(TraderID);
|
IN(TraderID);
|
||||||
IN(Approval);
|
IN(Approval);
|
||||||
LogTrading("DECODE(OP_TraderShop): TraderClick_Struct Code [{}], TraderID [{}], Approval [{}]",
|
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderClick_Struct Code %d, TraderID %d, Approval %d",
|
||||||
eq->Code, eq->TraderID, eq->Approval);
|
eq->Code, eq->TraderID, eq->Approval);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
@@ -5220,7 +5271,7 @@ namespace RoF2
|
|||||||
emu->Beginning.Action = eq->Code;
|
emu->Beginning.Action = eq->Code;
|
||||||
IN(Traders);
|
IN(Traders);
|
||||||
IN(Items);
|
IN(Items);
|
||||||
LogTrading("DECODE(OP_TraderShop): BazaarWelcome_Struct Code [{}], Traders [{}], Items [{}]",
|
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): BazaarWelcome_Struct Code %d, Traders %d, Items %d",
|
||||||
eq->Code, eq->Traders, eq->Items);
|
eq->Code, eq->Traders, eq->Items);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
@@ -5237,20 +5288,20 @@ namespace RoF2
|
|||||||
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
memcpy(emu->ItemName, eq->ItemName, sizeof(emu->ItemName));
|
||||||
IN(ItemID);
|
IN(ItemID);
|
||||||
IN(Quantity);
|
IN(Quantity);
|
||||||
LogTrading("DECODE(OP_TraderShop): TraderBuy_Struct (Unknowns) Unknown004 [{}], Unknown008 [{}], Unknown012 [{}], Unknown076 [{}], Unknown276 [{}]",
|
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderBuy_Struct (Unknowns) Unknown004 %d, Unknown008 %d, Unknown012 %d, Unknown076 %d, Unknown276 %d",
|
||||||
eq->Unknown004, eq->Unknown008, eq->Unknown012, eq->Unknown076, eq->Unknown276);
|
eq->Unknown004, eq->Unknown008, eq->Unknown012, eq->Unknown076, eq->Unknown276);
|
||||||
LogTrading("DECODE(OP_TraderShop): TraderBuy_Struct Buy Action [{}], Price [{}], Trader [{}], ItemID [{}], Quantity [{}], ItemName, [{}]",
|
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): TraderBuy_Struct Buy Action %d, Price %d, Trader %d, ItemID %d, Quantity %d, ItemName, %s",
|
||||||
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, eq->ItemName);
|
eq->Action, eq->Price, eq->TraderID, eq->ItemID, eq->Quantity, eq->ItemName);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
else if (psize == 4)
|
else if (psize == 4)
|
||||||
{
|
{
|
||||||
LogTrading("DECODE(OP_TraderShop): Forwarding packet as-is with size 4");
|
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Forwarding packet as-is with size 4");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogTrading("DECODE(OP_TraderShop): Decode Size Unknown ([{}])", psize);
|
Log(Logs::Detail, Logs::Trading, "DECODE(OP_TraderShop): Decode Size Unknown (%d)", psize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5927,7 +5978,7 @@ namespace RoF2
|
|||||||
RoF2Slot = server_corpse_slot;
|
RoF2Slot = server_corpse_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert Server Corpse Slot [{}] to RoF2 Corpse Main Slot [{}]", server_corpse_slot, RoF2Slot);
|
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to RoF2 Corpse Main Slot %i", server_corpse_slot, RoF2Slot);
|
||||||
|
|
||||||
return RoF2Slot;
|
return RoF2Slot;
|
||||||
}
|
}
|
||||||
@@ -6110,7 +6161,7 @@ namespace RoF2
|
|||||||
ServerSlot = rof2_corpse_slot;
|
ServerSlot = rof2_corpse_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert RoF2 Corpse Main Slot [{}] to Server Corpse Slot [{}]", rof2_corpse_slot, ServerSlot);
|
Log(Logs::Detail, Logs::Netcode, "Convert RoF2 Corpse Main Slot %i to Server Corpse Slot %i", rof2_corpse_slot, ServerSlot);
|
||||||
|
|
||||||
return ServerSlot;
|
return ServerSlot;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ E(OP_CastSpell)
|
|||||||
E(OP_ChannelMessage)
|
E(OP_ChannelMessage)
|
||||||
E(OP_CharInventory)
|
E(OP_CharInventory)
|
||||||
E(OP_ClickObjectAction)
|
E(OP_ClickObjectAction)
|
||||||
|
E(OP_ClientUpdate)
|
||||||
E(OP_Consider)
|
E(OP_Consider)
|
||||||
E(OP_Damage)
|
E(OP_Damage)
|
||||||
E(OP_DeleteCharge)
|
E(OP_DeleteCharge)
|
||||||
@@ -154,6 +155,7 @@ D(OP_BuffRemoveRequest)
|
|||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
|
D(OP_ClientUpdate)
|
||||||
D(OP_Consider)
|
D(OP_Consider)
|
||||||
D(OP_ConsiderCorpse)
|
D(OP_ConsiderCorpse)
|
||||||
D(OP_Consume)
|
D(OP_Consume)
|
||||||
|
|||||||
@@ -1620,24 +1620,24 @@ struct RespawnWindow_Struct {
|
|||||||
*/
|
*/
|
||||||
struct PlayerPositionUpdateServer_Struct
|
struct PlayerPositionUpdateServer_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 spawn_id;
|
/*0000*/ uint16 spawn_id;
|
||||||
/*0002*/ uint16 vehicle_id;
|
/*0002*/ uint16 spawnId2;
|
||||||
/*0004*/ signed padding0004 : 12;
|
/*0004*/ signed padding0004 : 12;
|
||||||
signed y_pos : 19; // y coord
|
signed y_pos : 19; // y coord
|
||||||
unsigned padding : 1;
|
unsigned padding : 1;
|
||||||
/*0008*/ signed delta_z : 13; // change in z
|
/*0008*/ signed delta_z : 13; // change in z
|
||||||
signed delta_x : 13; // change in x
|
signed delta_x : 13; // change in x
|
||||||
signed padding0008 : 6;
|
signed padding0008 : 6;
|
||||||
/*0012*/ signed x_pos : 19; // x coord
|
/*0012*/ signed x_pos : 19; // x coord
|
||||||
unsigned heading : 12; // heading
|
unsigned heading : 12; // heading
|
||||||
signed padding0016 : 1;
|
signed padding0016 : 1;
|
||||||
/*0016*/ signed delta_heading : 10; // change in heading
|
/*0016*/ signed delta_heading : 10; // change in heading
|
||||||
signed z_pos : 19; // z coord
|
signed z_pos : 19; // z coord
|
||||||
signed padding0020 : 3;
|
signed padding0020 : 3;
|
||||||
/*0020*/ signed animation : 10; // animation
|
/*0020*/ signed animation : 10; // animation
|
||||||
signed delta_y : 13; // change in y
|
signed delta_y : 13; // change in y
|
||||||
signed padding0024 : 9;
|
signed padding0024 : 9;
|
||||||
/*0024*/
|
/*0024*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1648,23 +1648,22 @@ struct PlayerPositionUpdateServer_Struct
|
|||||||
*/
|
*/
|
||||||
struct PlayerPositionUpdateClient_Struct
|
struct PlayerPositionUpdateClient_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
/*0004*/ uint8 unknown0004[6]; // ***Placeholder
|
||||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
/*0010*/ float delta_x; // Change in x
|
||||||
/*0010*/ float delta_x; // Change in x
|
/*0014*/ unsigned heading : 12; // Directional heading
|
||||||
/*0014*/ unsigned heading : 12; // Directional heading
|
|
||||||
unsigned padding0040 : 20; // ***Placeholder
|
unsigned padding0040 : 20; // ***Placeholder
|
||||||
/*0018*/ float x_pos; // x coord (2nd loc value)
|
/*0018*/ float x_pos; // x coord (2nd loc value)
|
||||||
/*0022*/ float delta_z; // Change in z
|
/*0022*/ float delta_z; // Change in z
|
||||||
/*0026*/ float z_pos; // z coord (3rd loc value)
|
/*0026*/ float z_pos; // z coord (3rd loc value)
|
||||||
/*0030*/ float y_pos; // y coord (1st loc value)
|
/*0030*/ float y_pos; // y coord (1st loc value)
|
||||||
/*0034*/ unsigned animation : 10; // ***Placeholder
|
/*0034*/ unsigned animation : 10; // ***Placeholder
|
||||||
unsigned padding0024 : 22; // animation
|
unsigned padding0024 : 22; // animation
|
||||||
/*0038*/ float delta_y; // Change in y
|
/*0038*/ float delta_y; // Change in y
|
||||||
/*0042*/ signed delta_heading : 10; // change in heading
|
/*0042*/ signed delta_heading : 10; // change in heading
|
||||||
unsigned padding0041 : 22; // ***Placeholder
|
unsigned padding0041 : 22; // ***Placeholder
|
||||||
/*0046*/
|
/*0046*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4401,7 +4400,7 @@ struct SendAA_Struct {
|
|||||||
/*0104*/ uint32 special_category;
|
/*0104*/ uint32 special_category;
|
||||||
/*0108*/ uint8 shroud;
|
/*0108*/ uint8 shroud;
|
||||||
/*0109*/ uint8 unknown109;
|
/*0109*/ uint8 unknown109;
|
||||||
/*0110*/ uint8 reset_on_death; // timer is reset on death
|
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
/*0111*/ uint8 unknown111;
|
/*0111*/ uint8 unknown111;
|
||||||
/*0112*/ uint32 total_abilities;
|
/*0112*/ uint32 total_abilities;
|
||||||
/*0116*/ AA_Ability abilities[0];
|
/*0116*/ AA_Ability abilities[0];
|
||||||
|
|||||||
@@ -1609,21 +1609,21 @@ struct RespawnWindow_Struct {
|
|||||||
struct PlayerPositionUpdateServer_Struct
|
struct PlayerPositionUpdateServer_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 spawn_id;
|
/*0000*/ uint16 spawn_id;
|
||||||
/*0002*/ uint16 vehicle_id;
|
/*0002*/ uint16 spawnId2;
|
||||||
/*0004*/ signed padding0004 : 12;
|
/*0004*/ signed padding0004:12;
|
||||||
signed y_pos : 19; // y coord
|
signed y_pos:19; // y coord
|
||||||
unsigned padding : 1;
|
unsigned padding:1;
|
||||||
/*0008*/ signed delta_x : 13; // change in x
|
/*0008*/ signed delta_x:13; // change in x
|
||||||
signed delta_heading : 10; // change in heading
|
signed delta_heading:10;// change in heading
|
||||||
signed padding0008 : 9;
|
signed padding0008:9;
|
||||||
/*0012*/ signed delta_y : 13; // change in y
|
/*0012*/ signed delta_y:13; // change in y
|
||||||
signed z_pos : 19; // z coord
|
signed z_pos:19; // z coord
|
||||||
/*0016*/ signed x_pos : 19; // x coord
|
/*0016*/ signed x_pos:19; // x coord
|
||||||
signed animation : 10; // animation
|
signed animation:10; // animation
|
||||||
signed padding0016 : 3;
|
signed padding0016:3;
|
||||||
/*0020*/ unsigned heading : 12; // heading
|
/*0020*/ unsigned heading:12; // heading
|
||||||
signed delta_z : 13; // change in z
|
signed delta_z:13; // change in z
|
||||||
signed padding0020 : 7;
|
signed padding0020:7;
|
||||||
/*0024*/
|
/*0024*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1638,20 +1638,19 @@ struct PlayerPositionUpdateClient_Struct
|
|||||||
{
|
{
|
||||||
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
/*0000*/ uint16 sequence; // increments one each packet - Verified
|
||||||
/*0002*/ uint16 spawn_id; // Player's spawn id
|
/*0002*/ uint16 spawn_id; // Player's spawn id
|
||||||
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
|
/*0004*/ uint8 unknown0004[6]; // ***Placeholder
|
||||||
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
|
|
||||||
/*0010*/ float delta_y; // Change in y
|
/*0010*/ float delta_y; // Change in y
|
||||||
/*0014*/ float x_pos; // x coord (2nd loc value)
|
/*0014*/ float x_pos; // x coord (2nd loc value)
|
||||||
/*0018*/ float y_pos; // y coord (1st loc value)
|
/*0018*/ float y_pos; // y coord (1st loc value)
|
||||||
/*0022*/ signed delta_heading : 10; // change in heading
|
/*0022*/ signed delta_heading:10; // change in heading
|
||||||
unsigned animation : 10; // ***Placeholder
|
unsigned animation:10; // ***Placeholder
|
||||||
unsigned padding0024 : 12; // animation
|
unsigned padding0024:12; // animation
|
||||||
/*0026*/ float delta_z; // Change in z
|
/*0026*/ float delta_z; // Change in z
|
||||||
/*0030*/ float delta_x; // Change in x
|
/*0030*/ float delta_x; // Change in x
|
||||||
/*0034*/ float z_pos; // z coord (3rd loc value)
|
/*0034*/ float z_pos; // z coord (3rd loc value)
|
||||||
/*0038*/ unsigned heading : 12; // Directional heading
|
/*0038*/ unsigned heading:12; // Directional heading
|
||||||
unsigned padding0040 : 10; // ***Placeholder
|
unsigned padding0040:10; // ***Placeholder
|
||||||
unsigned padding0041 : 10; // ***Placeholder
|
unsigned padding0041:10; // ***Placeholder
|
||||||
/*0042*/
|
/*0042*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4341,7 +4340,7 @@ struct SendAA_Struct {
|
|||||||
/*0104*/ uint32 special_category;
|
/*0104*/ uint32 special_category;
|
||||||
/*0108*/ uint8 shroud;
|
/*0108*/ uint8 shroud;
|
||||||
/*0109*/ uint8 unknown109;
|
/*0109*/ uint8 unknown109;
|
||||||
/*0110*/ uint8 reset_on_death; // timer is reset on death
|
/*0110*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
/*0111*/ uint8 unknown111;
|
/*0111*/ uint8 unknown111;
|
||||||
/*0112*/ uint32 total_abilities;
|
/*0112*/ uint32 total_abilities;
|
||||||
/*0116*/ AA_Ability abilities[0];
|
/*0116*/ AA_Ability abilities[0];
|
||||||
|
|||||||
+46
-35
@@ -79,7 +79,7 @@ namespace SoD
|
|||||||
//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();
|
||||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ namespace SoD
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reload()
|
void Reload()
|
||||||
@@ -122,10 +122,10 @@ namespace SoD
|
|||||||
opfile += name;
|
opfile += name;
|
||||||
opfile += ".conf";
|
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);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ namespace SoD
|
|||||||
|
|
||||||
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
if (EntryCount == 0 || (in->size % sizeof(BazaarSearchResults_Struct)) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(BazaarSearchResults_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -400,7 +400,7 @@ namespace SoD
|
|||||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||||
if (ob.tellp() == last_pos)
|
if (ob.tellp() == last_pos)
|
||||||
LogNetcode("SoD::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
Log(Logs::General, Logs::Netcode, "SoD::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||||
|
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
@@ -1069,7 +1069,7 @@ namespace SoD
|
|||||||
|
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||||
if (ob.tellp() == last_pos) {
|
if (ob.tellp() == last_pos) {
|
||||||
LogNetcode("SoD::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
Log(Logs::General, Logs::Netcode, "SoD::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2069,35 +2069,47 @@ namespace SoD
|
|||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
SerializeBuffer buf(in->size);
|
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||||
buf.WriteInt8(in->ReadUInt8()); // speak mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // journal mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // language
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // message type
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // target spawn id
|
|
||||||
|
|
||||||
std::string name;
|
unsigned char *__emu_buffer = in->pBuffer;
|
||||||
in->ReadString(name); // NPC names max out at 63 chars
|
|
||||||
|
|
||||||
buf.WriteString(name);
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // loc
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
|
|
||||||
std::string old_message;
|
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
in->ReadString(old_message);
|
|
||||||
|
|
||||||
ServerToSoDSayLink(new_message, old_message);
|
ServerToSoDSayLink(new_message, old_message);
|
||||||
|
|
||||||
buf.WriteString(new_message);
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
|
in->pBuffer = new unsigned char[in->size];
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
char *OutBuffer = (char *)in->pBuffer;
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||||
delete in;
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[0]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||||
|
|
||||||
|
delete[] __emu_buffer;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_Stun)
|
ENCODE(OP_Stun)
|
||||||
@@ -2198,7 +2210,7 @@ namespace SoD
|
|||||||
|
|
||||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2435,7 +2447,7 @@ namespace SoD
|
|||||||
//determine and verify length
|
//determine and verify length
|
||||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2926,7 +2938,6 @@ namespace SoD
|
|||||||
IN(delta_z);
|
IN(delta_z);
|
||||||
IN(delta_heading);
|
IN(delta_heading);
|
||||||
IN(animation);
|
IN(animation);
|
||||||
emu->vehicle_id = 0;
|
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -3849,7 +3860,7 @@ namespace SoD
|
|||||||
SoDSlot = serverSlot;
|
SoDSlot = serverSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert Server Slot [{}] to SoD Slot [{}]", serverSlot, SoDSlot);
|
Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to SoD Slot %i", serverSlot, SoDSlot);
|
||||||
|
|
||||||
return SoDSlot;
|
return SoDSlot;
|
||||||
}
|
}
|
||||||
@@ -3866,7 +3877,7 @@ namespace SoD
|
|||||||
SoDSlot = server_corpse_slot - 2;
|
SoDSlot = server_corpse_slot - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert Server Corpse Slot [{}] to SoD Corpse Slot [{}]", server_corpse_slot, SoDSlot);
|
Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to SoD Corpse Slot %i", server_corpse_slot, SoDSlot);
|
||||||
|
|
||||||
return SoDSlot;
|
return SoDSlot;
|
||||||
}
|
}
|
||||||
@@ -3931,7 +3942,7 @@ namespace SoD
|
|||||||
server_slot = sod_slot;
|
server_slot = sod_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert SoD Slot [{}] to Server Slot [{}]", sod_slot, server_slot);
|
Log(Logs::Detail, Logs::Netcode, "Convert SoD Slot %i to Server Slot %i", sod_slot, server_slot);
|
||||||
|
|
||||||
return server_slot;
|
return server_slot;
|
||||||
}
|
}
|
||||||
@@ -3948,7 +3959,7 @@ namespace SoD
|
|||||||
server_slot = sod_corpse_slot + 2;
|
server_slot = sod_corpse_slot + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert SoD Corpse Slot [{}] to Server Corpse Slot [{}]", sod_corpse_slot, server_slot);
|
Log(Logs::Detail, Logs::Netcode, "Convert SoD Corpse Slot %i to Server Corpse Slot %i", sod_corpse_slot, server_slot);
|
||||||
|
|
||||||
return server_slot;
|
return server_slot;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1373,20 +1373,20 @@ struct RespawnWindow_Struct {
|
|||||||
struct PlayerPositionUpdateServer_Struct
|
struct PlayerPositionUpdateServer_Struct
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 spawn_id;
|
/*0000*/ uint16 spawn_id;
|
||||||
/*0002*/ signed padding0000 : 12; // ***Placeholder
|
/*0002*/ signed padding0000:12; // ***Placeholder
|
||||||
signed delta_x : 13; // change in x
|
signed delta_x:13; // change in x
|
||||||
signed padding0005 : 7; // ***Placeholder
|
signed padding0005:7; // ***Placeholder
|
||||||
/*0006*/ signed delta_heading : 10; // change in heading
|
/*0006*/ signed delta_heading:10;// change in heading
|
||||||
signed delta_y : 13; // change in y
|
signed delta_y:13; // change in y
|
||||||
signed padding0006 : 9; // ***Placeholder
|
signed padding0006:9; // ***Placeholder
|
||||||
/*0010*/ signed y_pos : 19; // y coord
|
/*0010*/ signed y_pos:19; // y coord
|
||||||
signed animation : 10; // animation
|
signed animation:10; // animation
|
||||||
signed padding0010 : 3; // ***Placeholder
|
signed padding0010:3; // ***Placeholder
|
||||||
/*0014*/ unsigned heading : 12; // heading
|
/*0014*/ unsigned heading:12; // heading
|
||||||
signed x_pos : 19; // x coord
|
signed x_pos:19; // x coord
|
||||||
signed padding0014 : 1; // ***Placeholder
|
signed padding0014:1; // ***Placeholder
|
||||||
/*0018*/ signed z_pos : 19; // z coord
|
/*0018*/ signed z_pos:19; // z coord
|
||||||
signed delta_z : 13; // change in z
|
signed delta_z:13; // change in z
|
||||||
/*0022*/
|
/*0022*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1404,16 +1404,16 @@ struct PlayerPositionUpdateClient_Struct
|
|||||||
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
/*0004*/ uint8 unknown0004[4]; // ***Placeholder
|
||||||
/*0008*/ float x_pos; // x coord (2nd loc value)
|
/*0008*/ float x_pos; // x coord (2nd loc value)
|
||||||
/*0012*/ float y_pos; // y coord (1st loc value)
|
/*0012*/ float y_pos; // y coord (1st loc value)
|
||||||
/*0016*/ signed delta_heading : 10; // change in heading
|
/*0016*/ signed delta_heading:10; // change in heading
|
||||||
unsigned padding0036 : 10; // animation
|
unsigned padding0036:10; // animation
|
||||||
unsigned padding0016 : 12; // ***Placeholder
|
unsigned padding0016:12; // ***Placeholder
|
||||||
/*0020*/ float delta_x; // Change in x
|
/*0020*/ float delta_x; // Change in x
|
||||||
/*0024*/ float delta_y; // Change in y
|
/*0024*/ float delta_y; // Change in y
|
||||||
/*0028*/ float z_pos; // z coord (3rd loc value)
|
/*0028*/ float z_pos; // z coord (3rd loc value)
|
||||||
/*0032*/ float delta_z; // Change in z
|
/*0032*/ float delta_z; // Change in z
|
||||||
/*0036*/ unsigned animation : 10; // ***Placeholder
|
/*0036*/ unsigned animation:10; // ***Placeholder
|
||||||
unsigned heading : 12; // Directional heading
|
unsigned heading:12; // Directional heading
|
||||||
unsigned padding0037 : 10; // ***Placeholder
|
unsigned padding0037:10; // ***Placeholder
|
||||||
/*0040*/
|
/*0040*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3780,7 +3780,7 @@ struct SendAA_Struct {
|
|||||||
/*0092*/ uint32 special_category;
|
/*0092*/ uint32 special_category;
|
||||||
/*0096*/ uint8 shroud;
|
/*0096*/ uint8 shroud;
|
||||||
/*0097*/ uint8 unknown97;
|
/*0097*/ uint8 unknown97;
|
||||||
/*0098*/ uint8 reset_on_death; // timer is reset on death
|
/*0098*/ uint8 layonhands; // 1 for lay on hands -- doesn't seem to matter?
|
||||||
/*0099*/ uint8 unknown99;
|
/*0099*/ uint8 unknown99;
|
||||||
/*0100*/ uint32 total_abilities;
|
/*0100*/ uint32 total_abilities;
|
||||||
/*0104*/ AA_Ability abilities[0];
|
/*0104*/ AA_Ability abilities[0];
|
||||||
|
|||||||
+43
-38
@@ -79,7 +79,7 @@ namespace SoF
|
|||||||
//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();
|
||||||
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
if (!opcodes->LoadOpcodes(opfile.c_str())) {
|
||||||
LogNetcode("[OPCODES] Error loading opcodes file [{}]. Not registering patch [{}]", opfile.c_str(), name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error loading opcodes file %s. Not registering patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ namespace SoF
|
|||||||
signature.first_eq_opcode = opcodes->EmuToEQ(OP_ZoneEntry);
|
signature.first_eq_opcode = opcodes->EmuToEQ(OP_ZoneEntry);
|
||||||
into.RegisterPatch(signature, pname.c_str(), &opcodes, &struct_strategy);
|
into.RegisterPatch(signature, pname.c_str(), &opcodes, &struct_strategy);
|
||||||
|
|
||||||
LogNetcode("[StreamIdentify] Registered patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[IDENTIFY] Registered patch %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reload()
|
void Reload()
|
||||||
@@ -120,10 +120,10 @@ namespace SoF
|
|||||||
opfile += name;
|
opfile += name;
|
||||||
opfile += ".conf";
|
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);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Error reloading opcodes file %s for patch %s.", opfile.c_str(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogNetcode("[OPCODES] Reloaded opcodes for patch [{}]", name);
|
Log(Logs::General, Logs::Netcode, "[OPCODES] Reloaded opcodes for patch %s", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +380,7 @@ namespace SoF
|
|||||||
for (int index = 0; index < item_count; ++index, ++eq) {
|
for (int index = 0; index < item_count; ++index, ++eq) {
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
|
||||||
if (ob.tellp() == last_pos)
|
if (ob.tellp() == last_pos)
|
||||||
LogNetcode("SoF::ENCODE(OP_CharInventory) Serialization failed on item slot [{}] during OP_CharInventory. Item skipped", eq->slot_id);
|
Log(Logs::General, Logs::Netcode, "SoF::ENCODE(OP_CharInventory) Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
|
||||||
|
|
||||||
last_pos = ob.tellp();
|
last_pos = ob.tellp();
|
||||||
}
|
}
|
||||||
@@ -864,7 +864,7 @@ namespace SoF
|
|||||||
|
|
||||||
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
|
||||||
if (ob.tellp() == last_pos) {
|
if (ob.tellp() == last_pos) {
|
||||||
LogNetcode("SoF::ENCODE(OP_ItemPacket) Serialization failed on item slot [{}]", int_struct->slot_id);
|
Log(Logs::General, Logs::Netcode, "SoF::ENCODE(OP_ItemPacket) Serialization failed on item slot %d.", int_struct->slot_id);
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1116,10 +1116,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
OUT(deity);
|
OUT(deity);
|
||||||
OUT(intoxication);
|
OUT(intoxication);
|
||||||
|
|
||||||
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
|
OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT);
|
||||||
eq->spellSlotRefresh[9] = 0; // 10th slot is not valid in this release
|
|
||||||
|
|
||||||
OUT(abilitySlotRefresh);
|
OUT(abilitySlotRefresh);
|
||||||
OUT(points); // Relocation Test
|
OUT(points); // Relocation Test
|
||||||
// OUT(unknown0166[4]);
|
// OUT(unknown0166[4]);
|
||||||
@@ -1180,10 +1177,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OUT(unknown4184[128]);
|
// OUT(unknown4184[128]);
|
||||||
|
|
||||||
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
OUT_array(mem_spells, spells::SPELL_GEM_COUNT);
|
||||||
eq->mem_spells[9] = 0xFFFFFFFFU; // 10th slot is not valid in this release
|
|
||||||
|
|
||||||
// OUT(unknown04396[32]);
|
// OUT(unknown04396[32]);
|
||||||
OUT(platinum);
|
OUT(platinum);
|
||||||
OUT(gold);
|
OUT(gold);
|
||||||
@@ -1726,35 +1720,47 @@ namespace SoF
|
|||||||
EQApplicationPacket *in = *p;
|
EQApplicationPacket *in = *p;
|
||||||
*p = nullptr;
|
*p = nullptr;
|
||||||
|
|
||||||
SerializeBuffer buf(in->size);
|
SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer;
|
||||||
buf.WriteInt8(in->ReadUInt8()); // speak mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // journal mode
|
|
||||||
buf.WriteInt8(in->ReadUInt8()); // language
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // message type
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // target spawn id
|
|
||||||
|
|
||||||
std::string name;
|
unsigned char *__emu_buffer = in->pBuffer;
|
||||||
in->ReadString(name);
|
|
||||||
|
|
||||||
buf.WriteString(name);
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
|
|
||||||
buf.WriteInt32(in->ReadUInt32()); // loc
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
buf.WriteInt32(in->ReadUInt32());
|
|
||||||
|
|
||||||
std::string old_message;
|
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
in->ReadString(old_message);
|
|
||||||
|
|
||||||
ServerToSoFSayLink(new_message, old_message);
|
ServerToSoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
buf.WriteString(new_message);
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
|
in->pBuffer = new unsigned char[in->size];
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
char *OutBuffer = (char *)in->pBuffer;
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]);
|
||||||
delete in;
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[0]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[1]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[2]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[3]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[4]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[5]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[6]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[7]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[8]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[9]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[10]);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->unknown12[11]);
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str());
|
||||||
|
|
||||||
|
delete[] __emu_buffer;
|
||||||
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENCODE(OP_Stun)
|
ENCODE(OP_Stun)
|
||||||
@@ -1827,7 +1833,7 @@ namespace SoF
|
|||||||
|
|
||||||
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
if (EntryCount == 0 || ((in->size % sizeof(Track_Struct))) != 0)
|
||||||
{
|
{
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Track_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1989,7 +1995,7 @@ namespace SoF
|
|||||||
//determine and verify length
|
//determine and verify length
|
||||||
int entrycount = in->size / sizeof(Spawn_Struct);
|
int entrycount = in->size / sizeof(Spawn_Struct);
|
||||||
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
if (entrycount == 0 || (in->size % sizeof(Spawn_Struct)) != 0) {
|
||||||
LogNetcode("[STRUCTS] Wrong size on outbound [{}]: Got [{}], expected multiple of [{}]", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(Spawn_Struct));
|
||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2387,7 +2393,6 @@ namespace SoF
|
|||||||
IN(delta_z);
|
IN(delta_z);
|
||||||
IN(delta_heading);
|
IN(delta_heading);
|
||||||
IN(animation);
|
IN(animation);
|
||||||
emu->vehicle_id = 0;
|
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@@ -3245,7 +3250,7 @@ namespace SoF
|
|||||||
sof_slot = server_slot;
|
sof_slot = server_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert Server Slot [{}] to SoF Slot [{}]", server_slot, sof_slot);
|
Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to SoF Slot %i", server_slot, sof_slot);
|
||||||
|
|
||||||
return sof_slot;
|
return sof_slot;
|
||||||
}
|
}
|
||||||
@@ -3331,7 +3336,7 @@ namespace SoF
|
|||||||
server_slot = sof_slot;
|
server_slot = sof_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogNetcode("Convert SoF Slot [{}] to Server Slot [{}]", sof_slot, server_slot);
|
Log(Logs::Detail, Logs::Netcode, "Convert SoF Slot %i to Server Slot %i", sof_slot, server_slot);
|
||||||
|
|
||||||
return server_slot;
|
return server_slot;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user