mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-26 03:42:28 +00:00
Compare commits
385 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25f5898bae | |||
| 934ff3dadf | |||
| e4ff76dceb | |||
| 6960a1a682 | |||
| d4174ca236 | |||
| 7854130a93 | |||
| e9c63c7d94 | |||
| 27e0665aae | |||
| ea2f431fce | |||
| 8bdcf7cb94 | |||
| 87cb74b851 | |||
| 26c267db1b | |||
| 99f8e6cef5 | |||
| b6917ec782 | |||
| eb51550109 | |||
| 9d1ace627c | |||
| ec3ef411a1 | |||
| 1394b6a4d2 | |||
| 7f41547963 | |||
| 2e4071cdcf | |||
| dc475a1bd7 | |||
| 59ad91a140 | |||
| abc27ab423 | |||
| c975dc2412 | |||
| e085f271f5 | |||
| 5a6314e1a9 | |||
| dc45e0d280 | |||
| 2e2c4d64fe | |||
| c5add503ab | |||
| fe2dcb6544 | |||
| 4fe44f4cb6 | |||
| 63a8d2d641 | |||
| abcb5d069f | |||
| d6b954a4b9 | |||
| 2415645b86 | |||
| e77a83f8c3 | |||
| a5d564a6fb | |||
| 2f4c91824e | |||
| 53e6f931c9 | |||
| a6efb1e8b5 | |||
| b2757143a8 | |||
| 6e5da0e558 | |||
| 6b8e74a29f | |||
| 203e63101a | |||
| 91257d599b | |||
| 491b358e28 | |||
| 180c3088ca | |||
| 97e4547192 | |||
| 0caee9026a | |||
| 0be7ead1d1 | |||
| 950489bc34 | |||
| 45da8cab61 | |||
| e778041198 | |||
| 97e50ced93 | |||
| 4491bb9a70 | |||
| 04fba27467 | |||
| fa47dd7f93 | |||
| b3fb5f00ab | |||
| e17fad9ae0 | |||
| bbdaacd3b0 | |||
| 61bd485449 | |||
| 4b405fe9fe | |||
| d5aaf7cee5 | |||
| 12e9e0f71d | |||
| 0a64e26672 | |||
| 11fc5a9e93 | |||
| 7bbcdfb479 | |||
| 3a530eb43b | |||
| 48a60114b7 | |||
| 06f1f36c95 | |||
| ccd9bd7d4c | |||
| fea6cbf633 | |||
| 460739d35c | |||
| 11e1edc99f | |||
| 7374660045 | |||
| 9e8d365ca7 | |||
| 14d69a0a14 | |||
| fe063637e9 | |||
| 232b1028d7 | |||
| 3624307385 | |||
| c0055cf357 | |||
| f9c1683d36 | |||
| 64df993c10 | |||
| 890ef696fe | |||
| 3f1848b01a | |||
| f7c4f1ff75 | |||
| dcb127f4b6 | |||
| 669b068978 | |||
| db2aeca38f | |||
| 1b3ca95f8c | |||
| c05baac551 | |||
| 939fc79d19 | |||
| a0e6fce057 | |||
| 452389b7a5 | |||
| dd184fa8b6 | |||
| 4a3e6b5edc | |||
| 7961d7afa8 | |||
| cc6bcf3295 | |||
| b73c2016cf | |||
| db7e8241ac | |||
| b7747b07db | |||
| 02ada0e496 | |||
| 7c819539c8 | |||
| e670c89163 | |||
| 9ecdf057db | |||
| b6448c840f | |||
| 0ba90df1f1 | |||
| 12dcbd0871 | |||
| b0be4ca8bd | |||
| 412eb5deaa | |||
| f030461bc7 | |||
| 8f5e7978ab | |||
| 2e55da2b2d | |||
| 16a8f88ae5 | |||
| 22d7ef6763 | |||
| 457e800c73 | |||
| 8393e50aa8 | |||
| b6497cdd6a | |||
| 218ef80f96 | |||
| a90d41480a | |||
| 67df6f62b7 | |||
| 4572dbc426 | |||
| e8cc160572 | |||
| 8c9adca852 | |||
| b53310e23b | |||
| 14f01dc2d7 | |||
| a4d6509e6d | |||
| fc835bfb0e | |||
| 9ec4e5ade0 | |||
| 6b65e93a06 | |||
| a0a28fef04 | |||
| 034feb4ff4 | |||
| 65c14b160e | |||
| c21d47f450 | |||
| 83ea9816b8 | |||
| e3f9b396ab | |||
| 2a6cf8c8e7 | |||
| be567af70d | |||
| 6494fbf916 | |||
| 2cc61ef8c1 | |||
| 5d7a7bb4b2 | |||
| 00f82f43a6 | |||
| d3ca636a70 | |||
| 01855d40df | |||
| 748602b04e | |||
| a97a9a0d1c | |||
| a78c754c0e | |||
| ef214f91e9 | |||
| 04a74df0b2 | |||
| c15bfe12eb | |||
| 5702f7bcd1 | |||
| 9a5bf53e11 | |||
| 69c6a7b89a | |||
| 2f0dbc5d15 | |||
| 93c79817cd | |||
| 3296287d70 | |||
| 774a7fa779 | |||
| 1ff4541a9f | |||
| 3448758c03 | |||
| ff4ccfa98f | |||
| d2c3c14ae0 | |||
| a470931fdd | |||
| 078db3460d | |||
| 0980a780d0 | |||
| 7f01bb509c | |||
| 4bb189cbf4 | |||
| b03e8ff0fb | |||
| 6179b7481e | |||
| 5f68e4a41a | |||
| e103422ca5 | |||
| 0cbfad975d | |||
| 2a20c69c69 | |||
| de2dfc1a7e | |||
| bad631df59 | |||
| e8f1aa253a | |||
| 889e57a5af | |||
| 5cfdeb928e | |||
| 7519b0225e | |||
| 04fdc54522 | |||
| f39155952f | |||
| 5acc181d64 | |||
| 2ae0b7dd3e | |||
| b0d4f095ef | |||
| 7c7a88650b | |||
| afaa8f4100 | |||
| 0d72295cc9 | |||
| 9d4f231619 | |||
| fcb0a47280 | |||
| 1e50f19f7e | |||
| 33bb5aa8e5 | |||
| 6a668f8aa5 | |||
| df499b22ab | |||
| 7bc00cb466 | |||
| 51f6108aab | |||
| c13f9f80d9 | |||
| 443abf9199 | |||
| 1556e05b2f | |||
| 1d645aa5f6 | |||
| 9f42da5bad | |||
| 4a8222f243 | |||
| db4c515853 | |||
| 462656a201 | |||
| ddd98be383 | |||
| 4ad3ebf36a | |||
| b5a2713a3a | |||
| 999fe10d86 | |||
| ce1472db1e | |||
| d6c6b78d8a | |||
| ee6c9a2ad7 | |||
| 3e4767269e | |||
| e0eb145081 | |||
| a6dd65435f | |||
| 26dc05c0dc | |||
| da20a6ab67 | |||
| 3949a31246 | |||
| e898be1ce9 | |||
| 2962575dda | |||
| 6a6045a21c | |||
| 717fe7dc8c | |||
| df69d12c0c | |||
| 99e49cb2ec | |||
| 5ee2856133 | |||
| 4a64048744 | |||
| 2ae795fd61 | |||
| 0829bc08b8 | |||
| 903a385229 | |||
| fafa33e190 | |||
| 90a01f7c53 | |||
| 19434197d4 | |||
| 18b62667f0 | |||
| 8ed7ca977f | |||
| 665e336946 | |||
| ccf8504dec | |||
| d107213fe1 | |||
| c115cbcd6a | |||
| 064ae7ba89 | |||
| 02302802b8 | |||
| 536e248424 | |||
| 5b56a23a8a | |||
| 97edb09fba | |||
| 85f7b10f90 | |||
| 0f49fbcfcd | |||
| e57979c3a8 | |||
| fc7c30977a | |||
| b3fd9dd88a | |||
| 4df9661903 | |||
| 8c363320d8 | |||
| d4afc78982 | |||
| 24de1d948a | |||
| ca0e85b4bc | |||
| 5b24d38d1e | |||
| 4a1d026215 | |||
| 5ef8f8c3a8 | |||
| 384de31989 | |||
| 5be3780a54 | |||
| 21e42714eb | |||
| 3474c00e7a | |||
| 3d6b0e5f74 | |||
| 9f619859d1 | |||
| 805a9c5f59 | |||
| 43329dc583 | |||
| 66fee56c47 | |||
| efb2ab57aa | |||
| 0a7d482299 | |||
| de047fb851 | |||
| 9836b5cf67 | |||
| c64591b8f7 | |||
| 3813162bac | |||
| 7099e17c7e | |||
| 2c75e8fcd4 | |||
| e8f01fb6ac | |||
| fd0764d4cb | |||
| 71b2bf6a64 | |||
| 2dcff247c8 | |||
| 93f19d3971 | |||
| bad44f35e2 | |||
| 4a339d49df | |||
| 57d0420399 | |||
| 90def9b882 | |||
| 84156829a7 | |||
| d210b1e5ff | |||
| 086538754e | |||
| 241f900dc4 | |||
| 604256a223 | |||
| 2dffc66c6f | |||
| 1bf24273d2 | |||
| c060280417 | |||
| bc6efd5f74 | |||
| efd6d2f9b1 | |||
| 9dd4cf71f1 | |||
| cfec31457c | |||
| 5ac5beb456 | |||
| 0e51131d67 | |||
| f9a87e26c9 | |||
| 9e16cd8ae8 | |||
| 9644f14746 | |||
| d9f545a5ec | |||
| 1cc32d92cf | |||
| 924e91cf64 | |||
| 9825c61a13 | |||
| 5a0a1b1ffd | |||
| a3bb7e7741 | |||
| a1251bdda8 | |||
| b90082d694 | |||
| a49fa42f35 | |||
| 7064a4156f | |||
| 106cb45b57 | |||
| 9a544650ee | |||
| 032d423add | |||
| 760b30ca0a | |||
| 6b08ca51cc | |||
| 268879b414 | |||
| 4c6dc960e4 | |||
| cc46b54f7f | |||
| 9e3b363d4a | |||
| b0d1dc5f04 | |||
| 158396937a | |||
| fb1467284c | |||
| 14addd4869 | |||
| 0a114fae9a | |||
| 2b224d42ad | |||
| 155ec9ac0d | |||
| 25b4b97c41 | |||
| 839f31b24d | |||
| 20728c31c4 | |||
| c6eb12ac16 | |||
| 34d21d4056 | |||
| d369b47ef4 | |||
| 404f7cada8 | |||
| 823e73336d | |||
| 0da6391be3 | |||
| 0348cb6b8e | |||
| b385a4385f | |||
| 6a9228ed6e | |||
| 8031bf0bcb | |||
| c1584da9cc | |||
| ee6f6f683c | |||
| 60707a14db | |||
| 54050924d8 | |||
| f727c9f75a | |||
| f410c89815 | |||
| 2e575652f6 | |||
| 8e831dce36 | |||
| 040c092795 | |||
| a25952910a | |||
| 66896a3121 | |||
| 4d2418af9d | |||
| 265b32f46f | |||
| 1cde55c535 | |||
| 369b5c2921 | |||
| bcc2e022dc | |||
| 0fef46a6c1 | |||
| b867d40774 | |||
| a489290eba | |||
| 549d731849 | |||
| 68a34565f9 | |||
| c05f951f81 | |||
| dc64561b3c | |||
| cb2aee2713 | |||
| 0730b6b588 | |||
| 826550acac | |||
| b71b3f5be0 | |||
| 1fe79f430c | |||
| e5dabe0afc | |||
| 5720ffbcb6 | |||
| 2b0c778ad1 | |||
| bf39a0540c | |||
| 08c8393988 | |||
| 8c12f7b431 | |||
| 037be84f38 | |||
| 4d355afe9d | |||
| 93eddf603b | |||
| 293f79268d | |||
| 7e35d5aa79 | |||
| f7e4fba584 | |||
| 01a0f906e1 | |||
| 0a11eaa092 | |||
| d0edb93d62 | |||
| 35c3778baf | |||
| abb41840f8 | |||
| cd63047e60 | |||
| 4fe5522212 | |||
| 0ccb18d017 | |||
| e010e41a83 | |||
| 886f80117c |
+80
-9
@@ -1,7 +1,8 @@
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: EQEmulator Server Linux CI
|
||||
name: Build Linux
|
||||
|
||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||
concurrency:
|
||||
@@ -10,18 +11,88 @@ concurrency:
|
||||
volumes:
|
||||
- name: cache
|
||||
host:
|
||||
path: /var/lib/cache
|
||||
path: /var/lib/cache-release
|
||||
|
||||
steps:
|
||||
- name: server-build
|
||||
# Source build script https://github.com/Akkadius/akk-stack/blob/master/containers/eqemu-server/Dockerfile#L20
|
||||
- name: Build Linux X64
|
||||
image: akkadius/eqemu-server:v11
|
||||
environment:
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
commands:
|
||||
- sudo chown eqemu:eqemu /drone/src/ * -R
|
||||
- sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
|
||||
- git submodule init && git submodule update && mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-O0 -g -DNDEBUG" -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
|
||||
- curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
|
||||
- ./bin/tests
|
||||
- ./utils/scripts/build/linux-build.sh
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /home/eqemu/.ccache/
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: exec
|
||||
name: Build Windows
|
||||
|
||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||
concurrency:
|
||||
limit: 1
|
||||
|
||||
platform:
|
||||
os: windows
|
||||
arch: amd64
|
||||
|
||||
steps:
|
||||
- name: Build Windows X64
|
||||
environment:
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
commands:
|
||||
- .\utils\scripts\build\windows-build.ps1
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: Publish Artifacts to Github
|
||||
|
||||
steps:
|
||||
- name: Upload Artifacts
|
||||
image: akkadius/eqemu-build-releaser:v3
|
||||
environment:
|
||||
RCLONE_CONFIG_REMOTE_TYPE: ftp
|
||||
RCLONE_FTP_HOST: drone.akkadius.com
|
||||
RCLONE_FTP_USER: artifacts
|
||||
RCLONE_FTP_PASS:
|
||||
from_secret: RCLONE_FTP_PASS
|
||||
GH_RELEASE_GITHUB_API_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
GITHUB_TOKEN:
|
||||
from_secret: GH_RELEASE_GITHUB_API_TOKEN
|
||||
commands:
|
||||
- ./utils/scripts/build/should-release/should-release
|
||||
- rclone config create remote ftp env_auth true > /dev/null
|
||||
- |
|
||||
rclone copy remote: --include "eqemu-server*.zip" .
|
||||
- gh-release --assets=eqemu-server-linux-x64.zip,eqemu-server-windows-x64.zip -y
|
||||
- |
|
||||
rclone delete remote: --include "eqemu-server*.zip"
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
|
||||
depends_on:
|
||||
- Build Windows
|
||||
- Build Linux
|
||||
|
||||
|
||||
|
||||
+9
-1
@@ -62,4 +62,12 @@ compile_flags.txt
|
||||
.cache/
|
||||
|
||||
# vscode generated settings
|
||||
.vscode/
|
||||
.vscode/
|
||||
|
||||
# Build pipeline
|
||||
!utils/scripts/build/
|
||||
!utils/scripts/build/should-release/should-release
|
||||
!utils/scripts/build/should-release/should-release.exe
|
||||
|
||||
# CMake Files
|
||||
cmake-build-relwithdebinfo/*
|
||||
|
||||
+1275
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
ELSE(MSVC)
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# EQEmulator Core Server
|
||||
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
||||
|:---:|:---:|:---:|
|
||||
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
||||
| Drone (Linux x64) | Drone (Windows x64) |
|
||||
|:---:|:---:|
|
||||
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
||||
|
||||
***
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
image: Visual Studio 2017
|
||||
configuration: RelWithDebInfo
|
||||
clone_folder: c:\projects\eqemu
|
||||
init:
|
||||
- ps: git config --global core.autocrlf input
|
||||
cache: c:\tools\vcpkg\installed\
|
||||
before_build:
|
||||
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||
build:
|
||||
project: C:\projects\eqemu\build\EQEmu.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- cmd: >-
|
||||
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||
|
||||
appveyor PushArtifact build_x64-bots.zip
|
||||
@@ -1,21 +0,0 @@
|
||||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
image: Visual Studio 2017
|
||||
configuration: RelWithDebInfo
|
||||
clone_folder: c:\projects\eqemu
|
||||
init:
|
||||
- ps: git config --global core.autocrlf input
|
||||
cache: c:\tools\vcpkg\installed\
|
||||
before_build:
|
||||
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||
build:
|
||||
project: C:\projects\eqemu\build\EQEmu.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
after_build:
|
||||
- cmd: >-
|
||||
7z a build_x64-no-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||
|
||||
appveyor PushArtifact build_x64-no-bots.zip
|
||||
@@ -86,7 +86,7 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
content_db.SetMysql(database.getMySQL());
|
||||
content_db.SetMySQL(database);
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
@@ -183,7 +183,7 @@ bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
if (row[0] && atoi(row[0]) > 0) {
|
||||
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
return Strings::ToInt(row[0]);
|
||||
}
|
||||
|
||||
void ExportSkillCaps(SharedDatabase *db)
|
||||
|
||||
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
content_db.SetMysql(database.getMySQL());
|
||||
content_db.SetMySQL(database);
|
||||
}
|
||||
|
||||
LogSys.SetDatabase(&database)
|
||||
@@ -241,10 +241,10 @@ void ImportSkillCaps(SharedDatabase *db) {
|
||||
}
|
||||
|
||||
int class_id, skill_id, level, cap;
|
||||
class_id = atoi(split[0].c_str());
|
||||
skill_id = atoi(split[1].c_str());
|
||||
level = atoi(split[2].c_str());
|
||||
cap = atoi(split[3].c_str());
|
||||
class_id = Strings::ToInt(split[0].c_str());
|
||||
skill_id = Strings::ToInt(split[1].c_str());
|
||||
level = Strings::ToInt(split[2].c_str());
|
||||
cap = Strings::ToInt(split[3].c_str());
|
||||
|
||||
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
||||
class_id, skill_id, level, cap);
|
||||
@@ -280,16 +280,16 @@ void ImportBaseData(SharedDatabase *db) {
|
||||
int level, class_id;
|
||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
||||
|
||||
level = atoi(split[0].c_str());
|
||||
class_id = atoi(split[1].c_str());
|
||||
hp = atof(split[2].c_str());
|
||||
mana = atof(split[3].c_str());
|
||||
end = atof(split[4].c_str());
|
||||
unk1 = atof(split[5].c_str());
|
||||
unk2 = atof(split[6].c_str());
|
||||
hp_fac = atof(split[7].c_str());
|
||||
mana_fac = atof(split[8].c_str());
|
||||
end_fac = atof(split[9].c_str());
|
||||
level = Strings::ToInt(split[0].c_str());
|
||||
class_id = Strings::ToInt(split[1].c_str());
|
||||
hp = Strings::ToFloat(split[2].c_str());
|
||||
mana = Strings::ToFloat(split[3].c_str());
|
||||
end = Strings::ToFloat(split[4].c_str());
|
||||
unk1 = Strings::ToFloat(split[5].c_str());
|
||||
unk2 = Strings::ToFloat(split[6].c_str());
|
||||
hp_fac = Strings::ToFloat(split[7].c_str());
|
||||
mana_fac = Strings::ToFloat(split[8].c_str());
|
||||
end_fac = Strings::ToFloat(split[9].c_str());
|
||||
|
||||
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
||||
"mana_fac, end_fac) VALUES(%d, %d, %f, %f, %f, %f, %f, %f, %f, %f)",
|
||||
@@ -339,8 +339,8 @@ void ImportDBStrings(SharedDatabase *db) {
|
||||
int id, type;
|
||||
std::string value;
|
||||
|
||||
id = atoi(split[0].c_str());
|
||||
type = atoi(split[1].c_str());
|
||||
id = Strings::ToInt(split[0].c_str());
|
||||
type = Strings::ToInt(split[1].c_str());
|
||||
|
||||
if(split.size() >= 3) {
|
||||
value = ::Strings::Escape(split[2]);
|
||||
|
||||
+13
-9
@@ -33,9 +33,11 @@ SET(common_sources
|
||||
eq_stream_proxy.cpp
|
||||
eqtime.cpp
|
||||
event_sub.cpp
|
||||
events/player_event_logs.cpp
|
||||
events/player_event_discord_formatter.cpp
|
||||
expedition_lockout_timer.cpp
|
||||
extprofile.cpp
|
||||
discord_manager.cpp
|
||||
discord/discord_manager.cpp
|
||||
faction.cpp
|
||||
file.cpp
|
||||
guild_base.cpp
|
||||
@@ -198,7 +200,6 @@ SET(repositories
|
||||
repositories/base/base_dynamic_zones_repository.h
|
||||
repositories/base/base_dynamic_zone_members_repository.h
|
||||
repositories/base/base_dynamic_zone_templates_repository.h
|
||||
repositories/base/base_eventlog_repository.h
|
||||
repositories/base/base_expeditions_repository.h
|
||||
repositories/base/base_expedition_lockouts_repository.h
|
||||
repositories/base/base_faction_association_repository.h
|
||||
@@ -218,7 +219,6 @@ SET(repositories
|
||||
repositories/base/base_guilds_repository.h
|
||||
repositories/base/base_guild_ranks_repository.h
|
||||
repositories/base/base_guild_relations_repository.h
|
||||
repositories/base/base_hackers_repository.h
|
||||
repositories/base/base_horses_repository.h
|
||||
repositories/base/base_instance_list_repository.h
|
||||
repositories/base/base_instance_list_player_repository.h
|
||||
@@ -264,6 +264,8 @@ SET(repositories
|
||||
repositories/base/base_pets_equipmentset_repository.h
|
||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||
repositories/base/base_player_titlesets_repository.h
|
||||
repositories/base/base_player_event_log_settings_repository.h
|
||||
repositories/base/base_player_event_logs_repository.h
|
||||
repositories/base/base_quest_globals_repository.h
|
||||
repositories/base/base_raid_details_repository.h
|
||||
repositories/base/base_raid_members_repository.h
|
||||
@@ -376,7 +378,6 @@ SET(repositories
|
||||
repositories/dynamic_zones_repository.h
|
||||
repositories/dynamic_zone_members_repository.h
|
||||
repositories/dynamic_zone_templates_repository.h
|
||||
repositories/eventlog_repository.h
|
||||
repositories/expeditions_repository.h
|
||||
repositories/expedition_lockouts_repository.h
|
||||
repositories/faction_association_repository.h
|
||||
@@ -396,7 +397,6 @@ SET(repositories
|
||||
repositories/guilds_repository.h
|
||||
repositories/guild_ranks_repository.h
|
||||
repositories/guild_relations_repository.h
|
||||
repositories/hackers_repository.h
|
||||
repositories/horses_repository.h
|
||||
repositories/instance_list_repository.h
|
||||
repositories/instance_list_player_repository.h
|
||||
@@ -442,6 +442,8 @@ SET(repositories
|
||||
repositories/pets_equipmentset_repository.h
|
||||
repositories/pets_equipmentset_entries_repository.h
|
||||
repositories/player_titlesets_repository.h
|
||||
repositories/player_event_log_settings_repository.h
|
||||
repositories/player_event_logs_repository.h
|
||||
repositories/quest_globals_repository.h
|
||||
repositories/raid_details_repository.h
|
||||
repositories/raid_members_repository.h
|
||||
@@ -507,7 +509,7 @@ SET(common_headers
|
||||
dbcore.h
|
||||
deity.h
|
||||
discord/discord.h
|
||||
discord_manager.h
|
||||
discord/discord_manager.h
|
||||
dynamic_zone_base.h
|
||||
emu_constants.h
|
||||
emu_limits.h
|
||||
@@ -530,6 +532,9 @@ SET(common_headers
|
||||
eq_stream_locator.h
|
||||
eq_stream_proxy.h
|
||||
eqtime.h
|
||||
events/player_event_logs.h
|
||||
events/player_event_discord_formatter.h
|
||||
events/player_events.h
|
||||
errmsg.h
|
||||
event_sub.h
|
||||
expedition_lockout_timer.h
|
||||
@@ -603,11 +608,11 @@ SET(common_headers
|
||||
unix.h
|
||||
useperl.h
|
||||
version.h
|
||||
zone_numbers.h
|
||||
zone_store.h
|
||||
event/event_loop.h
|
||||
event/task.h
|
||||
event/timer.h
|
||||
json/json_archive_single_line.h
|
||||
json/json.h
|
||||
json/json-forwards.h
|
||||
net/console_server.h
|
||||
@@ -661,8 +666,7 @@ SET(common_headers
|
||||
StackWalker/StackWalker.h
|
||||
util/memory_stream.h
|
||||
util/directory.h
|
||||
util/uuid.h
|
||||
)
|
||||
util/uuid.h)
|
||||
|
||||
SOURCE_GROUP(Event FILES
|
||||
event/event_loop.h
|
||||
|
||||
+115
-5
@@ -3,13 +3,96 @@
|
||||
#include "crash.h"
|
||||
#include "strings.h"
|
||||
#include "process/process.h"
|
||||
#include "http/httplib.h"
|
||||
#include "http/uri.h"
|
||||
#include "json/json.h"
|
||||
#include "version.h"
|
||||
#include "eqemu_config.h"
|
||||
#include "serverinfo.h"
|
||||
#include "rulesys.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
|
||||
#if WINDOWS
|
||||
#define popen _popen
|
||||
#endif
|
||||
|
||||
void SendCrashReport(const std::string &crash_report)
|
||||
{
|
||||
// can configure multiple endpoints if need be
|
||||
std::vector<std::string> endpoints = {
|
||||
"http://spire.akkadius.com/api/v1/analytics/server-crash-report",
|
||||
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development
|
||||
};
|
||||
|
||||
auto config = EQEmuConfig::get();
|
||||
for (auto &e: endpoints) {
|
||||
uri u(e);
|
||||
|
||||
std::string base_url = fmt::format("{}://{}", u.get_scheme(), u.get_host());
|
||||
if (u.get_port()) {
|
||||
base_url += fmt::format(":{}", u.get_port());
|
||||
}
|
||||
|
||||
// client
|
||||
httplib::Client r(base_url);
|
||||
r.set_connection_timeout(1, 0);
|
||||
r.set_read_timeout(1, 0);
|
||||
r.set_write_timeout(1, 0);
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
// os info
|
||||
auto os = EQ::GetOS();
|
||||
auto cpus = EQ::GetCPUs();
|
||||
auto process_id = EQ::GetPID();
|
||||
auto rss = EQ::GetRSS() / 1048576.0;
|
||||
auto uptime = static_cast<uint32>(EQ::GetUptime());
|
||||
|
||||
// payload
|
||||
Json::Value p;
|
||||
p["platform_name"] = GetPlatformName();
|
||||
p["crash_report"] = crash_report;
|
||||
p["server_version"] = CURRENT_VERSION;
|
||||
p["compile_date"] = COMPILE_DATE;
|
||||
p["compile_time"] = COMPILE_TIME;
|
||||
p["server_name"] = config->LongName;
|
||||
p["server_short_name"] = config->ShortName;
|
||||
p["uptime"] = uptime;
|
||||
p["os_machine"] = os.machine;
|
||||
p["os_release"] = os.release;
|
||||
p["os_version"] = os.version;
|
||||
p["os_sysname"] = os.sysname;
|
||||
p["process_id"] = process_id;
|
||||
p["rss_memory"] = rss;
|
||||
p["cpus"] = cpus.size();
|
||||
p["origination_info"] = "";
|
||||
|
||||
if (!LogSys.origination_info.zone_short_name.empty()) {
|
||||
p["origination_info"] = fmt::format(
|
||||
"{} ({}) instance_id [{}]",
|
||||
LogSys.origination_info.zone_short_name,
|
||||
LogSys.origination_info.zone_long_name,
|
||||
LogSys.origination_info.instance_id
|
||||
);
|
||||
}
|
||||
|
||||
std::stringstream payload;
|
||||
payload << p;
|
||||
|
||||
if (auto res = r.Post(e, payload.str(), "application/json")) {
|
||||
if (res->status == 200) {
|
||||
LogInfo("Sent crash report");
|
||||
}
|
||||
else {
|
||||
LogError("Failed to send crash report to [{}]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
||||
#include "StackWalker.h"
|
||||
@@ -21,22 +104,30 @@ public:
|
||||
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
|
||||
virtual void OnOutput(LPCSTR szText) {
|
||||
char buffer[4096];
|
||||
for(int i = 0; i < 4096; ++i) {
|
||||
if(szText[i] == 0) {
|
||||
for (int i = 0; i < 4096; ++i) {
|
||||
if (szText[i] == 0) {
|
||||
buffer[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
if(szText[i] == '\n' || szText[i] == '\r') {
|
||||
if (szText[i] == '\n' || szText[i] == '\r') {
|
||||
buffer[i] = ' ';
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
buffer[i] = szText[i];
|
||||
}
|
||||
}
|
||||
|
||||
std::string line = buffer;
|
||||
_lines.push_back(line);
|
||||
|
||||
Log(Logs::General, Logs::Crash, buffer);
|
||||
StackWalker::OnOutput(szText);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& const GetLines() { return _lines; }
|
||||
private:
|
||||
std::vector<std::string> _lines;
|
||||
};
|
||||
|
||||
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
@@ -110,7 +201,20 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||
|
||||
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||
EQEmuStackWalker sw;
|
||||
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||
|
||||
if (RuleB(Analytics, CrashReporting)) {
|
||||
std::string crash_report;
|
||||
auto& lines = sw.GetLines();
|
||||
|
||||
for (auto& line : lines) {
|
||||
crash_report += line;
|
||||
crash_report += "\n";
|
||||
}
|
||||
|
||||
SendCrashReport(crash_report);
|
||||
}
|
||||
}
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
@@ -181,12 +285,18 @@ void print_trace()
|
||||
}
|
||||
|
||||
std::ifstream input(temp_output_file);
|
||||
std::string crash_report;
|
||||
for (std::string line; getline(input, line);) {
|
||||
LogCrash("{}", line);
|
||||
crash_report += fmt::format("{}\n", line);
|
||||
}
|
||||
|
||||
std::remove(temp_output_file.c_str());
|
||||
|
||||
if (RuleB(Analytics, CrashReporting)) {
|
||||
SendCrashReport(crash_report);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ namespace cron
|
||||
{
|
||||
try
|
||||
{
|
||||
return static_cast<cron_int>(std::stoul(text.data()));
|
||||
return static_cast<cron_int>(Strings::ToUnsignedInt(text.data()));
|
||||
}
|
||||
catch (std::exception const & ex)
|
||||
{
|
||||
|
||||
+65
-103
@@ -121,10 +121,10 @@ uint32 Database::CheckLogin(const char* name, const char* password, const char *
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
auto id = std::stoul(row[0]);
|
||||
auto id = Strings::ToUnsignedInt(row[0]);
|
||||
|
||||
if (oStatus) {
|
||||
*oStatus = std::stoi(row[1]);
|
||||
*oStatus = Strings::ToInt(row[1]);
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -202,11 +202,11 @@ int16 Database::CheckStatus(uint32 account_id)
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
int16 status = std::stoi(row[0]);
|
||||
int16 status = Strings::ToInt(row[0]);
|
||||
int32 date_diff = 0;
|
||||
|
||||
if (row[1]) {
|
||||
date_diff = std::stoi(row[1]);
|
||||
date_diff = Strings::ToInt(row[1]);
|
||||
}
|
||||
|
||||
if (date_diff > 0) {
|
||||
@@ -345,7 +345,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
||||
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
|
||||
auto results = QueryDatabase(query);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
if (row[0] && atoi(row[0]) > 0){
|
||||
if (row[0] && Strings::ToInt(row[0]) > 0){
|
||||
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
||||
return false;
|
||||
}
|
||||
@@ -387,7 +387,7 @@ bool Database::DeleteCharacter(char *character_name)
|
||||
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
|
||||
auto results = QueryDatabase(query);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
character_id = atoi(row[0]);
|
||||
character_id = Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
if (character_id <= 0) {
|
||||
@@ -787,7 +787,7 @@ uint32 Database::GetCharacterID(const char *name) {
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1)
|
||||
{
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -812,10 +812,10 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
uint32 accountId = atoi(row[0]);
|
||||
uint32 accountId = Strings::ToUnsignedInt(row[0]);
|
||||
|
||||
if (oCharID)
|
||||
*oCharID = atoi(row[1]);
|
||||
*oCharID = Strings::ToUnsignedInt(row[1]);
|
||||
|
||||
return accountId;
|
||||
}
|
||||
@@ -832,7 +832,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
|
||||
@@ -852,14 +852,14 @@ uint32 Database::GetAccountIDByName(std::string account_name, std::string logins
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
auto account_id = std::stoul(row[0]);
|
||||
auto account_id = Strings::ToUnsignedInt(row[0]);
|
||||
|
||||
if (status) {
|
||||
*status = static_cast<int16>(std::stoi(row[1]));
|
||||
*status = static_cast<int16>(Strings::ToInt(row[1]));
|
||||
}
|
||||
|
||||
if (lsid) {
|
||||
*lsid = row[2] ? std::stoul(row[2]) : 0;
|
||||
*lsid = row[2] ? Strings::ToUnsignedInt(row[2]) : 0;
|
||||
}
|
||||
|
||||
return account_id;
|
||||
@@ -880,7 +880,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID
|
||||
|
||||
strcpy(name, row[0]);
|
||||
if (row[1] && oLSAccountID) {
|
||||
*oLSAccountID = atoi(row[1]);
|
||||
*oLSAccountID = Strings::ToUnsignedInt(row[1]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -968,7 +968,7 @@ bool Database::LoadVariables() {
|
||||
|
||||
std::string key, value;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
varcache.last_update = atoi(row[2]); // ahh should we be comparing if this is newer?
|
||||
varcache.last_update = Strings::ToUnsignedInt(row[2]); // ahh should we be comparing if this is newer?
|
||||
key = row[0];
|
||||
value = row[1];
|
||||
std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be
|
||||
@@ -1052,15 +1052,15 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
|
||||
auto row = results.begin();
|
||||
|
||||
if(graveyard_zoneid != nullptr)
|
||||
*graveyard_zoneid = atoi(row[0]);
|
||||
*graveyard_zoneid = Strings::ToUnsignedInt(row[0]);
|
||||
if(graveyard_x != nullptr)
|
||||
*graveyard_x = atof(row[1]);
|
||||
*graveyard_x = Strings::ToFloat(row[1]);
|
||||
if(graveyard_y != nullptr)
|
||||
*graveyard_y = atof(row[2]);
|
||||
*graveyard_y = Strings::ToFloat(row[2]);
|
||||
if(graveyard_z != nullptr)
|
||||
*graveyard_z = atof(row[3]);
|
||||
*graveyard_z = Strings::ToFloat(row[3]);
|
||||
if(graveyard_heading != nullptr)
|
||||
*graveyard_heading = atof(row[4]);
|
||||
*graveyard_heading = Strings::ToFloat(row[4]);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1168,13 +1168,13 @@ uint32 Database::GetAccountIDFromLSID(
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
account_id = std::stoi(row[0]);
|
||||
account_id = Strings::ToUnsignedInt(row[0]);
|
||||
|
||||
if (in_account_name) {
|
||||
strcpy(in_account_name, row[1]);
|
||||
}
|
||||
if (in_status) {
|
||||
*in_status = std::stoi(row[2]);
|
||||
*in_status = Strings::ToInt(row[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1198,7 +1198,7 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
|
||||
if (oAccountName)
|
||||
strcpy(oAccountName, row[0]);
|
||||
if (oStatus)
|
||||
*oStatus = atoi(row[1]);
|
||||
*oStatus = Strings::ToInt(row[1]);
|
||||
}
|
||||
|
||||
void Database::ClearMerchantTemp(){
|
||||
@@ -1244,7 +1244,7 @@ uint8 Database::GetServerType() {
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id)
|
||||
@@ -1281,44 +1281,6 @@ bool Database::MoveCharacterToZone(const char *charname, uint32 zone_id)
|
||||
return results.RowsAffected() != 0;
|
||||
}
|
||||
|
||||
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
|
||||
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return results.RowsAffected() != 0;
|
||||
}
|
||||
|
||||
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
|
||||
//Utilize the "hacker" table, but also give zone information.
|
||||
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return results.RowsAffected() != 0;
|
||||
}
|
||||
|
||||
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const std::string &hacked, const char* zone) {
|
||||
//Utilize the "hacker" table, but also give zone information.
|
||||
auto query = fmt::format("INSERT INTO hackers(account, name, hacked, zone) values('{}', '{}', '{}', '{}')",
|
||||
accountname, charactername, hacked, zone);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return results.RowsAffected() != 0;
|
||||
}
|
||||
|
||||
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
||||
{
|
||||
uint16 race_cap = 0;
|
||||
@@ -1334,7 +1296,7 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
|
||||
@@ -1350,12 +1312,12 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
|
||||
if (results.Success() && results.RowsAffected() != 0)
|
||||
{
|
||||
auto row = results.begin();
|
||||
skill_level = atoi(row[0]);
|
||||
skill_formula = atoi(row[1]);
|
||||
skill_cap = atoi(row[2]);
|
||||
if (atoi(row[3]) > skill_cap)
|
||||
skill_cap2 = (atoi(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
|
||||
skill_cap3 = atoi(row[4]);
|
||||
skill_level = Strings::ToUnsignedInt(row[0]);
|
||||
skill_formula = Strings::ToUnsignedInt(row[1]);
|
||||
skill_cap = Strings::ToUnsignedInt(row[2]);
|
||||
if (Strings::ToUnsignedInt(row[3]) > skill_cap)
|
||||
skill_cap2 = (Strings::ToUnsignedInt(row[3])-skill_cap)/10; //Split the post-50 skill cap into difference between pre-50 cap and post-50 cap / 10 to determine amount of points per level.
|
||||
skill_cap3 = Strings::ToUnsignedInt(row[4]);
|
||||
}
|
||||
|
||||
int race_skill = GetRaceSkill(skillid,in_race);
|
||||
@@ -1400,10 +1362,10 @@ uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
auto character_id = std::stoul(row[0]);
|
||||
*account_id = std::stoul(row[1]);
|
||||
*zone_id = std::stoul(row[2]);
|
||||
*instance_id = std::stoul(row[3]);
|
||||
auto character_id = Strings::ToUnsignedInt(row[0]);
|
||||
*account_id = Strings::ToUnsignedInt(row[1]);
|
||||
*zone_id = Strings::ToUnsignedInt(row[2]);
|
||||
*instance_id = Strings::ToUnsignedInt(row[3]);
|
||||
|
||||
return character_id;
|
||||
}
|
||||
@@ -1526,7 +1488,7 @@ uint32 Database::GetGroupID(const char* name){
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
||||
@@ -1540,7 +1502,7 @@ std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
||||
|
||||
if (results.Success() && results.RowCount()) {
|
||||
auto row = results.begin();
|
||||
group_id = std::stoul(row[0]);
|
||||
group_id = Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
if (!group_id) {
|
||||
@@ -1629,7 +1591,7 @@ char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* mainta
|
||||
strcpy(mentoree, row[5]);
|
||||
|
||||
if (mentor_percent)
|
||||
*mentor_percent = atoi(row[6]);
|
||||
*mentor_percent = Strings::ToInt(row[6]);
|
||||
|
||||
if(GLAA && results.LengthOfColumn(7) == sizeof(GroupLeadershipAA_Struct))
|
||||
memcpy(GLAA, row[7], sizeof(GroupLeadershipAA_Struct));
|
||||
@@ -1676,7 +1638,7 @@ uint8 Database::GetAgreementFlag(uint32 acctid) {
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
void Database::SetAgreementFlag(uint32 acctid) {
|
||||
@@ -1762,7 +1724,7 @@ uint32 Database::GetRaidID(const char* name)
|
||||
}
|
||||
|
||||
if (row[0]) // would it ever be possible to have a null here?
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1845,7 +1807,7 @@ void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
|
||||
strcpy(mentoree, row[4]);
|
||||
|
||||
if (mentor_percent)
|
||||
*mentor_percent = atoi(row[5]);
|
||||
*mentor_percent = Strings::ToInt(row[5]);
|
||||
|
||||
if (GLAA && results.LengthOfColumn(6) == sizeof(GroupLeadershipAA_Struct))
|
||||
memcpy(GLAA, row[6], sizeof(GroupLeadershipAA_Struct));
|
||||
@@ -2018,16 +1980,16 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
as->success.guk = atoi(row[0]);
|
||||
as->success.mir = atoi(row[1]);
|
||||
as->success.mmc = atoi(row[2]);
|
||||
as->success.ruj = atoi(row[3]);
|
||||
as->success.tak = atoi(row[4]);
|
||||
as->failure.guk = atoi(row[5]);
|
||||
as->failure.mir = atoi(row[6]);
|
||||
as->failure.mmc = atoi(row[7]);
|
||||
as->failure.ruj = atoi(row[8]);
|
||||
as->failure.tak = atoi(row[9]);
|
||||
as->success.guk = Strings::ToUnsignedInt(row[0]);
|
||||
as->success.mir = Strings::ToUnsignedInt(row[1]);
|
||||
as->success.mmc = Strings::ToUnsignedInt(row[2]);
|
||||
as->success.ruj = Strings::ToUnsignedInt(row[3]);
|
||||
as->success.tak = Strings::ToUnsignedInt(row[4]);
|
||||
as->failure.guk = Strings::ToUnsignedInt(row[5]);
|
||||
as->failure.mir = Strings::ToUnsignedInt(row[6]);
|
||||
as->failure.mmc = Strings::ToUnsignedInt(row[7]);
|
||||
as->failure.ruj = Strings::ToUnsignedInt(row[8]);
|
||||
as->failure.tak = Strings::ToUnsignedInt(row[9]);
|
||||
as->failure.total = as->failure.guk + as->failure.mir + as->failure.mmc + as->failure.ruj + as->failure.tak;
|
||||
as->success.total = as->success.guk + as->success.mir + as->success.mmc + as->success.ruj + as->success.tak;
|
||||
|
||||
@@ -2046,7 +2008,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
||||
@@ -2068,7 +2030,7 @@ uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
||||
return 0;
|
||||
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
||||
@@ -2082,7 +2044,7 @@ uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
return atoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2096,7 +2058,7 @@ int Database::CountInvSnapshots() {
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
int64 count = atoll(row[0]);
|
||||
int64 count = Strings::ToBigInt(row[0]);
|
||||
if (count > 2147483647)
|
||||
return -2;
|
||||
if (count < 0)
|
||||
@@ -2127,17 +2089,17 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
||||
eqTime.day = 1;
|
||||
eqTime.month = 1;
|
||||
eqTime.year = 3100;
|
||||
realtime = time(0);
|
||||
realtime = time(nullptr);
|
||||
}
|
||||
else{
|
||||
auto row = results.begin();
|
||||
|
||||
eqTime.minute = atoi(row[0]);
|
||||
eqTime.hour = atoi(row[1]);
|
||||
eqTime.day = atoi(row[2]);
|
||||
eqTime.month = atoi(row[3]);
|
||||
eqTime.year = atoi(row[4]);
|
||||
realtime = atoi(row[5]);
|
||||
eqTime.minute = Strings::ToUnsignedInt(row[0]);
|
||||
eqTime.hour = Strings::ToUnsignedInt(row[1]);
|
||||
eqTime.day = Strings::ToUnsignedInt(row[2]);
|
||||
eqTime.month = Strings::ToUnsignedInt(row[3]);
|
||||
eqTime.year = Strings::ToUnsignedInt(row[4]);
|
||||
realtime = Strings::ToBigInt(row[5]);
|
||||
}
|
||||
|
||||
return eqTime;
|
||||
@@ -2164,7 +2126,7 @@ int Database::GetIPExemption(std::string account_ip) {
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
return std::stoi(row[0]);
|
||||
return Strings::ToInt(row[0]);
|
||||
}
|
||||
|
||||
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
||||
@@ -2178,7 +2140,7 @@ void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
||||
auto results = QueryDatabase(query);
|
||||
if (results.Success() && results.RowCount()) {
|
||||
auto row = results.begin();
|
||||
exemption_id = std::stoul(row[0]);
|
||||
exemption_id = Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
query = fmt::format(
|
||||
@@ -2204,7 +2166,7 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
||||
|
||||
if (results.Success() && results.RowCount() > 0) {
|
||||
auto row = results.begin();
|
||||
return atoi(row[0]);;
|
||||
return Strings::ToInt(row[0]);;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//atoi is not uint32 or uint32 safe!!!!
|
||||
#define atoul(str) strtoul(str, nullptr, 10)
|
||||
|
||||
class MySQLRequestResult;
|
||||
class Client;
|
||||
@@ -108,9 +106,6 @@ public:
|
||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||
bool ReserveName(uint32 account_id, char *name);
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||
bool SetHackerFlag(const char *accountname, const char *charactername, const char *hacked);
|
||||
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const char *hacked, const char *zone);
|
||||
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
|
||||
bool UpdateName(const char *oldname, const char *newname);
|
||||
bool CopyCharacter(
|
||||
const std::string& source_character_name,
|
||||
|
||||
@@ -476,10 +476,11 @@ bool Database::CheckDatabaseConversions() {
|
||||
CheckDatabaseConvertPPDeblob();
|
||||
CheckDatabaseConvertCorpseDeblob();
|
||||
|
||||
RuleManager::Instance()->LoadRules(this, "default", false);
|
||||
auto *r = RuleManager::Instance();
|
||||
r->LoadRules(this, "default", false);
|
||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
||||
RuleManager::Instance()->SetRule("Bots:Enabled", "true", this, true, true);
|
||||
r->SetRule("Bots:Enabled", "true", this, true, true);
|
||||
}
|
||||
|
||||
/* Run EQEmu Server script (Checks for database updates) */
|
||||
@@ -498,7 +499,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
ExtendedProfile_Struct* e_pp;
|
||||
uint32 pplen = 0;
|
||||
uint32 i;
|
||||
int character_id = 0;
|
||||
uint32 character_id = 0;
|
||||
int account_id = 0;
|
||||
int number_of_characters = 0;
|
||||
int printppdebug = 0; /* Prints Player Profile */
|
||||
@@ -529,7 +530,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
rquery = StringFormat("SELECT COUNT(`id`) FROM `character_`");
|
||||
results = QueryDatabase(rquery);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
number_of_characters = atoi(row[0]);
|
||||
number_of_characters = Strings::ToInt(row[0]);
|
||||
printf("Number of Characters in Database: %i \n", number_of_characters);
|
||||
}
|
||||
|
||||
@@ -928,19 +929,19 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
char_iter_count++;
|
||||
squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", atoi(row[0]));
|
||||
squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", Strings::ToUnsignedInt(row[0]));
|
||||
auto results2 = QueryDatabase(squery);
|
||||
auto row2 = results2.begin();
|
||||
pp = (Convert::PlayerProfile_Struct*)row2[1];
|
||||
e_pp = (ExtendedProfile_Struct*)row2[11];
|
||||
character_id = atoi(row[0]);
|
||||
account_id = atoi(row2[4]);
|
||||
character_id = Strings::ToUnsignedInt(row[0]);
|
||||
account_id = Strings::ToInt(row2[4]);
|
||||
/* Convert some data from the character_ table that is still relevant */
|
||||
firstlogon = atoi(row2[5]);
|
||||
lfg = atoi(row2[6]);
|
||||
lfp = atoi(row2[7]);
|
||||
firstlogon = Strings::ToUnsignedInt(row2[5]);
|
||||
lfg = Strings::ToUnsignedInt(row2[6]);
|
||||
lfp = Strings::ToUnsignedInt(row2[7]);
|
||||
mailkey = row2[8];
|
||||
xtargets = atoi(row2[9]);
|
||||
xtargets = Strings::ToUnsignedInt(row2[9]);
|
||||
inspectmessage = row2[10];
|
||||
|
||||
/* Verify PP Integrity */
|
||||
@@ -1566,7 +1567,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses");
|
||||
results = QueryDatabase(rquery);
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", atoi(row[0]));
|
||||
std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", Strings::ToUnsignedInt(row[0]));
|
||||
auto results2 = QueryDatabase(squery);
|
||||
for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) {
|
||||
in_datasize = results2.LengthOfColumn(2);
|
||||
@@ -1598,7 +1599,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
c_type = "NULL";
|
||||
continue;
|
||||
}
|
||||
std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << atoi(row2[0]) << std::endl;
|
||||
std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << Strings::ToUnsignedInt(row2[0]) << std::endl;
|
||||
|
||||
if (is_sof){
|
||||
scquery = StringFormat("UPDATE `character_corpses` SET \n"
|
||||
@@ -1669,7 +1670,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
dbpc->item_tint[6].color,
|
||||
dbpc->item_tint[7].color,
|
||||
dbpc->item_tint[8].color,
|
||||
atoi(row2[0])
|
||||
Strings::ToUnsignedInt(row2[0])
|
||||
);
|
||||
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
|
||||
|
||||
@@ -1681,7 +1682,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
scquery = StringFormat("REPLACE INTO `character_corpse_items` \n"
|
||||
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
|
||||
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||
atoi(row2[0]),
|
||||
Strings::ToUnsignedInt(row2[0]),
|
||||
dbpc->items[i].equipSlot,
|
||||
dbpc->items[i].item_id,
|
||||
dbpc->items[i].charges,
|
||||
@@ -1697,7 +1698,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
}
|
||||
else{
|
||||
scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||
atoi(row2[0]),
|
||||
Strings::ToUnsignedInt(row2[0]),
|
||||
dbpc->items[i].equipSlot,
|
||||
dbpc->items[i].item_id,
|
||||
dbpc->items[i].charges,
|
||||
@@ -1777,7 +1778,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
dbpc_c->item_tint[6].color,
|
||||
dbpc_c->item_tint[7].color,
|
||||
dbpc_c->item_tint[8].color,
|
||||
atoi(row2[0])
|
||||
Strings::ToUnsignedInt(row2[0])
|
||||
);
|
||||
if (scquery != ""){ auto sc_results = QueryDatabase(scquery); }
|
||||
|
||||
@@ -1790,7 +1791,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
scquery = StringFormat("REPLACE INTO `character_corpse_items` \n"
|
||||
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
|
||||
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||
atoi(row2[0]),
|
||||
Strings::ToUnsignedInt(row2[0]),
|
||||
dbpc_c->items[i].equipSlot,
|
||||
dbpc_c->items[i].item_id,
|
||||
dbpc_c->items[i].charges,
|
||||
@@ -1806,7 +1807,7 @@ bool Database::CheckDatabaseConvertCorpseDeblob(){
|
||||
}
|
||||
else{
|
||||
scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
|
||||
atoi(row2[0]),
|
||||
Strings::ToUnsignedInt(row2[0]),
|
||||
dbpc_c->items[i].equipSlot,
|
||||
dbpc_c->items[i].item_id,
|
||||
dbpc_c->items[i].charges,
|
||||
|
||||
@@ -167,8 +167,8 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (atoi(row[0]) <= max) {
|
||||
instance_id = atoi(row[0]);
|
||||
if (Strings::ToInt(row[0]) <= max) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -194,7 +194,7 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
max_reserved_instance_id++;
|
||||
|
||||
for (auto row : results) {
|
||||
if (max_reserved_instance_id < std::stoul(row[0])) {
|
||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
@@ -301,7 +301,7 @@ uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 versio
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return static_cast<uint16>(std::stoul(row[0]));
|
||||
return static_cast<uint16>(Strings::ToUnsignedInt(row[0]));
|
||||
}
|
||||
|
||||
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
|
||||
@@ -328,7 +328,7 @@ std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id
|
||||
}
|
||||
|
||||
for (auto row : results) {
|
||||
l.push_back(static_cast<uint16>(std::stoul(row[0])));
|
||||
l.push_back(static_cast<uint16>(Strings::ToUnsignedInt(row[0])));
|
||||
}
|
||||
|
||||
return l;
|
||||
@@ -409,7 +409,7 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
||||
auto zone_id = GetInstanceZoneID(instance_id);
|
||||
auto version = GetInstanceVersion(instance_id);
|
||||
|
||||
auto l = GroupIdRepository::GetWhere(
|
||||
auto l = RaidMembersRepository::GetWhere(
|
||||
*this,
|
||||
fmt::format(
|
||||
"raidid = {}",
|
||||
|
||||
@@ -321,13 +321,11 @@ namespace DatabaseSchema {
|
||||
"discord_webhooks",
|
||||
"dynamic_zone_members",
|
||||
"dynamic_zones",
|
||||
"eventlog",
|
||||
"expedition_lockouts",
|
||||
"expeditions",
|
||||
"gm_ips",
|
||||
"group_id",
|
||||
"group_leaders",
|
||||
"hackers",
|
||||
"instance_list",
|
||||
"ip_exemptions",
|
||||
"item_tick",
|
||||
@@ -343,6 +341,8 @@ namespace DatabaseSchema {
|
||||
"respawn_times",
|
||||
"saylink",
|
||||
"server_scheduled_events",
|
||||
"player_event_log_settings",
|
||||
"player_event_logs",
|
||||
"shared_task_activity_state",
|
||||
"shared_task_dynamic_zones",
|
||||
"shared_task_members",
|
||||
|
||||
+54
-48
@@ -34,14 +34,16 @@
|
||||
|
||||
DBcore::DBcore()
|
||||
{
|
||||
mysql_init(&mysql);
|
||||
pHost = nullptr;
|
||||
pUser = nullptr;
|
||||
pPassword = nullptr;
|
||||
pDatabase = nullptr;
|
||||
pCompress = false;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
mysql = mysql_init(nullptr);
|
||||
mysqlOwner = true;
|
||||
pHost = nullptr;
|
||||
pUser = nullptr;
|
||||
pPassword = nullptr;
|
||||
pDatabase = nullptr;
|
||||
pCompress = false;
|
||||
pSSL = false;
|
||||
pStatus = Closed;
|
||||
m_mutex = new Mutex;
|
||||
}
|
||||
|
||||
DBcore::~DBcore()
|
||||
@@ -51,16 +53,10 @@ DBcore::~DBcore()
|
||||
* are re-using the default database connection pointer when we dont have an
|
||||
* external configuration setup ex: (content_database)
|
||||
*/
|
||||
std::string mysql_connection_host;
|
||||
if (mysql.host) {
|
||||
mysql_connection_host = mysql.host;
|
||||
if (mysqlOwner) {
|
||||
mysql_close(mysql);
|
||||
}
|
||||
|
||||
if (GetOriginHost() != mysql_connection_host) {
|
||||
return;
|
||||
}
|
||||
|
||||
mysql_close(&mysql);
|
||||
safe_delete_array(pHost);
|
||||
safe_delete_array(pUser);
|
||||
safe_delete_array(pPassword);
|
||||
@@ -70,17 +66,18 @@ DBcore::~DBcore()
|
||||
// Sends the MySQL server a keepalive
|
||||
void DBcore::ping()
|
||||
{
|
||||
if (!MDatabase.trylock()) {
|
||||
if (!m_mutex->trylock()) {
|
||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||
return;
|
||||
}
|
||||
mysql_ping(&mysql);
|
||||
MDatabase.unlock();
|
||||
mysql_ping(mysql);
|
||||
m_mutex->unlock();
|
||||
}
|
||||
|
||||
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
||||
{
|
||||
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool DBcore::DoesTableExist(std::string table_name)
|
||||
@@ -95,18 +92,16 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
BenchTimer timer;
|
||||
timer.reset();
|
||||
|
||||
LockMutex lock(&MDatabase);
|
||||
LockMutex lock(m_mutex);
|
||||
|
||||
// Reconnect if we are not connected before hand.
|
||||
if (pStatus != Connected) {
|
||||
Open();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// request query. != 0 indicates some kind of error.
|
||||
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
||||
unsigned int errorNumber = mysql_errno(&mysql);
|
||||
if (mysql_real_query(mysql, query, querylen) != 0) {
|
||||
unsigned int errorNumber = mysql_errno(mysql);
|
||||
|
||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
||||
pStatus = Error;
|
||||
@@ -130,26 +125,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
|
||||
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));
|
||||
|
||||
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];
|
||||
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));
|
||||
|
||||
/**
|
||||
* Error logging
|
||||
*/
|
||||
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(&mysql), mysql_error(&mysql), query);
|
||||
if (mysql_errno(mysql) > 0 && strlen(query) > 0) {
|
||||
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.
|
||||
MYSQL_RES *res = mysql_store_result(&mysql);
|
||||
MYSQL_RES *res = mysql_store_result(mysql);
|
||||
uint32 rowCount = 0;
|
||||
|
||||
if (res != nullptr) {
|
||||
@@ -158,10 +153,10 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
||||
|
||||
MySQLRequestResult requestResult(
|
||||
res,
|
||||
(uint32) mysql_affected_rows(&mysql),
|
||||
(uint32) mysql_affected_rows(mysql),
|
||||
rowCount,
|
||||
(uint32) mysql_field_count(&mysql),
|
||||
(uint32) mysql_insert_id(&mysql)
|
||||
(uint32) mysql_field_count(mysql),
|
||||
(uint32) mysql_insert_id(mysql)
|
||||
);
|
||||
|
||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||
@@ -207,7 +202,7 @@ 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.
|
||||
// LockMutex lock(&MDatabase);
|
||||
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
||||
return mysql_real_escape_string(mysql, tobuf, frombuf, fromlen);
|
||||
}
|
||||
|
||||
bool DBcore::Open(
|
||||
@@ -222,7 +217,7 @@ bool DBcore::Open(
|
||||
bool iSSL
|
||||
)
|
||||
{
|
||||
LockMutex lock(&MDatabase);
|
||||
LockMutex lock(m_mutex);
|
||||
safe_delete_array(pHost);
|
||||
safe_delete_array(pUser);
|
||||
safe_delete_array(pPassword);
|
||||
@@ -242,13 +237,13 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||
if (errbuf) {
|
||||
errbuf[0] = 0;
|
||||
}
|
||||
LockMutex lock(&MDatabase);
|
||||
LockMutex lock(m_mutex);
|
||||
if (GetStatus() == Connected) {
|
||||
return true;
|
||||
}
|
||||
if (GetStatus() == Error) {
|
||||
mysql_close(&mysql);
|
||||
mysql_init(&mysql); // Initialize structure again
|
||||
mysql_close(mysql);
|
||||
mysql_init(mysql); // Initialize structure again
|
||||
}
|
||||
if (!pHost) {
|
||||
return false;
|
||||
@@ -265,7 +260,7 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||
if (pSSL) {
|
||||
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;
|
||||
|
||||
std::string connected_origin_host = pHost;
|
||||
@@ -275,21 +270,16 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||
}
|
||||
else {
|
||||
if (errnum) {
|
||||
*errnum = mysql_errno(&mysql);
|
||||
*errnum = mysql_errno(mysql);
|
||||
}
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DBcore::SetMysql(MYSQL *mysql)
|
||||
{
|
||||
DBcore::mysql = *mysql;
|
||||
}
|
||||
|
||||
const std::string &DBcore::GetOriginHost() const
|
||||
{
|
||||
return origin_host;
|
||||
@@ -299,3 +289,19 @@ void DBcore::SetOriginHost(const std::string &origin_host)
|
||||
{
|
||||
DBcore::origin_host = origin_host;
|
||||
}
|
||||
|
||||
std::string DBcore::Escape(const std::string& s)
|
||||
{
|
||||
const std::size_t s_len = s.length();
|
||||
std::vector<char> temp((s_len * 2) + 1, '\0');
|
||||
mysql_real_escape_string(mysql, temp.data(), s.c_str(), s_len);
|
||||
|
||||
return temp.data();
|
||||
}
|
||||
|
||||
void DBcore::SetMutex(Mutex *mutex)
|
||||
{
|
||||
safe_delete(m_mutex);
|
||||
|
||||
DBcore::m_mutex = mutex;
|
||||
}
|
||||
|
||||
+14
-4
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <mysql.h>
|
||||
#include <string.h>
|
||||
#include <mutex>
|
||||
|
||||
class DBcore {
|
||||
public:
|
||||
@@ -27,16 +28,22 @@ public:
|
||||
void TransactionBegin();
|
||||
void TransactionCommit();
|
||||
void TransactionRollback();
|
||||
std::string Escape(const std::string& s);
|
||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||
void ping();
|
||||
MYSQL *getMySQL() { return &mysql; }
|
||||
void SetMysql(MYSQL *mysql);
|
||||
|
||||
const std::string &GetOriginHost() const;
|
||||
void SetOriginHost(const std::string &origin_host);
|
||||
|
||||
bool DoesTableExist(std::string table_name);
|
||||
|
||||
void SetMySQL(const DBcore &o)
|
||||
{
|
||||
mysql = o.mysql;
|
||||
mysqlOwner = false;
|
||||
}
|
||||
void SetMutex(Mutex *mutex);
|
||||
|
||||
protected:
|
||||
bool Open(
|
||||
const char *iHost,
|
||||
@@ -53,10 +60,13 @@ protected:
|
||||
private:
|
||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||
|
||||
MYSQL mysql;
|
||||
Mutex MDatabase;
|
||||
MYSQL* mysql;
|
||||
bool mysqlOwner;
|
||||
Mutex *m_mutex;
|
||||
eStatus pStatus;
|
||||
|
||||
std::mutex m_query_lock{};
|
||||
|
||||
std::string origin_host;
|
||||
|
||||
char *pHost;
|
||||
|
||||
+93
-13
@@ -1,22 +1,17 @@
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <cereal/archives/binary.hpp>
|
||||
#include "discord.h"
|
||||
#include "../http/httplib.h"
|
||||
#include "../json/json.h"
|
||||
#include "../strings.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../events/player_event_logs.h"
|
||||
|
||||
constexpr int MAX_RETRIES = 10;
|
||||
|
||||
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
||||
{
|
||||
// validate
|
||||
if (webhook_url.empty()) {
|
||||
LogDiscord("[webhook_url] is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
// validate
|
||||
if (webhook_url.find("http://") == std::string::npos && webhook_url.find("https://") == std::string::npos) {
|
||||
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
|
||||
if (!ValidateWebhookUrl(webhook_url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,7 +23,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||
|
||||
// client
|
||||
httplib::Client cli(base_url.c_str());
|
||||
httplib::Client cli(base_url);
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
@@ -46,9 +41,9 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
||||
int retries = 0;
|
||||
int retry_timer = 1000;
|
||||
while (retry) {
|
||||
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
|
||||
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
|
||||
if (res->status != 200 && res->status != 204) {
|
||||
LogError("Code [{}] Error [{}]", res->status, res->body);
|
||||
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
|
||||
}
|
||||
if (res->status == 429) {
|
||||
if (!res->body.empty()) {
|
||||
@@ -62,7 +57,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||
}
|
||||
|
||||
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
||||
retry_timer = Strings::ToInt(response["retry_after"].asString()) + 500;
|
||||
}
|
||||
|
||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||
@@ -81,6 +76,74 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
||||
}
|
||||
}
|
||||
|
||||
void Discord::SendPlayerEventMessage(
|
||||
const PlayerEvent::PlayerEventContainer &e,
|
||||
const std::string &webhook_url
|
||||
)
|
||||
{
|
||||
if (!ValidateWebhookUrl(webhook_url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto s = Strings::Split(webhook_url, '/');
|
||||
|
||||
// url
|
||||
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
|
||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||
|
||||
// client
|
||||
httplib::Client cli(base_url);
|
||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||
cli.set_read_timeout(15, 0); // 15 seconds
|
||||
cli.set_write_timeout(15, 0); // 15 seconds
|
||||
httplib::Headers headers = {
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
|
||||
if (payload.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool retry = true;
|
||||
int retries = 0;
|
||||
int retry_timer = 1000;
|
||||
while (retry) {
|
||||
if (auto res = cli.Post(endpoint, payload, "application/json")) {
|
||||
if (res->status != 200 && res->status != 204) {
|
||||
LogError("Code [{}] Error [{}]", res->status, res->body);
|
||||
}
|
||||
if (res->status == 429) {
|
||||
if (!res->body.empty()) {
|
||||
std::stringstream ss(res->body);
|
||||
Json::Value response;
|
||||
|
||||
try {
|
||||
ss >> response;
|
||||
}
|
||||
catch (std::exception const &ex) {
|
||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||
}
|
||||
|
||||
retry_timer = Strings::ToInt(response["retry_after"].asString()) + 500;
|
||||
}
|
||||
|
||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
|
||||
}
|
||||
if (res->status == 204) {
|
||||
retry = false;
|
||||
}
|
||||
if (retries > MAX_RETRIES) {
|
||||
LogDiscord("Retries exceeded for player event message");
|
||||
retry = false;
|
||||
}
|
||||
|
||||
retries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
|
||||
{
|
||||
if (category_id == Logs::LogCategory::MySQLQuery) {
|
||||
@@ -89,3 +152,20 @@ std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string
|
||||
|
||||
return message + "\n";
|
||||
}
|
||||
|
||||
bool Discord::ValidateWebhookUrl(const std::string &webhook_url)
|
||||
{
|
||||
// validate
|
||||
if (webhook_url.empty()) {
|
||||
LogDiscord("[webhook_url] is empty");
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate
|
||||
if (!Strings::Contains(webhook_url, "http://") && !Strings::Contains(webhook_url, "https://")) {
|
||||
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,16 @@
|
||||
|
||||
#include <string>
|
||||
#include "../types.h"
|
||||
#include "../http/httplib.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../events/player_events.h"
|
||||
|
||||
class Discord {
|
||||
public:
|
||||
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
||||
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
|
||||
static void SendPlayerEventMessage(const PlayerEvent::PlayerEventContainer& e, const std::string &webhook_url);
|
||||
static bool ValidateWebhookUrl(const std::string &webhook_url);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "discord_manager.h"
|
||||
#include "../common/discord/discord.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/strings.h"
|
||||
#include "../../common/discord/discord.h"
|
||||
#include "../events/player_event_logs.h"
|
||||
|
||||
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
||||
{
|
||||
@@ -55,7 +54,6 @@ void DiscordManager::ProcessMessageQueue()
|
||||
message = "";
|
||||
}
|
||||
}
|
||||
|
||||
// final flush
|
||||
if (!message.empty()) {
|
||||
Discord::SendWebhookMessage(
|
||||
@@ -67,3 +65,11 @@ void DiscordManager::ProcessMessageQueue()
|
||||
webhook_message_queue.clear();
|
||||
webhook_queue_lock.unlock();
|
||||
}
|
||||
|
||||
void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
|
||||
{
|
||||
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
|
||||
if (!w.empty()) {
|
||||
Discord::SendPlayerEventMessage(e, w);
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,15 @@
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "../common/types.h"
|
||||
#include "../../common/types.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../events/player_events.h"
|
||||
|
||||
class DiscordManager {
|
||||
public:
|
||||
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
||||
void ProcessMessageQueue();
|
||||
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
||||
private:
|
||||
std::mutex webhook_queue_lock{};
|
||||
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
||||
@@ -593,4 +593,29 @@ enum class ApplySpellType {
|
||||
Raid
|
||||
};
|
||||
|
||||
|
||||
namespace HeroicBonusBucket
|
||||
{
|
||||
const std::string WisMaxMana = "HWIS-MaxMana";
|
||||
const std::string WisManaRegen = "HWIS-ManaRegen";
|
||||
const std::string WisHealAmt = "HWIS-HealAmt";
|
||||
const std::string IntMaxMana = "HINT-MaxMana";
|
||||
const std::string IntManaRegen = "HINT-ManaRegen";
|
||||
const std::string IntSpellDmg = "HINT-SpellDmg";
|
||||
const std::string StrMeleeDamage = "HSTR-MeleeDamage";
|
||||
const std::string StrShieldAC = "HSTR-ShieldAC";
|
||||
const std::string StrMaxEndurance = "HSTR-MaxEndurance";
|
||||
const std::string StrEnduranceRegen = "HSTR-EnduranceRegen";
|
||||
const std::string StaMaxHP = "HSTA-MaxHP";
|
||||
const std::string StaHPRegen = "HSTA-HPRegen";
|
||||
const std::string StaMaxEndurance = "HSTA-MaxEndurance";
|
||||
const std::string StaEnduranceRegen = "HSTA-EnduranceRegen";
|
||||
const std::string AgiAvoidance = "HAGI-Avoidance";
|
||||
const std::string AgiMaxEndurance = "HAGI-MaxEndurance";
|
||||
const std::string AgiEnduranceRegen = "HAGI-EnduranceRegen";
|
||||
const std::string DexRangedDamage = "HDEX-RangedDamage";
|
||||
const std::string DexMaxEndurance = "HDEX-MaxEndurance";
|
||||
const std::string DexEnduranceRegen = "HDEX-EnduranceRegen";
|
||||
}
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
+27
-8
@@ -79,6 +79,8 @@
|
||||
#define ANIM_DEATH 0x73
|
||||
#define ANIM_LOOT 0x69
|
||||
|
||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||
|
||||
typedef enum {
|
||||
eaStanding = 0,
|
||||
eaSitting, //1
|
||||
@@ -1015,15 +1017,32 @@ enum Anonymity : uint8
|
||||
Roleplaying
|
||||
};
|
||||
|
||||
enum ZoningMessage : int8
|
||||
{
|
||||
ZoneNoMessage = 0,
|
||||
ZoneSuccess = 1,
|
||||
ZoneNotReady = -1,
|
||||
ZoneValidPC = -2,
|
||||
ZoneStoryZone = -3,
|
||||
ZoneNoExpansion = -6,
|
||||
enum ZoningMessage : int8 {
|
||||
ZoneNoMessage = 0,
|
||||
ZoneSuccess = 1,
|
||||
ZoneNotReady = -1,
|
||||
ZoneValidPC = -2,
|
||||
ZoneStoryZone = -3,
|
||||
ZoneNoExpansion = -6,
|
||||
ZoneNoExperience = -7
|
||||
};
|
||||
|
||||
enum class RecipeCountType : uint8
|
||||
{
|
||||
Component,
|
||||
Container,
|
||||
Fail,
|
||||
Salvage,
|
||||
Success
|
||||
};
|
||||
|
||||
#define ALT_CURRENCY_ID_RADIANT 4
|
||||
#define ALT_CURRENCY_ID_EBON 5
|
||||
|
||||
enum ResurrectionActions
|
||||
{
|
||||
Decline,
|
||||
Accept
|
||||
};
|
||||
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
+18
-12
@@ -29,7 +29,7 @@
|
||||
#include "textures.h"
|
||||
|
||||
|
||||
static const uint32 BUFF_COUNT = 25;
|
||||
static const uint32 BUFF_COUNT = 42;
|
||||
static const uint32 PET_BUFF_COUNT = 30;
|
||||
static const uint32 MAX_MERC = 100;
|
||||
static const uint32 MAX_MERC_GRADES = 10;
|
||||
@@ -3632,17 +3632,19 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
|
||||
};
|
||||
|
||||
struct MerchantList {
|
||||
uint32 id;
|
||||
uint32 slot;
|
||||
uint32 item;
|
||||
int16 faction_required;
|
||||
int8 level_required;
|
||||
uint16 alt_currency_cost;
|
||||
uint32 classes_required;
|
||||
uint8 probability;
|
||||
uint32 id;
|
||||
uint32 slot;
|
||||
uint32 item;
|
||||
int16 faction_required;
|
||||
int8 level_required;
|
||||
uint8 min_status;
|
||||
uint8 max_status;
|
||||
uint16 alt_currency_cost;
|
||||
uint32 classes_required;
|
||||
uint8 probability;
|
||||
std::string bucket_name;
|
||||
std::string bucket_value;
|
||||
uint8 bucket_comparison;
|
||||
uint8 bucket_comparison;
|
||||
};
|
||||
|
||||
struct TempMerchantList {
|
||||
@@ -4545,7 +4547,7 @@ struct ItemVerifyReply_Struct {
|
||||
struct ItemRecastDelay_Struct {
|
||||
/*000*/ uint32 recast_delay; // in seconds
|
||||
/*004*/ uint32 recast_type;
|
||||
/*008*/ uint32 unknown008;
|
||||
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
||||
/*012*/
|
||||
};
|
||||
|
||||
@@ -5520,7 +5522,11 @@ struct ServerLootItem_Struct {
|
||||
uint32 aug_4; // uint32 aug_4;
|
||||
uint32 aug_5; // uint32 aug_5;
|
||||
uint32 aug_6; // uint32 aug_5;
|
||||
uint8 attuned;
|
||||
bool attuned;
|
||||
std::string custom_data;
|
||||
uint32 ornamenticon {};
|
||||
uint32 ornamentidfile {};
|
||||
uint32 ornament_hero_model {};
|
||||
uint16 trivial_min_level;
|
||||
uint16 trivial_max_level;
|
||||
uint16 npc_min_level;
|
||||
|
||||
+19
-18
@@ -19,6 +19,7 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "eqemu_config.h"
|
||||
#include "misc_functions.h"
|
||||
#include "strings.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
@@ -33,13 +34,13 @@ void EQEmuConfig::parse_config()
|
||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||
LoginCount = 0;
|
||||
|
||||
if (_root["server"]["world"]["loginserver"].isObject()) {
|
||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||
LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||
LoginLegacy = false;
|
||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||
@@ -62,7 +63,7 @@ void EQEmuConfig::parse_config()
|
||||
|
||||
auto loginconfig = new LoginConfig;
|
||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||
|
||||
@@ -85,15 +86,15 @@ void EQEmuConfig::parse_config()
|
||||
Locked = false;
|
||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||
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 = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||
|
||||
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 = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||
TelnetEnabled = false;
|
||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
||||
|
||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||
WorldHTTPEnabled = false;
|
||||
|
||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||
@@ -108,9 +109,9 @@ void EQEmuConfig::parse_config()
|
||||
* UCS
|
||||
*/
|
||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||
|
||||
/**
|
||||
* Database
|
||||
@@ -118,7 +119,7 @@ void EQEmuConfig::parse_config()
|
||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||
DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||
|
||||
/**
|
||||
@@ -127,14 +128,14 @@ void EQEmuConfig::parse_config()
|
||||
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
||||
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
||||
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
||||
ContentDbPort = atoi(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||
|
||||
/**
|
||||
* QS
|
||||
*/
|
||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||
@@ -142,9 +143,9 @@ void EQEmuConfig::parse_config()
|
||||
/**
|
||||
* Zones
|
||||
*/
|
||||
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).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());
|
||||
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||
|
||||
/**
|
||||
* Files
|
||||
@@ -174,10 +175,10 @@ void EQEmuConfig::parse_config()
|
||||
/**
|
||||
* Launcher
|
||||
*/
|
||||
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "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());
|
||||
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||
#ifdef WIN32
|
||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||
#else
|
||||
|
||||
@@ -136,6 +136,7 @@ namespace Logs {
|
||||
PacketServerToServer,
|
||||
Bugs,
|
||||
QuestErrors,
|
||||
PlayerEvents,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -230,7 +231,8 @@ namespace Logs {
|
||||
"Packet C->S",
|
||||
"Packet S->S",
|
||||
"Bugs",
|
||||
"QuestErrors"
|
||||
"QuestErrors",
|
||||
"PlayerEvents",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -784,6 +784,16 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPlayerEvents(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::PlayerEvents))\
|
||||
OutF(LogSys, Logs::General, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogPlayerEventsDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::PlayerEvents))\
|
||||
OutF(LogSys, Logs::Detail, Logs::PlayerEvents, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,214 @@
|
||||
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||
|
||||
#include <string>
|
||||
#include "player_events.h"
|
||||
#include "../repositories/base/base_player_event_logs_repository.h"
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
|
||||
struct DiscordField {
|
||||
std::string name;
|
||||
std::string value;
|
||||
bool is_inline;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(name),
|
||||
CEREAL_NVP(value),
|
||||
cereal::make_nvp("inline", is_inline)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscordAuthor {
|
||||
std::string name;
|
||||
std::string icon_url;
|
||||
std::string url;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(name),
|
||||
CEREAL_NVP(icon_url),
|
||||
CEREAL_NVP(url)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscordEmbed {
|
||||
std::vector<DiscordField> fields;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string timestamp;
|
||||
DiscordAuthor author;
|
||||
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(fields),
|
||||
CEREAL_NVP(title),
|
||||
CEREAL_NVP(description),
|
||||
CEREAL_NVP(timestamp),
|
||||
CEREAL_NVP(author)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscordWebhook {
|
||||
std::vector<DiscordEmbed> embeds;
|
||||
std::string content;
|
||||
std::string avatar_url;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(embeds),
|
||||
CEREAL_NVP(avatar_url),
|
||||
CEREAL_NVP(content)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PlayerEventDiscordFormatter {
|
||||
public:
|
||||
static std::string GetCurrentTimestamp();
|
||||
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
|
||||
static std::string
|
||||
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
|
||||
static void BuildDiscordField(
|
||||
std::vector<DiscordField> *f,
|
||||
const std::string &name,
|
||||
const std::string &value,
|
||||
bool is_inline = true
|
||||
);
|
||||
static void BuildBaseEmbed(
|
||||
std::vector<DiscordEmbed> *e,
|
||||
const std::vector<DiscordField> &f,
|
||||
PlayerEvent::PlayerEventContainer c
|
||||
);
|
||||
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
|
||||
|
||||
static std::string FormatAAGainedEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::AAGainedEvent &e
|
||||
);
|
||||
static std::string FormatAAPurchasedEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::AAPurchasedEvent &e
|
||||
);
|
||||
static std::string FormatDeathEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DeathEvent &e
|
||||
);
|
||||
static std::string FormatFishSuccessEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::FishSuccessEvent &e
|
||||
);
|
||||
static std::string FormatForageSuccessEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::ForageSuccessEvent &e
|
||||
);
|
||||
static std::string FormatDestroyItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DestroyItemEvent &e
|
||||
);
|
||||
static std::string FormatDiscoverItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DiscoverItemEvent &e
|
||||
);
|
||||
static std::string FormatDroppedItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::DroppedItemEvent &e
|
||||
);
|
||||
static std::string FormatLevelGainedEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::LevelGainedEvent &e
|
||||
);
|
||||
static std::string FormatLevelLostEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::LevelLostEvent &e
|
||||
);
|
||||
static std::string FormatLootItemEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::LootItemEvent &e
|
||||
);
|
||||
static std::string FormatGroundSpawnPickupEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::GroundSpawnPickupEvent &e
|
||||
);
|
||||
static std::string FormatMerchantPurchaseEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::MerchantPurchaseEvent &e
|
||||
);
|
||||
static std::string FormatMerchantSellEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::MerchantSellEvent &e
|
||||
);
|
||||
static std::string FormatNPCHandinEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::HandinEvent &e
|
||||
);
|
||||
static std::string FormatSkillUpEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::SkillUpEvent &e
|
||||
);
|
||||
static std::string FormatTaskAcceptEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TaskAcceptEvent &e
|
||||
);
|
||||
static std::string FormatTaskCompleteEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TaskCompleteEvent &e
|
||||
);
|
||||
static std::string FormatTaskUpdateEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TaskUpdateEvent &e
|
||||
);
|
||||
static std::string FormatTradeEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TradeEvent &e
|
||||
);
|
||||
static std::string FormatTraderPurchaseEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TraderPurchaseEvent &e
|
||||
);
|
||||
static std::string FormatTraderSellEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::TraderSellEvent &e
|
||||
);
|
||||
static std::string FormatResurrectAcceptEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::ResurrectAcceptEvent &e
|
||||
);
|
||||
static std::string FormatSplitMoneyEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::SplitMoneyEvent &e
|
||||
);
|
||||
static std::string FormatCombineEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::CombineEvent &e
|
||||
);
|
||||
static std::string FormatZoningEvent(
|
||||
const PlayerEvent::PlayerEventContainer &c,
|
||||
const PlayerEvent::ZoningEvent &e
|
||||
);
|
||||
static DiscordWebhook BuildDiscordWebhook(
|
||||
const PlayerEvent::PlayerEventContainer &p,
|
||||
std::vector<DiscordEmbed> &embeds
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
||||
@@ -0,0 +1,708 @@
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include "player_event_logs.h"
|
||||
#include "player_event_discord_formatter.h"
|
||||
#include "../platform.h"
|
||||
#include "../rulesys.h"
|
||||
|
||||
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
// general initialization routine
|
||||
void PlayerEventLogs::Init()
|
||||
{
|
||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
||||
|
||||
ValidateDatabaseConnection();
|
||||
|
||||
// initialize settings array
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
m_settings[i].id = i;
|
||||
m_settings[i].event_name = PlayerEvent::EventName[i];
|
||||
m_settings[i].event_enabled = 1;
|
||||
m_settings[i].retention_days = 0;
|
||||
m_settings[i].discord_webhook_id = 0;
|
||||
}
|
||||
|
||||
SetSettingsDefaults();
|
||||
|
||||
// initialize settings from database
|
||||
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
||||
std::vector<int> db{};
|
||||
db.reserve(s.size());
|
||||
for (auto &e: s) {
|
||||
if (e.id >= PlayerEvent::MAX) {
|
||||
continue;
|
||||
}
|
||||
m_settings[e.id] = e;
|
||||
db.emplace_back(e.id);
|
||||
}
|
||||
|
||||
// insert entries that don't exist in database
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
||||
bool is_deprecated = Strings::Contains(PlayerEvent::EventName[i], "Deprecated");
|
||||
bool is_implemented = !Strings::Contains(PlayerEvent::EventName[i], "Unimplemented");
|
||||
|
||||
// remove when deprecated
|
||||
if (is_deprecated && is_in_database) {
|
||||
LogInfo("[Deprecated] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
||||
}
|
||||
// remove when unimplemented if present
|
||||
if (!is_implemented && is_in_database) {
|
||||
LogInfo("[Unimplemented] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
||||
}
|
||||
|
||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
||||
LogInfo(
|
||||
"[New] PlayerEvent [{}] ({})",
|
||||
PlayerEvent::EventName[i],
|
||||
i
|
||||
);
|
||||
|
||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
||||
c.id = i;
|
||||
c.event_name = PlayerEvent::EventName[i];
|
||||
c.event_enabled = m_settings[i].event_enabled;
|
||||
c.retention_days = m_settings[i].retention_days;
|
||||
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
||||
}
|
||||
}
|
||||
|
||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||
|
||||
// on initial boot process truncation
|
||||
if (processing_in_world || processing_in_qs) {
|
||||
ProcessRetentionTruncation();
|
||||
}
|
||||
}
|
||||
|
||||
// set the database object, during initialization
|
||||
PlayerEventLogs *PlayerEventLogs::SetDatabase(Database *db)
|
||||
{
|
||||
m_database = db;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// validates whether the connection is valid or not, used in initialization
|
||||
bool PlayerEventLogs::ValidateDatabaseConnection()
|
||||
{
|
||||
if (!m_database) {
|
||||
LogError("No database connection");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// determines if the passed in event is enabled or not
|
||||
// this is used to gate logic or events from firing off
|
||||
// this is used prior to building the events, we don't want to
|
||||
// build the events, send them through the stack in a function call
|
||||
// only to discard them immediately afterwards, very wasteful on resources
|
||||
// the quest api currently does this
|
||||
bool PlayerEventLogs::IsEventEnabled(PlayerEvent::EventType event)
|
||||
{
|
||||
return m_settings[event].event_enabled ? m_settings[event].event_enabled : false;
|
||||
}
|
||||
|
||||
// this processes any current player events on the queue
|
||||
void PlayerEventLogs::ProcessBatchQueue()
|
||||
{
|
||||
m_batch_queue_lock.lock();
|
||||
if (m_record_batch_queue.empty()) {
|
||||
m_batch_queue_lock.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
BenchTimer benchmark;
|
||||
|
||||
// flush many
|
||||
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
||||
LogPlayerEventsDetail(
|
||||
"Processing batch player event log queue of [{}] took [{}]",
|
||||
m_record_batch_queue.size(),
|
||||
benchmark.elapsed()
|
||||
);
|
||||
|
||||
// empty
|
||||
m_record_batch_queue = {};
|
||||
m_batch_queue_lock.unlock();
|
||||
}
|
||||
|
||||
// adds a player event to the queue
|
||||
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
||||
{
|
||||
m_batch_queue_lock.lock();
|
||||
m_record_batch_queue.emplace_back(log);
|
||||
m_batch_queue_lock.unlock();
|
||||
}
|
||||
|
||||
// fills common event data in the SendEvent function
|
||||
void PlayerEventLogs::FillPlayerEvent(
|
||||
const PlayerEvent::PlayerEvent &p,
|
||||
PlayerEventLogsRepository::PlayerEventLogs &n
|
||||
)
|
||||
{
|
||||
n.account_id = p.account_id;
|
||||
n.character_id = p.character_id;
|
||||
n.zone_id = p.zone_id;
|
||||
n.instance_id = p.instance_id;
|
||||
n.x = p.x;
|
||||
n.y = p.y;
|
||||
n.z = p.z;
|
||||
n.heading = p.heading;
|
||||
}
|
||||
|
||||
// builds the dynamic packet used to ship the player event over the wire
|
||||
// supports serializing the struct so it can be rebuilt on the other end
|
||||
std::unique_ptr<ServerPacket>
|
||||
PlayerEventLogs::BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e)
|
||||
{
|
||||
EQ::Net::DynamicPacket dyn_pack;
|
||||
dyn_pack.PutSerialize(0, e);
|
||||
auto pack_size = sizeof(ServerSendPlayerEvent_Struct) + dyn_pack.Length();
|
||||
auto pack = std::make_unique<ServerPacket>(ServerOP_PlayerEvent, static_cast<uint32_t>(pack_size));
|
||||
auto buf = reinterpret_cast<ServerSendPlayerEvent_Struct *>(pack->pBuffer);
|
||||
buf->cereal_size = static_cast<uint32_t>(dyn_pack.Length());
|
||||
memcpy(buf->cereal_data, dyn_pack.Data(), dyn_pack.Length());
|
||||
|
||||
return pack;
|
||||
}
|
||||
|
||||
const PlayerEventLogSettingsRepository::PlayerEventLogSettings *PlayerEventLogs::GetSettings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
bool PlayerEventLogs::IsEventDiscordEnabled(int32_t event_type_id)
|
||||
{
|
||||
// out of bounds check
|
||||
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure webhook id is set
|
||||
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ensure there is a matching webhook to begin with
|
||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string PlayerEventLogs::GetDiscordWebhookUrlFromEventType(int32_t event_type_id)
|
||||
{
|
||||
// out of bounds check
|
||||
if (event_type_id >= PlayerEvent::EventType::MAX) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// make sure webhook id is set
|
||||
if (m_settings[event_type_id].discord_webhook_id == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// ensure there is a matching webhook to begin with
|
||||
if (!LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url.empty()) {
|
||||
return LogSys.GetDiscordWebhooks()[m_settings[event_type_id].discord_webhook_id].webhook_url;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// GM_COMMAND | [x] Implemented Formatter
|
||||
// ZONING | [x] Implemented Formatter
|
||||
// AA_GAIN | [x] Implemented Formatter
|
||||
// AA_PURCHASE | [x] Implemented Formatter
|
||||
// FORAGE_SUCCESS | [x] Implemented Formatter
|
||||
// FORAGE_FAILURE | [x] Implemented Formatter
|
||||
// FISH_SUCCESS | [x] Implemented Formatter
|
||||
// FISH_FAILURE | [x] Implemented Formatter
|
||||
// ITEM_DESTROY | [x] Implemented Formatter
|
||||
// WENT_ONLINE | [x] Implemented Formatter
|
||||
// WENT_OFFLINE | [x] Implemented Formatter
|
||||
// LEVEL_GAIN | [x] Implemented Formatter
|
||||
// LEVEL_LOSS | [x] Implemented Formatter
|
||||
// LOOT_ITEM | [x] Implemented Formatter
|
||||
// MERCHANT_PURCHASE | [x] Implemented Formatter
|
||||
// MERCHANT_SELL | [x] Implemented Formatter
|
||||
// GROUP_JOIN | [] Implemented Formatter
|
||||
// GROUP_LEAVE | [] Implemented Formatter
|
||||
// RAID_JOIN | [] Implemented Formatter
|
||||
// RAID_LEAVE | [] Implemented Formatter
|
||||
// GROUNDSPAWN_PICKUP | [x] Implemented Formatter
|
||||
// NPC_HANDIN | [x] Implemented Formatter
|
||||
// SKILL_UP | [x] Implemented Formatter
|
||||
// TASK_ACCEPT | [x] Implemented Formatter
|
||||
// TASK_UPDATE | [x] Implemented Formatter
|
||||
// TASK_COMPLETE | [x] Implemented Formatter
|
||||
// TRADE | [] Implemented Formatter
|
||||
// GIVE_ITEM | [] Implemented Formatter
|
||||
// SAY | [x] Implemented Formatter
|
||||
// REZ_ACCEPTED | [x] Implemented Formatter
|
||||
// DEATH | [x] Implemented Formatter
|
||||
// COMBINE_FAILURE | [x] Implemented Formatter
|
||||
// COMBINE_SUCCESS | [x] Implemented Formatter
|
||||
// DROPPED_ITEM | [x] Implemented Formatter
|
||||
// SPLIT_MONEY | [x] Implemented Formatter
|
||||
// DZ_JOIN | [] Implemented Formatter
|
||||
// DZ_LEAVE | [] Implemented Formatter
|
||||
// TRADER_PURCHASE | [x] Implemented Formatter
|
||||
// TRADER_SELL | [x] Implemented Formatter
|
||||
// BANDOLIER_CREATE | [] Implemented Formatter
|
||||
// BANDOLIER_SWAP | [] Implemented Formatter
|
||||
// DISCOVER_ITEM | [X] Implemented Formatter
|
||||
|
||||
std::string PlayerEventLogs::GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e)
|
||||
{
|
||||
std::string payload;
|
||||
switch (e.player_event_log.event_type_id) {
|
||||
case PlayerEvent::AA_GAIN: {
|
||||
PlayerEvent::AAGainedEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatAAGainedEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::AA_PURCHASE: {
|
||||
PlayerEvent::AAPurchasedEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatAAPurchasedEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::COMBINE_FAILURE:
|
||||
case PlayerEvent::COMBINE_SUCCESS: {
|
||||
PlayerEvent::CombineEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatCombineEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::DEATH: {
|
||||
PlayerEvent::DeathEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatDeathEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::DISCOVER_ITEM: {
|
||||
PlayerEvent::DiscoverItemEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatDiscoverItemEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::DROPPED_ITEM: {
|
||||
PlayerEvent::DroppedItemEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatDroppedItemEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FISH_FAILURE: {
|
||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FISH_SUCCESS: {
|
||||
PlayerEvent::FishSuccessEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatFishSuccessEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FORAGE_FAILURE: {
|
||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::FORAGE_SUCCESS: {
|
||||
PlayerEvent::ForageSuccessEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatForageSuccessEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::ITEM_DESTROY: {
|
||||
PlayerEvent::DestroyItemEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatDestroyItemEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::LEVEL_GAIN: {
|
||||
PlayerEvent::LevelGainedEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatLevelGainedEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::LEVEL_LOSS: {
|
||||
PlayerEvent::LevelLostEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatLevelLostEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::LOOT_ITEM: {
|
||||
PlayerEvent::LootItemEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatLootItemEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::GROUNDSPAWN_PICKUP: {
|
||||
PlayerEvent::GroundSpawnPickupEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatGroundSpawnPickupEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::NPC_HANDIN: {
|
||||
PlayerEvent::HandinEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatNPCHandinEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::SAY: {
|
||||
PlayerEvent::SayEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatEventSay(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::GM_COMMAND: {
|
||||
PlayerEvent::GMCommandEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatGMCommand(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::SKILL_UP: {
|
||||
PlayerEvent::SkillUpEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatSkillUpEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::SPLIT_MONEY: {
|
||||
PlayerEvent::SplitMoneyEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatSplitMoneyEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::TASK_ACCEPT: {
|
||||
PlayerEvent::TaskAcceptEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatTaskAcceptEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::TASK_COMPLETE: {
|
||||
PlayerEvent::TaskCompleteEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatTaskCompleteEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::TASK_UPDATE: {
|
||||
PlayerEvent::TaskUpdateEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatTaskUpdateEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::TRADE: {
|
||||
PlayerEvent::TradeEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatTradeEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::TRADER_PURCHASE: {
|
||||
PlayerEvent::TraderPurchaseEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatTraderPurchaseEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::TRADER_SELL: {
|
||||
PlayerEvent::TraderSellEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatTraderSellEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::REZ_ACCEPTED: {
|
||||
PlayerEvent::ResurrectAcceptEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
payload = PlayerEventDiscordFormatter::FormatResurrectAcceptEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::WENT_ONLINE:
|
||||
case PlayerEvent::WENT_OFFLINE: {
|
||||
payload = PlayerEventDiscordFormatter::FormatWithNodata(e);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::MERCHANT_PURCHASE: {
|
||||
PlayerEvent::MerchantPurchaseEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
|
||||
payload = PlayerEventDiscordFormatter::FormatMerchantPurchaseEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::MERCHANT_SELL: {
|
||||
PlayerEvent::MerchantSellEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
|
||||
payload = PlayerEventDiscordFormatter::FormatMerchantSellEvent(e, n);
|
||||
break;
|
||||
}
|
||||
case PlayerEvent::ZONING: {
|
||||
PlayerEvent::ZoningEvent n{};
|
||||
std::stringstream ss;
|
||||
{
|
||||
ss << e.player_event_log.event_data;
|
||||
cereal::JSONInputArchive ar(ss);
|
||||
n.serialize(ar);
|
||||
}
|
||||
|
||||
payload = PlayerEventDiscordFormatter::FormatZoningEvent(e, n);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LogInfo(
|
||||
"Player event [{}] ({}) Discord formatter not implemented",
|
||||
e.player_event_log.event_type_name,
|
||||
e.player_event_log.event_type_id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
// general process function, used in world or QS depending on rule Logging:PlayerEventsQSProcess
|
||||
void PlayerEventLogs::Process()
|
||||
{
|
||||
if (m_process_batch_events_timer.Check() || m_record_batch_queue.size() >= RuleI(Logging, BatchPlayerEventProcessChunkSize)) {
|
||||
ProcessBatchQueue();
|
||||
}
|
||||
|
||||
if (m_process_retention_truncation_timer.Check()) {
|
||||
ProcessRetentionTruncation();
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||
{
|
||||
LogInfo("Running truncation");
|
||||
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
if (m_settings[i].retention_days > 0) {
|
||||
int deleted_count = PlayerEventLogsRepository::DeleteWhere(
|
||||
*m_database,
|
||||
fmt::format(
|
||||
"event_type_id = {} AND created_at < (NOW() - INTERVAL {} DAY)",
|
||||
i,
|
||||
m_settings[i].retention_days
|
||||
)
|
||||
);
|
||||
|
||||
if (deleted_count > 0) {
|
||||
LogInfo(
|
||||
"Truncated [{}] events of type [{}] ({}) older than [{}] days",
|
||||
deleted_count,
|
||||
PlayerEvent::EventName[i],
|
||||
i,
|
||||
m_settings[i].retention_days
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerEventLogs::ReloadSettings()
|
||||
{
|
||||
for (auto &e: PlayerEventLogSettingsRepository::All(*m_database)) {
|
||||
m_settings[e.id] = e;
|
||||
}
|
||||
}
|
||||
|
||||
const int32_t RETENTION_DAYS_DEFAULT = 7;
|
||||
|
||||
void PlayerEventLogs::SetSettingsDefaults()
|
||||
{
|
||||
m_settings[PlayerEvent::GM_COMMAND].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ZONING].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::AA_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::FORAGE_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FORAGE_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_SUCCESS].event_enabled = 0;
|
||||
m_settings[PlayerEvent::FISH_FAILURE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::ITEM_DESTROY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::WENT_ONLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::WENT_OFFLINE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::LEVEL_GAIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LEVEL_LOSS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::LOOT_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::MERCHANT_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GROUP_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUP_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_JOIN].event_enabled = 0;
|
||||
m_settings[PlayerEvent::RAID_LEAVE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::GROUNDSPAWN_PICKUP].event_enabled = 1;
|
||||
m_settings[PlayerEvent::NPC_HANDIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SKILL_UP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::TASK_ACCEPT].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_UPDATE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TASK_COMPLETE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::GIVE_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SAY].event_enabled = 0;
|
||||
m_settings[PlayerEvent::REZ_ACCEPTED].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DEATH].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_FAILURE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::COMBINE_SUCCESS].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DROPPED_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::SPLIT_MONEY].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_JOIN].event_enabled = 1;
|
||||
m_settings[PlayerEvent::DZ_LEAVE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_PURCHASE].event_enabled = 1;
|
||||
m_settings[PlayerEvent::TRADER_SELL].event_enabled = 1;
|
||||
m_settings[PlayerEvent::BANDOLIER_CREATE].event_enabled = 0;
|
||||
m_settings[PlayerEvent::BANDOLIER_SWAP].event_enabled = 0;
|
||||
m_settings[PlayerEvent::DISCOVER_ITEM].event_enabled = 1;
|
||||
m_settings[PlayerEvent::POSSIBLE_HACK].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_NPC].event_enabled = 0;
|
||||
m_settings[PlayerEvent::KILLED_NAMED_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::KILLED_RAID_NPC].event_enabled = 1;
|
||||
m_settings[PlayerEvent::ITEM_CREATION].event_enabled = 1;
|
||||
|
||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||
m_settings[i].retention_days = RETENTION_DAYS_DEFAULT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
||||
#define EQEMU_PLAYER_EVENT_LOGS_H
|
||||
|
||||
#include "../repositories/player_event_log_settings_repository.h"
|
||||
#include "player_events.h"
|
||||
#include "../servertalk.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
#include "../timer.h"
|
||||
#include "../json/json_archive_single_line.h"
|
||||
#include <cereal/archives/json.hpp>
|
||||
#include <mutex>
|
||||
|
||||
class PlayerEventLogs {
|
||||
public:
|
||||
void Init();
|
||||
void ReloadSettings();
|
||||
PlayerEventLogs *SetDatabase(Database *db);
|
||||
bool ValidateDatabaseConnection();
|
||||
bool IsEventEnabled(PlayerEvent::EventType event);
|
||||
|
||||
void Process();
|
||||
|
||||
// batch queue
|
||||
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
||||
|
||||
// main event record generic function
|
||||
// can ingest any struct event types
|
||||
template<typename T>
|
||||
std::unique_ptr<ServerPacket> RecordEvent(
|
||||
PlayerEvent::EventType t,
|
||||
const PlayerEvent::PlayerEvent &p,
|
||||
T e
|
||||
)
|
||||
{
|
||||
auto n = PlayerEventLogsRepository::NewEntity();
|
||||
FillPlayerEvent(p, n);
|
||||
n.event_type_id = t;
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
cereal::JSONOutputArchiveSingleLine ar(ss);
|
||||
e.serialize(ar);
|
||||
}
|
||||
|
||||
n.event_type_name = PlayerEvent::EventName[t];
|
||||
n.event_data = Strings::Contains(ss.str(), "noop") ? "{}" : ss.str();
|
||||
n.created_at = std::time(nullptr);
|
||||
|
||||
auto c = PlayerEvent::PlayerEventContainer{
|
||||
.player_event = p,
|
||||
.player_event_log = n
|
||||
};
|
||||
|
||||
return BuildPlayerEventPacket(c);
|
||||
}
|
||||
|
||||
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
|
||||
bool IsEventDiscordEnabled(int32_t event_type_id);
|
||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
||||
|
||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
||||
private:
|
||||
Database *m_database; // reference to database
|
||||
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
||||
|
||||
// batch queue is used to record events in batch
|
||||
std::vector<PlayerEventLogsRepository::PlayerEventLogs> m_record_batch_queue{};
|
||||
static void FillPlayerEvent(const PlayerEvent::PlayerEvent &p, PlayerEventLogsRepository::PlayerEventLogs &n);
|
||||
static std::unique_ptr<ServerPacket>
|
||||
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
||||
|
||||
// timers
|
||||
Timer m_process_batch_events_timer; // events processing timer
|
||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
||||
|
||||
// processing
|
||||
std::mutex m_batch_queue_lock{};
|
||||
void ProcessBatchQueue();
|
||||
void ProcessRetentionTruncation();
|
||||
void SetSettingsDefaults();
|
||||
};
|
||||
|
||||
extern PlayerEventLogs player_event_logs;
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
||||
@@ -0,0 +1,971 @@
|
||||
#ifndef EQEMU_PLAYER_EVENTS_H
|
||||
#define EQEMU_PLAYER_EVENTS_H
|
||||
|
||||
#include <string>
|
||||
#include <cereal/cereal.hpp>
|
||||
#include "../types.h"
|
||||
#include "../repositories/player_event_logs_repository.h"
|
||||
|
||||
namespace PlayerEvent {
|
||||
|
||||
enum EventType {
|
||||
GM_COMMAND = 1,
|
||||
ZONING,
|
||||
AA_GAIN,
|
||||
AA_PURCHASE,
|
||||
FORAGE_SUCCESS,
|
||||
FORAGE_FAILURE,
|
||||
FISH_SUCCESS,
|
||||
FISH_FAILURE,
|
||||
ITEM_DESTROY,
|
||||
WENT_ONLINE,
|
||||
WENT_OFFLINE,
|
||||
LEVEL_GAIN,
|
||||
LEVEL_LOSS,
|
||||
LOOT_ITEM,
|
||||
MERCHANT_PURCHASE,
|
||||
MERCHANT_SELL,
|
||||
GROUP_JOIN, // unimplemented
|
||||
GROUP_LEAVE, // unimplemented
|
||||
RAID_JOIN, // unimplemented
|
||||
RAID_LEAVE, // unimplemented
|
||||
GROUNDSPAWN_PICKUP,
|
||||
NPC_HANDIN,
|
||||
SKILL_UP,
|
||||
TASK_ACCEPT,
|
||||
TASK_UPDATE,
|
||||
TASK_COMPLETE,
|
||||
TRADE,
|
||||
GIVE_ITEM, // unimplemented
|
||||
SAY,
|
||||
REZ_ACCEPTED,
|
||||
DEATH,
|
||||
COMBINE_FAILURE,
|
||||
COMBINE_SUCCESS,
|
||||
DROPPED_ITEM,
|
||||
SPLIT_MONEY,
|
||||
DZ_JOIN, // unimplemented
|
||||
DZ_LEAVE, // unimplemented
|
||||
TRADER_PURCHASE,
|
||||
TRADER_SELL,
|
||||
BANDOLIER_CREATE, // unimplemented
|
||||
BANDOLIER_SWAP, // unimplemented
|
||||
DISCOVER_ITEM,
|
||||
POSSIBLE_HACK,
|
||||
KILLED_NPC,
|
||||
KILLED_NAMED_NPC,
|
||||
KILLED_RAID_NPC,
|
||||
ITEM_CREATION,
|
||||
MAX // dont remove
|
||||
};
|
||||
|
||||
// Don't ever remove items, even if they are deprecated
|
||||
// If event is deprecated just tag (Deprecated) in the name
|
||||
// If event is unimplemented just tag (Unimplemented) in the name
|
||||
// Events don't get saved to the database if unimplemented or deprecated
|
||||
// Events tagged as deprecated will get automatically removed
|
||||
static const char *EventName[PlayerEvent::MAX] = {
|
||||
"None",
|
||||
"GM Command",
|
||||
"Zoning",
|
||||
"AA Gain",
|
||||
"AA Purchase",
|
||||
"Forage Success",
|
||||
"Forage Failure",
|
||||
"Fish Success",
|
||||
"Fish Failure",
|
||||
"Item Destroy",
|
||||
"Went Online",
|
||||
"Went Offline",
|
||||
"Level Gain",
|
||||
"Level Loss",
|
||||
"Loot Item",
|
||||
"Merchant Purchase",
|
||||
"Merchant Sell",
|
||||
"Group Join (Unimplemented)",
|
||||
"Group Leave (Unimplemented)",
|
||||
"Raid Join (Unimplemented)",
|
||||
"Raid Leave (Unimplemented)",
|
||||
"Groundspawn Pickup",
|
||||
"NPC Handin",
|
||||
"Skill Up",
|
||||
"Task Accept",
|
||||
"Task Update",
|
||||
"Task Complete",
|
||||
"Trade",
|
||||
"Given Item (Unimplemented)",
|
||||
"Say",
|
||||
"Rez Accepted",
|
||||
"Death",
|
||||
"Combine Failure",
|
||||
"Combine Success",
|
||||
"Dropped Item",
|
||||
"Split Money",
|
||||
"DZ Join (Unimplemented)",
|
||||
"DZ Leave (Unimplemented)",
|
||||
"Trader Purchase",
|
||||
"Trader Sell",
|
||||
"Bandolier Create (Unimplemented)",
|
||||
"Bandolier Swap (Unimplemented)",
|
||||
"Discover Item",
|
||||
"Possible Hack",
|
||||
"Killed NPC",
|
||||
"Killed Named NPC",
|
||||
"Killed Raid NPC",
|
||||
"Item Creation"
|
||||
};
|
||||
|
||||
// Generic struct used by all events
|
||||
struct PlayerEvent {
|
||||
int64 account_id;
|
||||
std::string account_name;
|
||||
int64 character_id;
|
||||
std::string character_name;
|
||||
int64 guild_id;
|
||||
std::string guild_name;
|
||||
int zone_id;
|
||||
std::string zone_short_name;
|
||||
std::string zone_long_name;
|
||||
int instance_id;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float heading;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(account_id),
|
||||
CEREAL_NVP(account_name),
|
||||
CEREAL_NVP(character_id),
|
||||
CEREAL_NVP(character_name),
|
||||
CEREAL_NVP(guild_id),
|
||||
CEREAL_NVP(guild_name),
|
||||
CEREAL_NVP(zone_id),
|
||||
CEREAL_NVP(zone_short_name),
|
||||
CEREAL_NVP(zone_long_name),
|
||||
CEREAL_NVP(instance_id),
|
||||
CEREAL_NVP(x),
|
||||
CEREAL_NVP(y),
|
||||
CEREAL_NVP(z),
|
||||
CEREAL_NVP(heading)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// contains metadata in use for things like log/discord formatters
|
||||
// along with the actual event to be persisted
|
||||
struct PlayerEventContainer {
|
||||
PlayerEvent player_event;
|
||||
PlayerEventLogsRepository::PlayerEventLogs player_event_log;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(player_event),
|
||||
CEREAL_NVP(player_event_log)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// used in events with no extra data
|
||||
struct EmptyEvent {
|
||||
std::string noop; // noop, gets discard upstream
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(noop)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// used in Trade event
|
||||
struct ItemCreationEvent {
|
||||
int64 item_id;
|
||||
std::string item_name;
|
||||
uint16 to_slot;
|
||||
int16 charges;
|
||||
uint32 aug1;
|
||||
uint32 aug2;
|
||||
uint32 aug3;
|
||||
uint32 aug4;
|
||||
uint32 aug5;
|
||||
uint32 aug6;
|
||||
bool attuned;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(to_slot),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(aug1),
|
||||
CEREAL_NVP(aug2),
|
||||
CEREAL_NVP(aug3),
|
||||
CEREAL_NVP(aug4),
|
||||
CEREAL_NVP(aug5),
|
||||
CEREAL_NVP(aug6),
|
||||
CEREAL_NVP(attuned)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// used in Trade event
|
||||
struct TradeItem {
|
||||
int64 item_id;
|
||||
std::string item_name;
|
||||
int32 slot;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(slot)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// used in Trade event
|
||||
class TradeItemEntry {
|
||||
public:
|
||||
uint16 slot;
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint16 charges;
|
||||
uint32 aug_1_item_id;
|
||||
std::string aug_1_item_name;
|
||||
uint32 aug_2_item_id;
|
||||
std::string aug_2_item_name;
|
||||
uint32 aug_3_item_id;
|
||||
std::string aug_3_item_name;
|
||||
uint32 aug_4_item_id;
|
||||
std::string aug_4_item_name;
|
||||
uint32 aug_5_item_id;
|
||||
std::string aug_5_item_name;
|
||||
uint32 aug_6_item_id;
|
||||
std::string aug_6_item_name;
|
||||
bool in_bag;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(slot),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(aug_1_item_id),
|
||||
CEREAL_NVP(aug_2_item_id),
|
||||
CEREAL_NVP(aug_3_item_id),
|
||||
CEREAL_NVP(aug_4_item_id),
|
||||
CEREAL_NVP(aug_5_item_id),
|
||||
CEREAL_NVP(in_bag)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Events
|
||||
*/
|
||||
struct Money {
|
||||
int32 platinum;
|
||||
int32 gold;
|
||||
int32 silver;
|
||||
int32 copper;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(platinum),
|
||||
CEREAL_NVP(gold),
|
||||
CEREAL_NVP(silver),
|
||||
CEREAL_NVP(copper)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct TradeEvent {
|
||||
uint32 character_1_id;
|
||||
std::string character_1_name;
|
||||
uint32 character_2_id;
|
||||
std::string character_2_name;
|
||||
Money character_1_give_money;
|
||||
Money character_2_give_money;
|
||||
std::vector<TradeItemEntry> character_1_give_items;
|
||||
std::vector<TradeItemEntry> character_2_give_items;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(character_1_id),
|
||||
CEREAL_NVP(character_1_name),
|
||||
CEREAL_NVP(character_2_id),
|
||||
CEREAL_NVP(character_2_name),
|
||||
CEREAL_NVP(character_1_give_money),
|
||||
CEREAL_NVP(character_2_give_money),
|
||||
CEREAL_NVP(character_1_give_items),
|
||||
CEREAL_NVP(character_2_give_items)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GMCommandEvent {
|
||||
std::string message;
|
||||
std::string target;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(message),
|
||||
CEREAL_NVP(target)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ZoningEvent {
|
||||
std::string from_zone_long_name;
|
||||
std::string from_zone_short_name;
|
||||
int32 from_zone_id;
|
||||
int32 from_instance_id;
|
||||
int32 from_instance_version;
|
||||
std::string to_zone_long_name;
|
||||
std::string to_zone_short_name;
|
||||
int32 to_zone_id;
|
||||
int32 to_instance_id;
|
||||
int32 to_instance_version;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(from_zone_long_name),
|
||||
CEREAL_NVP(from_zone_short_name),
|
||||
CEREAL_NVP(from_zone_id),
|
||||
CEREAL_NVP(from_instance_id),
|
||||
CEREAL_NVP(from_instance_version),
|
||||
CEREAL_NVP(to_zone_long_name),
|
||||
CEREAL_NVP(to_zone_short_name),
|
||||
CEREAL_NVP(to_zone_id),
|
||||
CEREAL_NVP(to_instance_id),
|
||||
CEREAL_NVP(to_instance_version)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct AAGainedEvent {
|
||||
uint32 aa_gained;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(CEREAL_NVP(aa_gained));
|
||||
}
|
||||
};
|
||||
|
||||
struct AAPurchasedEvent {
|
||||
uint32 aa_id;
|
||||
int32 aa_cost;
|
||||
int32 aa_previous_id;
|
||||
int32 aa_next_id;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(aa_id),
|
||||
CEREAL_NVP(aa_cost),
|
||||
CEREAL_NVP(aa_previous_id),
|
||||
CEREAL_NVP(aa_next_id)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ForageSuccessEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct FishSuccessEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DestroyItemEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 charges;
|
||||
std::string reason;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(reason),
|
||||
CEREAL_NVP(charges)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct LevelGainedEvent {
|
||||
uint32 from_level;
|
||||
uint8 to_level;
|
||||
int levels_gained;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(from_level),
|
||||
CEREAL_NVP(to_level),
|
||||
CEREAL_NVP(levels_gained)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct LevelLostEvent {
|
||||
uint32 from_level;
|
||||
uint8 to_level;
|
||||
int levels_lost;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(from_level),
|
||||
CEREAL_NVP(to_level),
|
||||
CEREAL_NVP(levels_lost)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct LootItemEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 charges;
|
||||
uint32 npc_id;
|
||||
std::string corpse_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(corpse_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct MerchantPurchaseEvent {
|
||||
uint32 npc_id;
|
||||
std::string merchant_name;
|
||||
uint32 merchant_type;
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 charges;
|
||||
uint32 cost;
|
||||
uint32 alternate_currency_id;
|
||||
uint64 player_money_balance;
|
||||
uint64 player_currency_balance;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(merchant_name),
|
||||
CEREAL_NVP(merchant_type),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(cost),
|
||||
CEREAL_NVP(alternate_currency_id),
|
||||
CEREAL_NVP(player_money_balance),
|
||||
CEREAL_NVP(player_currency_balance)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct MerchantSellEvent {
|
||||
uint32 npc_id;
|
||||
std::string merchant_name;
|
||||
uint32 merchant_type;
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 charges;
|
||||
uint32 cost;
|
||||
uint32 alternate_currency_id;
|
||||
uint64 player_money_balance;
|
||||
uint64 player_currency_balance;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(merchant_name),
|
||||
CEREAL_NVP(merchant_type),
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(cost),
|
||||
CEREAL_NVP(alternate_currency_id),
|
||||
CEREAL_NVP(player_money_balance),
|
||||
CEREAL_NVP(player_currency_balance)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct SkillUpEvent {
|
||||
uint32 skill_id;
|
||||
int value;
|
||||
int16 max_skill;
|
||||
std::string against_who;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(skill_id),
|
||||
CEREAL_NVP(value),
|
||||
CEREAL_NVP(max_skill),
|
||||
CEREAL_NVP(against_who)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct TaskAcceptEvent {
|
||||
uint32 npc_id;
|
||||
std::string npc_name;
|
||||
uint32 task_id;
|
||||
std::string task_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(npc_name),
|
||||
CEREAL_NVP(task_id),
|
||||
CEREAL_NVP(task_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct TaskUpdateEvent {
|
||||
uint32 task_id;
|
||||
std::string task_name;
|
||||
uint32 activity_id;
|
||||
uint32 done_count;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(task_id),
|
||||
CEREAL_NVP(task_name),
|
||||
CEREAL_NVP(activity_id),
|
||||
CEREAL_NVP(done_count)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct TaskCompleteEvent {
|
||||
uint32 task_id;
|
||||
std::string task_name;
|
||||
uint32 activity_id;
|
||||
uint32 done_count;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(task_id),
|
||||
CEREAL_NVP(task_name),
|
||||
CEREAL_NVP(activity_id),
|
||||
CEREAL_NVP(done_count)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GroundSpawnPickupEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct SayEvent {
|
||||
std::string message;
|
||||
std::string target;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(message),
|
||||
CEREAL_NVP(target)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct ResurrectAcceptEvent {
|
||||
std::string resurrecter_name;
|
||||
std::string spell_name;
|
||||
uint32 spell_id;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(resurrecter_name),
|
||||
CEREAL_NVP(spell_name),
|
||||
CEREAL_NVP(spell_id)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct CombineEvent {
|
||||
uint32 recipe_id;
|
||||
std::string recipe_name;
|
||||
uint32 made_count;
|
||||
uint32 tradeskill_id;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(recipe_id),
|
||||
CEREAL_NVP(recipe_name),
|
||||
CEREAL_NVP(made_count),
|
||||
CEREAL_NVP(tradeskill_id)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DroppedItemEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
int16 slot_id;
|
||||
uint32 charges;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(slot_id),
|
||||
CEREAL_NVP(charges)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DeathEvent {
|
||||
uint32 killer_id;
|
||||
std::string killer_name;
|
||||
int64 damage;
|
||||
uint32 spell_id;
|
||||
std::string spell_name;
|
||||
int skill_id;
|
||||
std::string skill_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(killer_id),
|
||||
CEREAL_NVP(killer_name),
|
||||
CEREAL_NVP(damage),
|
||||
CEREAL_NVP(spell_id),
|
||||
CEREAL_NVP(spell_name),
|
||||
CEREAL_NVP(skill_id),
|
||||
CEREAL_NVP(skill_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct SplitMoneyEvent {
|
||||
uint32 copper;
|
||||
uint32 silver;
|
||||
uint32 gold;
|
||||
uint32 platinum;
|
||||
uint64 player_money_balance;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(copper),
|
||||
CEREAL_NVP(silver),
|
||||
CEREAL_NVP(gold),
|
||||
CEREAL_NVP(platinum),
|
||||
CEREAL_NVP(player_money_balance)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct TraderPurchaseEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint32 trader_id;
|
||||
std::string trader_name;
|
||||
uint32 price;
|
||||
uint32 charges;
|
||||
uint32 total_cost;
|
||||
uint64 player_money_balance;
|
||||
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(trader_id),
|
||||
CEREAL_NVP(trader_name),
|
||||
CEREAL_NVP(price),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(total_cost),
|
||||
CEREAL_NVP(player_money_balance)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct TraderSellEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint32 buyer_id;
|
||||
std::string buyer_name;
|
||||
uint32 price;
|
||||
uint32 charges;
|
||||
uint32 total_cost;
|
||||
uint64 player_money_balance;
|
||||
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(buyer_id),
|
||||
CEREAL_NVP(buyer_name),
|
||||
CEREAL_NVP(price),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(total_cost),
|
||||
CEREAL_NVP(player_money_balance)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct DiscoverItemEvent {
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class HandinEntry {
|
||||
public:
|
||||
uint32 item_id;
|
||||
std::string item_name;
|
||||
uint16 charges;
|
||||
bool attuned;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(item_id),
|
||||
CEREAL_NVP(item_name),
|
||||
CEREAL_NVP(charges),
|
||||
CEREAL_NVP(attuned)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class HandinMoney {
|
||||
public:
|
||||
uint32 copper;
|
||||
uint32 silver;
|
||||
uint32 gold;
|
||||
uint32 platinum;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(copper),
|
||||
CEREAL_NVP(silver),
|
||||
CEREAL_NVP(gold),
|
||||
CEREAL_NVP(platinum)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct HandinEvent {
|
||||
uint32 npc_id;
|
||||
std::string npc_name;
|
||||
std::vector<HandinEntry> handin_items;
|
||||
HandinMoney handin_money;
|
||||
std::vector<HandinEntry> return_items;
|
||||
HandinMoney return_money;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(npc_name),
|
||||
CEREAL_NVP(handin_items),
|
||||
CEREAL_NVP(handin_money),
|
||||
CEREAL_NVP(return_items),
|
||||
CEREAL_NVP(return_money)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct PossibleHackEvent {
|
||||
std::string message;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(message)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct KilledNPCEvent {
|
||||
uint32 npc_id;
|
||||
std::string npc_name;
|
||||
uint32 combat_time_seconds;
|
||||
uint64 total_damage_per_second_taken;
|
||||
uint64 total_heal_per_second_taken;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(npc_id),
|
||||
CEREAL_NVP(npc_name),
|
||||
CEREAL_NVP(combat_time_seconds),
|
||||
CEREAL_NVP(total_damage_per_second_taken),
|
||||
CEREAL_NVP(total_heal_per_second_taken)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //EQEMU_PLAYER_EVENTS_H
|
||||
|
||||
#define RecordPlayerEventLog(event_type, event_data) do {\
|
||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||
worldserver.SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
#define RecordPlayerEventLogWithClient(c, event_type, event_data) do {\
|
||||
if (player_event_logs.IsEventEnabled(event_type)) {\
|
||||
worldserver.SendPacket(\
|
||||
player_event_logs.RecordEvent(\
|
||||
event_type,\
|
||||
(c)->GetPlayerEvent(),\
|
||||
event_data\
|
||||
).get()\
|
||||
);\
|
||||
}\
|
||||
} while (0)
|
||||
+1
-1
@@ -132,7 +132,7 @@ enum { //reuse times
|
||||
InstillDoubtReuseTime = 9,
|
||||
FishingReuseTime = 11,
|
||||
ForagingReuseTime = 50,
|
||||
MendReuseTime = 290,
|
||||
MendReuseTime = 360,
|
||||
BashReuseTime = 5,
|
||||
BackstabReuseTime = 9,
|
||||
KickReuseTime = 5,
|
||||
|
||||
+17
-21
@@ -61,7 +61,7 @@ bool BaseGuildManager::LoadGuilds() {
|
||||
}
|
||||
|
||||
for (auto row=results.begin();row!=results.end();++row)
|
||||
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
|
||||
_CreateGuild(Strings::ToUnsignedInt(row[0]), row[1], Strings::ToUnsignedInt(row[2]), Strings::ToUnsignedInt(row[3]), row[4], row[5], row[6], row[7]);
|
||||
|
||||
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
|
||||
|
||||
@@ -75,8 +75,8 @@ bool BaseGuildManager::LoadGuilds() {
|
||||
|
||||
for (auto row=results.begin();row!=results.end();++row)
|
||||
{
|
||||
uint32 guild_id = atoi(row[0]);
|
||||
uint8 rankn = atoi(row[1]);
|
||||
uint32 guild_id = Strings::ToUnsignedInt(row[0]);
|
||||
uint8 rankn = Strings::ToUnsignedInt(row[1]);
|
||||
|
||||
if(rankn > GUILD_MAX_RANK) {
|
||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||
@@ -131,7 +131,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(row[2]), row[3], row[4], row[5], row[6]);
|
||||
info = _CreateGuild(guild_id, row[0], Strings::ToUnsignedInt(row[1]), Strings::ToUnsignedInt(row[2]), row[3], row[4], row[5], row[6]);
|
||||
|
||||
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
||||
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
||||
@@ -144,7 +144,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
||||
|
||||
for (auto row=results.begin();row!=results.end();++row)
|
||||
{
|
||||
uint8 rankn = atoi(row[1]);
|
||||
uint8 rankn = Strings::ToUnsignedInt(row[1]);
|
||||
|
||||
if(rankn > GUILD_MAX_RANK) {
|
||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||
@@ -787,9 +787,7 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
bool IsBanker = atoi(row[0]);
|
||||
|
||||
return IsBanker;
|
||||
return Strings::ToBool(row[0]);
|
||||
}
|
||||
|
||||
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
|
||||
@@ -817,9 +815,7 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
bool IsAlt = atoi(row[0]);
|
||||
|
||||
return IsAlt;
|
||||
return Strings::ToBool(row[0]);
|
||||
}
|
||||
|
||||
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
|
||||
@@ -873,19 +869,19 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
|
||||
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
||||
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
||||
//fields from `characer_`
|
||||
into.char_id = atoi(row[0]);
|
||||
into.char_id = Strings::ToUnsignedInt(row[0]);
|
||||
into.char_name = row[1];
|
||||
into.class_ = atoi(row[2]);
|
||||
into.level = atoi(row[3]);
|
||||
into.time_last_on = atoul(row[4]);
|
||||
into.zone_id = atoi(row[5]);
|
||||
into.class_ = Strings::ToUnsignedInt(row[2]);
|
||||
into.level = Strings::ToUnsignedInt(row[3]);
|
||||
into.time_last_on = Strings::ToUnsignedInt(row[4]);
|
||||
into.zone_id = Strings::ToUnsignedInt(row[5]);
|
||||
|
||||
//fields from `guild_members`, leave at defaults if missing
|
||||
into.guild_id = row[6] ? atoi(row[6]) : GUILD_NONE;
|
||||
into.rank = row[7] ? atoi(row[7]) : (GUILD_MAX_RANK+1);
|
||||
into.guild_id = row[6] ? Strings::ToUnsignedInt(row[6]) : GUILD_NONE;
|
||||
into.rank = row[7] ? Strings::ToUnsignedInt(row[7]) : (GUILD_MAX_RANK+1);
|
||||
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
||||
into.total_tribute = row[9] ? atoi(row[9]) : 0;
|
||||
into.last_tribute = row[10]? atoul(row[10]) : 0; //timestamp
|
||||
into.total_tribute = row[9] ? Strings::ToUnsignedInt(row[9]) : 0;
|
||||
into.last_tribute = row[10]? Strings::ToUnsignedInt(row[10]) : 0; //timestamp
|
||||
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
||||
into.public_note = row[12]? row[12] : "";
|
||||
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
||||
@@ -1258,7 +1254,7 @@ uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id)
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
auto guild_id = std::stoul(row[0]);
|
||||
auto guild_id = Strings::ToUnsignedInt(row[0]);
|
||||
return guild_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +272,8 @@ inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) {
|
||||
#include <brotli/encode.h>
|
||||
#endif
|
||||
|
||||
#include "../strings.h"
|
||||
|
||||
/*
|
||||
* Declaration
|
||||
*/
|
||||
@@ -3812,12 +3814,12 @@ inline bool brotli_decompressor::decompress(const char *data,
|
||||
if (std::regex_match(b, e, cm, re_another_range)) {
|
||||
ssize_t first = -1;
|
||||
if (!cm.str(1).empty()) {
|
||||
first = static_cast<ssize_t>(std::stoll(cm.str(1)));
|
||||
first = static_cast<ssize_t>(Strings::ToBigInt(cm.str(1)));
|
||||
}
|
||||
|
||||
ssize_t last = -1;
|
||||
if (!cm.str(2).empty()) {
|
||||
last = static_cast<ssize_t>(std::stoll(cm.str(2)));
|
||||
last = static_cast<ssize_t>(Strings::ToBigInt(cm.str(2)));
|
||||
}
|
||||
|
||||
if (first != -1 && last != -1 && first > last) {
|
||||
|
||||
@@ -203,12 +203,12 @@ namespace EQ
|
||||
void dumpBankItems();
|
||||
void dumpSharedBankItems();
|
||||
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||
static const int GetItemStatValue(uint32 item_id, std::string identifier);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
|
||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
|
||||
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
|
||||
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
|
||||
protected:
|
||||
///////////////////////////////
|
||||
// Protected Methods
|
||||
|
||||
+3
-3
@@ -131,7 +131,7 @@ namespace EQ
|
||||
Mounts?
|
||||
Ornamentations?
|
||||
GuildBanners?
|
||||
Collectible?
|
||||
Collectible?
|
||||
Placeable?
|
||||
(others?)
|
||||
*/
|
||||
@@ -449,8 +449,8 @@ namespace EQ
|
||||
int8 Shielding; // PoP: Shielding %
|
||||
int8 StunResist; // PoP: Stun Resist %
|
||||
int8 StrikeThrough; // PoP: Strike Through %
|
||||
uint32 ExtraDmgSkill;
|
||||
uint32 ExtraDmgAmt;
|
||||
int32 ExtraDmgSkill;
|
||||
int32 ExtraDmgAmt;
|
||||
int8 SpellShield; // PoP: Spell Shield %
|
||||
int8 Avoidance; // PoP: Avoidance +
|
||||
int8 Accuracy; // PoP: Accuracy +
|
||||
|
||||
+37
-12
@@ -358,15 +358,27 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||
}
|
||||
|
||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
|
||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
||||
{
|
||||
if (!m_item || !m_item->IsClassCommon())
|
||||
return false;
|
||||
if (!m_item || !m_item->IsClassCommon()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) {
|
||||
if (
|
||||
(
|
||||
!GetItem(slot) &&
|
||||
m_item->AugSlotVisible[slot]
|
||||
) &&
|
||||
augment_type == -1 ||
|
||||
(
|
||||
m_item->AugSlotType[slot] &&
|
||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Retrieve item inside container
|
||||
@@ -598,7 +610,7 @@ bool EQ::ItemInstance::UpdateOrnamentationInfo() {
|
||||
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
|
||||
if (strlen(ornamentItem->IDFile) > 2)
|
||||
{
|
||||
SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2]));
|
||||
SetOrnamentationIDFile(Strings::ToUnsignedInt(&ornamentItem->IDFile[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -828,7 +840,20 @@ std::string EQ::ItemInstance::GetCustomDataString() const {
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
|
||||
void EQ::ItemInstance::SetCustomDataString(const std::string& str)
|
||||
{
|
||||
auto components = Strings::Split(str, "^");
|
||||
auto value_count = components.size() / 2;
|
||||
|
||||
for (auto i = 0; i < value_count; i++) {
|
||||
auto identifier = components[i * 2];
|
||||
auto value = components[(i * 2) + 1];
|
||||
|
||||
SetCustomData(identifier, value);
|
||||
}
|
||||
}
|
||||
|
||||
std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) {
|
||||
std::map<std::string, std::string>::const_iterator iter = m_custom_data.find(identifier);
|
||||
if (iter != m_custom_data.end()) {
|
||||
return iter->second;
|
||||
@@ -837,33 +862,33 @@ std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, std::string value) {
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, const std::string& value) {
|
||||
DeleteCustomData(identifier);
|
||||
m_custom_data[identifier] = value;
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, int value) {
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, int value) {
|
||||
DeleteCustomData(identifier);
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
m_custom_data[identifier] = ss.str();
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, float value) {
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, float value) {
|
||||
DeleteCustomData(identifier);
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
m_custom_data[identifier] = ss.str();
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::SetCustomData(std::string identifier, bool value) {
|
||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, bool value) {
|
||||
DeleteCustomData(identifier);
|
||||
std::stringstream ss;
|
||||
ss << value;
|
||||
m_custom_data[identifier] = ss.str();
|
||||
}
|
||||
|
||||
void EQ::ItemInstance::DeleteCustomData(std::string identifier) {
|
||||
void EQ::ItemInstance::DeleteCustomData(const std::string& identifier) {
|
||||
auto iter = m_custom_data.find(identifier);
|
||||
if (iter != m_custom_data.end()) {
|
||||
m_custom_data.erase(iter);
|
||||
|
||||
@@ -101,8 +101,8 @@ namespace EQ
|
||||
//
|
||||
bool IsAugmentable() const;
|
||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||
int8 AvailableAugmentSlot(int32 augtype) const;
|
||||
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
||||
int8 AvailableAugmentSlot(int32 augment_type) const;
|
||||
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
||||
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||
|
||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||
@@ -175,12 +175,13 @@ namespace EQ
|
||||
void SetAttuned(bool flag) { m_attuned = flag; }
|
||||
|
||||
std::string GetCustomDataString() const;
|
||||
std::string GetCustomData(std::string identifier);
|
||||
void SetCustomData(std::string identifier, std::string value);
|
||||
void SetCustomData(std::string identifier, int value);
|
||||
void SetCustomData(std::string identifier, float value);
|
||||
void SetCustomData(std::string identifier, bool value);
|
||||
void DeleteCustomData(std::string identifier);
|
||||
std::string GetCustomData(const std::string &identifier);
|
||||
void SetCustomDataString(const std::string& str);
|
||||
void SetCustomData(const std::string &identifier, const std::string& value);
|
||||
void SetCustomData(const std::string &identifier, int value);
|
||||
void SetCustomData(const std::string &identifier, float value);
|
||||
void SetCustomData(const std::string &identifier, bool value);
|
||||
void DeleteCustomData(const std::string& identifier);
|
||||
|
||||
// Allows treatment of this object as though it were a pointer to m_item
|
||||
operator bool() const { return (m_item != nullptr); }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -18,6 +18,7 @@
|
||||
#include "misc.h"
|
||||
#include "types.h"
|
||||
#include <cstring>
|
||||
#include "strings.h"
|
||||
|
||||
std::map<int,std::string> DBFieldNames;
|
||||
|
||||
@@ -150,7 +151,7 @@ static char *temp=nullptr;
|
||||
return false;
|
||||
}
|
||||
ptr++;
|
||||
uint32 id = atoi(field[id_pos].c_str());
|
||||
uint32 id = Strings::ToUnsignedInt(field[id_pos].c_str());
|
||||
items[id]=field;
|
||||
|
||||
for(i=0;i<10;i++) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "misc_functions.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "strings.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include <netinet/in.h>
|
||||
@@ -130,7 +131,7 @@ bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf
|
||||
if (*oIP == 0)
|
||||
return false;
|
||||
if (oPort)
|
||||
*oPort = atoi(sep.arg[1]);
|
||||
*oPort = Strings::ToUnsignedInt(sep.arg[1]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1050,7 +1050,7 @@ namespace RoF
|
||||
{
|
||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -1069,7 +1069,7 @@ namespace RoF
|
||||
return;
|
||||
}
|
||||
//if(gjs->action == groupActLeave)
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -1099,7 +1099,7 @@ namespace RoF
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
||||
if (gu2->membername[i][0] != '\0')
|
||||
{
|
||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||
@@ -1169,7 +1169,7 @@ namespace RoF
|
||||
return;
|
||||
|
||||
}
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||
|
||||
|
||||
@@ -1101,7 +1101,7 @@ namespace RoF2
|
||||
{
|
||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -1120,7 +1120,7 @@ namespace RoF2
|
||||
return;
|
||||
}
|
||||
//if(gjs->action == groupActLeave)
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -1150,7 +1150,7 @@ namespace RoF2
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
||||
if (gu2->membername[i][0] != '\0')
|
||||
{
|
||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||
@@ -1220,7 +1220,7 @@ namespace RoF2
|
||||
return;
|
||||
|
||||
}
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||
|
||||
|
||||
@@ -2590,7 +2590,7 @@ struct GroupUpdate_Struct_Live { // New for Live
|
||||
|
||||
struct GroupMembers_Struct { // New for Live
|
||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||
/*0000*/ uint32 memberlevel; // Guess
|
||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
||||
@@ -2600,7 +2600,7 @@ struct GroupJoin_Struct_Live { // New for Live
|
||||
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||
/*0004*/ uint32 action;
|
||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||
/*0013*/ //char membername[0]; // Null Terminated?
|
||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||
|
||||
@@ -2566,7 +2566,7 @@ struct GroupUpdate_Struct_Live { // New for Live
|
||||
|
||||
struct GroupMembers_Struct { // New for Live
|
||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||
/*0000*/ uint32 memberlevel; // Guess
|
||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
||||
@@ -2576,7 +2576,7 @@ struct GroupJoin_Struct_Live { // New for Live
|
||||
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||
/*0004*/ uint32 action;
|
||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||
/*0013*/ //char membername[0]; // Null Terminated?
|
||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||
|
||||
@@ -785,7 +785,7 @@ namespace SoD
|
||||
{
|
||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -804,7 +804,7 @@ namespace SoD
|
||||
return;
|
||||
}
|
||||
//if(gjs->action == groupActLeave)
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -834,7 +834,7 @@ namespace SoD
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
||||
if (gu2->membername[i][0] != '\0')
|
||||
{
|
||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||
@@ -902,7 +902,7 @@ namespace SoD
|
||||
return;
|
||||
}
|
||||
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||
|
||||
|
||||
@@ -2085,7 +2085,7 @@ struct GroupUpdate_Struct_SoD { // New for SoD
|
||||
|
||||
struct GroupMembers_Struct { // New for SoD
|
||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||
/*0000*/ uint32 memberlevel; // Guess
|
||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
||||
@@ -2095,7 +2095,7 @@ struct GroupJoin_Struct_SoD { // New for SoD
|
||||
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||
/*0004*/ uint32 action;
|
||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||
/*0013*/ //char membername[0]; // Null Terminated?
|
||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||
|
||||
@@ -2095,13 +2095,13 @@ namespace SoF
|
||||
}
|
||||
else
|
||||
{
|
||||
val = atoi(&emu->lastName[2]);
|
||||
val = Strings::ToInt(&emu->lastName[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sep[0] = nullptr;
|
||||
ofs = atoi(&emu->lastName[2]);
|
||||
ofs = Strings::ToInt(&emu->lastName[2]);
|
||||
sep[0] = '=';
|
||||
if ((sep[1] < '0') || (sep[1] > '9'))
|
||||
{
|
||||
@@ -2109,7 +2109,7 @@ namespace SoF
|
||||
}
|
||||
else
|
||||
{
|
||||
val = atoi(&sep[1]);
|
||||
val = Strings::ToInt(&sep[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -927,7 +927,7 @@ namespace UF
|
||||
{
|
||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -947,7 +947,7 @@ namespace UF
|
||||
return;
|
||||
}
|
||||
//if(gjs->action == groupActLeave)
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
|
||||
auto outapp =
|
||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||
@@ -977,7 +977,7 @@ namespace UF
|
||||
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
||||
if (gu2->membername[i][0] != '\0')
|
||||
{
|
||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||
@@ -1045,7 +1045,7 @@ namespace UF
|
||||
delete in;
|
||||
return;
|
||||
}
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||
|
||||
|
||||
@@ -2128,7 +2128,7 @@ struct GroupUpdate_Struct_Underfoot { // New for Underfoot
|
||||
|
||||
struct GroupMembers_Struct { // New for Underfoot
|
||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||
/*0000*/ uint32 memberlevel; // Guess
|
||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
||||
@@ -2138,7 +2138,7 @@ struct GroupJoin_Struct_Underfoot { // New for Underfoot
|
||||
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||
/*0004*/ uint32 action;
|
||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||
/*0013*/ //char membername[0]; // Null Terminated?
|
||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||
|
||||
+16
-11
@@ -22,26 +22,31 @@
|
||||
|
||||
EQEmuExePlatform exe_platform = ExePlatformNone;
|
||||
|
||||
void RegisterExecutablePlatform(EQEmuExePlatform p) {
|
||||
void RegisterExecutablePlatform(EQEmuExePlatform p)
|
||||
{
|
||||
exe_platform = p;
|
||||
}
|
||||
|
||||
const EQEmuExePlatform& GetExecutablePlatform() {
|
||||
const EQEmuExePlatform &GetExecutablePlatform()
|
||||
{
|
||||
return exe_platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
int GetExecutablePlatformInt(){
|
||||
int GetExecutablePlatformInt()
|
||||
{
|
||||
return exe_platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns platform name by string
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
bool IsWorld()
|
||||
{
|
||||
return exe_platform == EQEmuExePlatform::ExePlatformWorld;
|
||||
}
|
||||
|
||||
bool IsQueryServ()
|
||||
{
|
||||
return exe_platform == EQEmuExePlatform::ExePlatformQueryServ;
|
||||
}
|
||||
|
||||
std::string GetPlatformName()
|
||||
{
|
||||
switch (GetExecutablePlatformInt()) {
|
||||
|
||||
@@ -44,5 +44,7 @@ void RegisterExecutablePlatform(EQEmuExePlatform p);
|
||||
const EQEmuExePlatform& GetExecutablePlatform();
|
||||
int GetExecutablePlatformInt();
|
||||
std::string GetPlatformName();
|
||||
bool IsWorld();
|
||||
bool IsQueryServ();
|
||||
|
||||
#endif
|
||||
|
||||
+3
-3
@@ -288,9 +288,9 @@ bool PTimerList::Load(Database *db) {
|
||||
PersistentTimer *cur;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
type = atoi(row[0]);
|
||||
start_time = strtoul(row[1], nullptr, 10);
|
||||
timer_time = strtoul(row[2], nullptr, 10);
|
||||
type = Strings::ToUnsignedInt(row[0]);
|
||||
start_time = Strings::ToUnsignedInt(row[1]);
|
||||
timer_time = Strings::ToUnsignedInt(row[2]);
|
||||
enabled = (row[3][0] == '1');
|
||||
|
||||
//if it expired allready, dont bother.
|
||||
|
||||
@@ -69,6 +69,7 @@ public:
|
||||
int32_t expansion_bitmask;
|
||||
uint8_t enforce_spell_settings;
|
||||
uint8_t archery_setting;
|
||||
uint32_t caster_range;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -129,6 +130,7 @@ public:
|
||||
"expansion_bitmask",
|
||||
"enforce_spell_settings",
|
||||
"archery_setting",
|
||||
"caster_range",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -185,6 +187,7 @@ public:
|
||||
"expansion_bitmask",
|
||||
"enforce_spell_settings",
|
||||
"archery_setting",
|
||||
"caster_range",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -275,6 +278,7 @@ public:
|
||||
e.expansion_bitmask = -1;
|
||||
e.enforce_spell_settings = 0;
|
||||
e.archery_setting = 0;
|
||||
e.caster_range = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -361,6 +365,7 @@ public:
|
||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -443,6 +448,7 @@ public:
|
||||
v.push_back(columns[47] + " = " + std::to_string(e.expansion_bitmask));
|
||||
v.push_back(columns[48] + " = " + std::to_string(e.enforce_spell_settings));
|
||||
v.push_back(columns[49] + " = " + std::to_string(e.archery_setting));
|
||||
v.push_back(columns[50] + " = " + std::to_string(e.caster_range));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -514,6 +520,7 @@ public:
|
||||
v.push_back(std::to_string(e.expansion_bitmask));
|
||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
||||
v.push_back(std::to_string(e.archery_setting));
|
||||
v.push_back(std::to_string(e.caster_range));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -593,6 +600,7 @@ public:
|
||||
v.push_back(std::to_string(e.expansion_bitmask));
|
||||
v.push_back(std::to_string(e.enforce_spell_settings));
|
||||
v.push_back(std::to_string(e.archery_setting));
|
||||
v.push_back(std::to_string(e.caster_range));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -676,6 +684,7 @@ public:
|
||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -750,6 +759,7 @@ public:
|
||||
e.expansion_bitmask = static_cast<int32_t>(atoi(row[47]));
|
||||
e.enforce_spell_settings = static_cast<uint8_t>(strtoul(row[48], nullptr, 10));
|
||||
e.archery_setting = static_cast<uint8_t>(strtoul(row[49], nullptr, 10));
|
||||
e.caster_range = static_cast<uint32_t>(strtoul(row[50], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseDataBucketsRepository {
|
||||
public:
|
||||
struct DataBuckets {
|
||||
uint64_t id;
|
||||
std::string key;
|
||||
std::string key_;
|
||||
std::string value;
|
||||
uint32_t expires;
|
||||
};
|
||||
@@ -34,7 +35,7 @@ public:
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"key",
|
||||
"`key`",
|
||||
"value",
|
||||
"expires",
|
||||
};
|
||||
@@ -44,7 +45,7 @@ public:
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"key",
|
||||
"`key`",
|
||||
"value",
|
||||
"expires",
|
||||
};
|
||||
@@ -88,7 +89,7 @@ public:
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = 0;
|
||||
e.key = "";
|
||||
e.key_ = "";
|
||||
e.value = "";
|
||||
e.expires = 0;
|
||||
|
||||
@@ -116,8 +117,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
data_buckets_id
|
||||
)
|
||||
);
|
||||
@@ -127,7 +129,7 @@ public:
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key = row[1] ? row[1] : "";
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
|
||||
@@ -163,7 +165,7 @@ public:
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.key) + "'");
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.expires));
|
||||
|
||||
@@ -188,7 +190,7 @@ public:
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.key) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(std::to_string(e.expires));
|
||||
|
||||
@@ -221,7 +223,7 @@ public:
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.key) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.key_) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.value) + "'");
|
||||
v.push_back(std::to_string(e.expires));
|
||||
|
||||
@@ -258,7 +260,7 @@ public:
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key = row[1] ? row[1] : "";
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
|
||||
@@ -286,7 +288,7 @@ public:
|
||||
DataBuckets e{};
|
||||
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.key = row[1] ? row[1] : "";
|
||||
e.key_ = row[1] ? row[1] : "";
|
||||
e.value = row[2] ? row[2] : "";
|
||||
e.expires = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
|
||||
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
/**
|
||||
* DO NOT MODIFY THIS FILE
|
||||
*
|
||||
* This repository was automatically generated and is NOT to be modified directly.
|
||||
* Any repository modifications are meant to be made to the repository extending the base.
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_EVENTLOG_REPOSITORY_H
|
||||
#define EQEMU_BASE_EVENTLOG_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
class BaseEventlogRepository {
|
||||
public:
|
||||
struct Eventlog {
|
||||
uint32_t id;
|
||||
std::string accountname;
|
||||
uint32_t accountid;
|
||||
int32_t status;
|
||||
std::string charname;
|
||||
std::string target;
|
||||
std::string time;
|
||||
std::string descriptiontype;
|
||||
std::string description;
|
||||
int32_t event_nid;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"accountname",
|
||||
"accountid",
|
||||
"status",
|
||||
"charname",
|
||||
"target",
|
||||
"time",
|
||||
"descriptiontype",
|
||||
"description",
|
||||
"event_nid",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"accountname",
|
||||
"accountid",
|
||||
"status",
|
||||
"charname",
|
||||
"target",
|
||||
"time",
|
||||
"descriptiontype",
|
||||
"description",
|
||||
"event_nid",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string SelectColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("eventlog");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
SelectColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static Eventlog NewEntity()
|
||||
{
|
||||
Eventlog e{};
|
||||
|
||||
e.id = 0;
|
||||
e.accountname = "";
|
||||
e.accountid = 0;
|
||||
e.status = 0;
|
||||
e.charname = "";
|
||||
e.target = "None";
|
||||
e.time = std::time(nullptr);
|
||||
e.descriptiontype = "";
|
||||
e.description = "";
|
||||
e.event_nid = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static Eventlog GetEventlog(
|
||||
const std::vector<Eventlog> &eventlogs,
|
||||
int eventlog_id
|
||||
)
|
||||
{
|
||||
for (auto &eventlog : eventlogs) {
|
||||
if (eventlog.id == eventlog_id) {
|
||||
return eventlog;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static Eventlog FindOne(
|
||||
Database& db,
|
||||
int eventlog_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
eventlog_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
Eventlog e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.accountname = row[1] ? row[1] : "";
|
||||
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e.status = static_cast<int32_t>(atoi(row[3]));
|
||||
e.charname = row[4] ? row[4] : "";
|
||||
e.target = row[5] ? row[5] : "";
|
||||
e.time = row[6] ? row[6] : "";
|
||||
e.descriptiontype = row[7] ? row[7] : "";
|
||||
e.description = row[8] ? row[8] : "";
|
||||
e.event_nid = static_cast<int32_t>(atoi(row[9]));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int eventlog_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
eventlog_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const Eventlog &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.accountname) + "'");
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.accountid));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.status));
|
||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.charname) + "'");
|
||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.target) + "'");
|
||||
v.push_back(columns[6] + " = '" + Strings::Escape(e.time) + "'");
|
||||
v.push_back(columns[7] + " = '" + Strings::Escape(e.descriptiontype) + "'");
|
||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.description) + "'");
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.event_nid));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static Eventlog InsertOne(
|
||||
Database& db,
|
||||
Eventlog e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.accountname) + "'");
|
||||
v.push_back(std::to_string(e.accountid));
|
||||
v.push_back(std::to_string(e.status));
|
||||
v.push_back("'" + Strings::Escape(e.charname) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.target) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.time) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.descriptiontype) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.description) + "'");
|
||||
v.push_back(std::to_string(e.event_nid));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
e = NewEntity();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static int InsertMany(
|
||||
Database& db,
|
||||
const std::vector<Eventlog> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.accountname) + "'");
|
||||
v.push_back(std::to_string(e.accountid));
|
||||
v.push_back(std::to_string(e.status));
|
||||
v.push_back("'" + Strings::Escape(e.charname) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.target) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.time) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.descriptiontype) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.description) + "'");
|
||||
v.push_back(std::to_string(e.event_nid));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static std::vector<Eventlog> All(Database& db)
|
||||
{
|
||||
std::vector<Eventlog> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Eventlog e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.accountname = row[1] ? row[1] : "";
|
||||
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e.status = static_cast<int32_t>(atoi(row[3]));
|
||||
e.charname = row[4] ? row[4] : "";
|
||||
e.target = row[5] ? row[5] : "";
|
||||
e.time = row[6] ? row[6] : "";
|
||||
e.descriptiontype = row[7] ? row[7] : "";
|
||||
e.description = row[8] ? row[8] : "";
|
||||
e.event_nid = static_cast<int32_t>(atoi(row[9]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<Eventlog> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<Eventlog> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {}",
|
||||
BaseSelect(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Eventlog e{};
|
||||
|
||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
e.accountname = row[1] ? row[1] : "";
|
||||
e.accountid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e.status = static_cast<int32_t>(atoi(row[3]));
|
||||
e.charname = row[4] ? row[4] : "";
|
||||
e.target = row[5] ? row[5] : "";
|
||||
e.time = row[6] ? row[6] : "";
|
||||
e.descriptiontype = row[7] ? row[7] : "";
|
||||
e.description = row[8] ? row[8] : "";
|
||||
e.event_nid = static_cast<int32_t>(atoi(row[9]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {}",
|
||||
TableName(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int Truncate(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"TRUNCATE TABLE {}",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int64 GetMaxId(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||
PrimaryKey(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COUNT(*) FROM {} {}",
|
||||
TableName(),
|
||||
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_EVENTLOG_REPOSITORY_H
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseMerchantlistRepository {
|
||||
public:
|
||||
struct Merchantlist {
|
||||
@@ -24,6 +25,8 @@ public:
|
||||
int32_t item;
|
||||
int16_t faction_required;
|
||||
uint8_t level_required;
|
||||
uint8_t min_status;
|
||||
uint8_t max_status;
|
||||
uint16_t alt_currency_cost;
|
||||
int32_t classes_required;
|
||||
int32_t probability;
|
||||
@@ -49,6 +52,8 @@ public:
|
||||
"item",
|
||||
"faction_required",
|
||||
"level_required",
|
||||
"min_status",
|
||||
"max_status",
|
||||
"alt_currency_cost",
|
||||
"classes_required",
|
||||
"probability",
|
||||
@@ -70,6 +75,8 @@ public:
|
||||
"item",
|
||||
"faction_required",
|
||||
"level_required",
|
||||
"min_status",
|
||||
"max_status",
|
||||
"alt_currency_cost",
|
||||
"classes_required",
|
||||
"probability",
|
||||
@@ -125,6 +132,8 @@ public:
|
||||
e.item = 0;
|
||||
e.faction_required = -100;
|
||||
e.level_required = 0;
|
||||
e.min_status = 0;
|
||||
e.max_status = 255;
|
||||
e.alt_currency_cost = 0;
|
||||
e.classes_required = 65535;
|
||||
e.probability = 100;
|
||||
@@ -160,8 +169,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
merchantlist_id
|
||||
)
|
||||
);
|
||||
@@ -175,16 +185,18 @@ public:
|
||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
||||
e.bucket_name = row[8] ? row[8] : "";
|
||||
e.bucket_value = row[9] ? row[9] : "";
|
||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
||||
e.content_flags = row[13] ? row[13] : "";
|
||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
||||
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||
e.bucket_name = row[10] ? row[10] : "";
|
||||
e.bucket_value = row[11] ? row[11] : "";
|
||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||
e.content_flags = row[15] ? row[15] : "";
|
||||
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -223,16 +235,18 @@ public:
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.item));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.faction_required));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.level_required));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.alt_currency_cost));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.classes_required));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.probability));
|
||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.bucket_name) + "'");
|
||||
v.push_back(columns[9] + " = '" + Strings::Escape(e.bucket_value) + "'");
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.bucket_comparison));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[13] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[14] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.min_status));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.max_status));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.alt_currency_cost));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.classes_required));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.probability));
|
||||
v.push_back(columns[10] + " = '" + Strings::Escape(e.bucket_name) + "'");
|
||||
v.push_back(columns[11] + " = '" + Strings::Escape(e.bucket_value) + "'");
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.bucket_comparison));
|
||||
v.push_back(columns[13] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[14] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[15] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[16] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -259,6 +273,8 @@ public:
|
||||
v.push_back(std::to_string(e.item));
|
||||
v.push_back(std::to_string(e.faction_required));
|
||||
v.push_back(std::to_string(e.level_required));
|
||||
v.push_back(std::to_string(e.min_status));
|
||||
v.push_back(std::to_string(e.max_status));
|
||||
v.push_back(std::to_string(e.alt_currency_cost));
|
||||
v.push_back(std::to_string(e.classes_required));
|
||||
v.push_back(std::to_string(e.probability));
|
||||
@@ -303,6 +319,8 @@ public:
|
||||
v.push_back(std::to_string(e.item));
|
||||
v.push_back(std::to_string(e.faction_required));
|
||||
v.push_back(std::to_string(e.level_required));
|
||||
v.push_back(std::to_string(e.min_status));
|
||||
v.push_back(std::to_string(e.max_status));
|
||||
v.push_back(std::to_string(e.alt_currency_cost));
|
||||
v.push_back(std::to_string(e.classes_required));
|
||||
v.push_back(std::to_string(e.probability));
|
||||
@@ -351,16 +369,18 @@ public:
|
||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
||||
e.bucket_name = row[8] ? row[8] : "";
|
||||
e.bucket_value = row[9] ? row[9] : "";
|
||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
||||
e.content_flags = row[13] ? row[13] : "";
|
||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
||||
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||
e.bucket_name = row[10] ? row[10] : "";
|
||||
e.bucket_value = row[11] ? row[11] : "";
|
||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||
e.content_flags = row[15] ? row[15] : "";
|
||||
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -390,16 +410,18 @@ public:
|
||||
e.item = static_cast<int32_t>(atoi(row[2]));
|
||||
e.faction_required = static_cast<int16_t>(atoi(row[3]));
|
||||
e.level_required = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
|
||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
||||
e.classes_required = static_cast<int32_t>(atoi(row[6]));
|
||||
e.probability = static_cast<int32_t>(atoi(row[7]));
|
||||
e.bucket_name = row[8] ? row[8] : "";
|
||||
e.bucket_value = row[9] ? row[9] : "";
|
||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[10], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[11]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[12]));
|
||||
e.content_flags = row[13] ? row[13] : "";
|
||||
e.content_flags_disabled = row[14] ? row[14] : "";
|
||||
e.min_status = static_cast<uint8_t>(strtoul(row[5], nullptr, 10));
|
||||
e.max_status = static_cast<uint8_t>(strtoul(row[6], nullptr, 10));
|
||||
e.alt_currency_cost = static_cast<uint16_t>(strtoul(row[7], nullptr, 10));
|
||||
e.classes_required = static_cast<int32_t>(atoi(row[8]));
|
||||
e.probability = static_cast<int32_t>(atoi(row[9]));
|
||||
e.bucket_name = row[10] ? row[10] : "";
|
||||
e.bucket_value = row[11] ? row[11] : "";
|
||||
e.bucket_comparison = static_cast<uint8_t>(strtoul(row[12], nullptr, 10));
|
||||
e.min_expansion = static_cast<int8_t>(atoi(row[13]));
|
||||
e.max_expansion = static_cast<int8_t>(atoi(row[14]));
|
||||
e.content_flags = row[15] ? row[15] : "";
|
||||
e.content_flags_disabled = row[16] ? row[16] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseNpcScaleGlobalBaseRepository {
|
||||
public:
|
||||
struct NpcScaleGlobalBase {
|
||||
int32_t type;
|
||||
int32_t level;
|
||||
std::string zone_id_list;
|
||||
std::string instance_version_list;
|
||||
int32_t ac;
|
||||
int32_t hp;
|
||||
int64_t hp;
|
||||
int32_t accuracy;
|
||||
int32_t slow_mitigation;
|
||||
int32_t attack;
|
||||
@@ -42,10 +45,13 @@ public:
|
||||
int32_t physical_resist;
|
||||
int32_t min_dmg;
|
||||
int32_t max_dmg;
|
||||
int32_t hp_regen_rate;
|
||||
int64_t hp_regen_rate;
|
||||
int64_t hp_regen_per_second;
|
||||
int32_t attack_delay;
|
||||
int32_t spell_scale;
|
||||
int32_t heal_scale;
|
||||
uint32_t avoidance;
|
||||
int32_t heroic_strikethrough;
|
||||
std::string special_abilities;
|
||||
};
|
||||
|
||||
@@ -59,6 +65,8 @@ public:
|
||||
return {
|
||||
"type",
|
||||
"level",
|
||||
"zone_id_list",
|
||||
"instance_version_list",
|
||||
"ac",
|
||||
"hp",
|
||||
"accuracy",
|
||||
@@ -81,9 +89,12 @@ public:
|
||||
"min_dmg",
|
||||
"max_dmg",
|
||||
"hp_regen_rate",
|
||||
"hp_regen_per_second",
|
||||
"attack_delay",
|
||||
"spell_scale",
|
||||
"heal_scale",
|
||||
"avoidance",
|
||||
"heroic_strikethrough",
|
||||
"special_abilities",
|
||||
};
|
||||
}
|
||||
@@ -93,6 +104,8 @@ public:
|
||||
return {
|
||||
"type",
|
||||
"level",
|
||||
"zone_id_list",
|
||||
"instance_version_list",
|
||||
"ac",
|
||||
"hp",
|
||||
"accuracy",
|
||||
@@ -115,9 +128,12 @@ public:
|
||||
"min_dmg",
|
||||
"max_dmg",
|
||||
"hp_regen_rate",
|
||||
"hp_regen_per_second",
|
||||
"attack_delay",
|
||||
"spell_scale",
|
||||
"heal_scale",
|
||||
"avoidance",
|
||||
"heroic_strikethrough",
|
||||
"special_abilities",
|
||||
};
|
||||
}
|
||||
@@ -159,34 +175,39 @@ public:
|
||||
{
|
||||
NpcScaleGlobalBase e{};
|
||||
|
||||
e.type = 0;
|
||||
e.level = 0;
|
||||
e.ac = 0;
|
||||
e.hp = 0;
|
||||
e.accuracy = 0;
|
||||
e.slow_mitigation = 0;
|
||||
e.attack = 0;
|
||||
e.strength = 0;
|
||||
e.stamina = 0;
|
||||
e.dexterity = 0;
|
||||
e.agility = 0;
|
||||
e.intelligence = 0;
|
||||
e.wisdom = 0;
|
||||
e.charisma = 0;
|
||||
e.magic_resist = 0;
|
||||
e.cold_resist = 0;
|
||||
e.fire_resist = 0;
|
||||
e.poison_resist = 0;
|
||||
e.disease_resist = 0;
|
||||
e.corruption_resist = 0;
|
||||
e.physical_resist = 0;
|
||||
e.min_dmg = 0;
|
||||
e.max_dmg = 0;
|
||||
e.hp_regen_rate = 0;
|
||||
e.attack_delay = 0;
|
||||
e.spell_scale = 100;
|
||||
e.heal_scale = 100;
|
||||
e.special_abilities = "";
|
||||
e.type = 0;
|
||||
e.level = 0;
|
||||
e.zone_id_list = "";
|
||||
e.instance_version_list = "";
|
||||
e.ac = 0;
|
||||
e.hp = 0;
|
||||
e.accuracy = 0;
|
||||
e.slow_mitigation = 0;
|
||||
e.attack = 0;
|
||||
e.strength = 0;
|
||||
e.stamina = 0;
|
||||
e.dexterity = 0;
|
||||
e.agility = 0;
|
||||
e.intelligence = 0;
|
||||
e.wisdom = 0;
|
||||
e.charisma = 0;
|
||||
e.magic_resist = 0;
|
||||
e.cold_resist = 0;
|
||||
e.fire_resist = 0;
|
||||
e.poison_resist = 0;
|
||||
e.disease_resist = 0;
|
||||
e.corruption_resist = 0;
|
||||
e.physical_resist = 0;
|
||||
e.min_dmg = 0;
|
||||
e.max_dmg = 0;
|
||||
e.hp_regen_rate = 0;
|
||||
e.hp_regen_per_second = 0;
|
||||
e.attack_delay = 0;
|
||||
e.spell_scale = 100;
|
||||
e.heal_scale = 100;
|
||||
e.avoidance = 0;
|
||||
e.heroic_strikethrough = 0;
|
||||
e.special_abilities = "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -212,8 +233,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
npc_scale_global_base_id
|
||||
)
|
||||
);
|
||||
@@ -222,34 +244,39 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
NpcScaleGlobalBase e{};
|
||||
|
||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||
e.ac = static_cast<int32_t>(atoi(row[2]));
|
||||
e.hp = static_cast<int32_t>(atoi(row[3]));
|
||||
e.accuracy = static_cast<int32_t>(atoi(row[4]));
|
||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[5]));
|
||||
e.attack = static_cast<int32_t>(atoi(row[6]));
|
||||
e.strength = static_cast<int32_t>(atoi(row[7]));
|
||||
e.stamina = static_cast<int32_t>(atoi(row[8]));
|
||||
e.dexterity = static_cast<int32_t>(atoi(row[9]));
|
||||
e.agility = static_cast<int32_t>(atoi(row[10]));
|
||||
e.intelligence = static_cast<int32_t>(atoi(row[11]));
|
||||
e.wisdom = static_cast<int32_t>(atoi(row[12]));
|
||||
e.charisma = static_cast<int32_t>(atoi(row[13]));
|
||||
e.magic_resist = static_cast<int32_t>(atoi(row[14]));
|
||||
e.cold_resist = static_cast<int32_t>(atoi(row[15]));
|
||||
e.fire_resist = static_cast<int32_t>(atoi(row[16]));
|
||||
e.poison_resist = static_cast<int32_t>(atoi(row[17]));
|
||||
e.disease_resist = static_cast<int32_t>(atoi(row[18]));
|
||||
e.corruption_resist = static_cast<int32_t>(atoi(row[19]));
|
||||
e.physical_resist = static_cast<int32_t>(atoi(row[20]));
|
||||
e.min_dmg = static_cast<int32_t>(atoi(row[21]));
|
||||
e.max_dmg = static_cast<int32_t>(atoi(row[22]));
|
||||
e.hp_regen_rate = static_cast<int32_t>(atoi(row[23]));
|
||||
e.attack_delay = static_cast<int32_t>(atoi(row[24]));
|
||||
e.spell_scale = static_cast<int32_t>(atoi(row[25]));
|
||||
e.heal_scale = static_cast<int32_t>(atoi(row[26]));
|
||||
e.special_abilities = row[27] ? row[27] : "";
|
||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||
e.zone_id_list = row[2] ? row[2] : "";
|
||||
e.instance_version_list = row[3] ? row[3] : "";
|
||||
e.ac = static_cast<int32_t>(atoi(row[4]));
|
||||
e.hp = strtoll(row[5], nullptr, 10);
|
||||
e.accuracy = static_cast<int32_t>(atoi(row[6]));
|
||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
|
||||
e.attack = static_cast<int32_t>(atoi(row[8]));
|
||||
e.strength = static_cast<int32_t>(atoi(row[9]));
|
||||
e.stamina = static_cast<int32_t>(atoi(row[10]));
|
||||
e.dexterity = static_cast<int32_t>(atoi(row[11]));
|
||||
e.agility = static_cast<int32_t>(atoi(row[12]));
|
||||
e.intelligence = static_cast<int32_t>(atoi(row[13]));
|
||||
e.wisdom = static_cast<int32_t>(atoi(row[14]));
|
||||
e.charisma = static_cast<int32_t>(atoi(row[15]));
|
||||
e.magic_resist = static_cast<int32_t>(atoi(row[16]));
|
||||
e.cold_resist = static_cast<int32_t>(atoi(row[17]));
|
||||
e.fire_resist = static_cast<int32_t>(atoi(row[18]));
|
||||
e.poison_resist = static_cast<int32_t>(atoi(row[19]));
|
||||
e.disease_resist = static_cast<int32_t>(atoi(row[20]));
|
||||
e.corruption_resist = static_cast<int32_t>(atoi(row[21]));
|
||||
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
|
||||
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
|
||||
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
|
||||
e.hp_regen_rate = strtoll(row[25], nullptr, 10);
|
||||
e.hp_regen_per_second = strtoll(row[26], nullptr, 10);
|
||||
e.attack_delay = static_cast<int32_t>(atoi(row[27]));
|
||||
e.spell_scale = static_cast<int32_t>(atoi(row[28]));
|
||||
e.heal_scale = static_cast<int32_t>(atoi(row[29]));
|
||||
e.avoidance = static_cast<uint32_t>(strtoul(row[30], nullptr, 10));
|
||||
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[31]));
|
||||
e.special_abilities = row[32] ? row[32] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -285,32 +312,37 @@ public:
|
||||
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.type));
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.level));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.ac));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.hp));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.accuracy));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.slow_mitigation));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.attack));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.strength));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.stamina));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.dexterity));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.agility));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.intelligence));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.wisdom));
|
||||
v.push_back(columns[13] + " = " + std::to_string(e.charisma));
|
||||
v.push_back(columns[14] + " = " + std::to_string(e.magic_resist));
|
||||
v.push_back(columns[15] + " = " + std::to_string(e.cold_resist));
|
||||
v.push_back(columns[16] + " = " + std::to_string(e.fire_resist));
|
||||
v.push_back(columns[17] + " = " + std::to_string(e.poison_resist));
|
||||
v.push_back(columns[18] + " = " + std::to_string(e.disease_resist));
|
||||
v.push_back(columns[19] + " = " + std::to_string(e.corruption_resist));
|
||||
v.push_back(columns[20] + " = " + std::to_string(e.physical_resist));
|
||||
v.push_back(columns[21] + " = " + std::to_string(e.min_dmg));
|
||||
v.push_back(columns[22] + " = " + std::to_string(e.max_dmg));
|
||||
v.push_back(columns[23] + " = " + std::to_string(e.hp_regen_rate));
|
||||
v.push_back(columns[24] + " = " + std::to_string(e.attack_delay));
|
||||
v.push_back(columns[25] + " = " + std::to_string(e.spell_scale));
|
||||
v.push_back(columns[26] + " = " + std::to_string(e.heal_scale));
|
||||
v.push_back(columns[27] + " = '" + Strings::Escape(e.special_abilities) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.zone_id_list) + "'");
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.instance_version_list) + "'");
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.ac));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.hp));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.accuracy));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.slow_mitigation));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.attack));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.strength));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.stamina));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.dexterity));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.agility));
|
||||
v.push_back(columns[13] + " = " + std::to_string(e.intelligence));
|
||||
v.push_back(columns[14] + " = " + std::to_string(e.wisdom));
|
||||
v.push_back(columns[15] + " = " + std::to_string(e.charisma));
|
||||
v.push_back(columns[16] + " = " + std::to_string(e.magic_resist));
|
||||
v.push_back(columns[17] + " = " + std::to_string(e.cold_resist));
|
||||
v.push_back(columns[18] + " = " + std::to_string(e.fire_resist));
|
||||
v.push_back(columns[19] + " = " + std::to_string(e.poison_resist));
|
||||
v.push_back(columns[20] + " = " + std::to_string(e.disease_resist));
|
||||
v.push_back(columns[21] + " = " + std::to_string(e.corruption_resist));
|
||||
v.push_back(columns[22] + " = " + std::to_string(e.physical_resist));
|
||||
v.push_back(columns[23] + " = " + std::to_string(e.min_dmg));
|
||||
v.push_back(columns[24] + " = " + std::to_string(e.max_dmg));
|
||||
v.push_back(columns[25] + " = " + std::to_string(e.hp_regen_rate));
|
||||
v.push_back(columns[26] + " = " + std::to_string(e.hp_regen_per_second));
|
||||
v.push_back(columns[27] + " = " + std::to_string(e.attack_delay));
|
||||
v.push_back(columns[28] + " = " + std::to_string(e.spell_scale));
|
||||
v.push_back(columns[29] + " = " + std::to_string(e.heal_scale));
|
||||
v.push_back(columns[30] + " = " + std::to_string(e.avoidance));
|
||||
v.push_back(columns[31] + " = " + std::to_string(e.heroic_strikethrough));
|
||||
v.push_back(columns[32] + " = '" + Strings::Escape(e.special_abilities) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -334,6 +366,8 @@ public:
|
||||
|
||||
v.push_back(std::to_string(e.type));
|
||||
v.push_back(std::to_string(e.level));
|
||||
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.instance_version_list) + "'");
|
||||
v.push_back(std::to_string(e.ac));
|
||||
v.push_back(std::to_string(e.hp));
|
||||
v.push_back(std::to_string(e.accuracy));
|
||||
@@ -356,9 +390,12 @@ public:
|
||||
v.push_back(std::to_string(e.min_dmg));
|
||||
v.push_back(std::to_string(e.max_dmg));
|
||||
v.push_back(std::to_string(e.hp_regen_rate));
|
||||
v.push_back(std::to_string(e.hp_regen_per_second));
|
||||
v.push_back(std::to_string(e.attack_delay));
|
||||
v.push_back(std::to_string(e.spell_scale));
|
||||
v.push_back(std::to_string(e.heal_scale));
|
||||
v.push_back(std::to_string(e.avoidance));
|
||||
v.push_back(std::to_string(e.heroic_strikethrough));
|
||||
v.push_back("'" + Strings::Escape(e.special_abilities) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
@@ -391,6 +428,8 @@ public:
|
||||
|
||||
v.push_back(std::to_string(e.type));
|
||||
v.push_back(std::to_string(e.level));
|
||||
v.push_back("'" + Strings::Escape(e.zone_id_list) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.instance_version_list) + "'");
|
||||
v.push_back(std::to_string(e.ac));
|
||||
v.push_back(std::to_string(e.hp));
|
||||
v.push_back(std::to_string(e.accuracy));
|
||||
@@ -413,9 +452,12 @@ public:
|
||||
v.push_back(std::to_string(e.min_dmg));
|
||||
v.push_back(std::to_string(e.max_dmg));
|
||||
v.push_back(std::to_string(e.hp_regen_rate));
|
||||
v.push_back(std::to_string(e.hp_regen_per_second));
|
||||
v.push_back(std::to_string(e.attack_delay));
|
||||
v.push_back(std::to_string(e.spell_scale));
|
||||
v.push_back(std::to_string(e.heal_scale));
|
||||
v.push_back(std::to_string(e.avoidance));
|
||||
v.push_back(std::to_string(e.heroic_strikethrough));
|
||||
v.push_back("'" + Strings::Escape(e.special_abilities) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
@@ -450,34 +492,39 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
NpcScaleGlobalBase e{};
|
||||
|
||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||
e.ac = static_cast<int32_t>(atoi(row[2]));
|
||||
e.hp = static_cast<int32_t>(atoi(row[3]));
|
||||
e.accuracy = static_cast<int32_t>(atoi(row[4]));
|
||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[5]));
|
||||
e.attack = static_cast<int32_t>(atoi(row[6]));
|
||||
e.strength = static_cast<int32_t>(atoi(row[7]));
|
||||
e.stamina = static_cast<int32_t>(atoi(row[8]));
|
||||
e.dexterity = static_cast<int32_t>(atoi(row[9]));
|
||||
e.agility = static_cast<int32_t>(atoi(row[10]));
|
||||
e.intelligence = static_cast<int32_t>(atoi(row[11]));
|
||||
e.wisdom = static_cast<int32_t>(atoi(row[12]));
|
||||
e.charisma = static_cast<int32_t>(atoi(row[13]));
|
||||
e.magic_resist = static_cast<int32_t>(atoi(row[14]));
|
||||
e.cold_resist = static_cast<int32_t>(atoi(row[15]));
|
||||
e.fire_resist = static_cast<int32_t>(atoi(row[16]));
|
||||
e.poison_resist = static_cast<int32_t>(atoi(row[17]));
|
||||
e.disease_resist = static_cast<int32_t>(atoi(row[18]));
|
||||
e.corruption_resist = static_cast<int32_t>(atoi(row[19]));
|
||||
e.physical_resist = static_cast<int32_t>(atoi(row[20]));
|
||||
e.min_dmg = static_cast<int32_t>(atoi(row[21]));
|
||||
e.max_dmg = static_cast<int32_t>(atoi(row[22]));
|
||||
e.hp_regen_rate = static_cast<int32_t>(atoi(row[23]));
|
||||
e.attack_delay = static_cast<int32_t>(atoi(row[24]));
|
||||
e.spell_scale = static_cast<int32_t>(atoi(row[25]));
|
||||
e.heal_scale = static_cast<int32_t>(atoi(row[26]));
|
||||
e.special_abilities = row[27] ? row[27] : "";
|
||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||
e.zone_id_list = row[2] ? row[2] : "";
|
||||
e.instance_version_list = row[3] ? row[3] : "";
|
||||
e.ac = static_cast<int32_t>(atoi(row[4]));
|
||||
e.hp = strtoll(row[5], nullptr, 10);
|
||||
e.accuracy = static_cast<int32_t>(atoi(row[6]));
|
||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
|
||||
e.attack = static_cast<int32_t>(atoi(row[8]));
|
||||
e.strength = static_cast<int32_t>(atoi(row[9]));
|
||||
e.stamina = static_cast<int32_t>(atoi(row[10]));
|
||||
e.dexterity = static_cast<int32_t>(atoi(row[11]));
|
||||
e.agility = static_cast<int32_t>(atoi(row[12]));
|
||||
e.intelligence = static_cast<int32_t>(atoi(row[13]));
|
||||
e.wisdom = static_cast<int32_t>(atoi(row[14]));
|
||||
e.charisma = static_cast<int32_t>(atoi(row[15]));
|
||||
e.magic_resist = static_cast<int32_t>(atoi(row[16]));
|
||||
e.cold_resist = static_cast<int32_t>(atoi(row[17]));
|
||||
e.fire_resist = static_cast<int32_t>(atoi(row[18]));
|
||||
e.poison_resist = static_cast<int32_t>(atoi(row[19]));
|
||||
e.disease_resist = static_cast<int32_t>(atoi(row[20]));
|
||||
e.corruption_resist = static_cast<int32_t>(atoi(row[21]));
|
||||
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
|
||||
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
|
||||
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
|
||||
e.hp_regen_rate = strtoll(row[25], nullptr, 10);
|
||||
e.hp_regen_per_second = strtoll(row[26], nullptr, 10);
|
||||
e.attack_delay = static_cast<int32_t>(atoi(row[27]));
|
||||
e.spell_scale = static_cast<int32_t>(atoi(row[28]));
|
||||
e.heal_scale = static_cast<int32_t>(atoi(row[29]));
|
||||
e.avoidance = static_cast<uint32_t>(strtoul(row[30], nullptr, 10));
|
||||
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[31]));
|
||||
e.special_abilities = row[32] ? row[32] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -502,34 +549,39 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
NpcScaleGlobalBase e{};
|
||||
|
||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||
e.ac = static_cast<int32_t>(atoi(row[2]));
|
||||
e.hp = static_cast<int32_t>(atoi(row[3]));
|
||||
e.accuracy = static_cast<int32_t>(atoi(row[4]));
|
||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[5]));
|
||||
e.attack = static_cast<int32_t>(atoi(row[6]));
|
||||
e.strength = static_cast<int32_t>(atoi(row[7]));
|
||||
e.stamina = static_cast<int32_t>(atoi(row[8]));
|
||||
e.dexterity = static_cast<int32_t>(atoi(row[9]));
|
||||
e.agility = static_cast<int32_t>(atoi(row[10]));
|
||||
e.intelligence = static_cast<int32_t>(atoi(row[11]));
|
||||
e.wisdom = static_cast<int32_t>(atoi(row[12]));
|
||||
e.charisma = static_cast<int32_t>(atoi(row[13]));
|
||||
e.magic_resist = static_cast<int32_t>(atoi(row[14]));
|
||||
e.cold_resist = static_cast<int32_t>(atoi(row[15]));
|
||||
e.fire_resist = static_cast<int32_t>(atoi(row[16]));
|
||||
e.poison_resist = static_cast<int32_t>(atoi(row[17]));
|
||||
e.disease_resist = static_cast<int32_t>(atoi(row[18]));
|
||||
e.corruption_resist = static_cast<int32_t>(atoi(row[19]));
|
||||
e.physical_resist = static_cast<int32_t>(atoi(row[20]));
|
||||
e.min_dmg = static_cast<int32_t>(atoi(row[21]));
|
||||
e.max_dmg = static_cast<int32_t>(atoi(row[22]));
|
||||
e.hp_regen_rate = static_cast<int32_t>(atoi(row[23]));
|
||||
e.attack_delay = static_cast<int32_t>(atoi(row[24]));
|
||||
e.spell_scale = static_cast<int32_t>(atoi(row[25]));
|
||||
e.heal_scale = static_cast<int32_t>(atoi(row[26]));
|
||||
e.special_abilities = row[27] ? row[27] : "";
|
||||
e.type = static_cast<int32_t>(atoi(row[0]));
|
||||
e.level = static_cast<int32_t>(atoi(row[1]));
|
||||
e.zone_id_list = row[2] ? row[2] : "";
|
||||
e.instance_version_list = row[3] ? row[3] : "";
|
||||
e.ac = static_cast<int32_t>(atoi(row[4]));
|
||||
e.hp = strtoll(row[5], nullptr, 10);
|
||||
e.accuracy = static_cast<int32_t>(atoi(row[6]));
|
||||
e.slow_mitigation = static_cast<int32_t>(atoi(row[7]));
|
||||
e.attack = static_cast<int32_t>(atoi(row[8]));
|
||||
e.strength = static_cast<int32_t>(atoi(row[9]));
|
||||
e.stamina = static_cast<int32_t>(atoi(row[10]));
|
||||
e.dexterity = static_cast<int32_t>(atoi(row[11]));
|
||||
e.agility = static_cast<int32_t>(atoi(row[12]));
|
||||
e.intelligence = static_cast<int32_t>(atoi(row[13]));
|
||||
e.wisdom = static_cast<int32_t>(atoi(row[14]));
|
||||
e.charisma = static_cast<int32_t>(atoi(row[15]));
|
||||
e.magic_resist = static_cast<int32_t>(atoi(row[16]));
|
||||
e.cold_resist = static_cast<int32_t>(atoi(row[17]));
|
||||
e.fire_resist = static_cast<int32_t>(atoi(row[18]));
|
||||
e.poison_resist = static_cast<int32_t>(atoi(row[19]));
|
||||
e.disease_resist = static_cast<int32_t>(atoi(row[20]));
|
||||
e.corruption_resist = static_cast<int32_t>(atoi(row[21]));
|
||||
e.physical_resist = static_cast<int32_t>(atoi(row[22]));
|
||||
e.min_dmg = static_cast<int32_t>(atoi(row[23]));
|
||||
e.max_dmg = static_cast<int32_t>(atoi(row[24]));
|
||||
e.hp_regen_rate = strtoll(row[25], nullptr, 10);
|
||||
e.hp_regen_per_second = strtoll(row[26], nullptr, 10);
|
||||
e.attack_delay = static_cast<int32_t>(atoi(row[27]));
|
||||
e.spell_scale = static_cast<int32_t>(atoi(row[28]));
|
||||
e.heal_scale = static_cast<int32_t>(atoi(row[29]));
|
||||
e.avoidance = static_cast<uint32_t>(strtoul(row[30], nullptr, 10));
|
||||
e.heroic_strikethrough = static_cast<int32_t>(atoi(row[31]));
|
||||
e.special_abilities = row[32] ? row[32] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
+78
-86
@@ -9,22 +9,21 @@
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_HACKERS_REPOSITORY_H
|
||||
#define EQEMU_BASE_HACKERS_REPOSITORY_H
|
||||
#ifndef EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||
#define EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
class BaseHackersRepository {
|
||||
class BasePlayerEventLogSettingsRepository {
|
||||
public:
|
||||
struct Hackers {
|
||||
int32_t id;
|
||||
std::string account;
|
||||
std::string name;
|
||||
std::string hacked;
|
||||
std::string zone;
|
||||
std::string date;
|
||||
struct PlayerEventLogSettings {
|
||||
int64_t id;
|
||||
std::string event_name;
|
||||
int8_t event_enabled;
|
||||
int32_t retention_days;
|
||||
int32_t discord_webhook_id;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -36,11 +35,10 @@ public:
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"account",
|
||||
"name",
|
||||
"hacked",
|
||||
"zone",
|
||||
"date",
|
||||
"event_name",
|
||||
"event_enabled",
|
||||
"retention_days",
|
||||
"discord_webhook_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,11 +46,10 @@ public:
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"account",
|
||||
"name",
|
||||
"hacked",
|
||||
"zone",
|
||||
"date",
|
||||
"event_name",
|
||||
"event_enabled",
|
||||
"retention_days",
|
||||
"discord_webhook_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -68,7 +65,7 @@ public:
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("hackers");
|
||||
return std::string("player_event_log_settings");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
@@ -89,57 +86,56 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
static Hackers NewEntity()
|
||||
static PlayerEventLogSettings NewEntity()
|
||||
{
|
||||
Hackers e{};
|
||||
PlayerEventLogSettings e{};
|
||||
|
||||
e.id = 0;
|
||||
e.account = "";
|
||||
e.name = "";
|
||||
e.hacked = "";
|
||||
e.zone = "";
|
||||
e.date = std::time(nullptr);
|
||||
e.id = 0;
|
||||
e.event_name = "";
|
||||
e.event_enabled = 0;
|
||||
e.retention_days = 0;
|
||||
e.discord_webhook_id = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static Hackers GetHackers(
|
||||
const std::vector<Hackers> &hackerss,
|
||||
int hackers_id
|
||||
static PlayerEventLogSettings GetPlayerEventLogSettings(
|
||||
const std::vector<PlayerEventLogSettings> &player_event_log_settingss,
|
||||
int player_event_log_settings_id
|
||||
)
|
||||
{
|
||||
for (auto &hackers : hackerss) {
|
||||
if (hackers.id == hackers_id) {
|
||||
return hackers;
|
||||
for (auto &player_event_log_settings : player_event_log_settingss) {
|
||||
if (player_event_log_settings.id == player_event_log_settings_id) {
|
||||
return player_event_log_settings;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static Hackers FindOne(
|
||||
static PlayerEventLogSettings FindOne(
|
||||
Database& db,
|
||||
int hackers_id
|
||||
int player_event_log_settings_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
hackers_id
|
||||
PrimaryKey(),
|
||||
player_event_log_settings_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
Hackers e{};
|
||||
PlayerEventLogSettings e{};
|
||||
|
||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
||||
e.account = row[1] ? row[1] : "";
|
||||
e.name = row[2] ? row[2] : "";
|
||||
e.hacked = row[3] ? row[3] : "";
|
||||
e.zone = row[4] ? row[4] : "";
|
||||
e.date = row[5] ? row[5] : "";
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.event_name = row[1] ? row[1] : "";
|
||||
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
|
||||
e.retention_days = static_cast<int32_t>(atoi(row[3]));
|
||||
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -149,7 +145,7 @@ public:
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int hackers_id
|
||||
int player_event_log_settings_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
@@ -157,7 +153,7 @@ public:
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
hackers_id
|
||||
player_event_log_settings_id
|
||||
)
|
||||
);
|
||||
|
||||
@@ -166,18 +162,18 @@ public:
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const Hackers &e
|
||||
const PlayerEventLogSettings &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.account) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.hacked) + "'");
|
||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.zone) + "'");
|
||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.date) + "'");
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.id));
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.event_name) + "'");
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.event_enabled));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.retention_days));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.discord_webhook_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -192,19 +188,18 @@ public:
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static Hackers InsertOne(
|
||||
static PlayerEventLogSettings InsertOne(
|
||||
Database& db,
|
||||
Hackers e
|
||||
PlayerEventLogSettings e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.account) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.hacked) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.zone) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.date) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.event_name) + "'");
|
||||
v.push_back(std::to_string(e.event_enabled));
|
||||
v.push_back(std::to_string(e.retention_days));
|
||||
v.push_back(std::to_string(e.discord_webhook_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -226,7 +221,7 @@ public:
|
||||
|
||||
static int InsertMany(
|
||||
Database& db,
|
||||
const std::vector<Hackers> &entries
|
||||
const std::vector<PlayerEventLogSettings> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
@@ -235,11 +230,10 @@ public:
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back("'" + Strings::Escape(e.account) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.hacked) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.zone) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.date) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.event_name) + "'");
|
||||
v.push_back(std::to_string(e.event_enabled));
|
||||
v.push_back(std::to_string(e.retention_days));
|
||||
v.push_back(std::to_string(e.discord_webhook_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -257,9 +251,9 @@ public:
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static std::vector<Hackers> All(Database& db)
|
||||
static std::vector<PlayerEventLogSettings> All(Database& db)
|
||||
{
|
||||
std::vector<Hackers> all_entries;
|
||||
std::vector<PlayerEventLogSettings> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -271,14 +265,13 @@ public:
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Hackers e{};
|
||||
PlayerEventLogSettings e{};
|
||||
|
||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
||||
e.account = row[1] ? row[1] : "";
|
||||
e.name = row[2] ? row[2] : "";
|
||||
e.hacked = row[3] ? row[3] : "";
|
||||
e.zone = row[4] ? row[4] : "";
|
||||
e.date = row[5] ? row[5] : "";
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.event_name = row[1] ? row[1] : "";
|
||||
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
|
||||
e.retention_days = static_cast<int32_t>(atoi(row[3]));
|
||||
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -286,9 +279,9 @@ public:
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<Hackers> GetWhere(Database& db, const std::string &where_filter)
|
||||
static std::vector<PlayerEventLogSettings> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<Hackers> all_entries;
|
||||
std::vector<PlayerEventLogSettings> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -301,14 +294,13 @@ public:
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
Hackers e{};
|
||||
PlayerEventLogSettings e{};
|
||||
|
||||
e.id = static_cast<int32_t>(atoi(row[0]));
|
||||
e.account = row[1] ? row[1] : "";
|
||||
e.name = row[2] ? row[2] : "";
|
||||
e.hacked = row[3] ? row[3] : "";
|
||||
e.zone = row[4] ? row[4] : "";
|
||||
e.date = row[5] ? row[5] : "";
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.event_name = row[1] ? row[1] : "";
|
||||
e.event_enabled = static_cast<int8_t>(atoi(row[2]));
|
||||
e.retention_days = static_cast<int32_t>(atoi(row[3]));
|
||||
e.discord_webhook_id = static_cast<int32_t>(atoi(row[4]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -369,4 +361,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_HACKERS_REPOSITORY_H
|
||||
#endif //EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||
@@ -0,0 +1,465 @@
|
||||
/**
|
||||
* DO NOT MODIFY THIS FILE
|
||||
*
|
||||
* This repository was automatically generated and is NOT to be modified directly.
|
||||
* Any repository modifications are meant to be made to the repository extending the base.
|
||||
* Any modifications to base repositories are to be made by the generator only
|
||||
*
|
||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||
#define EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||
|
||||
#include "../../database.h"
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
#include <cereal/cereal.hpp>
|
||||
|
||||
class BasePlayerEventLogsRepository {
|
||||
public:
|
||||
struct PlayerEventLogs {
|
||||
int64_t id;
|
||||
int64_t account_id;
|
||||
int64_t character_id;
|
||||
int32_t zone_id;
|
||||
int32_t instance_id;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float heading;
|
||||
int32_t event_type_id;
|
||||
std::string event_type_name;
|
||||
std::string event_data;
|
||||
time_t created_at;
|
||||
|
||||
// cereal
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar)
|
||||
{
|
||||
ar(
|
||||
CEREAL_NVP(id),
|
||||
CEREAL_NVP(account_id),
|
||||
CEREAL_NVP(character_id),
|
||||
CEREAL_NVP(zone_id),
|
||||
CEREAL_NVP(instance_id),
|
||||
CEREAL_NVP(x),
|
||||
CEREAL_NVP(y),
|
||||
CEREAL_NVP(z),
|
||||
CEREAL_NVP(heading),
|
||||
CEREAL_NVP(event_type_id),
|
||||
CEREAL_NVP(event_type_name),
|
||||
CEREAL_NVP(event_data),
|
||||
CEREAL_NVP(created_at)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"account_id",
|
||||
"character_id",
|
||||
"zone_id",
|
||||
"instance_id",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"heading",
|
||||
"event_type_id",
|
||||
"event_type_name",
|
||||
"event_data",
|
||||
"created_at",
|
||||
};
|
||||
}
|
||||
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"account_id",
|
||||
"character_id",
|
||||
"zone_id",
|
||||
"instance_id",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"heading",
|
||||
"event_type_id",
|
||||
"event_type_name",
|
||||
"event_data",
|
||||
"UNIX_TIMESTAMP(created_at)",
|
||||
};
|
||||
}
|
||||
|
||||
static std::string ColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", Columns()));
|
||||
}
|
||||
|
||||
static std::string SelectColumnsRaw()
|
||||
{
|
||||
return std::string(Strings::Implode(", ", SelectColumns()));
|
||||
}
|
||||
|
||||
static std::string TableName()
|
||||
{
|
||||
return std::string("player_event_logs");
|
||||
}
|
||||
|
||||
static std::string BaseSelect()
|
||||
{
|
||||
return fmt::format(
|
||||
"SELECT {} FROM {}",
|
||||
SelectColumnsRaw(),
|
||||
TableName()
|
||||
);
|
||||
}
|
||||
|
||||
static std::string BaseInsert()
|
||||
{
|
||||
return fmt::format(
|
||||
"INSERT INTO {} ({}) ",
|
||||
TableName(),
|
||||
ColumnsRaw()
|
||||
);
|
||||
}
|
||||
|
||||
static PlayerEventLogs NewEntity()
|
||||
{
|
||||
PlayerEventLogs e{};
|
||||
|
||||
e.id = 0;
|
||||
e.account_id = 0;
|
||||
e.character_id = 0;
|
||||
e.zone_id = 0;
|
||||
e.instance_id = 0;
|
||||
e.x = 0;
|
||||
e.y = 0;
|
||||
e.z = 0;
|
||||
e.heading = 0;
|
||||
e.event_type_id = 0;
|
||||
e.event_type_name = "";
|
||||
e.event_data = "";
|
||||
e.created_at = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static PlayerEventLogs GetPlayerEventLogs(
|
||||
const std::vector<PlayerEventLogs> &player_event_logss,
|
||||
int player_event_logs_id
|
||||
)
|
||||
{
|
||||
for (auto &player_event_logs : player_event_logss) {
|
||||
if (player_event_logs.id == player_event_logs_id) {
|
||||
return player_event_logs;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static PlayerEventLogs FindOne(
|
||||
Database& db,
|
||||
int player_event_logs_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
player_event_logs_id
|
||||
)
|
||||
);
|
||||
|
||||
auto row = results.begin();
|
||||
if (results.RowCount() == 1) {
|
||||
PlayerEventLogs e{};
|
||||
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.account_id = strtoll(row[1], nullptr, 10);
|
||||
e.character_id = strtoll(row[2], nullptr, 10);
|
||||
e.zone_id = static_cast<int32_t>(atoi(row[3]));
|
||||
e.instance_id = static_cast<int32_t>(atoi(row[4]));
|
||||
e.x = strtof(row[5], nullptr);
|
||||
e.y = strtof(row[6], nullptr);
|
||||
e.z = strtof(row[7], nullptr);
|
||||
e.heading = strtof(row[8], nullptr);
|
||||
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
|
||||
e.event_type_name = row[10] ? row[10] : "";
|
||||
e.event_data = row[11] ? row[11] : "";
|
||||
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
return NewEntity();
|
||||
}
|
||||
|
||||
static int DeleteOne(
|
||||
Database& db,
|
||||
int player_event_logs_id
|
||||
)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {} = {}",
|
||||
TableName(),
|
||||
PrimaryKey(),
|
||||
player_event_logs_id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int UpdateOne(
|
||||
Database& db,
|
||||
const PlayerEventLogs &e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.account_id));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.character_id));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.zone_id));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.instance_id));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.x));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.y));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.z));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.heading));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.event_type_id));
|
||||
v.push_back(columns[10] + " = '" + db.Escape(e.event_type_name) + "'");
|
||||
v.push_back(columns[11] + " = '" + db.Escape(e.event_data) + "'");
|
||||
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE {} SET {} WHERE {} = {}",
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static PlayerEventLogs InsertOne(
|
||||
Database& db,
|
||||
PlayerEventLogs e
|
||||
)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.account_id));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.zone_id));
|
||||
v.push_back(std::to_string(e.instance_id));
|
||||
v.push_back(std::to_string(e.x));
|
||||
v.push_back(std::to_string(e.y));
|
||||
v.push_back(std::to_string(e.z));
|
||||
v.push_back(std::to_string(e.heading));
|
||||
v.push_back(std::to_string(e.event_type_id));
|
||||
v.push_back("'" + db.Escape(e.event_type_name) + "'");
|
||||
v.push_back("'" + db.Escape(e.event_data) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES ({})",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", v)
|
||||
)
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
e = NewEntity();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static int InsertMany(
|
||||
Database& db,
|
||||
const std::vector<PlayerEventLogs> &entries
|
||||
)
|
||||
{
|
||||
std::vector<std::string> insert_chunks;
|
||||
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.account_id));
|
||||
v.push_back(std::to_string(e.character_id));
|
||||
v.push_back(std::to_string(e.zone_id));
|
||||
v.push_back(std::to_string(e.instance_id));
|
||||
v.push_back(std::to_string(e.x));
|
||||
v.push_back(std::to_string(e.y));
|
||||
v.push_back(std::to_string(e.z));
|
||||
v.push_back(std::to_string(e.heading));
|
||||
v.push_back(std::to_string(e.event_type_id));
|
||||
v.push_back("'" + db.Escape(e.event_type_name) + "'");
|
||||
v.push_back("'" + db.Escape(e.event_data) + "'");
|
||||
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
std::vector<std::string> v;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} VALUES {}",
|
||||
BaseInsert(),
|
||||
Strings::Implode(",", insert_chunks)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static std::vector<PlayerEventLogs> All(Database& db)
|
||||
{
|
||||
std::vector<PlayerEventLogs> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{}",
|
||||
BaseSelect()
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
PlayerEventLogs e{};
|
||||
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.account_id = strtoll(row[1], nullptr, 10);
|
||||
e.character_id = strtoll(row[2], nullptr, 10);
|
||||
e.zone_id = static_cast<int32_t>(atoi(row[3]));
|
||||
e.instance_id = static_cast<int32_t>(atoi(row[4]));
|
||||
e.x = strtof(row[5], nullptr);
|
||||
e.y = strtof(row[6], nullptr);
|
||||
e.z = strtof(row[7], nullptr);
|
||||
e.heading = strtof(row[8], nullptr);
|
||||
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
|
||||
e.event_type_name = row[10] ? row[10] : "";
|
||||
e.event_data = row[11] ? row[11] : "";
|
||||
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static std::vector<PlayerEventLogs> GetWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
std::vector<PlayerEventLogs> all_entries;
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE {}",
|
||||
BaseSelect(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
PlayerEventLogs e{};
|
||||
|
||||
e.id = strtoll(row[0], nullptr, 10);
|
||||
e.account_id = strtoll(row[1], nullptr, 10);
|
||||
e.character_id = strtoll(row[2], nullptr, 10);
|
||||
e.zone_id = static_cast<int32_t>(atoi(row[3]));
|
||||
e.instance_id = static_cast<int32_t>(atoi(row[4]));
|
||||
e.x = strtof(row[5], nullptr);
|
||||
e.y = strtof(row[6], nullptr);
|
||||
e.z = strtof(row[7], nullptr);
|
||||
e.heading = strtof(row[8], nullptr);
|
||||
e.event_type_id = static_cast<int32_t>(atoi(row[9]));
|
||||
e.event_type_name = row[10] ? row[10] : "";
|
||||
e.event_data = row[11] ? row[11] : "";
|
||||
e.created_at = strtoll(row[12] ? row[12] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
static int DeleteWhere(Database& db, const std::string &where_filter)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"DELETE FROM {} WHERE {}",
|
||||
TableName(),
|
||||
where_filter
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int Truncate(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"TRUNCATE TABLE {}",
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() ? results.RowsAffected() : 0);
|
||||
}
|
||||
|
||||
static int64 GetMaxId(Database& db)
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COALESCE(MAX({}), 0) FROM {}",
|
||||
PrimaryKey(),
|
||||
TableName()
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
static int64 Count(Database& db, const std::string &where_filter = "")
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"SELECT COUNT(*) FROM {} {}",
|
||||
TableName(),
|
||||
(where_filter.empty() ? "" : "WHERE " + where_filter)
|
||||
)
|
||||
);
|
||||
|
||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||
@@ -16,11 +16,14 @@
|
||||
#include "../../strings.h"
|
||||
#include <ctime>
|
||||
|
||||
|
||||
class BaseRaidMembersRepository {
|
||||
public:
|
||||
struct RaidMembers {
|
||||
uint64_t id;
|
||||
int32_t raidid;
|
||||
int32_t charid;
|
||||
int32_t bot_id;
|
||||
uint32_t groupid;
|
||||
int8_t _class;
|
||||
int8_t level;
|
||||
@@ -32,14 +35,16 @@ public:
|
||||
|
||||
static std::string PrimaryKey()
|
||||
{
|
||||
return std::string("charid");
|
||||
return std::string("id");
|
||||
}
|
||||
|
||||
static std::vector<std::string> Columns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"raidid",
|
||||
"charid",
|
||||
"bot_id",
|
||||
"groupid",
|
||||
"_class",
|
||||
"level",
|
||||
@@ -53,8 +58,10 @@ public:
|
||||
static std::vector<std::string> SelectColumns()
|
||||
{
|
||||
return {
|
||||
"id",
|
||||
"raidid",
|
||||
"charid",
|
||||
"bot_id",
|
||||
"groupid",
|
||||
"_class",
|
||||
"level",
|
||||
@@ -102,8 +109,10 @@ public:
|
||||
{
|
||||
RaidMembers e{};
|
||||
|
||||
e.id = 0;
|
||||
e.raidid = 0;
|
||||
e.charid = 0;
|
||||
e.bot_id = 0;
|
||||
e.groupid = 0;
|
||||
e._class = 0;
|
||||
e.level = 0;
|
||||
@@ -121,7 +130,7 @@ public:
|
||||
)
|
||||
{
|
||||
for (auto &raid_members : raid_memberss) {
|
||||
if (raid_members.charid == raid_members_id) {
|
||||
if (raid_members.id == raid_members_id) {
|
||||
return raid_members;
|
||||
}
|
||||
}
|
||||
@@ -136,8 +145,9 @@ public:
|
||||
{
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"{} WHERE id = {} LIMIT 1",
|
||||
"{} WHERE {} = {} LIMIT 1",
|
||||
BaseSelect(),
|
||||
PrimaryKey(),
|
||||
raid_members_id
|
||||
)
|
||||
);
|
||||
@@ -146,15 +156,17 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
RaidMembers e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.charid = static_cast<int32_t>(atoi(row[1]));
|
||||
e.groupid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e._class = static_cast<int8_t>(atoi(row[3]));
|
||||
e.level = static_cast<int8_t>(atoi(row[4]));
|
||||
e.name = row[5] ? row[5] : "";
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[6]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[7]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[8]));
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.raidid = static_cast<int32_t>(atoi(row[1]));
|
||||
e.charid = static_cast<int32_t>(atoi(row[2]));
|
||||
e.bot_id = static_cast<int32_t>(atoi(row[3]));
|
||||
e.groupid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e._class = static_cast<int8_t>(atoi(row[5]));
|
||||
e.level = static_cast<int8_t>(atoi(row[6]));
|
||||
e.name = row[7] ? row[7] : "";
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[9]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[10]));
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -188,15 +200,16 @@ public:
|
||||
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[0] + " = " + std::to_string(e.raidid));
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.charid));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.groupid));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e._class));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.level));
|
||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.isgroupleader));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.israidleader));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.islooter));
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.raidid));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.charid));
|
||||
v.push_back(columns[3] + " = " + std::to_string(e.bot_id));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.groupid));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e._class));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.level));
|
||||
v.push_back(columns[7] + " = '" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.isgroupleader));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.israidleader));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.islooter));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -204,7 +217,7 @@ public:
|
||||
TableName(),
|
||||
Strings::Implode(", ", v),
|
||||
PrimaryKey(),
|
||||
e.charid
|
||||
e.id
|
||||
)
|
||||
);
|
||||
|
||||
@@ -218,8 +231,10 @@ public:
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.raidid));
|
||||
v.push_back(std::to_string(e.charid));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
v.push_back(std::to_string(e.groupid));
|
||||
v.push_back(std::to_string(e._class));
|
||||
v.push_back(std::to_string(e.level));
|
||||
@@ -237,7 +252,7 @@ public:
|
||||
);
|
||||
|
||||
if (results.Success()) {
|
||||
e.charid = results.LastInsertedID();
|
||||
e.id = results.LastInsertedID();
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -256,8 +271,10 @@ public:
|
||||
for (auto &e: entries) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
v.push_back(std::to_string(e.id));
|
||||
v.push_back(std::to_string(e.raidid));
|
||||
v.push_back(std::to_string(e.charid));
|
||||
v.push_back(std::to_string(e.bot_id));
|
||||
v.push_back(std::to_string(e.groupid));
|
||||
v.push_back(std::to_string(e._class));
|
||||
v.push_back(std::to_string(e.level));
|
||||
@@ -298,15 +315,17 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidMembers e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.charid = static_cast<int32_t>(atoi(row[1]));
|
||||
e.groupid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e._class = static_cast<int8_t>(atoi(row[3]));
|
||||
e.level = static_cast<int8_t>(atoi(row[4]));
|
||||
e.name = row[5] ? row[5] : "";
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[6]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[7]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[8]));
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.raidid = static_cast<int32_t>(atoi(row[1]));
|
||||
e.charid = static_cast<int32_t>(atoi(row[2]));
|
||||
e.bot_id = static_cast<int32_t>(atoi(row[3]));
|
||||
e.groupid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e._class = static_cast<int8_t>(atoi(row[5]));
|
||||
e.level = static_cast<int8_t>(atoi(row[6]));
|
||||
e.name = row[7] ? row[7] : "";
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[9]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[10]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -331,15 +350,17 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidMembers e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.charid = static_cast<int32_t>(atoi(row[1]));
|
||||
e.groupid = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||
e._class = static_cast<int8_t>(atoi(row[3]));
|
||||
e.level = static_cast<int8_t>(atoi(row[4]));
|
||||
e.name = row[5] ? row[5] : "";
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[6]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[7]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[8]));
|
||||
e.id = strtoull(row[0], nullptr, 10);
|
||||
e.raidid = static_cast<int32_t>(atoi(row[1]));
|
||||
e.charid = static_cast<int32_t>(atoi(row[2]));
|
||||
e.bot_id = static_cast<int32_t>(atoi(row[3]));
|
||||
e.groupid = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e._class = static_cast<int8_t>(atoi(row[5]));
|
||||
e.level = static_cast<int8_t>(atoi(row[6]));
|
||||
e.name = row[7] ? row[7] : "";
|
||||
e.isgroupleader = static_cast<int8_t>(atoi(row[8]));
|
||||
e.israidleader = static_cast<int8_t>(atoi(row[9]));
|
||||
e.islooter = static_cast<int8_t>(atoi(row[10]));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "../strings.h"
|
||||
#include "base/base_character_data_repository.h"
|
||||
|
||||
|
||||
|
||||
class CharacterDataRepository: public BaseCharacterDataRepository {
|
||||
public:
|
||||
|
||||
@@ -44,7 +46,6 @@ public:
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
||||
|
||||
@@ -172,7 +172,7 @@ public:
|
||||
DELETE FROM {}
|
||||
WHERE dynamic_zone_id IN ({});
|
||||
),
|
||||
TableName(), fmt::join(dynamic_zone_ids, ",")
|
||||
TableName(), Strings::Join(dynamic_zone_ids, ",")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
FROM expedition_lockouts
|
||||
WHERE expedition_id IN ({})
|
||||
),
|
||||
fmt::join(expedition_ids, ",")
|
||||
Strings::Join(expedition_ids, ",")
|
||||
));
|
||||
|
||||
all_entries.reserve(results.RowCount());
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
std::vector<CharacterExpedition> entries;
|
||||
|
||||
auto joined_character_names = fmt::format("'{}'", fmt::join(character_names, "','"));
|
||||
auto joined_character_names = fmt::format("'{}'", Strings::Join(character_names, "','"));
|
||||
|
||||
auto results = db.QueryDatabase(fmt::format(SQL(
|
||||
SELECT
|
||||
|
||||
+9
-9
@@ -1,11 +1,11 @@
|
||||
#ifndef EQEMU_HACKERS_REPOSITORY_H
|
||||
#define EQEMU_HACKERS_REPOSITORY_H
|
||||
#ifndef EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||
#define EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_hackers_repository.h"
|
||||
#include "base/base_player_event_log_settings_repository.h"
|
||||
|
||||
class HackersRepository: public BaseHackersRepository {
|
||||
class PlayerEventLogSettingsRepository: public BasePlayerEventLogSettingsRepository {
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -32,10 +32,10 @@ public:
|
||||
*
|
||||
* Example custom methods in a repository
|
||||
*
|
||||
* HackersRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* HackersRepository::GetWhereNeverExpires()
|
||||
* HackersRepository::GetWhereXAndY()
|
||||
* HackersRepository::DeleteWhereXAndY()
|
||||
* PlayerEventLogSettingsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* PlayerEventLogSettingsRepository::GetWhereNeverExpires()
|
||||
* PlayerEventLogSettingsRepository::GetWhereXAndY()
|
||||
* PlayerEventLogSettingsRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
@@ -47,4 +47,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_HACKERS_REPOSITORY_H
|
||||
#endif //EQEMU_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||
+9
-9
@@ -1,11 +1,11 @@
|
||||
#ifndef EQEMU_EVENTLOG_REPOSITORY_H
|
||||
#define EQEMU_EVENTLOG_REPOSITORY_H
|
||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||
#define EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_eventlog_repository.h"
|
||||
#include "base/base_player_event_logs_repository.h"
|
||||
|
||||
class EventlogRepository: public BaseEventlogRepository {
|
||||
class PlayerEventLogsRepository: public BasePlayerEventLogsRepository {
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -32,10 +32,10 @@ public:
|
||||
*
|
||||
* Example custom methods in a repository
|
||||
*
|
||||
* EventlogRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* EventlogRepository::GetWhereNeverExpires()
|
||||
* EventlogRepository::GetWhereXAndY()
|
||||
* EventlogRepository::DeleteWhereXAndY()
|
||||
* PlayerEventLogsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* PlayerEventLogsRepository::GetWhereNeverExpires()
|
||||
* PlayerEventLogsRepository::GetWhereXAndY()
|
||||
* PlayerEventLogsRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
@@ -47,4 +47,4 @@ public:
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_EVENTLOG_REPOSITORY_H
|
||||
#endif //EQEMU_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||
+12
-3
@@ -141,11 +141,11 @@ bool RuleManager::SetRule(const std::string &rule_name, const std::string &rule_
|
||||
|
||||
switch (type) {
|
||||
case IntRule:
|
||||
m_RuleIntValues[index] = atoi(rule_value.c_str());
|
||||
m_RuleIntValues[index] = Strings::ToInt(rule_value.c_str());
|
||||
LogRules("Set rule [{}] to value [{}]", rule_name, m_RuleIntValues[index]);
|
||||
break;
|
||||
case RealRule:
|
||||
m_RuleRealValues[index] = atof(rule_value.c_str());
|
||||
m_RuleRealValues[index] = Strings::ToFloat(rule_value.c_str());
|
||||
LogRules("Set rule [{}] to value [{:.2f}]", rule_name, m_RuleRealValues[index]);
|
||||
break;
|
||||
case BoolRule:
|
||||
@@ -385,7 +385,16 @@ void RuleManager::_SaveRule(Database *db, RuleType type, uint16 index) {
|
||||
e.rule_value = rule_value;
|
||||
e.notes = rule_notes;
|
||||
|
||||
RuleValuesRepository::UpdateOne(*db, e);
|
||||
db->QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE rule_values SET rule_value = '{}', notes = '{}' WHERE ruleset_id = {} AND rule_name = '{}'",
|
||||
rule_value,
|
||||
Strings::Escape(rule_notes),
|
||||
e.ruleset_id,
|
||||
e.rule_name
|
||||
)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+30
-3
@@ -93,6 +93,15 @@ RULE_INT(Character, ItemEnduranceRegenCap, 15, "Limit on endurance regeneration
|
||||
RULE_INT(Character, ItemExtraDmgCap, 150, "Cap for bonuses to melee skills like Bash, Frenzy, etc.")
|
||||
RULE_INT(Character, HasteCap, 100, "Haste cap for non-v3(over haste) haste")
|
||||
RULE_INT(Character, Hastev3Cap, 25, "Haste cap for v3(over haste) haste")
|
||||
RULE_BOOL(Character, HeroicStatsUseDataBucketsToScale, false, "Allows scaling the benefits a character receives from Heroic Stats using Data Buckets. Stacks with other Heroic Stats Mulitplier Rules.")
|
||||
RULE_REAL(Character, HeroicIntelligenceIncreaseSpellDmgMultiplier, 0.00, "Allows Heroic Intelligence to increase a Players Worn Spell Damage Stat from Equipment, for example, setting this rule to 1.00 will always grant 1 Spell Damage per 1 Heroic Intelligence")
|
||||
RULE_REAL(Character, HeroicWisdomIncreaseHealAmtMultiplier, 0.00, "Allows Heroic Wisdom to increase a Players Worn Heal Amount Stat from Equipment, for example, setting this rule to 1.00 will always grant 1 Heal Amount per 1 Heroic Wisdom")
|
||||
RULE_REAL(Character, HeroicStrengthMultiplier, 1.00, "Multplier scales benefits from Heroic Strength. Grants 25 Base Endurance, 0.05 Endurance Regen, 1 Melee Damage each Hit, and 1 Shield AC per 10 Heroic Strength.")
|
||||
RULE_REAL(Character, HeroicStaminaMultiplier, 1.00, "Multplier scales benefits from Heroic Stamina. Grants 25 Base Endurance, 0.05 Endurance Regen, 100 Base HP, and 0.5 HP Regen per 10 Heroic Stamina.")
|
||||
RULE_REAL(Character, HeroicAgilityMultiplier, 1.00, "Multplier scales benefits from Heroic Agility. Grants 25 Base Endurance, 0.05 Endurance Regen, and 1 Avoidance AC per 10 Heroic Agility. (Rule does not change Dodge Chance)")
|
||||
RULE_REAL(Character, HeroicDexterityMultiplier, 1.00, "Multplier scales benefits from Heroic Dexterity. Grants 25 Base Endurance, 0.05 Endurance Regen, and 1 Archery/Throwing Damage each hit per 10 Heroic Dexterity. (Rule does not change Assassinate/Headshot/Block/Parry/Riposte Chances)")
|
||||
RULE_REAL(Character, HeroicWisdomMultiplier, 1.00, "Multplier scales benefits from Heroic Wisdom. Grants 250 Base Mana, 1 Mana Regen per 25 Heroic Wisdom.")
|
||||
RULE_REAL(Character, HeroicIntelligenceMultiplier, 1.00, "Multplier scales benefits from Heroic Intelligence. Grants 250 Base Mana, 1 Mana Regen per 25 Heroic Intelligence.")
|
||||
RULE_INT(Character, SkillUpModifier, 100, "The probability for a skill-up is multiplied by value/100")
|
||||
RULE_BOOL(Character, SharedBankPlat, false, "Shared bank platinum. Off by default to prevent duplication")
|
||||
RULE_BOOL(Character, BindAnywhere, false, "Allows players to bind their soul anywhere in the world")
|
||||
@@ -197,9 +206,15 @@ RULE_BOOL(Character, PetZoneWithOwner, true, "Should Pets Zone with Owner")
|
||||
RULE_BOOL(Character, FullManaOnDeath, true, "On death set mana to full")
|
||||
RULE_BOOL(Character, FullEndurOnDeath, true, "On death set endurance to full")
|
||||
RULE_INT(Character, ExperiencePercentCapPerKill, -1, "Caps the percentage of experience that can be gained per kill. -1 disables the cap; 0 blocks all (non-aa) xp.")
|
||||
RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier based on number of players in group, default is true")
|
||||
RULE_BOOL(Character, EnableGroupEXPModifier, true, "Enable or disable the group experience modifier in group, default is true")
|
||||
RULE_BOOL(Character, EnableGroupMemberEXPModifier, true, "Enable or disable the group member experience modifier based on number of players in group, default is true")
|
||||
RULE_REAL(Character, GroupMemberEXPModifier, 0.2, "Sets the group experience modifier per members between 2 and 5, default is 0.2")
|
||||
RULE_REAL(Character, FullGroupEXPModifier, 2.16, "Sets the group experience modifier for a full group, default is 2.16")
|
||||
RULE_BOOL(Character, IgnoreLevelBasedHasteCaps, false, "Ignores hard coded level based haste caps.")
|
||||
RULE_BOOL(Character, EnableRaidEXPModifier, true, "Enable or disable the raid experience modifier, default is true")
|
||||
RULE_BOOL(Character, EnableRaidMemberEXPModifier, true, "Enable or disable the raid experience modifier based on members in raid, default is true")
|
||||
RULE_BOOL(Character, LeaveCursorMoneyOnCorpse, false, "Enable or disable leaving cursor money on player corpses")
|
||||
RULE_BOOL(Character, ItemExtraSkillDamageCalcAsPercent, false, "If enabled, apply Item Extra Skill Damage as Percentage-based modifiers")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Mercs)
|
||||
@@ -259,7 +274,6 @@ RULE_BOOL(World, EnableTutorialButton, true, "Setting whether the Tutorial butto
|
||||
RULE_BOOL(World, EnableReturnHomeButton, true, "Setting whether the Return Home button should be active")
|
||||
RULE_INT(World, MaxLevelForTutorial, 10, "The highest level with which you can enter the tutorial")
|
||||
RULE_INT(World, TutorialZoneID, 189, "Zone ID of the tutorial")
|
||||
RULE_INT(World, GuildBankZoneID, 345, "Zone ID of the guild bank")
|
||||
RULE_INT(World, MinOfflineTimeToReturnHome, 21600, "Minimum offline time to activate the Return Home button. 21600 seconds is 6 Hours")
|
||||
RULE_INT(World, MaxClientsPerIP, -1, "Maximum number of clients allowed to connect per IP address if account status is < AddMaxClientsStatus. Default value: -1 (feature disabled)")
|
||||
RULE_INT(World, ExemptMaxClientsStatus, -1, "Exempt accounts from the MaxClientsPerIP and AddMaxClientsStatus rules, if their status is >= this value. Default value: -1 (feature disabled)")
|
||||
@@ -315,8 +329,8 @@ RULE_CATEGORY_END()
|
||||
RULE_CATEGORY(Map)
|
||||
RULE_BOOL(Map, FixPathingZOnSendTo, false, "Try to repair Z coordinates in the SendTo routine as well")
|
||||
RULE_BOOL(Map, FixZWhenPathing, true, "Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)")
|
||||
RULE_REAL(Map, DistanceCanTravelBeforeAdjustment, 10.0, "Distance a mob can path before FixZ is called, depends on FixZWhenPathing")
|
||||
RULE_BOOL(Map, MobZVisualDebug, false, "Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)")
|
||||
RULE_BOOL(Map, MobPathingVisualDebug, false, "Displays nodes in pathing points in realtime to help with visual debugging")
|
||||
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20, "At runtime in SendTo: maximum change in Z to allow the BestZ code to apply")
|
||||
RULE_INT(Map, FindBestZHeightAdjust, 1, "Adds this to the current Z before seeking the best Z position")
|
||||
RULE_CATEGORY_END()
|
||||
@@ -339,6 +353,7 @@ RULE_REAL(Watermap, FishingLineStepSize, 1, "Basic step size for fishing calc, t
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Spells)
|
||||
RULE_BOOL(Spells, AllowExtraDmgSkill, false, "Allow ExtraDmgSkill from Items, Spells, and AAs to apply ExtraDmgAmt when the ExtraDmgSkill matches the casted Spells Skill Type.")
|
||||
RULE_INT(Spells, BaseCritChance, 0, "Base percentage chance that everyone has to crit a spell")
|
||||
RULE_INT(Spells, BaseCritRatio, 100, "Base percentage bonus to damage on a successful spell crit. 100=2xdamage")
|
||||
RULE_INT(Spells, WizCritLevel, 12, "Level wizards first get spell crits")
|
||||
@@ -430,6 +445,7 @@ RULE_BOOL(Spells, IllusionsAlwaysPersist, false, "Allows Illusions to persist be
|
||||
RULE_BOOL(Spells, UseItemCastMessage, false, "Enable to use the \"item begins to glow\" messages when casting from an item.")
|
||||
RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove combat range requirement from Target's Target Spell Target Type")
|
||||
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
|
||||
RULE_BOOL(Spells, ResurrectionEffectsBlock, true, "If enabled, resurrection effects cannot be overwritten.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
@@ -566,6 +582,7 @@ RULE_BOOL(TaskSystem, RecordCompletedOptionalActivities, false, "Record complete
|
||||
RULE_BOOL(TaskSystem, KeepOneRecordPerCompletedTask, true, "Keep only one record per completed task")
|
||||
RULE_BOOL(TaskSystem, EnableTaskProximity, true, "Enable task proximity system")
|
||||
RULE_INT(TaskSystem, RequestCooldownTimerSeconds, 15, "Seconds between allowing characters to request tasks (live-like default: 15 seconds)")
|
||||
RULE_BOOL(TaskSystem, ExpRewardsIgnoreLevelBasedEXPMods, false, "Rewarding Level Based Exp will ignore Rule LevelBasedEXPMods if true")
|
||||
RULE_INT(TaskSystem, SharedTasksWorldProcessRate, 6000, "Timer interval (milliseconds) that shared tasks are processed in world")
|
||||
RULE_INT(TaskSystem, SharedTasksTerminateTimerMS, 120000, "Delay (milliseconds) until a shared task is terminated if requirements are no longer met after member removal (default: 2 minutes)")
|
||||
RULE_BOOL(TaskSystem, UpdateOneElementPerTask, true, "If true (live-like) task updates only increment the first matching activity. If false all matching elements will be incremented.")
|
||||
@@ -583,6 +600,7 @@ RULE_INT(Range, SongMessages, 75, "The packet range in which song messages are s
|
||||
RULE_INT(Range, ClientPositionUpdates, 300, "Distance in which the own changed position is communicated to other clients")
|
||||
RULE_INT(Range, CriticalDamage, 80, "The packet range in which critical hit messages are sent")
|
||||
RULE_INT(Range, MobCloseScanDistance, 600, "Close scan distance")
|
||||
RULE_INT(Range, MaxDistanceToClickDoors, 100, "Max distance that a client can click a door from (Client says 'You can't reach that' at roughly 25-50 for most doors)")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Bots)
|
||||
@@ -623,6 +641,7 @@ RULE_BOOL(Chat, EnableVoiceMacros, true, "Enable voice macros")
|
||||
RULE_BOOL(Chat, EnableMailKeyIPVerification, true, "Setting whether the authenticity of the client should be verified via its IP address when accessing the InGame mailbox")
|
||||
RULE_BOOL(Chat, EnableAntiSpam, true, "Enable anti-spam system for chat")
|
||||
RULE_BOOL(Chat, SuppressCommandErrors, false, "Do not suppress command errors by default")
|
||||
RULE_BOOL(Chat, ChannelsIgnoreNameFilter, false, "Ignore name filtering when creating new chat channels")
|
||||
RULE_INT(Chat, MaxPermanentPlayerChannels, 0, "Maximum number of permanent chat channels a player can make. Default 0.")
|
||||
RULE_INT(Chat, MinStatusToBypassAntiSpam, 100, "Minimum status to bypass the anti-spam system")
|
||||
RULE_INT(Chat, MinimumMessagesPerInterval, 4, "Minimum number of chat messages allowed per interval. The karma value is added to this value")
|
||||
@@ -744,6 +763,7 @@ RULE_BOOL(Inventory, DeleteTransformationMold, true, "False if you want mold to
|
||||
RULE_BOOL(Inventory, AllowAnyWeaponTransformation, false, "Weapons can use any weapon transformation")
|
||||
RULE_BOOL(Inventory, TransformSummonedBags, false, "Transforms summoned bags into disenchanted ones instead of deleting")
|
||||
RULE_BOOL(Inventory, AllowMultipleOfSameAugment, false, "Allows multiple of the same augment to be placed in an item via #augmentitem or MQ2, set to true to allow")
|
||||
RULE_INT(Inventory, AlternateAugmentationSealer, 53, "Allows RoF+ clients to augment items from a special container type")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Client)
|
||||
@@ -766,9 +786,16 @@ RULE_INT(Faction, DubiouslyFactionMinimum, -500, "Minimum faction for dubiously"
|
||||
RULE_INT(Faction, ThreateninglyFactionMinimum, -750, "Minimum faction for threateningly")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Analytics)
|
||||
RULE_BOOL(Analytics, CrashReporting, true, "Automatic crash reporting analytics for EQEmu Server developers")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Logging)
|
||||
RULE_BOOL(Logging, PrintFileFunctionAndLine, false, "Ex: [World Server] [net.cpp::main:309] Loading variables...")
|
||||
RULE_BOOL(Logging, WorldGMSayLogging, true, "Relay worldserver logging to zone processes via GM say output")
|
||||
RULE_BOOL(Logging, PlayerEventsQSProcess, false, "Have query server process player events instead of world. Useful when wanting to use a dedicated server and database for processing player events on separate disk")
|
||||
RULE_INT(Logging, BatchPlayerEventProcessIntervalSeconds, 5, "This is the interval in which player events are processed in world or qs")
|
||||
RULE_INT(Logging, BatchPlayerEventProcessChunkSize, 10000, "This is the cap of events that can be inserted into the queue before a force flush. This is to keep from hitting MySQL max_allowed_packet and killing the connection")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(HotReload)
|
||||
|
||||
+2
-1
@@ -99,8 +99,9 @@ public:
|
||||
}
|
||||
}
|
||||
~Seperator() {
|
||||
for (int i=0; i<=maxargnum; i++)
|
||||
for (int i=0; i<=maxargnum; i++) {
|
||||
safe_delete_array(arg[i]);
|
||||
}
|
||||
safe_delete_array(arg);
|
||||
safe_delete_array(argplus);
|
||||
safe_delete_array(msg);
|
||||
|
||||
@@ -143,6 +143,10 @@ bool ServerEventScheduler::ValidateDatabaseConnection()
|
||||
// this helps inform decisions to tell all zones to reload their events
|
||||
bool ServerEventScheduler::CheckIfEventsChanged()
|
||||
{
|
||||
if (!m_database) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto events = ServerScheduledEventsRepository::GetWhere(*m_database, "deleted_at is null");
|
||||
|
||||
// first check if the size changed, if it did this is the easiest step
|
||||
|
||||
+20
-12
@@ -281,6 +281,9 @@
|
||||
#define ServerOP_QSSendQuery 0x5006
|
||||
#define ServerOP_QSPlayerDropItem 0x5007
|
||||
|
||||
// player events
|
||||
#define ServerOP_PlayerEvent 0x5100
|
||||
|
||||
enum {
|
||||
CZUpdateType_Character,
|
||||
CZUpdateType_Group,
|
||||
@@ -1308,10 +1311,10 @@ struct Server_Speech_Struct {
|
||||
char message[0];
|
||||
};
|
||||
|
||||
struct QSTradeItems_Struct {
|
||||
uint32 from_id;
|
||||
struct PlayerLogTradeItemsEntry_Struct {
|
||||
uint32 from_character_id;
|
||||
uint16 from_slot;
|
||||
uint32 to_id;
|
||||
uint32 to_character_id;
|
||||
uint16 to_slot;
|
||||
uint32 item_id;
|
||||
uint16 charges;
|
||||
@@ -1322,15 +1325,15 @@ struct QSTradeItems_Struct {
|
||||
uint32 aug_5;
|
||||
};
|
||||
|
||||
struct QSPlayerLogTrade_Struct {
|
||||
uint32 char1_id;
|
||||
MoneyUpdate_Struct char1_money;
|
||||
uint16 char1_count;
|
||||
uint32 char2_id;
|
||||
MoneyUpdate_Struct char2_money;
|
||||
uint16 char2_count;
|
||||
uint16 _detail_count;
|
||||
QSTradeItems_Struct items[0];
|
||||
struct PlayerLogTrade_Struct {
|
||||
uint32 character_1_id;
|
||||
MoneyUpdate_Struct character_1_money;
|
||||
uint16 character_1_item_count;
|
||||
uint32 character_2_id;
|
||||
MoneyUpdate_Struct character_2_money;
|
||||
uint16 character_2_item_count;
|
||||
uint16 _detail_count;
|
||||
PlayerLogTradeItemsEntry_Struct item_entries[0];
|
||||
};
|
||||
|
||||
struct QSDropItems_Struct {
|
||||
@@ -1806,6 +1809,11 @@ struct ServerDzCreateSerialized_Struct {
|
||||
char cereal_data[0];
|
||||
};
|
||||
|
||||
struct ServerSendPlayerEvent_Struct {
|
||||
uint32_t cereal_size;
|
||||
char cereal_data[0];
|
||||
};
|
||||
|
||||
struct ServerFlagUpdate_Struct {
|
||||
uint32 account_id;
|
||||
int16 admin;
|
||||
|
||||
+415
-457
File diff suppressed because it is too large
Load Diff
+10
-2
@@ -126,7 +126,11 @@ public:
|
||||
uint32 aug4 = 0,
|
||||
uint32 aug5 = 0,
|
||||
uint32 aug6 = 0,
|
||||
bool attuned = 0
|
||||
bool attuned = false,
|
||||
const std::string& custom_data = "",
|
||||
uint32 ornamenticon = 0,
|
||||
uint32 ornamentidfile = 0,
|
||||
uint32 ornament_hero_model = 0
|
||||
);
|
||||
EQ::ItemInstance *CreateItem(
|
||||
const EQ::ItemData *item,
|
||||
@@ -137,7 +141,11 @@ public:
|
||||
uint32 aug4 = 0,
|
||||
uint32 aug5 = 0,
|
||||
uint32 aug6 = 0,
|
||||
bool attuned = 0
|
||||
bool attuned = false,
|
||||
const std::string &custom_data = "",
|
||||
uint32 ornamenticon = 0,
|
||||
uint32 ornamentidfile = 0,
|
||||
uint32 ornament_hero_model = 0
|
||||
);
|
||||
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);
|
||||
|
||||
|
||||
+20
-2
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -260,13 +260,31 @@ const std::map<EQ::skills::SkillType, std::string>& EQ::skills::GetSkillTypeMap(
|
||||
return skill_type_map;
|
||||
}
|
||||
|
||||
const std::vector<EQ::skills::SkillType>& EQ::skills::GetExtraDamageSkills()
|
||||
{
|
||||
static const std::vector<EQ::skills::SkillType> v = {
|
||||
EQ::skills::SkillBackstab,
|
||||
EQ::skills::SkillBash,
|
||||
EQ::skills::SkillDragonPunch, // Same ID as Tail Rake
|
||||
EQ::skills::SkillEagleStrike,
|
||||
EQ::skills::SkillFlyingKick,
|
||||
EQ::skills::SkillKick,
|
||||
EQ::skills::SkillRoundKick,
|
||||
EQ::skills::SkillRoundKick,
|
||||
EQ::skills::SkillTigerClaw,
|
||||
EQ::skills::SkillFrenzy
|
||||
};
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
std::string EQ::skills::GetSkillName(SkillType skill)
|
||||
{
|
||||
if (skill >= Skill1HBlunt && skill <= Skill2HPiercing) {
|
||||
auto skills = GetSkillTypeMap();
|
||||
return skills[skill];
|
||||
}
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
EQ::SkillProfile::SkillProfile()
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
|
||||
|
||||
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace EQ
|
||||
@@ -170,6 +171,7 @@ namespace EQ
|
||||
bool IsMeleeDmg(SkillType skill);
|
||||
|
||||
extern const std::map<SkillType, std::string>& GetSkillTypeMap();
|
||||
extern const std::vector<SkillType>& GetExtraDamageSkills();
|
||||
|
||||
std::string GetSkillName(SkillType skill);
|
||||
} /*skills*/
|
||||
@@ -305,7 +307,7 @@ namespace EQ
|
||||
|
||||
uint32 operator[](int skill_id) const { return const_cast<SkillProfile*>(this)->GetSkill(skill_id); }
|
||||
};
|
||||
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
#endif /*COMMON_SKILLS_H*/
|
||||
|
||||
+2
-2
@@ -504,7 +504,7 @@ enum SpellRestriction
|
||||
HAS_NO_ILLUSIONS_OF_GRANDEUR_BUFF = 12519, //
|
||||
IS_HP_ABOVE_50_PCT = 16010, //
|
||||
IS_HP_UNDER_50_PCT = 16031, //
|
||||
IS_OFF_HAND_EQUIPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
|
||||
IS_OFF_HAND_EQUIPPED = 27672, // You must be wielding a weapon or shield in your offhand to use this ability.
|
||||
HAS_NO_PACT_OF_FATE_RECOURSE_BUFF = 29556, // This spell will not work while Pact of Fate Recourse is active. | caster restriction |
|
||||
HAS_NO_SHROUD_OF_PRAYER_BUFF = 32339, // Your target cannot receive another Quiet Prayer this soon.
|
||||
IS_MANA_BELOW_20_PCT = 38311, // This ability requires you to be at or below 20% of your maximum mana.
|
||||
@@ -1211,7 +1211,7 @@ typedef enum {
|
||||
#define SE_Double_Backstab_Front 473 // implemented - Chance to double backstab from front
|
||||
#define SE_Pet_Crit_Melee_Damage_Pct_Owner 474 // implemenetd - Critical damage mod applied to pets from owner
|
||||
#define SE_Trigger_Spell_Non_Item 475 // implemented - Trigger spell on cast only if not from item click.
|
||||
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Duel Wield is equiped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
|
||||
#define SE_Weapon_Stance 476 // implemented, @Misc, Apply a specific spell buffs automatically depending 2Hander, Shield or Dual Wield is equipped, base: spellid, base: 0=2H 1=Shield 2=DW, max: none
|
||||
#define SE_Hatelist_To_Top_Index 477 // Implemented - Chance to be set to top of rampage list
|
||||
#define SE_Hatelist_To_Tail_Index 478 // Implemented - Chance to be set to bottom of rampage list
|
||||
#define SE_Ff_Value_Min 479 // implemented, @Ff, Minimum base value of a spell that can be focused, base: spells to be focused base1 value
|
||||
|
||||
+121
-23
@@ -115,7 +115,7 @@ Strings::SearchDelim(const std::string &haystack, const std::string &needle, con
|
||||
}
|
||||
|
||||
|
||||
std::string Strings::Implode(std::string glue, std::vector<std::string> src)
|
||||
std::string Strings::Implode(const std::string& glue, std::vector<std::string> src)
|
||||
{
|
||||
if (src.empty()) {
|
||||
return {};
|
||||
@@ -191,24 +191,23 @@ std::string Strings::Escape(const std::string &s)
|
||||
|
||||
bool Strings::IsNumber(const std::string &s)
|
||||
{
|
||||
try {
|
||||
auto r = stoi(s);
|
||||
return true;
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return false;
|
||||
for (char const &c: s) {
|
||||
if (c == s[0] && s[0] == '-') {
|
||||
continue;
|
||||
}
|
||||
if (std::isdigit(c) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Strings::IsFloat(const std::string &s)
|
||||
{
|
||||
try {
|
||||
auto r = stof(s);
|
||||
return true;
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return false;
|
||||
}
|
||||
char* ptr;
|
||||
strtof(s.c_str(), &ptr);
|
||||
return (*ptr) == '\0';
|
||||
}
|
||||
|
||||
std::string Strings::Join(const std::vector<std::string> &ar, const std::string &delim)
|
||||
@@ -225,6 +224,20 @@ std::string Strings::Join(const std::vector<std::string> &ar, const std::string
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string Strings::Join(const std::vector<uint32_t> &ar, const std::string &delim)
|
||||
{
|
||||
std::string ret;
|
||||
for (size_t i = 0; i < ar.size(); ++i) {
|
||||
if (i != 0) {
|
||||
ret += delim;
|
||||
}
|
||||
|
||||
ret += std::to_string(ar[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
Strings::FindReplace(std::string &string_subject, const std::string &search_string, const std::string &replace_string)
|
||||
{
|
||||
@@ -259,7 +272,7 @@ std::string Strings::Repeat(std::string s, int n)
|
||||
return s;
|
||||
}
|
||||
|
||||
bool Strings::Contains(std::vector<std::string> container, std::string element)
|
||||
bool Strings::Contains(std::vector<std::string> container, const std::string& element)
|
||||
{
|
||||
return std::find(container.begin(), container.end(), element) != container.end();
|
||||
}
|
||||
@@ -303,7 +316,7 @@ const std::string Strings::ToUpper(std::string s)
|
||||
);
|
||||
return s;
|
||||
}
|
||||
const std::string Strings::UcFirst(std::string s)
|
||||
const std::string Strings::UcFirst(const std::string& s)
|
||||
{
|
||||
std::string output = s;
|
||||
if (!s.empty()) {
|
||||
@@ -314,7 +327,7 @@ const std::string Strings::UcFirst(std::string s)
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> Strings::Wrap(std::vector<std::string> &src, std::string character)
|
||||
std::vector<std::string> Strings::Wrap(std::vector<std::string> &src, const std::string& character)
|
||||
{
|
||||
std::vector<std::string> new_vector;
|
||||
new_vector.reserve(src.size());
|
||||
@@ -646,7 +659,7 @@ std::string Strings::SecondsToTime(int duration, bool is_milliseconds)
|
||||
return time_string;
|
||||
}
|
||||
|
||||
std::string &Strings::LTrim(std::string &str, const std::string &chars)
|
||||
std::string &Strings::LTrim(std::string &str, std::string_view chars)
|
||||
{
|
||||
str.erase(0, str.find_first_not_of(chars));
|
||||
return str;
|
||||
@@ -657,7 +670,7 @@ std::string Strings::MillisecondsToTime(int duration)
|
||||
return SecondsToTime(duration, true);
|
||||
}
|
||||
|
||||
std::string &Strings::RTrim(std::string &str, const std::string &chars)
|
||||
std::string &Strings::RTrim(std::string &str, std::string_view chars)
|
||||
{
|
||||
str.erase(str.find_last_not_of(chars) + 1);
|
||||
return str;
|
||||
@@ -669,7 +682,7 @@ std::string &Strings::Trim(std::string &str, const std::string &chars)
|
||||
}
|
||||
|
||||
// Function to convert single digit or two digit number into words
|
||||
std::string Strings::ConvertToDigit(int n, std::string suffix)
|
||||
std::string Strings::ConvertToDigit(int n, const std::string& suffix)
|
||||
{
|
||||
// if n is zero
|
||||
if (n == 0) {
|
||||
@@ -714,7 +727,7 @@ uint32 Strings::TimeToSeconds(std::string time_string)
|
||||
time_unit.end()
|
||||
);
|
||||
|
||||
auto unit = std::stoul(time_unit);
|
||||
auto unit = Strings::ToUnsignedInt(time_unit);
|
||||
uint32 duration = 0;
|
||||
|
||||
if (Strings::Contains(time_string, "s")) {
|
||||
@@ -732,7 +745,7 @@ uint32 Strings::TimeToSeconds(std::string time_string)
|
||||
return duration;
|
||||
}
|
||||
|
||||
bool Strings::ToBool(std::string bool_string)
|
||||
bool Strings::ToBool(const std::string& bool_string)
|
||||
{
|
||||
if (
|
||||
Strings::Contains(bool_string, "true") ||
|
||||
@@ -741,7 +754,7 @@ bool Strings::ToBool(std::string bool_string)
|
||||
Strings::Contains(bool_string, "on") ||
|
||||
Strings::Contains(bool_string, "enable") ||
|
||||
Strings::Contains(bool_string, "enabled") ||
|
||||
(Strings::IsNumber(bool_string) && std::stoi(bool_string))
|
||||
(Strings::IsNumber(bool_string) && Strings::ToInt(bool_string))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@@ -763,3 +776,88 @@ std::string Strings::Random(size_t length)
|
||||
std::generate_n(str.begin(), length, randchar);
|
||||
return str;
|
||||
}
|
||||
|
||||
// a wrapper for stoi which will return a fallback if the string
|
||||
// fails to cast to a number
|
||||
int Strings::ToInt(const std::string &s, int fallback)
|
||||
{
|
||||
if (!Strings::IsNumber(s)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stoi(s);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
int64 Strings::ToBigInt(const std::string &s, int64 fallback)
|
||||
{
|
||||
if (!Strings::IsNumber(s)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stoll(s);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Strings::ToUnsignedInt(const std::string &s, uint32 fallback)
|
||||
{
|
||||
if (!Strings::IsNumber(s)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stoul(s);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 Strings::ToUnsignedBigInt(const std::string &s, uint64 fallback)
|
||||
{
|
||||
if (!Strings::IsNumber(s)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stoull(s);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
float Strings::ToFloat(const std::string &s, float fallback)
|
||||
{
|
||||
if (!Strings::IsFloat(s)) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
try {
|
||||
return std::stof(s);
|
||||
}
|
||||
catch (std::exception &) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Strings::RemoveNumbers(std::string s)
|
||||
{
|
||||
int current = 0;
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (!isdigit(s[i])) {
|
||||
s[current] = s[i];
|
||||
current++;
|
||||
}
|
||||
}
|
||||
|
||||
return s.substr(0, current);
|
||||
}
|
||||
|
||||
+15
-8
@@ -84,15 +84,21 @@ namespace EQ {
|
||||
|
||||
class Strings {
|
||||
public:
|
||||
static bool Contains(std::vector<std::string> container, std::string element);
|
||||
static bool Contains(std::vector<std::string> container, const std::string& element);
|
||||
static bool Contains(const std::string& subject, const std::string& search);
|
||||
static int ToInt(const std::string &s, int fallback = 0);
|
||||
static int64 ToBigInt(const std::string &s, int64 fallback = 0);
|
||||
static uint32 ToUnsignedInt(const std::string &s, uint32 fallback = 0);
|
||||
static uint64 ToUnsignedBigInt(const std::string &s, uint64 fallback = 0);
|
||||
static float ToFloat(const std::string &s, float fallback = 0.0f);
|
||||
static bool IsNumber(const std::string &s);
|
||||
static std::string RemoveNumbers(std::string s);
|
||||
static bool IsFloat(const std::string &s);
|
||||
static const std::string ToLower(std::string s);
|
||||
static const std::string ToUpper(std::string s);
|
||||
static const std::string UcFirst(std::string s);
|
||||
static std::string <rim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||
static std::string &RTrim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||
static const std::string UcFirst(const std::string& s);
|
||||
static std::string <rim(std::string &str, std::string_view chars = "\t\n\v\f\r ");
|
||||
static std::string &RTrim(std::string &str, std::string_view chars = "\t\n\v\f\r ");
|
||||
static std::string &Trim(std::string &str, const std::string &chars = "\t\n\v\f\r ");
|
||||
static std::string Commify(const std::string &number);
|
||||
static std::string Commify(uint16 number) { return Strings::Commify(std::to_string(number)); };
|
||||
@@ -101,11 +107,12 @@ public:
|
||||
static std::string Commify(int16 number) { return Strings::Commify(std::to_string(number)); };
|
||||
static std::string Commify(int32 number) { return Strings::Commify(std::to_string(number)); };
|
||||
static std::string Commify(int64 number) { return Strings::Commify(std::to_string(number)); };
|
||||
static std::string ConvertToDigit(int n, std::string suffix);
|
||||
static std::string ConvertToDigit(int n, const std::string& suffix);
|
||||
static std::string Escape(const std::string &s);
|
||||
static std::string GetBetween(const std::string &s, std::string start_delim, std::string stop_delim);
|
||||
static std::string Implode(std::string glue, std::vector<std::string> src);
|
||||
static std::string Implode(const std::string& glue, std::vector<std::string> src);
|
||||
static std::string Join(const std::vector<std::string> &ar, const std::string &delim);
|
||||
static std::string Join(const std::vector<uint32_t> &ar, const std::string &delim);
|
||||
static std::string MillisecondsToTime(int duration);
|
||||
static std::string Money(uint32 platinum, uint32 gold = 0, uint32 silver = 0, uint32 copper = 0);
|
||||
static std::string NumberToWords(unsigned long long int n);
|
||||
@@ -115,10 +122,10 @@ public:
|
||||
static std::string::size_type SearchDelim(const std::string &haystack, const std::string &needle, const char deliminator = ',');
|
||||
static std::vector<std::string> Split(const std::string &s, const char delim = ',');
|
||||
static std::vector<std::string> Split(const std::string& s, const std::string& delimiter);
|
||||
static std::vector<std::string> Wrap(std::vector<std::string> &src, std::string character);
|
||||
static std::vector<std::string> Wrap(std::vector<std::string> &src, const std::string& character);
|
||||
static void FindReplace(std::string &string_subject, const std::string &search_string, const std::string &replace_string);
|
||||
static uint32 TimeToSeconds(std::string time_string);
|
||||
static bool ToBool(std::string bool_string);
|
||||
static bool ToBool(const std::string& bool_string);
|
||||
static inline bool EqualFold(const std::string &string_one, const std::string &string_two) { return strcasecmp(string_one.c_str(), string_two.c_str()) == 0; }
|
||||
static std::string Random(size_t length);
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ bool atobool(const char *iBool)
|
||||
if (!strcasecmp(iBool, "n")) {
|
||||
return false;
|
||||
}
|
||||
if (atoi(iBool)) {
|
||||
if (Strings::ToInt(iBool)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -71,14 +71,6 @@ namespace StructStrategyFactory {
|
||||
strategies[first_opcode] = structs;
|
||||
}
|
||||
|
||||
const StructStrategy *FindPatch(EmuOpcode first_opcode) {
|
||||
std::map<EmuOpcode, const StructStrategy *>::const_iterator res;
|
||||
res = strategies.find(first_opcode);
|
||||
if(res == strategies.end())
|
||||
return(nullptr);
|
||||
return(res->second);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@ protected:
|
||||
//effectively a singleton, but I decided to do it this way for no apparent reason.
|
||||
namespace StructStrategyFactory {
|
||||
void RegisterPatch(EmuOpcode first_opcode, const StructStrategy *structs);
|
||||
|
||||
//does NOT return ownership of the strategy.
|
||||
const StructStrategy *FindPatch(EmuOpcode first_opcode);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
inline bool g_is_forced_tty = std::getenv("IS_TTY");
|
||||
|
||||
namespace rang {
|
||||
|
||||
/* For better compability with most of terminals do not use any style settings
|
||||
@@ -220,6 +222,10 @@ inline bool isMsysPty(int fd) noexcept
|
||||
|
||||
inline bool isTerminal(const std::streambuf *osbuf) noexcept
|
||||
{
|
||||
if (g_is_forced_tty) {
|
||||
return g_is_forced_tty;
|
||||
}
|
||||
|
||||
using std::cerr;
|
||||
using std::clog;
|
||||
using std::cout;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
// Disgrace: for windows compile
|
||||
#ifndef WIN32
|
||||
#include <sys/time.h>
|
||||
|
||||
+15
-14
@@ -18,14 +18,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _EQEMU_VERSION_H
|
||||
#define _EQEMU_VERSION_H
|
||||
#ifndef EQEMU_VERSION_H
|
||||
#define EQEMU_VERSION_H
|
||||
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define EQEMU_PROTOCOL_VERSION "0.3.10"
|
||||
|
||||
#define CURRENT_VERSION "2.0"
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "22.8.2-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
#define LAST_MODIFIED __TIME__
|
||||
#else
|
||||
#define LAST_MODIFIED __TIMESTAMP__
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Every time a Database SQL is added to Github increment CURRENT_BINARY_DATABASE_VERSION
|
||||
@@ -34,16 +42,9 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9217
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9036
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9227
|
||||
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
#ifndef WIN32
|
||||
#define LAST_MODIFIED __TIME__
|
||||
#else
|
||||
#define LAST_MODIFIED __TIMESTAMP__
|
||||
#endif
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,490 +0,0 @@
|
||||
#include "../common/types.h"
|
||||
|
||||
inline const char* StaticGetZoneName(uint32 zoneID) {
|
||||
// @merth: I did the following query to retrieve these (following by a simple find/replace)
|
||||
// select concat('case ', zoneidnumber), concat(short_name, '";') from zone order by zoneidnumber;
|
||||
switch (zoneID) {
|
||||
case 1: return "qeynos";
|
||||
case 2: return "qeynos2";
|
||||
case 3: return "qrg";
|
||||
case 4: return "qeytoqrg";
|
||||
case 5: return "highpass";
|
||||
case 6: return "highkeep";
|
||||
case 8: return "freportn";
|
||||
case 9: return "freportw";
|
||||
case 10: return "freporte";
|
||||
case 11: return "runnyeye";
|
||||
case 12: return "qey2hh1";
|
||||
case 13: return "northkarana";
|
||||
case 14: return "southkarana";
|
||||
case 15: return "eastkarana";
|
||||
case 16: return "beholder";
|
||||
case 17: return "blackburrow";
|
||||
case 18: return "paw";
|
||||
case 19: return "rivervale";
|
||||
case 20: return "kithicor";
|
||||
case 21: return "commons";
|
||||
case 22: return "ecommons";
|
||||
case 23: return "erudnint";
|
||||
case 24: return "erudnext";
|
||||
case 25: return "nektulos";
|
||||
case 26: return "cshome";
|
||||
case 27: return "lavastorm";
|
||||
case 28: return "nektropos";
|
||||
case 29: return "halas";
|
||||
case 30: return "everfrost";
|
||||
case 31: return "soldunga";
|
||||
case 32: return "soldungb";
|
||||
case 33: return "misty";
|
||||
case 34: return "nro";
|
||||
case 35: return "sro";
|
||||
case 36: return "befallen";
|
||||
case 37: return "oasis";
|
||||
case 38: return "tox";
|
||||
case 39: return "hole";
|
||||
case 40: return "neriaka";
|
||||
case 41: return "neriakb";
|
||||
case 42: return "neriakc";
|
||||
case 43: return "neriakd";
|
||||
case 44: return "najena";
|
||||
case 45: return "qcat";
|
||||
case 46: return "innothule";
|
||||
case 47: return "feerrott";
|
||||
case 48: return "cazicthule";
|
||||
case 49: return "oggok";
|
||||
case 50: return "rathemtn";
|
||||
case 51: return "lakerathe";
|
||||
case 52: return "grobb";
|
||||
case 53: return "aviak";
|
||||
case 54: return "gfaydark";
|
||||
case 55: return "akanon";
|
||||
case 56: return "steamfont";
|
||||
case 57: return "lfaydark";
|
||||
case 58: return "crushbone";
|
||||
case 59: return "mistmoore";
|
||||
case 60: return "kaladima";
|
||||
case 61: return "felwithea";
|
||||
case 62: return "felwitheb";
|
||||
case 63: return "unrest";
|
||||
case 64: return "kedge";
|
||||
case 65: return "guktop";
|
||||
case 66: return "gukbottom";
|
||||
case 67: return "kaladimb";
|
||||
case 68: return "butcher";
|
||||
case 69: return "oot";
|
||||
case 70: return "cauldron";
|
||||
case 71: return "airplane";
|
||||
case 72: return "fearplane";
|
||||
case 73: return "permafrost";
|
||||
case 74: return "kerraridge";
|
||||
case 75: return "paineel";
|
||||
case 76: return "hateplane";
|
||||
case 77: return "arena";
|
||||
case 78: return "fieldofbone";
|
||||
case 79: return "warslikswood";
|
||||
case 80: return "soltemple";
|
||||
case 81: return "droga";
|
||||
case 82: return "cabwest";
|
||||
case 83: return "swampofnohope";
|
||||
case 84: return "firiona";
|
||||
case 85: return "lakeofillomen";
|
||||
case 86: return "dreadlands";
|
||||
case 87: return "burningwood";
|
||||
case 88: return "kaesora";
|
||||
case 89: return "sebilis";
|
||||
case 90: return "citymist";
|
||||
case 91: return "skyfire";
|
||||
case 92: return "frontiermtns";
|
||||
case 93: return "overthere";
|
||||
case 94: return "emeraldjungle";
|
||||
case 95: return "trakanon";
|
||||
case 96: return "timorous";
|
||||
case 97: return "kurn";
|
||||
case 98: return "erudsxing";
|
||||
case 100: return "stonebrunt";
|
||||
case 101: return "warrens";
|
||||
case 102: return "karnor";
|
||||
case 103: return "chardok";
|
||||
case 104: return "dalnir";
|
||||
case 105: return "charasis";
|
||||
case 106: return "cabeast";
|
||||
case 107: return "nurga";
|
||||
case 108: return "veeshan";
|
||||
case 109: return "veksar";
|
||||
case 110: return "iceclad";
|
||||
case 111: return "frozenshadow";
|
||||
case 112: return "velketor";
|
||||
case 113: return "kael";
|
||||
case 114: return "skyshrine";
|
||||
case 115: return "thurgadina";
|
||||
case 116: return "eastwastes";
|
||||
case 117: return "cobaltscar";
|
||||
case 118: return "greatdivide";
|
||||
case 119: return "wakening";
|
||||
case 120: return "westwastes";
|
||||
case 121: return "crystal";
|
||||
case 123: return "necropolis";
|
||||
case 124: return "templeveeshan";
|
||||
case 125: return "sirens";
|
||||
case 126: return "mischiefplane";
|
||||
case 127: return "growthplane";
|
||||
case 128: return "sleeper";
|
||||
case 129: return "thurgadinb";
|
||||
case 130: return "erudsxing2";
|
||||
case 150: return "shadowhaven";
|
||||
case 151: return "bazaar";
|
||||
case 152: return "nexus";
|
||||
case 153: return "echo";
|
||||
case 154: return "acrylia";
|
||||
case 155: return "sharvahl";
|
||||
case 156: return "paludal";
|
||||
case 157: return "fungusgrove";
|
||||
case 158: return "vexthal";
|
||||
case 159: return "sseru";
|
||||
case 160: return "katta";
|
||||
case 161: return "netherbian";
|
||||
case 162: return "ssratemple";
|
||||
case 163: return "griegsend";
|
||||
case 164: return "thedeep";
|
||||
case 165: return "shadeweaver";
|
||||
case 166: return "hollowshade";
|
||||
case 167: return "grimling";
|
||||
case 168: return "mseru";
|
||||
case 169: return "letalis";
|
||||
case 170: return "twilight";
|
||||
case 171: return "thegrey";
|
||||
case 172: return "tenebrous";
|
||||
case 173: return "maiden";
|
||||
case 174: return "dawnshroud";
|
||||
case 175: return "scarlet";
|
||||
case 176: return "umbral";
|
||||
case 179: return "akheva";
|
||||
case 180: return "arena2";
|
||||
case 181: return "jaggedpine";
|
||||
case 182: return "nedaria";
|
||||
case 183: return "tutorial";
|
||||
case 184: return "load";
|
||||
case 185: return "load2";
|
||||
case 186: return "hateplaneb";
|
||||
case 187: return "shadowrest";
|
||||
case 188: return "tutoriala";
|
||||
case 189: return "tutorialb";
|
||||
case 190: return "clz";
|
||||
case 200: return "codecay";
|
||||
case 201: return "pojustice";
|
||||
case 202: return "poknowledge";
|
||||
case 203: return "potranquility";
|
||||
case 204: return "ponightmare";
|
||||
case 205: return "podisease";
|
||||
case 206: return "poinnovation";
|
||||
case 207: return "potorment";
|
||||
case 208: return "povalor";
|
||||
case 209: return "bothunder";
|
||||
case 210: return "postorms";
|
||||
case 211: return "hohonora";
|
||||
case 212: return "solrotower";
|
||||
case 213: return "powar";
|
||||
case 214: return "potactics";
|
||||
case 215: return "poair";
|
||||
case 216: return "powater";
|
||||
case 217: return "pofire";
|
||||
case 218: return "poeartha";
|
||||
case 219: return "potimea";
|
||||
case 220: return "hohonorb";
|
||||
case 221: return "nightmareb";
|
||||
case 222: return "poearthb";
|
||||
case 223: return "potimeb";
|
||||
case 224: return "gunthak";
|
||||
case 225: return "dulak";
|
||||
case 226: return "torgiran";
|
||||
case 227: return "nadox";
|
||||
case 228: return "hatesfury";
|
||||
case 229: return "guka";
|
||||
case 230: return "ruja";
|
||||
case 231: return "taka";
|
||||
case 232: return "mira";
|
||||
case 233: return "mmca";
|
||||
case 234: return "gukb";
|
||||
case 235: return "rujb";
|
||||
case 236: return "takb";
|
||||
case 237: return "mirb";
|
||||
case 238: return "mmcb";
|
||||
case 239: return "gukc";
|
||||
case 240: return "rujc";
|
||||
case 241: return "takc";
|
||||
case 242: return "mirc";
|
||||
case 243: return "mmcc";
|
||||
case 244: return "gukd";
|
||||
case 245: return "rujd";
|
||||
case 246: return "takd";
|
||||
case 247: return "mird";
|
||||
case 248: return "mmcd";
|
||||
case 249: return "guke";
|
||||
case 250: return "ruje";
|
||||
case 251: return "take";
|
||||
case 252: return "mire";
|
||||
case 253: return "mmce";
|
||||
case 254: return "gukf";
|
||||
case 255: return "rujf";
|
||||
case 256: return "takf";
|
||||
case 257: return "mirf";
|
||||
case 258: return "mmcf";
|
||||
case 259: return "gukg";
|
||||
case 260: return "rujg";
|
||||
case 261: return "takg";
|
||||
case 262: return "mirg";
|
||||
case 263: return "mmcg";
|
||||
case 264: return "gukh";
|
||||
case 265: return "rujh";
|
||||
case 266: return "takh";
|
||||
case 267: return "mirh";
|
||||
case 268: return "mmch";
|
||||
case 269: return "ruji";
|
||||
case 270: return "taki";
|
||||
case 271: return "miri";
|
||||
case 272: return "mmci";
|
||||
case 273: return "rujj";
|
||||
case 274: return "takj";
|
||||
case 275: return "mirj";
|
||||
case 276: return "mmcj";
|
||||
case 277: return "chardokb";
|
||||
case 278: return "soldungc";
|
||||
case 279: return "abysmal";
|
||||
case 280: return "natimbi";
|
||||
case 281: return "qinimi";
|
||||
case 282: return "riwwi";
|
||||
case 283: return "barindu";
|
||||
case 284: return "ferubi";
|
||||
case 285: return "snpool";
|
||||
case 286: return "snlair";
|
||||
case 287: return "snplant";
|
||||
case 288: return "sncrematory";
|
||||
case 289: return "tipt";
|
||||
case 290: return "vxed";
|
||||
case 291: return "yxtta";
|
||||
case 292: return "uqua";
|
||||
case 293: return "kodtaz";
|
||||
case 294: return "ikkinz";
|
||||
case 295: return "qvic";
|
||||
case 296: return "inktuta";
|
||||
case 297: return "txevu";
|
||||
case 298: return "tacvi";
|
||||
case 299: return "qvicb";
|
||||
case 300: return "wallofslaughter";
|
||||
case 301: return "bloodfields";
|
||||
case 302: return "draniksscar";
|
||||
case 303: return "causeway";
|
||||
case 304: return "chambersa";
|
||||
case 305: return "chambersb";
|
||||
case 306: return "chambersc";
|
||||
case 307: return "chambersd";
|
||||
case 308: return "chamberse";
|
||||
case 309: return "chambersf";
|
||||
case 316: return "provinggrounds";
|
||||
case 317: return "anguish";
|
||||
case 318: return "dranikhollowsa";
|
||||
case 319: return "dranikhollowsb";
|
||||
case 320: return "dranikhollowsc";
|
||||
case 328: return "dranikcatacombsa";
|
||||
case 329: return "dranikcatacombsb";
|
||||
case 330: return "dranikcatacombsc";
|
||||
case 331: return "draniksewersa";
|
||||
case 332: return "draniksewersb";
|
||||
case 333: return "draniksewersc";
|
||||
case 334: return "riftseekers";
|
||||
case 335: return "harbingers";
|
||||
case 336: return "dranik";
|
||||
case 337: return "broodlands";
|
||||
case 338: return "stillmoona";
|
||||
case 339: return "stillmoonb";
|
||||
case 340: return "thundercrest";
|
||||
case 341: return "delvea";
|
||||
case 342: return "delveb";
|
||||
case 343: return "thenest";
|
||||
case 344: return "guildlobby";
|
||||
case 345: return "guildhall";
|
||||
case 346: return "barter";
|
||||
case 347: return "illsalin";
|
||||
case 348: return "illsalina";
|
||||
case 349: return "illsalinb";
|
||||
case 350: return "illsalinc";
|
||||
case 351: return "dreadspire";
|
||||
case 354: return "drachnidhive";
|
||||
case 355: return "drachnidhivea";
|
||||
case 356: return "drachnidhiveb";
|
||||
case 357: return "drachnidhivec";
|
||||
case 358: return "westkorlach";
|
||||
case 359: return "westkorlacha";
|
||||
case 360: return "westkorlachb";
|
||||
case 361: return "westkorlachc";
|
||||
case 362: return "eastkorlach";
|
||||
case 363: return "eastkorlacha";
|
||||
case 364: return "shadowspine";
|
||||
case 365: return "corathus";
|
||||
case 366: return "corathusa";
|
||||
case 367: return "corathusb";
|
||||
case 368: return "nektulosa";
|
||||
case 369: return "arcstone";
|
||||
case 370: return "relic";
|
||||
case 371: return "skylance";
|
||||
case 372: return "devastation";
|
||||
case 373: return "devastationa";
|
||||
case 374: return "rage";
|
||||
case 375: return "ragea";
|
||||
case 376: return "takishruins";
|
||||
case 377: return "takishruinsa";
|
||||
case 378: return "elddar";
|
||||
case 379: return "elddara";
|
||||
case 380: return "theater";
|
||||
case 381: return "theatera";
|
||||
case 382: return "freeporteast";
|
||||
case 383: return "freeportwest";
|
||||
case 384: return "freeportsewers";
|
||||
case 385: return "freeportacademy";
|
||||
case 386: return "freeporttemple";
|
||||
case 387: return "freeportmilitia";
|
||||
case 388: return "freeportarena";
|
||||
case 389: return "freeportcityhall";
|
||||
case 390: return "freeporttheater";
|
||||
case 391: return "freeporthall";
|
||||
case 392: return "northro";
|
||||
case 393: return "southro";
|
||||
case 394: return "crescent";
|
||||
case 395: return "moors";
|
||||
case 396: return "stonehive";
|
||||
case 397: return "mesa";
|
||||
case 398: return "roost";
|
||||
case 399: return "steppes";
|
||||
case 400: return "icefall";
|
||||
case 401: return "valdeholm";
|
||||
case 402: return "frostcrypt";
|
||||
case 403: return "sunderock";
|
||||
case 404: return "vergalid";
|
||||
case 405: return "direwind";
|
||||
case 406: return "ashengate";
|
||||
case 407: return "highpasshold";
|
||||
case 408: return "commonlands";
|
||||
case 409: return "oceanoftears";
|
||||
case 410: return "kithforest";
|
||||
case 411: return "befallenb";
|
||||
case 412: return "highpasskeep";
|
||||
case 413: return "innothuleb";
|
||||
case 414: return "toxxulia";
|
||||
case 415: return "mistythicket";
|
||||
case 416: return "kattacastrum";
|
||||
case 417: return "thalassius";
|
||||
case 418: return "atiiki";
|
||||
case 419: return "zhisza";
|
||||
case 420: return "silyssar";
|
||||
case 421: return "solteris";
|
||||
case 422: return "barren";
|
||||
case 423: return "buriedsea";
|
||||
case 424: return "jardelshook";
|
||||
case 425: return "monkeyrock";
|
||||
case 426: return "suncrest";
|
||||
case 427: return "deadbone";
|
||||
case 428: return "blacksail";
|
||||
case 429: return "maidensgrave";
|
||||
case 430: return "redfeather";
|
||||
case 431: return "shipmvp";
|
||||
case 432: return "shipmvu";
|
||||
case 433: return "shippvu";
|
||||
case 434: return "shipuvu";
|
||||
case 435: return "shipmvm";
|
||||
case 436: return "mechanotus";
|
||||
case 437: return "mansion";
|
||||
case 438: return "steamfactory";
|
||||
case 439: return "shipworkshop";
|
||||
case 440: return "gyrospireb";
|
||||
case 441: return "gyrospirez";
|
||||
case 442: return "dragonscale";
|
||||
case 443: return "lopingplains";
|
||||
case 444: return "hillsofshade";
|
||||
case 445: return "bloodmoon";
|
||||
case 446: return "crystallos";
|
||||
case 447: return "guardian";
|
||||
case 448: return "steamfontmts";
|
||||
case 449: return "cryptofshade";
|
||||
case 451: return "dragonscaleb";
|
||||
case 452: return "oldfieldofbone";
|
||||
case 453: return "oldkaesoraa";
|
||||
case 454: return "oldkaesorab";
|
||||
case 455: return "oldkurn";
|
||||
case 456: return "oldkithicor";
|
||||
case 457: return "oldcommons";
|
||||
case 458: return "oldhighpass";
|
||||
case 459: return "thevoida";
|
||||
case 460: return "thevoidb";
|
||||
case 461: return "thevoidc";
|
||||
case 462: return "thevoidd";
|
||||
case 463: return "thevoide";
|
||||
case 464: return "thevoidf";
|
||||
case 465: return "thevoidg";
|
||||
case 466: return "oceangreenhills";
|
||||
case 467: return "oceangreenvillage";
|
||||
case 468: return "oldblackburrow";
|
||||
case 469: return "bertoxtemple";
|
||||
case 470: return "discord";
|
||||
case 471: return "discordtower";
|
||||
case 472: return "oldbloodfield";
|
||||
case 473: return "precipiceofwar";
|
||||
case 474: return "olddranik";
|
||||
case 475: return "toskirakk";
|
||||
case 476: return "korascian";
|
||||
case 477: return "rathechamber";
|
||||
case 480: return "brellsrest";
|
||||
case 481: return "fungalforest";
|
||||
case 482: return "underquarry";
|
||||
case 483: return "coolingchamber";
|
||||
case 484: return "shiningcity";
|
||||
case 485: return "arthicrex";
|
||||
case 486: return "foundation";
|
||||
case 487: return "lichencreep";
|
||||
case 488: return "pellucid";
|
||||
case 489: return "stonesnake";
|
||||
case 490: return "brellstemple";
|
||||
case 491: return "convorteum";
|
||||
case 492: return "brellsarena";
|
||||
case 493: return "weddingchapel";
|
||||
case 494: return "weddingchapeldark";
|
||||
case 495: return "dragoncrypt";
|
||||
case 700: return "feerrott2";
|
||||
case 701: return "thulehouse1";
|
||||
case 702: return "thulehouse2";
|
||||
case 703: return "housegarden";
|
||||
case 704: return "thulelibrary";
|
||||
case 705: return "well";
|
||||
case 706: return "fallen";
|
||||
case 707: return "morellcastle";
|
||||
case 708: return "somnium";
|
||||
case 709: return "alkabormare";
|
||||
case 710: return "miragulmare";
|
||||
case 711: return "thuledream";
|
||||
case 712: return "neighborhood";
|
||||
case 724: return "argath";
|
||||
case 725: return "arelis";
|
||||
case 726: return "sarithcity";
|
||||
case 727: return "rubak";
|
||||
case 728: return "beastdomain";
|
||||
case 729: return "resplendent";
|
||||
case 730: return "pillarsalra";
|
||||
case 731: return "windsong";
|
||||
case 732: return "cityofbronze";
|
||||
case 733: return "sepulcher";
|
||||
case 734: return "eastsepulcher";
|
||||
case 735: return "westsepulcher";
|
||||
case 752: return "shardslanding";
|
||||
case 753: return "xorbb";
|
||||
case 754: return "kaelshard";
|
||||
case 755: return "eastwastesshard";
|
||||
case 756: return "crystalshard";
|
||||
case 757: return "breedinggrounds";
|
||||
case 758: return "eviltree";
|
||||
case 759: return "grelleth";
|
||||
case 760: return "chapterhouse";
|
||||
case 996: return "arttest";
|
||||
case 998: return "fhalls";
|
||||
case 999: return "apprentice";
|
||||
}
|
||||
return "UNKNWN";
|
||||
}
|
||||
@@ -28,11 +28,6 @@
|
||||
int ZoneLaunch::s_running = 0; //the number of zones running under this launcher
|
||||
Timer ZoneLaunch::s_startTimer(1); //I do not trust this things state after static initialization
|
||||
|
||||
void ZoneLaunch::InitStartTimer() {
|
||||
s_startTimer.Start(1);
|
||||
s_startTimer.Trigger();
|
||||
}
|
||||
|
||||
ZoneLaunch::ZoneLaunch(WorldServer *world, const char *launcher_name,
|
||||
const char *zone_name, uint16 port, const EQEmuConfig *config)
|
||||
: m_state(StateStartPending),
|
||||
|
||||
@@ -39,10 +39,6 @@ public:
|
||||
void SendStatus() const;
|
||||
|
||||
const char *GetZone() const { return(m_zone.c_str()); }
|
||||
uint32 GetStartCount() const { return(m_startCount); }
|
||||
|
||||
//should only be called during process init to setup the start timer.
|
||||
static void InitStartTimer();
|
||||
|
||||
protected:
|
||||
bool IsRunning() const { return(m_state == StateStarted || m_state == StateStopPending || m_state == StateRestartPending); }
|
||||
|
||||
@@ -260,27 +260,6 @@ bool AccountManagement::UpdateLoginserverWorldAdminAccountPasswordByName(
|
||||
return updated_account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in_account_id
|
||||
* @param in_account_password_hash
|
||||
*/
|
||||
bool AccountManagement::UpdateLoginserverWorldAdminAccountPasswordById(
|
||||
uint32 in_account_id,
|
||||
const std::string &in_account_password_hash
|
||||
)
|
||||
{
|
||||
bool updated_account = server.db->UpdateLoginWorldAdminAccountPassword(in_account_id, in_account_password_hash);
|
||||
|
||||
LogInfo(
|
||||
"[{}] account_name [{}] status [{}]",
|
||||
__func__,
|
||||
in_account_id,
|
||||
(updated_account ? "success" : "failed")
|
||||
);
|
||||
|
||||
return updated_account;
|
||||
}
|
||||
|
||||
constexpr int REQUEST_TIMEOUT_MS = 1500;
|
||||
|
||||
/**
|
||||
@@ -381,7 +360,7 @@ uint32 AccountManagement::CheckExternalLoginserverUserCredentials(
|
||||
auto s = Strings::Split(server.options.GetEQEmuLoginServerAddress(), ':');
|
||||
if (s.size() == 2) {
|
||||
auto address = s[0];
|
||||
auto port = std::stoi(s[1]);
|
||||
auto port = Strings::ToInt(s[1]);
|
||||
|
||||
EQ::Net::DNSLookup(
|
||||
address, port, false, [&](const std::string &addr) {
|
||||
|
||||
@@ -80,16 +80,6 @@ public:
|
||||
const std::string &in_account_password
|
||||
);
|
||||
|
||||
/**
|
||||
* @param in_account_id
|
||||
* @param in_account_password_hash
|
||||
* @return
|
||||
*/
|
||||
static bool UpdateLoginserverWorldAdminAccountPasswordById(
|
||||
uint32 in_account_id,
|
||||
const std::string &in_account_password_hash
|
||||
);
|
||||
|
||||
static uint32 HealthCheckUserLogin();
|
||||
};
|
||||
|
||||
|
||||
+2
-141
@@ -26,10 +26,11 @@ bool Client::Process()
|
||||
{
|
||||
EQApplicationPacket *app = m_connection->PopPacket();
|
||||
while (app) {
|
||||
auto o = m_connection->GetOpcodeManager();
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
m_connection->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
o->EmuToEQ(app->GetOpcode()) == 0 ? app->GetProtocolOpcode() : o->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
@@ -657,146 +658,6 @@ void Client::CreateEQEmuAccount(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param connection
|
||||
*/
|
||||
void Client::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
{
|
||||
m_login_connection = connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param conn
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
void Client::LoginOnStatusChange(
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
LogDebug("EQ::Net::StatusConnected");
|
||||
LoginSendSessionReady();
|
||||
}
|
||||
|
||||
if (to == EQ::Net::StatusDisconnecting || to == EQ::Net::StatusDisconnected) {
|
||||
LogDebug("EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected");
|
||||
|
||||
DoFailedLogin();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param conn
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
void Client::LoginOnStatusChangeIgnored(
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param conn
|
||||
* @param p
|
||||
*/
|
||||
void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
case 0x0017: //OP_ChatMessage
|
||||
LoginSendLogin();
|
||||
break;
|
||||
case 0x0018:
|
||||
LoginProcessLoginResponse(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::LoginSendSessionReady()
|
||||
{
|
||||
EQ::Net::DynamicPacket p;
|
||||
p.PutUInt16(0, 1); //OP_SessionReady
|
||||
p.PutUInt32(2, 2);
|
||||
|
||||
m_login_connection->QueuePacket(p);
|
||||
}
|
||||
|
||||
void Client::LoginSendLogin()
|
||||
{
|
||||
size_t buffer_len = m_stored_user.length() + m_stored_pass.length() + 2;
|
||||
std::unique_ptr<char[]> buffer(new char[buffer_len]);
|
||||
|
||||
strcpy(&buffer[0], m_stored_user.c_str());
|
||||
strcpy(&buffer[m_stored_user.length() + 1], m_stored_pass.c_str());
|
||||
|
||||
size_t encrypted_len = buffer_len;
|
||||
|
||||
if (encrypted_len % 8 > 0) {
|
||||
encrypted_len = ((encrypted_len / 8) + 1) * 8;
|
||||
}
|
||||
|
||||
EQ::Net::DynamicPacket p;
|
||||
p.Resize(12 + encrypted_len);
|
||||
p.PutUInt16(0, 2); //OP_Login
|
||||
p.PutUInt32(2, 3);
|
||||
|
||||
eqcrypt_block(&buffer[0], buffer_len, (char *) p.Data() + 12, true);
|
||||
|
||||
m_login_connection->QueuePacket(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param p
|
||||
*/
|
||||
void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p)
|
||||
{
|
||||
auto encrypt_size = p.Length() - 12;
|
||||
|
||||
if (encrypt_size % 8 > 0) {
|
||||
encrypt_size = (encrypt_size / 8) * 8;
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> decrypted(new char[encrypt_size]);
|
||||
|
||||
eqcrypt_block((char *) p.Data() + 12, encrypt_size, &decrypted[0], false);
|
||||
|
||||
EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size);
|
||||
auto response_error = sp.GetUInt16(1);
|
||||
|
||||
m_login_connection_manager->OnConnectionStateChange(
|
||||
std::bind(
|
||||
&Client::LoginOnStatusChangeIgnored,
|
||||
this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2,
|
||||
std::placeholders::_3
|
||||
)
|
||||
);
|
||||
|
||||
if (response_error > 101) {
|
||||
LogDebug("response [{0}] failed login", response_error);
|
||||
DoFailedLogin();
|
||||
m_login_connection->Close();
|
||||
}
|
||||
else {
|
||||
LogDebug(
|
||||
"response [{0}] login succeeded user [{1}]",
|
||||
response_error,
|
||||
m_stored_user
|
||||
);
|
||||
|
||||
auto m_dbid = sp.GetUInt32(8);
|
||||
|
||||
CreateEQEmuAccount(m_stored_user, m_stored_pass, m_dbid);
|
||||
m_login_connection->Close();
|
||||
}
|
||||
}
|
||||
bool Client::ProcessHealthCheck(std::string username)
|
||||
{
|
||||
if (username == "healthcheckuser") {
|
||||
|
||||
@@ -198,21 +198,6 @@ private:
|
||||
|
||||
std::string m_stored_user;
|
||||
std::string m_stored_pass;
|
||||
void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void LoginOnStatusChange(
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
);
|
||||
void LoginOnStatusChangeIgnored(
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
);
|
||||
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void LoginSendSessionReady();
|
||||
void LoginSendLogin();
|
||||
void LoginProcessLoginResponse(const EQ::Net::Packet &p);
|
||||
static bool ProcessHealthCheck(std::string username);
|
||||
};
|
||||
|
||||
|
||||
+11
-11
@@ -32,7 +32,7 @@ Database::Database(
|
||||
user.c_str(),
|
||||
pass.c_str(),
|
||||
name.c_str(),
|
||||
std::stoi(port),
|
||||
Strings::ToUnsignedInt(port),
|
||||
&errnum,
|
||||
errbuf
|
||||
)
|
||||
@@ -93,7 +93,7 @@ bool Database::GetLoginDataFromAccountInfo(
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
id = atoi(row[0]);
|
||||
id = Strings::ToUnsignedInt(row[0]);
|
||||
password = row[1];
|
||||
|
||||
LogDebug(
|
||||
@@ -145,7 +145,7 @@ bool Database::GetLoginTokenDataFromToken(
|
||||
}
|
||||
|
||||
if (strcmp(row[2], "login_server_id") == 0) {
|
||||
db_account_id = atoi(row[3]);
|
||||
db_account_id = Strings::ToUnsignedInt(row[3]);
|
||||
found_login_id = true;
|
||||
continue;
|
||||
}
|
||||
@@ -178,7 +178,7 @@ unsigned int Database::GetFreeID(const std::string &loginserver)
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
return std::stoi(row[0]);
|
||||
return Strings::ToUnsignedInt(row[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,12 +368,12 @@ Database::DbWorldRegistration Database::GetWorldRegistration(
|
||||
auto row = results.begin();
|
||||
|
||||
r.loaded = true;
|
||||
r.server_id = std::stoi(row[0]);
|
||||
r.server_id = Strings::ToInt(row[0]);
|
||||
r.server_description = row[1];
|
||||
r.server_list_type = std::stoi(row[3]);
|
||||
r.is_server_trusted = std::stoi(row[2]) > 0;
|
||||
r.server_list_type = Strings::ToInt(row[3]);
|
||||
r.is_server_trusted = Strings::ToInt(row[2]) > 0;
|
||||
r.server_list_description = row[4];
|
||||
r.server_admin_id = std::stoi(row[5]);
|
||||
r.server_admin_id = Strings::ToUnsignedInt(row[5]);
|
||||
|
||||
if (r.server_admin_id <= 0) {
|
||||
return r;
|
||||
@@ -513,7 +513,7 @@ bool Database::CreateWorldRegistration(
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
id = std::stoi(row[0]);
|
||||
id = Strings::ToUnsignedInt(row[0]);
|
||||
auto insert_query = fmt::format(
|
||||
"INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', last_ip_address = '{3}', \n"
|
||||
"login_server_list_type_id = 3, login_server_admin_id = {4}, is_server_trusted = 0, tag_description = ''",
|
||||
@@ -647,7 +647,7 @@ Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &ac
|
||||
if (results.RowCount() == 1) {
|
||||
auto row = results.begin();
|
||||
r.loaded = true;
|
||||
r.id = std::stoi(row[0]);
|
||||
r.id = Strings::ToUnsignedInt(row[0]);
|
||||
r.account_name = row[1];
|
||||
r.account_password = row[2];
|
||||
r.first_name = row[3];
|
||||
@@ -683,7 +683,7 @@ Database::DbLoginServerAccount Database::GetLoginServerAccountByAccountName(
|
||||
if (results.RowCount() == 1) {
|
||||
auto row = results.begin();
|
||||
r.loaded = true;
|
||||
r.id = std::stoi(row[0]);
|
||||
r.id = Strings::ToUnsignedInt(row[0]);
|
||||
r.account_name = row[1];
|
||||
r.account_password = row[2];
|
||||
r.account_email = row[3];
|
||||
|
||||
@@ -29,7 +29,6 @@ public:
|
||||
* Destructor, frees our database if needed.
|
||||
*/
|
||||
~Database();
|
||||
bool IsConnected() { return (m_database != nullptr); }
|
||||
|
||||
/**
|
||||
* Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure.
|
||||
|
||||
@@ -23,13 +23,6 @@ struct LoginHandShakeReply_Struct {
|
||||
char unknown[1]; // variable length string
|
||||
};
|
||||
|
||||
// for reference, login buffer is variable (minimum size 8 due to encryption)
|
||||
struct PlayerLogin_Struct {
|
||||
LoginBaseMessage_Struct base_header;
|
||||
char username[1];
|
||||
char password[1];
|
||||
};
|
||||
|
||||
// variable length, can use directly if not serializing strings
|
||||
struct PlayerLoginReply_Struct {
|
||||
// base header excluded to make struct data easier to encrypt
|
||||
|
||||
@@ -480,8 +480,8 @@ namespace LoginserverWebserver {
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
LoginserverWebserver::TokenManager::token_data token_data;
|
||||
token_data.token = row[0];
|
||||
token_data.can_write = std::stoi(row[1]) > 0;
|
||||
token_data.can_read = std::stoi(row[2]) > 0;
|
||||
token_data.can_write = Strings::ToInt(row[1]) > 0;
|
||||
token_data.can_read = Strings::ToInt(row[2]) > 0;
|
||||
|
||||
LogDebug(
|
||||
"Inserting api token to internal list [{0}] write {1} read {2}",
|
||||
|
||||
@@ -288,9 +288,16 @@ int main(int argc, char **argv)
|
||||
LogInfo("[Config] [Security] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed());
|
||||
LogInfo("[Config] [Security] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords());
|
||||
|
||||
Timer keepalive(INTERSERVER_TIMER); // does auto-reconnect
|
||||
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
if (keepalive.Check()) {
|
||||
keepalive.Start();
|
||||
server.db->ping();
|
||||
}
|
||||
|
||||
if (!run_server) {
|
||||
EQ::EventLoop::Get().Shutdown();
|
||||
return;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user