mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-31 17:26:30 +00:00
Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 332a1dcab1 | |||
| 8dd8caff63 | |||
| fc24385fd6 | |||
| c9d8c45b39 | |||
| 191746975c | |||
| 965bf0e684 | |||
| 4ed820039c | |||
| c931b1051e | |||
| 5375603b81 | |||
| 77ad1c6f9c | |||
| 3771da84c4 | |||
| 77cbe4b9d4 | |||
| c7dcf52b82 | |||
| a942b65553 | |||
| 62546b6f2f | |||
| 4ac0bfd69e | |||
| 9cde2f7405 | |||
| c17ab5a848 | |||
| 158dd3ac97 | |||
| f5de63b1d7 | |||
| bf157eab7f | |||
| 11fc66c490 | |||
| f654fa6f58 | |||
| c75f731a82 | |||
| f29421a7d6 | |||
| 0a6212f9a8 | |||
| 84415b146b | |||
| e4fe36088b | |||
| 5aea91e680 | |||
| 8d7cef6237 | |||
| f65ab8d372 | |||
| 217ea71bd7 | |||
| d5f2669cab | |||
| c49548c090 | |||
| b615b4d474 | |||
| f151e5fbe3 | |||
| 2835f79a9f | |||
| 9fbdf1e7c0 | |||
| 1c074ec84c | |||
| aa953731ad | |||
| 23ef6b9c8c | |||
| 3655b1a350 | |||
| 9ff2d03d01 | |||
| eedba3949d | |||
| 241e6e6823 | |||
| d00ab2233a | |||
| af03ac7df2 | |||
| 45c1a60684 | |||
| f3407f5972 | |||
| e7b43b9e2f | |||
| cf6b97c745 | |||
| 26116ec808 | |||
| a6438b833c | |||
| e840eeb931 | |||
| 6cd2cb20b5 | |||
| 440eb64328 | |||
| af0e64cef8 | |||
| 2db28a7e42 | |||
| 4bbad8678c | |||
| b6e5ef5521 | |||
| b22b281312 | |||
| b66c65fc02 | |||
| 1c7dedb12d | |||
| e6dc06c0c6 | |||
| c445f7bed6 | |||
| 4e0b762244 | |||
| 4f3c97ff24 | |||
| c5d5bf6503 | |||
| a76204bd38 | |||
| d828c72176 | |||
| 60962005d1 | |||
| 2a81314d49 | |||
| 9edad8fa3b | |||
| 74f8629884 | |||
| 6f8fc85a92 | |||
| 87af11374c | |||
| 90366302bd | |||
| 92df505c6e |
+5
-11
@@ -4,6 +4,9 @@ kind: pipeline
|
|||||||
type: docker
|
type: docker
|
||||||
name: Build Linux
|
name: Build Linux
|
||||||
|
|
||||||
|
clone:
|
||||||
|
depth: 1
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
||||||
concurrency:
|
concurrency:
|
||||||
limit: 1
|
limit: 1
|
||||||
@@ -36,9 +39,8 @@ kind: pipeline
|
|||||||
type: exec
|
type: exec
|
||||||
name: Build Windows
|
name: Build Windows
|
||||||
|
|
||||||
# Limits how many of these builds can run on the drone runner at a time, this isn't about cores
|
clone:
|
||||||
concurrency:
|
depth: 1
|
||||||
limit: 1
|
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
os: windows
|
os: windows
|
||||||
@@ -85,14 +87,6 @@ steps:
|
|||||||
- |
|
- |
|
||||||
rclone delete remote: --include "eqemu-server*.zip"
|
rclone delete remote: --include "eqemu-server*.zip"
|
||||||
|
|
||||||
trigger:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- Build Windows
|
- Build Windows
|
||||||
- Build Linux
|
- Build Linux
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,3 @@ compile_flags.txt
|
|||||||
!utils/scripts/build/
|
!utils/scripts/build/
|
||||||
!utils/scripts/build/should-release/should-release
|
!utils/scripts/build/should-release/should-release
|
||||||
!utils/scripts/build/should-release/should-release.exe
|
!utils/scripts/build/should-release/should-release.exe
|
||||||
|
|
||||||
# CMake Files
|
|
||||||
cmake-build-relwithdebinfo/*
|
|
||||||
|
|||||||
+24
-1866
File diff suppressed because it is too large
Load Diff
@@ -16,15 +16,6 @@ SET(CMAKE_CXX_STANDARD 20)
|
|||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
SET(CMAKE_CXX_EXTENSIONS OFF)
|
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
OPTION(EQEMU_BUILD_STATIC "Build with static linking" OFF)
|
|
||||||
|
|
||||||
IF (EQEMU_BUILD_STATIC)
|
|
||||||
SET(BUILD_SHARED_LIBS OFF)
|
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
|
|
||||||
MESSAGE(STATUS "Building with static linking")
|
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
|
|
||||||
ENDIF(EQEMU_BUILD_STATIC)
|
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
@@ -316,10 +307,6 @@ ELSE()
|
|||||||
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
SET(ZLIB_LIBRARY_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (EQEMU_BUILD_STATIC)
|
|
||||||
SET(ZLIB_LIBRARY_LIBS libz.a)
|
|
||||||
ENDIF(EQEMU_BUILD_STATIC)
|
|
||||||
|
|
||||||
MESSAGE(STATUS "")
|
MESSAGE(STATUS "")
|
||||||
MESSAGE(STATUS "**************************************************")
|
MESSAGE(STATUS "**************************************************")
|
||||||
MESSAGE(STATUS "* Library Usage *")
|
MESSAGE(STATUS "* Library Usage *")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# EQEmulator Core Server
|
# EQEmulator Core Server
|
||||||
| Drone (Linux x64) | Drone (Windows x64) |
|
|Travis CI (Linux)|Appveyor (Windows x86) |Appveyor (Windows x64) |
|
||||||
|:---:|:---:|
|
|:---:|:---:|:---:|
|
||||||
|[](http://drone.akkadius.com/EQEmu/Server) |[](http://drone.akkadius.com/EQEmu/Server) |
|
|[](https://travis-ci.org/EQEmu/Server) |[](https://ci.appveyor.com/project/KimLS/server) |[](https://ci.appveyor.com/project/KimLS/server-87crp) |
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
version: 1.0.{build}
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
image: Visual Studio 2017
|
||||||
|
configuration: RelWithDebInfo
|
||||||
|
clone_folder: c:\projects\eqemu
|
||||||
|
init:
|
||||||
|
- ps: git config --global core.autocrlf input
|
||||||
|
cache: c:\tools\vcpkg\installed\
|
||||||
|
before_build:
|
||||||
|
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -DPERL_EXECUTABLE=\"C:/projects/eqemu/strawberry-perl-portable/perl/bin/perl.exe\" -DPERL_INCLUDE_PATH=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE\" -DPERL_LIBRARY=\"C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/libperl526.a\" -DCMAKE_TOOLCHAIN_FILE=\"c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake\" .."
|
||||||
|
build:
|
||||||
|
project: C:\projects\eqemu\build\EQEmu.sln
|
||||||
|
parallel: true
|
||||||
|
verbosity: minimal
|
||||||
|
after_build:
|
||||||
|
- cmd: >-
|
||||||
|
7z a build_x64-bots.zip C:\projects\eqemu\build\bin\RelWithDebInfo\*.exe C:\projects\eqemu\build\bin\RelWithDebInfo\*.dll C:\projects\eqemu\build\bin\RelWithDebInfo\*.pdb C:\projects\eqemu\build\libs\zlibng\RelWithDebInfo\*.dll
|
||||||
|
|
||||||
|
appveyor PushArtifact build_x64-bots.zip
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
version: 1.0.{build}
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
image: Visual Studio 2017
|
||||||
|
configuration: RelWithDebInfo
|
||||||
|
clone_folder: c:\projects\eqemu
|
||||||
|
init:
|
||||||
|
- ps: git config --global core.autocrlf input
|
||||||
|
cache: c:\tools\vcpkg\installed\
|
||||||
|
before_build:
|
||||||
|
- ps: "$wc = New-Object System.Net.WebClient\n$wc.DownloadFile(\"http://strawberryperl.com/download/5.26.2.1/strawberry-perl-5.26.2.1-64bit-portable.zip\", \"c:\\projects\\eqemu\\strawberry-perl-5.26.2.1-64bit-portable.zip\")\ncd c:\\projects\\eqemu\n7z x c:/projects/eqemu/strawberry-perl-5.26.2.1-64bit-portable.zip -oc:/projects/eqemu/strawberry-perl-portable -y\n(Get-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h).replace('#define PERL_STATIC_INLINE static __inline__', '#define PERL_STATIC_INLINE static __inline') | Set-Content C:/projects/eqemu/strawberry-perl-portable/perl/lib/CORE/config.h\nvcpkg install boost-geometry:x64-windows boost-dynamic-bitset:x64-windows luajit:x64-windows libsodium:x64-windows libmysql:x64-windows openssl:x64-windows zlib:x64-windows \nmkdir build\ncd build\ncmake -G \"Visual Studio 15 2017 Win64\" -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_LOGIN=ON -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;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMysql(database.getMySQL());
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
@@ -183,7 +183,7 @@ bool SkillUsable(SharedDatabase *db, int skill_id, int class_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
if (row[0] && Strings::ToInt(row[0]) > 0) {
|
if (row[0] && atoi(row[0]) > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportSkillCaps(SharedDatabase *db)
|
void ExportSkillCaps(SharedDatabase *db)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMysql(database.getMySQL());
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.SetDatabase(&database)
|
LogSys.SetDatabase(&database)
|
||||||
@@ -241,10 +241,10 @@ void ImportSkillCaps(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int class_id, skill_id, level, cap;
|
int class_id, skill_id, level, cap;
|
||||||
class_id = Strings::ToInt(split[0].c_str());
|
class_id = atoi(split[0].c_str());
|
||||||
skill_id = Strings::ToInt(split[1].c_str());
|
skill_id = atoi(split[1].c_str());
|
||||||
level = Strings::ToInt(split[2].c_str());
|
level = atoi(split[2].c_str());
|
||||||
cap = Strings::ToInt(split[3].c_str());
|
cap = atoi(split[3].c_str());
|
||||||
|
|
||||||
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
std::string sql = StringFormat("INSERT INTO skill_caps(class, skillID, level, cap) VALUES(%d, %d, %d, %d)",
|
||||||
class_id, skill_id, level, cap);
|
class_id, skill_id, level, cap);
|
||||||
@@ -280,16 +280,16 @@ void ImportBaseData(SharedDatabase *db) {
|
|||||||
int level, class_id;
|
int level, class_id;
|
||||||
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
double hp, mana, end, unk1, unk2, hp_fac, mana_fac, end_fac;
|
||||||
|
|
||||||
level = Strings::ToInt(split[0].c_str());
|
level = atoi(split[0].c_str());
|
||||||
class_id = Strings::ToInt(split[1].c_str());
|
class_id = atoi(split[1].c_str());
|
||||||
hp = Strings::ToFloat(split[2].c_str());
|
hp = atof(split[2].c_str());
|
||||||
mana = Strings::ToFloat(split[3].c_str());
|
mana = atof(split[3].c_str());
|
||||||
end = Strings::ToFloat(split[4].c_str());
|
end = atof(split[4].c_str());
|
||||||
unk1 = Strings::ToFloat(split[5].c_str());
|
unk1 = atof(split[5].c_str());
|
||||||
unk2 = Strings::ToFloat(split[6].c_str());
|
unk2 = atof(split[6].c_str());
|
||||||
hp_fac = Strings::ToFloat(split[7].c_str());
|
hp_fac = atof(split[7].c_str());
|
||||||
mana_fac = Strings::ToFloat(split[8].c_str());
|
mana_fac = atof(split[8].c_str());
|
||||||
end_fac = Strings::ToFloat(split[9].c_str());
|
end_fac = atof(split[9].c_str());
|
||||||
|
|
||||||
sql = StringFormat("INSERT INTO base_data(level, class, hp, mana, end, unk1, unk2, hp_fac, "
|
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)",
|
"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;
|
int id, type;
|
||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
id = Strings::ToInt(split[0].c_str());
|
id = atoi(split[0].c_str());
|
||||||
type = Strings::ToInt(split[1].c_str());
|
type = atoi(split[1].c_str());
|
||||||
|
|
||||||
if(split.size() >= 3) {
|
if(split.size() >= 3) {
|
||||||
value = ::Strings::Escape(split[2]);
|
value = ::Strings::Escape(split[2]);
|
||||||
|
|||||||
+7
-16
@@ -15,9 +15,6 @@ SET(common_sources
|
|||||||
database.cpp
|
database.cpp
|
||||||
database_conversions.cpp
|
database_conversions.cpp
|
||||||
database_instances.cpp
|
database_instances.cpp
|
||||||
database/database_update_manifest.cpp
|
|
||||||
database/database_update_manifest_bots.cpp
|
|
||||||
database/database_update.cpp
|
|
||||||
dbcore.cpp
|
dbcore.cpp
|
||||||
deity.cpp
|
deity.cpp
|
||||||
dynamic_zone_base.cpp
|
dynamic_zone_base.cpp
|
||||||
@@ -36,11 +33,9 @@ SET(common_sources
|
|||||||
eq_stream_proxy.cpp
|
eq_stream_proxy.cpp
|
||||||
eqtime.cpp
|
eqtime.cpp
|
||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
events/player_event_logs.cpp
|
|
||||||
events/player_event_discord_formatter.cpp
|
|
||||||
expedition_lockout_timer.cpp
|
expedition_lockout_timer.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
discord/discord_manager.cpp
|
discord_manager.cpp
|
||||||
faction.cpp
|
faction.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
guild_base.cpp
|
guild_base.cpp
|
||||||
@@ -203,6 +198,7 @@ SET(repositories
|
|||||||
repositories/base/base_dynamic_zones_repository.h
|
repositories/base/base_dynamic_zones_repository.h
|
||||||
repositories/base/base_dynamic_zone_members_repository.h
|
repositories/base/base_dynamic_zone_members_repository.h
|
||||||
repositories/base/base_dynamic_zone_templates_repository.h
|
repositories/base/base_dynamic_zone_templates_repository.h
|
||||||
|
repositories/base/base_eventlog_repository.h
|
||||||
repositories/base/base_expeditions_repository.h
|
repositories/base/base_expeditions_repository.h
|
||||||
repositories/base/base_expedition_lockouts_repository.h
|
repositories/base/base_expedition_lockouts_repository.h
|
||||||
repositories/base/base_faction_association_repository.h
|
repositories/base/base_faction_association_repository.h
|
||||||
@@ -222,6 +218,7 @@ SET(repositories
|
|||||||
repositories/base/base_guilds_repository.h
|
repositories/base/base_guilds_repository.h
|
||||||
repositories/base/base_guild_ranks_repository.h
|
repositories/base/base_guild_ranks_repository.h
|
||||||
repositories/base/base_guild_relations_repository.h
|
repositories/base/base_guild_relations_repository.h
|
||||||
|
repositories/base/base_hackers_repository.h
|
||||||
repositories/base/base_horses_repository.h
|
repositories/base/base_horses_repository.h
|
||||||
repositories/base/base_instance_list_repository.h
|
repositories/base/base_instance_list_repository.h
|
||||||
repositories/base/base_instance_list_player_repository.h
|
repositories/base/base_instance_list_player_repository.h
|
||||||
@@ -267,8 +264,6 @@ SET(repositories
|
|||||||
repositories/base/base_pets_equipmentset_repository.h
|
repositories/base/base_pets_equipmentset_repository.h
|
||||||
repositories/base/base_pets_equipmentset_entries_repository.h
|
repositories/base/base_pets_equipmentset_entries_repository.h
|
||||||
repositories/base/base_player_titlesets_repository.h
|
repositories/base/base_player_titlesets_repository.h
|
||||||
repositories/base/base_player_event_log_settings_repository.h
|
|
||||||
repositories/base/base_player_event_logs_repository.h
|
|
||||||
repositories/base/base_quest_globals_repository.h
|
repositories/base/base_quest_globals_repository.h
|
||||||
repositories/base/base_raid_details_repository.h
|
repositories/base/base_raid_details_repository.h
|
||||||
repositories/base/base_raid_members_repository.h
|
repositories/base/base_raid_members_repository.h
|
||||||
@@ -381,6 +376,7 @@ SET(repositories
|
|||||||
repositories/dynamic_zones_repository.h
|
repositories/dynamic_zones_repository.h
|
||||||
repositories/dynamic_zone_members_repository.h
|
repositories/dynamic_zone_members_repository.h
|
||||||
repositories/dynamic_zone_templates_repository.h
|
repositories/dynamic_zone_templates_repository.h
|
||||||
|
repositories/eventlog_repository.h
|
||||||
repositories/expeditions_repository.h
|
repositories/expeditions_repository.h
|
||||||
repositories/expedition_lockouts_repository.h
|
repositories/expedition_lockouts_repository.h
|
||||||
repositories/faction_association_repository.h
|
repositories/faction_association_repository.h
|
||||||
@@ -400,6 +396,7 @@ SET(repositories
|
|||||||
repositories/guilds_repository.h
|
repositories/guilds_repository.h
|
||||||
repositories/guild_ranks_repository.h
|
repositories/guild_ranks_repository.h
|
||||||
repositories/guild_relations_repository.h
|
repositories/guild_relations_repository.h
|
||||||
|
repositories/hackers_repository.h
|
||||||
repositories/horses_repository.h
|
repositories/horses_repository.h
|
||||||
repositories/instance_list_repository.h
|
repositories/instance_list_repository.h
|
||||||
repositories/instance_list_player_repository.h
|
repositories/instance_list_player_repository.h
|
||||||
@@ -445,8 +442,6 @@ SET(repositories
|
|||||||
repositories/pets_equipmentset_repository.h
|
repositories/pets_equipmentset_repository.h
|
||||||
repositories/pets_equipmentset_entries_repository.h
|
repositories/pets_equipmentset_entries_repository.h
|
||||||
repositories/player_titlesets_repository.h
|
repositories/player_titlesets_repository.h
|
||||||
repositories/player_event_log_settings_repository.h
|
|
||||||
repositories/player_event_logs_repository.h
|
|
||||||
repositories/quest_globals_repository.h
|
repositories/quest_globals_repository.h
|
||||||
repositories/raid_details_repository.h
|
repositories/raid_details_repository.h
|
||||||
repositories/raid_members_repository.h
|
repositories/raid_members_repository.h
|
||||||
@@ -509,11 +504,10 @@ SET(common_headers
|
|||||||
data_verification.h
|
data_verification.h
|
||||||
database.h
|
database.h
|
||||||
database_schema.h
|
database_schema.h
|
||||||
database/database_update.h
|
|
||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
discord/discord.h
|
discord/discord.h
|
||||||
discord/discord_manager.h
|
discord_manager.h
|
||||||
dynamic_zone_base.h
|
dynamic_zone_base.h
|
||||||
emu_constants.h
|
emu_constants.h
|
||||||
emu_limits.h
|
emu_limits.h
|
||||||
@@ -536,9 +530,6 @@ SET(common_headers
|
|||||||
eq_stream_locator.h
|
eq_stream_locator.h
|
||||||
eq_stream_proxy.h
|
eq_stream_proxy.h
|
||||||
eqtime.h
|
eqtime.h
|
||||||
events/player_event_logs.h
|
|
||||||
events/player_event_discord_formatter.h
|
|
||||||
events/player_events.h
|
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
@@ -612,11 +603,11 @@ SET(common_headers
|
|||||||
unix.h
|
unix.h
|
||||||
useperl.h
|
useperl.h
|
||||||
version.h
|
version.h
|
||||||
|
zone_numbers.h
|
||||||
zone_store.h
|
zone_store.h
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/task.h
|
event/task.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
json/json_archive_single_line.h
|
|
||||||
json/json.h
|
json/json.h
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
net/console_server.h
|
net/console_server.h
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "../common/classes.h"
|
#include "../common/classes.h"
|
||||||
#include "data_verification.h"
|
|
||||||
|
|
||||||
const char *GetClassIDName(uint8 class_id, uint8 level)
|
const char *GetClassIDName(uint8 class_id, uint8 level)
|
||||||
{
|
{
|
||||||
@@ -631,20 +630,6 @@ bool IsINTCasterClass(uint8 class_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHeroicINTCasterClass(uint8 class_id)
|
|
||||||
{
|
|
||||||
switch (class_id) {
|
|
||||||
case NECROMANCER:
|
|
||||||
case WIZARD:
|
|
||||||
case MAGICIAN:
|
|
||||||
case ENCHANTER:
|
|
||||||
case SHADOWKNIGHT:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsWISCasterClass(uint8 class_id)
|
bool IsWISCasterClass(uint8 class_id)
|
||||||
{
|
{
|
||||||
switch (class_id) {
|
switch (class_id) {
|
||||||
@@ -657,21 +642,6 @@ bool IsWISCasterClass(uint8 class_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHeroicWISCasterClass(uint8 class_id)
|
|
||||||
{
|
|
||||||
switch (class_id) {
|
|
||||||
case CLERIC:
|
|
||||||
case DRUID:
|
|
||||||
case SHAMAN:
|
|
||||||
case PALADIN:
|
|
||||||
case BEASTLORD:
|
|
||||||
case RANGER:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsPlateClass(uint8 class_id)
|
bool IsPlateClass(uint8 class_id)
|
||||||
{
|
{
|
||||||
switch (class_id) {
|
switch (class_id) {
|
||||||
@@ -751,51 +721,3 @@ uint8 ClassArmorType(uint8 class_id)
|
|||||||
return ARMOR_TYPE_UNKNOWN;
|
return ARMOR_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string GetPlayerClassAbbreviation(uint8 class_id)
|
|
||||||
{
|
|
||||||
if (!EQ::ValueWithin(class_id, WARRIOR, BERSERKER)) {
|
|
||||||
return std::string("UNK");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (class_id) {
|
|
||||||
case WARRIOR:
|
|
||||||
return "WAR";
|
|
||||||
case CLERIC:
|
|
||||||
return "CLR";
|
|
||||||
case PALADIN:
|
|
||||||
return "PAL";
|
|
||||||
case RANGER:
|
|
||||||
return "RNG";
|
|
||||||
case SHADOWKNIGHT:
|
|
||||||
return "SHD";
|
|
||||||
case DRUID:
|
|
||||||
return "DRU";
|
|
||||||
case MONK:
|
|
||||||
return "MNK";
|
|
||||||
case BARD:
|
|
||||||
return "BRD";
|
|
||||||
case ROGUE:
|
|
||||||
return "ROG";
|
|
||||||
case SHAMAN:
|
|
||||||
return "SHM";
|
|
||||||
case NECROMANCER:
|
|
||||||
return "NEC";
|
|
||||||
case WIZARD:
|
|
||||||
return "WIZ";
|
|
||||||
case MAGICIAN:
|
|
||||||
return "MAG";
|
|
||||||
case ENCHANTER:
|
|
||||||
return "ENC";
|
|
||||||
case BEASTLORD:
|
|
||||||
return "BST";
|
|
||||||
case BERSERKER:
|
|
||||||
return "BER";
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::string("UNK");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsPlayerClass(uint8 class_id) {
|
|
||||||
return EQ::ValueWithin(class_id, WARRIOR, BERSERKER);
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-6
@@ -19,7 +19,6 @@
|
|||||||
#define CLASSES_CH
|
#define CLASSES_CH
|
||||||
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#define NO_CLASS 0
|
#define NO_CLASS 0
|
||||||
#define WARRIOR 1
|
#define WARRIOR 1
|
||||||
@@ -128,9 +127,6 @@
|
|||||||
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
const char* GetClassIDName(uint8 class_id, uint8 level = 0);
|
||||||
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
const char* GetPlayerClassName(uint32 player_class_value, uint8 level = 0);
|
||||||
|
|
||||||
bool IsPlayerClass(uint8 class_id);
|
|
||||||
const std::string GetPlayerClassAbbreviation(uint8 class_id);
|
|
||||||
|
|
||||||
uint32 GetPlayerClassValue(uint8 class_id);
|
uint32 GetPlayerClassValue(uint8 class_id);
|
||||||
uint32 GetPlayerClassBit(uint8 class_id);
|
uint32 GetPlayerClassBit(uint8 class_id);
|
||||||
|
|
||||||
@@ -144,8 +140,7 @@ bool IsHybridClass(uint8 class_id);
|
|||||||
bool IsCasterClass(uint8 class_id);
|
bool IsCasterClass(uint8 class_id);
|
||||||
bool IsINTCasterClass(uint8 class_id);
|
bool IsINTCasterClass(uint8 class_id);
|
||||||
bool IsWISCasterClass(uint8 class_id);
|
bool IsWISCasterClass(uint8 class_id);
|
||||||
bool IsHeroicINTCasterClass(uint8 class_id);
|
|
||||||
bool IsHeroicWISCasterClass(uint8 class_id);
|
|
||||||
bool IsPlateClass(uint8 class_id);
|
bool IsPlateClass(uint8 class_id);
|
||||||
bool IsChainClass(uint8 class_id);
|
bool IsChainClass(uint8 class_id);
|
||||||
bool IsLeatherClass(uint8 class_id);
|
bool IsLeatherClass(uint8 class_id);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace EQEmuCommand {
|
|||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arguments_filled || (argc == 2 && !cmd[{"-h", "--help"}]) || (argc == 3 && cmd[{"-h", "--help"}])) {
|
if (!arguments_filled || argc == 2 || cmd[{"-h", "--help"}]) {
|
||||||
std::string arguments_string;
|
std::string arguments_string;
|
||||||
for (auto &arg : arguments) {
|
for (auto &arg : arguments) {
|
||||||
arguments_string += " " + arg;
|
arguments_string += " " + arg;
|
||||||
@@ -160,7 +160,7 @@ namespace EQEmuCommand {
|
|||||||
*/
|
*/
|
||||||
std::string command_section;
|
std::string command_section;
|
||||||
for (auto &it: in_function_map) {
|
for (auto &it: in_function_map) {
|
||||||
description.clear();
|
description = "";
|
||||||
|
|
||||||
(it.second)(argc, argv, cmd, description);
|
(it.second)(argc, argv, cmd, description);
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
|
|||||||
/**
|
/**
|
||||||
* @param content_flags
|
* @param content_flags
|
||||||
*/
|
*/
|
||||||
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags)
|
void WorldContentService::SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags)
|
||||||
{
|
{
|
||||||
WorldContentService::content_flags = content_flags;
|
WorldContentService::content_flags = content_flags;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ public:
|
|||||||
std::vector<std::string> GetContentFlagsDisabled();
|
std::vector<std::string> GetContentFlagsDisabled();
|
||||||
bool IsContentFlagEnabled(const std::string& content_flag);
|
bool IsContentFlagEnabled(const std::string& content_flag);
|
||||||
bool IsContentFlagDisabled(const std::string& content_flag);
|
bool IsContentFlagDisabled(const std::string& content_flag);
|
||||||
void SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags>& content_flags);
|
void SetContentFlags(std::vector<ContentFlagsRepository::ContentFlags> content_flags);
|
||||||
void ReloadContentFlags();
|
void ReloadContentFlags();
|
||||||
WorldContentService * SetExpansionContext();
|
WorldContentService * SetExpansionContext();
|
||||||
|
|
||||||
|
|||||||
+2
-109
@@ -3,93 +3,13 @@
|
|||||||
#include "crash.h"
|
#include "crash.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "process/process.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 <cstdio>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
#define popen _popen
|
#define popen _popen
|
||||||
#endif
|
#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);
|
|
||||||
|
|
||||||
// os info
|
|
||||||
auto os = EQ::GetOS();
|
|
||||||
auto cpus = EQ::GetCPUs();
|
|
||||||
auto process_id = EQ::GetPID();
|
|
||||||
auto rss = EQ::GetRSS() / 1048576.0;
|
|
||||||
auto uptime = static_cast<uint32>(EQ::GetUptime());
|
|
||||||
|
|
||||||
// payload
|
|
||||||
Json::Value p;
|
|
||||||
p["platform_name"] = GetPlatformName();
|
|
||||||
p["crash_report"] = crash_report;
|
|
||||||
p["server_version"] = CURRENT_VERSION;
|
|
||||||
p["compile_date"] = COMPILE_DATE;
|
|
||||||
p["compile_time"] = COMPILE_TIME;
|
|
||||||
p["server_name"] = config->LongName;
|
|
||||||
p["server_short_name"] = config->ShortName;
|
|
||||||
p["uptime"] = uptime;
|
|
||||||
p["os_machine"] = os.machine;
|
|
||||||
p["os_release"] = os.release;
|
|
||||||
p["os_version"] = os.version;
|
|
||||||
p["os_sysname"] = os.sysname;
|
|
||||||
p["process_id"] = process_id;
|
|
||||||
p["rss_memory"] = rss;
|
|
||||||
p["cpus"] = cpus.size();
|
|
||||||
p["origination_info"] = "";
|
|
||||||
|
|
||||||
if (!LogSys.origination_info.zone_short_name.empty()) {
|
|
||||||
p["origination_info"] = fmt::format(
|
|
||||||
"{} ({}) instance_id [{}]",
|
|
||||||
LogSys.origination_info.zone_short_name,
|
|
||||||
LogSys.origination_info.zone_long_name,
|
|
||||||
LogSys.origination_info.instance_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream payload;
|
|
||||||
payload << p;
|
|
||||||
|
|
||||||
if (auto res = r.Post(e, payload.str(), "application/json")) {
|
|
||||||
if (res->status == 200) {
|
|
||||||
LogInfo("Sent crash report");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogError("Failed to send crash report to [{}]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
#if defined(_WINDOWS) && defined(CRASH_LOGGING)
|
||||||
#include "StackWalker.h"
|
#include "StackWalker.h"
|
||||||
@@ -109,22 +29,14 @@ public:
|
|||||||
|
|
||||||
if(szText[i] == '\n' || szText[i] == '\r') {
|
if(szText[i] == '\n' || szText[i] == '\r') {
|
||||||
buffer[i] = ' ';
|
buffer[i] = ' ';
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
buffer[i] = szText[i];
|
buffer[i] = szText[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line = buffer;
|
|
||||||
_lines.push_back(line);
|
|
||||||
|
|
||||||
Log(Logs::General, Logs::Crash, buffer);
|
Log(Logs::General, Logs::Crash, buffer);
|
||||||
StackWalker::OnOutput(szText);
|
StackWalker::OnOutput(szText);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& GetLines() { return _lines; }
|
|
||||||
private:
|
|
||||||
std::vector<std::string> _lines;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
@@ -198,20 +110,7 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
|
|||||||
|
|
||||||
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
if(EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode)
|
||||||
{
|
{
|
||||||
EQEmuStackWalker sw;
|
EQEmuStackWalker sw; sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
||||||
sw.ShowCallstack(GetCurrentThread(), ExceptionInfo->ContextRecord);
|
|
||||||
|
|
||||||
if (RuleB(Analytics, CrashReporting)) {
|
|
||||||
std::string crash_report;
|
|
||||||
auto& lines = sw.GetLines();
|
|
||||||
|
|
||||||
for (auto& line : lines) {
|
|
||||||
crash_report += line;
|
|
||||||
crash_report += "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
SendCrashReport(crash_report);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXCEPTION_EXECUTE_HANDLER;
|
return EXCEPTION_EXECUTE_HANDLER;
|
||||||
@@ -282,18 +181,12 @@ void print_trace()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream input(temp_output_file);
|
std::ifstream input(temp_output_file);
|
||||||
std::string crash_report;
|
|
||||||
for (std::string line; getline(input, line);) {
|
for (std::string line; getline(input, line);) {
|
||||||
LogCrash("{}", line);
|
LogCrash("{}", line);
|
||||||
crash_report += fmt::format("{}\n", line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::remove(temp_output_file.c_str());
|
std::remove(temp_output_file.c_str());
|
||||||
|
|
||||||
if (RuleB(Analytics, CrashReporting)) {
|
|
||||||
SendCrashReport(crash_report);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ namespace cron
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return static_cast<cron_int>(Strings::ToUnsignedInt(text.data()));
|
return static_cast<cron_int>(std::stoul(text.data()));
|
||||||
}
|
}
|
||||||
catch (std::exception const & ex)
|
catch (std::exception const & ex)
|
||||||
{
|
{
|
||||||
|
|||||||
+133
-166
@@ -121,10 +121,10 @@ uint32 Database::CheckLogin(const char* name, const char* password, const char *
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
auto id = Strings::ToUnsignedInt(row[0]);
|
auto id = std::stoul(row[0]);
|
||||||
|
|
||||||
if (oStatus) {
|
if (oStatus) {
|
||||||
*oStatus = Strings::ToInt(row[1]);
|
*oStatus = std::stoi(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
@@ -202,11 +202,11 @@ int16 Database::CheckStatus(uint32 account_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
int16 status = Strings::ToInt(row[0]);
|
int16 status = std::stoi(row[0]);
|
||||||
int32 date_diff = 0;
|
int32 date_diff = 0;
|
||||||
|
|
||||||
if (row[1]) {
|
if (row[1]) {
|
||||||
date_diff = Strings::ToInt(row[1]);
|
date_diff = std::stoi(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (date_diff > 0) {
|
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);
|
std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
if (row[0] && Strings::ToInt(row[0]) > 0){
|
if (row[0] && atoi(row[0]) > 0){
|
||||||
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
LogInfo("Account: [{}] tried to request name: [{}], but it is already taken", account_id, name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -353,7 +353,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
|||||||
|
|
||||||
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
|
query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.ErrorMessage().empty()){ return false; }
|
if (!results.Success() || results.ErrorMessage() != ""){ return false; }
|
||||||
|
|
||||||
// Put character into the default guild if rule is being used.
|
// Put character into the default guild if rule is being used.
|
||||||
int guild_id = RuleI(Character, DefaultGuild);
|
int guild_id = RuleI(Character, DefaultGuild);
|
||||||
@@ -363,7 +363,7 @@ bool Database::ReserveName(uint32 account_id, char* name) {
|
|||||||
if (character_id > -1) {
|
if (character_id > -1) {
|
||||||
query = StringFormat("INSERT INTO `guild_members` SET `char_id` = %i, `guild_id` = '%i'", character_id, guild_id);
|
query = StringFormat("INSERT INTO `guild_members` SET `char_id` = %i, `guild_id` = '%i'", character_id, guild_id);
|
||||||
results = QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.ErrorMessage().empty()){
|
if (!results.Success() || results.ErrorMessage() != ""){
|
||||||
LogInfo("Could not put character [{}] into default Guild", name);
|
LogInfo("Could not put character [{}] into default Guild", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,7 +387,7 @@ bool Database::DeleteCharacter(char *character_name)
|
|||||||
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
|
std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", character_name);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
character_id = Strings::ToUnsignedInt(row[0]);
|
character_id = atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character_id <= 0) {
|
if (character_id <= 0) {
|
||||||
@@ -449,8 +449,7 @@ bool Database::DeleteCharacter(char *character_name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp)
|
bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp){
|
||||||
{
|
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat(
|
||||||
"REPLACE INTO `character_data` ("
|
"REPLACE INTO `character_data` ("
|
||||||
"id,"
|
"id,"
|
||||||
@@ -726,11 +725,10 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
pp->guildAutoconsent, // " guild_auto_consent, "
|
pp->guildAutoconsent, // " guild_auto_consent, "
|
||||||
pp->RestTimer // " RestTimer) "
|
pp->RestTimer // " RestTimer) "
|
||||||
);
|
);
|
||||||
QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
/* Save Bind Points */
|
/* Save Bind Points */
|
||||||
query = StringFormat(
|
query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
||||||
"REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, slot)"
|
|
||||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
|
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i), "
|
||||||
"(%u, %u, %u, %f, %f, %f, %f, %i), "
|
"(%u, %u, %u, %f, %f, %f, %f, %i), "
|
||||||
"(%u, %u, %u, %f, %f, %f, %f, %i), "
|
"(%u, %u, %u, %f, %f, %f, %f, %i), "
|
||||||
@@ -741,18 +739,13 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
character_id, pp->binds[2].zone_id, 0, pp->binds[2].x, pp->binds[2].y, pp->binds[2].z, pp->binds[2].heading, 2,
|
character_id, pp->binds[2].zone_id, 0, pp->binds[2].x, pp->binds[2].y, pp->binds[2].z, pp->binds[2].heading, 2,
|
||||||
character_id, pp->binds[3].zone_id, 0, pp->binds[3].x, pp->binds[3].y, pp->binds[3].z, pp->binds[3].heading, 3,
|
character_id, pp->binds[3].zone_id, 0, pp->binds[3].x, pp->binds[3].y, pp->binds[3].z, pp->binds[3].heading, 3,
|
||||||
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
|
character_id, pp->binds[4].zone_id, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
|
||||||
);
|
); results = QueryDatabase(query);
|
||||||
QueryDatabase(query);
|
|
||||||
|
|
||||||
/* HoTT Ability */
|
/* HoTT Ability */
|
||||||
if (RuleB(Character, GrantHoTTOnCreate)) {
|
if(RuleB(Character, GrantHoTTOnCreate))
|
||||||
query = StringFormat(
|
{
|
||||||
"INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)",
|
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, `rank`) VALUES (%u, %i, %i)", character_id, 14, 1);
|
||||||
character_id,
|
results = QueryDatabase(query);
|
||||||
14,
|
|
||||||
1
|
|
||||||
);
|
|
||||||
QueryDatabase(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save Skills */
|
/* Save Skills */
|
||||||
@@ -761,18 +754,14 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
if (pp->skills[i] > 0){
|
if (pp->skills[i] > 0){
|
||||||
if (firstquery != 1){
|
if (firstquery != 1){
|
||||||
firstquery = 1;
|
firstquery = 1;
|
||||||
query = StringFormat(
|
query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]);
|
||||||
"REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)",
|
}
|
||||||
character_id,
|
else{
|
||||||
i,
|
|
||||||
pp->skills[i]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]);
|
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
/* Save Language */
|
/* Save Language */
|
||||||
firstquery = 0;
|
firstquery = 0;
|
||||||
@@ -780,34 +769,27 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
|
|||||||
if (pp->languages[i] > 0){
|
if (pp->languages[i] > 0){
|
||||||
if (firstquery != 1){
|
if (firstquery != 1){
|
||||||
firstquery = 1;
|
firstquery = 1;
|
||||||
query = StringFormat(
|
query = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]);
|
||||||
"REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)",
|
}
|
||||||
character_id,
|
else{
|
||||||
i,
|
|
||||||
pp->languages[i]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]);
|
query = query + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QueryDatabase(query);
|
results = QueryDatabase(query);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetCharacterID(const char *name) {
|
uint32 Database::GetCharacterID(const char *name) {
|
||||||
const auto query = fmt::format(
|
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name);
|
||||||
"SELECT `id` FROM `character_data` WHERE `name` = '{}'",
|
|
||||||
Strings::Escape(name)
|
|
||||||
);
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.RowCount()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
if (results.RowCount() == 1)
|
||||||
|
{
|
||||||
|
return atoi(row[0]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -830,10 +812,10 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
uint32 accountId = Strings::ToUnsignedInt(row[0]);
|
uint32 accountId = atoi(row[0]);
|
||||||
|
|
||||||
if (oCharID)
|
if (oCharID)
|
||||||
*oCharID = Strings::ToUnsignedInt(row[1]);
|
*oCharID = atoi(row[1]);
|
||||||
|
|
||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
@@ -850,7 +832,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
|
uint32 Database::GetAccountIDByName(std::string account_name, std::string loginserver, int16* status, uint32* lsid) {
|
||||||
@@ -870,14 +852,14 @@ uint32 Database::GetAccountIDByName(std::string account_name, std::string logins
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto account_id = Strings::ToUnsignedInt(row[0]);
|
auto account_id = std::stoul(row[0]);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
*status = static_cast<int16>(Strings::ToInt(row[1]));
|
*status = static_cast<int16>(std::stoi(row[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lsid) {
|
if (lsid) {
|
||||||
*lsid = row[2] ? Strings::ToUnsignedInt(row[2]) : 0;
|
*lsid = row[2] ? std::stoul(row[2]) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return account_id;
|
return account_id;
|
||||||
@@ -898,7 +880,7 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID
|
|||||||
|
|
||||||
strcpy(name, row[0]);
|
strcpy(name, row[0]);
|
||||||
if (row[1] && oLSAccountID) {
|
if (row[1] && oLSAccountID) {
|
||||||
*oLSAccountID = Strings::ToUnsignedInt(row[1]);
|
*oLSAccountID = atoi(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -986,7 +968,7 @@ bool Database::LoadVariables() {
|
|||||||
|
|
||||||
std::string key, value;
|
std::string key, value;
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
varcache.last_update = Strings::ToUnsignedInt(row[2]); // ahh should we be comparing if this is newer?
|
varcache.last_update = atoi(row[2]); // ahh should we be comparing if this is newer?
|
||||||
key = row[0];
|
key = row[0];
|
||||||
value = row[1];
|
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
|
std::transform(std::begin(key), std::end(key), std::begin(key), ::tolower); // keys are lower case, DB doesn't have to be
|
||||||
@@ -1017,7 +999,7 @@ bool Database::GetVariable(std::string varname, std::string &varvalue)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::SetVariable(const std::string& varname, const std::string &varvalue)
|
bool Database::SetVariable(const std::string varname, const std::string &varvalue)
|
||||||
{
|
{
|
||||||
std::string escaped_name = Strings::Escape(varname);
|
std::string escaped_name = Strings::Escape(varname);
|
||||||
std::string escaped_value = Strings::Escape(varvalue);
|
std::string escaped_value = Strings::Escape(varvalue);
|
||||||
@@ -1070,15 +1052,15 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon
|
|||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if(graveyard_zoneid != nullptr)
|
if(graveyard_zoneid != nullptr)
|
||||||
*graveyard_zoneid = Strings::ToUnsignedInt(row[0]);
|
*graveyard_zoneid = atoi(row[0]);
|
||||||
if(graveyard_x != nullptr)
|
if(graveyard_x != nullptr)
|
||||||
*graveyard_x = Strings::ToFloat(row[1]);
|
*graveyard_x = atof(row[1]);
|
||||||
if(graveyard_y != nullptr)
|
if(graveyard_y != nullptr)
|
||||||
*graveyard_y = Strings::ToFloat(row[2]);
|
*graveyard_y = atof(row[2]);
|
||||||
if(graveyard_z != nullptr)
|
if(graveyard_z != nullptr)
|
||||||
*graveyard_z = Strings::ToFloat(row[3]);
|
*graveyard_z = atof(row[3]);
|
||||||
if(graveyard_heading != nullptr)
|
if(graveyard_heading != nullptr)
|
||||||
*graveyard_heading = Strings::ToFloat(row[4]);
|
*graveyard_heading = atof(row[4]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1186,13 +1168,13 @@ uint32 Database::GetAccountIDFromLSID(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
account_id = Strings::ToUnsignedInt(row[0]);
|
account_id = std::stoi(row[0]);
|
||||||
|
|
||||||
if (in_account_name) {
|
if (in_account_name) {
|
||||||
strcpy(in_account_name, row[1]);
|
strcpy(in_account_name, row[1]);
|
||||||
}
|
}
|
||||||
if (in_status) {
|
if (in_status) {
|
||||||
*in_status = Strings::ToInt(row[2]);
|
*in_status = std::stoi(row[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,7 +1198,7 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) {
|
|||||||
if (oAccountName)
|
if (oAccountName)
|
||||||
strcpy(oAccountName, row[0]);
|
strcpy(oAccountName, row[0]);
|
||||||
if (oStatus)
|
if (oStatus)
|
||||||
*oStatus = Strings::ToInt(row[1]);
|
*oStatus = atoi(row[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::ClearMerchantTemp(){
|
void Database::ClearMerchantTemp(){
|
||||||
@@ -1262,7 +1244,7 @@ uint8 Database::GetServerType() {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id)
|
bool Database::MoveCharacterToZone(uint32 character_id, uint32 zone_id)
|
||||||
@@ -1299,6 +1281,44 @@ bool Database::MoveCharacterToZone(const char *charname, uint32 zone_id)
|
|||||||
return results.RowsAffected() != 0;
|
return results.RowsAffected() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
|
||||||
|
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.RowsAffected() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
|
||||||
|
//Utilize the "hacker" table, but also give zone information.
|
||||||
|
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.RowsAffected() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const std::string &hacked, const char* zone) {
|
||||||
|
//Utilize the "hacker" table, but also give zone information.
|
||||||
|
auto query = fmt::format("INSERT INTO hackers(account, name, hacked, zone) values('{}', '{}', '{}', '{}')",
|
||||||
|
accountname, charactername, hacked, zone);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
|
if (!results.Success())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.RowsAffected() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
||||||
{
|
{
|
||||||
uint16 race_cap = 0;
|
uint16 race_cap = 0;
|
||||||
@@ -1314,7 +1334,7 @@ uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
|
uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level)
|
||||||
@@ -1330,12 +1350,12 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16
|
|||||||
if (results.Success() && results.RowsAffected() != 0)
|
if (results.Success() && results.RowsAffected() != 0)
|
||||||
{
|
{
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
skill_level = Strings::ToUnsignedInt(row[0]);
|
skill_level = atoi(row[0]);
|
||||||
skill_formula = Strings::ToUnsignedInt(row[1]);
|
skill_formula = atoi(row[1]);
|
||||||
skill_cap = Strings::ToUnsignedInt(row[2]);
|
skill_cap = atoi(row[2]);
|
||||||
if (Strings::ToUnsignedInt(row[3]) > skill_cap)
|
if (atoi(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_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 = Strings::ToUnsignedInt(row[4]);
|
skill_cap3 = atoi(row[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int race_skill = GetRaceSkill(skillid,in_race);
|
int race_skill = GetRaceSkill(skillid,in_race);
|
||||||
@@ -1380,10 +1400,10 @@ uint32 Database::GetCharacterInfo(std::string character_name, uint32 *account_id
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto character_id = Strings::ToUnsignedInt(row[0]);
|
auto character_id = std::stoul(row[0]);
|
||||||
*account_id = Strings::ToUnsignedInt(row[1]);
|
*account_id = std::stoul(row[1]);
|
||||||
*zone_id = Strings::ToUnsignedInt(row[2]);
|
*zone_id = std::stoul(row[2]);
|
||||||
*instance_id = Strings::ToUnsignedInt(row[3]);
|
*instance_id = std::stoul(row[3]);
|
||||||
|
|
||||||
return character_id;
|
return character_id;
|
||||||
}
|
}
|
||||||
@@ -1506,7 +1526,7 @@ uint32 Database::GetGroupID(const char* name){
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
||||||
@@ -1520,7 +1540,7 @@ std::string Database::GetGroupLeaderForLogin(std::string character_name) {
|
|||||||
|
|
||||||
if (results.Success() && results.RowCount()) {
|
if (results.Success() && results.RowCount()) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
group_id = Strings::ToUnsignedInt(row[0]);
|
group_id = std::stoul(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!group_id) {
|
if (!group_id) {
|
||||||
@@ -1609,7 +1629,7 @@ char *Database::GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* mainta
|
|||||||
strcpy(mentoree, row[5]);
|
strcpy(mentoree, row[5]);
|
||||||
|
|
||||||
if (mentor_percent)
|
if (mentor_percent)
|
||||||
*mentor_percent = Strings::ToInt(row[6]);
|
*mentor_percent = atoi(row[6]);
|
||||||
|
|
||||||
if(GLAA && results.LengthOfColumn(7) == sizeof(GroupLeadershipAA_Struct))
|
if(GLAA && results.LengthOfColumn(7) == sizeof(GroupLeadershipAA_Struct))
|
||||||
memcpy(GLAA, row[7], sizeof(GroupLeadershipAA_Struct));
|
memcpy(GLAA, row[7], sizeof(GroupLeadershipAA_Struct));
|
||||||
@@ -1656,7 +1676,7 @@ uint8 Database::GetAgreementFlag(uint32 acctid) {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetAgreementFlag(uint32 acctid) {
|
void Database::SetAgreementFlag(uint32 acctid) {
|
||||||
@@ -1742,7 +1762,7 @@ uint32 Database::GetRaidID(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (row[0]) // would it ever be possible to have a null here?
|
if (row[0]) // would it ever be possible to have a null here?
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1825,7 +1845,7 @@ void Database::GetGroupLeadershipInfo(uint32 gid, uint32 rid, char *maintank,
|
|||||||
strcpy(mentoree, row[4]);
|
strcpy(mentoree, row[4]);
|
||||||
|
|
||||||
if (mentor_percent)
|
if (mentor_percent)
|
||||||
*mentor_percent = Strings::ToInt(row[5]);
|
*mentor_percent = atoi(row[5]);
|
||||||
|
|
||||||
if (GLAA && results.LengthOfColumn(6) == sizeof(GroupLeadershipAA_Struct))
|
if (GLAA && results.LengthOfColumn(6) == sizeof(GroupLeadershipAA_Struct))
|
||||||
memcpy(GLAA, row[6], sizeof(GroupLeadershipAA_Struct));
|
memcpy(GLAA, row[6], sizeof(GroupLeadershipAA_Struct));
|
||||||
@@ -1998,16 +2018,16 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
as->success.guk = Strings::ToUnsignedInt(row[0]);
|
as->success.guk = atoi(row[0]);
|
||||||
as->success.mir = Strings::ToUnsignedInt(row[1]);
|
as->success.mir = atoi(row[1]);
|
||||||
as->success.mmc = Strings::ToUnsignedInt(row[2]);
|
as->success.mmc = atoi(row[2]);
|
||||||
as->success.ruj = Strings::ToUnsignedInt(row[3]);
|
as->success.ruj = atoi(row[3]);
|
||||||
as->success.tak = Strings::ToUnsignedInt(row[4]);
|
as->success.tak = atoi(row[4]);
|
||||||
as->failure.guk = Strings::ToUnsignedInt(row[5]);
|
as->failure.guk = atoi(row[5]);
|
||||||
as->failure.mir = Strings::ToUnsignedInt(row[6]);
|
as->failure.mir = atoi(row[6]);
|
||||||
as->failure.mmc = Strings::ToUnsignedInt(row[7]);
|
as->failure.mmc = atoi(row[7]);
|
||||||
as->failure.ruj = Strings::ToUnsignedInt(row[8]);
|
as->failure.ruj = atoi(row[8]);
|
||||||
as->failure.tak = Strings::ToUnsignedInt(row[9]);
|
as->failure.tak = atoi(row[9]);
|
||||||
as->failure.total = as->failure.guk + as->failure.mir + as->failure.mmc + as->failure.ruj + as->failure.tak;
|
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;
|
as->success.total = as->success.guk + as->success.mir + as->success.mmc + as->success.ruj + as->success.tak;
|
||||||
|
|
||||||
@@ -2026,7 +2046,7 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
||||||
@@ -2048,7 +2068,7 @@ uint32 Database::GetGroupIDByCharID(uint32 character_id)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
||||||
@@ -2061,12 +2081,10 @@ uint32 Database::GetRaidIDByCharID(uint32 character_id) {
|
|||||||
character_id
|
character_id
|
||||||
);
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success() || !results.RowCount()) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
return 0;
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
auto row = results.begin();
|
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::CountInvSnapshots() {
|
int Database::CountInvSnapshots() {
|
||||||
@@ -2078,7 +2096,7 @@ int Database::CountInvSnapshots() {
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
int64 count = Strings::ToBigInt(row[0]);
|
int64 count = atoll(row[0]);
|
||||||
if (count > 2147483647)
|
if (count > 2147483647)
|
||||||
return -2;
|
return -2;
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
@@ -2109,17 +2127,17 @@ struct TimeOfDay_Struct Database::LoadTime(time_t &realtime)
|
|||||||
eqTime.day = 1;
|
eqTime.day = 1;
|
||||||
eqTime.month = 1;
|
eqTime.month = 1;
|
||||||
eqTime.year = 3100;
|
eqTime.year = 3100;
|
||||||
realtime = time(nullptr);
|
realtime = time(0);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
eqTime.minute = Strings::ToUnsignedInt(row[0]);
|
eqTime.minute = atoi(row[0]);
|
||||||
eqTime.hour = Strings::ToUnsignedInt(row[1]);
|
eqTime.hour = atoi(row[1]);
|
||||||
eqTime.day = Strings::ToUnsignedInt(row[2]);
|
eqTime.day = atoi(row[2]);
|
||||||
eqTime.month = Strings::ToUnsignedInt(row[3]);
|
eqTime.month = atoi(row[3]);
|
||||||
eqTime.year = Strings::ToUnsignedInt(row[4]);
|
eqTime.year = atoi(row[4]);
|
||||||
realtime = Strings::ToBigInt(row[5]);
|
realtime = atoi(row[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return eqTime;
|
return eqTime;
|
||||||
@@ -2146,7 +2164,7 @@ int Database::GetIPExemption(std::string account_ip) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToInt(row[0]);
|
return std::stoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
||||||
@@ -2160,7 +2178,7 @@ void Database::SetIPExemption(std::string account_ip, int exemption_amount) {
|
|||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (results.Success() && results.RowCount()) {
|
if (results.Success() && results.RowCount()) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
exemption_id = Strings::ToUnsignedInt(row[0]);
|
exemption_id = std::stoul(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
query = fmt::format(
|
query = fmt::format(
|
||||||
@@ -2186,7 +2204,7 @@ int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
|
|||||||
|
|
||||||
if (results.Success() && results.RowCount() > 0) {
|
if (results.Success() && results.RowCount() > 0) {
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
return Strings::ToInt(row[0]);;
|
return atoi(row[0]);;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2292,6 +2310,7 @@ bool Database::CopyCharacter(
|
|||||||
new_rows.emplace_back(new_values);
|
new_rows.emplace_back(new_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string insert_values;
|
||||||
std::vector<std::string> insert_rows;
|
std::vector<std::string> insert_rows;
|
||||||
|
|
||||||
for (auto &r: new_rows) {
|
for (auto &r: new_rows) {
|
||||||
@@ -2347,7 +2366,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!DoesTableExist(table_name)) {
|
if (!DoesTableExist(table_name)) {
|
||||||
LogMySQLQuery("Table [{}] does not exist. Downloading and installing...", table_name);
|
LogMySQLQuery("Table [{}] does not exist. Downloading from Github and installing...", table_name);
|
||||||
|
|
||||||
// http get request
|
// http get request
|
||||||
httplib::Client cli(
|
httplib::Client cli(
|
||||||
@@ -2355,7 +2374,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
"{}://{}",
|
"{}://{}",
|
||||||
request_uri.get_scheme(),
|
request_uri.get_scheme(),
|
||||||
request_uri.get_host()
|
request_uri.get_host()
|
||||||
)
|
).c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
cli.set_connection_timeout(0, 60000000); // 60 sec
|
cli.set_connection_timeout(0, 60000000); // 60 sec
|
||||||
@@ -2364,7 +2383,7 @@ void Database::SourceDatabaseTableFromUrl(std::string table_name, std::string ur
|
|||||||
|
|
||||||
int sourced_queries = 0;
|
int sourced_queries = 0;
|
||||||
|
|
||||||
if (auto res = cli.Get(request_uri.get_path())) {
|
if (auto res = cli.Get(request_uri.get_path().c_str())) {
|
||||||
if (res->status == 200) {
|
if (res->status == 200) {
|
||||||
for (auto &s: Strings::Split(res->body, ';')) {
|
for (auto &s: Strings::Split(res->body, ';')) {
|
||||||
if (!Strings::Trim(s).empty()) {
|
if (!Strings::Trim(s).empty()) {
|
||||||
@@ -2408,55 +2427,3 @@ uint8 Database::GetMinStatus(uint32 zone_id, uint32 instance_version)
|
|||||||
|
|
||||||
return !zones.empty() ? zones[0].min_status : 0;
|
return !zones.empty() ? zones[0].min_status : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SourceSqlFromUrl(std::string url)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
uri request_uri(url);
|
|
||||||
|
|
||||||
LogHTTPDetail(
|
|
||||||
"parsing url [{}] path [{}] host [{}] query_string [{}] protocol [{}] port [{}]",
|
|
||||||
url,
|
|
||||||
request_uri.get_path(),
|
|
||||||
request_uri.get_host(),
|
|
||||||
request_uri.get_query(),
|
|
||||||
request_uri.get_scheme(),
|
|
||||||
request_uri.get_port()
|
|
||||||
);
|
|
||||||
|
|
||||||
LogInfo("Downloading and installing from [{}]", url);
|
|
||||||
|
|
||||||
// http get request
|
|
||||||
httplib::Client cli(
|
|
||||||
fmt::format(
|
|
||||||
"{}://{}",
|
|
||||||
request_uri.get_scheme(),
|
|
||||||
request_uri.get_host()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
cli.set_connection_timeout(0, 60000000); // 60 sec
|
|
||||||
cli.set_read_timeout(60, 0); // 60 seconds
|
|
||||||
cli.set_write_timeout(60, 0); // 60 seconds
|
|
||||||
|
|
||||||
if (auto res = cli.Get(request_uri.get_path())) {
|
|
||||||
if (res->status == 200) {
|
|
||||||
auto results = QueryDatabaseMulti(res->body);
|
|
||||||
if (!results.ErrorMessage().empty()) {
|
|
||||||
LogError("Error sourcing SQL [{}]", results.ErrorMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (res->status == 404) {
|
|
||||||
LogError("Error retrieving URL [{}]", url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogError("Error retrieving URL [{}]", url);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (std::invalid_argument iae) {
|
|
||||||
LogError("URI parser error [{}]", iae.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+7
-2
@@ -34,6 +34,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
//atoi is not uint32 or uint32 safe!!!!
|
||||||
|
#define atoul(str) strtoul(str, nullptr, 10)
|
||||||
|
|
||||||
class MySQLRequestResult;
|
class MySQLRequestResult;
|
||||||
class Client;
|
class Client;
|
||||||
@@ -106,6 +108,9 @@ public:
|
|||||||
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
|
||||||
bool ReserveName(uint32 account_id, char *name);
|
bool ReserveName(uint32 account_id, char *name);
|
||||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
|
||||||
|
bool SetHackerFlag(const char *accountname, const char *charactername, const char *hacked);
|
||||||
|
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const char *hacked, const char *zone);
|
||||||
|
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
|
||||||
bool UpdateName(const char *oldname, const char *newname);
|
bool UpdateName(const char *oldname, const char *newname);
|
||||||
bool CopyCharacter(
|
bool CopyCharacter(
|
||||||
const std::string& source_character_name,
|
const std::string& source_character_name,
|
||||||
@@ -235,7 +240,7 @@ public:
|
|||||||
/* Database Variables */
|
/* Database Variables */
|
||||||
|
|
||||||
bool GetVariable(std::string varname, std::string &varvalue);
|
bool GetVariable(std::string varname, std::string &varvalue);
|
||||||
bool SetVariable(const std::string& varname, const std::string &varvalue);
|
bool SetVariable(const std::string varname, const std::string &varvalue);
|
||||||
bool LoadVariables();
|
bool LoadVariables();
|
||||||
|
|
||||||
/* General Queries */
|
/* General Queries */
|
||||||
@@ -263,7 +268,7 @@ public:
|
|||||||
void ClearInvSnapshots(bool from_now = false);
|
void ClearInvSnapshots(bool from_now = false);
|
||||||
|
|
||||||
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
void SourceDatabaseTableFromUrl(std::string table_name, std::string url);
|
||||||
void SourceSqlFromUrl(std::string url);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@
|
|||||||
#include "../database_schema.h"
|
#include "../database_schema.h"
|
||||||
#include "../file.h"
|
#include "../file.h"
|
||||||
#include "../process/process.h"
|
#include "../process/process.h"
|
||||||
#include "../termcolor/rang.hpp"
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
@@ -37,7 +36,6 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -93,8 +91,6 @@ std::string DatabaseDumpService::GetMySQLVersion()
|
|||||||
return Strings::Trim(version_output);
|
return Strings::Trim(version_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string CREDENTIALS_FILE = "login.my.cnf";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -103,15 +99,21 @@ std::string DatabaseDumpService::GetBaseMySQLDumpCommand()
|
|||||||
auto config = EQEmuConfig::get();
|
auto config = EQEmuConfig::get();
|
||||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"mysqldump --defaults-extra-file={} {}",
|
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||||
CREDENTIALS_FILE,
|
config->ContentDbUsername,
|
||||||
|
config->ContentDbPassword,
|
||||||
|
config->ContentDbHost,
|
||||||
|
config->ContentDbPort,
|
||||||
config->ContentDbName
|
config->ContentDbName
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return fmt::format(
|
return fmt::format(
|
||||||
"mysqldump --defaults-extra-file={} {}",
|
"mysqldump -u {} -p{} -h {} --port={} {}",
|
||||||
CREDENTIALS_FILE,
|
config->DatabaseUsername,
|
||||||
|
config->DatabasePassword,
|
||||||
|
config->DatabaseHost,
|
||||||
|
config->DatabasePort,
|
||||||
config->DatabaseDB
|
config->DatabaseDB
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -197,7 +199,7 @@ std::string DatabaseDumpService::GetDumpFileNameWithPath()
|
|||||||
return GetSetDumpPath() + GetDumpFileName();
|
return GetSetDumpPath() + GetDumpFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseDumpService::DatabaseDump()
|
void DatabaseDumpService::Dump()
|
||||||
{
|
{
|
||||||
if (!IsMySQLInstalled()) {
|
if (!IsMySQLInstalled()) {
|
||||||
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
LogError("MySQL is not installed; Please check your PATH for a valid MySQL installation");
|
||||||
@@ -291,6 +293,14 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
pipe_file = fmt::format(" > {}.sql", GetDumpFileNameWithPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string execute_command = fmt::format(
|
||||||
|
"{} {} {} {}",
|
||||||
|
GetBaseMySQLDumpCommand(),
|
||||||
|
options,
|
||||||
|
tables_to_dump,
|
||||||
|
pipe_file
|
||||||
|
);
|
||||||
|
|
||||||
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
if (!File::Exists(GetSetDumpPath()) && !IsDumpOutputToConsole()) {
|
||||||
File::Makedir(GetSetDumpPath());
|
File::Makedir(GetSetDumpPath());
|
||||||
}
|
}
|
||||||
@@ -305,53 +315,23 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
if (tables_to_dump.empty()) {
|
if (tables_to_dump.empty()) {
|
||||||
std::cerr << "No tables were specified" << std::endl;
|
std::cerr << "No tables were specified" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const auto execute_command = fmt::format(
|
|
||||||
"{} {} {} {}",
|
|
||||||
GetBaseMySQLDumpCommand(),
|
|
||||||
options,
|
|
||||||
tables_to_dump,
|
|
||||||
pipe_file
|
|
||||||
);
|
|
||||||
|
|
||||||
BuildCredentialsFile();
|
|
||||||
std::string execution_result = Process::execute(execute_command);
|
std::string execution_result = Process::execute(execute_command);
|
||||||
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
if (!execution_result.empty() && IsDumpOutputToConsole()) {
|
||||||
std::cout << execution_result;
|
std::cout << execution_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSys.LoadLogSettingsDefaults();
|
|
||||||
|
|
||||||
if (!pipe_file.empty()) {
|
|
||||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
|
||||||
auto r = File::GetContents(file);
|
|
||||||
if (!r.error.empty()) {
|
|
||||||
LogError("{}", r.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &line: Strings::Split(r.contents, "\n")) {
|
|
||||||
if (Strings::Contains(line, "mysqldump:")) {
|
|
||||||
LogError("{}", line);
|
|
||||||
LogError("Database dump failed. Correct the error before continuing or trying again");
|
|
||||||
LogError("This is to prevent data loss on behalf of the server operator");
|
|
||||||
RemoveSqlBackup();
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tables_to_dump.empty()) {
|
if (!tables_to_dump.empty()) {
|
||||||
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
|
LogInfo("Dumping Tables [{}]", Strings::Trim(tables_to_dump));
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Database dump created at [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
if (IsDumpWithCompression() && !IsDumpOutputToConsole()) {
|
||||||
if (HasCompressionBinary()) {
|
if (HasCompressionBinary()) {
|
||||||
LogInfo("Compression requested. Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
LogInfo("Compression requested... Compressing dump [{}.sql]", GetDumpFileNameWithPath());
|
||||||
|
|
||||||
if (IsTarAvailable()) {
|
if (IsTarAvailable()) {
|
||||||
Process::execute(
|
Process::execute(
|
||||||
@@ -363,7 +343,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
LogInfo("Compressed dump created at [{}.tar.gz]", GetDumpFileNameWithPath());
|
||||||
RemoveSqlBackup();
|
|
||||||
}
|
}
|
||||||
else if (Is7ZipAvailable()) {
|
else if (Is7ZipAvailable()) {
|
||||||
Process::execute(
|
Process::execute(
|
||||||
@@ -374,7 +353,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
LogInfo("Compressed dump created at [{}.zip]", GetDumpFileNameWithPath());
|
||||||
RemoveSqlBackup();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LogInfo("Compression requested, but no available compression binary was found");
|
LogInfo("Compression requested, but no available compression binary was found");
|
||||||
@@ -385,8 +363,6 @@ void DatabaseDumpService::DatabaseDump()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveCredentialsFile();
|
|
||||||
|
|
||||||
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
// LogDebug("[{}] dump-to-console", IsDumpOutputToConsole());
|
||||||
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
// LogDebug("[{}] dump-path", GetSetDumpPath());
|
||||||
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
// LogDebug("[{}] compression", (IsDumpWithCompression() ? "true" : "false"));
|
||||||
@@ -559,48 +535,3 @@ void DatabaseDumpService::SetDumpMercTables(bool dump_merc_tables)
|
|||||||
{
|
{
|
||||||
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
|
DatabaseDumpService::dump_merc_tables = dump_merc_tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseDumpService::RemoveSqlBackup()
|
|
||||||
{
|
|
||||||
std::string file = fmt::format("{}.sql", GetDumpFileNameWithPath());
|
|
||||||
if (File::Exists(file)) {
|
|
||||||
std::filesystem::remove(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveCredentialsFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::BuildCredentialsFile()
|
|
||||||
{
|
|
||||||
auto config = EQEmuConfig::get();
|
|
||||||
std::ofstream out(CREDENTIALS_FILE);
|
|
||||||
if (out.is_open()) {
|
|
||||||
if (IsDumpContentTables() && !config->ContentDbHost.empty()) {
|
|
||||||
out << "[mysqldump]" << std::endl;
|
|
||||||
out << "user=" << config->ContentDbUsername << std::endl;
|
|
||||||
out << "password=" << config->ContentDbPassword << std::endl;
|
|
||||||
out << "host=" << config->ContentDbHost << std::endl;
|
|
||||||
out << "port=" << config->ContentDbPort << std::endl;
|
|
||||||
out << "default-character-set=utf8" << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out << "[mysqldump]" << std::endl;
|
|
||||||
out << "user=" << config->DatabaseUsername << std::endl;
|
|
||||||
out << "password=" << config->DatabasePassword << std::endl;
|
|
||||||
out << "host=" << config->DatabaseHost << std::endl;
|
|
||||||
out << "port=" << config->DatabasePort << std::endl;
|
|
||||||
out << "default-character-set=utf8" << std::endl;
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogError("Failed to open credentials file for writing");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseDumpService::RemoveCredentialsFile()
|
|
||||||
{
|
|
||||||
if (File::Exists(CREDENTIALS_FILE)) {
|
|
||||||
std::filesystem::remove(CREDENTIALS_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
class DatabaseDumpService {
|
class DatabaseDumpService {
|
||||||
public:
|
public:
|
||||||
void DatabaseDump();
|
void Dump();
|
||||||
bool IsDumpAllTables() const;
|
bool IsDumpAllTables() const;
|
||||||
void SetDumpAllTables(bool dump_all_tables);
|
void SetDumpAllTables(bool dump_all_tables);
|
||||||
bool IsDumpWithNoData() const;
|
bool IsDumpWithNoData() const;
|
||||||
@@ -92,9 +92,6 @@ private:
|
|||||||
std::string GetDumpFileNameWithPath();
|
std::string GetDumpFileNameWithPath();
|
||||||
std::string GetSetDumpPath();
|
std::string GetSetDumpPath();
|
||||||
std::string GetQueryServTables();
|
std::string GetQueryServTables();
|
||||||
void RemoveSqlBackup();
|
|
||||||
void BuildCredentialsFile();
|
|
||||||
void RemoveCredentialsFile();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,300 +0,0 @@
|
|||||||
#include <filesystem>
|
|
||||||
#include "database_update.h"
|
|
||||||
#include "../eqemu_logsys.h"
|
|
||||||
#include "../database.h"
|
|
||||||
#include "../strings.h"
|
|
||||||
#include "../rulesys.h"
|
|
||||||
#include "../http/httplib.h"
|
|
||||||
|
|
||||||
#include "database_update_manifest.cpp"
|
|
||||||
#include "database_update_manifest_bots.cpp"
|
|
||||||
#include "database_dump_service.h"
|
|
||||||
|
|
||||||
constexpr int BREAK_LENGTH = 70;
|
|
||||||
|
|
||||||
DatabaseVersion DatabaseUpdate::GetDatabaseVersions()
|
|
||||||
{
|
|
||||||
auto results = m_database->QueryDatabase("SELECT `version`, `bots_version` FROM `db_version` LIMIT 1");
|
|
||||||
if (!results.Success() || !results.RowCount()) {
|
|
||||||
LogError("Failed to read from [db_version] table!");
|
|
||||||
return DatabaseVersion{};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto r = results.begin();
|
|
||||||
|
|
||||||
return DatabaseVersion{
|
|
||||||
.server_database_version = Strings::ToInt(r[0]),
|
|
||||||
.bots_database_version = Strings::ToInt(r[1]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseVersion DatabaseUpdate::GetBinaryDatabaseVersions()
|
|
||||||
{
|
|
||||||
return DatabaseVersion{
|
|
||||||
.server_database_version = CURRENT_BINARY_DATABASE_VERSION,
|
|
||||||
.bots_database_version = (RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// the amount of versions we look-back to ensure we have all migrations
|
|
||||||
// we may not want to force these, but just warn about the look-backs
|
|
||||||
constexpr int LOOK_BACK_AMOUNT = 10;
|
|
||||||
|
|
||||||
// this check will take action
|
|
||||||
void DatabaseUpdate::CheckDbUpdates()
|
|
||||||
{
|
|
||||||
InjectBotsVersionColumn();
|
|
||||||
auto v = GetDatabaseVersions();
|
|
||||||
auto b = GetBinaryDatabaseVersions();
|
|
||||||
if (CheckVersionsUpToDate(v, b)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
|
|
||||||
LogInfo(
|
|
||||||
"Updates ran successfully, setting database version to [{}] from [{}]",
|
|
||||||
b.server_database_version,
|
|
||||||
v.server_database_version
|
|
||||||
);
|
|
||||||
m_database->QueryDatabase(fmt::format("UPDATE `db_version` SET `version` = {}", b.server_database_version));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b.bots_database_version > 0) {
|
|
||||||
if (UpdateManifest(bot_manifest_entries, v.bots_database_version, b.bots_database_version)) {
|
|
||||||
LogInfo(
|
|
||||||
"Updates ran successfully, setting database version to [{}] from [{}]",
|
|
||||||
b.bots_database_version,
|
|
||||||
v.bots_database_version
|
|
||||||
);
|
|
||||||
m_database->QueryDatabase(
|
|
||||||
fmt::format(
|
|
||||||
"UPDATE `db_version` SET `bots_version` = {}",
|
|
||||||
b.bots_database_version
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DatabaseUpdate::GetQueryResult(std::string query)
|
|
||||||
{
|
|
||||||
auto results = m_database->QueryDatabase(query);
|
|
||||||
|
|
||||||
std::vector<std::string> result_lines = {};
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
std::vector<std::string> cols;
|
|
||||||
|
|
||||||
int field_count = results.ColumnCount();
|
|
||||||
cols.reserve(field_count);
|
|
||||||
for (int i = 0; i < field_count; ++i) {
|
|
||||||
if (row[i] != nullptr) {
|
|
||||||
cols.emplace_back(row[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result_lines.emplace_back(Strings::Join(cols, " "));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Strings::Join(result_lines, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_result)
|
|
||||||
{
|
|
||||||
std::string r = Strings::Trim(query_result);
|
|
||||||
if (e.condition == "contains") {
|
|
||||||
return Strings::Contains(r, e.match);
|
|
||||||
}
|
|
||||||
else if (e.condition == "match") {
|
|
||||||
return r == e.match;
|
|
||||||
}
|
|
||||||
else if (e.condition == "missing") {
|
|
||||||
return !Strings::Contains(r, e.match);
|
|
||||||
}
|
|
||||||
else if (e.condition == "empty") {
|
|
||||||
return r.empty();
|
|
||||||
}
|
|
||||||
else if (e.condition == "not_empty") {
|
|
||||||
return !r.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if we ran updates
|
|
||||||
bool DatabaseUpdate::UpdateManifest(
|
|
||||||
std::vector<ManifestEntry> entries,
|
|
||||||
int version_low,
|
|
||||||
int version_high
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::vector<int> missing_migrations = {};
|
|
||||||
if (version_low != version_high) {
|
|
||||||
|
|
||||||
LogSys.DisableMySQLErrorLogs();
|
|
||||||
for (int version = version_low + 1; version <= version_high; ++version) {
|
|
||||||
for (auto &e: entries) {
|
|
||||||
if (e.version == version) {
|
|
||||||
bool has_migration = true;
|
|
||||||
std::string r = GetQueryResult(e.check);
|
|
||||||
if (ShouldRunMigration(e, r)) {
|
|
||||||
has_migration = false;
|
|
||||||
missing_migrations.emplace_back(e.version);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string prefix = fmt::format(
|
|
||||||
"[{}]",
|
|
||||||
has_migration ? "ok" : "missing"
|
|
||||||
);
|
|
||||||
|
|
||||||
LogInfo(
|
|
||||||
"[{}] {:>10} | [{}]",
|
|
||||||
e.version,
|
|
||||||
prefix,
|
|
||||||
e.description
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogSys.EnableMySQLErrorLogs();
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
|
|
||||||
if (!missing_migrations.empty()) {
|
|
||||||
LogInfo("Automatically backing up database before applying updates");
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
auto s = DatabaseDumpService();
|
|
||||||
s.SetDumpAllTables(true);
|
|
||||||
s.SetDumpWithCompression(true);
|
|
||||||
s.DatabaseDump();
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!missing_migrations.empty()) {
|
|
||||||
LogInfo("Running database migrations. Please wait...");
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &m: missing_migrations) {
|
|
||||||
for (auto &e: entries) {
|
|
||||||
if (e.version == m) {
|
|
||||||
bool errored_migration = false;
|
|
||||||
|
|
||||||
auto r = m_database->QueryDatabaseMulti(e.sql);
|
|
||||||
|
|
||||||
// ignore empty query result "errors"
|
|
||||||
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
|
||||||
LogError("(#{}) [{}]", r.ErrorNumber(), r.ErrorMessage());
|
|
||||||
errored_migration = true;
|
|
||||||
|
|
||||||
LogInfo("Required database update failed. This could be a problem");
|
|
||||||
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
|
||||||
|
|
||||||
// user input
|
|
||||||
std::string input;
|
|
||||||
bool gave_input = false;
|
|
||||||
time_t start_time = time(nullptr);
|
|
||||||
time_t wait_time_seconds = 60;
|
|
||||||
|
|
||||||
// spawn a concurrent thread that waits for input from std::cin
|
|
||||||
std::thread t1(
|
|
||||||
[&]() {
|
|
||||||
std::cin >> input;
|
|
||||||
gave_input = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
t1.detach();
|
|
||||||
|
|
||||||
// check the inputReceived flag once every 50ms for 10 seconds
|
|
||||||
while (time(nullptr) < start_time + wait_time_seconds && !gave_input) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
||||||
}
|
|
||||||
|
|
||||||
// prompt for user skip
|
|
||||||
if (Strings::Trim(input) == "y") {
|
|
||||||
errored_migration = false;
|
|
||||||
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo(
|
|
||||||
"[{}] [{}] [{}]",
|
|
||||||
e.version,
|
|
||||||
e.description,
|
|
||||||
(errored_migration ? "error" : "ok")
|
|
||||||
);
|
|
||||||
|
|
||||||
if (errored_migration) {
|
|
||||||
LogError("Fatal | Database migration [{}] failed to run", e.description);
|
|
||||||
LogError("Fatal | Shutting down");
|
|
||||||
std::exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
|
|
||||||
{
|
|
||||||
m_database = db;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
|
||||||
{
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
|
|
||||||
LogInfo(
|
|
||||||
"{:>8} | database [{}] binary [{}] {}",
|
|
||||||
"Server",
|
|
||||||
v.server_database_version,
|
|
||||||
b.server_database_version,
|
|
||||||
(v.server_database_version == b.server_database_version) ? "up to date" : "checking updates"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
|
|
||||||
LogInfo(
|
|
||||||
"{:>8} | database [{}] binary [{}] {}",
|
|
||||||
"Bots",
|
|
||||||
v.bots_database_version,
|
|
||||||
b.bots_database_version,
|
|
||||||
(v.bots_database_version == b.bots_database_version) ? "up to date" : "checking updates"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
|
|
||||||
|
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
|
||||||
|
|
||||||
// server database version is required
|
|
||||||
bool server_up_to_date = v.server_database_version == b.server_database_version;
|
|
||||||
// bots database version is optional, if not enabled then it is always up-to-date
|
|
||||||
bool bots_up_to_date = RuleB(Bots, Enabled) ? v.bots_database_version == b.bots_database_version : true;
|
|
||||||
|
|
||||||
return server_up_to_date && bots_up_to_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks to see if there are pending updates
|
|
||||||
// used by zone to prevent launch or boot loop until updates are applied
|
|
||||||
bool DatabaseUpdate::HasPendingUpdates()
|
|
||||||
{
|
|
||||||
auto v = GetDatabaseVersions();
|
|
||||||
auto b = GetBinaryDatabaseVersions();
|
|
||||||
|
|
||||||
return !CheckVersionsUpToDate(v, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabaseUpdate::InjectBotsVersionColumn()
|
|
||||||
{
|
|
||||||
auto r = m_database->QueryDatabase("show columns from db_version where Field like '%bots_version%'");
|
|
||||||
if (r.RowCount() == 0) {
|
|
||||||
m_database->QueryDatabase("ALTER TABLE db_version ADD bots_version int(11) DEFAULT '0' AFTER version");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#ifndef EQEMU_DATABASE_UPDATE_H
|
|
||||||
#define EQEMU_DATABASE_UPDATE_H
|
|
||||||
|
|
||||||
#include "../database.h"
|
|
||||||
|
|
||||||
struct ManifestEntry {
|
|
||||||
int version{}; // database version of the migration
|
|
||||||
std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
|
||||||
std::string check{}; // query that checks against the condition
|
|
||||||
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
|
||||||
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
|
||||||
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DatabaseVersion {
|
|
||||||
int server_database_version;
|
|
||||||
int bots_database_version;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DatabaseUpdate {
|
|
||||||
public:
|
|
||||||
DatabaseVersion GetDatabaseVersions();
|
|
||||||
DatabaseVersion GetBinaryDatabaseVersions();
|
|
||||||
void CheckDbUpdates();
|
|
||||||
std::string GetQueryResult(std::string query);
|
|
||||||
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
|
|
||||||
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
|
|
||||||
|
|
||||||
DatabaseUpdate *SetDatabase(Database *db);
|
|
||||||
bool HasPendingUpdates();
|
|
||||||
private:
|
|
||||||
Database *m_database;
|
|
||||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
|
||||||
void InjectBotsVersionColumn();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //EQEMU_DATABASE_UPDATE_H
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,84 +0,0 @@
|
|||||||
#include "database_update.h"
|
|
||||||
|
|
||||||
std::vector<ManifestEntry> bot_manifest_entries = {
|
|
||||||
ManifestEntry{
|
|
||||||
.version = 9035,
|
|
||||||
.description = "2022_12_04_bot_archery.sql",
|
|
||||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'archery_setting'",
|
|
||||||
.condition = "empty",
|
|
||||||
.match = "",
|
|
||||||
.sql = R"(
|
|
||||||
ALTER TABLE `bot_data`
|
|
||||||
ADD COLUMN `archery_setting` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0' AFTER `enforce_spell_settings`;
|
|
||||||
)",
|
|
||||||
},
|
|
||||||
ManifestEntry{
|
|
||||||
.version = 9036,
|
|
||||||
.description = "2023_01_19_drop_bot_views.sql",
|
|
||||||
.check = "SHOW TABLES LIKE 'vw_groups'",
|
|
||||||
.condition = "not_empty",
|
|
||||||
.match = "",
|
|
||||||
.sql = R"(
|
|
||||||
DROP VIEW vw_bot_groups;
|
|
||||||
DROP VIEW vw_bot_character_mobs;
|
|
||||||
DROP VIEW vw_groups;
|
|
||||||
DROP VIEW vw_guild_members;
|
|
||||||
DROP TABLE bot_guild_members;
|
|
||||||
|
|
||||||
)",
|
|
||||||
},
|
|
||||||
ManifestEntry{
|
|
||||||
.version = 9037,
|
|
||||||
.description = "2023_01_22_add_name_index.sql",
|
|
||||||
.check = "show index from bot_data WHERE key_name = 'name`",
|
|
||||||
.condition = "",
|
|
||||||
.match = "empty",
|
|
||||||
.sql = R"(
|
|
||||||
create index `name` on bot_data(`name`);
|
|
||||||
)",
|
|
||||||
},
|
|
||||||
ManifestEntry{
|
|
||||||
.version = 9038,
|
|
||||||
.description = "2023_02_16_add_caster_range.sql",
|
|
||||||
.check = "SHOW COLUMNS FROM `bot_data` LIKE 'caster_range'",
|
|
||||||
.condition = "",
|
|
||||||
.match = "empty",
|
|
||||||
.sql = R"(
|
|
||||||
ALTER TABLE `bot_data`
|
|
||||||
ADD COLUMN `caster_range` INT(11) UNSIGNED NOT NULL DEFAULT '300' AFTER `archery_setting`;
|
|
||||||
)",
|
|
||||||
},
|
|
||||||
ManifestEntry{
|
|
||||||
.version = 9039,
|
|
||||||
.description = "2023_03_31_remove_bot_groups.sql",
|
|
||||||
.check = "SHOW TABLES LIKE 'bot_groups'",
|
|
||||||
.condition = "",
|
|
||||||
.match = "not_empty",
|
|
||||||
.sql = R"(
|
|
||||||
SET FOREIGN_KEY_CHECKS = 0;
|
|
||||||
DROP TABLE IF EXISTS `bot_groups`;
|
|
||||||
DROP TABLE IF EXISTS `bot_group_members`;
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
|
||||||
)",
|
|
||||||
},
|
|
||||||
// -- template; copy/paste this when you need to create a new entry
|
|
||||||
// ManifestEntry{
|
|
||||||
// .version = 9228,
|
|
||||||
// .description = "some_new_migration.sql",
|
|
||||||
// .check = "SHOW COLUMNS FROM `table_name` LIKE 'column_name'",
|
|
||||||
// .condition = "empty",
|
|
||||||
// .match = "",
|
|
||||||
// .sql = R"(
|
|
||||||
//
|
|
||||||
//)"
|
|
||||||
};
|
|
||||||
|
|
||||||
// see struct definitions for what each field does
|
|
||||||
// struct ManifestEntry {
|
|
||||||
// int version{}; // database version of the migration
|
|
||||||
// std::string description{}; // description of the migration ex: "add_new_table" or "add_index_to_table"
|
|
||||||
// std::string check{}; // query that checks against the condition
|
|
||||||
// std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
|
||||||
// std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
|
||||||
// std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
|
||||||
// };
|
|
||||||
+1802
-11
File diff suppressed because it is too large
Load Diff
@@ -167,8 +167,8 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
if (Strings::ToInt(row[0]) <= max) {
|
if (atoi(row[0]) <= max) {
|
||||||
instance_id = Strings::ToInt(row[0]);
|
instance_id = atoi(row[0]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
|||||||
max_reserved_instance_id++;
|
max_reserved_instance_id++;
|
||||||
|
|
||||||
for (auto row : results) {
|
for (auto row : results) {
|
||||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
if (max_reserved_instance_id < std::stoul(row[0])) {
|
||||||
instance_id = max_reserved_instance_id;
|
instance_id = max_reserved_instance_id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -301,7 +301,7 @@ uint16 Database::GetInstanceID(uint32 zone_id, uint32 character_id, int16 versio
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return static_cast<uint16>(Strings::ToUnsignedInt(row[0]));
|
return static_cast<uint16>(std::stoul(row[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint16> Database::GetInstanceIDs(uint32 zone_id, uint32 character_id)
|
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) {
|
for (auto row : results) {
|
||||||
l.push_back(static_cast<uint16>(Strings::ToUnsignedInt(row[0])));
|
l.push_back(static_cast<uint16>(std::stoul(row[0])));
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
@@ -409,7 +409,7 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
|||||||
auto zone_id = GetInstanceZoneID(instance_id);
|
auto zone_id = GetInstanceZoneID(instance_id);
|
||||||
auto version = GetInstanceVersion(instance_id);
|
auto version = GetInstanceVersion(instance_id);
|
||||||
|
|
||||||
auto l = RaidMembersRepository::GetWhere(
|
auto l = GroupIdRepository::GetWhere(
|
||||||
*this,
|
*this,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"raidid = {}",
|
"raidid = {}",
|
||||||
@@ -429,6 +429,8 @@ void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id)
|
|||||||
|
|
||||||
void Database::DeleteInstance(uint16 instance_id)
|
void Database::DeleteInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
|
std::string query;
|
||||||
|
|
||||||
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
InstanceListPlayerRepository::DeleteWhere(*this, fmt::format("id = {}", instance_id));
|
||||||
|
|
||||||
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
RespawnTimesRepository::DeleteWhere(*this, fmt::format("instance_id = {}", instance_id));
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ namespace DatabaseSchema {
|
|||||||
{"character_spells", "id"},
|
{"character_spells", "id"},
|
||||||
{"character_task_timers", "character_id"},
|
{"character_task_timers", "character_id"},
|
||||||
{"character_tasks", "charid"},
|
{"character_tasks", "charid"},
|
||||||
{"character_tribute", "character_id"},
|
{"character_tribute", "id"},
|
||||||
{"completed_tasks", "charid"},
|
{"completed_tasks", "charid"},
|
||||||
{"data_buckets", "id"},
|
{"data_buckets", "id"},
|
||||||
{"faction_values", "char_id"},
|
{"faction_values", "char_id"},
|
||||||
@@ -256,7 +256,6 @@ namespace DatabaseSchema {
|
|||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
"chatchannels",
|
"chatchannels",
|
||||||
"chatchannel_reserved_names",
|
|
||||||
"command_settings",
|
"command_settings",
|
||||||
"content_flags",
|
"content_flags",
|
||||||
"db_str",
|
"db_str",
|
||||||
@@ -322,11 +321,13 @@ namespace DatabaseSchema {
|
|||||||
"discord_webhooks",
|
"discord_webhooks",
|
||||||
"dynamic_zone_members",
|
"dynamic_zone_members",
|
||||||
"dynamic_zones",
|
"dynamic_zones",
|
||||||
|
"eventlog",
|
||||||
"expedition_lockouts",
|
"expedition_lockouts",
|
||||||
"expeditions",
|
"expeditions",
|
||||||
"gm_ips",
|
"gm_ips",
|
||||||
"group_id",
|
"group_id",
|
||||||
"group_leaders",
|
"group_leaders",
|
||||||
|
"hackers",
|
||||||
"instance_list",
|
"instance_list",
|
||||||
"ip_exemptions",
|
"ip_exemptions",
|
||||||
"item_tick",
|
"item_tick",
|
||||||
@@ -342,8 +343,6 @@ namespace DatabaseSchema {
|
|||||||
"respawn_times",
|
"respawn_times",
|
||||||
"saylink",
|
"saylink",
|
||||||
"server_scheduled_events",
|
"server_scheduled_events",
|
||||||
"player_event_log_settings",
|
|
||||||
"player_event_logs",
|
|
||||||
"shared_task_activity_state",
|
"shared_task_activity_state",
|
||||||
"shared_task_dynamic_zones",
|
"shared_task_dynamic_zones",
|
||||||
"shared_task_members",
|
"shared_task_members",
|
||||||
@@ -393,6 +392,9 @@ namespace DatabaseSchema {
|
|||||||
"bot_command_settings",
|
"bot_command_settings",
|
||||||
"bot_create_combinations",
|
"bot_create_combinations",
|
||||||
"bot_data",
|
"bot_data",
|
||||||
|
"bot_group_members",
|
||||||
|
"bot_groups",
|
||||||
|
"bot_guild_members",
|
||||||
"bot_heal_rotation_members",
|
"bot_heal_rotation_members",
|
||||||
"bot_heal_rotation_targets",
|
"bot_heal_rotation_targets",
|
||||||
"bot_heal_rotations",
|
"bot_heal_rotations",
|
||||||
|
|||||||
+43
-181
@@ -13,7 +13,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "strings.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@@ -35,8 +34,7 @@
|
|||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore()
|
||||||
{
|
{
|
||||||
mysql = mysql_init(nullptr);
|
mysql_init(&mysql);
|
||||||
mysqlOwner = true;
|
|
||||||
pHost = nullptr;
|
pHost = nullptr;
|
||||||
pUser = nullptr;
|
pUser = nullptr;
|
||||||
pPassword = nullptr;
|
pPassword = nullptr;
|
||||||
@@ -44,7 +42,6 @@ DBcore::DBcore()
|
|||||||
pCompress = false;
|
pCompress = false;
|
||||||
pSSL = false;
|
pSSL = false;
|
||||||
pStatus = Closed;
|
pStatus = Closed;
|
||||||
m_mutex = new Mutex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBcore::~DBcore()
|
DBcore::~DBcore()
|
||||||
@@ -54,10 +51,16 @@ DBcore::~DBcore()
|
|||||||
* are re-using the default database connection pointer when we dont have an
|
* are re-using the default database connection pointer when we dont have an
|
||||||
* external configuration setup ex: (content_database)
|
* external configuration setup ex: (content_database)
|
||||||
*/
|
*/
|
||||||
if (mysqlOwner) {
|
std::string mysql_connection_host;
|
||||||
mysql_close(mysql);
|
if (mysql.host) {
|
||||||
|
mysql_connection_host = mysql.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetOriginHost() != mysql_connection_host) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_close(&mysql);
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
safe_delete_array(pPassword);
|
safe_delete_array(pPassword);
|
||||||
@@ -67,21 +70,20 @@ DBcore::~DBcore()
|
|||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping()
|
||||||
{
|
{
|
||||||
if (!m_mutex->trylock()) {
|
if (!MDatabase.trylock()) {
|
||||||
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
// well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mysql_ping(mysql);
|
mysql_ping(&mysql);
|
||||||
m_mutex->unlock();
|
MDatabase.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLRequestResult DBcore::QueryDatabase(const std::string& query, bool retryOnFailureOnce)
|
MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureOnce)
|
||||||
{
|
{
|
||||||
auto r = QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::DoesTableExist(const std::string& table_name)
|
bool DBcore::DoesTableExist(std::string table_name)
|
||||||
{
|
{
|
||||||
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
|
auto results = QueryDatabase(fmt::format("SHOW TABLES LIKE '{}'", table_name));
|
||||||
|
|
||||||
@@ -93,16 +95,18 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
LockMutex lock(&MDatabase);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
Open();
|
Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// request query. != 0 indicates some kind of error.
|
// request query. != 0 indicates some kind of error.
|
||||||
if (mysql_real_query(mysql, query, querylen) != 0) {
|
if (mysql_real_query(&mysql, query, querylen) != 0) {
|
||||||
unsigned int errorNumber = mysql_errno(mysql);
|
unsigned int errorNumber = mysql_errno(&mysql);
|
||||||
|
|
||||||
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
if (errorNumber == CR_SERVER_GONE_ERROR) {
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
@@ -126,26 +130,26 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||||
|
|
||||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
auto errorBuffer = new char[MYSQL_ERRMSG_SIZE];
|
||||||
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error logging
|
* Error logging
|
||||||
*/
|
*/
|
||||||
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
if (mysql_errno(&mysql) > 0 && strlen(query) > 0) {
|
||||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(&mysql), mysql_error(&mysql), query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// successful query. get results.
|
// successful query. get results.
|
||||||
MYSQL_RES *res = mysql_store_result(mysql);
|
MYSQL_RES *res = mysql_store_result(&mysql);
|
||||||
uint32 rowCount = 0;
|
uint32 rowCount = 0;
|
||||||
|
|
||||||
if (res != nullptr) {
|
if (res != nullptr) {
|
||||||
@@ -154,10 +158,10 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
|
|
||||||
MySQLRequestResult requestResult(
|
MySQLRequestResult requestResult(
|
||||||
res,
|
res,
|
||||||
(uint32) mysql_affected_rows(mysql),
|
(uint32) mysql_affected_rows(&mysql),
|
||||||
rowCount,
|
rowCount,
|
||||||
(uint32) mysql_field_count(mysql),
|
(uint32) mysql_field_count(&mysql),
|
||||||
(uint32) mysql_insert_id(mysql)
|
(uint32) mysql_insert_id(&mysql)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) {
|
||||||
@@ -203,7 +207,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.
|
// No good reason to lock the DB, we only need it in the first place to check char encoding.
|
||||||
// LockMutex lock(&MDatabase);
|
// LockMutex lock(&MDatabase);
|
||||||
return mysql_real_escape_string(mysql, tobuf, frombuf, fromlen);
|
return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DBcore::Open(
|
bool DBcore::Open(
|
||||||
@@ -218,7 +222,7 @@ bool DBcore::Open(
|
|||||||
bool iSSL
|
bool iSSL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LockMutex lock(m_mutex);
|
LockMutex lock(&MDatabase);
|
||||||
safe_delete_array(pHost);
|
safe_delete_array(pHost);
|
||||||
safe_delete_array(pUser);
|
safe_delete_array(pUser);
|
||||||
safe_delete_array(pPassword);
|
safe_delete_array(pPassword);
|
||||||
@@ -238,13 +242,13 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
}
|
||||||
LockMutex lock(m_mutex);
|
LockMutex lock(&MDatabase);
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (GetStatus() == Error) {
|
if (GetStatus() == Error) {
|
||||||
mysql_close(mysql);
|
mysql_close(&mysql);
|
||||||
mysql_init(mysql); // Initialize structure again
|
mysql_init(&mysql); // Initialize structure again
|
||||||
}
|
}
|
||||||
if (!pHost) {
|
if (!pHost) {
|
||||||
return false;
|
return false;
|
||||||
@@ -261,7 +265,7 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
if (pSSL) {
|
if (pSSL) {
|
||||||
flags |= CLIENT_SSL;
|
flags |= CLIENT_SSL;
|
||||||
}
|
}
|
||||||
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
||||||
pStatus = Connected;
|
pStatus = Connected;
|
||||||
|
|
||||||
std::string connected_origin_host = pHost;
|
std::string connected_origin_host = pHost;
|
||||||
@@ -271,16 +275,21 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (errnum) {
|
if (errnum) {
|
||||||
*errnum = mysql_errno(mysql);
|
*errnum = mysql_errno(&mysql);
|
||||||
}
|
}
|
||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(mysql), mysql_error(mysql));
|
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
|
||||||
}
|
}
|
||||||
pStatus = Error;
|
pStatus = Error;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DBcore::SetMysql(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
DBcore::mysql = *mysql;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string &DBcore::GetOriginHost() const
|
const std::string &DBcore::GetOriginHost() const
|
||||||
{
|
{
|
||||||
return origin_host;
|
return origin_host;
|
||||||
@@ -290,150 +299,3 @@ void DBcore::SetOriginHost(const std::string &origin_host)
|
|||||||
{
|
{
|
||||||
DBcore::origin_host = origin_host;
|
DBcore::origin_host = origin_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DBcore::Escape(const std::string& s)
|
|
||||||
{
|
|
||||||
const std::size_t s_len = s.length();
|
|
||||||
std::vector<char> temp((s_len * 2) + 1, '\0');
|
|
||||||
mysql_real_escape_string(mysql, temp.data(), s.c_str(), s_len);
|
|
||||||
|
|
||||||
return temp.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DBcore::SetMutex(Mutex *mutex)
|
|
||||||
{
|
|
||||||
safe_delete(m_mutex);
|
|
||||||
|
|
||||||
DBcore::m_mutex = mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// executes multiple statements in one query
|
|
||||||
// do not use this in application logic
|
|
||||||
// this was built and maintained for database migrations only
|
|
||||||
MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
|
||||||
{
|
|
||||||
SetMultiStatementsOn();
|
|
||||||
|
|
||||||
BenchTimer timer;
|
|
||||||
timer.reset();
|
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
|
||||||
if (pStatus != Connected) {
|
|
||||||
Open();
|
|
||||||
}
|
|
||||||
auto r = MySQLRequestResult{};
|
|
||||||
|
|
||||||
int status = mysql_real_query(mysql, query.c_str(), query.length());
|
|
||||||
|
|
||||||
// process single result
|
|
||||||
if (status != 0) {
|
|
||||||
unsigned int error_number = mysql_errno(mysql);
|
|
||||||
|
|
||||||
if (error_number == CR_SERVER_GONE_ERROR) {
|
|
||||||
pStatus = Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// error logging
|
|
||||||
if (mysql_errno(mysql) > 0 && query.length() > 0 && mysql_errno(mysql) != 1065) {
|
|
||||||
std::string error_raw = fmt::format("{}", mysql_error(mysql));
|
|
||||||
std::string mysql_err = Strings::Trim(error_raw);
|
|
||||||
std::string clean_query = Strings::Replace(query, "\n", "");
|
|
||||||
LogMySQLError("[{}] ({}) query [{}]", mysql_err, mysql_errno(mysql), clean_query);
|
|
||||||
|
|
||||||
MYSQL_RES *res = mysql_store_result(mysql);
|
|
||||||
|
|
||||||
uint32 row_count = 0;
|
|
||||||
if (res) {
|
|
||||||
row_count = (uint32) mysql_num_rows(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
r = MySQLRequestResult(
|
|
||||||
res,
|
|
||||||
(uint32) mysql_affected_rows(mysql),
|
|
||||||
row_count,
|
|
||||||
(uint32) mysql_field_count(mysql),
|
|
||||||
(uint32) mysql_insert_id(mysql)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string error_message = mysql_error(mysql);
|
|
||||||
r.SetErrorMessage(error_message);
|
|
||||||
r.SetErrorNumber(mysql_errno(mysql));
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
mysql_free_result(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetMultiStatementsOff();
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
// there could be a query with a semicolon in the actual data, this is best effort for
|
|
||||||
// logging / display purposes
|
|
||||||
// rare that we see this when this is only used in DDL statements
|
|
||||||
auto pieces = Strings::Split(query, ";");
|
|
||||||
|
|
||||||
// process each statement result
|
|
||||||
do {
|
|
||||||
uint32 row_count = 0;
|
|
||||||
MYSQL_RES *res = mysql_store_result(mysql);
|
|
||||||
|
|
||||||
r = MySQLRequestResult(
|
|
||||||
res,
|
|
||||||
(uint32) mysql_affected_rows(mysql),
|
|
||||||
row_count,
|
|
||||||
(uint32) mysql_field_count(mysql),
|
|
||||||
(uint32) mysql_insert_id(mysql)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pieces.size() >= index) {
|
|
||||||
auto piece = pieces[index];
|
|
||||||
LogMySQLQuery(
|
|
||||||
"{} -- ({} row{} affected) ({}s)",
|
|
||||||
piece,
|
|
||||||
r.RowsAffected(),
|
|
||||||
r.RowsAffected() == 1 ? "" : "s",
|
|
||||||
std::to_string(timer.elapsed())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
row_count = (uint32) mysql_num_rows(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// more results? -1 = no, >0 = error, 0 = yes (keep looping)
|
|
||||||
if ((status = mysql_next_result(mysql)) > 0) {
|
|
||||||
if (mysql_errno(mysql) > 0) {
|
|
||||||
LogMySQLError("[{}] [{}]", mysql_errno(mysql), mysql_error(mysql));
|
|
||||||
}
|
|
||||||
|
|
||||||
mysql_free_result(res);
|
|
||||||
|
|
||||||
// error logging
|
|
||||||
std::string error_message = mysql_error(mysql);
|
|
||||||
r.SetErrorMessage(error_message);
|
|
||||||
r.SetErrorNumber(mysql_errno(mysql));
|
|
||||||
|
|
||||||
SetMultiStatementsOff();
|
|
||||||
|
|
||||||
// we handle errors elsewhere
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
mysql_free_result(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
} while (status == 0);
|
|
||||||
|
|
||||||
SetMultiStatementsOff();
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|||||||
+7
-30
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
@@ -24,26 +23,19 @@ public:
|
|||||||
~DBcore();
|
~DBcore();
|
||||||
eStatus GetStatus() { return pStatus; }
|
eStatus GetStatus() { return pStatus; }
|
||||||
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce = true);
|
||||||
MySQLRequestResult QueryDatabase(const std::string& query, bool retryOnFailureOnce = true);
|
MySQLRequestResult QueryDatabase(std::string query, bool retryOnFailureOnce = true);
|
||||||
MySQLRequestResult QueryDatabaseMulti(const std::string &query);
|
|
||||||
void TransactionBegin();
|
void TransactionBegin();
|
||||||
void TransactionCommit();
|
void TransactionCommit();
|
||||||
void TransactionRollback();
|
void TransactionRollback();
|
||||||
std::string Escape(const std::string& s);
|
|
||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
void ping();
|
void ping();
|
||||||
|
MYSQL *getMySQL() { return &mysql; }
|
||||||
|
void SetMysql(MYSQL *mysql);
|
||||||
|
|
||||||
const std::string &GetOriginHost() const;
|
const std::string &GetOriginHost() const;
|
||||||
void SetOriginHost(const std::string &origin_host);
|
void SetOriginHost(const std::string &origin_host);
|
||||||
|
|
||||||
bool DoesTableExist(const std::string& table_name);
|
bool DoesTableExist(std::string table_name);
|
||||||
|
|
||||||
void SetMySQL(const DBcore &o)
|
|
||||||
{
|
|
||||||
mysql = o.mysql;
|
|
||||||
mysqlOwner = false;
|
|
||||||
}
|
|
||||||
void SetMutex(Mutex *mutex);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Open(
|
bool Open(
|
||||||
@@ -61,13 +53,10 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||||
|
|
||||||
MYSQL* mysql;
|
MYSQL mysql;
|
||||||
bool mysqlOwner;
|
Mutex MDatabase;
|
||||||
Mutex *m_mutex;
|
|
||||||
eStatus pStatus;
|
eStatus pStatus;
|
||||||
|
|
||||||
std::mutex m_query_lock{};
|
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
char *pHost;
|
char *pHost;
|
||||||
@@ -78,20 +67,8 @@ private:
|
|||||||
uint32 pPort;
|
uint32 pPort;
|
||||||
bool pSSL;
|
bool pSSL;
|
||||||
|
|
||||||
// allows multiple queries to be executed within the same query
|
|
||||||
// do not use this under normal operation
|
|
||||||
// we use this during database migrations only currently
|
|
||||||
void SetMultiStatementsOn()
|
|
||||||
{
|
|
||||||
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
// disables multiple statements to be executed in one query
|
|
||||||
void SetMultiStatementsOff()
|
|
||||||
{
|
|
||||||
mysql_set_server_option(mysql, MYSQL_OPTION_MULTI_STATEMENTS_OFF);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+82
-32
@@ -19,7 +19,8 @@
|
|||||||
|
|
||||||
#include "deity.h"
|
#include "deity.h"
|
||||||
|
|
||||||
EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
|
||||||
|
EQ::deity::DeityTypeBit EQ::deity::ConvertDeityTypeToDeityTypeBit(DeityType deity_type)
|
||||||
{
|
{
|
||||||
switch (deity_type) {
|
switch (deity_type) {
|
||||||
case DeityBertoxxulous:
|
case DeityBertoxxulous:
|
||||||
@@ -59,41 +60,90 @@ EQ::deity::DeityTypeBit EQ::deity::GetDeityBitmask(DeityType deity_type)
|
|||||||
return bit_DeityAgnostic;
|
return bit_DeityAgnostic;
|
||||||
default:
|
default:
|
||||||
return bit_DeityAll;
|
return bit_DeityAll;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<EQ::deity::DeityType, std::string>& EQ::deity::GetDeityMap()
|
|
||||||
{
|
|
||||||
static const std::map<EQ::deity::DeityType, std::string> deity_map = {
|
|
||||||
{ DeityAgnostic, "Agnostic" },
|
|
||||||
{ DeityAgnostic_LB, "Agnostic" },
|
|
||||||
{ DeityBertoxxulous, "Bertoxxulous" },
|
|
||||||
{ DeityBrellSirilis, "Brell Serilis" },
|
|
||||||
{ DeityBristlebane, "Bristlebane" },
|
|
||||||
{ DeityCazicThule, "Cazic-Thule" },
|
|
||||||
{ DeityErollisiMarr, "Erollisi Marr" },
|
|
||||||
{ DeityInnoruuk, "Innoruuk" },
|
|
||||||
{ DeityKarana, "Karana" },
|
|
||||||
{ DeityMithanielMarr, "Mithaniel Marr" },
|
|
||||||
{ DeityPrexus, "Prexus" },
|
|
||||||
{ DeityQuellious, "Quellious" },
|
|
||||||
{ DeityRallosZek, "Rallos Zek" },
|
|
||||||
{ DeityRodcetNife, "Rodcet Nife" },
|
|
||||||
{ DeitySolusekRo, "Solusek Ro" },
|
|
||||||
{ DeityTheTribunal, "The Tribunal" },
|
|
||||||
{ DeityTunare, "Tunare" },
|
|
||||||
{ DeityVeeshan, "Veeshan" }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return deity_map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQ::deity::GetDeityName(DeityType deity_type)
|
EQ::deity::DeityType EQ::deity::ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit)
|
||||||
{
|
{
|
||||||
|
switch (deity_type_bit) {
|
||||||
if (EQ::deity::GetDeityMap().find(deity_type) != EQ::deity::GetDeityMap().end()) {
|
case bit_DeityAgnostic:
|
||||||
return EQ::deity::GetDeityMap().find(deity_type)->second;
|
return DeityAgnostic;
|
||||||
|
case bit_DeityBertoxxulous:
|
||||||
|
return DeityBertoxxulous;
|
||||||
|
case bit_DeityBrellSirilis:
|
||||||
|
return DeityBrellSirilis;
|
||||||
|
case bit_DeityCazicThule:
|
||||||
|
return DeityCazicThule;
|
||||||
|
case bit_DeityErollisiMarr:
|
||||||
|
return DeityErollisiMarr;
|
||||||
|
case bit_DeityBristlebane:
|
||||||
|
return DeityBristlebane;
|
||||||
|
case bit_DeityInnoruuk:
|
||||||
|
return DeityInnoruuk;
|
||||||
|
case bit_DeityKarana:
|
||||||
|
return DeityKarana;
|
||||||
|
case bit_DeityMithanielMarr:
|
||||||
|
return DeityMithanielMarr;
|
||||||
|
case bit_DeityPrexus:
|
||||||
|
return DeityPrexus;
|
||||||
|
case bit_DeityQuellious:
|
||||||
|
return DeityQuellious;
|
||||||
|
case bit_DeityRallosZek:
|
||||||
|
return DeityRallosZek;
|
||||||
|
case bit_DeityRodcetNife:
|
||||||
|
return DeityRodcetNife;
|
||||||
|
case bit_DeitySolusekRo:
|
||||||
|
return DeitySolusekRo;
|
||||||
|
case bit_DeityTheTribunal:
|
||||||
|
return DeityTheTribunal;
|
||||||
|
case bit_DeityTunare:
|
||||||
|
return DeityTunare;
|
||||||
|
case bit_DeityVeeshan:
|
||||||
|
return DeityVeeshan;
|
||||||
|
default:
|
||||||
|
return DeityUnknown;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string();
|
const char* EQ::deity::DeityName(DeityType deity_type)
|
||||||
|
{
|
||||||
|
switch (deity_type) {
|
||||||
|
case DeityBertoxxulous:
|
||||||
|
return "Bertoxxulous";
|
||||||
|
case DeityBrellSirilis:
|
||||||
|
return "Brell Serilis";
|
||||||
|
case DeityCazicThule:
|
||||||
|
return "Cazic-Thule";
|
||||||
|
case DeityErollisiMarr:
|
||||||
|
return "Erollisi Marr";
|
||||||
|
case DeityBristlebane:
|
||||||
|
return "Bristlebane";
|
||||||
|
case DeityInnoruuk:
|
||||||
|
return "Innoruuk";
|
||||||
|
case DeityKarana:
|
||||||
|
return "Karana";
|
||||||
|
case DeityMithanielMarr:
|
||||||
|
return "Mithaniel Marr";
|
||||||
|
case DeityPrexus:
|
||||||
|
return "Prexus";
|
||||||
|
case DeityQuellious:
|
||||||
|
return "Quellious";
|
||||||
|
case DeityRallosZek:
|
||||||
|
return "Rallos Zek";
|
||||||
|
case DeityRodcetNife:
|
||||||
|
return "Rodcet Nife";
|
||||||
|
case DeitySolusekRo:
|
||||||
|
return "Solusek Ro";
|
||||||
|
case DeityTheTribunal:
|
||||||
|
return "The Tribunal";
|
||||||
|
case DeityTunare:
|
||||||
|
return "Tunare";
|
||||||
|
case DeityVeeshan:
|
||||||
|
return "Veeshan";
|
||||||
|
case DeityAgnostic_LB:
|
||||||
|
case DeityAgnostic:
|
||||||
|
return "Agnostic";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-6
@@ -21,8 +21,6 @@
|
|||||||
#define COMMON_DEITY_H
|
#define COMMON_DEITY_H
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
@@ -51,6 +49,7 @@ namespace EQ
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum DeityTypeBit : uint32 {
|
enum DeityTypeBit : uint32 {
|
||||||
|
bit_DeityNone = 0x00000000,
|
||||||
bit_DeityAgnostic = 0x00000001,
|
bit_DeityAgnostic = 0x00000001,
|
||||||
bit_DeityBertoxxulous = 0x00000002,
|
bit_DeityBertoxxulous = 0x00000002,
|
||||||
bit_DeityBrellSirilis = 0x00000004,
|
bit_DeityBrellSirilis = 0x00000004,
|
||||||
@@ -68,12 +67,12 @@ namespace EQ
|
|||||||
bit_DeityTheTribunal = 0x00004000,
|
bit_DeityTheTribunal = 0x00004000,
|
||||||
bit_DeityTunare = 0x00008000,
|
bit_DeityTunare = 0x00008000,
|
||||||
bit_DeityVeeshan = 0x00010000,
|
bit_DeityVeeshan = 0x00010000,
|
||||||
bit_DeityAll = UINT32_MAX
|
bit_DeityAll = 0xFFFFFFFF
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DeityTypeBit GetDeityBitmask(DeityType deity_type);
|
extern DeityTypeBit ConvertDeityTypeToDeityTypeBit(DeityType deity_type);
|
||||||
extern std::string GetDeityName(DeityType deity_type);
|
extern DeityType ConvertDeityTypeBitToDeityType(DeityTypeBit deity_type_bit);
|
||||||
extern const std::map<DeityType, std::string>& GetDeityMap();
|
extern const char* DeityName(DeityType deity_type);
|
||||||
|
|
||||||
} /*deity*/
|
} /*deity*/
|
||||||
|
|
||||||
|
|||||||
+16
-90
@@ -1,17 +1,22 @@
|
|||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <cereal/archives/binary.hpp>
|
|
||||||
#include "discord.h"
|
#include "discord.h"
|
||||||
#include "../http/httplib.h"
|
#include "../http/httplib.h"
|
||||||
#include "../json/json.h"
|
#include "../json/json.h"
|
||||||
#include "../strings.h"
|
#include "../strings.h"
|
||||||
#include "../eqemu_logsys.h"
|
#include "../eqemu_logsys.h"
|
||||||
#include "../events/player_event_logs.h"
|
|
||||||
|
|
||||||
constexpr int MAX_RETRIES = 10;
|
constexpr int MAX_RETRIES = 10;
|
||||||
|
|
||||||
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
|
||||||
{
|
{
|
||||||
if (!ValidateWebhookUrl(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);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,10 +28,13 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
std::string endpoint = Strings::Replace(webhook_url, base_url, "");
|
||||||
|
|
||||||
// client
|
// client
|
||||||
httplib::Client cli(base_url);
|
httplib::Client cli(base_url.c_str());
|
||||||
cli.set_connection_timeout(0, 15000000); // 15 sec
|
cli.set_connection_timeout(0, 15000000); // 15 sec
|
||||||
cli.set_read_timeout(15, 0); // 15 seconds
|
cli.set_read_timeout(15, 0); // 15 seconds
|
||||||
cli.set_write_timeout(15, 0); // 15 seconds
|
cli.set_write_timeout(15, 0); // 15 seconds
|
||||||
|
httplib::Headers headers = {
|
||||||
|
{"Content-Type", "application/json"}
|
||||||
|
};
|
||||||
|
|
||||||
// payload
|
// payload
|
||||||
Json::Value p;
|
Json::Value p;
|
||||||
@@ -38,9 +46,9 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
int retries = 0;
|
int retries = 0;
|
||||||
int retry_timer = 1000;
|
int retry_timer = 1000;
|
||||||
while (retry) {
|
while (retry) {
|
||||||
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
|
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
|
||||||
if (res->status != 200 && res->status != 204) {
|
if (res->status != 200 && res->status != 204) {
|
||||||
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
|
LogError("Code [{}] Error [{}]", res->status, res->body);
|
||||||
}
|
}
|
||||||
if (res->status == 429) {
|
if (res->status == 429) {
|
||||||
if (!res->body.empty()) {
|
if (!res->body.empty()) {
|
||||||
@@ -54,7 +62,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
|
|||||||
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
retry_timer = Strings::ToInt(response["retry_after"].asString()) + 500;
|
retry_timer = std::stoi(response["retry_after"].asString()) + 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
|
||||||
@@ -73,71 +81,6 @@ 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
|
|
||||||
|
|
||||||
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)
|
std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
|
||||||
{
|
{
|
||||||
if (category_id == Logs::LogCategory::MySQLQuery) {
|
if (category_id == Logs::LogCategory::MySQLQuery) {
|
||||||
@@ -146,20 +89,3 @@ std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string
|
|||||||
|
|
||||||
return message + "\n";
|
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,16 +4,11 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
#include "../http/httplib.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../events/player_events.h"
|
|
||||||
|
|
||||||
class Discord {
|
class Discord {
|
||||||
public:
|
public:
|
||||||
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
|
||||||
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
|
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,6 +1,7 @@
|
|||||||
#include "discord_manager.h"
|
#include "discord_manager.h"
|
||||||
#include "../../common/discord/discord.h"
|
#include "../common/discord/discord.h"
|
||||||
#include "../events/player_event_logs.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
|
#include "../common/strings.h"
|
||||||
|
|
||||||
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
|
||||||
{
|
{
|
||||||
@@ -37,7 +38,7 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
message,
|
message,
|
||||||
webhook.webhook_url
|
webhook.webhook_url
|
||||||
);
|
);
|
||||||
message.clear();
|
message = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
message += m;
|
message += m;
|
||||||
@@ -51,9 +52,10 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
webhook.webhook_url
|
webhook.webhook_url
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
message.clear();
|
message = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// final flush
|
// final flush
|
||||||
if (!message.empty()) {
|
if (!message.empty()) {
|
||||||
Discord::SendWebhookMessage(
|
Discord::SendWebhookMessage(
|
||||||
@@ -65,11 +67,3 @@ void DiscordManager::ProcessMessageQueue()
|
|||||||
webhook_message_queue.clear();
|
webhook_message_queue.clear();
|
||||||
webhook_queue_lock.unlock();
|
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,15 +4,12 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../../common/types.h"
|
#include "../common/types.h"
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../events/player_events.h"
|
|
||||||
|
|
||||||
class DiscordManager {
|
class DiscordManager {
|
||||||
public:
|
public:
|
||||||
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
|
||||||
void ProcessMessageQueue();
|
void ProcessMessageQueue();
|
||||||
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
|
|
||||||
private:
|
private:
|
||||||
std::mutex webhook_queue_lock{};
|
std::mutex webhook_queue_lock{};
|
||||||
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
|
||||||
+34
-35
@@ -197,11 +197,11 @@ const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetLanguageName(int language_id)
|
std::string EQ::constants::GetLanguageName(int language_id)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
if (EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
||||||
return std::string();
|
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetLanguageMap().find(language_id)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
|
const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
|
||||||
@@ -220,11 +220,11 @@ const std::map<uint32, std::string>& EQ::constants::GetLDoNThemeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
|
std::string EQ::constants::GetLDoNThemeName(uint32 theme_id)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
|
if (EQ::ValueWithin(theme_id, LDoNThemes::Unused, LDoNThemes::TAK)) {
|
||||||
return std::string();
|
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetLDoNThemeMap().find(theme_id)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
||||||
@@ -243,11 +243,11 @@ const std::map<int8, std::string>& EQ::constants::GetFlyModeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
std::string EQ::constants::GetFlyModeName(int8 flymode_id)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
|
if (EQ::ValueWithin(flymode_id, GravityBehavior::Ground, GravityBehavior::LevitateWhileRunning)) {
|
||||||
return std::string();
|
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
|
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
|
||||||
@@ -365,11 +365,11 @@ const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
|
std::string EQ::constants::GetConsiderLevelName(uint8 faction_consider_level)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(faction_consider_level, ConsiderLevel::Ally, ConsiderLevel::Scowls)) {
|
if (EQ::constants::GetConsiderLevelMap().find(faction_consider_level) != EQ::constants::GetConsiderLevelMap().end()) {
|
||||||
return std::string();;
|
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetConsiderLevelMap().find(faction_consider_level)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
||||||
@@ -386,11 +386,11 @@ const std::map<uint8, std::string>& EQ::constants::GetEnvironmentalDamageMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
|
std::string EQ::constants::GetEnvironmentalDamageName(uint8 damage_type)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
|
if (EQ::ValueWithin(damage_type, EnvironmentalDamage::Lava, EnvironmentalDamage::Trap)) {
|
||||||
return std::string();
|
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetEnvironmentalDamageMap().find(damage_type)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
||||||
@@ -407,11 +407,11 @@ const std::map<uint8, std::string>& EQ::constants::GetStuckBehaviorMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
|
std::string EQ::constants::GetStuckBehaviorName(uint8 behavior_id)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
|
if (EQ::ValueWithin(behavior_id, StuckBehavior::RunToTarget, StuckBehavior::EvadeCombat)) {
|
||||||
return std::string();
|
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetStuckBehaviorMap().find(behavior_id)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
||||||
@@ -429,11 +429,11 @@ const std::map<uint8, std::string>& EQ::constants::GetSpawnAnimationMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
|
if (EQ::ValueWithin(animation_id, SpawnAnimations::Standing, SpawnAnimations::Looting)) {
|
||||||
return std::string();
|
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
||||||
@@ -507,12 +507,11 @@ const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetObjectTypeName(int object_type)
|
std::string EQ::constants::GetObjectTypeName(int object_type)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
if (EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
||||||
return std::string();
|
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
||||||
@@ -528,11 +527,11 @@ const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
|
std::string EQ::constants::GetWeatherTypeName(uint8 weather_type)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
if (EQ::ValueWithin(weather_type, WeatherTypes::None, WeatherTypes::Snowing)) {
|
||||||
return std::string();
|
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetWeatherTypeMap().find(weather_type)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
||||||
@@ -554,11 +553,11 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteEventTypeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
std::string EQ::constants::GetEmoteEventTypeName(uint8 emote_event_type)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
if (EQ::ValueWithin(emote_event_type, EmoteEventTypes::LeaveCombat, EmoteEventTypes::OnDespawn)) {
|
||||||
return std::string();
|
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetEmoteEventTypeMap().find(emote_event_type)->second;
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
||||||
@@ -574,9 +573,9 @@ const std::map<uint8, std::string> &EQ::constants::GetEmoteTypeMap()
|
|||||||
|
|
||||||
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
if (EQ::ValueWithin(emote_type, EmoteTypes::Emote, EmoteTypes::Proximity)) {
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|||||||
@@ -593,29 +593,4 @@ enum class ApplySpellType {
|
|||||||
Raid
|
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*/
|
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||||
|
|||||||
@@ -316,7 +316,6 @@ N(OP_LootRequest),
|
|||||||
N(OP_ManaChange),
|
N(OP_ManaChange),
|
||||||
N(OP_ManaUpdate),
|
N(OP_ManaUpdate),
|
||||||
N(OP_MarkNPC),
|
N(OP_MarkNPC),
|
||||||
N(OP_MarkRaidNPC),
|
|
||||||
N(OP_Marquee),
|
N(OP_Marquee),
|
||||||
N(OP_MemorizeSpell),
|
N(OP_MemorizeSpell),
|
||||||
N(OP_Mend),
|
N(OP_Mend),
|
||||||
@@ -399,8 +398,6 @@ N(OP_PVPLeaderBoardRequest),
|
|||||||
N(OP_PVPStats),
|
N(OP_PVPStats),
|
||||||
N(OP_QueryResponseThing),
|
N(OP_QueryResponseThing),
|
||||||
N(OP_QueryUCSServerStatus),
|
N(OP_QueryUCSServerStatus),
|
||||||
N(OP_RaidDelegateAbility),
|
|
||||||
N(OP_RaidClearNPCMarks),
|
|
||||||
N(OP_RaidInvite),
|
N(OP_RaidInvite),
|
||||||
N(OP_RaidJoin),
|
N(OP_RaidJoin),
|
||||||
N(OP_RaidUpdate),
|
N(OP_RaidUpdate),
|
||||||
|
|||||||
+2
-28
@@ -79,8 +79,6 @@
|
|||||||
#define ANIM_DEATH 0x73
|
#define ANIM_DEATH 0x73
|
||||||
#define ANIM_LOOT 0x69
|
#define ANIM_LOOT 0x69
|
||||||
|
|
||||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eaStanding = 0,
|
eaStanding = 0,
|
||||||
eaSitting, //1
|
eaSitting, //1
|
||||||
@@ -1017,7 +1015,8 @@ enum Anonymity : uint8
|
|||||||
Roleplaying
|
Roleplaying
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ZoningMessage : int8 {
|
enum ZoningMessage : int8
|
||||||
|
{
|
||||||
ZoneNoMessage = 0,
|
ZoneNoMessage = 0,
|
||||||
ZoneSuccess = 1,
|
ZoneSuccess = 1,
|
||||||
ZoneNotReady = -1,
|
ZoneNotReady = -1,
|
||||||
@@ -1027,29 +1026,4 @@ enum ZoningMessage : int8 {
|
|||||||
ZoneNoExperience = -7
|
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
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ScribeSpellActions
|
|
||||||
{
|
|
||||||
Scribe,
|
|
||||||
Memorize,
|
|
||||||
Unmemorize
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
+1
-1
@@ -129,7 +129,7 @@ namespace EQ
|
|||||||
|
|
||||||
LookupEntry(const LookupEntry *lookup_entry) { }
|
LookupEntry(const LookupEntry *lookup_entry) { }
|
||||||
LookupEntry(
|
LookupEntry(
|
||||||
const InventoryTypeSize_Struct& InventoryTypeSize,
|
InventoryTypeSize_Struct InventoryTypeSize,
|
||||||
uint64 EquipmentBitmask,
|
uint64 EquipmentBitmask,
|
||||||
uint64 GeneralBitmask,
|
uint64 GeneralBitmask,
|
||||||
uint64 CursorBitmask,
|
uint64 CursorBitmask,
|
||||||
|
|||||||
@@ -236,6 +236,26 @@ uint32 EQApplicationPacket::serialize(uint16 opcode, unsigned char *dest) const
|
|||||||
return size+OpCodeBytes;
|
return size+OpCodeBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*EQProtocolPacket::EQProtocolPacket(uint16 op, const unsigned char *buf, uint32 len)
|
||||||
|
: BasePacket(buf, len),
|
||||||
|
opcode(op)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint32 offset;
|
||||||
|
opcode=ntohs(*(const uint16 *)buf);
|
||||||
|
offset=2;
|
||||||
|
|
||||||
|
if (len-offset) {
|
||||||
|
pBuffer= new unsigned char[len-offset];
|
||||||
|
memcpy(pBuffer,buf+offset,len-offset);
|
||||||
|
size=len-offset;
|
||||||
|
} else {
|
||||||
|
pBuffer=nullptr;
|
||||||
|
size=0;
|
||||||
|
}
|
||||||
|
OpMgr=&RawOpcodeManager;
|
||||||
|
}*/
|
||||||
|
|
||||||
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
|
bool EQProtocolPacket::combine(const EQProtocolPacket *rhs)
|
||||||
{
|
{
|
||||||
bool result=false;
|
bool result=false;
|
||||||
@@ -267,6 +287,74 @@ bool result=false;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
this is the code to do app-layer combining, instead of protocol layer.
|
||||||
|
this was taken out due to complex interactions with the opcode manager,
|
||||||
|
and will require a bit more thinking (likely moving into EQStream) to
|
||||||
|
get running again... but might be a good thing some day.
|
||||||
|
|
||||||
|
bool EQApplicationPacket::combine(const EQApplicationPacket *rhs)
|
||||||
|
{
|
||||||
|
uint32 newsize=0, offset=0;
|
||||||
|
unsigned char *tmpbuffer=nullptr;
|
||||||
|
|
||||||
|
if (opcode!=OP_AppCombined) {
|
||||||
|
newsize=app_opcode_size+size+(size>254?3:1)+app_opcode_size+rhs->size+(rhs->size>254?3:1);
|
||||||
|
tmpbuffer=new unsigned char [newsize];
|
||||||
|
offset=0;
|
||||||
|
if (size>254) {
|
||||||
|
tmpbuffer[offset++]=0xff;
|
||||||
|
*(uint16 *)(tmpbuffer+offset)=htons(size);
|
||||||
|
offset+=1;
|
||||||
|
} else {
|
||||||
|
tmpbuffer[offset++]=size;
|
||||||
|
}
|
||||||
|
offset+=serialize(tmpbuffer+offset);
|
||||||
|
} else {
|
||||||
|
newsize=size+app_opcode_size+rhs->size+(rhs->size>254?3:1);
|
||||||
|
tmpbuffer=new unsigned char [newsize];
|
||||||
|
memcpy(tmpbuffer,pBuffer,size);
|
||||||
|
offset=size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rhs->size>254) {
|
||||||
|
tmpbuffer[offset++]=0xff;
|
||||||
|
*(uint16 *)(tmpbuffer+offset)=htons(rhs->size);
|
||||||
|
offset+=1;
|
||||||
|
} else {
|
||||||
|
tmpbuffer[offset++]=rhs->size;
|
||||||
|
}
|
||||||
|
offset+=rhs->serialize(tmpbuffer+offset);
|
||||||
|
|
||||||
|
size=offset;
|
||||||
|
opcode=OP_AppCombined;
|
||||||
|
|
||||||
|
delete[] pBuffer;
|
||||||
|
pBuffer=tmpbuffer;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool EQProtocolPacket::ValidateCRC(const unsigned char *buffer, int length, uint32 Key)
|
||||||
|
{
|
||||||
|
bool valid=false;
|
||||||
|
// OP_SessionRequest, OP_SessionResponse, OP_OutOfSession are not CRC'd
|
||||||
|
if (buffer[0]==0x00 && (buffer[1]==OP_SessionRequest || buffer[1]==OP_SessionResponse || buffer[1]==OP_OutOfSession)) {
|
||||||
|
valid=true;
|
||||||
|
} else {
|
||||||
|
uint16 comp_crc=CRC16(buffer,length-2,Key);
|
||||||
|
uint16 packet_crc=ntohs(*(const uint16 *)(buffer+length-2));
|
||||||
|
#ifdef EQN_DEBUG
|
||||||
|
if (packet_crc && comp_crc != packet_crc) {
|
||||||
|
std::cout << "CRC mismatch: comp=" << std::hex << comp_crc << ", packet=" << packet_crc << std::dec << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
valid = (!packet_crc || comp_crc == packet_crc);
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
|
uint32 EQProtocolPacket::Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize)
|
||||||
{
|
{
|
||||||
uint32 newlen=0;
|
uint32 newlen=0;
|
||||||
@@ -315,6 +403,55 @@ uint32 flag_offset=1,newlength;
|
|||||||
return newlength;
|
return newlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EQProtocolPacket::ChatDecode(unsigned char *buffer, int size, int DecodeKey)
|
||||||
|
{
|
||||||
|
if ((size >= 2) && buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
|
||||||
|
int Key=DecodeKey;
|
||||||
|
unsigned char *test=(unsigned char *)malloc(size);
|
||||||
|
buffer+=2;
|
||||||
|
size-=2;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0 ; i+4 <= size ; i+=4)
|
||||||
|
{
|
||||||
|
int pt = (*(int*)&buffer[i])^(Key);
|
||||||
|
Key = (*(int*)&buffer[i]);
|
||||||
|
*(int*)&test[i]=pt;
|
||||||
|
}
|
||||||
|
unsigned char KC=Key&0xFF;
|
||||||
|
for ( ; i < size ; i++)
|
||||||
|
{
|
||||||
|
test[i]=buffer[i]^KC;
|
||||||
|
}
|
||||||
|
memcpy(buffer,test,size);
|
||||||
|
free(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQProtocolPacket::ChatEncode(unsigned char *buffer, int size, int EncodeKey)
|
||||||
|
{
|
||||||
|
if (buffer[1]!=0x01 && buffer[0]!=0x02 && buffer[0]!=0x1d) {
|
||||||
|
int Key=EncodeKey;
|
||||||
|
char *test=(char*)malloc(size);
|
||||||
|
int i;
|
||||||
|
buffer+=2;
|
||||||
|
size-=2;
|
||||||
|
for ( i = 0 ; i+4 <= size ; i+=4)
|
||||||
|
{
|
||||||
|
int pt = (*(int*)&buffer[i])^(Key);
|
||||||
|
Key = pt;
|
||||||
|
*(int*)&test[i]=pt;
|
||||||
|
}
|
||||||
|
unsigned char KC=Key&0xFF;
|
||||||
|
for ( ; i < size ; i++)
|
||||||
|
{
|
||||||
|
test[i]=buffer[i]^KC;
|
||||||
|
}
|
||||||
|
memcpy(buffer,test,size);
|
||||||
|
free(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EQApplicationPacket *EQApplicationPacket::Copy() const {
|
EQApplicationPacket *EQApplicationPacket::Copy() const {
|
||||||
return(new EQApplicationPacket(*this));
|
return(new EQApplicationPacket(*this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
static bool ValidateCRC(const unsigned char *buffer, int length, uint32 Key);
|
||||||
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
static uint32 Decompress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||||
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
static uint32 Compress(const unsigned char *buffer, const uint32 length, unsigned char *newbuf, uint32 newbufsize);
|
||||||
|
static void ChatDecode(unsigned char *buffer, int size, int DecodeKey);
|
||||||
|
static void ChatEncode(unsigned char *buffer, int size, int EncodeKey);
|
||||||
|
|
||||||
uint16 GetRawOpcode() const { return(opcode); }
|
uint16 GetRawOpcode() const { return(opcode); }
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
|
|
||||||
static const uint32 BUFF_COUNT = 42;
|
static const uint32 BUFF_COUNT = 25;
|
||||||
static const uint32 PET_BUFF_COUNT = 30;
|
static const uint32 PET_BUFF_COUNT = 30;
|
||||||
static const uint32 MAX_MERC = 100;
|
static const uint32 MAX_MERC = 100;
|
||||||
static const uint32 MAX_MERC_GRADES = 10;
|
static const uint32 MAX_MERC_GRADES = 10;
|
||||||
@@ -1793,17 +1793,6 @@ struct GMSummon_Struct {
|
|||||||
/*104*/ uint32 unknown2; // E0 E0 56 00
|
/*104*/ uint32 unknown2; // E0 E0 56 00
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GMFind_Struct {
|
|
||||||
char charname[64];
|
|
||||||
char gmname[64];
|
|
||||||
uint32 success;
|
|
||||||
uint32 zoneID;
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
uint32 unknown2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
|
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
|
||||||
/* 0*/ char charname[64];
|
/* 0*/ char charname[64];
|
||||||
|
|
||||||
@@ -3648,8 +3637,6 @@ struct MerchantList {
|
|||||||
uint32 item;
|
uint32 item;
|
||||||
int16 faction_required;
|
int16 faction_required;
|
||||||
int8 level_required;
|
int8 level_required;
|
||||||
uint8 min_status;
|
|
||||||
uint8 max_status;
|
|
||||||
uint16 alt_currency_cost;
|
uint16 alt_currency_cost;
|
||||||
uint32 classes_required;
|
uint32 classes_required;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
@@ -4105,9 +4092,7 @@ struct UpdateLeadershipAA_Struct {
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
GroupLeadershipAbility_MarkNPC = 0,
|
GroupLeadershipAbility_MarkNPC = 0
|
||||||
RaidLeadershipAbility_MarkNPC = 16,
|
|
||||||
RaidLeadershipAbility_MainAssist = 19
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DoGroupLeadershipAbility_Struct
|
struct DoGroupLeadershipAbility_Struct
|
||||||
@@ -4151,10 +4136,8 @@ struct InspectBuffs_Struct {
|
|||||||
struct RaidGeneral_Struct {
|
struct RaidGeneral_Struct {
|
||||||
/*00*/ uint32 action; //=10
|
/*00*/ uint32 action; //=10
|
||||||
/*04*/ char player_name[64]; //should both be the player's name
|
/*04*/ char player_name[64]; //should both be the player's name
|
||||||
/*68*/ uint32 unknown1;
|
/*64*/ char leader_name[64];
|
||||||
/*72*/ char leader_name[64];
|
/*132*/ uint32 parameter;
|
||||||
/*136*/ uint32 parameter;
|
|
||||||
/*200*/ char note[64];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RaidAddMember_Struct {
|
struct RaidAddMember_Struct {
|
||||||
@@ -4562,7 +4545,7 @@ struct ItemVerifyReply_Struct {
|
|||||||
struct ItemRecastDelay_Struct {
|
struct ItemRecastDelay_Struct {
|
||||||
/*000*/ uint32 recast_delay; // in seconds
|
/*000*/ uint32 recast_delay; // in seconds
|
||||||
/*004*/ uint32 recast_type;
|
/*004*/ uint32 recast_type;
|
||||||
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
|
/*008*/ uint32 unknown008;
|
||||||
/*012*/
|
/*012*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -5537,11 +5520,7 @@ struct ServerLootItem_Struct {
|
|||||||
uint32 aug_4; // uint32 aug_4;
|
uint32 aug_4; // uint32 aug_4;
|
||||||
uint32 aug_5; // uint32 aug_5;
|
uint32 aug_5; // uint32 aug_5;
|
||||||
uint32 aug_6; // uint32 aug_5;
|
uint32 aug_6; // uint32 aug_5;
|
||||||
bool attuned;
|
uint8 attuned;
|
||||||
std::string custom_data;
|
|
||||||
uint32 ornamenticon {};
|
|
||||||
uint32 ornamentidfile {};
|
|
||||||
uint32 ornament_hero_model {};
|
|
||||||
uint16 trivial_min_level;
|
uint16 trivial_min_level;
|
||||||
uint16 trivial_max_level;
|
uint16 trivial_max_level;
|
||||||
uint16 npc_min_level;
|
uint16 npc_min_level;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ EQStreamIdentifier::~EQStreamIdentifier() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQStreamIdentifier::RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
|
void EQStreamIdentifier::RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs) {
|
||||||
auto p = new Patch;
|
auto p = new Patch;
|
||||||
p->signature = sig;
|
p->signature = sig;
|
||||||
p->name = name;
|
p->name = name;
|
||||||
@@ -145,7 +145,7 @@ void EQStreamIdentifier::Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
|
void EQStreamIdentifier::AddStream(std::shared_ptr<EQStreamInterface> eqs) {
|
||||||
m_streams.emplace_back(Record(eqs));
|
m_streams.push_back(Record(eqs));
|
||||||
eqs = nullptr;
|
eqs = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
~EQStreamIdentifier();
|
~EQStreamIdentifier();
|
||||||
|
|
||||||
//registration interface.
|
//registration interface.
|
||||||
void RegisterPatch(EQStreamInterface::Signature sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
|
void RegisterPatch(const EQStreamInterface::Signature &sig, const char *name, OpcodeManager ** opcodes, const StructStrategy *structs);
|
||||||
|
|
||||||
//main processing interface
|
//main processing interface
|
||||||
void Process();
|
void Process();
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
|
|
||||||
EQDB EQDB::s_EQDB;
|
EQDB EQDB::s_EQDB;
|
||||||
|
|
||||||
|
EQDB::EQDB() {
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int EQDB::field_count() {
|
unsigned int EQDB::field_count() {
|
||||||
return mysql_field_count(mysql_ref);
|
return mysql_field_count(mysql_ref);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
//this is the main object exported to perl.
|
//this is the main object exported to perl.
|
||||||
class EQDB {
|
class EQDB {
|
||||||
EQDB() = default;
|
EQDB();
|
||||||
public:
|
public:
|
||||||
static EQDB *Singleton() { return(&s_EQDB); }
|
static EQDB *Singleton() { return(&s_EQDB); }
|
||||||
|
|
||||||
|
|||||||
+18
-25
@@ -19,7 +19,6 @@
|
|||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "eqemu_config.h"
|
#include "eqemu_config.h"
|
||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
#include "strings.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -34,13 +33,13 @@ void EQEmuConfig::parse_config()
|
|||||||
LongName = _root["server"]["world"].get("longname", "").asString();
|
LongName = _root["server"]["world"].get("longname", "").asString();
|
||||||
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
WorldAddress = _root["server"]["world"].get("address", "").asString();
|
||||||
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
|
||||||
MaxClients = Strings::ToInt(_root["server"]["world"].get("maxclients", "-1").asString());
|
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
|
||||||
SharedKey = _root["server"]["world"].get("key", "").asString();
|
SharedKey = _root["server"]["world"].get("key", "").asString();
|
||||||
LoginCount = 0;
|
LoginCount = 0;
|
||||||
|
|
||||||
if (_root["server"]["world"]["loginserver"].isObject()) {
|
if (_root["server"]["world"]["loginserver"].isObject()) {
|
||||||
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
|
||||||
LoginPort = Strings::ToUnsignedInt(_root["server"]["world"]["loginserver"].get("port", "5998").asString());
|
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
|
||||||
LoginLegacy = false;
|
LoginLegacy = false;
|
||||||
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
|
||||||
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
|
||||||
@@ -63,7 +62,7 @@ void EQEmuConfig::parse_config()
|
|||||||
|
|
||||||
auto loginconfig = new LoginConfig;
|
auto loginconfig = new LoginConfig;
|
||||||
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
|
||||||
loginconfig->LoginPort = Strings::ToUnsignedInt(_root["server"]["world"][str].get("port", "5998").asString());
|
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
|
||||||
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
|
||||||
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
|
||||||
|
|
||||||
@@ -85,22 +84,16 @@ void EQEmuConfig::parse_config()
|
|||||||
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
|
||||||
Locked = false;
|
Locked = false;
|
||||||
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }
|
||||||
|
|
||||||
auto_database_updates = false;
|
|
||||||
if (_root["server"].get("auto_database_updates", "true").asString() == "true") {
|
|
||||||
auto_database_updates = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
|
||||||
WorldTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["tcp"].get("port", "9000").asString());
|
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
|
||||||
|
|
||||||
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
|
||||||
TelnetTCPPort = Strings::ToUnsignedInt(_root["server"]["world"]["telnet"].get("port", "9001").asString());
|
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
|
||||||
TelnetEnabled = false;
|
TelnetEnabled = false;
|
||||||
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") { TelnetEnabled = true; }
|
||||||
|
|
||||||
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
|
||||||
WorldHTTPPort = Strings::ToUnsignedInt(_root["server"]["world"]["http"].get("port", "9080").asString());
|
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
|
||||||
WorldHTTPEnabled = false;
|
WorldHTTPEnabled = false;
|
||||||
|
|
||||||
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") {
|
||||||
@@ -115,9 +108,9 @@ void EQEmuConfig::parse_config()
|
|||||||
* UCS
|
* UCS
|
||||||
*/
|
*/
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
||||||
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
|
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
|
||||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
||||||
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
|
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database
|
* Database
|
||||||
@@ -125,7 +118,7 @@ void EQEmuConfig::parse_config()
|
|||||||
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
|
||||||
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
|
||||||
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
|
||||||
DatabasePort = Strings::ToUnsignedInt(_root["server"]["database"].get("port", "3306").asString());
|
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
|
||||||
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,14 +127,14 @@ void EQEmuConfig::parse_config()
|
|||||||
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
ContentDbUsername = _root["server"]["content_database"].get("username", "").asString();
|
||||||
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
ContentDbPassword = _root["server"]["content_database"].get("password", "").asString();
|
||||||
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
ContentDbHost = _root["server"]["content_database"].get("host", "").asString();
|
||||||
ContentDbPort = Strings::ToUnsignedInt(_root["server"]["content_database"].get("port", 0).asString());
|
ContentDbPort = atoi(_root["server"]["content_database"].get("port", 0).asString().c_str());
|
||||||
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
ContentDbName = _root["server"]["content_database"].get("db", "").asString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QS
|
* QS
|
||||||
*/
|
*/
|
||||||
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
|
||||||
QSDatabasePort = Strings::ToUnsignedInt(_root["server"]["qsdatabase"].get("port", "3306").asString());
|
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
|
||||||
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
|
||||||
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
|
||||||
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
|
||||||
@@ -149,9 +142,9 @@ void EQEmuConfig::parse_config()
|
|||||||
/**
|
/**
|
||||||
* Zones
|
* Zones
|
||||||
*/
|
*/
|
||||||
DefaultStatus = Strings::ToUnsignedInt(_root["server"]["zones"].get("defaultstatus", 0).asString());
|
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
|
||||||
ZonePortLow = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("low", "7000").asString());
|
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
|
||||||
ZonePortHigh = Strings::ToUnsignedInt(_root["server"]["zones"]["ports"].get("high", "7999").asString());
|
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Files
|
* Files
|
||||||
@@ -181,10 +174,10 @@ void EQEmuConfig::parse_config()
|
|||||||
/**
|
/**
|
||||||
* Launcher
|
* Launcher
|
||||||
*/
|
*/
|
||||||
RestartWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("restart", "10000").asString());
|
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
|
||||||
TerminateWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString());
|
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
|
||||||
InitialBootWait = Strings::ToInt(_root["server"]["launcher"]["timers"].get("initial", "20000").asString());
|
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
|
||||||
ZoneBootInterval = Strings::ToInt(_root["server"]["launcher"]["timers"].get("interval", "2000").asString());
|
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -120,8 +120,6 @@ class EQEmuConfig
|
|||||||
uint16 ZonePortHigh;
|
uint16 ZonePortHigh;
|
||||||
uint8 DefaultStatus;
|
uint8 DefaultStatus;
|
||||||
|
|
||||||
bool auto_database_updates;
|
|
||||||
|
|
||||||
// uint16 DynamicCount;
|
// uint16 DynamicCount;
|
||||||
|
|
||||||
// map<string,uint16> StaticZones;
|
// map<string,uint16> StaticZones;
|
||||||
@@ -149,6 +147,12 @@ class EQEmuConfig
|
|||||||
return (_config);
|
return (_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow the use to set the conf file to be used.
|
||||||
|
static void SetConfigFile(std::string file)
|
||||||
|
{
|
||||||
|
EQEmuConfig::ConfigFile = file;
|
||||||
|
}
|
||||||
|
|
||||||
// Load the config
|
// Load the config
|
||||||
static bool LoadConfig(const std::string& path = "")
|
static bool LoadConfig(const std::string& path = "")
|
||||||
{
|
{
|
||||||
|
|||||||
+9
-79
@@ -187,10 +187,9 @@ void EQEmuLogSys::ProcessLogWrite(
|
|||||||
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
||||||
{
|
{
|
||||||
switch (log_category) {
|
switch (log_category) {
|
||||||
case Logs::Crash:
|
|
||||||
case Logs::Error:
|
|
||||||
case Logs::MySQLError:
|
case Logs::MySQLError:
|
||||||
case Logs::QuestErrors:
|
case Logs::QuestErrors:
|
||||||
|
case Logs::Error:
|
||||||
return Chat::Red;
|
return Chat::Red;
|
||||||
case Logs::MySQLQuery:
|
case Logs::MySQLQuery:
|
||||||
case Logs::Debug:
|
case Logs::Debug:
|
||||||
@@ -200,6 +199,8 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category)
|
|||||||
case Logs::Commands:
|
case Logs::Commands:
|
||||||
case Logs::Mercenaries:
|
case Logs::Mercenaries:
|
||||||
return Chat::Magenta;
|
return Chat::Magenta;
|
||||||
|
case Logs::Crash:
|
||||||
|
return Chat::Red;
|
||||||
default:
|
default:
|
||||||
return Chat::Yellow;
|
return Chat::Yellow;
|
||||||
}
|
}
|
||||||
@@ -297,62 +298,6 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// color matching in []
|
|
||||||
// ex: [<red>variable] would produce [variable] with red inside brackets
|
|
||||||
std::map<std::string, rang::fgB> colors = {
|
|
||||||
{"<black>", rang::fgB::black},
|
|
||||||
{"<green>", rang::fgB::green},
|
|
||||||
{"<yellow>", rang::fgB::yellow},
|
|
||||||
{"<blue>", rang::fgB::blue},
|
|
||||||
{"<magenta>", rang::fgB::magenta},
|
|
||||||
{"<cyan>", rang::fgB::cyan},
|
|
||||||
{"<gray>", rang::fgB::gray},
|
|
||||||
{"<red>", rang::fgB::red},
|
|
||||||
};
|
|
||||||
|
|
||||||
bool match_color = false;
|
|
||||||
for (auto &c: colors) {
|
|
||||||
if (Strings::Contains(e, c.first)) {
|
|
||||||
e = Strings::Replace(e, c.first, "");
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< "["
|
|
||||||
<< rang::style::bold
|
|
||||||
<< c.second
|
|
||||||
<< e
|
|
||||||
<< rang::style::reset
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< "] ";
|
|
||||||
match_color = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// string match to colors
|
|
||||||
std::map<std::string, rang::fgB> matches = {
|
|
||||||
{"missing", rang::fgB::red},
|
|
||||||
{"error", rang::fgB::red},
|
|
||||||
{"ok", rang::fgB::green},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto &c: matches) {
|
|
||||||
if (Strings::Contains(e, c.first)) {
|
|
||||||
(!is_error ? std::cout : std::cerr)
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< "["
|
|
||||||
<< rang::style::bold
|
|
||||||
<< c.second
|
|
||||||
<< e
|
|
||||||
<< rang::style::reset
|
|
||||||
<< rang::fgB::gray
|
|
||||||
<< "] ";
|
|
||||||
match_color = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we don't match a color in either the string matching or
|
|
||||||
// the color tag matching, we default to yellow inside brackets
|
|
||||||
// if uppercase, does not get colored
|
|
||||||
if (!match_color) {
|
|
||||||
if (!is_upper) {
|
if (!is_upper) {
|
||||||
(!is_error ? std::cout : std::cerr)
|
(!is_error ? std::cout : std::cerr)
|
||||||
<< rang::fgB::gray
|
<< rang::fgB::gray
|
||||||
@@ -360,15 +305,14 @@ void EQEmuLogSys::ProcessConsoleMessage(
|
|||||||
<< rang::style::bold
|
<< rang::style::bold
|
||||||
<< rang::fgB::yellow
|
<< rang::fgB::yellow
|
||||||
<< e
|
<< e
|
||||||
<< rang::style::reset
|
|
||||||
<< rang::fgB::gray
|
<< rang::fgB::gray
|
||||||
<< "] ";
|
<< "] "
|
||||||
|
;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
(!is_error ? std::cout : std::cerr)
|
(!is_error ? std::cout : std::cerr)
|
||||||
<< (is_error ? rang::fgB::red : rang::fgB::gray)
|
<< (is_error ? rang::fgB::red : rang::fgB::gray)
|
||||||
@@ -446,8 +390,6 @@ void EQEmuLogSys::Out(
|
|||||||
// remove this when we remove all legacy logs
|
// remove this when we remove all legacy logs
|
||||||
bool ignore_log_legacy_format = (
|
bool ignore_log_legacy_format = (
|
||||||
log_category == Logs::Netcode ||
|
log_category == Logs::Netcode ||
|
||||||
log_category == Logs::MySQLQuery ||
|
|
||||||
log_category == Logs::MySQLError ||
|
|
||||||
log_category == Logs::PacketServerClient ||
|
log_category == Logs::PacketServerClient ||
|
||||||
log_category == Logs::PacketClientServer ||
|
log_category == Logs::PacketClientServer ||
|
||||||
log_category == Logs::PacketServerToServer
|
log_category == Logs::PacketServerToServer
|
||||||
@@ -582,8 +524,6 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name)
|
|||||||
*/
|
*/
|
||||||
void EQEmuLogSys::SilenceConsoleLogging()
|
void EQEmuLogSys::SilenceConsoleLogging()
|
||||||
{
|
{
|
||||||
std::copy(std::begin(log_settings), std::end(log_settings), std::begin(pre_silence_settings));
|
|
||||||
|
|
||||||
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||||
log_settings[log_index].log_to_console = 0;
|
log_settings[log_index].log_to_console = 0;
|
||||||
log_settings[log_index].is_category_enabled = 0;
|
log_settings[log_index].is_category_enabled = 0;
|
||||||
@@ -597,7 +537,10 @@ void EQEmuLogSys::SilenceConsoleLogging()
|
|||||||
*/
|
*/
|
||||||
void EQEmuLogSys::EnableConsoleLogging()
|
void EQEmuLogSys::EnableConsoleLogging()
|
||||||
{
|
{
|
||||||
std::copy(std::begin(pre_silence_settings), std::end(pre_silence_settings), std::begin(log_settings));
|
for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) {
|
||||||
|
log_settings[log_index].log_to_console = Logs::General;
|
||||||
|
log_settings[log_index].is_category_enabled = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||||
@@ -799,16 +742,3 @@ EQEmuLogSys *EQEmuLogSys::SetLogPath(const std::string &log_path)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQEmuLogSys::DisableMySQLErrorLogs()
|
|
||||||
{
|
|
||||||
log_settings[Logs::MySQLError].log_to_file = 0;
|
|
||||||
log_settings[Logs::MySQLError].log_to_console = 0;
|
|
||||||
log_settings[Logs::MySQLError].log_to_gmsay = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQEmuLogSys::EnableMySQLErrorLogs()
|
|
||||||
{
|
|
||||||
log_settings[Logs::MySQLError].log_to_file = 1;
|
|
||||||
log_settings[Logs::MySQLError].log_to_console = 1;
|
|
||||||
log_settings[Logs::MySQLError].log_to_gmsay = 1;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -136,7 +136,6 @@ namespace Logs {
|
|||||||
PacketServerToServer,
|
PacketServerToServer,
|
||||||
Bugs,
|
Bugs,
|
||||||
QuestErrors,
|
QuestErrors,
|
||||||
PlayerEvents,
|
|
||||||
MaxCategoryID /* Don't Remove this */
|
MaxCategoryID /* Don't Remove this */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,8 +230,7 @@ namespace Logs {
|
|||||||
"Packet C->S",
|
"Packet C->S",
|
||||||
"Packet S->S",
|
"Packet S->S",
|
||||||
"Bugs",
|
"Bugs",
|
||||||
"QuestErrors",
|
"QuestErrors"
|
||||||
"PlayerEvents",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +322,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||||
|
|
||||||
// temporary bucket to re-load after silencing
|
|
||||||
LogSettings pre_silence_settings[Logs::LogCategory::MaxCategoryID]{};
|
|
||||||
|
|
||||||
struct LogEnabled {
|
struct LogEnabled {
|
||||||
bool log_to_file_enabled;
|
bool log_to_file_enabled;
|
||||||
bool log_to_console_enabled;
|
bool log_to_console_enabled;
|
||||||
@@ -377,9 +372,6 @@ public:
|
|||||||
[[nodiscard]] const std::string &GetLogPath() const;
|
[[nodiscard]] const std::string &GetLogPath() const;
|
||||||
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
EQEmuLogSys * SetLogPath(const std::string &log_path);
|
||||||
|
|
||||||
void DisableMySQLErrorLogs();
|
|
||||||
void EnableMySQLErrorLogs();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// reference to database
|
// reference to database
|
||||||
|
|||||||
@@ -784,16 +784,6 @@
|
|||||||
OutF(LogSys, Logs::Detail, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
OutF(LogSys, Logs::Detail, Logs::QuestErrors, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
} while (0)
|
} 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 {\
|
#define Log(debug_level, log_category, message, ...) do {\
|
||||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ EQTime::EQTime()
|
|||||||
SetCurrentEQTimeOfDay(start, time(0));
|
SetCurrentEQTimeOfDay(start, time(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EQTime::~EQTime()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
//getEQTimeOfDay - Reads timeConvert and writes the result to eqTimeOfDay
|
||||||
//This function was written by the ShowEQ Project.
|
//This function was written by the ShowEQ Project.
|
||||||
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
|
//Input: Current Time (as a time_t), a pointer to the TimeOfDay_Struct that will be written to.
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ public:
|
|||||||
//Constructor/destructor
|
//Constructor/destructor
|
||||||
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
|
EQTime(TimeOfDay_Struct start_eq, time_t start_real);
|
||||||
EQTime();
|
EQTime();
|
||||||
~EQTime() = default;
|
~EQTime();
|
||||||
|
|
||||||
//Get functions
|
//Get functions
|
||||||
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
int GetCurrentEQTimeOfDay( TimeOfDay_Struct *eqTimeOfDay ) { return(GetCurrentEQTimeOfDay(time(nullptr), eqTimeOfDay)); }
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace EQ
|
|||||||
_running = true;
|
_running = true;
|
||||||
|
|
||||||
for (size_t i = 0; i < threads; ++i) {
|
for (size_t i = 0; i < threads; ++i) {
|
||||||
_threads.emplace_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
_threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,214 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
#define EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../repositories/base/base_player_event_logs_repository.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <cereal/types/vector.hpp>
|
|
||||||
|
|
||||||
struct DiscordField {
|
|
||||||
std::string name;
|
|
||||||
std::string value;
|
|
||||||
bool is_inline;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(name),
|
|
||||||
CEREAL_NVP(value),
|
|
||||||
cereal::make_nvp("inline", is_inline)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordAuthor {
|
|
||||||
std::string name;
|
|
||||||
std::string icon_url;
|
|
||||||
std::string url;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(name),
|
|
||||||
CEREAL_NVP(icon_url),
|
|
||||||
CEREAL_NVP(url)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordEmbed {
|
|
||||||
std::vector<DiscordField> fields;
|
|
||||||
std::string title;
|
|
||||||
std::string description;
|
|
||||||
std::string timestamp;
|
|
||||||
DiscordAuthor author;
|
|
||||||
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(fields),
|
|
||||||
CEREAL_NVP(title),
|
|
||||||
CEREAL_NVP(description),
|
|
||||||
CEREAL_NVP(timestamp),
|
|
||||||
CEREAL_NVP(author)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DiscordWebhook {
|
|
||||||
std::vector<DiscordEmbed> embeds;
|
|
||||||
std::string content;
|
|
||||||
std::string avatar_url;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(embeds),
|
|
||||||
CEREAL_NVP(avatar_url),
|
|
||||||
CEREAL_NVP(content)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PlayerEventDiscordFormatter {
|
|
||||||
public:
|
|
||||||
static std::string GetCurrentTimestamp();
|
|
||||||
static std::string FormatEventSay(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::SayEvent &e);
|
|
||||||
static std::string
|
|
||||||
FormatGMCommand(const PlayerEvent::PlayerEventContainer &c, const PlayerEvent::GMCommandEvent &e);
|
|
||||||
static void BuildDiscordField(
|
|
||||||
std::vector<DiscordField> *f,
|
|
||||||
const std::string &name,
|
|
||||||
const std::string &value,
|
|
||||||
bool is_inline = true
|
|
||||||
);
|
|
||||||
static void BuildBaseEmbed(
|
|
||||||
std::vector<DiscordEmbed> *e,
|
|
||||||
const std::vector<DiscordField> &f,
|
|
||||||
PlayerEvent::PlayerEventContainer c
|
|
||||||
);
|
|
||||||
static std::string FormatWithNodata(const PlayerEvent::PlayerEventContainer &c);
|
|
||||||
|
|
||||||
static std::string FormatAAGainedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::AAGainedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatAAPurchasedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::AAPurchasedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDeathEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DeathEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatFishSuccessEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::FishSuccessEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatForageSuccessEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ForageSuccessEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDestroyItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DestroyItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDiscoverItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DiscoverItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatDroppedItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::DroppedItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLevelGainedEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LevelGainedEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLevelLostEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LevelLostEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatLootItemEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::LootItemEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatGroundSpawnPickupEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::GroundSpawnPickupEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatMerchantPurchaseEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::MerchantPurchaseEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatMerchantSellEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::MerchantSellEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatNPCHandinEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::HandinEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatSkillUpEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::SkillUpEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskAcceptEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskAcceptEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskCompleteEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskCompleteEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTaskUpdateEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TaskUpdateEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTradeEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TradeEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTraderPurchaseEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TraderPurchaseEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatTraderSellEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::TraderSellEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatResurrectAcceptEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ResurrectAcceptEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatSplitMoneyEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::SplitMoneyEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatCombineEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::CombineEvent &e
|
|
||||||
);
|
|
||||||
static std::string FormatZoningEvent(
|
|
||||||
const PlayerEvent::PlayerEventContainer &c,
|
|
||||||
const PlayerEvent::ZoningEvent &e
|
|
||||||
);
|
|
||||||
static DiscordWebhook BuildDiscordWebhook(
|
|
||||||
const PlayerEvent::PlayerEventContainer &p,
|
|
||||||
std::vector<DiscordEmbed> &embeds
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_DISCORD_FORMATTER_H
|
|
||||||
@@ -1,702 +0,0 @@
|
|||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include "player_event_logs.h"
|
|
||||||
#include "player_event_discord_formatter.h"
|
|
||||||
#include "../platform.h"
|
|
||||||
#include "../rulesys.h"
|
|
||||||
|
|
||||||
const uint32 PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL = 60 * 60 * 1000; // 1 hour
|
|
||||||
|
|
||||||
// general initialization routine
|
|
||||||
void PlayerEventLogs::Init()
|
|
||||||
{
|
|
||||||
m_process_batch_events_timer.SetTimer(RuleI(Logging, BatchPlayerEventProcessIntervalSeconds) * 1000);
|
|
||||||
m_process_retention_truncation_timer.SetTimer(PROCESS_RETENTION_TRUNCATION_TIMER_INTERVAL);
|
|
||||||
|
|
||||||
ValidateDatabaseConnection();
|
|
||||||
|
|
||||||
// initialize settings array
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
m_settings[i].id = i;
|
|
||||||
m_settings[i].event_name = PlayerEvent::EventName[i];
|
|
||||||
m_settings[i].event_enabled = 1;
|
|
||||||
m_settings[i].retention_days = 0;
|
|
||||||
m_settings[i].discord_webhook_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSettingsDefaults();
|
|
||||||
|
|
||||||
// initialize settings from database
|
|
||||||
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
|
||||||
std::vector<int> db{};
|
|
||||||
db.reserve(s.size());
|
|
||||||
for (auto &e: s) {
|
|
||||||
if (e.id >= PlayerEvent::MAX) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_settings[e.id] = e;
|
|
||||||
db.emplace_back(e.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert entries that don't exist in database
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
|
||||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
|
||||||
bool is_deprecated = Strings::Contains(PlayerEvent::EventName[i], "Deprecated");
|
|
||||||
bool is_implemented = !Strings::Contains(PlayerEvent::EventName[i], "Unimplemented");
|
|
||||||
|
|
||||||
// remove when deprecated
|
|
||||||
if (is_deprecated && is_in_database) {
|
|
||||||
LogInfo("[Deprecated] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
|
||||||
}
|
|
||||||
// remove when unimplemented if present
|
|
||||||
if (!is_implemented && is_in_database) {
|
|
||||||
LogInfo("[Unimplemented] Removing PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
|
||||||
PlayerEventLogSettingsRepository::DeleteWhere(*m_database, fmt::format("id = {}", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
|
||||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
|
||||||
LogInfo(
|
|
||||||
"[New] PlayerEvent [{}] ({})",
|
|
||||||
PlayerEvent::EventName[i],
|
|
||||||
i
|
|
||||||
);
|
|
||||||
|
|
||||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
|
||||||
c.id = i;
|
|
||||||
c.event_name = PlayerEvent::EventName[i];
|
|
||||||
c.event_enabled = m_settings[i].event_enabled;
|
|
||||||
c.retention_days = m_settings[i].retention_days;
|
|
||||||
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
|
||||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
|
||||||
|
|
||||||
// on initial boot process truncation
|
|
||||||
if (processing_in_world || processing_in_qs) {
|
|
||||||
ProcessRetentionTruncation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the database object, during initialization
|
|
||||||
PlayerEventLogs *PlayerEventLogs::SetDatabase(Database *db)
|
|
||||||
{
|
|
||||||
m_database = db;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// validates whether the connection is valid or not, used in initialization
|
|
||||||
bool PlayerEventLogs::ValidateDatabaseConnection()
|
|
||||||
{
|
|
||||||
if (!m_database) {
|
|
||||||
LogError("No database connection");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determines if the passed in event is enabled or not
|
|
||||||
// this is used to gate logic or events from firing off
|
|
||||||
// this is used prior to building the events, we don't want to
|
|
||||||
// build the events, send them through the stack in a function call
|
|
||||||
// only to discard them immediately afterwards, very wasteful on resources
|
|
||||||
// the quest api currently does this
|
|
||||||
bool PlayerEventLogs::IsEventEnabled(PlayerEvent::EventType event)
|
|
||||||
{
|
|
||||||
return m_settings[event].event_enabled ? m_settings[event].event_enabled : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this processes any current player events on the queue
|
|
||||||
void PlayerEventLogs::ProcessBatchQueue()
|
|
||||||
{
|
|
||||||
m_batch_queue_lock.lock();
|
|
||||||
if (m_record_batch_queue.empty()) {
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BenchTimer benchmark;
|
|
||||||
|
|
||||||
// flush many
|
|
||||||
PlayerEventLogsRepository::InsertMany(*m_database, m_record_batch_queue);
|
|
||||||
LogPlayerEventsDetail(
|
|
||||||
"Processing batch player event log queue of [{}] took [{}]",
|
|
||||||
m_record_batch_queue.size(),
|
|
||||||
benchmark.elapsed()
|
|
||||||
);
|
|
||||||
|
|
||||||
// empty
|
|
||||||
m_record_batch_queue = {};
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// adds a player event to the queue
|
|
||||||
void PlayerEventLogs::AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &log)
|
|
||||||
{
|
|
||||||
m_batch_queue_lock.lock();
|
|
||||||
m_record_batch_queue.emplace_back(log);
|
|
||||||
m_batch_queue_lock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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:
|
|
||||||
case PlayerEvent::FORAGE_FAILURE:
|
|
||||||
case PlayerEvent::WENT_ONLINE:
|
|
||||||
case PlayerEvent::WENT_OFFLINE: {
|
|
||||||
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_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::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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
#define EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
|
|
||||||
#include "../repositories/player_event_log_settings_repository.h"
|
|
||||||
#include "player_events.h"
|
|
||||||
#include "../servertalk.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
#include "../timer.h"
|
|
||||||
#include "../json/json_archive_single_line.h"
|
|
||||||
#include <cereal/archives/json.hpp>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class PlayerEventLogs {
|
|
||||||
public:
|
|
||||||
void Init();
|
|
||||||
void ReloadSettings();
|
|
||||||
PlayerEventLogs *SetDatabase(Database *db);
|
|
||||||
bool ValidateDatabaseConnection();
|
|
||||||
bool IsEventEnabled(PlayerEvent::EventType event);
|
|
||||||
|
|
||||||
void Process();
|
|
||||||
|
|
||||||
// batch queue
|
|
||||||
void AddToQueue(const PlayerEventLogsRepository::PlayerEventLogs &logs);
|
|
||||||
|
|
||||||
// main event record generic function
|
|
||||||
// can ingest any struct event types
|
|
||||||
template<typename T>
|
|
||||||
std::unique_ptr<ServerPacket> RecordEvent(
|
|
||||||
PlayerEvent::EventType t,
|
|
||||||
const PlayerEvent::PlayerEvent &p,
|
|
||||||
T e
|
|
||||||
)
|
|
||||||
{
|
|
||||||
auto n = PlayerEventLogsRepository::NewEntity();
|
|
||||||
FillPlayerEvent(p, n);
|
|
||||||
n.event_type_id = t;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
|
||||||
{
|
|
||||||
cereal::JSONOutputArchiveSingleLine ar(ss);
|
|
||||||
e.serialize(ar);
|
|
||||||
}
|
|
||||||
|
|
||||||
n.event_type_name = PlayerEvent::EventName[t];
|
|
||||||
n.event_data = Strings::Contains(ss.str(), "noop") ? "{}" : ss.str();
|
|
||||||
n.created_at = std::time(nullptr);
|
|
||||||
|
|
||||||
auto c = PlayerEvent::PlayerEventContainer{
|
|
||||||
.player_event = p,
|
|
||||||
.player_event_log = n
|
|
||||||
};
|
|
||||||
|
|
||||||
return BuildPlayerEventPacket(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const PlayerEventLogSettingsRepository::PlayerEventLogSettings *GetSettings() const;
|
|
||||||
bool IsEventDiscordEnabled(int32_t event_type_id);
|
|
||||||
std::string GetDiscordWebhookUrlFromEventType(int32_t event_type_id);
|
|
||||||
|
|
||||||
static std::string GetDiscordPayloadFromEvent(const PlayerEvent::PlayerEventContainer &e);
|
|
||||||
private:
|
|
||||||
Database *m_database; // reference to database
|
|
||||||
PlayerEventLogSettingsRepository::PlayerEventLogSettings m_settings[PlayerEvent::EventType::MAX]{};
|
|
||||||
|
|
||||||
// batch queue is used to record events in batch
|
|
||||||
std::vector<PlayerEventLogsRepository::PlayerEventLogs> m_record_batch_queue{};
|
|
||||||
static void FillPlayerEvent(const PlayerEvent::PlayerEvent &p, PlayerEventLogsRepository::PlayerEventLogs &n);
|
|
||||||
static std::unique_ptr<ServerPacket>
|
|
||||||
BuildPlayerEventPacket(const PlayerEvent::PlayerEventContainer &e);
|
|
||||||
|
|
||||||
// timers
|
|
||||||
Timer m_process_batch_events_timer; // events processing timer
|
|
||||||
Timer m_process_retention_truncation_timer; // timer for truncating events based on retention settings
|
|
||||||
|
|
||||||
// processing
|
|
||||||
std::mutex m_batch_queue_lock{};
|
|
||||||
void ProcessBatchQueue();
|
|
||||||
void ProcessRetentionTruncation();
|
|
||||||
void SetSettingsDefaults();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern PlayerEventLogs player_event_logs;
|
|
||||||
|
|
||||||
#endif //EQEMU_PLAYER_EVENT_LOGS_H
|
|
||||||
@@ -1,971 +0,0 @@
|
|||||||
#ifndef EQEMU_PLAYER_EVENTS_H
|
|
||||||
#define EQEMU_PLAYER_EVENTS_H
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cereal/cereal.hpp>
|
|
||||||
#include "../types.h"
|
|
||||||
#include "../repositories/player_event_logs_repository.h"
|
|
||||||
|
|
||||||
namespace PlayerEvent {
|
|
||||||
|
|
||||||
enum EventType {
|
|
||||||
GM_COMMAND = 1,
|
|
||||||
ZONING,
|
|
||||||
AA_GAIN,
|
|
||||||
AA_PURCHASE,
|
|
||||||
FORAGE_SUCCESS,
|
|
||||||
FORAGE_FAILURE,
|
|
||||||
FISH_SUCCESS,
|
|
||||||
FISH_FAILURE,
|
|
||||||
ITEM_DESTROY,
|
|
||||||
WENT_ONLINE,
|
|
||||||
WENT_OFFLINE,
|
|
||||||
LEVEL_GAIN,
|
|
||||||
LEVEL_LOSS,
|
|
||||||
LOOT_ITEM,
|
|
||||||
MERCHANT_PURCHASE,
|
|
||||||
MERCHANT_SELL,
|
|
||||||
GROUP_JOIN, // unimplemented
|
|
||||||
GROUP_LEAVE, // unimplemented
|
|
||||||
RAID_JOIN, // unimplemented
|
|
||||||
RAID_LEAVE, // unimplemented
|
|
||||||
GROUNDSPAWN_PICKUP,
|
|
||||||
NPC_HANDIN,
|
|
||||||
SKILL_UP,
|
|
||||||
TASK_ACCEPT,
|
|
||||||
TASK_UPDATE,
|
|
||||||
TASK_COMPLETE,
|
|
||||||
TRADE,
|
|
||||||
GIVE_ITEM, // unimplemented
|
|
||||||
SAY,
|
|
||||||
REZ_ACCEPTED,
|
|
||||||
DEATH,
|
|
||||||
COMBINE_FAILURE,
|
|
||||||
COMBINE_SUCCESS,
|
|
||||||
DROPPED_ITEM,
|
|
||||||
SPLIT_MONEY,
|
|
||||||
DZ_JOIN, // unimplemented
|
|
||||||
DZ_LEAVE, // unimplemented
|
|
||||||
TRADER_PURCHASE,
|
|
||||||
TRADER_SELL,
|
|
||||||
BANDOLIER_CREATE, // unimplemented
|
|
||||||
BANDOLIER_SWAP, // unimplemented
|
|
||||||
DISCOVER_ITEM,
|
|
||||||
POSSIBLE_HACK,
|
|
||||||
KILLED_NPC,
|
|
||||||
KILLED_NAMED_NPC,
|
|
||||||
KILLED_RAID_NPC,
|
|
||||||
ITEM_CREATION,
|
|
||||||
MAX // dont remove
|
|
||||||
};
|
|
||||||
|
|
||||||
// Don't ever remove items, even if they are deprecated
|
|
||||||
// If event is deprecated just tag (Deprecated) in the name
|
|
||||||
// If event is unimplemented just tag (Unimplemented) in the name
|
|
||||||
// Events don't get saved to the database if unimplemented or deprecated
|
|
||||||
// Events tagged as deprecated will get automatically removed
|
|
||||||
static const char *EventName[PlayerEvent::MAX] = {
|
|
||||||
"None",
|
|
||||||
"GM Command",
|
|
||||||
"Zoning",
|
|
||||||
"AA Gain",
|
|
||||||
"AA Purchase",
|
|
||||||
"Forage Success",
|
|
||||||
"Forage Failure",
|
|
||||||
"Fish Success",
|
|
||||||
"Fish Failure",
|
|
||||||
"Item Destroy",
|
|
||||||
"Went Online",
|
|
||||||
"Went Offline",
|
|
||||||
"Level Gain",
|
|
||||||
"Level Loss",
|
|
||||||
"Loot Item",
|
|
||||||
"Merchant Purchase",
|
|
||||||
"Merchant Sell",
|
|
||||||
"Group Join (Unimplemented)",
|
|
||||||
"Group Leave (Unimplemented)",
|
|
||||||
"Raid Join (Unimplemented)",
|
|
||||||
"Raid Leave (Unimplemented)",
|
|
||||||
"Groundspawn Pickup",
|
|
||||||
"NPC Handin",
|
|
||||||
"Skill Up",
|
|
||||||
"Task Accept",
|
|
||||||
"Task Update",
|
|
||||||
"Task Complete",
|
|
||||||
"Trade",
|
|
||||||
"Given Item (Unimplemented)",
|
|
||||||
"Say",
|
|
||||||
"Rez Accepted",
|
|
||||||
"Death",
|
|
||||||
"Combine Failure",
|
|
||||||
"Combine Success",
|
|
||||||
"Dropped Item",
|
|
||||||
"Split Money",
|
|
||||||
"DZ Join (Unimplemented)",
|
|
||||||
"DZ Leave (Unimplemented)",
|
|
||||||
"Trader Purchase",
|
|
||||||
"Trader Sell",
|
|
||||||
"Bandolier Create (Unimplemented)",
|
|
||||||
"Bandolier Swap (Unimplemented)",
|
|
||||||
"Discover Item",
|
|
||||||
"Possible Hack",
|
|
||||||
"Killed NPC",
|
|
||||||
"Killed Named NPC",
|
|
||||||
"Killed Raid NPC",
|
|
||||||
"Item Creation"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generic struct used by all events
|
|
||||||
struct PlayerEvent {
|
|
||||||
int64 account_id;
|
|
||||||
std::string account_name;
|
|
||||||
int64 character_id;
|
|
||||||
std::string character_name;
|
|
||||||
int64 guild_id;
|
|
||||||
std::string guild_name;
|
|
||||||
int zone_id;
|
|
||||||
std::string zone_short_name;
|
|
||||||
std::string zone_long_name;
|
|
||||||
int instance_id;
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float heading;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(account_id),
|
|
||||||
CEREAL_NVP(account_name),
|
|
||||||
CEREAL_NVP(character_id),
|
|
||||||
CEREAL_NVP(character_name),
|
|
||||||
CEREAL_NVP(guild_id),
|
|
||||||
CEREAL_NVP(guild_name),
|
|
||||||
CEREAL_NVP(zone_id),
|
|
||||||
CEREAL_NVP(zone_short_name),
|
|
||||||
CEREAL_NVP(zone_long_name),
|
|
||||||
CEREAL_NVP(instance_id),
|
|
||||||
CEREAL_NVP(x),
|
|
||||||
CEREAL_NVP(y),
|
|
||||||
CEREAL_NVP(z),
|
|
||||||
CEREAL_NVP(heading)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// contains metadata in use for things like log/discord formatters
|
|
||||||
// along with the actual event to be persisted
|
|
||||||
struct PlayerEventContainer {
|
|
||||||
PlayerEvent player_event;
|
|
||||||
PlayerEventLogsRepository::PlayerEventLogs player_event_log;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(player_event),
|
|
||||||
CEREAL_NVP(player_event_log)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in events with no extra data
|
|
||||||
struct EmptyEvent {
|
|
||||||
std::string noop; // noop, gets discard upstream
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(noop)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
struct ItemCreationEvent {
|
|
||||||
int64 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 to_slot;
|
|
||||||
int16 charges;
|
|
||||||
uint32 aug1;
|
|
||||||
uint32 aug2;
|
|
||||||
uint32 aug3;
|
|
||||||
uint32 aug4;
|
|
||||||
uint32 aug5;
|
|
||||||
uint32 aug6;
|
|
||||||
bool attuned;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(to_slot),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(aug1),
|
|
||||||
CEREAL_NVP(aug2),
|
|
||||||
CEREAL_NVP(aug3),
|
|
||||||
CEREAL_NVP(aug4),
|
|
||||||
CEREAL_NVP(aug5),
|
|
||||||
CEREAL_NVP(aug6),
|
|
||||||
CEREAL_NVP(attuned)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
struct TradeItem {
|
|
||||||
int64 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
int32 slot;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(item_name),
|
|
||||||
CEREAL_NVP(slot)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// used in Trade event
|
|
||||||
class TradeItemEntry {
|
|
||||||
public:
|
|
||||||
uint16 slot;
|
|
||||||
uint32 item_id;
|
|
||||||
std::string item_name;
|
|
||||||
uint16 charges;
|
|
||||||
uint32 aug_1_item_id;
|
|
||||||
std::string aug_1_item_name;
|
|
||||||
uint32 aug_2_item_id;
|
|
||||||
std::string aug_2_item_name;
|
|
||||||
uint32 aug_3_item_id;
|
|
||||||
std::string aug_3_item_name;
|
|
||||||
uint32 aug_4_item_id;
|
|
||||||
std::string aug_4_item_name;
|
|
||||||
uint32 aug_5_item_id;
|
|
||||||
std::string aug_5_item_name;
|
|
||||||
uint32 aug_6_item_id;
|
|
||||||
std::string aug_6_item_name;
|
|
||||||
bool in_bag;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(slot),
|
|
||||||
CEREAL_NVP(item_id),
|
|
||||||
CEREAL_NVP(charges),
|
|
||||||
CEREAL_NVP(aug_1_item_id),
|
|
||||||
CEREAL_NVP(aug_2_item_id),
|
|
||||||
CEREAL_NVP(aug_3_item_id),
|
|
||||||
CEREAL_NVP(aug_4_item_id),
|
|
||||||
CEREAL_NVP(aug_5_item_id),
|
|
||||||
CEREAL_NVP(in_bag)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Events
|
|
||||||
*/
|
|
||||||
struct Money {
|
|
||||||
int32 platinum;
|
|
||||||
int32 gold;
|
|
||||||
int32 silver;
|
|
||||||
int32 copper;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(platinum),
|
|
||||||
CEREAL_NVP(gold),
|
|
||||||
CEREAL_NVP(silver),
|
|
||||||
CEREAL_NVP(copper)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TradeEvent {
|
|
||||||
uint32 character_1_id;
|
|
||||||
std::string character_1_name;
|
|
||||||
uint32 character_2_id;
|
|
||||||
std::string character_2_name;
|
|
||||||
Money character_1_give_money;
|
|
||||||
Money character_2_give_money;
|
|
||||||
std::vector<TradeItemEntry> character_1_give_items;
|
|
||||||
std::vector<TradeItemEntry> character_2_give_items;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(character_1_id),
|
|
||||||
CEREAL_NVP(character_1_name),
|
|
||||||
CEREAL_NVP(character_2_id),
|
|
||||||
CEREAL_NVP(character_2_name),
|
|
||||||
CEREAL_NVP(character_1_give_money),
|
|
||||||
CEREAL_NVP(character_2_give_money),
|
|
||||||
CEREAL_NVP(character_1_give_items),
|
|
||||||
CEREAL_NVP(character_2_give_items)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GMCommandEvent {
|
|
||||||
std::string message;
|
|
||||||
std::string target;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(message),
|
|
||||||
CEREAL_NVP(target)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZoningEvent {
|
|
||||||
std::string from_zone_long_name;
|
|
||||||
std::string from_zone_short_name;
|
|
||||||
int32 from_zone_id;
|
|
||||||
int32 from_instance_id;
|
|
||||||
int32 from_instance_version;
|
|
||||||
std::string to_zone_long_name;
|
|
||||||
std::string to_zone_short_name;
|
|
||||||
int32 to_zone_id;
|
|
||||||
int32 to_instance_id;
|
|
||||||
int32 to_instance_version;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(
|
|
||||||
CEREAL_NVP(from_zone_long_name),
|
|
||||||
CEREAL_NVP(from_zone_short_name),
|
|
||||||
CEREAL_NVP(from_zone_id),
|
|
||||||
CEREAL_NVP(from_instance_id),
|
|
||||||
CEREAL_NVP(from_instance_version),
|
|
||||||
CEREAL_NVP(to_zone_long_name),
|
|
||||||
CEREAL_NVP(to_zone_short_name),
|
|
||||||
CEREAL_NVP(to_zone_id),
|
|
||||||
CEREAL_NVP(to_instance_id),
|
|
||||||
CEREAL_NVP(to_instance_version)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAGainedEvent {
|
|
||||||
uint32 aa_gained;
|
|
||||||
|
|
||||||
// cereal
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar)
|
|
||||||
{
|
|
||||||
ar(CEREAL_NVP(aa_gained));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AAPurchasedEvent {
|
|
||||||
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)
|
|
||||||
+18
-4
@@ -132,7 +132,7 @@ enum { //reuse times
|
|||||||
InstillDoubtReuseTime = 9,
|
InstillDoubtReuseTime = 9,
|
||||||
FishingReuseTime = 11,
|
FishingReuseTime = 11,
|
||||||
ForagingReuseTime = 50,
|
ForagingReuseTime = 50,
|
||||||
MendReuseTime = 360,
|
MendReuseTime = 290,
|
||||||
BashReuseTime = 5,
|
BashReuseTime = 5,
|
||||||
BackstabReuseTime = 9,
|
BackstabReuseTime = 9,
|
||||||
KickReuseTime = 5,
|
KickReuseTime = 5,
|
||||||
@@ -218,14 +218,14 @@ enum { //some random constants
|
|||||||
#define HARD_LEVEL_CAP 127
|
#define HARD_LEVEL_CAP 127
|
||||||
|
|
||||||
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
||||||
#define USE_NPC_RANGE2 40000 //arbitrary right now
|
#define USE_NPC_RANGE2 200*200 //arbitrary right now
|
||||||
|
|
||||||
// Squared range for rampage 75.0 * 75.0 for now
|
// Squared range for rampage 75.0 * 75.0 for now
|
||||||
#define NPC_RAMPAGE_RANGE2 5625.0f
|
#define NPC_RAMPAGE_RANGE2 5625.0f
|
||||||
|
|
||||||
//the formula for experience for killing a mob.
|
//the formula for experience for killing a mob.
|
||||||
//level is the only valid variable to use
|
//level is the only valid variable to use
|
||||||
#define EXP_FORMULA (level * level * 75 * 35 / 10)
|
#define EXP_FORMULA level*level*75*35/10
|
||||||
|
|
||||||
#define HIGHEST_AA_VALUE 35
|
#define HIGHEST_AA_VALUE 35
|
||||||
|
|
||||||
@@ -244,16 +244,30 @@ enum {
|
|||||||
minStatusToUseGMCommands = 80,
|
minStatusToUseGMCommands = 80,
|
||||||
minStatusToKick = 150,
|
minStatusToKick = 150,
|
||||||
minStatusToAvoidFalling = 100,
|
minStatusToAvoidFalling = 100,
|
||||||
|
minStatusToHaveInvalidSpells = 80,
|
||||||
|
minStatusToHaveInvalidSkills = 80,
|
||||||
minStatusToIgnoreZoneFlags = 80,
|
minStatusToIgnoreZoneFlags = 80,
|
||||||
minStatusToSeeOthersZoneFlags = 80,
|
minStatusToSeeOthersZoneFlags = 80,
|
||||||
minStatusToEditOtherGuilds = 80,
|
minStatusToEditOtherGuilds = 80,
|
||||||
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
commandMovecharSelfOnly = 80, //below this == only self move allowed
|
||||||
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
|
||||||
|
commandZoneToSpecials = 80, //zone to cshome, out of load zones
|
||||||
|
commandToggleAI = 250, //can turn NPC AI on and off
|
||||||
commandCastSpecials = 100, //can cast special spells
|
commandCastSpecials = 100, //can cast special spells
|
||||||
commandInstacast = 100, //insta-cast all #casted spells
|
commandInstacast = 100, //insta-cast all #casted spells
|
||||||
|
commandLevelAboveCap = 100, //can #level players above level cap
|
||||||
|
commandLevelNPCAboveCap = 100, //can #level NPCs above level cap
|
||||||
|
commandSetSkillsOther = 100, //ability to setskills on others
|
||||||
|
commandRaceOthers = 100, //ability to #race on others
|
||||||
|
commandGenderOthers = 100, //ability to #gender on others
|
||||||
|
commandTextureOthers = 100, //ability to #texture on others
|
||||||
commandDoAnimOthers = 100, //can #doanim on others
|
commandDoAnimOthers = 100, //can #doanim on others
|
||||||
commandLockZones = 101, //can lock or unlock zones
|
commandLockZones = 101, //can lock or unlock zones
|
||||||
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
commandEditPlayerCorpses = 150, //can Edit Player Corpses
|
||||||
|
commandChangeFlags = 200, //ability to set/refresh flags
|
||||||
|
commandBanPlayers = 100, //can set bans on players
|
||||||
|
commandChangeDatarate = 201, //edit client's data rate
|
||||||
|
commandZoneToCoords = 0, //can #zone with coords
|
||||||
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
|
||||||
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
commandInvSnapshot = 150 //ability to clear/restore snapshots
|
||||||
};
|
};
|
||||||
@@ -281,7 +295,7 @@ Developer configuration
|
|||||||
|
|
||||||
#define COMMON_PROFILE
|
#define COMMON_PROFILE
|
||||||
|
|
||||||
#define PROFILE_DUMP_TIME 180
|
#define PROFILE_DUMP_TIME 3*60
|
||||||
#endif //EQPROFILE
|
#endif //EQPROFILE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
@@ -81,26 +80,3 @@ std::string File::GetCwd()
|
|||||||
{
|
{
|
||||||
return fs::current_path().string();
|
return fs::current_path().string();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileContentsResult File::GetContents(const std::string &file_name)
|
|
||||||
{
|
|
||||||
std::string error;
|
|
||||||
std::ifstream f;
|
|
||||||
f.open(file_name);
|
|
||||||
std::string line;
|
|
||||||
std::string lines;
|
|
||||||
if (f.is_open()) {
|
|
||||||
while (f) {
|
|
||||||
std::getline(f, line);
|
|
||||||
lines += line + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error = fmt::format("Couldn't open file [{}]", file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FileContentsResult{
|
|
||||||
.contents = lines,
|
|
||||||
.error = error,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,16 +25,10 @@
|
|||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
struct FileContentsResult {
|
|
||||||
std::string contents;
|
|
||||||
std::string error;
|
|
||||||
};
|
|
||||||
|
|
||||||
class File {
|
class File {
|
||||||
public:
|
public:
|
||||||
static bool Exists(const std::string &name);
|
static bool Exists(const std::string &name);
|
||||||
static void Makedir(const std::string& directory_name);
|
static void Makedir(const std::string& directory_name);
|
||||||
static FileContentsResult GetContents(const std::string &file_name);
|
|
||||||
static std::string FindEqemuConfigPath();
|
static std::string FindEqemuConfigPath();
|
||||||
static std::string GetCwd();
|
static std::string GetCwd();
|
||||||
};
|
};
|
||||||
|
|||||||
+21
-17
@@ -61,7 +61,7 @@ bool BaseGuildManager::LoadGuilds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
_CreateGuild(Strings::ToUnsignedInt(row[0]), row[1], Strings::ToUnsignedInt(row[2]), Strings::ToUnsignedInt(row[3]), row[4], row[5], row[6], row[7]);
|
_CreateGuild(atoi(row[0]), row[1], atoi(row[2]), atoi(row[3]), row[4], row[5], row[6], row[7]);
|
||||||
|
|
||||||
LogInfo("Loaded [{}] Guilds", Strings::Commify(std::to_string(results.RowCount())));
|
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)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
{
|
{
|
||||||
uint32 guild_id = Strings::ToUnsignedInt(row[0]);
|
uint32 guild_id = atoi(row[0]);
|
||||||
uint8 rankn = Strings::ToUnsignedInt(row[1]);
|
uint8 rankn = atoi(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
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();
|
auto row = results.begin();
|
||||||
|
|
||||||
info = _CreateGuild(guild_id, row[0], Strings::ToUnsignedInt(row[1]), Strings::ToUnsignedInt(row[2]), row[3], row[4], row[5], row[6]);
|
info = _CreateGuild(guild_id, row[0], atoi(row[1]), atoi(row[2]), row[3], row[4], row[5], row[6]);
|
||||||
|
|
||||||
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
query = StringFormat("SELECT guild_id, `rank`, title, can_hear, can_speak, can_invite, can_remove, can_promote, can_demote, can_motd, can_warpeace "
|
||||||
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
"FROM guild_ranks WHERE guild_id=%lu", (unsigned long)guild_id);
|
||||||
@@ -144,7 +144,7 @@ bool BaseGuildManager::RefreshGuild(uint32 guild_id) {
|
|||||||
|
|
||||||
for (auto row=results.begin();row!=results.end();++row)
|
for (auto row=results.begin();row!=results.end();++row)
|
||||||
{
|
{
|
||||||
uint8 rankn = Strings::ToUnsignedInt(row[1]);
|
uint8 rankn = atoi(row[1]);
|
||||||
|
|
||||||
if(rankn > GUILD_MAX_RANK) {
|
if(rankn > GUILD_MAX_RANK) {
|
||||||
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
LogGuilds("Found invalid (too high) rank [{}] for guild [{}], skipping", rankn, guild_id);
|
||||||
@@ -787,7 +787,9 @@ bool BaseGuildManager::GetBankerFlag(uint32 CharID)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return Strings::ToBool(row[0]);
|
bool IsBanker = atoi(row[0]);
|
||||||
|
|
||||||
|
return IsBanker;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
|
bool BaseGuildManager::DBSetAltFlag(uint32 charid, bool is_alt)
|
||||||
@@ -815,7 +817,9 @@ bool BaseGuildManager::GetAltFlag(uint32 CharID)
|
|||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
return Strings::ToBool(row[0]);
|
bool IsAlt = atoi(row[0]);
|
||||||
|
|
||||||
|
return IsAlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
|
bool BaseGuildManager::DBSetTributeFlag(uint32 charid, bool enabled) {
|
||||||
@@ -869,19 +873,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` "
|
" FROM `character_data` AS c LEFT JOIN `guild_members` AS g ON c.`id` = g.`char_id` "
|
||||||
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
||||||
//fields from `characer_`
|
//fields from `characer_`
|
||||||
into.char_id = Strings::ToUnsignedInt(row[0]);
|
into.char_id = atoi(row[0]);
|
||||||
into.char_name = row[1];
|
into.char_name = row[1];
|
||||||
into.class_ = Strings::ToUnsignedInt(row[2]);
|
into.class_ = atoi(row[2]);
|
||||||
into.level = Strings::ToUnsignedInt(row[3]);
|
into.level = atoi(row[3]);
|
||||||
into.time_last_on = Strings::ToUnsignedInt(row[4]);
|
into.time_last_on = atoul(row[4]);
|
||||||
into.zone_id = Strings::ToUnsignedInt(row[5]);
|
into.zone_id = atoi(row[5]);
|
||||||
|
|
||||||
//fields from `guild_members`, leave at defaults if missing
|
//fields from `guild_members`, leave at defaults if missing
|
||||||
into.guild_id = row[6] ? Strings::ToUnsignedInt(row[6]) : GUILD_NONE;
|
into.guild_id = row[6] ? atoi(row[6]) : GUILD_NONE;
|
||||||
into.rank = row[7] ? Strings::ToUnsignedInt(row[7]) : (GUILD_MAX_RANK+1);
|
into.rank = row[7] ? atoi(row[7]) : (GUILD_MAX_RANK+1);
|
||||||
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
into.tribute_enable = row[8] ? (row[8][0] == '0'?false:true) : false;
|
||||||
into.total_tribute = row[9] ? Strings::ToUnsignedInt(row[9]) : 0;
|
into.total_tribute = row[9] ? atoi(row[9]) : 0;
|
||||||
into.last_tribute = row[10]? Strings::ToUnsignedInt(row[10]) : 0; //timestamp
|
into.last_tribute = row[10]? atoul(row[10]) : 0; //timestamp
|
||||||
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
into.banker = row[11]? (row[11][0] == '0'?false:true) : false;
|
||||||
into.public_note = row[12]? row[12] : "";
|
into.public_note = row[12]? row[12] : "";
|
||||||
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
into.alt = row[13]? (row[13][0] == '0'?false:true) : false;
|
||||||
@@ -1254,7 +1258,7 @@ uint32 BaseGuildManager::GetGuildIDByCharacterID(uint32 character_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
auto guild_id = Strings::ToUnsignedInt(row[0]);
|
auto guild_id = std::stoul(row[0]);
|
||||||
return guild_id;
|
return guild_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -272,8 +272,6 @@ inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) {
|
|||||||
#include <brotli/encode.h>
|
#include <brotli/encode.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../strings.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Declaration
|
* Declaration
|
||||||
*/
|
*/
|
||||||
@@ -3814,12 +3812,12 @@ inline bool brotli_decompressor::decompress(const char *data,
|
|||||||
if (std::regex_match(b, e, cm, re_another_range)) {
|
if (std::regex_match(b, e, cm, re_another_range)) {
|
||||||
ssize_t first = -1;
|
ssize_t first = -1;
|
||||||
if (!cm.str(1).empty()) {
|
if (!cm.str(1).empty()) {
|
||||||
first = static_cast<ssize_t>(Strings::ToBigInt(cm.str(1)));
|
first = static_cast<ssize_t>(std::stoll(cm.str(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t last = -1;
|
ssize_t last = -1;
|
||||||
if (!cm.str(2).empty()) {
|
if (!cm.str(2).empty()) {
|
||||||
last = static_cast<ssize_t>(Strings::ToBigInt(cm.str(2)));
|
last = static_cast<ssize_t>(std::stoll(cm.str(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first != -1 && last != -1 && first > last) {
|
if (first != -1 && last != -1 && first > last) {
|
||||||
@@ -6690,7 +6688,7 @@ static WSInit wsinit_;
|
|||||||
if (params.empty()) { return Get(path, headers); }
|
if (params.empty()) { return Get(path, headers); }
|
||||||
|
|
||||||
std::string path_with_query = append_query_params(path, params);
|
std::string path_with_query = append_query_params(path, params);
|
||||||
return Get(path_with_query, headers, progress);
|
return Get(path_with_query.c_str(), headers, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
||||||
@@ -6710,7 +6708,7 @@ static WSInit wsinit_;
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string path_with_query = append_query_params(path, params);
|
std::string path_with_query = append_query_params(path, params);
|
||||||
return Get(path_with_query, headers, response_handler,
|
return Get(path_with_query.c_str(), headers, response_handler,
|
||||||
content_receiver, progress);
|
content_receiver, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6807,7 +6805,7 @@ static WSInit wsinit_;
|
|||||||
std::string content_type;
|
std::string content_type;
|
||||||
const auto &body = detail::serialize_multipart_formdata(
|
const auto &body = detail::serialize_multipart_formdata(
|
||||||
items, detail::make_multipart_data_boundary(), content_type);
|
items, detail::make_multipart_data_boundary(), content_type);
|
||||||
return Post(path, headers, body, content_type);
|
return Post(path, headers, body, content_type.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
||||||
@@ -6820,7 +6818,7 @@ static WSInit wsinit_;
|
|||||||
std::string content_type;
|
std::string content_type;
|
||||||
const auto &body =
|
const auto &body =
|
||||||
detail::serialize_multipart_formdata(items, boundary, content_type);
|
detail::serialize_multipart_formdata(items, boundary, content_type);
|
||||||
return Post(path, headers, body, content_type);
|
return Post(path, headers, body, content_type.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Result ClientImpl::Put(const std::string &path) {
|
inline Result ClientImpl::Put(const std::string &path) {
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapRaceClass;
|
fail_state = swapRaceClass;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deity_id && source_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & source_item->Deity)) {
|
if (deity_id && source_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & source_item->Deity)) {
|
||||||
fail_state = swapDeity;
|
fail_state = swapDeity;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapRaceClass;
|
fail_state = swapRaceClass;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deity_id && destination_item->Deity && !(deity::GetDeityBitmask((deity::DeityType)deity_id) & destination_item->Deity)) {
|
if (deity_id && destination_item->Deity && !(deity::ConvertDeityTypeToDeityTypeBit((deity::DeityType)deity_id) & destination_item->Deity)) {
|
||||||
fail_state = swapDeity;
|
fail_state = swapDeity;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -412,11 +412,10 @@ bool EQ::InventoryProfile::DeleteItem(int16 slot_id, int16 quantity) {
|
|||||||
// If there are no charges left on the item,
|
// If there are no charges left on the item,
|
||||||
if (item_to_delete->GetCharges() <= 0) {
|
if (item_to_delete->GetCharges() <= 0) {
|
||||||
// If the item is stackable (e.g arrows), or
|
// If the item is stackable (e.g arrows), or
|
||||||
// the item is not a charged item, or is expendable, delete it
|
// the item is not stackable, and is not a charged item, or is expendable, delete it
|
||||||
if (
|
if (item_to_delete->IsStackable() ||
|
||||||
item_to_delete->IsStackable() ||
|
(!item_to_delete->IsStackable() &&
|
||||||
item_to_delete->GetItem()->MaxCharges == 0 ||
|
((item_to_delete->GetItem()->MaxCharges == 0) || item_to_delete->IsExpendable()))
|
||||||
item_to_delete->IsExpendable()
|
|
||||||
) {
|
) {
|
||||||
// Item can now be destroyed
|
// Item can now be destroyed
|
||||||
InventoryProfile::MarkDirty(item_to_delete);
|
InventoryProfile::MarkDirty(item_to_delete);
|
||||||
@@ -1444,7 +1443,7 @@ int16 EQ::InventoryProfile::_PutItem(int16 slot_id, ItemInstance* inst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == INVALID_INDEX) {
|
if (result == INVALID_INDEX) {
|
||||||
LogError("Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
LogError("InventoryProfile::_PutItem: Invalid slot_id specified ({}) with parent slot id ({})", slot_id, parentSlot);
|
||||||
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
InventoryProfile::MarkDirty(inst); // Slot not found, clean up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,12 +203,12 @@ namespace EQ
|
|||||||
void dumpBankItems();
|
void dumpBankItems();
|
||||||
void dumpSharedBankItems();
|
void dumpSharedBankItems();
|
||||||
|
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, 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, 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, std::string identifier, float value);
|
||||||
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
|
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
|
||||||
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
|
std::string GetCustomItemData(int16 slot_id, std::string identifier);
|
||||||
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
|
static const int GetItemStatValue(uint32 item_id, std::string identifier);
|
||||||
protected:
|
protected:
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Protected Methods
|
// Protected Methods
|
||||||
|
|||||||
+159
-164
@@ -355,186 +355,181 @@ namespace EQ
|
|||||||
|
|
||||||
struct ItemData {
|
struct ItemData {
|
||||||
// Non packet based fields
|
// Non packet based fields
|
||||||
uint8 MinStatus {};
|
uint8 MinStatus;
|
||||||
|
|
||||||
// Packet based fields
|
// Packet based fields
|
||||||
uint8 ItemClass {}; // Item Type: 0=common, 1=container, 2=book
|
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
|
||||||
char Name[64] {}; // Name
|
char Name[64]; // Name
|
||||||
char Lore[80] {}; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
|
char Lore[80]; // Lore Name: *=lore, &=summoned, #=artifact, ~=pending lore
|
||||||
char IDFile[30] {}; // Visible model
|
char IDFile[30]; // Visible model
|
||||||
uint32 ID {}; // Unique ID (also PK for DB)
|
uint32 ID; // Unique ID (also PK for DB)
|
||||||
int32 Weight {}; // Item weight * 10
|
int32 Weight; // Item weight * 10
|
||||||
uint8 NoRent{} ; // No Rent: 0=norent, 255=not norent
|
uint8 NoRent; // No Rent: 0=norent, 255=not norent
|
||||||
uint8 NoDrop {}; // No Drop: 0=nodrop, 255=not nodrop
|
uint8 NoDrop; // No Drop: 0=nodrop, 255=not nodrop
|
||||||
uint8 Size {}; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
|
uint8 Size; // Size: 0=tiny, 1=small, 2=medium, 3=large, 4=giant
|
||||||
uint32 Slots {}; // Bitfield for which slots this item can be used in
|
uint32 Slots; // Bitfield for which slots this item can be used in
|
||||||
uint32 Price {}; // Item cost (?)
|
uint32 Price; // Item cost (?)
|
||||||
uint32 Icon {}; // Icon Number
|
uint32 Icon; // Icon Number
|
||||||
int32 LoreGroup {}; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
|
int32 LoreGroup; // Later items use LoreGroup instead of LoreFlag. we might want to see about changing this to int32 since it is commonly -1 and is constantly being cast from signed (-1) to unsigned (4294967295)
|
||||||
bool LoreFlag {}; // This will be true if LoreGroup is non-zero
|
bool LoreFlag; // This will be true if LoreGroup is non-zero
|
||||||
bool PendingLoreFlag {};
|
bool PendingLoreFlag;
|
||||||
bool ArtifactFlag {};
|
bool ArtifactFlag;
|
||||||
bool SummonedFlag {};
|
bool SummonedFlag;
|
||||||
uint8 FVNoDrop {}; // Firiona Vie nodrop flag
|
uint8 FVNoDrop; // Firiona Vie nodrop flag
|
||||||
uint32 Favor {}; // Individual favor
|
uint32 Favor; // Individual favor
|
||||||
uint32 GuildFavor {}; // Guild favor
|
uint32 GuildFavor; // Guild favor
|
||||||
uint32 PointType {};
|
uint32 PointType;
|
||||||
|
|
||||||
//uint32 Unk117;
|
//uint32 Unk117;
|
||||||
//uint32 Unk118;
|
//uint32 Unk118;
|
||||||
//uint32 Unk121;
|
//uint32 Unk121;
|
||||||
//uint32 Unk124;
|
//uint32 Unk124;
|
||||||
|
|
||||||
uint8 BagType {}; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
|
uint8 BagType; // 0:Small Bag, 1:Large Bag, 2:Quiver, 3:Belt Pouch ... there are 50 types
|
||||||
uint8 BagSlots {}; // Number of slots: can only be 2, 4, 6, 8, or 10
|
uint8 BagSlots; // Number of slots: can only be 2, 4, 6, 8, or 10
|
||||||
uint8 BagSize {}; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
|
uint8 BagSize; // 0:TINY, 1:SMALL, 2:MEDIUM, 3:LARGE, 4:GIANT
|
||||||
uint8 BagWR {}; // 0->100
|
uint8 BagWR; // 0->100
|
||||||
|
|
||||||
bool BenefitFlag {};
|
bool BenefitFlag;
|
||||||
bool Tradeskills {}; // Is this a tradeskill item?
|
bool Tradeskills; // Is this a tradeskill item?
|
||||||
int8 CR {}; // Save vs Cold
|
int8 CR; // Save vs Cold
|
||||||
int8 DR {}; // Save vs Disease
|
int8 DR; // Save vs Disease
|
||||||
int8 PR {}; // Save vs Poison
|
int8 PR; // Save vs Poison
|
||||||
int8 MR {}; // Save vs Magic
|
int8 MR; // Save vs Magic
|
||||||
int8 FR {}; // Save vs Fire
|
int8 FR; // Save vs Fire
|
||||||
int8 AStr {}; // Strength
|
int8 AStr; // Strength
|
||||||
int8 ASta {}; // Stamina
|
int8 ASta; // Stamina
|
||||||
int8 AAgi {}; // Agility
|
int8 AAgi; // Agility
|
||||||
int8 ADex {}; // Dexterity
|
int8 ADex; // Dexterity
|
||||||
int8 ACha {}; // Charisma
|
int8 ACha; // Charisma
|
||||||
int8 AInt {}; // Intelligence
|
int8 AInt; // Intelligence
|
||||||
int8 AWis {}; // Wisdom
|
int8 AWis; // Wisdom
|
||||||
int32 HP {}; // HP
|
int32 HP; // HP
|
||||||
int32 Mana {}; // Mana
|
int32 Mana; // Mana
|
||||||
int32 AC {}; // AC
|
int32 AC; // AC
|
||||||
uint32 Deity {}; // Bitmask of Deities that can equip this item
|
uint32 Deity; // Bitmask of Deities that can equip this item
|
||||||
//uint32 Unk033
|
//uint32 Unk033
|
||||||
int32 SkillModValue {}; // % Mod to skill specified in SkillModType
|
int32 SkillModValue; // % Mod to skill specified in SkillModType
|
||||||
int32 SkillModMax {}; // Max skill point modification
|
int32 SkillModMax; // Max skill point modification
|
||||||
uint32 SkillModType {}; // Type of skill for SkillModValue to apply to
|
uint32 SkillModType; // Type of skill for SkillModValue to apply to
|
||||||
uint32 BaneDmgRace {}; // Bane Damage Race
|
uint32 BaneDmgRace; // Bane Damage Race
|
||||||
int32 BaneDmgAmt {}; // Bane Damage Body Amount
|
int32 BaneDmgAmt; // Bane Damage Body Amount
|
||||||
uint32 BaneDmgBody {}; // Bane Damage Body
|
uint32 BaneDmgBody; // Bane Damage Body
|
||||||
bool Magic {}; // True=Magic Item, False=not
|
bool Magic; // True=Magic Item, False=not
|
||||||
int32 CastTime_ {};
|
int32 CastTime_;
|
||||||
uint8 ReqLevel {}; // Required Level to use item
|
uint8 ReqLevel; // Required Level to use item
|
||||||
uint32 BardType {}; // Bard Skill Type
|
uint32 BardType; // Bard Skill Type
|
||||||
int32 BardValue {}; // Bard Skill Amount
|
int32 BardValue; // Bard Skill Amount
|
||||||
int8 Light {}; // Light
|
int8 Light; // Light
|
||||||
uint8 Delay {}; // Delay * 10
|
uint8 Delay; // Delay * 10
|
||||||
uint8 RecLevel {}; // Recommended level to use item
|
uint8 RecLevel; // Recommended level to use item
|
||||||
uint8 RecSkill {}; // Recommended skill to use item (refers to primary skill of item)
|
uint8 RecSkill; // Recommended skill to use item (refers to primary skill of item)
|
||||||
uint8 ElemDmgType {}; // Elemental Damage Type (1=magic, 2=fire)
|
uint8 ElemDmgType; // Elemental Damage Type (1=magic, 2=fire)
|
||||||
uint8 ElemDmgAmt {}; // Elemental Damage
|
uint8 ElemDmgAmt; // Elemental Damage
|
||||||
uint8 Range {}; // Range of item
|
uint8 Range; // Range of item
|
||||||
uint32 Damage {}; // Delay between item usage (in 0.1 sec increments)
|
uint32 Damage; // Delay between item usage (in 0.1 sec increments)
|
||||||
uint32 Color {}; // RR GG BB 00 <-- as it appears in pc
|
uint32 Color; // RR GG BB 00 <-- as it appears in pc
|
||||||
uint32 Classes {}; // Bitfield of classes that can equip item (1 << class#)
|
uint32 Classes; // Bitfield of classes that can equip item (1 << class#)
|
||||||
uint32 Races {}; // Bitfield of races that can equip item (1 << race#)
|
uint32 Races; // Bitfield of races that can equip item (1 << race#)
|
||||||
//uint32 Unk054 {};
|
//uint32 Unk054;
|
||||||
int16 MaxCharges {}; // Maximum charges items can hold: -1 if not a chargeable item
|
int16 MaxCharges; // Maximum charges items can hold: -1 if not a chargeable item
|
||||||
uint8 ItemType {}; // Item Type/Skill (itemClass* from above)
|
uint8 ItemType; // Item Type/Skill (itemClass* from above)
|
||||||
int32 SubType {}; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
int32 SubType; // Some items have sub types that can be used for other things (unbreakable fishing poles, SE_FFItemClass)
|
||||||
uint8 Material {}; // Item material type
|
uint8 Material; // Item material type
|
||||||
uint32 HerosForgeModel {};// Hero's Forge Armor Model Type (2-13?)
|
uint32 HerosForgeModel;// Hero's Forge Armor Model Type (2-13?)
|
||||||
float SellRate {}; // Sell rate
|
float SellRate; // Sell rate
|
||||||
//uint32 Unk059 {};
|
//uint32 Unk059;
|
||||||
union {
|
union {
|
||||||
uint32 Fulfilment; // Food fulfilment (How long it lasts)
|
uint32 Fulfilment; // Food fulfilment (How long it lasts)
|
||||||
uint32 CastTime; // Cast Time for clicky effects, in milliseconds
|
uint32 CastTime; // Cast Time for clicky effects, in milliseconds
|
||||||
};
|
};
|
||||||
uint32 EliteMaterial {};
|
uint32 EliteMaterial;
|
||||||
int32 ProcRate {};
|
int32 ProcRate;
|
||||||
int8 CombatEffects {}; // PoP: Combat Effects +
|
int8 CombatEffects; // PoP: Combat Effects +
|
||||||
int8 Shielding {}; // PoP: Shielding %
|
int8 Shielding; // PoP: Shielding %
|
||||||
int8 StunResist {}; // PoP: Stun Resist %
|
int8 StunResist; // PoP: Stun Resist %
|
||||||
int8 StrikeThrough {}; // PoP: Strike Through %
|
int8 StrikeThrough; // PoP: Strike Through %
|
||||||
int32 ExtraDmgSkill {};
|
uint32 ExtraDmgSkill;
|
||||||
int32 ExtraDmgAmt {};
|
uint32 ExtraDmgAmt;
|
||||||
int8 SpellShield {}; // PoP: Spell Shield %
|
int8 SpellShield; // PoP: Spell Shield %
|
||||||
int8 Avoidance {}; // PoP: Avoidance +
|
int8 Avoidance; // PoP: Avoidance +
|
||||||
int8 Accuracy {}; // PoP: Accuracy +
|
int8 Accuracy; // PoP: Accuracy +
|
||||||
uint32 CharmFileID {};
|
uint32 CharmFileID;
|
||||||
int32 FactionMod1 {}; // Faction Mod 1
|
int32 FactionMod1; // Faction Mod 1
|
||||||
int32 FactionMod2 {}; // Faction Mod 2
|
int32 FactionMod2; // Faction Mod 2
|
||||||
int32 FactionMod3 {}; // Faction Mod 3
|
int32 FactionMod3; // Faction Mod 3
|
||||||
int32 FactionMod4 {}; // Faction Mod 4
|
int32 FactionMod4; // Faction Mod 4
|
||||||
int32 FactionAmt1 {}; // Faction Amt 1
|
int32 FactionAmt1; // Faction Amt 1
|
||||||
int32 FactionAmt2 {}; // Faction Amt 2
|
int32 FactionAmt2; // Faction Amt 2
|
||||||
int32 FactionAmt3 {}; // Faction Amt 3
|
int32 FactionAmt3; // Faction Amt 3
|
||||||
int32 FactionAmt4 {}; // Faction Amt 4
|
int32 FactionAmt4; // Faction Amt 4
|
||||||
char CharmFile[32] {}; // ?
|
char CharmFile[32]; // ?
|
||||||
uint32 AugType {};
|
uint32 AugType;
|
||||||
uint8 AugSlotType[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Type
|
uint8 AugSlotType[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Type
|
||||||
uint8 AugSlotVisible[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Visible
|
uint8 AugSlotVisible[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Visible
|
||||||
uint8 AugSlotUnk2[invaug::SOCKET_COUNT] {}; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
uint8 AugSlotUnk2[invaug::SOCKET_COUNT]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
|
||||||
uint32 LDoNTheme {};
|
uint32 LDoNTheme;
|
||||||
uint32 LDoNPrice {};
|
uint32 LDoNPrice;
|
||||||
uint32 LDoNSold {};
|
uint32 LDoNSold;
|
||||||
uint32 BaneDmgRaceAmt {};
|
uint32 BaneDmgRaceAmt;
|
||||||
uint32 AugRestrict {};
|
uint32 AugRestrict;
|
||||||
int32 Endur {};
|
int32 Endur;
|
||||||
int32 DotShielding {};
|
int32 DotShielding;
|
||||||
int32 Attack {};
|
int32 Attack;
|
||||||
int32 Regen {};
|
int32 Regen;
|
||||||
int32 ManaRegen {};
|
int32 ManaRegen;
|
||||||
int32 EnduranceRegen {};
|
int32 EnduranceRegen;
|
||||||
int32 Haste {};
|
int32 Haste;
|
||||||
int32 DamageShield {};
|
int32 DamageShield;
|
||||||
uint32 RecastDelay {};
|
uint32 RecastDelay;
|
||||||
int RecastType {};
|
int RecastType;
|
||||||
uint32 AugDistiller {};
|
uint32 AugDistiller;
|
||||||
bool Attuneable {};
|
bool Attuneable;
|
||||||
bool NoPet {};
|
bool NoPet;
|
||||||
bool PotionBelt {};
|
bool PotionBelt;
|
||||||
bool Stackable {};
|
bool Stackable;
|
||||||
bool NoTransfer {};
|
bool NoTransfer;
|
||||||
bool QuestItemFlag {};
|
bool QuestItemFlag;
|
||||||
int16 StackSize {};
|
int16 StackSize;
|
||||||
uint8 PotionBeltSlots {};
|
uint8 PotionBeltSlots;
|
||||||
item::ItemEffect_Struct Click {};
|
item::ItemEffect_Struct Click, Proc, Worn, Focus, Scroll, Bard;
|
||||||
item::ItemEffect_Struct Proc {};
|
|
||||||
item::ItemEffect_Struct Worn {};
|
|
||||||
item::ItemEffect_Struct Focus {};
|
|
||||||
item::ItemEffect_Struct Scroll {};
|
|
||||||
item::ItemEffect_Struct Bard {};
|
|
||||||
|
|
||||||
uint8 Book {}; // 0=Not book, 1=Book
|
uint8 Book; // 0=Not book, 1=Book
|
||||||
uint32 BookType {};
|
uint32 BookType;
|
||||||
char Filename[33] {}; // Filename for book data
|
char Filename[33]; // Filename for book data
|
||||||
// Begin SoF Fields
|
// Begin SoF Fields
|
||||||
int32 SVCorruption {};
|
int32 SVCorruption;
|
||||||
uint32 Purity {};
|
uint32 Purity;
|
||||||
uint8 EvolvingItem {};
|
uint8 EvolvingItem;
|
||||||
uint32 EvolvingID {};
|
uint32 EvolvingID;
|
||||||
uint8 EvolvingLevel {};
|
uint8 EvolvingLevel;
|
||||||
uint8 EvolvingMax {};
|
uint8 EvolvingMax;
|
||||||
uint32 BackstabDmg {};
|
uint32 BackstabDmg;
|
||||||
uint32 DSMitigation {};
|
uint32 DSMitigation;
|
||||||
int32 HeroicStr {};
|
int32 HeroicStr;
|
||||||
int32 HeroicInt {};
|
int32 HeroicInt;
|
||||||
int32 HeroicWis {};
|
int32 HeroicWis;
|
||||||
int32 HeroicAgi {};
|
int32 HeroicAgi;
|
||||||
int32 HeroicDex {};
|
int32 HeroicDex;
|
||||||
int32 HeroicSta {};
|
int32 HeroicSta;
|
||||||
int32 HeroicCha {};
|
int32 HeroicCha;
|
||||||
int32 HeroicMR {};
|
int32 HeroicMR;
|
||||||
int32 HeroicFR {};
|
int32 HeroicFR;
|
||||||
int32 HeroicCR {};
|
int32 HeroicCR;
|
||||||
int32 HeroicDR {};
|
int32 HeroicDR;
|
||||||
int32 HeroicPR {};
|
int32 HeroicPR;
|
||||||
int32 HeroicSVCorrup {};
|
int32 HeroicSVCorrup;
|
||||||
int32 HealAmt {};
|
int32 HealAmt;
|
||||||
int32 SpellDmg {};
|
int32 SpellDmg;
|
||||||
uint32 LDoNSellBackRate {};
|
uint32 LDoNSellBackRate;
|
||||||
uint32 ScriptFileID {};
|
uint32 ScriptFileID;
|
||||||
uint16 ExpendableArrow {};
|
uint16 ExpendableArrow;
|
||||||
uint32 Clairvoyance {};
|
uint32 Clairvoyance;
|
||||||
char ClickName[65] {};
|
char ClickName[65];
|
||||||
char ProcName[65] {};
|
char ProcName[65];
|
||||||
char WornName[65] {};
|
char WornName[65];
|
||||||
char FocusName[65] {};
|
char FocusName[65];
|
||||||
char ScrollName[65] {};
|
char ScrollName[65];
|
||||||
//BardName
|
//BardName
|
||||||
|
|
||||||
bool IsEquipable(uint16 Race, uint16 Class) const;
|
bool IsEquipable(uint16 Race, uint16 Class) const;
|
||||||
|
|||||||
+144
-166
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "inventory_profile.h"
|
#include "inventory_profile.h"
|
||||||
#include "../common/data_verification.h"
|
|
||||||
//#include "classes.h"
|
//#include "classes.h"
|
||||||
//#include "global_define.h"
|
//#include "global_define.h"
|
||||||
//#include "item_instance.h"
|
//#include "item_instance.h"
|
||||||
@@ -58,53 +57,100 @@ static inline int32 GetNextItemInstSerialNumber() {
|
|||||||
// class EQ::ItemInstance
|
// class EQ::ItemInstance
|
||||||
//
|
//
|
||||||
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
EQ::ItemInstance::ItemInstance(const ItemData* item, int16 charges) {
|
||||||
|
m_use_type = ItemInstNormal;
|
||||||
if(item) {
|
if(item) {
|
||||||
m_item = new ItemData(*item);
|
m_item = new ItemData(*item);
|
||||||
|
} else {
|
||||||
|
m_item = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_charges = charges;
|
m_charges = charges;
|
||||||
|
m_price = 0;
|
||||||
if (m_item && m_item->IsClassCommon()) {
|
m_attuned = false;
|
||||||
|
m_merchantslot = 0;
|
||||||
|
if (m_item && m_item->IsClassCommon())
|
||||||
m_color = m_item->Color;
|
m_color = m_item->Color;
|
||||||
}
|
else
|
||||||
|
m_color = 0;
|
||||||
|
m_merchantcount = 1;
|
||||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||||
|
|
||||||
|
m_exp = 0;
|
||||||
|
m_evolveLvl = 0;
|
||||||
|
m_activated = false;
|
||||||
|
m_scaledItem = nullptr;
|
||||||
|
m_evolveInfo = nullptr;
|
||||||
|
m_scaling = false;
|
||||||
|
m_ornamenticon = 0;
|
||||||
|
m_ornamentidfile = 0;
|
||||||
|
m_ornament_hero_model = 0;
|
||||||
|
m_recast_timestamp = 0;
|
||||||
|
m_new_id_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
|
EQ::ItemInstance::ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges) {
|
||||||
|
m_use_type = ItemInstNormal;
|
||||||
m_item = db->GetItem(item_id);
|
m_item = db->GetItem(item_id);
|
||||||
|
|
||||||
if(m_item) {
|
if(m_item) {
|
||||||
m_item = new ItemData(*m_item);
|
m_item = new ItemData(*m_item);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
m_charges = charges;
|
m_item = nullptr;
|
||||||
|
|
||||||
if (m_item && m_item->IsClassCommon()) {
|
|
||||||
m_color = m_item->Color;
|
|
||||||
} else {
|
|
||||||
m_color = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_charges = charges;
|
||||||
|
m_price = 0;
|
||||||
|
m_merchantslot = 0;
|
||||||
|
m_attuned=false;
|
||||||
|
if (m_item && m_item->IsClassCommon())
|
||||||
|
m_color = m_item->Color;
|
||||||
|
else
|
||||||
|
m_color = 0;
|
||||||
|
m_merchantcount = 1;
|
||||||
m_SerialNumber = GetNextItemInstSerialNumber();
|
m_SerialNumber = GetNextItemInstSerialNumber();
|
||||||
|
|
||||||
|
m_exp = 0;
|
||||||
|
m_evolveLvl = 0;
|
||||||
|
m_activated = false;
|
||||||
|
m_scaledItem = nullptr;
|
||||||
|
m_evolveInfo = nullptr;
|
||||||
|
m_scaling = false;
|
||||||
|
m_ornamenticon = 0;
|
||||||
|
m_ornamentidfile = 0;
|
||||||
|
m_ornament_hero_model = 0;
|
||||||
|
m_recast_timestamp = 0;
|
||||||
|
m_new_id_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
EQ::ItemInstance::ItemInstance(ItemInstTypes use_type) {
|
||||||
m_use_type = use_type;
|
m_use_type = use_type;
|
||||||
|
m_item = nullptr;
|
||||||
|
m_charges = 0;
|
||||||
|
m_price = 0;
|
||||||
|
m_attuned = false;
|
||||||
|
m_merchantslot = 0;
|
||||||
|
m_color = 0;
|
||||||
|
|
||||||
|
m_exp = 0;
|
||||||
|
m_evolveLvl = 0;
|
||||||
|
m_activated = false;
|
||||||
|
m_scaledItem = nullptr;
|
||||||
|
m_evolveInfo = nullptr;
|
||||||
|
m_scaling = false;
|
||||||
|
m_ornamenticon = 0;
|
||||||
|
m_ornamentidfile = 0;
|
||||||
|
m_ornament_hero_model = 0;
|
||||||
|
m_recast_timestamp = 0;
|
||||||
|
m_new_id_file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a copy of an EQ::ItemInstance object
|
// Make a copy of an EQ::ItemInstance object
|
||||||
EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
||||||
{
|
{
|
||||||
m_use_type=copy.m_use_type;
|
m_use_type=copy.m_use_type;
|
||||||
|
if(copy.m_item)
|
||||||
if (copy.m_item) {
|
|
||||||
m_item = new ItemData(*copy.m_item);
|
m_item = new ItemData(*copy.m_item);
|
||||||
} else {
|
else
|
||||||
m_item = nullptr;
|
m_item = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
m_charges=copy.m_charges;
|
m_charges=copy.m_charges;
|
||||||
m_price=copy.m_price;
|
m_price=copy.m_price;
|
||||||
@@ -113,7 +159,6 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
m_currentslot=copy.m_currentslot;
|
m_currentslot=copy.m_currentslot;
|
||||||
m_attuned=copy.m_attuned;
|
m_attuned=copy.m_attuned;
|
||||||
m_merchantcount=copy.m_merchantcount;
|
m_merchantcount=copy.m_merchantcount;
|
||||||
|
|
||||||
// Copy container contents
|
// Copy container contents
|
||||||
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
|
for (auto it = copy.m_contents.begin(); it != copy.m_contents.end(); ++it) {
|
||||||
ItemInstance* inst_old = it->second;
|
ItemInstance* inst_old = it->second;
|
||||||
@@ -123,16 +168,14 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
inst_new = inst_old->Clone();
|
inst_new = inst_old->Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst_new) {
|
if (inst_new != nullptr) {
|
||||||
m_contents[it->first] = inst_new;
|
m_contents[it->first] = inst_new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::string>::const_iterator iter;
|
std::map<std::string, std::string>::const_iterator iter;
|
||||||
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
|
for (iter = copy.m_custom_data.begin(); iter != copy.m_custom_data.end(); ++iter) {
|
||||||
m_custom_data[iter->first] = iter->second;
|
m_custom_data[iter->first] = iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SerialNumber = copy.m_SerialNumber;
|
m_SerialNumber = copy.m_SerialNumber;
|
||||||
m_custom_data = copy.m_custom_data;
|
m_custom_data = copy.m_custom_data;
|
||||||
m_timers = copy.m_timers;
|
m_timers = copy.m_timers;
|
||||||
@@ -140,18 +183,15 @@ EQ::ItemInstance::ItemInstance(const ItemInstance& copy)
|
|||||||
m_exp = copy.m_exp;
|
m_exp = copy.m_exp;
|
||||||
m_evolveLvl = copy.m_evolveLvl;
|
m_evolveLvl = copy.m_evolveLvl;
|
||||||
m_activated = copy.m_activated;
|
m_activated = copy.m_activated;
|
||||||
|
if (copy.m_scaledItem)
|
||||||
if (copy.m_scaledItem) {
|
|
||||||
m_scaledItem = new ItemData(*copy.m_scaledItem);
|
m_scaledItem = new ItemData(*copy.m_scaledItem);
|
||||||
} else {
|
else
|
||||||
m_scaledItem = nullptr;
|
m_scaledItem = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
if (copy.m_evolveInfo) {
|
if(copy.m_evolveInfo)
|
||||||
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
|
m_evolveInfo = new EvolveInfo(*copy.m_evolveInfo);
|
||||||
} else {
|
else
|
||||||
m_evolveInfo = nullptr;
|
m_evolveInfo = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
m_scaling = copy.m_scaling;
|
m_scaling = copy.m_scaling;
|
||||||
m_ornamenticon = copy.m_ornamenticon;
|
m_ornamenticon = copy.m_ornamenticon;
|
||||||
@@ -176,13 +216,11 @@ bool EQ::ItemInstance::IsType(item::ItemClass item_class) const
|
|||||||
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
|
// IsType(<ItemClassTypes>) does not protect against 'm_item = nullptr'
|
||||||
|
|
||||||
// Check usage type
|
// Check usage type
|
||||||
if (m_use_type == ItemInstWorldContainer && item_class == item::ItemClassBag) {
|
if ((m_use_type == ItemInstWorldContainer) && (item_class == item::ItemClassBag))
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_item) {
|
if (!m_item)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return (m_item->ItemClass == item_class);
|
return (m_item->ItemClass == item_class);
|
||||||
}
|
}
|
||||||
@@ -205,21 +243,22 @@ bool EQ::ItemInstance::IsClassBook() const
|
|||||||
// Is item stackable?
|
// Is item stackable?
|
||||||
bool EQ::ItemInstance::IsStackable() const
|
bool EQ::ItemInstance::IsStackable() const
|
||||||
{
|
{
|
||||||
return (m_item && m_item->Stackable);
|
if (!m_item)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return m_item->Stackable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsCharged() const
|
bool EQ::ItemInstance::IsCharged() const
|
||||||
{
|
{
|
||||||
if (!m_item) {
|
if (!m_item)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_item->MaxCharges > 1) {
|
if (m_item->MaxCharges > 1)
|
||||||
return true;
|
return true;
|
||||||
} else {
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Can item be equipped?
|
// Can item be equipped?
|
||||||
bool EQ::ItemInstance::IsEquipable(uint16 race, uint16 class_) const
|
bool EQ::ItemInstance::IsEquipable(uint16 race, uint16 class_) const
|
||||||
@@ -267,32 +306,28 @@ bool EQ::ItemInstance::IsEquipable(int16 slot_id) const
|
|||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmentable() const
|
bool EQ::ItemInstance::IsAugmentable() const
|
||||||
{
|
{
|
||||||
if (!m_item) {
|
if (!m_item)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
||||||
if (m_item->AugSlotType[index] != 0) {
|
if (m_item->AugSlotType[index] != 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
|
bool EQ::ItemInstance::AvailableWearSlot(uint32 aug_wear_slots) const {
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
int index = invslot::EQUIPMENT_BEGIN;
|
int index = invslot::EQUIPMENT_BEGIN;
|
||||||
for (; index <= invslot::EQUIPMENT_END; ++index) {
|
for (; index <= invslot::EQUIPMENT_END; ++index) {
|
||||||
if (m_item->Slots & (1 << index)) {
|
if (m_item->Slots & (1 << index)) {
|
||||||
if (aug_wear_slots & (1 << index)) {
|
if (aug_wear_slots & (1 << index))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return (index <= EQ::invslot::EQUIPMENT_END);
|
return (index <= EQ::invslot::EQUIPMENT_END);
|
||||||
}
|
}
|
||||||
@@ -323,26 +358,14 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
|
|||||||
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
|
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augtype, uint8 slot) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if ((!GetItem(slot) && m_item->AugSlotVisible[slot]) && augtype == -1 || (m_item->AugSlotType[slot] && ((1 << (m_item->AugSlotType[slot] - 1)) & augtype))) {
|
||||||
(
|
|
||||||
!GetItem(slot) &&
|
|
||||||
m_item->AugSlotVisible[slot]
|
|
||||||
) &&
|
|
||||||
augment_type == -1 ||
|
|
||||||
(
|
|
||||||
m_item->AugSlotType[slot] &&
|
|
||||||
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,10 +382,9 @@ EQ::ItemInstance* EQ::ItemInstance::GetItem(uint8 index) const
|
|||||||
|
|
||||||
uint32 EQ::ItemInstance::GetItemID(uint8 slot) const
|
uint32 EQ::ItemInstance::GetItemID(uint8 slot) const
|
||||||
{
|
{
|
||||||
const auto item = GetItem(slot);
|
ItemInstance *item = GetItem(slot);
|
||||||
if (item) {
|
if (item)
|
||||||
return item->GetID();
|
return item->GetID();
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -486,21 +508,14 @@ uint8 EQ::ItemInstance::FirstOpenSlot() const
|
|||||||
|
|
||||||
uint8 EQ::ItemInstance::GetTotalItemCount() const
|
uint8 EQ::ItemInstance::GetTotalItemCount() const
|
||||||
{
|
{
|
||||||
if (!m_item) {
|
if (!m_item)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
uint8 item_count = 1;
|
uint8 item_count = 1;
|
||||||
|
|
||||||
if (!m_item->IsClassBag()) {
|
if (m_item && !m_item->IsClassBag()) { return item_count; }
|
||||||
return item_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) {
|
for (int index = invbag::SLOT_BEGIN; index < m_item->BagSlots; ++index) { if (GetItem(index)) { ++item_count; } }
|
||||||
if (GetItem(index)) {
|
|
||||||
++item_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return item_count;
|
return item_count;
|
||||||
}
|
}
|
||||||
@@ -528,99 +543,78 @@ EQ::ItemInstance* EQ::ItemInstance::GetAugment(uint8 augment_index) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::IsOrnamentationAugment(EQ::ItemInstance* augment) const
|
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAug(int32 ornamentationAugtype) const
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon() || !augment) {
|
if (!m_item || !m_item->IsClassCommon()) { return nullptr; }
|
||||||
return false;
|
if (ornamentationAugtype == 0) { return nullptr; }
|
||||||
}
|
|
||||||
|
|
||||||
const auto augment_item = augment->GetItem();
|
|
||||||
if (!augment_item) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& idfile = augment_item->IDFile;
|
|
||||||
|
|
||||||
|
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++)
|
||||||
|
{
|
||||||
|
if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
|
||||||
|
{
|
||||||
|
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
|
||||||
if (
|
if (
|
||||||
EQ::ValueWithin(
|
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
|
||||||
augment->GetAugmentType(),
|
|| strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
|
||||||
OrnamentationAugmentTypes::StandardOrnamentation,
|
&& GetAugment(i)->GetItem()->HerosForgeModel == 0
|
||||||
OrnamentationAugmentTypes::SpecialOrnamentation
|
)
|
||||||
) ||
|
|
||||||
(
|
|
||||||
idfile != "IT63" &&
|
|
||||||
idfile != "IT64"
|
|
||||||
) ||
|
|
||||||
augment_item->HerosForgeModel
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
|
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
continue;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
return GetAugment(i);
|
||||||
for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++) {
|
|
||||||
const auto augment = GetAugment(i);
|
|
||||||
if (augment && IsOrnamentationAugment(augment)) {
|
|
||||||
return augment;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const
|
uint32 EQ::ItemInstance::GetOrnamentHeroModel(int32 material_slot) const {
|
||||||
{
|
|
||||||
// Not a Hero Forge item.
|
// Not a Hero Forge item.
|
||||||
if (m_ornament_hero_model == 0 || material_slot < 0) {
|
if (m_ornament_hero_model == 0 || material_slot < 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
// Item is using an explicit Hero Forge ID
|
// Item is using an explicit Hero Forge ID
|
||||||
if (m_ornament_hero_model >= 1000) {
|
if (m_ornament_hero_model >= 1000)
|
||||||
return m_ornament_hero_model;
|
return m_ornament_hero_model;
|
||||||
}
|
|
||||||
|
|
||||||
// Item is using a shorthand ID
|
// Item is using a shorthand ID
|
||||||
return (m_ornament_hero_model * 100) + material_slot;
|
return (m_ornament_hero_model * 100) + material_slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::UpdateOrnamentationInfo()
|
bool EQ::ItemInstance::UpdateOrnamentationInfo() {
|
||||||
{
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bool ornamentSet = false;
|
||||||
|
|
||||||
|
int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||||
|
if (GetOrnamentationAug(ornamentationAugtype))
|
||||||
|
{
|
||||||
|
const ItemData* ornamentItem;
|
||||||
|
ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||||
|
if (ornamentItem != nullptr)
|
||||||
|
{
|
||||||
|
SetOrnamentIcon(ornamentItem->Icon);
|
||||||
|
SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
|
||||||
|
if (strlen(ornamentItem->IDFile) > 2)
|
||||||
|
{
|
||||||
|
SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2]));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
const auto augment = GetOrnamentationAugment();
|
{
|
||||||
|
|
||||||
if (augment) {
|
|
||||||
const auto augment_item = GetOrnamentationAugment()->GetItem();
|
|
||||||
|
|
||||||
if (augment_item) {
|
|
||||||
SetOrnamentIcon(augment_item->Icon);
|
|
||||||
SetOrnamentHeroModel(augment_item->HerosForgeModel);
|
|
||||||
|
|
||||||
if (strlen(augment_item->IDFile) > 2) {
|
|
||||||
SetOrnamentationIDFile(Strings::ToUnsignedInt(&augment_item->IDFile[2]));
|
|
||||||
} else {
|
|
||||||
SetOrnamentationIDFile(0);
|
SetOrnamentationIDFile(0);
|
||||||
}
|
}
|
||||||
|
ornamentSet = true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
SetOrnamentIcon(0);
|
SetOrnamentIcon(0);
|
||||||
SetOrnamentHeroModel(0);
|
SetOrnamentHeroModel(0);
|
||||||
SetOrnamentationIDFile(0);
|
SetOrnamentationIDFile(0);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return ornamentSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
|
bool EQ::ItemInstance::CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll) {
|
||||||
@@ -720,15 +714,13 @@ EQ::ItemInstance* EQ::ItemInstance::RemoveAugment(uint8 index)
|
|||||||
|
|
||||||
bool EQ::ItemInstance::IsAugmented()
|
bool EQ::ItemInstance::IsAugmented()
|
||||||
{
|
{
|
||||||
if (!m_item || !m_item->IsClassCommon()) {
|
if (!m_item || !m_item->IsClassCommon())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
|
for (int index = invaug::SOCKET_BEGIN; index <= invaug::SOCKET_END; ++index) {
|
||||||
if (GetAugmentItemID(slot_id)) {
|
if (GetAugmentItemID(index))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -836,20 +828,7 @@ std::string EQ::ItemInstance::GetCustomDataString() const {
|
|||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::ItemInstance::SetCustomDataString(const std::string& str)
|
std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
|
||||||
{
|
|
||||||
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);
|
std::map<std::string, std::string>::const_iterator iter = m_custom_data.find(identifier);
|
||||||
if (iter != m_custom_data.end()) {
|
if (iter != m_custom_data.end()) {
|
||||||
return iter->second;
|
return iter->second;
|
||||||
@@ -858,33 +837,33 @@ std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, const std::string& value) {
|
void EQ::ItemInstance::SetCustomData(std::string identifier, std::string value) {
|
||||||
DeleteCustomData(identifier);
|
DeleteCustomData(identifier);
|
||||||
m_custom_data[identifier] = value;
|
m_custom_data[identifier] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, int value) {
|
void EQ::ItemInstance::SetCustomData(std::string identifier, int value) {
|
||||||
DeleteCustomData(identifier);
|
DeleteCustomData(identifier);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << value;
|
ss << value;
|
||||||
m_custom_data[identifier] = ss.str();
|
m_custom_data[identifier] = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, float value) {
|
void EQ::ItemInstance::SetCustomData(std::string identifier, float value) {
|
||||||
DeleteCustomData(identifier);
|
DeleteCustomData(identifier);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << value;
|
ss << value;
|
||||||
m_custom_data[identifier] = ss.str();
|
m_custom_data[identifier] = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::ItemInstance::SetCustomData(const std::string& identifier, bool value) {
|
void EQ::ItemInstance::SetCustomData(std::string identifier, bool value) {
|
||||||
DeleteCustomData(identifier);
|
DeleteCustomData(identifier);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << value;
|
ss << value;
|
||||||
m_custom_data[identifier] = ss.str();
|
m_custom_data[identifier] = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::ItemInstance::DeleteCustomData(const std::string& identifier) {
|
void EQ::ItemInstance::DeleteCustomData(std::string identifier) {
|
||||||
auto iter = m_custom_data.find(identifier);
|
auto iter = m_custom_data.find(identifier);
|
||||||
if (iter != m_custom_data.end()) {
|
if (iter != m_custom_data.end()) {
|
||||||
m_custom_data.erase(iter);
|
m_custom_data.erase(iter);
|
||||||
@@ -936,9 +915,8 @@ bool EQ::ItemInstance::IsDroppable(bool recurse) const
|
|||||||
|
|
||||||
void EQ::ItemInstance::Initialize(SharedDatabase *db) {
|
void EQ::ItemInstance::Initialize(SharedDatabase *db) {
|
||||||
// if there's no actual item, don't do anything
|
// if there's no actual item, don't do anything
|
||||||
if (!m_item) {
|
if (!m_item)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// initialize scaling items
|
// initialize scaling items
|
||||||
if (m_item->CharmFileID != 0) {
|
if (m_item->CharmFileID != 0) {
|
||||||
@@ -947,7 +925,7 @@ void EQ::ItemInstance::Initialize(SharedDatabase *db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initialize evolving items
|
// initialize evolving items
|
||||||
else if (db && m_item->LoreGroup >= 1000) {
|
else if ((db) && m_item->LoreGroup >= 1000 && m_item->LoreGroup != -1) {
|
||||||
// not complete yet
|
// not complete yet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-44
@@ -51,11 +51,6 @@ typedef enum {
|
|||||||
byFlagNotSet //apply action if the flag is NOT set
|
byFlagNotSet //apply action if the flag is NOT set
|
||||||
} byFlagSetting;
|
} byFlagSetting;
|
||||||
|
|
||||||
enum OrnamentationAugmentTypes {
|
|
||||||
StandardOrnamentation = 20,
|
|
||||||
SpecialOrnamentation = 21
|
|
||||||
};
|
|
||||||
|
|
||||||
class SharedDatabase;
|
class SharedDatabase;
|
||||||
|
|
||||||
// ########################################
|
// ########################################
|
||||||
@@ -106,10 +101,9 @@ namespace EQ
|
|||||||
//
|
//
|
||||||
bool IsAugmentable() const;
|
bool IsAugmentable() const;
|
||||||
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
bool AvailableWearSlot(uint32 aug_wear_slots) const;
|
||||||
int8 AvailableAugmentSlot(int32 augment_type) const;
|
int8 AvailableAugmentSlot(int32 augtype) const;
|
||||||
bool IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const;
|
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
|
||||||
inline int GetAugmentType() const { return m_item ? m_item->AugType : 0; }
|
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
|
||||||
inline uint32 GetAugmentRestriction() const { return m_item ? m_item->AugRestrict : 0; }
|
|
||||||
|
|
||||||
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
|
||||||
|
|
||||||
@@ -142,8 +136,7 @@ namespace EQ
|
|||||||
bool IsAugmented();
|
bool IsAugmented();
|
||||||
bool ContainsAugmentByID(uint32 item_id);
|
bool ContainsAugmentByID(uint32 item_id);
|
||||||
int CountAugmentByID(uint32 item_id);
|
int CountAugmentByID(uint32 item_id);
|
||||||
bool IsOrnamentationAugment(EQ::ItemInstance* augment) const;
|
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
|
||||||
ItemInstance* GetOrnamentationAugment() const;
|
|
||||||
bool UpdateOrnamentationInfo();
|
bool UpdateOrnamentationInfo();
|
||||||
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
|
||||||
|
|
||||||
@@ -182,13 +175,12 @@ namespace EQ
|
|||||||
void SetAttuned(bool flag) { m_attuned = flag; }
|
void SetAttuned(bool flag) { m_attuned = flag; }
|
||||||
|
|
||||||
std::string GetCustomDataString() const;
|
std::string GetCustomDataString() const;
|
||||||
std::string GetCustomData(const std::string &identifier);
|
std::string GetCustomData(std::string identifier);
|
||||||
void SetCustomDataString(const std::string& str);
|
void SetCustomData(std::string identifier, std::string value);
|
||||||
void SetCustomData(const std::string &identifier, const std::string& value);
|
void SetCustomData(std::string identifier, int value);
|
||||||
void SetCustomData(const std::string &identifier, int value);
|
void SetCustomData(std::string identifier, float value);
|
||||||
void SetCustomData(const std::string &identifier, float value);
|
void SetCustomData(std::string identifier, bool value);
|
||||||
void SetCustomData(const std::string &identifier, bool value);
|
void DeleteCustomData(std::string identifier);
|
||||||
void DeleteCustomData(const std::string& identifier);
|
|
||||||
|
|
||||||
// Allows treatment of this object as though it were a pointer to m_item
|
// Allows treatment of this object as though it were a pointer to m_item
|
||||||
operator bool() const { return (m_item != nullptr); }
|
operator bool() const { return (m_item != nullptr); }
|
||||||
@@ -311,33 +303,34 @@ namespace EQ
|
|||||||
|
|
||||||
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
|
||||||
|
|
||||||
ItemInstTypes m_use_type {ItemInstNormal}; // Usage type for item
|
ItemInstTypes m_use_type; // Usage type for item
|
||||||
const ItemData* m_item {nullptr}; // Ptr to item data
|
const ItemData* m_item; // Ptr to item data
|
||||||
int16 m_charges {0}; // # of charges for chargeable items
|
int16 m_charges; // # of charges for chargeable items
|
||||||
uint32 m_price {0}; // Bazaar /trader price
|
uint32 m_price; // Bazaar /trader price
|
||||||
uint32 m_color {0};
|
uint32 m_color;
|
||||||
uint32 m_merchantslot {0};
|
uint32 m_merchantslot;
|
||||||
int16 m_currentslot {0};
|
int16 m_currentslot;
|
||||||
bool m_attuned {false};
|
bool m_attuned;
|
||||||
int32 m_merchantcount {1}; //number avaliable on the merchant, -1=unlimited
|
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
|
||||||
int32 m_SerialNumber {0}; // Unique identifier for this instance of an item. Needed for Bazaar.
|
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
|
||||||
uint32 m_exp {0};
|
uint32 m_exp;
|
||||||
int8 m_evolveLvl {0};
|
int8 m_evolveLvl;
|
||||||
bool m_activated {false};
|
bool m_activated;
|
||||||
ItemData* m_scaledItem {nullptr};
|
ItemData* m_scaledItem;
|
||||||
::EvolveInfo* m_evolveInfo {nullptr};
|
::EvolveInfo* m_evolveInfo;
|
||||||
bool m_scaling {false};
|
bool m_scaling;
|
||||||
uint32 m_ornamenticon {0};
|
uint32 m_ornamenticon;
|
||||||
uint32 m_ornamentidfile {0};
|
uint32 m_ornamentidfile;
|
||||||
uint32 m_new_id_file {0};
|
uint32 m_new_id_file;
|
||||||
uint32 m_ornament_hero_model {0};
|
uint32 m_ornament_hero_model;
|
||||||
uint32 m_recast_timestamp {0};
|
uint32 m_recast_timestamp;
|
||||||
int m_task_delivered_count {0};
|
int m_task_delivered_count = 0;
|
||||||
|
|
||||||
// Items inside of this item (augs or contents) {};
|
//
|
||||||
std::map<uint8, ItemInstance*> m_contents {}; // Zero-based index: min=0, max=9
|
// Items inside of this item (augs or contents);
|
||||||
std::map<std::string, std::string> m_custom_data {};
|
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
|
||||||
std::map<std::string, ::Timer> m_timers {};
|
std::map<std::string, std::string> m_custom_data;
|
||||||
|
std::map<std::string, ::Timer> m_timers;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -48,7 +48,5 @@
|
|||||||
#define LANG_HADAL 26
|
#define LANG_HADAL 26
|
||||||
#define LANG_UNKNOWN 27
|
#define LANG_UNKNOWN 27
|
||||||
|
|
||||||
#define MAX_LANGUAGE_SKILL 100
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+118
-2
@@ -18,7 +18,6 @@
|
|||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "strings.h"
|
|
||||||
|
|
||||||
std::map<int,std::string> DBFieldNames;
|
std::map<int,std::string> DBFieldNames;
|
||||||
|
|
||||||
@@ -151,7 +150,7 @@ static char *temp=nullptr;
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ptr++;
|
ptr++;
|
||||||
uint32 id = Strings::ToUnsignedInt(field[id_pos]);
|
uint32 id = atoi(field[id_pos].c_str());
|
||||||
items[id]=field;
|
items[id]=field;
|
||||||
|
|
||||||
for(i=0;i<10;i++) {
|
for(i=0;i<10;i++) {
|
||||||
@@ -214,6 +213,123 @@ std::string x;
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadItemDBFieldNames() {
|
||||||
|
DBFieldNames[0]="N/A"; // Charges
|
||||||
|
DBFieldNames[1]="unknown002"; // ?
|
||||||
|
DBFieldNames[2]="N/A"; // Current Equip Slot
|
||||||
|
DBFieldNames[3]="unknown004";
|
||||||
|
DBFieldNames[4]="unknown005"; // ?
|
||||||
|
DBFieldNames[5]="itemclass"; // "Item Type (0=common, 1=container, 2=book)"
|
||||||
|
DBFieldNames[6]="name"; // Name
|
||||||
|
DBFieldNames[7]="lore"; // "Lore Name (*=lore, &=summoned, #=artifact)"
|
||||||
|
DBFieldNames[8]="idfile"; // IDFile
|
||||||
|
DBFieldNames[9]="id"; // ItemNumber
|
||||||
|
DBFieldNames[10]="weight"; // Weight
|
||||||
|
DBFieldNames[11]="norent"; // "NoRent (0=norent, 255=not norent)"
|
||||||
|
DBFieldNames[12]="nodrop"; // "NoDrop (0=nodrop, 255=not nodrop)"
|
||||||
|
DBFieldNames[13]="size"; // "Size (0=tiny, 1=small, 2=medium, 3=large, 4=giant)"
|
||||||
|
DBFieldNames[14]="slots"; // EquipSlots
|
||||||
|
DBFieldNames[15]="cost"; // Cost
|
||||||
|
DBFieldNames[16]="icon"; // IconNumber
|
||||||
|
DBFieldNames[17]="unknown018";
|
||||||
|
DBFieldNames[18]="unknown019";
|
||||||
|
DBFieldNames[19]="unknown020"; // ?
|
||||||
|
DBFieldNames[20]="tradeskills"; // "Tradeskill Item (1=is a tradeskill item, 0=not)"
|
||||||
|
DBFieldNames[21]="cr"; // SvCold
|
||||||
|
DBFieldNames[22]="dr"; // SvDisease
|
||||||
|
DBFieldNames[23]="pr"; // SvPoison
|
||||||
|
DBFieldNames[24]="mr"; // SvMagic
|
||||||
|
DBFieldNames[25]="fr"; // SvFire
|
||||||
|
DBFieldNames[26]="astr"; // STR
|
||||||
|
DBFieldNames[27]="asta"; // STA
|
||||||
|
DBFieldNames[28]="aagi"; // AGI
|
||||||
|
DBFieldNames[29]="adex"; // DEX
|
||||||
|
DBFieldNames[30]="acha"; // CHA
|
||||||
|
DBFieldNames[31]="aint"; // INT
|
||||||
|
DBFieldNames[32]="awis"; // WIS
|
||||||
|
DBFieldNames[33]="hp"; // HP
|
||||||
|
DBFieldNames[34]="mana"; // Mana
|
||||||
|
DBFieldNames[35]="ac"; // AC
|
||||||
|
DBFieldNames[36]="deity"; // Deity
|
||||||
|
DBFieldNames[37]="skillmodvalue"; // Skill Mod Value
|
||||||
|
DBFieldNames[38]="skillmodtype"; // Skill Mod Type
|
||||||
|
DBFieldNames[39]="banedmgrace"; // Bane Dmg Race
|
||||||
|
DBFieldNames[40]="banedmgamt"; // Band Dmg
|
||||||
|
DBFieldNames[41]="banedmgbody"; // Band Dmg Body
|
||||||
|
DBFieldNames[42]="magic"; // "Magic (0=not magic, 1=magic)"
|
||||||
|
DBFieldNames[43]="casttime2"; // Casttime appears twice
|
||||||
|
DBFieldNames[44]="hasteproclvl"; // "Level (Haste value, rather)"
|
||||||
|
DBFieldNames[45]="reqlevel"; // Required Level
|
||||||
|
DBFieldNames[46]="bardtype"; // Bard Type
|
||||||
|
DBFieldNames[47]="bardvalue"; // Bard Type Amount
|
||||||
|
DBFieldNames[48]="light"; // Light
|
||||||
|
DBFieldNames[49]="delay"; // Attack Delay
|
||||||
|
DBFieldNames[50]="reclevel"; // Recommended Level
|
||||||
|
DBFieldNames[51]="recskill"; // Recommended Skill
|
||||||
|
DBFieldNames[52]="elemdmgamt"; // "Elemental Dmg Type (1=magic, 2=fire, 3=cold, 4=poison, 5=disease)"
|
||||||
|
DBFieldNames[53]="elemdmgtype"; // Elemental Dmg
|
||||||
|
DBFieldNames[54]="effecttype"; // "Effect Type (0=combat, 1=clicky, 2=Worn, 3=Expendable charges, 4=Must Equip Clicky, 5=clicky)"
|
||||||
|
DBFieldNames[55]="range"; // Range
|
||||||
|
DBFieldNames[56]="damage"; // Damage
|
||||||
|
DBFieldNames[57]="color"; // Color
|
||||||
|
DBFieldNames[58]="classes"; // Classes
|
||||||
|
DBFieldNames[59]="races"; // Races
|
||||||
|
DBFieldNames[60]="unknown061";
|
||||||
|
DBFieldNames[61]="spellid"; // SpellId
|
||||||
|
DBFieldNames[62]="maxcharges"; // MaxCharges
|
||||||
|
DBFieldNames[63]="itemtype"; // "Skill (ItemType: 1hs, etc)"
|
||||||
|
DBFieldNames[64]="material"; // Material
|
||||||
|
DBFieldNames[65]="sellrate"; // ** Sell Rate
|
||||||
|
DBFieldNames[66]="unknown067";
|
||||||
|
DBFieldNames[67]="casttime"; // CastTime (milliseconds)
|
||||||
|
DBFieldNames[68]="unknown069";
|
||||||
|
DBFieldNames[69]="unknown070"; // ?
|
||||||
|
DBFieldNames[70]="focusid"; // Focus Effect Spell Id
|
||||||
|
DBFieldNames[71]="combateffects"; // CombatEffects
|
||||||
|
DBFieldNames[72]="shielding"; // Shielding
|
||||||
|
DBFieldNames[73]="stunresist"; // StunResist
|
||||||
|
DBFieldNames[74]="strikethrough"; // StrikeThrough
|
||||||
|
DBFieldNames[75]="unknown076";
|
||||||
|
DBFieldNames[76]="unknown077"; // ?
|
||||||
|
DBFieldNames[77]="spellshield"; // Spell Shield
|
||||||
|
DBFieldNames[78]="avoidance"; // Avoidance
|
||||||
|
DBFieldNames[79]="accuracy"; // Accuracy
|
||||||
|
DBFieldNames[80]="factionmod1"; // Faction Mod Index 1
|
||||||
|
DBFieldNames[81]="factionmod2"; // Faction Mod Index 2
|
||||||
|
DBFieldNames[82]="factionmod3"; // Faction Mod Index 3
|
||||||
|
DBFieldNames[83]="factionmod4"; // Faction Mod Index 4
|
||||||
|
DBFieldNames[84]="factionamt1"; // Faction Mod Value 1
|
||||||
|
DBFieldNames[85]="factionamt2"; // Faction Mod Value 2
|
||||||
|
DBFieldNames[86]="factionamt3"; // Faction Mod Value 3
|
||||||
|
DBFieldNames[87]="factionamt4"; // Faction Mod Value 4
|
||||||
|
DBFieldNames[88]="unknown089";
|
||||||
|
DBFieldNames[89]="charmfile"; // ** Charm File
|
||||||
|
DBFieldNames[90]="unknown091";
|
||||||
|
DBFieldNames[91]="augslot1type"; // Slot1Type
|
||||||
|
DBFieldNames[92]="augslot2type"; // Slot2Type
|
||||||
|
DBFieldNames[93]="augslot3type"; // Slot3Type
|
||||||
|
DBFieldNames[94]="augslot4type"; // Slot4Type
|
||||||
|
DBFieldNames[95]="augslot5type"; // Slot5Type
|
||||||
|
DBFieldNames[96]="ldonpointtheme";
|
||||||
|
DBFieldNames[97]="ldonpointcost"; // ?
|
||||||
|
DBFieldNames[98]="unknown099";
|
||||||
|
DBFieldNames[99]="bagtype"; // bag type
|
||||||
|
DBFieldNames[100]="bagslots"; // bag slots
|
||||||
|
DBFieldNames[101]="bagsize"; // bag size capacity
|
||||||
|
DBFieldNames[102]="bagwr"; // bag weight reduction
|
||||||
|
DBFieldNames[103]="booktype"; // "book type (0=rolled up note, 1=book)"
|
||||||
|
DBFieldNames[104]="unknown105";
|
||||||
|
DBFieldNames[105]="filename"; // Book Filename
|
||||||
|
DBFieldNames[106]="unknown107";
|
||||||
|
DBFieldNames[107]="unknown108";
|
||||||
|
DBFieldNames[108]="loreflag";
|
||||||
|
DBFieldNames[109]="unknown111";
|
||||||
|
DBFieldNames[110]="unknown112";
|
||||||
|
DBFieldNames[111]="unknown113";
|
||||||
|
DBFieldNames[112]="unknown114";
|
||||||
|
DBFieldNames[113]="unknown115"; // ? (end quote)
|
||||||
|
}
|
||||||
|
|
||||||
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
void dump_message_column(unsigned char *buffer, unsigned long length, std::string leader, FILE *to)
|
||||||
{
|
{
|
||||||
unsigned long i,j;
|
unsigned long i,j;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ bool ItemParse(const char *data, int length, std::map<int,std::map<int,std::stri
|
|||||||
|
|
||||||
int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
int Tokenize(std::string s, std::map<int,std::string> & tokens, char delim='|');
|
||||||
|
|
||||||
|
void LoadItemDBFieldNames();
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int print_stacktrace();
|
int print_stacktrace();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "strings.h"
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@@ -131,7 +130,7 @@ bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf
|
|||||||
if (*oIP == 0)
|
if (*oIP == 0)
|
||||||
return false;
|
return false;
|
||||||
if (oPort)
|
if (oPort)
|
||||||
*oPort = Strings::ToUnsignedInt(sep.arg[1]);
|
*oPort = atoi(sep.arg[1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ void MySQLRequestResult::ZeroOut()
|
|||||||
m_RowCount = 0;
|
m_RowCount = 0;
|
||||||
m_RowsAffected = 0;
|
m_RowsAffected = 0;
|
||||||
m_LastInsertedID = 0;
|
m_LastInsertedID = 0;
|
||||||
m_error_message = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLRequestResult::~MySQLRequestResult()
|
MySQLRequestResult::~MySQLRequestResult()
|
||||||
@@ -138,23 +137,3 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
|
|||||||
other.ZeroOut();
|
other.ZeroOut();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MySQLRequestResult::GetErrorNumber() const
|
|
||||||
{
|
|
||||||
return m_ErrorNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MySQLRequestResult::SetErrorNumber(uint32 m_error_number)
|
|
||||||
{
|
|
||||||
m_ErrorNumber = m_error_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string &MySQLRequestResult::GetErrorMessage() const
|
|
||||||
{
|
|
||||||
return m_error_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MySQLRequestResult::SetErrorMessage(const std::string &m_error_message)
|
|
||||||
{
|
|
||||||
MySQLRequestResult::m_error_message = m_error_message;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ private:
|
|||||||
uint32 m_LastInsertedID;
|
uint32 m_LastInsertedID;
|
||||||
uint32 m_ErrorNumber;
|
uint32 m_ErrorNumber;
|
||||||
|
|
||||||
std::string m_error_message;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -45,13 +44,7 @@ public:
|
|||||||
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
||||||
|
|
||||||
bool Success() const { return m_Success;}
|
bool Success() const { return m_Success;}
|
||||||
std::string ErrorMessage() const {
|
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
|
||||||
if (!m_error_message.empty()) {
|
|
||||||
return m_error_message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");
|
|
||||||
}
|
|
||||||
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
||||||
uint32 RowsAffected() const {return m_RowsAffected;}
|
uint32 RowsAffected() const {return m_RowsAffected;}
|
||||||
uint32 RowCount() const {return m_RowCount;}
|
uint32 RowCount() const {return m_RowCount;}
|
||||||
@@ -64,11 +57,6 @@ public:
|
|||||||
MySQLRequestRow& begin() { return m_CurrentRow; }
|
MySQLRequestRow& begin() { return m_CurrentRow; }
|
||||||
MySQLRequestRow& end() { return m_OneBeyondRow; }
|
MySQLRequestRow& end() { return m_OneBeyondRow; }
|
||||||
|
|
||||||
uint32 GetErrorNumber() const;
|
|
||||||
void SetErrorNumber(uint32 m_error_number);
|
|
||||||
const std::string &GetErrorMessage() const;
|
|
||||||
void SetErrorMessage(const std::string &m_error_message);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FreeInternals();
|
void FreeInternals();
|
||||||
void ZeroOut();
|
void ZeroOut();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ EQ::Net::ConsoleServer::ConsoleServer(const std::string &addr, int port)
|
|||||||
m_server = std::make_unique<EQ::Net::TCPServer>();
|
m_server = std::make_unique<EQ::Net::TCPServer>();
|
||||||
m_server->Listen(addr, port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
m_server->Listen(addr, port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
|
||||||
ConsoleServerConnection *c = new ConsoleServerConnection(this, connection);
|
ConsoleServerConnection *c = new ConsoleServerConnection(this, connection);
|
||||||
m_connections.emplace(std::make_pair(c->GetUUID(), std::unique_ptr<ConsoleServerConnection>(c)));
|
m_connections.insert(std::make_pair(c->GetUUID(), std::unique_ptr<ConsoleServerConnection>(c)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
|
|||||||
m_on_new_connection(connection);
|
m_on_new_connection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
|
m_connections.insert(std::make_pair(std::make_pair(addr, port), connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnectionManager::Process()
|
void EQ::Net::DaybreakConnectionManager::Process()
|
||||||
@@ -234,7 +234,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
|||||||
if (m_on_new_connection) {
|
if (m_on_new_connection) {
|
||||||
m_on_new_connection(connection);
|
m_on_new_connection(connection);
|
||||||
}
|
}
|
||||||
m_connections.emplace(std::make_pair(std::make_pair(endpoint, port), connection));
|
m_connections.insert(std::make_pair(std::make_pair(endpoint, port), connection));
|
||||||
connection->ProcessPacket(p);
|
connection->ProcessPacket(p);
|
||||||
}
|
}
|
||||||
else if (data[1] != OP_OutOfSession) {
|
else if (data[1] != OP_OutOfSession) {
|
||||||
@@ -527,7 +527,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
|
|||||||
DynamicPacket *out = new DynamicPacket();
|
DynamicPacket *out = new DynamicPacket();
|
||||||
out->PutPacket(0, p);
|
out->PutPacket(0, p);
|
||||||
|
|
||||||
s->packet_queue.emplace(std::make_pair(seq, out));
|
s->packet_queue.insert(std::make_pair(seq, out));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1427,7 +1427,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||||
m_owner->m_options.resend_delay_min,
|
m_owner->m_options.resend_delay_min,
|
||||||
m_owner->m_options.resend_delay_max);
|
m_owner->m_options.resend_delay_max);
|
||||||
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
|
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||||
stream->sequence_out++;
|
stream->sequence_out++;
|
||||||
|
|
||||||
InternalBufferedSend(first_packet);
|
InternalBufferedSend(first_packet);
|
||||||
@@ -1459,7 +1459,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||||
m_owner->m_options.resend_delay_min,
|
m_owner->m_options.resend_delay_min,
|
||||||
m_owner->m_options.resend_delay_max);
|
m_owner->m_options.resend_delay_max);
|
||||||
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
|
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||||
stream->sequence_out++;
|
stream->sequence_out++;
|
||||||
|
|
||||||
InternalBufferedSend(packet);
|
InternalBufferedSend(packet);
|
||||||
@@ -1483,7 +1483,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||||
m_owner->m_options.resend_delay_min,
|
m_owner->m_options.resend_delay_min,
|
||||||
m_owner->m_options.resend_delay_max);
|
m_owner->m_options.resend_delay_max);
|
||||||
stream->sent_packets.emplace(std::make_pair(stream->sequence_out, sent));
|
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||||
stream->sequence_out++;
|
stream->sequence_out++;
|
||||||
|
|
||||||
InternalBufferedSend(packet);
|
InternalBufferedSend(packet);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions
|
|||||||
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||||
{
|
{
|
||||||
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
||||||
m_streams.emplace(std::make_pair(connection, stream));
|
m_streams.insert(std::make_pair(connection, stream));
|
||||||
if (m_on_new_connection) {
|
if (m_on_new_connection) {
|
||||||
m_on_new_connection(stream);
|
m_on_new_connection(stream);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void EQ::Net::ServertalkClient::SendPacket(ServerPacket *p)
|
|||||||
|
|
||||||
void EQ::Net::ServertalkClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
void EQ::Net::ServertalkClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
||||||
{
|
{
|
||||||
m_message_callbacks.emplace(std::make_pair(opcode, cb));
|
m_message_callbacks.insert(std::make_pair(opcode, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::ServertalkClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
void EQ::Net::ServertalkClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void EQ::Net::ServertalkLegacyClient::SendPacket(ServerPacket *p)
|
|||||||
|
|
||||||
void EQ::Net::ServertalkLegacyClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
void EQ::Net::ServertalkLegacyClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
||||||
{
|
{
|
||||||
m_message_callbacks.emplace(std::make_pair(opcode, cb));
|
m_message_callbacks.insert(std::make_pair(opcode, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::ServertalkLegacyClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
void EQ::Net::ServertalkLegacyClient::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ void EQ::Net::ServertalkServer::Listen(const ServertalkServerOptions& opts)
|
|||||||
|
|
||||||
void EQ::Net::ServertalkServer::OnConnectionIdentified(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
|
void EQ::Net::ServertalkServer::OnConnectionIdentified(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
|
||||||
{
|
{
|
||||||
m_on_ident.emplace(std::make_pair(type, cb));
|
m_on_ident.insert(std::make_pair(type, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::ServertalkServer::OnConnectionRemoved(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
|
void EQ::Net::ServertalkServer::OnConnectionRemoved(const std::string &type, std::function<void(std::shared_ptr<ServertalkServerConnection>)> cb)
|
||||||
{
|
{
|
||||||
m_on_disc.emplace(std::make_pair(type, cb));
|
m_on_disc.insert(std::make_pair(type, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::ServertalkServer::ConnectionDisconnected(ServertalkServerConnection *conn)
|
void EQ::Net::ServertalkServer::ConnectionDisconnected(ServertalkServerConnection *conn)
|
||||||
@@ -75,7 +75,7 @@ void EQ::Net::ServertalkServer::ConnectionIdentified(ServertalkServerConnection
|
|||||||
else {
|
else {
|
||||||
std::vector<std::shared_ptr<EQ::Net::ServertalkServerConnection>> vec;
|
std::vector<std::shared_ptr<EQ::Net::ServertalkServerConnection>> vec;
|
||||||
vec.push_back(*iter);
|
vec.push_back(*iter);
|
||||||
m_ident_connections.emplace(std::make_pair(conn->GetIdentifier(), vec));
|
m_ident_connections.insert(std::make_pair(conn->GetIdentifier(), vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_unident_connections.erase(iter);
|
m_unident_connections.erase(iter);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void EQ::Net::ServertalkServerConnection::SendPacket(ServerPacket *p)
|
|||||||
|
|
||||||
void EQ::Net::ServertalkServerConnection::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
void EQ::Net::ServertalkServerConnection::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
||||||
{
|
{
|
||||||
m_message_callbacks.emplace(std::make_pair(opcode, cb));
|
m_message_callbacks.insert(std::make_pair(opcode, cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::ServertalkServerConnection::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
void EQ::Net::ServertalkServerConnection::OnMessage(std::function<void(uint16_t, EQ::Net::Packet&)> cb)
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ void EQ::Net::TCPConnection::Write(const char *data, size_t count)
|
|||||||
|
|
||||||
WriteBaton *baton = new WriteBaton;
|
WriteBaton *baton = new WriteBaton;
|
||||||
baton->connection = this;
|
baton->connection = this;
|
||||||
baton->buffer = new char[count];
|
baton->buffer = new char[count];;
|
||||||
|
|
||||||
uv_write_t *write_req = new uv_write_t;
|
uv_write_t *write_req = new uv_write_t;
|
||||||
memset(write_req, 0, sizeof(uv_write_t));
|
memset(write_req, 0, sizeof(uv_write_t));
|
||||||
|
|||||||
@@ -1050,7 +1050,7 @@ namespace RoF
|
|||||||
{
|
{
|
||||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -1069,7 +1069,7 @@ namespace RoF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if(gjs->action == groupActLeave)
|
//if(gjs->action == groupActLeave)
|
||||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -1099,7 +1099,7 @@ namespace RoF
|
|||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||||
if (gu2->membername[i][0] != '\0')
|
if (gu2->membername[i][0] != '\0')
|
||||||
{
|
{
|
||||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||||
@@ -1169,7 +1169,7 @@ namespace RoF
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||||
|
|
||||||
@@ -5218,6 +5218,7 @@ namespace RoF
|
|||||||
/**
|
/**
|
||||||
* Ornamentation
|
* Ornamentation
|
||||||
*/
|
*/
|
||||||
|
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
|
||||||
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
|
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
|
||||||
uint32 hero_model = 0;
|
uint32 hero_model = 0;
|
||||||
|
|
||||||
|
|||||||
+5
-17
@@ -35,7 +35,6 @@
|
|||||||
#include "../path_manager.h"
|
#include "../path_manager.h"
|
||||||
#include "../classes.h"
|
#include "../classes.h"
|
||||||
#include "../races.h"
|
#include "../races.h"
|
||||||
#include "../../zone/raids.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -1102,7 +1101,7 @@ namespace RoF2
|
|||||||
{
|
{
|
||||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -1121,7 +1120,7 @@ namespace RoF2
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if(gjs->action == groupActLeave)
|
//if(gjs->action == groupActLeave)
|
||||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -1151,7 +1150,7 @@ namespace RoF2
|
|||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||||
if (gu2->membername[i][0] != '\0')
|
if (gu2->membername[i][0] != '\0')
|
||||||
{
|
{
|
||||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||||
@@ -1221,7 +1220,7 @@ namespace RoF2
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||||
|
|
||||||
@@ -2747,18 +2746,6 @@ namespace RoF2
|
|||||||
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
|
||||||
dest->FastQueuePacket(&outapp);
|
dest->FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
else if (raid_gen->action == raidSetNote)
|
|
||||||
{
|
|
||||||
auto in_note = (RaidGeneral_Struct*)__emu_buffer;
|
|
||||||
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
|
|
||||||
auto note = (RaidGeneral_Struct*)outapp->pBuffer;
|
|
||||||
note->action = raidSetNote;
|
|
||||||
strn0cpy(note->leader_name, in_note->leader_name, sizeof(note->leader_name));
|
|
||||||
strn0cpy(note->player_name, in_note->player_name, sizeof(note->leader_name));
|
|
||||||
strn0cpy(note->note, in_note->note, sizeof(note->note));
|
|
||||||
dest->QueuePacket(outapp);
|
|
||||||
safe_delete(outapp);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
|
||||||
@@ -5490,6 +5477,7 @@ namespace RoF2
|
|||||||
/**
|
/**
|
||||||
* Ornamentation
|
* Ornamentation
|
||||||
*/
|
*/
|
||||||
|
int ornamentation_augment_type = RuleI(Character, OrnamentationAugmentType);
|
||||||
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
|
uint32 ornamentation_icon = (inst->GetOrnamentationIcon() ? inst->GetOrnamentationIcon() : 0);
|
||||||
uint32 hero_model = 0;
|
uint32 hero_model = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -2590,7 +2590,7 @@ struct GroupUpdate_Struct_Live { // New for Live
|
|||||||
|
|
||||||
struct GroupMembers_Struct { // New for Live
|
struct GroupMembers_Struct { // New for Live
|
||||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||||
/*0000*/ uint32 memberlevel; // Guess
|
/*0000*/ uint32 memberlevel; // Guess
|
||||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
/*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
|
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||||
/*0004*/ uint32 action;
|
/*0004*/ uint32 action;
|
||||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
/*0013*/ //char membername[0]; // Null Terminated?
|
||||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||||
|
|||||||
@@ -2566,7 +2566,7 @@ struct GroupUpdate_Struct_Live { // New for Live
|
|||||||
|
|
||||||
struct GroupMembers_Struct { // New for Live
|
struct GroupMembers_Struct { // New for Live
|
||||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||||
/*0000*/ uint32 memberlevel; // Guess
|
/*0000*/ uint32 memberlevel; // Guess
|
||||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
/*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
|
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||||
/*0004*/ uint32 action;
|
/*0004*/ uint32 action;
|
||||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
/*0013*/ //char membername[0]; // Null Terminated?
|
||||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ namespace SoD
|
|||||||
{
|
{
|
||||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -804,7 +804,7 @@ namespace SoD
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if(gjs->action == groupActLeave)
|
//if(gjs->action == groupActLeave)
|
||||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -834,7 +834,7 @@ namespace SoD
|
|||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||||
if (gu2->membername[i][0] != '\0')
|
if (gu2->membername[i][0] != '\0')
|
||||||
{
|
{
|
||||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||||
@@ -902,7 +902,7 @@ namespace SoD
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::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
|
struct GroupMembers_Struct { // New for SoD
|
||||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||||
/*0000*/ uint32 memberlevel; // Guess
|
/*0000*/ uint32 memberlevel; // Guess
|
||||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
/*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
|
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||||
/*0004*/ uint32 action;
|
/*0004*/ uint32 action;
|
||||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
/*0013*/ //char membername[0]; // Null Terminated?
|
||||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||||
|
|||||||
@@ -2095,13 +2095,13 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = Strings::ToInt(&emu->lastName[2]);
|
val = atoi(&emu->lastName[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sep[0] = nullptr;
|
sep[0] = nullptr;
|
||||||
ofs = Strings::ToInt(&emu->lastName[2]);
|
ofs = atoi(&emu->lastName[2]);
|
||||||
sep[0] = '=';
|
sep[0] = '=';
|
||||||
if ((sep[1] < '0') || (sep[1] > '9'))
|
if ((sep[1] < '0') || (sep[1] > '9'))
|
||||||
{
|
{
|
||||||
@@ -2109,7 +2109,7 @@ namespace SoF
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
val = Strings::ToInt(&sep[1]);
|
val = atoi(&sep[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -927,7 +927,7 @@ namespace UF
|
|||||||
{
|
{
|
||||||
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
if ((gjs->action == groupActDisband) || !strcmp(gjs->yourname, gjs->membername))
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandYou, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -947,7 +947,7 @@ namespace UF
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if(gjs->action == groupActLeave)
|
//if(gjs->action == groupActLeave)
|
||||||
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
// Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Group Leave, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
|
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
new EQApplicationPacket(OP_GroupDisbandOther, sizeof(structs::GroupGeneric_Struct));
|
||||||
@@ -977,7 +977,7 @@ namespace UF
|
|||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->member_name[i]);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Membername[%i] is %s", i, gu2->membername[i]);
|
||||||
if (gu2->membername[i][0] != '\0')
|
if (gu2->membername[i][0] != '\0')
|
||||||
{
|
{
|
||||||
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
PacketLength += (22 + strlen(gu2->membername[i]) + 1);
|
||||||
@@ -1045,7 +1045,7 @@ namespace UF
|
|||||||
delete in;
|
delete in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, member_name = %s", gjs->yourname, gjs->member_name);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Generic GroupUpdate, yourname = %s, membername = %s", gjs->yourname, gjs->membername);
|
||||||
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
ENCODE_LENGTH_EXACT(GroupJoin_Struct);
|
||||||
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
SETUP_DIRECT_ENCODE(GroupJoin_Struct, structs::GroupJoin_Struct);
|
||||||
|
|
||||||
@@ -3851,17 +3851,17 @@ namespace UF
|
|||||||
ob.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
|
ob.write((const char*)&evotop, sizeof(UF::structs::EvolvingItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 ornament_icon = 0;
|
//ORNAMENT IDFILE / ICON -
|
||||||
const auto augment = inst->GetOrnamentationAugment();
|
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
|
||||||
|
uint16 ornaIcon = 0;
|
||||||
|
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
|
||||||
|
const EQ::ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
|
||||||
|
ornaIcon = aug_weap->Icon;
|
||||||
|
|
||||||
if (augment) {
|
ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
|
||||||
const auto augment_item = augment->GetItem();
|
|
||||||
ornament_icon = augment_item->Icon;
|
|
||||||
|
|
||||||
ob.write(augment_item->IDFile, strlen(augment_item->IDFile));
|
|
||||||
}
|
}
|
||||||
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
|
else if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
|
||||||
ornament_icon = inst->GetOrnamentationIcon();
|
ornaIcon = inst->GetOrnamentationIcon();
|
||||||
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
|
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
|
||||||
|
|
||||||
ob.write(tmp, strlen(tmp));
|
ob.write(tmp, strlen(tmp));
|
||||||
@@ -3870,7 +3870,7 @@ namespace UF
|
|||||||
|
|
||||||
UF::structs::ItemSerializationHeaderFinish hdrf;
|
UF::structs::ItemSerializationHeaderFinish hdrf;
|
||||||
|
|
||||||
hdrf.ornamentIcon = ornament_icon;
|
hdrf.ornamentIcon = ornaIcon;
|
||||||
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
|
hdrf.unknown060 = 0; //This is Always 0.. or it breaks shit..
|
||||||
hdrf.unknown061 = 0; //possibly ornament / special ornament
|
hdrf.unknown061 = 0; //possibly ornament / special ornament
|
||||||
hdrf.isCopied = 0; //Flag for item to be 'Copied'
|
hdrf.isCopied = 0; //Flag for item to be 'Copied'
|
||||||
|
|||||||
@@ -2128,7 +2128,7 @@ struct GroupUpdate_Struct_Underfoot { // New for Underfoot
|
|||||||
|
|
||||||
struct GroupMembers_Struct { // New for Underfoot
|
struct GroupMembers_Struct { // New for Underfoot
|
||||||
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
/*0000*/ uint32 membernumber; // Guess - number of member in the group (0 to 5?)
|
||||||
/*0000*/ //char member_name[0]; // Member Name Null Terminated
|
/*0000*/ //char membername[0]; // Member Name Null Terminated
|
||||||
/*0000*/ uint8 unknown001[3]; // Seen 0
|
/*0000*/ uint8 unknown001[3]; // Seen 0
|
||||||
/*0000*/ uint32 memberlevel; // Guess
|
/*0000*/ uint32 memberlevel; // Guess
|
||||||
/*0000*/ uint8 unknown002[11]; // Seen 0
|
/*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
|
/*0000*/ uint32 unknown0000; // Matches unknown0136 from GroupFollow_Struct
|
||||||
/*0004*/ uint32 action;
|
/*0004*/ uint32 action;
|
||||||
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
/*0008*/ uint8 unknown0008[5]; // Seen 0
|
||||||
/*0013*/ //char member_name[0]; // Null Terminated?
|
/*0013*/ //char membername[0]; // Null Terminated?
|
||||||
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
/*0000*/ uint8 unknown0013[3]; // Seen 0
|
||||||
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
/*0000*/ uint32 unknown0016; // Matches unknown0132 from GroupFollow_Struct
|
||||||
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
/*0000*/ uint8 unknown0020[11]; // Seen 0
|
||||||
|
|||||||
+11
-16
@@ -22,31 +22,26 @@
|
|||||||
|
|
||||||
EQEmuExePlatform exe_platform = ExePlatformNone;
|
EQEmuExePlatform exe_platform = ExePlatformNone;
|
||||||
|
|
||||||
void RegisterExecutablePlatform(EQEmuExePlatform p)
|
void RegisterExecutablePlatform(EQEmuExePlatform p) {
|
||||||
{
|
|
||||||
exe_platform = p;
|
exe_platform = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EQEmuExePlatform &GetExecutablePlatform()
|
const EQEmuExePlatform& GetExecutablePlatform() {
|
||||||
{
|
|
||||||
return exe_platform;
|
return exe_platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetExecutablePlatformInt()
|
/**
|
||||||
{
|
* @return
|
||||||
|
*/
|
||||||
|
int GetExecutablePlatformInt(){
|
||||||
return exe_platform;
|
return exe_platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsWorld()
|
/**
|
||||||
{
|
* Returns platform name by string
|
||||||
return exe_platform == EQEmuExePlatform::ExePlatformWorld;
|
*
|
||||||
}
|
* @return
|
||||||
|
*/
|
||||||
bool IsQueryServ()
|
|
||||||
{
|
|
||||||
return exe_platform == EQEmuExePlatform::ExePlatformQueryServ;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetPlatformName()
|
std::string GetPlatformName()
|
||||||
{
|
{
|
||||||
switch (GetExecutablePlatformInt()) {
|
switch (GetExecutablePlatformInt()) {
|
||||||
|
|||||||
@@ -44,7 +44,5 @@ void RegisterExecutablePlatform(EQEmuExePlatform p);
|
|||||||
const EQEmuExePlatform& GetExecutablePlatform();
|
const EQEmuExePlatform& GetExecutablePlatform();
|
||||||
int GetExecutablePlatformInt();
|
int GetExecutablePlatformInt();
|
||||||
std::string GetPlatformName();
|
std::string GetPlatformName();
|
||||||
bool IsWorld();
|
|
||||||
bool IsQueryServ();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ void ProcLauncher::Process() {
|
|||||||
if(GetExitCodeProcess(cur->second->proc_info.hProcess, &res)) {
|
if(GetExitCodeProcess(cur->second->proc_info.hProcess, &res)) {
|
||||||
//got exit code, see if its still running...
|
//got exit code, see if its still running...
|
||||||
if(res == STILL_ACTIVE) {
|
if(res == STILL_ACTIVE) {
|
||||||
++cur;
|
cur++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//else, it died, handle properly
|
//else, it died, handle properly
|
||||||
@@ -76,7 +76,7 @@ void ProcLauncher::Process() {
|
|||||||
|
|
||||||
//if we get here, the current process died.
|
//if we get here, the current process died.
|
||||||
tmp = cur;
|
tmp = cur;
|
||||||
++tmp;
|
tmp++;
|
||||||
ProcessTerminated(cur);
|
ProcessTerminated(cur);
|
||||||
cur = tmp;
|
cur = tmp;
|
||||||
}
|
}
|
||||||
@@ -174,7 +174,7 @@ ProcLauncher::ProcRef ProcLauncher::Launch(Spec *&to_launch) {
|
|||||||
std::vector<std::string>::iterator cur, end;
|
std::vector<std::string>::iterator cur, end;
|
||||||
cur = it->args.begin();
|
cur = it->args.begin();
|
||||||
end = it->args.end();
|
end = it->args.end();
|
||||||
for(; cur != end; ++cur) {
|
for(; cur != end; cur++) {
|
||||||
args += " ";
|
args += " ";
|
||||||
args += *cur;
|
args += *cur;
|
||||||
}
|
}
|
||||||
@@ -306,7 +306,7 @@ void ProcLauncher::TerminateAll(bool final) {
|
|||||||
std::map<ProcRef, Spec *>::iterator cur, end;
|
std::map<ProcRef, Spec *>::iterator cur, end;
|
||||||
cur = m_running.begin();
|
cur = m_running.begin();
|
||||||
end = m_running.end();
|
end = m_running.end();
|
||||||
for(; cur != end; ++cur) {
|
for(; cur != end; cur++) {
|
||||||
Terminate(cur->first, true);
|
Terminate(cur->first, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -317,7 +317,7 @@ void ProcLauncher::TerminateAll(bool final) {
|
|||||||
std::map<ProcRef, Spec *>::iterator cur, end;
|
std::map<ProcRef, Spec *>::iterator cur, end;
|
||||||
cur = running.begin();
|
cur = running.begin();
|
||||||
end = running.end();
|
end = running.end();
|
||||||
for(; cur != end; ++cur) {
|
for(; cur != end; cur++) {
|
||||||
Terminate(cur->first, true);
|
Terminate(cur->first, true);
|
||||||
safe_delete(cur->second);
|
safe_delete(cur->second);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
std::string Process::execute(const std::string &cmd)
|
std::string Process::execute(const std::string &cmd)
|
||||||
{
|
{
|
||||||
std::string command = fmt::format("{} 2>&1", cmd);
|
std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
|
||||||
std::shared_ptr<FILE> pipe(popen(command.c_str(), "r"), pclose);
|
|
||||||
if (!pipe) { return "ERROR"; }
|
if (!pipe) { return "ERROR"; }
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ bool EQ::ProfanityManager::clear_database_entries(DBcore *db) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EQ::ProfanityManager::check_for_existing_entry(const std::string& profanity) {
|
bool EQ::ProfanityManager::check_for_existing_entry(std::string profanity) {
|
||||||
if (profanity.empty()) {
|
if (profanity.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user