Compare commits

..

81 Commits

Author SHA1 Message Date
Akkadius 2fdee255fb Add version tag injection in the build pipeline 2023-01-23 02:34:04 -06:00
Akkadius 35b624034d Crash reporting 2023-01-23 02:12:52 -06:00
Akkadius 140fa3e96e [22.1.0] Release 2023-01-22 23:53:16 -06:00
Akkadius 9ab93ae7cd Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius 03da2e783f Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius 63f54a1fb6 Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius 632867631e Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius ec9476528f Trim windows assets 2023-01-22 23:53:16 -06:00
Akkadius f726fc8786 Update CMakeLists.txt 2023-01-22 23:53:16 -06:00
Akkadius fbad3ca88a Update linux-build.sh 2023-01-22 23:53:16 -06:00
Akkadius 63727cc1e3 Update linux-build.sh 2023-01-22 23:53:16 -06:00
Akkadius c616a9588b Another release test 2023-01-22 23:53:16 -06:00
Akkadius b3788a0cee Update linux-build.sh 2023-01-22 23:53:16 -06:00
Akkadius 6031eee429 Pop cache back in 2023-01-22 23:53:16 -06:00
Akkadius 4d67c12752 Run it 2023-01-22 23:53:16 -06:00
Akkadius 57f64a3f2e Consolidate 2023-01-22 23:53:16 -06:00
Akkadius b314b048db Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius d1d119d7fb F 2023-01-22 23:53:16 -06:00
Akkadius f22c08cbdb Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius 1711cae4f4 Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius 0d740b87aa Update windows-build.ps1 2023-01-22 23:53:16 -06:00
Akkadius c0ff63e2d8 Take #45354 2023-01-22 23:53:16 -06:00
Akkadius 7934a85086 Shuffle 2023-01-22 23:53:16 -06:00
Akkadius 6d881d0b1b Update build-release.bat 2023-01-22 23:53:16 -06:00
Akkadius 4b20db6ab7 Update build-release.bat 2023-01-22 23:53:16 -06:00
Akkadius 8c9127fc3c Bump 2023-01-22 23:53:16 -06:00
Akkadius c8c9d4b010 Update CHANGELOG.md 2023-01-22 23:53:16 -06:00
Akkadius 9df9f213f6 Test pipeline 2023-01-22 23:53:16 -06:00
Akkadius 5ab1d7740f Update build-release.bat 2023-01-22 23:53:16 -06:00
Akkadius aa17afd6e0 Update build-release.bat 2023-01-22 23:53:16 -06:00
Akkadius 925780dcd9 Update .drone.yml 2023-01-22 23:53:16 -06:00
Akkadius c86519bae9 Update .drone.yml 2023-01-22 23:53:16 -06:00
Akkadius d223de3e3c Update .drone.yml 2023-01-22 23:53:16 -06:00
Akkadius 5b19ecd800 Update build-release.bat 2023-01-22 23:53:16 -06:00
Akkadius 21479dc517 Test 2023-01-22 23:53:16 -06:00
Akkadius 78616bd014 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 7007a716bf Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 576d39e04b Add version checks 2023-01-22 23:53:15 -06:00
Akkadius 6ac451b8b3 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius f8f661a343 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 1f3d18723d exit 78 2023-01-22 23:53:15 -06:00
Akkadius 33c11005ff Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 144dfb0ec2 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 1173702b00 Check if release 2023-01-22 23:53:15 -06:00
Akkadius 08b1f2edcb Release bot test #2 2023-01-22 23:53:15 -06:00
Akkadius 9833627683 Bots release 22.0.5 (Test) 2023-01-22 23:53:15 -06:00
Akkadius e9841b8d9a Test 2023-01-22 23:53:15 -06:00
Akkadius 6103db0c8b Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius f50bb6ab59 Filter pipeline stage 2023-01-22 23:53:15 -06:00
Akkadius 62f9533614 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 80abf85528 Remove debug 2023-01-22 23:53:15 -06:00
Akkadius 6fe89dc0aa Test pipeline 2023-01-22 23:53:15 -06:00
Akkadius 7496d45f7b Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius b03314efe1 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 268e03206a Release without bots 2023-01-22 23:53:15 -06:00
Akkadius 420c545dbd Yolo 2023-01-22 23:53:15 -06:00
Akkadius 66bca9549b Copy 2023-01-22 23:53:15 -06:00
Akkadius 39c321f449 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius e326e39e8a Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 1eada5259a Yolo 2023-01-22 23:53:15 -06:00
Akkadius 7ac170627d Yolo 2023-01-22 23:53:15 -06:00
Akkadius d9c674e888 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 88fb994357 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius e708b55f4d Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 911ce259e8 Test upload 2023-01-22 23:53:15 -06:00
Akkadius ccd325f75d Naming 2023-01-22 23:53:15 -06:00
Akkadius 45afba6e5f Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 3fc9c470c4 Test 2023-01-22 23:53:15 -06:00
Akkadius c5501a3693 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius ce24b5e442 Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 46fc763f6a Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius cbf89e9a1f Update .drone.yml 2023-01-22 23:53:15 -06:00
Akkadius 5a1eefcd13 Linux 2023-01-22 23:53:15 -06:00
Akkadius 0aa69504a1 Remove 7z from build scripts 2023-01-22 23:53:15 -06:00
Akkadius 3408d136e2 Split 2023-01-22 23:53:15 -06:00
Akkadius 78b1307f6f Kill excessive warnings 2023-01-22 23:53:15 -06:00
Akkadius 337019fb4d Update windows-build.ps1 2023-01-22 23:53:15 -06:00
Akkadius 840744df9a Update windows-build.ps1 2023-01-22 23:53:15 -06:00
Akkadius 68954ef965 Update windows-build.ps1 2023-01-22 23:53:15 -06:00
Akkadius e10c7da2f9 Test 2023-01-22 23:53:15 -06:00
Akkadius b2dc6c88d9 Test 2023-01-22 23:53:15 -06:00
1122 changed files with 89141 additions and 94761 deletions
+6 -12
View File
@@ -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
@@ -15,7 +18,7 @@ volumes:
steps: steps:
- name: Build Linux X64 - name: Build Linux X64
image: akkadius/eqemu-server:v13 image: akkadius/eqemu-server:v11
environment: environment:
GITHUB_TOKEN: GITHUB_TOKEN:
from_secret: GH_RELEASE_GITHUB_API_TOKEN from_secret: GH_RELEASE_GITHUB_API_TOKEN
@@ -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
-3
View File
@@ -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/*
+321 -1940
View File
File diff suppressed because it is too large Load Diff
+1 -34
View File
@@ -16,20 +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++")
IF (UNIX)
SET(PERL_LIBRARY "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/libperl.so")
SET(PERL_INCLUDE_PATH "/opt/eqemu-perl/lib/5.32.1/x86_64-linux-thread-multi/CORE/")
SET(PERL_EXECUTABLE "/opt/eqemu-perl/bin/perl")
ENDIF ()
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)
@@ -37,11 +23,7 @@ IF(MSVC)
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17 ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
IF(EQEMU_DISABLE_MSVC_WARNINGS)
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
ELSE(MSVC) ELSE(MSVC)
ADD_DEFINITIONS(-DHAS_UNION_SEMUN) ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
ENDIF(MSVC) ENDIF(MSVC)
@@ -138,13 +120,6 @@ ELSE()
MESSAGE(STATUS "* mbedTLS: MISSING *") MESSAGE(STATUS "* mbedTLS: MISSING *")
ENDIF() ENDIF()
MESSAGE(STATUS "PERL_INCLUDE_PATH: ${PERL_INCLUDE_PATH}")
MESSAGE(STATUS "PERL_LIBRARY: ${PERL_LIBRARY}")
MESSAGE(STATUS "PERL_INCLUDE_DIR: ${PERL_INCLUDE_DIR}")
MESSAGE(STATUS "PERL_INCLUDE_DIRS: ${PERL_INCLUDE_DIRS}")
MESSAGE(STATUS "PERL_LIBRARIES: ${PERL_LIBRARIES}")
MESSAGE(STATUS "PERL_VERSION: ${PERL_VERSION}")
MESSAGE(STATUS "**************************************************") MESSAGE(STATUS "**************************************************")
#options #options
@@ -332,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 *")
@@ -400,10 +371,6 @@ IF(PERL_LIBRARY_ENABLED)
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}") INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
ADD_DEFINITIONS(-DEMBPERL) ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN) ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
IF (UNIX AND EQEMU_BUILD_STATIC)
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
ENDIF ()
ENDIF() ENDIF()
ENDIF() ENDIF()
+3 -3
View File
@@ -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) |
|:---:|:---:| |:---:|:---:|:---:|
|[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) |[![Build Status](http://drone.akkadius.com/api/badges/EQEmu/Server/status.svg)](http://drone.akkadius.com/EQEmu/Server) | |[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Build status](https://ci.appveyor.com/api/projects/status/v3utuu0dttm2cqd0?svg=true)](https://ci.appveyor.com/project/KimLS/server) |[![Build status](https://ci.appveyor.com/api/projects/status/scr25kmntx36c1ub?svg=true)](https://ci.appveyor.com/project/KimLS/server-87crp) |
*** ***
+3 -3
View File
@@ -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)
+17 -17
View File
@@ -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]);
+8 -21
View File
@@ -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
@@ -70,7 +65,6 @@ SET(common_sources
perl_eqdb.cpp perl_eqdb.cpp
perl_eqdb_res.cpp perl_eqdb_res.cpp
process/process.cpp process/process.cpp
process.cpp
proc_launcher.cpp proc_launcher.cpp
profanity_manager.cpp profanity_manager.cpp
ptimer.cpp ptimer.cpp
@@ -91,7 +85,6 @@ SET(common_sources
timer.cpp timer.cpp
unix.cpp unix.cpp
platform.cpp platform.cpp
json/json.hpp
json/jsoncpp.cpp json/jsoncpp.cpp
zone_store.cpp zone_store.cpp
net/console_server.cpp net/console_server.cpp
@@ -205,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
@@ -224,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
@@ -269,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
@@ -383,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
@@ -402,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
@@ -447,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
@@ -511,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
@@ -538,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
@@ -585,14 +574,12 @@ SET(common_headers
path_manager.cpp path_manager.cpp
platform.h platform.h
process/process.h process/process.h
process.h
proc_launcher.h proc_launcher.h
profanity_manager.h profanity_manager.h
profiler.h profiler.h
ptimer.h ptimer.h
queue.h queue.h
races.h races.h
raid.h
random.h random.h
rdtsc.h rdtsc.h
rulesys.h rulesys.h
@@ -616,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
@@ -675,7 +662,7 @@ SET(common_headers
util/memory_stream.h util/memory_stream.h
util/directory.h util/directory.h
util/uuid.h util/uuid.h
) )
SOURCE_GROUP(Event FILES SOURCE_GROUP(Event FILES
event/event_loop.h event/event_loop.h
-78
View File
@@ -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
View File
@@ -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);
+29 -22
View File
@@ -39,15 +39,15 @@ namespace EQEmuCommand {
{ {
if (cmd[{"-d", "--debug"}]) { if (cmd[{"-d", "--debug"}]) {
std::cout << "Positional args:\n"; std::cout << "Positional args:\n";
for (auto &pos_arg: cmd.pos_args()) for (auto &pos_arg : cmd.pos_args())
std::cout << '\t' << pos_arg << std::endl; std::cout << '\t' << pos_arg << std::endl;
std::cout << "\nFlags:\n"; std::cout << "\nFlags:\n";
for (auto &flag: cmd.flags()) for (auto &flag : cmd.flags())
std::cout << '\t' << flag << std::endl; std::cout << '\t' << flag << std::endl;
std::cout << "\nParameters:\n"; std::cout << "\nParameters:\n";
for (auto &param: cmd.params()) for (auto &param : cmd.params())
std::cout << '\t' << param.first << " : " << param.second << std::endl; std::cout << '\t' << param.first << " : " << param.second << std::endl;
} }
} }
@@ -69,22 +69,22 @@ namespace EQEmuCommand {
{ {
bool arguments_filled = true; bool arguments_filled = true;
int index = 2; int index = 2;
for (auto &arg: arguments) { for (auto &arg : arguments) {
if (cmd(arg).str().empty() && cmd(index).str().empty()) { if (cmd(arg).str().empty() && cmd(index).str().empty()) {
arguments_filled = false; arguments_filled = false;
} }
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;
} }
std::string options_string; std::string options_string;
for (auto &opt: options) { for (auto &opt : options) {
options_string += " " + opt + "\n"; options_string += " " + opt + "\n";
} }
@@ -124,6 +124,14 @@ namespace EQEmuCommand {
) )
{ {
std::string description; std::string description;
bool ran_command = false;
for (auto &it: in_function_map) {
if (it.first == argv[1]) {
(it.second)(argc, argv, cmd, description);
ran_command = true;
}
}
if (cmd[{"-h", "--help"}]) { if (cmd[{"-h", "--help"}]) {
std::cout << std::endl; std::cout << std::endl;
std::cout << std::cout <<
@@ -134,7 +142,9 @@ namespace EQEmuCommand {
<< std::endl << std::endl
<< std::endl; << std::endl;
// Get max command length for padding length /**
* Get max command length for padding length
*/
int max_command_length = 0; int max_command_length = 0;
for (auto &it: in_function_map) { for (auto &it: in_function_map) {
@@ -145,14 +155,18 @@ namespace EQEmuCommand {
} }
} }
// Display command menu /**
* Display command menu
*/
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);
// Print section header /**
* Print section header
*/
std::string command_prefix = it.first.substr(0, it.first.find(":")); std::string command_prefix = it.first.substr(0, it.first.find(":"));
if (command_prefix.find("test") != std::string::npos) { if (command_prefix.find("test") != std::string::npos) {
@@ -164,7 +178,9 @@ namespace EQEmuCommand {
std::cout << termcolor::reset << command_prefix << std::endl; std::cout << termcolor::reset << command_prefix << std::endl;
} }
// Print commands /**
* Print commands
*/
std::stringstream command; std::stringstream command;
command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset; command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset;
printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str()); printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str());
@@ -175,15 +191,6 @@ namespace EQEmuCommand {
std::exit(0); std::exit(0);
} }
bool ran_command = false;
for (auto &it: in_function_map) {
if (it.first == argv[1]) {
(it.second)(argc, argv, cmd, description);
ran_command = true;
}
}
if (ran_command) { if (ran_command) {
std::exit(0); std::exit(0);
} }
+1 -1
View File
@@ -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;
} }
+1 -1
View File
@@ -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();
+14 -28
View File
@@ -13,7 +13,6 @@
#include "platform.h" #include "platform.h"
#include <cstdio> #include <cstdio>
#include <vector>
#if WINDOWS #if WINDOWS
#define popen _popen #define popen _popen
@@ -23,8 +22,8 @@ void SendCrashReport(const std::string &crash_report)
{ {
// can configure multiple endpoints if need be // can configure multiple endpoints if need be
std::vector<std::string> endpoints = { std::vector<std::string> endpoints = {
"http://spire.akkadius.com/api/v1/analytics/server-crash-report", "http://spire.akkadius.com/api/v1/server-crash-report",
// "http://localhost:3010/api/v1/analytics/server-crash-report", // development // "http://localhost:3010/api/v1/server-crash-report", // development
}; };
auto config = EQEmuConfig::get(); auto config = EQEmuConfig::get();
@@ -41,6 +40,9 @@ void SendCrashReport(const std::string &crash_report)
r.set_connection_timeout(1, 0); r.set_connection_timeout(1, 0);
r.set_read_timeout(1, 0); r.set_read_timeout(1, 0);
r.set_write_timeout(1, 0); r.set_write_timeout(1, 0);
httplib::Headers headers = {
{"Content-Type", "application/json"}
};
// os info // os info
auto os = EQ::GetOS(); auto os = EQ::GetOS();
@@ -101,30 +103,27 @@ public:
EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { } EQEmuStackWalker(DWORD dwProcessId, HANDLE hProcess) : StackWalker(dwProcessId, hProcess) { }
virtual void OnOutput(LPCSTR szText) { virtual void OnOutput(LPCSTR szText) {
char buffer[4096]; char buffer[4096];
for (int i = 0; i < 4096; ++i) { for(int i = 0; i < 4096; ++i) {
if (szText[i] == 0) { if(szText[i] == 0) {
buffer[i] = '\0'; buffer[i] = '\0';
break; break;
} }
if (szText[i] == '\n' || szText[i] == '\r') { if(szText[i] == '\n' || szText[i] == '\r') {
buffer[i] = ' '; buffer[i] = ' ';
} } else {
else {
buffer[i] = szText[i]; buffer[i] = szText[i];
} }
} }
std::string line = buffer; if (RuleB(Analytics, CrashReporting)) {
_lines.push_back(line); std::string crash_report = buffer;
SendCrashReport(crash_report);
}
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 +197,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;
+1 -1
View File
@@ -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)
{ {
+229 -262
View File
@@ -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,"
@@ -635,102 +634,101 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
"%u," // guild_auto_consent "%u," // guild_auto_consent
"%u" // RestTimer "%u" // RestTimer
")", ")",
character_id, // " id, " character_id, // " id, "
account_id, // " account_id, " account_id, // " account_id, "
Strings::Escape(pp->name).c_str(), // " `name`, " Strings::Escape(pp->name).c_str(), // " `name`, "
Strings::Escape(pp->last_name).c_str(), // " last_name, " Strings::Escape(pp->last_name).c_str(), // " last_name, "
pp->gender, // " gender, " pp->gender, // " gender, "
pp->race, // " race, " pp->race, // " race, "
pp->class_, // " class, " pp->class_, // " class, "
pp->level, // " `level`, " pp->level, // " `level`, "
pp->deity, // " deity, " pp->deity, // " deity, "
pp->birthday, // " birthday, " pp->birthday, // " birthday, "
pp->lastlogin, // " last_login, " pp->lastlogin, // " last_login, "
pp->timePlayedMin, // " time_played, " pp->timePlayedMin, // " time_played, "
pp->pvp, // " pvp_status, " pp->pvp, // " pvp_status, "
pp->level2, // " level2, " pp->level2, // " level2, "
pp->anon, // " anon, " pp->anon, // " anon, "
pp->gm, // " gm, " pp->gm, // " gm, "
pp->intoxication, // " intoxication, " pp->intoxication, // " intoxication, "
pp->haircolor, // " hair_color, " pp->haircolor, // " hair_color, "
pp->beardcolor, // " beard_color, " pp->beardcolor, // " beard_color, "
pp->eyecolor1, // " eye_color_1, " pp->eyecolor1, // " eye_color_1, "
pp->eyecolor2, // " eye_color_2, " pp->eyecolor2, // " eye_color_2, "
pp->hairstyle, // " hair_style, " pp->hairstyle, // " hair_style, "
pp->beard, // " beard, " pp->beard, // " beard, "
pp->ability_time_seconds, // " ability_time_seconds, " pp->ability_time_seconds, // " ability_time_seconds, "
pp->ability_number, // " ability_number, " pp->ability_number, // " ability_number, "
pp->ability_time_minutes, // " ability_time_minutes, " pp->ability_time_minutes, // " ability_time_minutes, "
pp->ability_time_hours, // " ability_time_hours, " pp->ability_time_hours, // " ability_time_hours, "
Strings::Escape(pp->title).c_str(), // " title, " Strings::Escape(pp->title).c_str(), // " title, "
Strings::Escape(pp->suffix).c_str(), // " suffix, " Strings::Escape(pp->suffix).c_str(), // " suffix, "
pp->exp, // " exp, " pp->exp, // " exp, "
pp->points, // " points, " pp->points, // " points, "
pp->mana, // " mana, " pp->mana, // " mana, "
pp->cur_hp, // " cur_hp, " pp->cur_hp, // " cur_hp, "
pp->STR, // " str, " pp->STR, // " str, "
pp->STA, // " sta, " pp->STA, // " sta, "
pp->CHA, // " cha, " pp->CHA, // " cha, "
pp->DEX, // " dex, " pp->DEX, // " dex, "
pp->INT, // " `int`, " pp->INT, // " `int`, "
pp->AGI, // " agi, " pp->AGI, // " agi, "
pp->WIS, // " wis, " pp->WIS, // " wis, "
pp->face, // " face, " pp->face, // " face, "
pp->y, // " y, " pp->y, // " y, "
pp->x, // " x, " pp->x, // " x, "
pp->z, // " z, " pp->z, // " z, "
pp->heading, // " heading, " pp->heading, // " heading, "
pp->pvp2, // " pvp2, " pp->pvp2, // " pvp2, "
pp->pvptype, // " pvp_type, " pp->pvptype, // " pvp_type, "
pp->autosplit, // " autosplit_enabled, " pp->autosplit, // " autosplit_enabled, "
pp->zone_change_count, // " zone_change_count, " pp->zone_change_count, // " zone_change_count, "
pp->drakkin_heritage, // " drakkin_heritage, " pp->drakkin_heritage, // " drakkin_heritage, "
pp->drakkin_tattoo, // " drakkin_tattoo, " pp->drakkin_tattoo, // " drakkin_tattoo, "
pp->drakkin_details, // " drakkin_details, " pp->drakkin_details, // " drakkin_details, "
pp->toxicity, // " toxicity, " pp->toxicity, // " toxicity, "
pp->hunger_level, // " hunger_level, " pp->hunger_level, // " hunger_level, "
pp->thirst_level, // " thirst_level, " pp->thirst_level, // " thirst_level, "
pp->ability_up, // " ability_up, " pp->ability_up, // " ability_up, "
pp->zone_id, // " zone_id, " pp->zone_id, // " zone_id, "
pp->zoneInstance, // " zone_instance, " pp->zoneInstance, // " zone_instance, "
pp->leadAAActive, // " leadership_exp_on, " pp->leadAAActive, // " leadership_exp_on, "
pp->ldon_points_guk, // " ldon_points_guk, " pp->ldon_points_guk, // " ldon_points_guk, "
pp->ldon_points_mir, // " ldon_points_mir, " pp->ldon_points_mir, // " ldon_points_mir, "
pp->ldon_points_mmc, // " ldon_points_mmc, " pp->ldon_points_mmc, // " ldon_points_mmc, "
pp->ldon_points_ruj, // " ldon_points_ruj, " pp->ldon_points_ruj, // " ldon_points_ruj, "
pp->ldon_points_tak, // " ldon_points_tak, " pp->ldon_points_tak, // " ldon_points_tak, "
pp->ldon_points_available, // " ldon_points_available, " pp->ldon_points_available, // " ldon_points_available, "
pp->tribute_time_remaining, // " tribute_time_remaining, " pp->tribute_time_remaining, // " tribute_time_remaining, "
pp->showhelm, // " show_helm, " pp->showhelm, // " show_helm, "
pp->career_tribute_points, // " career_tribute_points, " pp->career_tribute_points, // " career_tribute_points, "
pp->tribute_points, // " tribute_points, " pp->tribute_points, // " tribute_points, "
pp->tribute_active, // " tribute_active, " pp->tribute_active, // " tribute_active, "
pp->endurance, // " endurance, " pp->endurance, // " endurance, "
pp->group_leadership_exp, // " group_leadership_exp, " pp->group_leadership_exp, // " group_leadership_exp, "
pp->raid_leadership_exp, // " raid_leadership_exp, " pp->raid_leadership_exp, // " raid_leadership_exp, "
pp->group_leadership_points, // " group_leadership_points, " pp->group_leadership_points, // " group_leadership_points, "
pp->raid_leadership_points, // " raid_leadership_points, " pp->raid_leadership_points, // " raid_leadership_points, "
pp->air_remaining, // " air_remaining, " pp->air_remaining, // " air_remaining, "
pp->PVPKills, // " pvp_kills, " pp->PVPKills, // " pvp_kills, "
pp->PVPDeaths, // " pvp_deaths, " pp->PVPDeaths, // " pvp_deaths, "
pp->PVPCurrentPoints, // " pvp_current_points, " pp->PVPCurrentPoints, // " pvp_current_points, "
pp->PVPCareerPoints, // " pvp_career_points, " pp->PVPCareerPoints, // " pvp_career_points, "
pp->PVPBestKillStreak, // " pvp_best_kill_streak, " pp->PVPBestKillStreak, // " pvp_best_kill_streak, "
pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, " pp->PVPWorstDeathStreak, // " pvp_worst_death_streak, "
pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, " pp->PVPCurrentKillStreak, // " pvp_current_kill_streak, "
pp->aapoints_spent, // " aa_points_spent, " pp->aapoints_spent, // " aa_points_spent, "
pp->expAA, // " aa_exp, " pp->expAA, // " aa_exp, "
pp->aapoints, // " aa_points, " pp->aapoints, // " aa_points, "
pp->groupAutoconsent, // " group_auto_consent, " pp->groupAutoconsent, // " group_auto_consent, "
pp->raidAutoconsent, // " raid_auto_consent, " pp->raidAutoconsent, // " raid_auto_consent, "
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,73 +739,57 @@ 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 */
int firstquery = 0; int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++) { for (int i = 0; i < MAX_PP_SKILL; i++){
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;
for (int i = 0; i < MAX_PP_LANGUAGE; i++) { for (int i = 0; i < MAX_PP_LANGUAGE; i++){
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
View File
@@ -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:
+23 -109
View File
@@ -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
); );
} }
@@ -143,7 +145,7 @@ std::string DatabaseDumpService::GetQueryServTables()
std::string DatabaseDumpService::GetSystemTablesList() std::string DatabaseDumpService::GetSystemTablesList()
{ {
auto system_tables = DatabaseSchema::GetServerTables(); auto system_tables = DatabaseSchema::GetServerTables();
auto version_tables = DatabaseSchema::GetVersionTables(); auto version_tables = DatabaseSchema::GetVersionTables();
system_tables.insert( system_tables.insert(
@@ -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");
@@ -279,11 +281,6 @@ void DatabaseDumpService::DatabaseDump()
} }
} }
if (IsDumpStaticInstanceData()) {
tables_to_dump += "instance_list";
options += " --no-create-info --where=\"instance_list.is_global > 0 and instance_list.never_expires > 0\"";
}
if (!dump_descriptor.empty()) { if (!dump_descriptor.empty()) {
SetDumpFileName(GetDumpFileName() + dump_descriptor); SetDumpFileName(GetDumpFileName() + dump_descriptor);
} }
@@ -296,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());
} }
@@ -303,62 +308,30 @@ void DatabaseDumpService::DatabaseDump()
if (IsDumpDropTableSyntaxOnly()) { if (IsDumpDropTableSyntaxOnly()) {
std::vector<std::string> tables = Strings::Split(tables_to_dump, ' '); std::vector<std::string> tables = Strings::Split(tables_to_dump, ' ');
for (auto &table: tables) { for (auto &table : tables) {
std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl; std::cout << "DROP TABLE IF EXISTS `" << table << "`;" << std::endl;
} }
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;
} }
} }
if (!IsDumpOutputToConsole()) {
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(
@@ -370,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(
@@ -381,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");
@@ -392,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"));
@@ -566,58 +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);
}
}
bool DatabaseDumpService::IsDumpStaticInstanceData()
{
return dump_static_instance_data;
}
void DatabaseDumpService::SetDumpStaticInstanceData(bool b)
{
dump_static_instance_data = b;
}
+1 -9
View 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;
@@ -58,9 +58,6 @@ public:
bool IsDumpMercTables() const; bool IsDumpMercTables() const;
void SetDumpMercTables(bool dump_bot_tables); void SetDumpMercTables(bool dump_bot_tables);
void SetDumpStaticInstanceData(bool b);
bool IsDumpStaticInstanceData();
private: private:
bool dump_all_tables = false; bool dump_all_tables = false;
bool dump_state_tables = false; bool dump_state_tables = false;
@@ -76,8 +73,6 @@ private:
bool dump_drop_table_syntax_only = false; bool dump_drop_table_syntax_only = false;
bool dump_bot_tables = false; bool dump_bot_tables = false;
bool dump_merc_tables = false; bool dump_merc_tables = false;
bool dump_static_instance_data = false;
std::string dump_path; std::string dump_path;
std::string dump_file_name; std::string dump_file_name;
@@ -97,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();
}; };
-300
View File
@@ -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");
}
}
-37
View File
@@ -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,107 +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;
)",
},
ManifestEntry{
.version = 9040,
.description = "2023_11_16_bot_starting_items.sql",
.check = "SHOW TABLES LIKE 'bot_starting_items'",
.condition = "empty",
.match = "",
.sql = R"(
CREATE TABLE `bot_starting_items` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`races` int(11) UNSIGNED NOT NULL DEFAULT 0,
`classes` int(11) UNSIGNED NOT NULL DEFAULT 0,
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
`min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
`slot_id` mediumint(9) NOT NULL DEFAULT -1,
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
`content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
)"
}
// -- 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
// };
File diff suppressed because it is too large Load Diff
+61 -92
View File
@@ -131,118 +131,85 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
bool Database::GetUnusedInstanceID(uint16 &instance_id) bool Database::GetUnusedInstanceID(uint16 &instance_id)
{ {
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances); uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
uint32 max_instance_id = 32000; uint32 max = 32000;
// sanity check reserved
if (max_reserved_instance_id >= max_instance_id) {
instance_id = 0;
return false;
}
// recycle instances
if (RuleB(Instances, RecycleInstanceIds)) {
//query to get first unused id above reserved
auto query = fmt::format(
SQL(
SELECT id
FROM instance_list
WHERE id = {};
),
max_reserved_instance_id + 1
);
auto results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) {
instance_id = 0;
return false;
}
// first id is available
if (results.RowCount() == 0) {
instance_id = max_reserved_instance_id + 1;
return true;
}
// now look for next available above reserved
query = fmt::format(
SQL(
SELECT MIN(i.id + 1) AS next_available
FROM instance_list i
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
WHERE i.id >= {}
AND i2.id IS NULL;
),
max_reserved_instance_id
);
results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) {
instance_id = 0;
return false;
}
// did not retrieve any rows - bail out
if (results.RowCount() == 0) {
instance_id = 0;
return false;
}
auto row = results.begin();
// check that id is within limits
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]);
return true;
}
// no available instance ids
instance_id = 0;
return false;
}
// get max unused id above reserved
auto query = fmt::format( auto query = fmt::format(
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}", "SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
max_reserved_instance_id, max_reserved_instance_id,
max_reserved_instance_id max_reserved_instance_id
); );
if (RuleB(Instances, RecycleInstanceIds)) {
query = (
SQL(
SELECT i.id + 1 AS next_available
FROM instance_list i
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
WHERE i2.id IS NULL
ORDER BY i.id
LIMIT 0, 1;
)
);
}
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
// could not successfully query - bail out
if (!results.Success()) { if (!results.Success()) {
instance_id = 0; instance_id = 0;
return false; return false;
} }
// did not retrieve any rows - bail out if (results.RowCount() == 0) {
instance_id = max_reserved_instance_id;
return true;
}
auto row = results.begin();
if (atoi(row[0]) <= max) {
instance_id = atoi(row[0]);
return true;
}
if (instance_id < max_reserved_instance_id) {
instance_id = max_reserved_instance_id;
return true;
}
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
results = QueryDatabase(query);
if (!results.Success()) {
instance_id = 0;
return false;
}
if (results.RowCount() == 0) { if (results.RowCount() == 0) {
instance_id = 0; instance_id = 0;
return false; return false;
} }
auto row = results.begin(); max_reserved_instance_id++;
// no instances currently used for (auto row : results) {
if (!row[0]) { if (max_reserved_instance_id < std::stoul(row[0])) {
instance_id = max_reserved_instance_id + 1; instance_id = max_reserved_instance_id;
return true; return true;
}
if (max_reserved_instance_id > max) {
instance_id = 0;
return false;
}
max_reserved_instance_id++;
} }
// check that id is within limits instance_id = max_reserved_instance_id;
if (Strings::ToInt(row[0]) <= max_instance_id) {
instance_id = Strings::ToInt(row[0]);
return true;
}
// no available instance ids return true;
instance_id = 0;
return false;
} }
bool Database::IsGlobalInstance(uint16 instance_id) bool Database::IsGlobalInstance(uint16 instance_id)
@@ -334,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)
@@ -361,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;
@@ -442,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 = {}",
@@ -462,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));
+6 -7
View File
@@ -66,10 +66,9 @@ namespace DatabaseSchema {
{"character_potionbelt", "id"}, {"character_potionbelt", "id"},
{"character_skills", "id"}, {"character_skills", "id"},
{"character_spells", "id"}, {"character_spells", "id"},
{"character_stats_record", "character_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"},
@@ -135,7 +134,6 @@ namespace DatabaseSchema {
"character_potionbelt", "character_potionbelt",
"character_skills", "character_skills",
"character_spells", "character_spells",
"character_stats_record",
"character_task_timers", "character_task_timers",
"character_tasks", "character_tasks",
"character_tribute", "character_tribute",
@@ -258,9 +256,7 @@ namespace DatabaseSchema {
{ {
return { return {
"chatchannels", "chatchannels",
"chatchannel_reserved_names",
"command_settings", "command_settings",
"command_subsettings",
"content_flags", "content_flags",
"db_str", "db_str",
"eqtime", "eqtime",
@@ -325,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",
@@ -345,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",
@@ -396,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",
+50 -188
View File
@@ -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,16 +34,14 @@
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; pDatabase = nullptr;
pDatabase = nullptr; 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
View File
@@ -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
+121 -71
View File
@@ -19,81 +19,131 @@
#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:
return bit_DeityBertoxxulous; return bit_DeityBertoxxulous;
case DeityBrellSirilis: case DeityBrellSirilis:
return bit_DeityBrellSirilis; return bit_DeityBrellSirilis;
case DeityCazicThule: case DeityCazicThule:
return bit_DeityCazicThule; return bit_DeityCazicThule;
case DeityErollisiMarr: case DeityErollisiMarr:
return bit_DeityErollisiMarr; return bit_DeityErollisiMarr;
case DeityBristlebane: case DeityBristlebane:
return bit_DeityBristlebane; return bit_DeityBristlebane;
case DeityInnoruuk: case DeityInnoruuk:
return bit_DeityInnoruuk; return bit_DeityInnoruuk;
case DeityKarana: case DeityKarana:
return bit_DeityKarana; return bit_DeityKarana;
case DeityMithanielMarr: case DeityMithanielMarr:
return bit_DeityMithanielMarr; return bit_DeityMithanielMarr;
case DeityPrexus: case DeityPrexus:
return bit_DeityPrexus; return bit_DeityPrexus;
case DeityQuellious: case DeityQuellious:
return bit_DeityQuellious; return bit_DeityQuellious;
case DeityRallosZek: case DeityRallosZek:
return bit_DeityRallosZek; return bit_DeityRallosZek;
case DeityRodcetNife: case DeityRodcetNife:
return bit_DeityRodcetNife; return bit_DeityRodcetNife;
case DeitySolusekRo: case DeitySolusekRo:
return bit_DeitySolusekRo; return bit_DeitySolusekRo;
case DeityTheTribunal: case DeityTheTribunal:
return bit_DeityTheTribunal; return bit_DeityTheTribunal;
case DeityTunare: case DeityTunare:
return bit_DeityTunare; return bit_DeityTunare;
case DeityVeeshan: case DeityVeeshan:
return bit_DeityVeeshan; return bit_DeityVeeshan;
case DeityAgnostic_LB: case DeityAgnostic_LB:
case DeityAgnostic: case DeityAgnostic:
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;
return std::string(); 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;
};
}
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";
};
} }
+21 -22
View File
@@ -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,29 +49,30 @@ namespace EQ
}; };
enum DeityTypeBit : uint32 { enum DeityTypeBit : uint32 {
bit_DeityAgnostic = 0x00000001, bit_DeityNone = 0x00000000,
bit_DeityBertoxxulous = 0x00000002, bit_DeityAgnostic = 0x00000001,
bit_DeityBrellSirilis = 0x00000004, bit_DeityBertoxxulous = 0x00000002,
bit_DeityCazicThule = 0x00000008, bit_DeityBrellSirilis = 0x00000004,
bit_DeityErollisiMarr = 0x00000010, bit_DeityCazicThule = 0x00000008,
bit_DeityBristlebane = 0x00000020, bit_DeityErollisiMarr = 0x00000010,
bit_DeityInnoruuk = 0x00000040, bit_DeityBristlebane = 0x00000020,
bit_DeityKarana = 0x00000080, bit_DeityInnoruuk = 0x00000040,
bit_DeityKarana = 0x00000080,
bit_DeityMithanielMarr = 0x00000100, bit_DeityMithanielMarr = 0x00000100,
bit_DeityPrexus = 0x00000200, bit_DeityPrexus = 0x00000200,
bit_DeityQuellious = 0x00000400, bit_DeityQuellious = 0x00000400,
bit_DeityRallosZek = 0x00000800, bit_DeityRallosZek = 0x00000800,
bit_DeityRodcetNife = 0x00001000, bit_DeityRodcetNife = 0x00001000,
bit_DeitySolusekRo = 0x00002000, bit_DeitySolusekRo = 0x00002000,
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
View File
@@ -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;
}
-5
View File
@@ -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{};
+33 -34
View File
@@ -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();
} }
-25
View File
@@ -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*/
-4
View File
@@ -62,7 +62,6 @@ N(OP_BeginCast),
N(OP_Bind_Wound), N(OP_Bind_Wound),
N(OP_BlockedBuffs), N(OP_BlockedBuffs),
N(OP_BoardBoat), N(OP_BoardBoat),
N(OP_BookButton),
N(OP_Buff), N(OP_Buff),
N(OP_BuffCreate), N(OP_BuffCreate),
N(OP_BuffRemoveRequest), N(OP_BuffRemoveRequest),
@@ -317,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),
@@ -400,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),
+8 -34
View File
@@ -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,39 +1015,15 @@ enum Anonymity : uint8
Roleplaying Roleplaying
}; };
enum ZoningMessage : int8 { enum ZoningMessage : int8
ZoneNoMessage = 0, {
ZoneSuccess = 1, ZoneNoMessage = 0,
ZoneNotReady = -1, ZoneSuccess = 1,
ZoneValidPC = -2, ZoneNotReady = -1,
ZoneStoryZone = -3, ZoneValidPC = -2,
ZoneNoExpansion = -6, ZoneStoryZone = -3,
ZoneNoExpansion = -6,
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
View File
@@ -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,
+137
View File
@@ -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));
} }
+3
View File
@@ -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); }
+20 -55
View File
@@ -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];
@@ -2559,10 +2548,7 @@ struct GMEmoteZone_Struct {
struct BookText_Struct { struct BookText_Struct {
uint8 window; // where to display the text (0xFF means new window) uint8 window; // where to display the text (0xFF means new window)
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others. uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
int16 invslot; // Only used in SoF and later clients. uint32 invslot; // Only used in SoF and later clients.
int32 target_id;
int8 can_cast;
int8 can_scribe;
char booktext[1]; // Variable Length char booktext[1]; // Variable Length
}; };
// This is the request to read a book. // This is the request to read a book.
@@ -2571,18 +2557,11 @@ struct BookText_Struct {
struct BookRequest_Struct { struct BookRequest_Struct {
uint8 window; // where to display the text (0xFF means new window) uint8 window; // where to display the text (0xFF means new window)
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others. uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
int16 invslot; // Only used in Sof and later clients; uint32 invslot; // Only used in Sof and later clients;
int32 target_id; int16 subslot; // The subslot inside of a bag if it is inside one.
char txtfile[20]; char txtfile[20];
}; };
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
int16 invslot; // server slot
int32 target_id;
};
/* /*
** Object/Ground Spawn struct ** Object/Ground Spawn struct
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc ** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
@@ -3653,19 +3632,17 @@ struct LevelAppearance_Struct { //Sends a little graphic on level up
}; };
struct MerchantList { struct MerchantList {
uint32 id; uint32 id;
uint32 slot; uint32 slot;
uint32 item; uint32 item;
int16 faction_required; int16 faction_required;
int8 level_required; int8 level_required;
uint8 min_status; uint16 alt_currency_cost;
uint8 max_status; uint32 classes_required;
uint16 alt_currency_cost; uint8 probability;
uint32 classes_required;
uint8 probability;
std::string bucket_name; std::string bucket_name;
std::string bucket_value; std::string bucket_value;
uint8 bucket_comparison; uint8 bucket_comparison;
}; };
struct TempMerchantList { struct TempMerchantList {
@@ -4115,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
@@ -4161,9 +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;
}; };
struct RaidAddMember_Struct { struct RaidAddMember_Struct {
@@ -4174,14 +4148,9 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed... /*139*/ uint8 flags[5]; //no idea if these are needed...
}; };
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct { struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; /*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[1024]; /*136*/ char motd[0]; // max size is 1024, but reply is variable
}; };
struct RaidLeadershipUpdate_Struct { struct RaidLeadershipUpdate_Struct {
@@ -4576,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*/
}; };
@@ -5551,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;
+2 -2
View File
@@ -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;
} }
+1 -1
View File
@@ -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();
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
+6 -2
View File
@@ -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 = "")
{ {
+24 -94
View File
@@ -104,9 +104,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults()
/** /**
* RFC 5424 * RFC 5424
*/ */
log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General); log_settings[Logs::Error].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General); log_settings[Logs::Warning].log_to_console = static_cast<uint8>(Logs::General);
log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General); log_settings[Logs::Info].log_to_console = static_cast<uint8>(Logs::General);
/** /**
* Set Category enabled status on defaults * Set Category enabled status on defaults
@@ -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;
} }
@@ -219,7 +220,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
int line int line
) )
{ {
bool is_error = ( bool is_error = (
log_category == Logs::LogCategory::Error || log_category == Logs::LogCategory::Error ||
log_category == Logs::LogCategory::MySQLError || log_category == Logs::LogCategory::MySQLError ||
log_category == Logs::LogCategory::Crash || log_category == Logs::LogCategory::Crash ||
@@ -261,7 +262,7 @@ void EQEmuLogSys::ProcessConsoleMessage(
} }
if (log_category == Logs::LogCategory::MySQLQuery) { if (log_category == Logs::LogCategory::MySQLQuery) {
auto s = Strings::Split(message, "--"); auto s = Strings::Split(message, "--");
if (s.size() > 1) { if (s.size() > 1) {
std::string query = Strings::Trim(s[0]); std::string query = Strings::Trim(s[0]);
std::string meta = Strings::Trim(s[1]); std::string meta = Strings::Trim(s[1]);
@@ -297,76 +298,19 @@ void EQEmuLogSys::ProcessConsoleMessage(
} }
} }
// color matching in [] if (!is_upper) {
// ex: [<red>variable] would produce [variable] with red inside brackets (!is_error ? std::cout : std::cerr)
std::map<std::string, rang::fgB> colors = { << rang::fgB::gray
{"<black>", rang::fgB::black}, << "["
{"<green>", rang::fgB::green}, << rang::style::bold
{"<yellow>", rang::fgB::yellow}, << rang::fgB::yellow
{"<blue>", rang::fgB::blue}, << e
{"<magenta>", rang::fgB::magenta}, << rang::fgB::gray
{"<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;
}
} }
else {
// string match to colors (!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
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) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
}
} }
} }
else { else {
@@ -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;
}
+1 -13
View File
@@ -136,9 +136,6 @@ namespace Logs {
PacketServerToServer, PacketServerToServer,
Bugs, Bugs,
QuestErrors, QuestErrors,
PlayerEvents,
DataBuckets,
Zoning,
MaxCategoryID /* Don't Remove this */ MaxCategoryID /* Don't Remove this */
}; };
@@ -233,10 +230,7 @@ namespace Logs {
"Packet C->S", "Packet C->S",
"Packet S->S", "Packet S->S",
"Bugs", "Bugs",
"QuestErrors", "QuestErrors"
"PlayerEvents",
"DataBuckets",
"Zoning",
}; };
} }
@@ -328,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;
@@ -381,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
-30
View File
@@ -784,36 +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 LogDataBuckets(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::DataBuckets))\
OutF(LogSys, Logs::General, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogDataBucketsDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::DataBuckets))\
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogZoning(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::Zoning))\
OutF(LogSys, Logs::General, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogZoningDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Zoning))\
OutF(LogSys, Logs::Detail, Logs::Zoning, __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__);\
+4
View File
@@ -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
View File
@@ -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)); }
+1 -1
View File
@@ -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
-702
View File
@@ -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;
}
}
-85
View File
@@ -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
-971
View File
@@ -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)
+33 -17
View File
@@ -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
@@ -240,20 +240,36 @@ enum { //some random constants
//Some hard coded statuses from commands and other places: //Some hard coded statuses from commands and other places:
enum { enum {
minStatusToBeGM = 40, minStatusToBeGM = 40,
minStatusToUseGMCommands = 80, minStatusToUseGMCommands = 80,
minStatusToKick = 150, minStatusToKick = 150,
minStatusToAvoidFalling = 100, minStatusToAvoidFalling = 100,
minStatusToIgnoreZoneFlags = 80, minStatusToHaveInvalidSpells = 80,
minStatusToHaveInvalidSkills = 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
commandCastSpecials = 100, //can cast special spells commandZoneToSpecials = 80, //zone to cshome, out of load zones
commandDoAnimOthers = 100, //can #doanim on others commandToggleAI = 250, //can turn NPC AI on and off
commandEditPlayerCorpses = 150, //can Edit Player Corpses commandCastSpecials = 100, //can cast special spells
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump commandInstacast = 100, //insta-cast all #casted spells
commandInvSnapshot = 150 //ability to clear/restore snapshots 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
commandLockZones = 101, //can lock or unlock zones
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
commandInvSnapshot = 150 //ability to clear/restore snapshots
}; };
@@ -279,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
+2 -32
View File
@@ -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;
@@ -55,14 +54,8 @@ bool File::Exists(const std::string &name)
*/ */
void File::Makedir(const std::string &directory_name) void File::Makedir(const std::string &directory_name)
{ {
try { fs::create_directory(directory_name);
fs::create_directory(directory_name); fs::permissions(directory_name, fs::perms::owner_all);
fs::permissions(directory_name, fs::perms::owner_all);
}
catch (const fs::filesystem_error &ex) {
std::cout << "Failed to create directory: " << directory_name << std::endl;
std::cout << ex.what() << std::endl;
}
} }
std::string File::FindEqemuConfigPath() std::string File::FindEqemuConfigPath()
@@ -87,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,
};
}
-6
View File
@@ -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
View File
@@ -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;
} }
+6 -8
View File
@@ -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 &params, inline Result ClientImpl::Get(const std::string &path, const Params &params,
@@ -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) {
+8 -9
View File
@@ -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,12 +412,11 @@ 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);
return true; return true;
@@ -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
} }
+6 -6
View File
@@ -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
-4
View File
@@ -230,10 +230,6 @@ bool EQ::ItemData::IsTypeShield() const
return (ItemType == item::ItemTypeShield); return (ItemType == item::ItemTypeShield);
} }
bool EQ::ItemData::IsQuestItem() const {
return QuestItemFlag;
}
bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item) bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
{ {
if (!l_item || !r_item) if (!l_item || !r_item)
+159 -165
View File
@@ -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;
@@ -546,7 +541,6 @@ namespace EQ
bool IsType1HWeapon() const; bool IsType1HWeapon() const;
bool IsType2HWeapon() const; bool IsType2HWeapon() const;
bool IsTypeShield() const; bool IsTypeShield() const;
bool IsQuestItem() const;
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item); static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); } bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
+169 -191
View File
@@ -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,62 +57,108 @@ 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_item = nullptr;
}
m_charges = charges; m_charges = charges;
m_price = 0;
if (m_item && m_item->IsClassCommon()) { m_merchantslot = 0;
m_attuned=false;
if (m_item && m_item->IsClassCommon())
m_color = m_item->Color; m_color = m_item->Color;
} else { else
m_color = 0; 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_price = copy.m_price;
m_color = copy.m_color;
m_merchantslot = copy.m_merchantslot;
m_currentslot = copy.m_currentslot;
m_attuned = copy.m_attuned;
m_merchantcount = copy.m_merchantcount;
m_charges=copy.m_charges;
m_price=copy.m_price;
m_color=copy.m_color;
m_merchantslot=copy.m_merchantslot;
m_currentslot=copy.m_currentslot;
m_attuned=copy.m_attuned;
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,42 +168,37 @@ 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;
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;
m_ornamentidfile = copy.m_ornamentidfile; m_ornamentidfile = copy.m_ornamentidfile;
m_ornament_hero_model = copy.m_ornament_hero_model; m_ornament_hero_model = copy.m_ornament_hero_model;
m_recast_timestamp = copy.m_recast_timestamp; m_recast_timestamp = copy.m_recast_timestamp;
m_new_id_file = copy.m_new_id_file; m_new_id_file = copy.m_new_id_file;
} }
// Clean up container contents // Clean up container contents
@@ -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,20 +243,21 @@ 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?
@@ -267,30 +306,26 @@ 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;
}
} }
} }
@@ -323,27 +358,15 @@ 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;
} }
// Retrieve item inside container // Retrieve item inside container
@@ -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(); for (int i = invaug::SOCKET_BEGIN; i <= invaug::SOCKET_END; i++)
if (!augment_item) { {
return false; if (GetAugment(i) && m_item->AugSlotType[i] == ornamentationAugtype)
} {
const char *item_IDFile = GetAugment(i)->GetItem()->IDFile;
const std::string& idfile = augment_item->IDFile; if (
(strncmp(item_IDFile, "IT64", strlen(item_IDFile)) == 0
if ( || strncmp(item_IDFile, "IT63", strlen(item_IDFile)) == 0)
EQ::ValueWithin( && GetAugment(i)->GetItem()->HerosForgeModel == 0
augment->GetAugmentType(), )
OrnamentationAugmentTypes::StandardOrnamentation, {
OrnamentationAugmentTypes::SpecialOrnamentation continue;
) || }
( return GetAugment(i);
idfile != "IT63" &&
idfile != "IT64"
) ||
augment_item->HerosForgeModel
) {
return true;
}
return false;
}
EQ::ItemInstance* EQ::ItemInstance::GetOrnamentationAugment() const
{
if (!m_item || !m_item->IsClassCommon()) {
return nullptr;
}
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;
}
const auto augment = GetOrnamentationAugment(); bool ornamentSet = false;
if (augment) { int32 ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
const auto augment_item = GetOrnamentationAugment()->GetItem(); if (GetOrnamentationAug(ornamentationAugtype))
{
if (augment_item) { const ItemData* ornamentItem;
SetOrnamentIcon(augment_item->Icon); ornamentItem = GetOrnamentationAug(ornamentationAugtype)->GetItem();
SetOrnamentHeroModel(augment_item->HerosForgeModel); if (ornamentItem != nullptr)
{
if (strlen(augment_item->IDFile) > 2) { SetOrnamentIcon(ornamentItem->Icon);
SetOrnamentationIDFile(Strings::ToUnsignedInt(&augment_item->IDFile[2])); SetOrnamentHeroModel(ornamentItem->HerosForgeModel);
} else { if (strlen(ornamentItem->IDFile) > 2)
{
SetOrnamentationIDFile(atoi(&ornamentItem->IDFile[2]));
}
else
{
SetOrnamentationIDFile(0); SetOrnamentationIDFile(0);
} }
ornamentSet = true;
return true;
} }
} }
else
{
SetOrnamentIcon(0);
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
}
SetOrnamentIcon(0); return ornamentSet;
SetOrnamentHeroModel(0);
SetOrnamentationIDFile(0);
return false;
} }
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,14 +714,12 @@ 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
View File
@@ -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;
}; };
} }
-24640
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-2
View File
@@ -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
View File
@@ -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;
+2
View File
@@ -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
+1 -2
View File
@@ -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;
-21
View File
@@ -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;
}
+1 -13
View File
@@ -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();
+1 -1
View File
@@ -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)));
}); });
} }
+6 -6
View File
@@ -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);
+1 -1
View File
@@ -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);
} }
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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);
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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));
+89 -135
View File
@@ -34,7 +34,6 @@
#include "../rulesys.h" #include "../rulesys.h"
#include "../path_manager.h" #include "../path_manager.h"
#include "../races.h" #include "../races.h"
#include "../raid.h"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -1051,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));
@@ -1070,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));
@@ -1100,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);
@@ -1170,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);
@@ -2609,124 +2608,88 @@ namespace RoF
ENCODE(OP_RaidJoin) ENCODE(OP_RaidJoin)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; unsigned char * __emu_buffer = inapp->pBuffer;
unsigned char* __emu_buffer = inapp->pBuffer; RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
general->action = raidCreate; general->action = 8;
general->parameter = RaidCommandAcceptInvite; general->parameter = 1;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->player_name, raid_create->leader_name, 64);
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp); safe_delete(inapp);
} }
ENCODE(OP_RaidUpdate) ENCODE(OP_RaidUpdate)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; *p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer; unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
switch (raid_gen->action) if (raid_gen->action == 0) // raid add has longer length than other raid updates
{ {
case raidAdd: RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetMotd: else if (raid_gen->action == 35)
{ {
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetLeaderAbilities: else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidMakeLeader:
{ {
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetNote: else
{ {
auto emu = (RaidNote_Struct*)__emu_buffer; RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
OUT(action); strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
OUT(parameter); raid_general->action = in_raid_general->action;
OUT_str(leader_name); raid_general->parameter = in_raid_general->parameter;
OUT_str(player_name);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
}
} }
safe_delete(inapp); safe_delete(inapp);
} }
@@ -4898,47 +4861,37 @@ namespace RoF
{ {
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; // This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
switch (rgs->action) case 35: { // raidMOTD
{ // we don't have a nice macro for this
case raidSetMotd: structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
{ __eq_buffer->motd[1023] = '\0';
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
IN(general.action); __packet->pBuffer = new unsigned char[__packet->size];
IN(general.parameter); RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
IN_str(general.leader_name); structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
IN_str(general.player_name); strn0cpy(emu->general.player_name, eq->general.player_name, 64);
IN_str(motd); strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
FINISH_VAR_DECODE(); IN(general.parameter);
break; FINISH_DIRECT_DECODE();
} break;
case raidSetNote: }
{ case 36: { // raidPlayerNote unhandled
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); break;
}
IN(general.action); default: {
IN(general.parameter); DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
IN_str(general.leader_name); SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN_str(general.player_name); strn0cpy(emu->leader_name, eq->leader_name, 64);
IN_str(note); strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
FINISH_VAR_DECODE(); IN(parameter);
break; FINISH_DIRECT_DECODE();
} break;
default: }
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
} }
} }
@@ -5265,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;
+92 -152
View File
@@ -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 "../raid.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);
@@ -2678,124 +2677,88 @@ namespace RoF2
ENCODE(OP_RaidJoin) ENCODE(OP_RaidJoin)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; unsigned char * __emu_buffer = inapp->pBuffer;
unsigned char* __emu_buffer = inapp->pBuffer; RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
general->action = raidCreate; general->action = 8;
general->parameter = RaidCommandAcceptInvite; general->parameter = 1;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->player_name, raid_create->leader_name, 64);
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp); safe_delete(inapp);
} }
ENCODE(OP_RaidUpdate) ENCODE(OP_RaidUpdate)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; *p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer; unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
switch (raid_gen->action) if (raid_gen->action == 0) // raid add has longer length than other raid updates
{ {
case raidAdd: RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetMotd: else if (raid_gen->action == 35)
{ {
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetLeaderAbilities: else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidMakeLeader:
{ {
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetNote: else
{ {
auto emu = (RaidNote_Struct*)__emu_buffer; RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
OUT(action); strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
OUT(parameter); raid_general->action = in_raid_general->action;
OUT_str(leader_name); raid_general->parameter = in_raid_general->parameter;
OUT_str(player_name);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
}
} }
safe_delete(inapp); safe_delete(inapp);
} }
@@ -2809,10 +2772,7 @@ namespace RoF2
else else
eq->window = emu->window; eq->window = emu->window;
OUT(type); OUT(type);
eq->invslot = ServerToRoF2TypelessSlot(emu->invslot, invtype::typePossessions); OUT(invslot);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile)); strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE(); FINISH_ENCODE();
@@ -4438,17 +4398,6 @@ namespace RoF2
FINISH_DIRECT_DECODE(); FINISH_DIRECT_DECODE();
} }
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->slot, invtype::typePossessions));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff) DECODE(OP_Buff)
{ {
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct); DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -5115,47 +5064,37 @@ namespace RoF2
{ {
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; // This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
switch (rgs->action) case 35: { // raidMOTD
{ // we don't have a nice macro for this
case raidSetMotd: structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
{ __eq_buffer->motd[1023] = '\0';
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
IN(general.action); __packet->pBuffer = new unsigned char[__packet->size];
IN(general.parameter); RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
IN_str(general.leader_name); structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
IN_str(general.player_name); strn0cpy(emu->general.player_name, eq->general.player_name, 64);
IN_str(motd); strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
FINISH_VAR_DECODE(); IN(general.parameter);
break; FINISH_DIRECT_DECODE();
} break;
case raidSetNote: }
{ case 36: { // raidPlayerNote unhandled
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); break;
}
IN(general.action); default: {
IN(general.parameter); DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
IN_str(general.leader_name); SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN_str(general.player_name); strn0cpy(emu->leader_name, eq->leader_name, 64);
IN_str(note); strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
FINISH_VAR_DECODE(); IN(parameter);
break; FINISH_DIRECT_DECODE();
} break;
default: }
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
} }
} }
@@ -5165,8 +5104,8 @@ namespace RoF2
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct); SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type); IN(type);
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->invslot, invtype::typePossessions)); IN(invslot);
IN(target_id); IN(subslot);
emu->window = (uint8)eq->window; emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile)); strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
@@ -5538,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;
-1
View File
@@ -150,7 +150,6 @@ D(OP_AugmentInfo)
D(OP_AugmentItem) D(OP_AugmentItem)
D(OP_BazaarSearch) D(OP_BazaarSearch)
D(OP_BlockedBuffs) D(OP_BlockedBuffs)
D(OP_BookButton)
D(OP_Buff) D(OP_Buff)
D(OP_BuffRemoveRequest) D(OP_BuffRemoveRequest)
D(OP_CastSpell) D(OP_CastSpell)
+13 -26
View File
@@ -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
@@ -2868,23 +2868,15 @@ struct BookText_Struct {
// This is just a "text file" on the server // This is just a "text file" on the server
// or in our case, the 'name' column in our books table. // or in our case, the 'name' column in our books table.
struct BookRequest_Struct { struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window). /*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ TypelessInventorySlot_Struct invslot; // book ItemIndex (with int16_t alignment padding) /*0004*/ uint16 invslot; // Is the slot, but the RoF2 conversion causes it to fail. Turned to 0 since it isnt required anyway.
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others /*0006*/ int16 subslot; // Inventory sub-slot (0-x)
/*0016*/ uint32 target_id; // client's target when using the book /*0008*/ uint16 unknown006; // Seen FFFF
/*0020*/ uint8 can_cast; // show Cast Spell button in book window /*0010*/ uint16 unknown008; // seen 0000
/*0021*/ uint8 can_scribe; // show Scribe button in book window /*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0022*/ char txtfile[8194]; /*0016*/ uint32 unknown0012;
/*8216*/ /*0020*/ uint16 unknown0016;
}; /*0022*/ char txtfile[8194];
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ TypelessInventorySlot_Struct slot; // book ItemIndex (with int16_t alignment padding)
/*0008*/ int32 target_id; // client's target when using the book button
/*0012*/ int32 unused; // always 0 from button packets
/*0016*/
}; };
/* /*
@@ -4198,14 +4190,9 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed... /*139*/ uint8 flags[5]; //no idea if these are needed...
}; };
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct { struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; /*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[1024]; /*140*/ char motd[0]; // max size 1024, but reply is variable
}; };
struct RaidLeadershipUpdate_Struct { struct RaidLeadershipUpdate_Struct {
+3 -8
View File
@@ -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
@@ -4136,14 +4136,9 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed... /*139*/ uint8 flags[5]; //no idea if these are needed...
}; };
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct { struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used /*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[1024]; // max size is 1024, but reply is variable /*140*/ char motd[0]; // max size 1024, but reply is variable
}; };
struct RaidLeadershipUpdate_Struct { struct RaidLeadershipUpdate_Struct {
+89 -151
View File
@@ -34,7 +34,6 @@
#include "../rulesys.h" #include "../rulesys.h"
#include "../path_manager.h" #include "../path_manager.h"
#include "../races.h" #include "../races.h"
#include "../raid.h"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -786,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));
@@ -805,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));
@@ -835,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);
@@ -903,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);
@@ -1687,124 +1686,88 @@ namespace SoD
ENCODE(OP_RaidJoin) ENCODE(OP_RaidJoin)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; unsigned char * __emu_buffer = inapp->pBuffer;
unsigned char* __emu_buffer = inapp->pBuffer; RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
general->action = raidCreate; general->action = 8;
general->parameter = RaidCommandAcceptInvite; general->parameter = 1;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->player_name, raid_create->leader_name, 64);
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp); safe_delete(inapp);
} }
ENCODE(OP_RaidUpdate) ENCODE(OP_RaidUpdate)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; *p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer; unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
switch (raid_gen->action) if (raid_gen->action == 0) // raid add has longer length than other raid updates
{ {
case raidAdd: RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetMotd: else if (raid_gen->action == 35)
{ {
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetLeaderAbilities: else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidMakeLeader:
{ {
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetNote: else
{ {
auto emu = (RaidNote_Struct*)__emu_buffer; RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
OUT(action); strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
OUT(parameter); raid_general->action = in_raid_general->action;
OUT_str(leader_name); raid_general->parameter = in_raid_general->parameter;
OUT_str(player_name);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
}
} }
safe_delete(inapp); safe_delete(inapp);
} }
@@ -1819,9 +1782,6 @@ namespace SoD
eq->window = emu->window; eq->window = emu->window;
OUT(type); OUT(type);
eq->invslot = ServerToSoDSlot(emu->invslot); eq->invslot = ServerToSoDSlot(emu->invslot);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile)); strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE(); FINISH_ENCODE();
@@ -2857,17 +2817,6 @@ namespace SoD
FINISH_DIRECT_DECODE(); FINISH_DIRECT_DECODE();
} }
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff) DECODE(OP_Buff)
{ {
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct); DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -3375,47 +3324,37 @@ namespace SoD
{ {
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; // This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
switch (rgs->action) case 35: { // raidMOTD
{ // we don't have a nice macro for this
case raidSetMotd: structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
{ __eq_buffer->motd[1023] = '\0';
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
IN(general.action); __packet->pBuffer = new unsigned char[__packet->size];
IN(general.parameter); RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
IN_str(general.leader_name); structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
IN_str(general.player_name); strn0cpy(emu->general.player_name, eq->general.player_name, 64);
IN_str(motd); strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
FINISH_VAR_DECODE(); IN(general.parameter);
break; FINISH_DIRECT_DECODE();
} break;
case raidSetNote: }
{ case 36: { // raidPlayerNote unhandled
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); break;
}
IN(general.action); default: {
IN(general.parameter); DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
IN_str(general.leader_name); SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN_str(general.player_name); strn0cpy(emu->leader_name, eq->leader_name, 64);
IN_str(note); strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
FINISH_VAR_DECODE(); IN(parameter);
break; FINISH_DIRECT_DECODE();
} break;
default: }
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
} }
} }
@@ -3425,8 +3364,7 @@ namespace SoD
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct); SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type); IN(type);
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot)); emu->invslot = SoDToServerSlot(eq->invslot);
IN(target_id);
emu->window = (uint8)eq->window; emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile)); strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
-1
View File
@@ -103,7 +103,6 @@ D(OP_ApplyPoison)
D(OP_AugmentInfo) D(OP_AugmentInfo)
D(OP_AugmentItem) D(OP_AugmentItem)
D(OP_BazaarSearch) D(OP_BazaarSearch)
D(OP_BookButton)
D(OP_Buff) D(OP_Buff)
D(OP_CastSpell) D(OP_CastSpell)
D(OP_ChannelMessage) D(OP_ChannelMessage)
+9 -23
View File
@@ -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
@@ -2351,21 +2351,12 @@ struct BookText_Struct {
// This is just a "text file" on the server // This is just a "text file" on the server
// or in our case, the 'name' column in our books table. // or in our case, the 'name' column in our books table.
struct BookRequest_Struct { struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window). /*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in /*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others /*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 target_id; /*0012*/ uint32 unknown0012;
/*0016*/ uint8 can_cast; /*0016*/ uint16 unknown0016;
/*0017*/ uint8 can_scribe; /*0018*/ char txtfile[8194];
/*0018*/ char txtfile[8194];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ int32 invslot;
/*0004*/ int32 target_id; // client's target when using the book
/*0008*/ int32 unused; // always 0 from button packets
}; };
/* /*
@@ -3592,14 +3583,9 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed... /*139*/ uint8 flags[5]; //no idea if these are needed...
}; };
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct { struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used /*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[1024]; // max size is 1024, but reply is variable /*140*/ char motd[0]; // max size 1024, but reply is variable
}; };
struct RaidLeadershipUpdate_Struct { struct RaidLeadershipUpdate_Struct {
+88 -150
View File
@@ -33,7 +33,6 @@
#include "sof_structs.h" #include "sof_structs.h"
#include "../rulesys.h" #include "../rulesys.h"
#include "../path_manager.h" #include "../path_manager.h"
#include "../raid.h"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -1357,124 +1356,88 @@ namespace SoF
ENCODE(OP_RaidJoin) ENCODE(OP_RaidJoin)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; unsigned char * __emu_buffer = inapp->pBuffer;
unsigned char* __emu_buffer = inapp->pBuffer; RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
general->action = raidCreate; general->action = 8;
general->parameter = RaidCommandAcceptInvite; general->parameter = 1;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); strn0cpy(general->player_name, raid_create->leader_name, 64);
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp); safe_delete(inapp);
} }
ENCODE(OP_RaidUpdate) ENCODE(OP_RaidUpdate)
{ {
EQApplicationPacket* inapp = *p; EQApplicationPacket *inapp = *p;
*p = nullptr; *p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer; unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
switch (raid_gen->action) if (raid_gen->action == 0) // raid add has longer length than other raid updates
{ {
case raidAdd: RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetMotd: else if (raid_gen->action == 35)
{ {
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetLeaderAbilities: else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidMakeLeader:
{ {
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
} }
case raidSetNote: else
{ {
auto emu = (RaidNote_Struct*)__emu_buffer; RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
OUT(action); strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
OUT(parameter); raid_general->action = in_raid_general->action;
OUT_str(leader_name); raid_general->parameter = in_raid_general->parameter;
OUT_str(player_name);
dest->FastQueuePacket(&outapp); dest->FastQueuePacket(&outapp);
break;
}
} }
safe_delete(inapp); safe_delete(inapp);
} }
@@ -1489,9 +1452,6 @@ namespace SoF
eq->window = emu->window; eq->window = emu->window;
OUT(type); OUT(type);
eq->invslot = ServerToSoFSlot(emu->invslot); eq->invslot = ServerToSoFSlot(emu->invslot);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile)); strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE(); FINISH_ENCODE();
@@ -2135,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'))
{ {
@@ -2149,7 +2109,7 @@ namespace SoF
} }
else else
{ {
val = Strings::ToInt(&sep[1]); val = atoi(&sep[1]);
} }
} }
@@ -2301,17 +2261,6 @@ namespace SoF
FINISH_DIRECT_DECODE(); FINISH_DIRECT_DECODE();
} }
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff) DECODE(OP_Buff)
{ {
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct); DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -2780,47 +2729,37 @@ namespace SoF
{ {
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; // This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
switch (rgs->action) case 35: { // raidMOTD
{ // we don't have a nice macro for this
case raidSetMotd: structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
{ __eq_buffer->motd[1023] = '\0';
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
IN(general.action); __packet->pBuffer = new unsigned char[__packet->size];
IN(general.parameter); RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
IN_str(general.leader_name); structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
IN_str(general.player_name); strn0cpy(emu->general.player_name, eq->general.player_name, 64);
IN_str(motd); strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
FINISH_VAR_DECODE(); IN(general.parameter);
break; FINISH_DIRECT_DECODE();
} break;
case raidSetNote: }
{ case 36: { // raidPlayerNote unhandled
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); break;
}
IN(general.action); default: {
IN(general.parameter); DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
IN_str(general.leader_name); SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN_str(general.player_name); strn0cpy(emu->leader_name, eq->leader_name, 64);
IN_str(note); strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
FINISH_VAR_DECODE(); IN(parameter);
break; FINISH_DIRECT_DECODE();
} break;
default: }
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
} }
} }
@@ -2830,8 +2769,7 @@ namespace SoF
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct); SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type); IN(type);
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot)); emu->invslot = SoFToServerSlot(eq->invslot);
IN(target_id);
emu->window = (uint8)eq->window; emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile)); strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
-1
View File
@@ -94,7 +94,6 @@ D(OP_AltCurrencySellSelection)
D(OP_ApplyPoison) D(OP_ApplyPoison)
D(OP_AugmentInfo) D(OP_AugmentInfo)
D(OP_AugmentItem) D(OP_AugmentItem)
D(OP_BookButton)
D(OP_Buff) D(OP_Buff)
D(OP_Bug) D(OP_Bug)
D(OP_CastSpell) D(OP_CastSpell)
+7 -21
View File
@@ -2321,21 +2321,12 @@ struct BookText_Struct {
// This is just a "text file" on the server // This is just a "text file" on the server
// or in our case, the 'name' column in our books table. // or in our case, the 'name' column in our books table.
struct BookRequest_Struct { struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window). /*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in /*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others /*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 target_id; /*0012*/ uint32 unknown0012;
/*0016*/ uint8 can_cast; /*0016*/ uint16 unknown0016;
/*0017*/ uint8 can_scribe; /*0018*/ char txtfile[8194];
/*0018*/ char txtfile[8194];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ int32 invslot;
/*0004*/ int32 target_id; // client's target when using the book
/*0008*/ int32 unused; // always 0 from button packets
}; };
/* /*
@@ -3517,14 +3508,9 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed... /*139*/ uint8 flags[5]; //no idea if these are needed...
}; };
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct { struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used /*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[1024]; // max size is 1024, but reply is variable /*140*/ char motd[0]; // max size 1024, but reply is variable
}; };
struct RaidLeadershipUpdate_Struct { struct RaidLeadershipUpdate_Struct {
-12
View File
@@ -128,15 +128,6 @@
emu_struct *emu = (emu_struct *) __packet->pBuffer; \ emu_struct *emu = (emu_struct *) __packet->pBuffer; \
eq_struct *eq = (eq_struct *) __eq_buffer; eq_struct *eq = (eq_struct *) __eq_buffer;
#define SETUP_VAR_DECODE(emu_struct, eq_struct, var_field) \
unsigned char *__eq_buffer = __packet->pBuffer; \
eq_struct* in = (eq_struct*)__packet->pBuffer; \
auto size = strlen(in->var_field); \
__packet->size = sizeof(emu_struct) + size + 1; \
__packet->pBuffer = new unsigned char[__packet->size]; \
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
eq_struct *eq = (eq_struct *) __eq_buffer;
#define MEMSET_IN(emu_struct) \ #define MEMSET_IN(emu_struct) \
memset(__packet->pBuffer, 0, sizeof(emu_struct)); memset(__packet->pBuffer, 0, sizeof(emu_struct));
@@ -155,9 +146,6 @@
delete[] __eq_buffer; \ delete[] __eq_buffer; \
p->SetOpcode(OP_Unknown); p->SetOpcode(OP_Unknown);
#define FINISH_VAR_DECODE() \
delete[] __eq_buffer;
//call to finish an encoder using SETUP_DIRECT_DECODE //call to finish an encoder using SETUP_DIRECT_DECODE
#define FINISH_DIRECT_DECODE() \ #define FINISH_DIRECT_DECODE() \
delete[] __eq_buffer; delete[] __eq_buffer;
-171
View File
@@ -33,7 +33,6 @@
#include "../item_instance.h" #include "../item_instance.h"
#include "titanium_structs.h" #include "titanium_structs.h"
#include "../path_manager.h" #include "../path_manager.h"
#include "../raid.h"
#include <sstream> #include <sstream>
@@ -1246,119 +1245,6 @@ namespace Titanium
FINISH_ENCODE(); FINISH_ENCODE();
} }
ENCODE(OP_MarkRaidNPC)
{
ENCODE_LENGTH_EXACT(MarkNPC_Struct);
SETUP_DIRECT_ENCODE(MarkNPC_Struct, MarkNPC_Struct);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
mnpcs->TargetID = emu->TargetID;
mnpcs->Number = emu->Number;
dest->QueuePacket(outapp);
safe_delete(outapp);
FINISH_ENCODE();
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
switch (raid_gen->action)
{
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
dest->FastQueuePacket(&outapp);
break;
}
case raidSetMotd:
{
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
dest->FastQueuePacket(&outapp);
break;
}
case raidSetLeaderAbilities:
case raidMakeLeader:
{
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
case raidSetNote:
{
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
ENCODE(OP_ReadBook) ENCODE(OP_ReadBook)
{ {
// no apparent slot translation needed // no apparent slot translation needed
@@ -2386,63 +2272,6 @@ namespace Titanium
FINISH_DIRECT_DECODE(); FINISH_DIRECT_DECODE();
} }
DECODE(OP_RaidInvite)
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
auto len = 0;
if (__packet->size < sizeof(structs::RaidMOTD_Struct)) {
len = __packet->size - sizeof(structs::RaidGeneral_Struct);
}
else {
len = sizeof(eq->motd);
}
strn0cpy(emu->motd, eq->motd, len > 1024 ? 1024 : len);
emu->motd[len - 1] = '\0';
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
DECODE(OP_ReadBook) DECODE(OP_ReadBook)
{ {
// no apparent slot translation needed // no apparent slot translation needed
-3
View File
@@ -61,8 +61,6 @@ E(OP_OnLevelMessage)
E(OP_PetBuffWindow) E(OP_PetBuffWindow)
E(OP_PlayerProfile) E(OP_PlayerProfile)
E(OP_NewSpawn) E(OP_NewSpawn)
E(OP_MarkRaidNPC)
E(OP_RaidUpdate)
E(OP_ReadBook) E(OP_ReadBook)
E(OP_RespondAA) E(OP_RespondAA)
E(OP_SendCharInfo) E(OP_SendCharInfo)
@@ -108,7 +106,6 @@ D(OP_LoadSpellSet)
D(OP_LootItem) D(OP_LootItem)
D(OP_MoveItem) D(OP_MoveItem)
D(OP_PetCommands) D(OP_PetCommands)
D(OP_RaidInvite)
D(OP_ReadBook) D(OP_ReadBook)
D(OP_SetServerFilter) D(OP_SetServerFilter)
D(OP_ShopPlayerSell) D(OP_ShopPlayerSell)

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