mirror of
https://github.com/EQEmu/Server.git
synced 2026-04-06 16:22:25 +00:00
Warning fixes, general cleanup (#5053)
This commit is contained in:
parent
435224631f
commit
491b1edd12
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -20,3 +20,4 @@
|
|||||||
*.css text
|
*.css text
|
||||||
*.js text
|
*.js text
|
||||||
*.types text
|
*.types text
|
||||||
|
*.pdf binary
|
||||||
|
|||||||
@ -20,7 +20,7 @@ endif()
|
|||||||
|
|
||||||
project(EQEmu
|
project(EQEmu
|
||||||
VERSION 24.10.3
|
VERSION 24.10.3
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
@ -42,10 +42,10 @@ option(EQEMU_BUILD_PCH "Build with precompiled headers (Windows)" ON)
|
|||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_compile_options(/bigobj)
|
add_compile_options(/bigobj)
|
||||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS NOMINMAX CRASH_LOGGING _HAS_AUTO_PTR_ETC)
|
add_compile_definitions(_CRT_SECURE_NO_WARNINGS NOMINMAX WIN32_LEAN_AND_MEAN CRASH_LOGGING _HAS_AUTO_PTR_ETC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
|
|
||||||
option(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
option(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." OFF)
|
||||||
if(EQEMU_DISABLE_MSVC_WARNINGS)
|
if(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||||
add_compile_options(/W0 /wd4005 /wd4996 /nologo /Os)
|
add_compile_options(/W0 /wd4005 /wd4996 /nologo /Os)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@ -7,20 +7,20 @@ set(common_sources
|
|||||||
classes.cpp
|
classes.cpp
|
||||||
cli/eqemu_command_handler.cpp
|
cli/eqemu_command_handler.cpp
|
||||||
compression.cpp
|
compression.cpp
|
||||||
condition.cpp
|
|
||||||
content/world_content_service.cpp
|
content/world_content_service.cpp
|
||||||
crash.cpp
|
crash.cpp
|
||||||
crc16.cpp
|
crc16.cpp
|
||||||
crc32.cpp
|
crc32.cpp
|
||||||
data_bucket.cpp
|
data_bucket.cpp
|
||||||
|
data_bucket.cpp
|
||||||
|
database_instances.cpp
|
||||||
database.cpp
|
database.cpp
|
||||||
database/database_dump_service.cpp
|
database/database_dump_service.cpp
|
||||||
database/database_update.cpp
|
database/database_update.cpp
|
||||||
database_instances.cpp
|
|
||||||
dbcore.cpp
|
dbcore.cpp
|
||||||
deity.cpp
|
deity.cpp
|
||||||
discord/discord.cpp
|
|
||||||
discord/discord_manager.cpp
|
discord/discord_manager.cpp
|
||||||
|
discord/discord.cpp
|
||||||
dynamic_zone_base.cpp
|
dynamic_zone_base.cpp
|
||||||
dynamic_zone_lockout.cpp
|
dynamic_zone_lockout.cpp
|
||||||
emu_constants.cpp
|
emu_constants.cpp
|
||||||
@ -31,13 +31,16 @@ set(common_sources
|
|||||||
eq_packet.cpp
|
eq_packet.cpp
|
||||||
eq_stream_ident.cpp
|
eq_stream_ident.cpp
|
||||||
eq_stream_proxy.cpp
|
eq_stream_proxy.cpp
|
||||||
eqdb.cpp
|
|
||||||
eqdb_res.cpp
|
eqdb_res.cpp
|
||||||
|
eqdb.cpp
|
||||||
eqemu_config.cpp
|
eqemu_config.cpp
|
||||||
eqemu_exception.cpp
|
eqemu_exception.cpp
|
||||||
eqemu_logsys.cpp
|
eqemu_logsys.cpp
|
||||||
eqtime.cpp
|
eqtime.cpp
|
||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
|
event/event_loop.cpp
|
||||||
|
event/task_scheduler.cpp
|
||||||
|
event/timer.cpp
|
||||||
events/player_event_discord_formatter.cpp
|
events/player_event_discord_formatter.cpp
|
||||||
events/player_event_logs.cpp
|
events/player_event_logs.cpp
|
||||||
evolving_items.cpp
|
evolving_items.cpp
|
||||||
@ -51,62 +54,56 @@ set(common_sources
|
|||||||
ipc_mutex.cpp
|
ipc_mutex.cpp
|
||||||
item_data.cpp
|
item_data.cpp
|
||||||
item_instance.cpp
|
item_instance.cpp
|
||||||
json/json.hpp
|
|
||||||
json/jsoncpp.cpp
|
|
||||||
json_config.cpp
|
json_config.cpp
|
||||||
|
json/jsoncpp.cpp
|
||||||
light_source.cpp
|
light_source.cpp
|
||||||
md5.cpp
|
md5.cpp
|
||||||
memory/ksm.hpp
|
|
||||||
memory_buffer.cpp
|
memory_buffer.cpp
|
||||||
memory_mapped_file.cpp
|
memory_mapped_file.cpp
|
||||||
misc.cpp
|
memory/ksm.cpp
|
||||||
misc_functions.cpp
|
misc_functions.cpp
|
||||||
mutex.cpp
|
misc.cpp
|
||||||
mysql_request_result.cpp
|
mysql_request_result.cpp
|
||||||
mysql_request_row.cpp
|
mysql_request_row.cpp
|
||||||
mysql_stmt.cpp
|
mysql_stmt.cpp
|
||||||
net/console_server.cpp
|
|
||||||
net/console_server_connection.cpp
|
net/console_server_connection.cpp
|
||||||
|
net/console_server.cpp
|
||||||
net/crc32.cpp
|
net/crc32.cpp
|
||||||
|
net/dns.cpp
|
||||||
net/eqstream.cpp
|
net/eqstream.cpp
|
||||||
net/packet.cpp
|
net/packet.cpp
|
||||||
net/reliable_stream_connection.cpp
|
net/reliable_stream_connection.cpp
|
||||||
net/servertalk_client_connection.cpp
|
net/servertalk_client_connection.cpp
|
||||||
net/servertalk_legacy_client_connection.cpp
|
net/servertalk_legacy_client_connection.cpp
|
||||||
net/servertalk_server.cpp
|
|
||||||
net/servertalk_server_connection.cpp
|
net/servertalk_server_connection.cpp
|
||||||
|
net/servertalk_server.cpp
|
||||||
net/tcp_connection.cpp
|
net/tcp_connection.cpp
|
||||||
net/tcp_server.cpp
|
net/tcp_server.cpp
|
||||||
net/websocket_server.cpp
|
|
||||||
net/websocket_server_connection.cpp
|
net/websocket_server_connection.cpp
|
||||||
|
net/websocket_server.cpp
|
||||||
opcode_map.cpp
|
opcode_map.cpp
|
||||||
opcodemgr.cpp
|
opcodemgr.cpp
|
||||||
packet_dump.cpp
|
|
||||||
packet_dump_file.cpp
|
packet_dump_file.cpp
|
||||||
|
packet_dump.cpp
|
||||||
packet_functions.cpp
|
packet_functions.cpp
|
||||||
patches/patches.cpp
|
patches/patches.cpp
|
||||||
patches/rof.cpp
|
|
||||||
patches/rof2.cpp
|
|
||||||
patches/rof2_limits.cpp
|
|
||||||
patches/rof_limits.cpp
|
patches/rof_limits.cpp
|
||||||
patches/sod.cpp
|
patches/rof.cpp
|
||||||
|
patches/rof2_limits.cpp
|
||||||
|
patches/rof2.cpp
|
||||||
patches/sod_limits.cpp
|
patches/sod_limits.cpp
|
||||||
patches/sof.cpp
|
patches/sod.cpp
|
||||||
patches/sof_limits.cpp
|
patches/sof_limits.cpp
|
||||||
patches/titanium.cpp
|
patches/sof.cpp
|
||||||
patches/titanium_limits.cpp
|
patches/titanium_limits.cpp
|
||||||
patches/uf.cpp
|
patches/titanium.cpp
|
||||||
patches/uf_limits.cpp
|
patches/uf_limits.cpp
|
||||||
|
patches/uf.cpp
|
||||||
|
path_manager.cpp
|
||||||
path_manager.cpp
|
path_manager.cpp
|
||||||
perl_eqdb.cpp
|
|
||||||
perl_eqdb_res.cpp
|
perl_eqdb_res.cpp
|
||||||
|
perl_eqdb.cpp
|
||||||
platform.cpp
|
platform.cpp
|
||||||
platform/inet.h
|
|
||||||
platform/platform.h
|
|
||||||
platform/posix/include_inet.h
|
|
||||||
platform/posix/include_pthreads.h
|
|
||||||
platform/win/include_windows.h
|
|
||||||
platform/win/include_winsock2.h
|
|
||||||
proc_launcher.cpp
|
proc_launcher.cpp
|
||||||
process.cpp
|
process.cpp
|
||||||
process/process.cpp
|
process/process.cpp
|
||||||
@ -123,12 +120,12 @@ set(common_sources
|
|||||||
shareddb.cpp
|
shareddb.cpp
|
||||||
skill_caps.cpp
|
skill_caps.cpp
|
||||||
skills.cpp
|
skills.cpp
|
||||||
spdat.cpp
|
|
||||||
spdat_bot.cpp
|
spdat_bot.cpp
|
||||||
|
spdat.cpp
|
||||||
StackWalker/StackWalker.cpp
|
StackWalker/StackWalker.cpp
|
||||||
strings.cpp
|
|
||||||
strings_legacy.cpp
|
strings_legacy.cpp
|
||||||
strings_misc.cpp
|
strings_misc.cpp
|
||||||
|
strings.cpp
|
||||||
struct_strategy.cpp
|
struct_strategy.cpp
|
||||||
textures.cpp
|
textures.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
@ -538,35 +535,32 @@ set(repositories
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(common_headers
|
set(common_headers
|
||||||
StackWalker/StackWalker.h
|
|
||||||
additive_lagged_fibonacci_engine.h
|
additive_lagged_fibonacci_engine.h
|
||||||
base_packet.h
|
base_packet.h
|
||||||
bazaar.h
|
bazaar.h
|
||||||
bodytypes.h
|
bodytypes.h
|
||||||
|
classes.h
|
||||||
cli/argh.h
|
cli/argh.h
|
||||||
cli/eqemu_command_handler.h
|
cli/eqemu_command_handler.h
|
||||||
cli/terminal_color.hpp
|
cli/terminal_color.hpp
|
||||||
classes.h
|
|
||||||
compression.h
|
compression.h
|
||||||
condition.h
|
|
||||||
content/world_content_service.h
|
content/world_content_service.h
|
||||||
crash.h
|
crash.h
|
||||||
crc16.h
|
crc16.h
|
||||||
crc32.h
|
crc32.h
|
||||||
cron/croncpp.h
|
cron/croncpp.h
|
||||||
data_bucket.cpp
|
|
||||||
data_verification.h
|
data_verification.h
|
||||||
|
database_schema.h
|
||||||
database.h
|
database.h
|
||||||
database/database_dump_service.h
|
database/database_dump_service.h
|
||||||
database/database_update.h
|
|
||||||
database/database_update_manifest.h
|
|
||||||
database/database_update_manifest_bots.h
|
database/database_update_manifest_bots.h
|
||||||
database/database_update_manifest_custom.h
|
database/database_update_manifest_custom.h
|
||||||
database_schema.h
|
database/database_update_manifest.h
|
||||||
|
database/database_update.h
|
||||||
dbcore.h
|
dbcore.h
|
||||||
deity.h
|
deity.h
|
||||||
discord/discord.h
|
|
||||||
discord/discord_manager.h
|
discord/discord_manager.h
|
||||||
|
discord/discord.h
|
||||||
dynamic_zone_base.h
|
dynamic_zone_base.h
|
||||||
dynamic_zone_lockout.h
|
dynamic_zone_lockout.h
|
||||||
emu_constants.h
|
emu_constants.h
|
||||||
@ -576,24 +570,24 @@ set(common_headers
|
|||||||
emu_versions.h
|
emu_versions.h
|
||||||
eq_constants.h
|
eq_constants.h
|
||||||
eq_limits.h
|
eq_limits.h
|
||||||
eq_packet.h
|
|
||||||
eq_packet_structs.h
|
eq_packet_structs.h
|
||||||
|
eq_packet.h
|
||||||
eq_stream_ident.h
|
eq_stream_ident.h
|
||||||
eq_stream_intf.h
|
eq_stream_intf.h
|
||||||
eq_stream_locator.h
|
eq_stream_locator.h
|
||||||
eq_stream_proxy.h
|
eq_stream_proxy.h
|
||||||
eqdb.h
|
|
||||||
eqdb_res.h
|
eqdb_res.h
|
||||||
eqemu_config.h
|
eqdb.h
|
||||||
eqemu_config_elements.h
|
eqemu_config_elements.h
|
||||||
|
eqemu_config.h
|
||||||
eqemu_exception.h
|
eqemu_exception.h
|
||||||
eqemu_logsys.h
|
|
||||||
eqemu_logsys_log_aliases.h
|
eqemu_logsys_log_aliases.h
|
||||||
|
eqemu_logsys.h
|
||||||
eqtime.h
|
eqtime.h
|
||||||
|
event_sub.h
|
||||||
event/event_loop.h
|
event/event_loop.h
|
||||||
event/task.h
|
event/task.h
|
||||||
event/timer.h
|
event/timer.h
|
||||||
event_sub.h
|
|
||||||
events/player_event_discord_formatter.h
|
events/player_event_discord_formatter.h
|
||||||
events/player_event_logs.h
|
events/player_event_logs.h
|
||||||
events/player_events.h
|
events/player_events.h
|
||||||
@ -614,10 +608,11 @@ set(common_headers
|
|||||||
ipc_mutex.h
|
ipc_mutex.h
|
||||||
item_data.h
|
item_data.h
|
||||||
item_instance.h
|
item_instance.h
|
||||||
|
json_config.h
|
||||||
|
json/json_archive_single_line.h
|
||||||
json/json-forwards.h
|
json/json-forwards.h
|
||||||
json/json.h
|
json/json.h
|
||||||
json/json_archive_single_line.h
|
json/json.hpp
|
||||||
json_config.h
|
|
||||||
light_source.h
|
light_source.h
|
||||||
linked_list.h
|
linked_list.h
|
||||||
loot.h
|
loot.h
|
||||||
@ -625,14 +620,14 @@ set(common_headers
|
|||||||
md5.h
|
md5.h
|
||||||
memory_buffer.h
|
memory_buffer.h
|
||||||
memory_mapped_file.h
|
memory_mapped_file.h
|
||||||
misc.h
|
memory/ksm.h
|
||||||
misc_functions.h
|
misc_functions.h
|
||||||
mutex.h
|
misc.h
|
||||||
mysql_request_result.h
|
mysql_request_result.h
|
||||||
mysql_request_row.h
|
mysql_request_row.h
|
||||||
mysql_stmt.h
|
mysql_stmt.h
|
||||||
net/console_server.h
|
|
||||||
net/console_server_connection.h
|
net/console_server_connection.h
|
||||||
|
net/console_server.h
|
||||||
net/crc32.h
|
net/crc32.h
|
||||||
net/dns.h
|
net/dns.h
|
||||||
net/endian.h
|
net/endian.h
|
||||||
@ -644,49 +639,54 @@ set(common_headers
|
|||||||
net/servertalk_client_connection.h
|
net/servertalk_client_connection.h
|
||||||
net/servertalk_common.h
|
net/servertalk_common.h
|
||||||
net/servertalk_legacy_client_connection.h
|
net/servertalk_legacy_client_connection.h
|
||||||
net/servertalk_server.h
|
|
||||||
net/servertalk_server_connection.h
|
net/servertalk_server_connection.h
|
||||||
net/tcp_connection.h
|
net/servertalk_server.h
|
||||||
net/tcp_connection_pooling.h
|
net/tcp_connection_pooling.h
|
||||||
|
net/tcp_connection.h
|
||||||
net/tcp_server.h
|
net/tcp_server.h
|
||||||
net/websocket_server.h
|
|
||||||
net/websocket_server_connection.h
|
net/websocket_server_connection.h
|
||||||
|
net/websocket_server.h
|
||||||
op_codes.h
|
op_codes.h
|
||||||
opcode_dispatch.h
|
opcode_dispatch.h
|
||||||
opcodemgr.h
|
opcodemgr.h
|
||||||
packet_dump.h
|
|
||||||
packet_dump_file.h
|
packet_dump_file.h
|
||||||
|
packet_dump.h
|
||||||
packet_functions.h
|
packet_functions.h
|
||||||
patches/patches.h
|
patches/patches.h
|
||||||
patches/rof.h
|
|
||||||
patches/rof2.h
|
|
||||||
patches/rof2_limits.h
|
|
||||||
patches/rof2_ops.h
|
|
||||||
patches/rof2_structs.h
|
|
||||||
patches/rof_limits.h
|
patches/rof_limits.h
|
||||||
patches/rof_ops.h
|
patches/rof_ops.h
|
||||||
patches/rof_structs.h
|
patches/rof_structs.h
|
||||||
patches/sod.h
|
patches/rof.h
|
||||||
|
patches/rof2_limits.h
|
||||||
|
patches/rof2_ops.h
|
||||||
|
patches/rof2_structs.h
|
||||||
|
patches/rof2.h
|
||||||
patches/sod_limits.h
|
patches/sod_limits.h
|
||||||
patches/sod_ops.h
|
patches/sod_ops.h
|
||||||
patches/sod_structs.h
|
patches/sod_structs.h
|
||||||
patches/sof.h
|
patches/sod.h
|
||||||
patches/sof_limits.h
|
patches/sof_limits.h
|
||||||
patches/sof_ops.h
|
patches/sof_ops.h
|
||||||
patches/sof_structs.h
|
patches/sof_structs.h
|
||||||
|
patches/sof.h
|
||||||
patches/ss_declare.h
|
patches/ss_declare.h
|
||||||
patches/ss_define.h
|
patches/ss_define.h
|
||||||
patches/ss_register.h
|
patches/ss_register.h
|
||||||
patches/titanium.h
|
|
||||||
patches/titanium_limits.h
|
patches/titanium_limits.h
|
||||||
patches/titanium_ops.h
|
patches/titanium_ops.h
|
||||||
patches/titanium_structs.h
|
patches/titanium_structs.h
|
||||||
patches/uf.h
|
patches/titanium.h
|
||||||
patches/uf_limits.h
|
patches/uf_limits.h
|
||||||
patches/uf_ops.h
|
patches/uf_ops.h
|
||||||
patches/uf_structs.h
|
patches/uf_structs.h
|
||||||
path_manager.cpp
|
patches/uf.h
|
||||||
platform.h
|
platform.h
|
||||||
|
platform/inet.h
|
||||||
|
platform/platform.h
|
||||||
|
platform/posix/include_inet.h
|
||||||
|
platform/posix/include_pthreads.h
|
||||||
|
platform/win/include_windows.h
|
||||||
|
platform/win/include_winsock2.h
|
||||||
proc_launcher.h
|
proc_launcher.h
|
||||||
process.h
|
process.h
|
||||||
process/process.h
|
process/process.h
|
||||||
@ -713,6 +713,7 @@ set(common_headers
|
|||||||
skills.h
|
skills.h
|
||||||
spdat.h
|
spdat.h
|
||||||
stacktrace/backward.hpp
|
stacktrace/backward.hpp
|
||||||
|
StackWalker/StackWalker.h
|
||||||
strings.h
|
strings.h
|
||||||
struct_strategy.h
|
struct_strategy.h
|
||||||
tasks.h
|
tasks.h
|
||||||
@ -729,25 +730,9 @@ set(common_headers
|
|||||||
zone_store.h
|
zone_store.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# Source Groups (Regex based for automatic subdirectory handling)
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Source Files" FILES ${common_sources})
|
||||||
source_group("CLI" REGULAR_EXPRESSION "^cli/")
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Header Files" FILES ${common_headers})
|
||||||
source_group("Content" REGULAR_EXPRESSION "^content/")
|
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/repositories" PREFIX "Repositories" FILES ${repositories})
|
||||||
source_group("Cron" REGULAR_EXPRESSION "^cron/")
|
|
||||||
source_group("Database" REGULAR_EXPRESSION "^database/")
|
|
||||||
source_group("Discord" REGULAR_EXPRESSION "^discord/")
|
|
||||||
source_group("Event" REGULAR_EXPRESSION "^event/")
|
|
||||||
source_group("Events" REGULAR_EXPRESSION "^events/")
|
|
||||||
source_group("Http" REGULAR_EXPRESSION "^http/")
|
|
||||||
source_group("Json" REGULAR_EXPRESSION "^json/")
|
|
||||||
source_group("Memory" REGULAR_EXPRESSION "^memory/")
|
|
||||||
source_group("Net" REGULAR_EXPRESSION "^net/")
|
|
||||||
source_group("Patches" REGULAR_EXPRESSION "^patches/")
|
|
||||||
source_group("Process" REGULAR_EXPRESSION "^process/")
|
|
||||||
source_group("Repositories" REGULAR_EXPRESSION "^repositories/")
|
|
||||||
source_group("StackWalker" REGULAR_EXPRESSION "^StackWalker/")
|
|
||||||
source_group("Stacktrace" REGULAR_EXPRESSION "^stacktrace/")
|
|
||||||
source_group("Termcolor" REGULAR_EXPRESSION "^termcolor/")
|
|
||||||
source_group("Util" REGULAR_EXPRESSION "^util/")
|
|
||||||
|
|
||||||
option(EQEMU_ADD_PROFILER "Link with Google perftools profiler" OFF)
|
option(EQEMU_ADD_PROFILER "Link with Google perftools profiler" OFF)
|
||||||
#PRNG options
|
#PRNG options
|
||||||
|
|||||||
@ -359,7 +359,7 @@ public:
|
|||||||
BOOL Publics; // contains public symbols
|
BOOL Publics; // contains public symbols
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
typedef struct IMAGEHLP_MODULE64_V2 {
|
struct IMAGEHLP_MODULE64_V2 {
|
||||||
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
|
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
|
||||||
DWORD64 BaseOfImage; // base load address of module
|
DWORD64 BaseOfImage; // base load address of module
|
||||||
DWORD ImageSize; // virtual size of the loaded module
|
DWORD ImageSize; // virtual size of the loaded module
|
||||||
|
|||||||
@ -134,7 +134,7 @@ protected:
|
|||||||
CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
|
CHAR loadedImageName[STACKWALK_MAX_NAMELEN];
|
||||||
} CallstackEntry;
|
} CallstackEntry;
|
||||||
|
|
||||||
typedef enum CallstackEntryType {firstEntry, nextEntry, lastEntry};
|
enum CallstackEntryType {firstEntry, nextEntry, lastEntry};
|
||||||
|
|
||||||
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
|
virtual void OnSymInit(LPCSTR szSearchPath, DWORD symOptions, LPCSTR szUserName);
|
||||||
virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion);
|
virtual void OnLoadModule(LPCSTR img, LPCSTR mod, DWORD64 baseAddr, DWORD size, DWORD result, LPCSTR symType, LPCSTR pdbName, ULONGLONG fileVersion);
|
||||||
|
|||||||
@ -19,44 +19,34 @@
|
|||||||
#include "common/misc.h"
|
#include "common/misc.h"
|
||||||
#include "common/packet_dump.h"
|
#include "common/packet_dump.h"
|
||||||
|
|
||||||
BasePacket::BasePacket(const unsigned char *buf, uint32 len)
|
BasePacket::BasePacket(const unsigned char* buf, size_t len)
|
||||||
{
|
{
|
||||||
pBuffer=nullptr;
|
if (len > 0) {
|
||||||
size=0;
|
size = static_cast<uint32>(len);
|
||||||
_wpos = 0;
|
pBuffer = new unsigned char[len];
|
||||||
_rpos = 0;
|
|
||||||
timestamp.tv_sec = 0;
|
|
||||||
if (len>0) {
|
|
||||||
size=len;
|
|
||||||
pBuffer= new unsigned char[len];
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
memcpy(pBuffer,buf,len);
|
memcpy(pBuffer, buf, len);
|
||||||
} else {
|
}
|
||||||
memset(pBuffer,0,len);
|
else {
|
||||||
|
memset(pBuffer, 0, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePacket::BasePacket(SerializeBuffer &buf)
|
BasePacket::BasePacket(SerializeBuffer&& buf)
|
||||||
|
: pBuffer(std::exchange(buf.m_buffer, nullptr))
|
||||||
{
|
{
|
||||||
pBuffer = buf.m_buffer;
|
// We are essentially taking ownership of this serialize buffer.
|
||||||
buf.m_buffer = nullptr;
|
size = static_cast<uint32>(std::exchange(buf.m_pos, 0));
|
||||||
size = buf.m_pos;
|
|
||||||
buf.m_pos = 0;
|
|
||||||
buf.m_capacity = 0;
|
buf.m_capacity = 0;
|
||||||
_wpos = 0;
|
|
||||||
_rpos = 0;
|
|
||||||
timestamp.tv_sec = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BasePacket::~BasePacket()
|
BasePacket::~BasePacket()
|
||||||
{
|
{
|
||||||
if (pBuffer)
|
delete[] pBuffer;
|
||||||
delete[] pBuffer;
|
pBuffer = nullptr;
|
||||||
pBuffer=nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BasePacket::build_raw_header_dump(char *buffer, uint16 seq) const
|
void BasePacket::build_raw_header_dump(char *buffer, uint16 seq) const
|
||||||
{
|
{
|
||||||
if (timestamp.tv_sec) {
|
if (timestamp.tv_sec) {
|
||||||
|
|||||||
@ -23,14 +23,26 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
class BasePacket {
|
class BasePacket
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
BasePacket() = default;
|
||||||
|
BasePacket(const unsigned char* buf, size_t len);
|
||||||
|
BasePacket(SerializeBuffer&& buf);
|
||||||
|
|
||||||
|
virtual ~BasePacket();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned char *pBuffer;
|
unsigned char* pBuffer = nullptr;
|
||||||
uint32 size, _wpos, _rpos;
|
uint32 size = 0;
|
||||||
uint32 src_ip,dst_ip;
|
uint32 _wpos = 0;
|
||||||
uint16 src_port,dst_port;
|
uint32 _rpos = 0;
|
||||||
uint32 priority;
|
uint32 src_ip = 0;
|
||||||
timeval timestamp;
|
uint32 dst_ip = 0;
|
||||||
|
uint16 src_port = 0;
|
||||||
|
uint16 dst_port = 0;
|
||||||
|
uint32 priority = 0;
|
||||||
|
timeval timestamp{};
|
||||||
|
|
||||||
virtual void build_raw_header_dump(char *buffer, uint16 seq=0xffff) const;
|
virtual void build_raw_header_dump(char *buffer, uint16 seq=0xffff) const;
|
||||||
virtual void build_header_dump(char *buffer) const;
|
virtual void build_header_dump(char *buffer) const;
|
||||||
@ -40,11 +52,11 @@ public:
|
|||||||
|
|
||||||
void setSrcInfo(uint32 sip, uint16 sport) { src_ip=sip; src_port=sport; }
|
void setSrcInfo(uint32 sip, uint16 sport) { src_ip=sip; src_port=sport; }
|
||||||
void setDstInfo(uint32 dip, uint16 dport) { dst_ip=dip; dst_port=dport; }
|
void setDstInfo(uint32 dip, uint16 dport) { dst_ip=dip; dst_port=dport; }
|
||||||
void setTimeInfo(uint32 ts_sec, uint32 ts_usec) { timestamp.tv_sec=ts_sec; timestamp.tv_usec=ts_usec; }
|
void setTimeInfo(uint32 ts_sec, uint32 ts_usec) { timestamp.tv_sec = ts_sec; timestamp.tv_usec = ts_usec; }
|
||||||
void copyInfo(const BasePacket *p) { src_ip=p->src_ip; src_port=p->src_port; dst_ip=p->dst_ip; dst_port=p->dst_port; timestamp.tv_sec=p->timestamp.tv_sec; timestamp.tv_usec=p->timestamp.tv_usec; }
|
void copyInfo(const BasePacket *p) { src_ip=p->src_ip; src_port=p->src_port; dst_ip=p->dst_ip; dst_port=p->dst_port; timestamp.tv_sec=p->timestamp.tv_sec; timestamp.tv_usec=p->timestamp.tv_usec; }
|
||||||
|
|
||||||
inline bool operator<(const BasePacket &rhs) {
|
inline bool operator<(const BasePacket &rhs) {
|
||||||
return (timestamp.tv_sec < rhs.timestamp.tv_sec || (timestamp.tv_sec==rhs.timestamp.tv_sec && timestamp.tv_usec < rhs.timestamp.tv_usec));
|
return (timestamp.tv_sec < rhs.timestamp.tv_sec || (timestamp.tv_sec == rhs.timestamp.tv_sec && timestamp.tv_usec < rhs.timestamp.tv_usec));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteUInt8(uint8 value) { *(uint8 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint8); }
|
void WriteUInt8(uint8 value) { *(uint8 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint8); }
|
||||||
@ -73,12 +85,6 @@ public:
|
|||||||
uint32 GetReadPosition() { return _rpos; }
|
uint32 GetReadPosition() { return _rpos; }
|
||||||
void SetWritePosition(uint32 Newwpos) { _wpos = Newwpos; }
|
void SetWritePosition(uint32 Newwpos) { _wpos = Newwpos; }
|
||||||
void SetReadPosition(uint32 Newrpos) { _rpos = Newrpos; }
|
void SetReadPosition(uint32 Newrpos) { _rpos = Newrpos; }
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~BasePacket();
|
|
||||||
BasePacket() { pBuffer=nullptr; size=0; _wpos = 0; _rpos = 0; }
|
|
||||||
BasePacket(const unsigned char *buf, const uint32 len);
|
|
||||||
BasePacket(SerializeBuffer &buf);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void DumpPacketHex(const BasePacket* app);
|
extern void DumpPacketHex(const BasePacket* app);
|
||||||
|
|||||||
@ -23,12 +23,9 @@
|
|||||||
|
|
||||||
namespace EQEmuCommand {
|
namespace EQEmuCommand {
|
||||||
|
|
||||||
std::map<std::string, void (*)(
|
using CommandFunction = void(*)(int argc, char** argv, argh::parser& cmd, std::string& description);
|
||||||
int argc,
|
|
||||||
char **argv,
|
std::map<std::string, CommandFunction> function_map;
|
||||||
argh::parser &cmd,
|
|
||||||
std::string &description
|
|
||||||
)> function_map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cmd
|
* @param cmd
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#elif defined(TERMCOLOR_OS_WINDOWS)
|
#elif defined(TERMCOLOR_OS_WINDOWS)
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
# include <windows.h>
|
# include "common/platform/win/include_windows.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,146 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "condition.h"
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
|
|
||||||
Condition::Condition()
|
|
||||||
{
|
|
||||||
m_events[SignalEvent] = CreateEvent (nullptr, // security
|
|
||||||
FALSE, // is auto-reset event?
|
|
||||||
FALSE, // is signaled initially?
|
|
||||||
nullptr); // name
|
|
||||||
m_events[BroadcastEvent] = CreateEvent (nullptr, // security
|
|
||||||
TRUE, // is auto-reset event?
|
|
||||||
FALSE, // is signaled initially?
|
|
||||||
nullptr); // name
|
|
||||||
m_waiters = 0;
|
|
||||||
InitializeCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
Condition::~Condition()
|
|
||||||
{
|
|
||||||
DeleteCriticalSection(&CSMutex);
|
|
||||||
CloseHandle(m_events[SignalEvent]);
|
|
||||||
CloseHandle(m_events[BroadcastEvent]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Signal()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
if(m_waiters > 0)
|
|
||||||
SetEvent(m_events[SignalEvent]);
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::SignalAll()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
if(m_waiters > 0)
|
|
||||||
SetEvent(m_events[BroadcastEvent]);
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Wait()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
|
|
||||||
m_waiters++;
|
|
||||||
|
|
||||||
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
int result = WaitForMultipleObjects (_eventCount, m_events, FALSE, INFINITE);
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
|
|
||||||
m_waiters--;
|
|
||||||
|
|
||||||
//see if we are the last person waiting on the condition, and there was a broadcast
|
|
||||||
//if so, we need to reset the broadcast event.
|
|
||||||
if(m_waiters == 0 && result == (WAIT_OBJECT_0+BroadcastEvent))
|
|
||||||
ResetEvent(m_events[BroadcastEvent]);
|
|
||||||
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
Condition::Condition()
|
|
||||||
{
|
|
||||||
pthread_cond_init(&cond,nullptr);
|
|
||||||
pthread_mutex_init(&mutex,nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Signal()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_signal(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::SignalAll()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_broadcast(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Condition::Wait()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_wait(&cond,&mutex);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
I commented this specifically because I think it might be very
|
|
||||||
difficult to write a windows counterpart to it, so I would like
|
|
||||||
to discourage its use until we can confirm that it can be reasonably
|
|
||||||
implemented on windows.
|
|
||||||
|
|
||||||
bool Condition::TimedWait(unsigned long usec)
|
|
||||||
{
|
|
||||||
struct timeval now;
|
|
||||||
struct timespec timeout;
|
|
||||||
int retcode=0;
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
gettimeofday(&now,nullptr);
|
|
||||||
now.tv_usec+=usec;
|
|
||||||
timeout.tv_sec = now.tv_sec + (now.tv_usec/1000000);
|
|
||||||
timeout.tv_nsec = (now.tv_usec%1000000) *1000;
|
|
||||||
//cout << "now=" << now.tv_sec << "."<<now.tv_usec << endl;
|
|
||||||
//cout << "timeout=" << timeout.tv_sec << "."<<timeout.tv_nsec << endl;
|
|
||||||
retcode=pthread_cond_timedwait(&cond,&mutex,&timeout);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
|
|
||||||
return retcode!=ETIMEDOUT;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Condition::~Condition()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
pthread_cond_destroy(&cond);
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
pthread_mutex_destroy(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/platform/posix/include_pthreads.h"
|
|
||||||
#include "common/platform/win/include_windows.h"
|
|
||||||
|
|
||||||
//Sombody, someday needs to figure out how to implement a condition
|
|
||||||
//system on windows...
|
|
||||||
|
|
||||||
|
|
||||||
class Condition {
|
|
||||||
private:
|
|
||||||
#ifdef WIN32
|
|
||||||
enum {
|
|
||||||
SignalEvent = 0,
|
|
||||||
BroadcastEvent,
|
|
||||||
_eventCount
|
|
||||||
};
|
|
||||||
|
|
||||||
HANDLE m_events[_eventCount];
|
|
||||||
uint32 m_waiters;
|
|
||||||
CRITICAL_SECTION CSMutex;
|
|
||||||
#else
|
|
||||||
pthread_cond_t cond;
|
|
||||||
pthread_mutex_t mutex;
|
|
||||||
#endif
|
|
||||||
public:
|
|
||||||
Condition();
|
|
||||||
void Signal();
|
|
||||||
void SignalAll();
|
|
||||||
void Wait();
|
|
||||||
// bool TimedWait(unsigned long usec);
|
|
||||||
~Condition();
|
|
||||||
};
|
|
||||||
@ -132,7 +132,7 @@ void WorldContentService::SetContentFlags(const std::vector<ContentFlagsReposito
|
|||||||
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
||||||
{
|
{
|
||||||
for (auto &f: GetContentFlags()) {
|
for (auto &f: GetContentFlags()) {
|
||||||
if (f.flag_name == content_flag && f.enabled == true) {
|
if (f.flag_name == content_flag && f.enabled == 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
|
|||||||
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
|
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
|
||||||
{
|
{
|
||||||
for (auto &f: GetContentFlags()) {
|
for (auto &f: GetContentFlags()) {
|
||||||
if (f.flag_name == content_flag && f.enabled == false) {
|
if (f.flag_name == content_flag && f.enabled == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,6 +125,6 @@ uint32 CRC32::Update(const uint8* buf, uint32 bufsize, uint32 crc32var) {
|
|||||||
return crc32var;
|
return crc32var;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CRC32::Calc(const uint8 byte, uint32& crc32var) {
|
void CRC32::Calc(const uint8 byte, uint32& crc32var) {
|
||||||
crc32var = ((crc32var) >> 8) ^ CRC32Table[(byte) ^ ((crc32var) & 0x000000FF)];
|
crc32var = ((crc32var) >> 8) ^ CRC32Table[(byte) ^ ((crc32var) & 0x000000FF)];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -728,7 +728,7 @@ bool Database::LoadVariables()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockMutex lock(&Mvarcache);
|
std::scoped_lock lock(Mvarcache);
|
||||||
|
|
||||||
for (const auto& e : l) {
|
for (const auto& e : l) {
|
||||||
varcache.last_update = std::time(nullptr);
|
varcache.last_update = std::time(nullptr);
|
||||||
@ -747,7 +747,7 @@ bool Database::LoadVariables()
|
|||||||
|
|
||||||
bool Database::GetVariable(const std::string& name, std::string& value)
|
bool Database::GetVariable(const std::string& name, std::string& value)
|
||||||
{
|
{
|
||||||
LockMutex lock(&Mvarcache);
|
std::scoped_lock lock(Mvarcache);
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -20,13 +20,12 @@
|
|||||||
#include "common/dbcore.h"
|
#include "common/dbcore.h"
|
||||||
#include "common/eq_packet_structs.h"
|
#include "common/eq_packet_structs.h"
|
||||||
#include "common/eqemu_logsys.h"
|
#include "common/eqemu_logsys.h"
|
||||||
#include "common/linked_list.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#define AUTHENTICATION_TIMEOUT 60
|
#define AUTHENTICATION_TIMEOUT 60
|
||||||
#define INVALID_ID 0xFFFFFFFF
|
#define INVALID_ID 0xFFFFFFFF
|
||||||
@ -265,7 +264,7 @@ public:
|
|||||||
uint64_t GetNextTableId(const std::string& table_name);
|
uint64_t GetNextTableId(const std::string& table_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex Mvarcache;
|
std::mutex Mvarcache;
|
||||||
VarCache_Struct varcache;
|
VarCache_Struct varcache;
|
||||||
|
|
||||||
/* Groups, utility methods. */
|
/* Groups, utility methods. */
|
||||||
|
|||||||
@ -33,17 +33,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBcore::DBcore()
|
DBcore::DBcore()
|
||||||
|
: mysql(mysql_init(nullptr))
|
||||||
|
, m_mutex(std::make_shared<Mutex>())
|
||||||
{
|
{
|
||||||
mysql = mysql_init(nullptr);
|
|
||||||
mysqlOwner = true;
|
|
||||||
pHost = nullptr;
|
|
||||||
pUser = nullptr;
|
|
||||||
pPassword = nullptr;
|
|
||||||
pDatabase = nullptr;
|
|
||||||
pCompress = false;
|
|
||||||
pSSL = false;
|
|
||||||
pStatus = Closed;
|
|
||||||
m_mutex = new Mutex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBcore::~DBcore()
|
DBcore::~DBcore()
|
||||||
@ -56,20 +48,17 @@ DBcore::~DBcore()
|
|||||||
if (mysqlOwner) {
|
if (mysqlOwner) {
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(pHost);
|
|
||||||
safe_delete_array(pUser);
|
|
||||||
safe_delete_array(pPassword);
|
|
||||||
safe_delete_array(pDatabase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends the MySQL server a keepalive
|
// Sends the MySQL server a keepalive
|
||||||
void DBcore::ping()
|
void DBcore::ping()
|
||||||
{
|
{
|
||||||
if (!m_mutex->trylock()) {
|
if (!m_mutex->try_lock())
|
||||||
|
{
|
||||||
// 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();
|
m_mutex->unlock();
|
||||||
}
|
}
|
||||||
@ -92,7 +81,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(*m_mutex);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
@ -217,15 +206,12 @@ bool DBcore::Open(
|
|||||||
bool iSSL
|
bool iSSL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(*m_mutex);
|
||||||
safe_delete_array(pHost);
|
|
||||||
safe_delete_array(pUser);
|
m_host = iHost;
|
||||||
safe_delete_array(pPassword);
|
m_user = iUser;
|
||||||
safe_delete_array(pDatabase);
|
m_password = iPassword;
|
||||||
pHost = strcpy(new char[strlen(iHost) + 1], iHost);
|
m_database = iDatabase;
|
||||||
pUser = strcpy(new char[strlen(iUser) + 1], iUser);
|
|
||||||
pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword);
|
|
||||||
pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase);
|
|
||||||
pCompress = iCompress;
|
pCompress = iCompress;
|
||||||
pPort = iPort;
|
pPort = iPort;
|
||||||
pSSL = iSSL;
|
pSSL = iSSL;
|
||||||
@ -234,10 +220,12 @@ bool DBcore::Open(
|
|||||||
|
|
||||||
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
bool DBcore::Open(uint32 *errnum, char *errbuf)
|
||||||
{
|
{
|
||||||
|
// Expects m_mutex to already be locked.
|
||||||
|
|
||||||
if (errbuf) {
|
if (errbuf) {
|
||||||
errbuf[0] = 0;
|
errbuf[0] = 0;
|
||||||
}
|
}
|
||||||
LockMutex lock(m_mutex);
|
|
||||||
if (GetStatus() == Connected) {
|
if (GetStatus() == Connected) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -245,7 +233,7 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
mysql_init(mysql); // Initialize structure again
|
mysql_init(mysql); // Initialize structure again
|
||||||
}
|
}
|
||||||
if (!pHost) {
|
if (m_host.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -268,11 +256,10 @@ bool DBcore::Open(uint32 *errnum, char *errbuf)
|
|||||||
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &off);
|
mysql_options(mysql, MYSQL_OPT_SSL_ENFORCE, &off);
|
||||||
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &off);
|
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &off);
|
||||||
}
|
}
|
||||||
if (mysql_real_connect(mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) {
|
if (mysql_real_connect(mysql, m_host.c_str(), m_user.c_str(), m_password.c_str(), m_database.c_str(), pPort, nullptr, flags)) {
|
||||||
pStatus = Connected;
|
pStatus = Connected;
|
||||||
|
|
||||||
std::string connected_origin_host = pHost;
|
SetOriginHost(m_host);
|
||||||
SetOriginHost(connected_origin_host);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -293,9 +280,9 @@ const std::string &DBcore::GetOriginHost() const
|
|||||||
return origin_host;
|
return origin_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::SetOriginHost(const std::string &origin_host)
|
void DBcore::SetOriginHost(const std::string& originHost)
|
||||||
{
|
{
|
||||||
DBcore::origin_host = origin_host;
|
DBcore::origin_host = originHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DBcore::Escape(const std::string& s)
|
std::string DBcore::Escape(const std::string& s)
|
||||||
@ -307,12 +294,8 @@ std::string DBcore::Escape(const std::string& s)
|
|||||||
return temp.data();
|
return temp.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBcore::SetMutex(Mutex *mutex)
|
void DBcore::SetMutex(const std::shared_ptr<Mutex>& mutex)
|
||||||
{
|
{
|
||||||
if (m_mutex && m_mutex != mutex) {
|
|
||||||
safe_delete(m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBcore::m_mutex = mutex;
|
DBcore::m_mutex = mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +309,7 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
|||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
timer.reset();
|
timer.reset();
|
||||||
|
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(*m_mutex);
|
||||||
|
|
||||||
// Reconnect if we are not connected before hand.
|
// Reconnect if we are not connected before hand.
|
||||||
if (pStatus != Connected) {
|
if (pStatus != Connected) {
|
||||||
@ -449,5 +432,5 @@ MySQLRequestResult DBcore::QueryDatabaseMulti(const std::string &query)
|
|||||||
|
|
||||||
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
mysql::PreparedStmt DBcore::Prepare(std::string query)
|
||||||
{
|
{
|
||||||
return mysql::PreparedStmt(*mysql, std::move(query), m_mutex);
|
return mysql::PreparedStmt(*mysql, std::move(query), *m_mutex);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,11 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/mysql_request_result.h"
|
#include "common/mysql_request_result.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include "mysql.h"
|
#include "mysql.h"
|
||||||
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#define CR_SERVER_GONE_ERROR 2006
|
#define CR_SERVER_GONE_ERROR 2006
|
||||||
@ -29,12 +29,15 @@
|
|||||||
|
|
||||||
namespace mysql { class PreparedStmt; }
|
namespace mysql { class PreparedStmt; }
|
||||||
|
|
||||||
class DBcore {
|
class DBcore
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
enum eStatus {
|
enum eStatus {
|
||||||
Closed, Connected, Error
|
Closed, Connected, Error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Mutex = std::recursive_mutex;
|
||||||
|
|
||||||
DBcore();
|
DBcore();
|
||||||
~DBcore();
|
~DBcore();
|
||||||
eStatus GetStatus() { return pStatus; }
|
eStatus GetStatus() { return pStatus; }
|
||||||
@ -48,17 +51,17 @@ public:
|
|||||||
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
uint32 DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen);
|
||||||
void ping();
|
void ping();
|
||||||
|
|
||||||
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(const std::string& table_name);
|
||||||
|
|
||||||
void SetMySQL(const DBcore &o)
|
void SetMySQL(const DBcore& o)
|
||||||
{
|
{
|
||||||
mysql = o.mysql;
|
mysql = o.mysql;
|
||||||
mysqlOwner = false;
|
mysqlOwner = false;
|
||||||
}
|
}
|
||||||
void SetMutex(Mutex *mutex);
|
void SetMutex(const std::shared_ptr<Mutex>& mutex);
|
||||||
|
|
||||||
// only safe on connections shared with other threads if results buffered
|
// only safe on connections shared with other threads if results buffered
|
||||||
// unsafe to use off main thread due to internal server logging
|
// unsafe to use off main thread due to internal server logging
|
||||||
@ -81,22 +84,21 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
bool Open(uint32 *errnum = nullptr, char *errbuf = nullptr);
|
||||||
|
|
||||||
MYSQL* mysql;
|
MYSQL* mysql = nullptr;
|
||||||
bool mysqlOwner;
|
bool mysqlOwner = true;
|
||||||
Mutex *m_mutex;
|
eStatus pStatus = Closed;
|
||||||
eStatus pStatus;
|
|
||||||
|
|
||||||
std::mutex m_query_lock{};
|
std::shared_ptr<Mutex> m_mutex;
|
||||||
|
|
||||||
std::string origin_host;
|
std::string origin_host;
|
||||||
|
|
||||||
char *pHost;
|
std::string m_host;
|
||||||
char *pUser;
|
std::string m_user;
|
||||||
char *pPassword;
|
std::string m_password;
|
||||||
char *pDatabase;
|
std::string m_database;
|
||||||
bool pCompress;
|
bool pCompress = false;
|
||||||
uint32 pPort;
|
uint32 pPort = 0;
|
||||||
bool pSSL;
|
bool pSSL = false;
|
||||||
|
|
||||||
// allows multiple queries to be executed within the same query
|
// allows multiple queries to be executed within the same query
|
||||||
// do not use this under normal operation
|
// do not use this under normal operation
|
||||||
|
|||||||
@ -31,9 +31,19 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
EQPacket::EQPacket(EmuOpcode op, const unsigned char *buf, uint32 len)
|
EQPacket::EQPacket()
|
||||||
: BasePacket(buf, len),
|
{
|
||||||
emu_opcode(op)
|
}
|
||||||
|
|
||||||
|
EQPacket::EQPacket(EmuOpcode op, const unsigned char *buf, size_t len)
|
||||||
|
: BasePacket(buf, len)
|
||||||
|
, emu_opcode(op)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EQPacket::EQPacket(EmuOpcode opcode, SerializeBuffer&& buf)
|
||||||
|
: BasePacket(std::move(buf))
|
||||||
|
, emu_opcode(opcode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,17 +370,16 @@ EQRawApplicationPacket::EQRawApplicationPacket(const unsigned char *buf, const u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpPacket(const EQApplicationPacket* app, bool iShowInfo) {
|
void DumpPacket(const EQApplicationPacket* app, bool iShowInfo)
|
||||||
|
{
|
||||||
if (iShowInfo) {
|
if (iShowInfo) {
|
||||||
std::cout << "Dumping Applayer: 0x" << std::hex << std::setfill('0') << std::setw(4) << app->GetOpcode() << std::dec;
|
printf("Dumping Applayer: 0x%04x size: %u", app->GetOpcode(), app->size);
|
||||||
std::cout << " size:" << app->size << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DumpPacketHex(app->pBuffer, app->size);
|
DumpPacketHex(app->pBuffer, app->size);
|
||||||
// DumpPacketAscii(app->pBuffer, app->size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DumpPacketToString(const EQApplicationPacket* app){
|
std::string DumpPacketToString(const EQApplicationPacket* app)
|
||||||
std::ostringstream out;
|
{
|
||||||
out << DumpPacketHexToString(app->pBuffer, app->size);
|
return DumpPacketHexToString(app->pBuffer, app->size);
|
||||||
return out.str();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,15 @@
|
|||||||
#include "common/emu_opcodes.h"
|
#include "common/emu_opcodes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class EQPacket : public BasePacket {
|
class EQPacket : public BasePacket
|
||||||
|
{
|
||||||
friend class EQStream;
|
friend class EQStream;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EQPacket();
|
||||||
|
EQPacket(EmuOpcode opcode, const unsigned char* buf, size_t len);
|
||||||
|
EQPacket(EmuOpcode opcode, SerializeBuffer&& buf);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~EQPacket() {}
|
virtual ~EQPacket() {}
|
||||||
|
|
||||||
@ -41,19 +48,12 @@ public:
|
|||||||
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
|
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
|
||||||
|
|
||||||
void SetOpcode(EmuOpcode op) { emu_opcode = op; }
|
void SetOpcode(EmuOpcode op) { emu_opcode = op; }
|
||||||
const EmuOpcode GetOpcode() const { return(emu_opcode); }
|
EmuOpcode GetOpcode() const { return(emu_opcode); }
|
||||||
// const char *GetOpcodeName() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//this is just a cache so we dont look it up several times on Get()
|
//this is just a cache so we dont look it up several times on Get()
|
||||||
//and it is mutable so we can store the cached copy even on a const object
|
//and it is mutable so we can store the cached copy even on a const object
|
||||||
EmuOpcode emu_opcode;
|
EmuOpcode emu_opcode = OP_Unknown;
|
||||||
|
|
||||||
EQPacket(EmuOpcode opcode, const unsigned char *buf, const uint32 len);
|
|
||||||
EQPacket(EmuOpcode opcode, SerializeBuffer &buf) : BasePacket(buf), emu_opcode(opcode) { };
|
|
||||||
// EQPacket(const EQPacket &p) { }
|
|
||||||
EQPacket() { emu_opcode=OP_Unknown; pBuffer=nullptr; size=0; }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EQRawApplicationPacket;
|
class EQRawApplicationPacket;
|
||||||
@ -90,19 +90,43 @@ protected:
|
|||||||
uint16 opcode;
|
uint16 opcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EQApplicationPacket : public EQPacket {
|
class EQApplicationPacket : public EQPacket
|
||||||
|
{
|
||||||
friend class EQStream;
|
friend class EQStream;
|
||||||
|
|
||||||
|
public:
|
||||||
|
EQApplicationPacket()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EQApplicationPacket(EmuOpcode op)
|
||||||
|
: EQPacket(op, nullptr, 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EQApplicationPacket(EmuOpcode op, size_t len)
|
||||||
|
: EQPacket(op, nullptr, len)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
EQApplicationPacket(EmuOpcode op, const unsigned char* buf, size_t len)
|
||||||
|
: EQPacket(op, buf, len)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EQApplicationPacket(EmuOpcode op, SerializeBuffer&& buf)
|
||||||
|
: EQPacket(op, std::move(buf))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
EQApplicationPacket(const EQApplicationPacket& p)
|
||||||
|
: EQPacket(p.emu_opcode, p.pBuffer, p.size)
|
||||||
|
, app_opcode_size(p.app_opcode_size)
|
||||||
|
, opcode_bypass(p.opcode_bypass)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EQApplicationPacket() : EQPacket(OP_Unknown, nullptr, 0), opcode_bypass(0)
|
|
||||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
|
||||||
EQApplicationPacket(const EmuOpcode op) : EQPacket(op, nullptr, 0), opcode_bypass(0)
|
|
||||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
|
||||||
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op, nullptr, len), opcode_bypass(0)
|
|
||||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
|
||||||
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
|
|
||||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
|
||||||
EQApplicationPacket(const EmuOpcode op, SerializeBuffer &buf) : EQPacket(op, buf), opcode_bypass(0)
|
|
||||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
|
||||||
bool combine(const EQApplicationPacket *rhs);
|
bool combine(const EQApplicationPacket *rhs);
|
||||||
uint32 serialize (uint16 opcode, unsigned char *dest) const;
|
uint32 serialize (uint16 opcode, unsigned char *dest) const;
|
||||||
uint32 Size() const { return size+app_opcode_size; }
|
uint32 Size() const { return size+app_opcode_size; }
|
||||||
@ -119,15 +143,11 @@ public:
|
|||||||
|
|
||||||
uint16 GetProtocolOpcode() const { return protocol_opcode; }
|
uint16 GetProtocolOpcode() const { return protocol_opcode; }
|
||||||
void SetProtocolOpcode(uint16 v) { protocol_opcode = v; }
|
void SetProtocolOpcode(uint16 v) { protocol_opcode = v; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
uint16 protocol_opcode = 0;
|
||||||
uint16 protocol_opcode;
|
uint8 app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2;
|
||||||
uint8 app_opcode_size;
|
uint16 opcode_bypass = 0;
|
||||||
uint16 opcode_bypass;
|
|
||||||
private:
|
|
||||||
|
|
||||||
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size), opcode_bypass(p.opcode_bypass) { app_opcode_size = p.app_opcode_size; }
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EQRawApplicationPacket : public EQApplicationPacket {
|
class EQRawApplicationPacket : public EQApplicationPacket {
|
||||||
|
|||||||
@ -26,13 +26,13 @@
|
|||||||
//this is the only part of an EQStream that is seen by the application.
|
//this is the only part of an EQStream that is seen by the application.
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
enum EQStreamState {
|
||||||
ESTABLISHED,
|
ESTABLISHED,
|
||||||
CLOSING, //waiting for pending data to flush.
|
CLOSING, //waiting for pending data to flush.
|
||||||
DISCONNECTING, //have sent disconnect, waiting for their disconnect reply.
|
DISCONNECTING, //have sent disconnect, waiting for their disconnect reply.
|
||||||
CLOSED, //received a disconnect from remote side.
|
CLOSED, //received a disconnect from remote side.
|
||||||
UNESTABLISHED
|
UNESTABLISHED
|
||||||
} EQStreamState;
|
};
|
||||||
|
|
||||||
class EQApplicationPacket;
|
class EQApplicationPacket;
|
||||||
class OpcodeManager;
|
class OpcodeManager;
|
||||||
|
|||||||
@ -33,10 +33,8 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include <conio.h>
|
#include "common/platform/platform.h"
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <process.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
#else
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|||||||
@ -15,36 +15,43 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/event/event_loop.h"
|
||||||
#include "common/platform/posix/include_pthreads.h"
|
#include "uv.h"
|
||||||
#include "common/platform/win/include_windows.h"
|
|
||||||
|
|
||||||
class Mutex {
|
namespace EQ {
|
||||||
public:
|
|
||||||
Mutex();
|
|
||||||
~Mutex();
|
|
||||||
|
|
||||||
void lock();
|
EventLoop& EventLoop::Get()
|
||||||
void unlock();
|
{
|
||||||
bool trylock();
|
thread_local EventLoop inst;
|
||||||
protected:
|
return inst;
|
||||||
private:
|
}
|
||||||
#if defined _WINDOWS
|
|
||||||
CRITICAL_SECTION CSMutex;
|
|
||||||
#else
|
|
||||||
pthread_mutex_t CSMutex;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class LockMutex {
|
EventLoop::EventLoop()
|
||||||
public:
|
: m_loop(std::make_unique<uv_loop_t>())
|
||||||
LockMutex(Mutex* in_mut, bool iLock = true);
|
{
|
||||||
~LockMutex();
|
memset(m_loop.get(), 0, sizeof(uv_loop_t));
|
||||||
void unlock();
|
uv_loop_init(m_loop.get());
|
||||||
void lock();
|
}
|
||||||
private:
|
|
||||||
bool locked;
|
EventLoop::~EventLoop()
|
||||||
Mutex* mut;
|
{
|
||||||
};
|
uv_loop_close(m_loop.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLoop::Process()
|
||||||
|
{
|
||||||
|
uv_run(m_loop.get(), UV_RUN_NOWAIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLoop::Run()
|
||||||
|
{
|
||||||
|
uv_run(m_loop.get(), UV_RUN_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventLoop::Shutdown()
|
||||||
|
{
|
||||||
|
uv_stop(m_loop.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace EQ
|
||||||
@ -17,48 +17,31 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/platform/win/include_windows.h" // uv.h is going to include it so let's do it first.
|
#include <memory>
|
||||||
#include "uv.h" // FIXME: hide this
|
|
||||||
|
|
||||||
#include <cstring>
|
typedef struct uv_loop_s uv_loop_t;
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ {
|
||||||
|
|
||||||
|
class EventLoop
|
||||||
{
|
{
|
||||||
class EventLoop
|
public:
|
||||||
{
|
static EventLoop& Get();
|
||||||
public:
|
|
||||||
static EventLoop &Get() {
|
|
||||||
static thread_local EventLoop inst;
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
~EventLoop() {
|
~EventLoop();
|
||||||
uv_loop_close(&m_loop);
|
EventLoop(const EventLoop&) = delete;
|
||||||
}
|
EventLoop& operator=(const EventLoop&) = delete;
|
||||||
|
|
||||||
void Process() {
|
void Process();
|
||||||
uv_run(&m_loop, UV_RUN_NOWAIT);
|
void Run();
|
||||||
}
|
void Shutdown();
|
||||||
|
|
||||||
void Run() {
|
uv_loop_t* Handle() { return m_loop.get(); }
|
||||||
uv_run(&m_loop, UV_RUN_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shutdown() {
|
private:
|
||||||
uv_stop(&m_loop);
|
EventLoop();
|
||||||
}
|
|
||||||
|
|
||||||
uv_loop_t* Handle() { return &m_loop; }
|
std::unique_ptr<uv_loop_t> m_loop;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace EQ
|
||||||
EventLoop() {
|
|
||||||
memset(&m_loop, 0, sizeof(uv_loop_t));
|
|
||||||
uv_loop_init(&m_loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventLoop(const EventLoop&);
|
|
||||||
EventLoop& operator=(const EventLoop&);
|
|
||||||
|
|
||||||
uv_loop_t m_loop;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
128
common/event/task_scheduler.cpp
Normal file
128
common/event/task_scheduler.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/* EQEmu: EQEmulator
|
||||||
|
|
||||||
|
Copyright (C) 2001-2026 EQEmu Development Team
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "task_scheduler.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace EQ::Event {
|
||||||
|
|
||||||
|
static constexpr int DefaultThreadCount = 4;
|
||||||
|
|
||||||
|
struct TaskScheduler::SchedulerData
|
||||||
|
{
|
||||||
|
std::atomic_bool running{ false };
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
std::mutex lock;
|
||||||
|
std::condition_variable cv;
|
||||||
|
std::queue<std::function<void()>> tasks;
|
||||||
|
};
|
||||||
|
|
||||||
|
TaskScheduler::TaskScheduler()
|
||||||
|
: m_data(std::make_unique<SchedulerData>())
|
||||||
|
{
|
||||||
|
Start(DefaultThreadCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskScheduler::TaskScheduler(size_t threads)
|
||||||
|
{
|
||||||
|
Start(threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskScheduler::~TaskScheduler()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::Start(size_t threads)
|
||||||
|
{
|
||||||
|
if (m_data->running.exchange(true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data->threads.reserve(threads);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < threads; ++i)
|
||||||
|
{
|
||||||
|
m_data->threads.emplace_back(
|
||||||
|
[this]{ ProcessWork(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::Stop()
|
||||||
|
{
|
||||||
|
if (!m_data->running.exchange(false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data->cv.notify_all();
|
||||||
|
|
||||||
|
for (auto& t : m_data->threads)
|
||||||
|
{
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data->threads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::ProcessWork()
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
std::function<void()> work;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock lock(m_data->lock);
|
||||||
|
|
||||||
|
m_data->cv.wait(lock,
|
||||||
|
[this]
|
||||||
|
{
|
||||||
|
return !m_data->running || !m_data->tasks.empty();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!m_data->running)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = std::move(m_data->tasks.front());
|
||||||
|
m_data->tasks.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
work();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::AddTask(std::function<void()>&& task)
|
||||||
|
{
|
||||||
|
if (!m_data->running)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Enqueue on stopped scheduler.");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(m_data->lock);
|
||||||
|
m_data->tasks.push(std::move(task));
|
||||||
|
}
|
||||||
|
m_data->cv.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace EQ::Event
|
||||||
@ -17,116 +17,45 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <mutex>
|
#include <memory>
|
||||||
#include <queue>
|
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ::Event {
|
||||||
|
|
||||||
|
class TaskScheduler
|
||||||
{
|
{
|
||||||
namespace Event
|
public:
|
||||||
|
TaskScheduler();
|
||||||
|
TaskScheduler(size_t threads);
|
||||||
|
|
||||||
|
~TaskScheduler();
|
||||||
|
|
||||||
|
void Start(size_t threads);
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
template <typename Fn, typename... Args>
|
||||||
|
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::invoke_result<Fn, Args...>::type>
|
||||||
{
|
{
|
||||||
class TaskScheduler
|
using return_type = typename std::invoke_result<Fn, Args...>::type;
|
||||||
{
|
|
||||||
public:
|
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
||||||
static const int DefaultThreadCount = 4;
|
[fn = std::forward<Fn>(fn), ...args = std::forward<Args>(args)]() mutable
|
||||||
|
|
||||||
TaskScheduler() : _running(false)
|
|
||||||
{
|
{
|
||||||
Start(DefaultThreadCount);
|
return fn(std::forward<Args>(args)...);
|
||||||
}
|
|
||||||
|
|
||||||
TaskScheduler(size_t threads) : _running(false)
|
|
||||||
{
|
|
||||||
Start(threads);
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
~TaskScheduler() {
|
AddTask([task] { (*task)(); });
|
||||||
Stop();
|
return task->get_future();
|
||||||
}
|
|
||||||
|
|
||||||
void Start(size_t threads) {
|
|
||||||
if (true == _running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_running = true;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < threads; ++i) {
|
|
||||||
_threads.emplace_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop() {
|
|
||||||
if (false == _running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_lock);
|
|
||||||
_running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cv.notify_all();
|
|
||||||
|
|
||||||
for (auto &t : _threads) {
|
|
||||||
t.join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Fn, typename... Args>
|
|
||||||
auto Enqueue(Fn&& fn, Args&&... args) -> std::future<typename std::invoke_result<Fn, Args...>::type> {
|
|
||||||
using return_type = typename std::invoke_result<Fn, Args...>::type;
|
|
||||||
|
|
||||||
auto task = std::make_shared<std::packaged_task<return_type()>>(
|
|
||||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::future<return_type> res = task->get_future();
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_lock);
|
|
||||||
|
|
||||||
if (false == _running) {
|
|
||||||
throw std::runtime_error("Enqueue on stopped scheduler.");
|
|
||||||
}
|
|
||||||
|
|
||||||
_tasks.emplace([task]() { (*task)(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
_cv.notify_one();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ProcessWork() {
|
|
||||||
for (;;) {
|
|
||||||
std::function<void()> work;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(_lock);
|
|
||||||
_cv.wait(lock, [this] { return !_running || !_tasks.empty(); });
|
|
||||||
|
|
||||||
if (false == _running) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
work = std::move(_tasks.front());
|
|
||||||
_tasks.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
work();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _running = true;
|
|
||||||
std::vector<std::thread> _threads;
|
|
||||||
std::mutex _lock;
|
|
||||||
std::condition_variable _cv;
|
|
||||||
std::queue<std::function<void()>> _tasks;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private:
|
||||||
|
void AddTask(std::function<void()>&& task);
|
||||||
|
void ProcessWork();
|
||||||
|
|
||||||
|
struct SchedulerData;
|
||||||
|
std::unique_ptr<SchedulerData> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace EQ::Event
|
||||||
|
|||||||
90
common/event/timer.cpp
Normal file
90
common/event/timer.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* EQEmu: EQEmulator
|
||||||
|
|
||||||
|
Copyright (C) 2001-2026 EQEmu Development Team
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/event/timer.h"
|
||||||
|
#include "uv.h"
|
||||||
|
|
||||||
|
namespace EQ {
|
||||||
|
|
||||||
|
Timer::Timer(callback_t cb)
|
||||||
|
: m_cb(std::move(cb))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer::Timer(uint64_t duration_ms, bool repeats, callback_t cb)
|
||||||
|
: m_cb(std::move(cb))
|
||||||
|
{
|
||||||
|
Start(duration_ms, repeats);
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer::~Timer()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::Start(uint64_t duration_ms, bool repeats)
|
||||||
|
{
|
||||||
|
if (!m_timer)
|
||||||
|
{
|
||||||
|
uv_loop_t* loop = EventLoop::Get().Handle();
|
||||||
|
|
||||||
|
m_timer = std::make_unique<uv_timer_t>();
|
||||||
|
memset(m_timer.get(), 0, sizeof(uv_timer_t));
|
||||||
|
|
||||||
|
uv_timer_init(loop, m_timer.get());
|
||||||
|
m_timer->data = this;
|
||||||
|
|
||||||
|
if (repeats)
|
||||||
|
{
|
||||||
|
uv_timer_start(m_timer.get(), [](uv_timer_t* handle)
|
||||||
|
{
|
||||||
|
Timer* t = static_cast<Timer*>(handle->data);
|
||||||
|
t->Execute();
|
||||||
|
}, duration_ms, duration_ms);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uv_timer_start(m_timer.get(),
|
||||||
|
[](uv_timer_t* handle)
|
||||||
|
{
|
||||||
|
Timer* t = static_cast<Timer*>(handle->data);
|
||||||
|
t->Stop();
|
||||||
|
t->Execute();
|
||||||
|
}, duration_ms, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::Stop()
|
||||||
|
{
|
||||||
|
if (m_timer)
|
||||||
|
{
|
||||||
|
uv_close(reinterpret_cast<uv_handle_t*>(m_timer.release()),
|
||||||
|
[](uv_handle_t* handle)
|
||||||
|
{
|
||||||
|
delete reinterpret_cast<uv_timer_t*>(handle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer::Execute()
|
||||||
|
{
|
||||||
|
m_cb(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace EQ
|
||||||
@ -19,69 +19,31 @@
|
|||||||
|
|
||||||
#include "event_loop.h"
|
#include "event_loop.h"
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
typedef struct uv_timer_s uv_timer_t;
|
||||||
|
|
||||||
namespace EQ {
|
namespace EQ {
|
||||||
class Timer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Timer(std::function<void(Timer *)> cb)
|
|
||||||
{
|
|
||||||
m_timer = nullptr;
|
|
||||||
m_cb = cb;
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer(uint64_t duration_ms, bool repeats, std::function<void(Timer *)> cb)
|
class Timer
|
||||||
{
|
{
|
||||||
m_timer = nullptr;
|
public:
|
||||||
m_cb = cb;
|
using callback_t = std::function<void(Timer*)>;
|
||||||
Start(duration_ms, repeats);
|
|
||||||
}
|
Timer(callback_t cb);
|
||||||
|
Timer(uint64_t duration_ms, bool repeats, callback_t cb);
|
||||||
|
|
||||||
~Timer()
|
~Timer();
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Start(uint64_t duration_ms, bool repeats) {
|
void Start(uint64_t duration_ms, bool repeats);
|
||||||
auto loop = EventLoop::Get().Handle();
|
void Stop();
|
||||||
if (!m_timer) {
|
|
||||||
m_timer = new uv_timer_t;
|
|
||||||
memset(m_timer, 0, sizeof(uv_timer_t));
|
|
||||||
uv_timer_init(loop, m_timer);
|
|
||||||
m_timer->data = this;
|
|
||||||
|
|
||||||
if (repeats) {
|
private:
|
||||||
uv_timer_start(m_timer, [](uv_timer_t *handle) {
|
void Execute();
|
||||||
Timer *t = (Timer*)handle->data;
|
|
||||||
t->Execute();
|
|
||||||
}, duration_ms, duration_ms);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uv_timer_start(m_timer, [](uv_timer_t *handle) {
|
|
||||||
Timer *t = (Timer*)handle->data;
|
|
||||||
t->Stop();
|
|
||||||
t->Execute();
|
|
||||||
}, duration_ms, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop() {
|
|
||||||
if (m_timer) {
|
|
||||||
uv_close((uv_handle_t*)m_timer, [](uv_handle_t* handle) {
|
|
||||||
delete (uv_timer_t *)handle;
|
|
||||||
});
|
|
||||||
m_timer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void Execute() {
|
|
||||||
m_cb(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_timer_t *m_timer;
|
std::unique_ptr<uv_timer_t> m_timer;
|
||||||
std::function<void(Timer*)> m_cb;
|
callback_t m_cb;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
} // namespace EQ
|
||||||
|
|||||||
@ -56,12 +56,12 @@ void PlayerEventLogs::Init()
|
|||||||
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
auto s = PlayerEventLogSettingsRepository::All(*m_database);
|
||||||
std::vector<int> db{};
|
std::vector<int> db{};
|
||||||
db.reserve(s.size());
|
db.reserve(s.size());
|
||||||
for (auto &e: s) {
|
for (auto& e: s) {
|
||||||
if (e.id >= PlayerEvent::MAX) {
|
if (e.id >= PlayerEvent::MAX) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m_settings[e.id] = e;
|
m_settings[e.id] = e;
|
||||||
db.emplace_back(e.id);
|
db.emplace_back(static_cast<int>(e.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
#define GUILD_INITIATE 7
|
#define GUILD_INITIATE 7
|
||||||
#define GUILD_RECRUIT 8
|
#define GUILD_RECRUIT 8
|
||||||
|
|
||||||
typedef enum {
|
enum GuildAction {
|
||||||
GUILD_ACTION_BANNER_CHANGE = 1,
|
GUILD_ACTION_BANNER_CHANGE = 1,
|
||||||
GUILD_ACTION_BANNER_PLANT = 2,
|
GUILD_ACTION_BANNER_PLANT = 2,
|
||||||
GUILD_ACTION_BANNER_REMOVE = 3,
|
GUILD_ACTION_BANNER_REMOVE = 3,
|
||||||
@ -77,6 +77,6 @@ typedef enum {
|
|||||||
GUILD_ACTION_REAL_ESTATE_GUILD_PLOT_SELL = 28,
|
GUILD_ACTION_REAL_ESTATE_GUILD_PLOT_SELL = 28,
|
||||||
GUILD_ACTION_REAL_ESTATE_MODIFY_TROPHIES = 29,
|
GUILD_ACTION_REAL_ESTATE_MODIFY_TROPHIES = 29,
|
||||||
GUILD_ACTION_MEMBERS_DEMOTE_SELF = 30,
|
GUILD_ACTION_MEMBERS_DEMOTE_SELF = 30,
|
||||||
} GuildAction;
|
};
|
||||||
|
|
||||||
constexpr int format_as(GuildAction action) { return static_cast<int>(action); }
|
constexpr int format_as(GuildAction action) { return static_cast<int>(action); }
|
||||||
|
|||||||
@ -349,7 +349,7 @@ bool EQ::InventoryProfile::SwapItem(
|
|||||||
fail_state = swapLevel;
|
fail_state = swapLevel;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (source_item_instance->IsEvolving() > 0) {
|
if (source_item_instance->IsEvolving()) {
|
||||||
source_item_instance->SetEvolveEquipped(true);
|
source_item_instance->SetEvolveEquipped(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,14 +25,24 @@
|
|||||||
#include "common/net/dns.h"
|
#include "common/net/dns.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include <cstring>
|
#include <iostream>
|
||||||
#include <csignal>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/**
|
#ifdef _WIN32
|
||||||
* @param ip
|
#include <winsock2.h>
|
||||||
* @return
|
#include <ws2tcpip.h>
|
||||||
*/
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint32_t IpUtil::IPToUInt(const std::string &ip)
|
uint32_t IpUtil::IPToUInt(const std::string &ip)
|
||||||
{
|
{
|
||||||
int a, b, c, d;
|
int a, b, c, d;
|
||||||
@ -49,12 +59,6 @@ uint32_t IpUtil::IPToUInt(const std::string &ip)
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* @param network
|
|
||||||
* @param mask
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool IpUtil::IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask)
|
bool IpUtil::IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask)
|
||||||
{
|
{
|
||||||
uint32_t ip_addr = IpUtil::IPToUInt(ip);
|
uint32_t ip_addr = IpUtil::IPToUInt(ip);
|
||||||
@ -67,10 +71,6 @@ bool IpUtil::IsIpInRange(const std::string &ip, const std::string &network, cons
|
|||||||
return ip_addr >= net_lower && ip_addr <= net_upper;
|
return ip_addr >= net_lower && ip_addr <= net_upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
@ -80,30 +80,13 @@ bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#pragma comment(lib, "Ws2_32.lib")
|
|
||||||
#else
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
std::string IpUtil::GetLocalIPAddress()
|
std::string IpUtil::GetLocalIPAddress()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char my_ip_address[INET_ADDRSTRLEN];
|
char my_ip_address[INET_ADDRSTRLEN];
|
||||||
@ -114,10 +97,10 @@ std::string IpUtil::GetLocalIPAddress()
|
|||||||
// Create a UDP socket
|
// Create a UDP socket
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sockfd == INVALID_SOCKET) {
|
if (sockfd == INVALID_SOCKET) {
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sockfd < 0) {
|
if (sockfd < 0) {
|
||||||
@ -200,98 +183,24 @@ std::string IpUtil::GetPublicIPAddress()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IpUtil::DNSLookupSync(const std::string &addr, int port)
|
|
||||||
{
|
|
||||||
auto task_runner = new EQ::Event::TaskScheduler();
|
|
||||||
auto res = task_runner->Enqueue(
|
|
||||||
[&]() -> std::string {
|
|
||||||
bool running = true;
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
EQ::Net::DNSLookup(
|
|
||||||
addr, port, false, [&](const std::string &addr) {
|
|
||||||
ret = addr;
|
|
||||||
if (addr.empty()) {
|
|
||||||
ret = "";
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
auto &loop = EQ::EventLoop::Get();
|
|
||||||
while (running) {
|
|
||||||
if (!ret.empty()) {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
|
||||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() > 1500) {
|
|
||||||
LogInfo(
|
|
||||||
"Deadline exceeded [{}]",
|
|
||||||
1500
|
|
||||||
);
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
loop.Process();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
std::string result = res.get();
|
|
||||||
safe_delete(task_runner);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IpUtil::IsIPAddress(const std::string &ip_address)
|
bool IpUtil::IsIPAddress(const std::string &ip_address)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sa{};
|
sockaddr_in sa{};
|
||||||
int result = inet_pton(AF_INET, ip_address.c_str(), &(sa.sin_addr));
|
int result = inet_pton(AF_INET, ip_address.c_str(), &(sa.sin_addr));
|
||||||
return result != 0;
|
return result != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
bool IpUtil::IsPortInUse(const std::string& ip, int port)
|
||||||
#ifdef _WIN32
|
{
|
||||||
#include <winsock2.h>
|
|
||||||
#pragma comment(lib, "ws2_32.lib") // Link against Winsock library
|
|
||||||
#else
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <ws2tcpip.h> // For inet_pton
|
|
||||||
#pragma comment(lib, "ws2_32.lib") // Link against Winsock library
|
|
||||||
#else
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <arpa/inet.h> // For inet_pton
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool IpUtil::IsPortInUse(const std::string& ip, int port) {
|
|
||||||
bool in_use = false;
|
bool in_use = false;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||||
std::cerr << "WSAStartup failed\n";
|
std::cerr << "WSAStartup failed\n";
|
||||||
return true; // Assume in use on failure
|
return true; // Assume in use on failure
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
@ -319,20 +228,20 @@ bool IpUtil::IsPortInUse(const std::string& ip, int port) {
|
|||||||
std::cerr << "Invalid IP address format: " << ip << std::endl;
|
std::cerr << "Invalid IP address format: " << ip << std::endl;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
return true; // Assume in use on failure
|
return true; // Assume in use on failure
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
if (bind(sock, (sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
in_use = true; // Bind failed, port is in use
|
in_use = true; // Bind failed, port is in use
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
closesocket(sock);
|
closesocket(sock);
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
#else
|
#else
|
||||||
close(sock);
|
close(sock);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -29,10 +29,7 @@ public:
|
|||||||
static bool IsIpInPrivateRfc1918(const std::string &ip);
|
static bool IsIpInPrivateRfc1918(const std::string &ip);
|
||||||
static std::string GetLocalIPAddress();
|
static std::string GetLocalIPAddress();
|
||||||
static std::string GetPublicIPAddress();
|
static std::string GetPublicIPAddress();
|
||||||
static std::string DNSLookupSync(
|
|
||||||
const std::string &addr,
|
|
||||||
int port
|
|
||||||
);
|
|
||||||
static bool IsIPAddress(const std::string &ip_address);
|
static bool IsIPAddress(const std::string &ip_address);
|
||||||
static bool IsPortInUse(const std::string& ip, int port);
|
static bool IsPortInUse(const std::string& ip, int port);
|
||||||
|
|
||||||
|
|||||||
@ -320,6 +320,7 @@ bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) co
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
slot < invaug::SOCKET_COUNT &&
|
||||||
(
|
(
|
||||||
augment_type == -1 ||
|
augment_type == -1 ||
|
||||||
(
|
(
|
||||||
|
|||||||
@ -45,5 +45,4 @@ struct LootItem {
|
|||||||
uint32 lootdrop_id; // required for zone state referencing
|
uint32 lootdrop_id; // required for zone state referencing
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<LootItem*> LootItems;
|
using LootItems = std::list<LootItem*>;
|
||||||
|
|
||||||
|
|||||||
192
common/memory/ksm.cpp
Normal file
192
common/memory/ksm.cpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/* EQEmu: EQEmulator
|
||||||
|
|
||||||
|
Copyright (C) 2001-2026 EQEmu Development Team
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "ksm.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h> // For madvise
|
||||||
|
#include <unistd.h> // For sysconf, sbrk
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Windows-specific functionality
|
||||||
|
|
||||||
|
void* PageAlignedAllocatorBase::allocateInternal(size_t size, size_t alignment)
|
||||||
|
{
|
||||||
|
void* ptr = malloc(size);
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t PageAlignedAllocatorBase::getPageSize() const
|
||||||
|
{
|
||||||
|
SYSTEM_INFO sysInfo;
|
||||||
|
GetSystemInfo(&sysInfo);
|
||||||
|
return sysInfo.dwPageSize; // Page size in bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace KSM {
|
||||||
|
|
||||||
|
// Windows-specific placeholder functions (no-op)
|
||||||
|
void CheckPageAlignment(void* ptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void* AllocatePageAligned(size_t size)
|
||||||
|
{
|
||||||
|
return memset(malloc(size), 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkMemoryForKSM(void* start, size_t size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlignHeapToPageBoundary()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void* MarkHeapStart()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MeasureHeapUsage(void* start)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace KSM
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Linux-specific functionality
|
||||||
|
|
||||||
|
void* PageAlignedAllocatorBase::allocateInternal(size_t size, size_t alignment)
|
||||||
|
{
|
||||||
|
void* ptr = nullptr;
|
||||||
|
|
||||||
|
if (posix_memalign(&ptr, alignment, size) != 0)
|
||||||
|
{
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t PageAlignedAllocatorBase::getPageSize() const
|
||||||
|
{
|
||||||
|
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace KSM {
|
||||||
|
|
||||||
|
void CheckPageAlignment(void* ptr)
|
||||||
|
{
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
|
if (reinterpret_cast<uintptr_t>(ptr) % page_size == 0)
|
||||||
|
{
|
||||||
|
LogKSMDetail("Memory is page-aligned [{}]", ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogKSMDetail("Memory is NOT page-aligned [{}]", ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* AllocatePageAligned(size_t size)
|
||||||
|
{
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
void* aligned_ptr = nullptr;
|
||||||
|
|
||||||
|
if (posix_memalign(&aligned_ptr, page_size, size) != 0)
|
||||||
|
{
|
||||||
|
LogKSM("Failed to allocate page-aligned memory on Linux. page_size [{}] size [{}] bytes", page_size, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::memset(aligned_ptr, 0, size);
|
||||||
|
return aligned_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkMemoryForKSM(void* start, size_t size)
|
||||||
|
{
|
||||||
|
if (madvise(start, size, MADV_MERGEABLE) == 0)
|
||||||
|
{
|
||||||
|
LogKSM("Marked memory for KSM | start [{}] size [{}] bytes", start, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
perror("madvise failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlignHeapToPageBoundary()
|
||||||
|
{
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
if (page_size == 0)
|
||||||
|
{
|
||||||
|
LogKSM("Failed to retrieve page size SC_PAGESIZE [{}]", page_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* current_break = sbrk(0);
|
||||||
|
if (current_break == (void*)-1)
|
||||||
|
{
|
||||||
|
LogKSM("Failed to retrieve the current program break");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t current_address = reinterpret_cast<uintptr_t>(current_break);
|
||||||
|
size_t misalignment = current_address % page_size;
|
||||||
|
|
||||||
|
if (misalignment != 0)
|
||||||
|
{
|
||||||
|
size_t adjustment = page_size - misalignment;
|
||||||
|
if (sbrk(adjustment) == (void*)-1)
|
||||||
|
{
|
||||||
|
LogKSM("Failed to align heap to page boundary. adjustment [{}] bytes", adjustment);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogKSMDetail("Heap aligned to next page boundary. Current break [{}]", sbrk(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void* MarkHeapStart()
|
||||||
|
{
|
||||||
|
void* current_pos = sbrk(0);
|
||||||
|
AlignHeapToPageBoundary();
|
||||||
|
return current_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MeasureHeapUsage(void* start)
|
||||||
|
{
|
||||||
|
void* current_break = sbrk(0);
|
||||||
|
return static_cast<char*>(current_break) - static_cast<char*>(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace KSM
|
||||||
|
|
||||||
|
#endif
|
||||||
74
common/memory/ksm.h
Normal file
74
common/memory/ksm.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/* EQEmu: EQEmulator
|
||||||
|
|
||||||
|
Copyright (C) 2001-2026 EQEmu Development Team
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/eqemu_logsys.h"
|
||||||
|
|
||||||
|
class PageAlignedAllocatorBase
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void* allocateInternal(size_t amount, size_t alignment);
|
||||||
|
size_t getPageSize() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Page-aligned allocator for std::vector
|
||||||
|
template <typename T>
|
||||||
|
class PageAlignedAllocator : public PageAlignedAllocatorBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
PageAlignedAllocator() noexcept = default;
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
PageAlignedAllocator(const PageAlignedAllocator<U>&) noexcept {}
|
||||||
|
|
||||||
|
T* allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
size_t size = n * sizeof(T);
|
||||||
|
|
||||||
|
return static_cast<T*>(allocateInternal(size, getPageSize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T* p, std::size_t) noexcept
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool operator==(const PageAlignedAllocator<T>&, const PageAlignedAllocator<U>&) noexcept {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool operator!=(const PageAlignedAllocator<T>&, const PageAlignedAllocator<U>&) noexcept {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kernel Samepage Merging (KSM) functionality
|
||||||
|
namespace KSM {
|
||||||
|
|
||||||
|
void CheckPageAlignment(void* ptr);
|
||||||
|
void* AllocatePageAligned(size_t size);
|
||||||
|
void MarkMemoryForKSM(void* start, size_t size);
|
||||||
|
void AlignHeapToPageBoundary();
|
||||||
|
void* MarkHeapStart();
|
||||||
|
size_t MeasureHeapUsage(void* start);
|
||||||
|
|
||||||
|
} // namespace KSM
|
||||||
@ -1,234 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/eqemu_logsys.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <cstring>
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <malloc.h> // For _aligned_malloc, _aligned_free
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <sys/mman.h> // For madvise
|
|
||||||
#include <unistd.h> // For sysconf, sbrk
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Page-aligned allocator for std::vector
|
|
||||||
template <typename T>
|
|
||||||
class PageAlignedAllocator {
|
|
||||||
public:
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
PageAlignedAllocator() noexcept = default;
|
|
||||||
template <typename U>
|
|
||||||
PageAlignedAllocator(const PageAlignedAllocator<U>&) noexcept {}
|
|
||||||
|
|
||||||
T* allocate(std::size_t n) {
|
|
||||||
void* ptr = nullptr;
|
|
||||||
size_t size = n * sizeof(T);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Simply allocate memory without alignment
|
|
||||||
ptr = malloc(size);
|
|
||||||
if (!ptr) throw std::bad_alloc();
|
|
||||||
#else
|
|
||||||
size_t alignment = getPageSize(); // Get the system's page size
|
|
||||||
if (posix_memalign(&ptr, alignment, size) != 0) {
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return static_cast<T*>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate(T* p, std::size_t) noexcept {
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t getPageSize() const
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEM_INFO sysInfo;
|
|
||||||
GetSystemInfo(&sysInfo);
|
|
||||||
return sysInfo.dwPageSize; // Page size in bytes
|
|
||||||
#else
|
|
||||||
return static_cast<size_t>(sysconf(_SC_PAGESIZE));
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
bool operator==(const PageAlignedAllocator<T>&, const PageAlignedAllocator<U>&) noexcept {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
bool operator!=(const PageAlignedAllocator<T>&, const PageAlignedAllocator<U>&) noexcept {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kernel Samepage Merging (KSM) functionality
|
|
||||||
namespace KSM {
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Windows-specific placeholder functions (no-op)
|
|
||||||
inline void CheckPageAlignment(void* ptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* AllocatePageAligned(size_t size) {
|
|
||||||
return memset(malloc(size), 0, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void MarkMemoryForKSM(void* start, size_t size) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AlignHeapToPageBoundary() {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* MarkHeapStart() {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t MeasureHeapUsage(void* start) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Linux-specific functionality
|
|
||||||
inline void CheckPageAlignment(void* ptr) {
|
|
||||||
size_t page_size = sysconf(_SC_PAGESIZE);
|
|
||||||
if (reinterpret_cast<uintptr_t>(ptr) % page_size == 0) {
|
|
||||||
LogKSMDetail("Memory is page-aligned [{}]", ptr);
|
|
||||||
} else {
|
|
||||||
LogKSMDetail("Memory is NOT page-aligned [{}]", ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* AllocatePageAligned(size_t size) {
|
|
||||||
size_t page_size = sysconf(_SC_PAGESIZE);
|
|
||||||
void* aligned_ptr = nullptr;
|
|
||||||
if (posix_memalign(&aligned_ptr, page_size, size) != 0) {
|
|
||||||
LogKSM("Failed to allocate page-aligned memory on Linux. page_size [{}] size [{}] bytes", page_size, size);
|
|
||||||
}
|
|
||||||
std::memset(aligned_ptr, 0, size);
|
|
||||||
return aligned_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void MarkMemoryForKSM(void* start, size_t size) {
|
|
||||||
if (madvise(start, size, MADV_MERGEABLE) == 0) {
|
|
||||||
LogKSM("Marked memory for KSM | start [{}] size [{}] bytes", start, size);
|
|
||||||
} else {
|
|
||||||
perror("madvise failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AlignHeapToPageBoundary() {
|
|
||||||
size_t page_size = sysconf(_SC_PAGESIZE);
|
|
||||||
if (page_size == 0) {
|
|
||||||
LogKSM("Failed to retrieve page size SC_PAGESIZE [{}]", page_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* current_break = sbrk(0);
|
|
||||||
if (current_break == (void*)-1) {
|
|
||||||
LogKSM("Failed to retrieve the current program break");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t current_address = reinterpret_cast<uintptr_t>(current_break);
|
|
||||||
size_t misalignment = current_address % page_size;
|
|
||||||
|
|
||||||
if (misalignment != 0) {
|
|
||||||
size_t adjustment = page_size - misalignment;
|
|
||||||
if (sbrk(adjustment) == (void*)-1) {
|
|
||||||
LogKSM("Failed to align heap to page boundary. adjustment [{}] bytes", adjustment);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogKSMDetail("Heap aligned to next page boundary. Current break [{}]", sbrk(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* MarkHeapStart() {
|
|
||||||
void* current_pos = sbrk(0);
|
|
||||||
AlignHeapToPageBoundary();
|
|
||||||
return current_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t MeasureHeapUsage(void* start) {
|
|
||||||
void* current_break = sbrk(0);
|
|
||||||
return static_cast<char*>(current_break) - static_cast<char*>(start);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
inline size_t getPageSize()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEM_INFO sysInfo;
|
|
||||||
GetSystemInfo(&sysInfo);
|
|
||||||
return sysInfo.dwPageSize; // Page size in bytes
|
|
||||||
#else
|
|
||||||
return static_cast<size_t>(sysconf(_SC_PAGESIZE)); // POSIX page size
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void PageAlignVectorAligned(std::vector<T, PageAlignedAllocator<T>>& vec) {
|
|
||||||
if (vec.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t page_size = getPageSize();
|
|
||||||
void* start = vec.data();
|
|
||||||
size_t size = vec.size() * sizeof(T);
|
|
||||||
|
|
||||||
// Check if the memory is page-aligned
|
|
||||||
if (reinterpret_cast<std::uintptr_t>(start) % page_size != 0) {
|
|
||||||
// Allocate a new aligned vector
|
|
||||||
std::vector<T, PageAlignedAllocator<T>> aligned_vec(vec.get_allocator());
|
|
||||||
aligned_vec.reserve(vec.capacity()); // Match capacity to avoid reallocation during copy
|
|
||||||
|
|
||||||
// Copy elements from the original vector
|
|
||||||
aligned_vec.insert(aligned_vec.end(), vec.begin(), vec.end());
|
|
||||||
|
|
||||||
// Swap the aligned vector with the original vector
|
|
||||||
vec.swap(aligned_vec);
|
|
||||||
|
|
||||||
// Clear the temporary aligned vector to free its memory
|
|
||||||
aligned_vec.clear();
|
|
||||||
|
|
||||||
// Verify the new alignment
|
|
||||||
start = vec.data();
|
|
||||||
if (reinterpret_cast<std::uintptr_t>(start) % page_size != 0) {
|
|
||||||
throw std::runtime_error("Failed to align vector memory to page boundaries.");
|
|
||||||
}
|
|
||||||
|
|
||||||
LogKSMDetail("Vector reallocated to ensure page alignment. start [{}] size [{}] bytes", start, size);
|
|
||||||
} else {
|
|
||||||
LogKSMDetail("Vector is already page-aligned. start [{}] size [{}] bytes", start, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// Mark memory for KSM (only on non-Windows systems)
|
|
||||||
MarkMemoryForKSM(start, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
162
common/mutex.cpp
162
common/mutex.cpp
@ -1,162 +0,0 @@
|
|||||||
/* EQEmu: EQEmulator
|
|
||||||
|
|
||||||
Copyright (C) 2001-2026 EQEmu Development Team
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "mutex.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#define DEBUG_MUTEX_CLASS 0
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
bool IsTryLockSupported();
|
|
||||||
bool TrylockSupported = IsTryLockSupported();
|
|
||||||
|
|
||||||
bool IsTryLockSupported() {
|
|
||||||
OSVERSIONINFOEX osvi;
|
|
||||||
BOOL bOsVersionInfoEx;
|
|
||||||
|
|
||||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
|
||||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
||||||
|
|
||||||
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
|
|
||||||
{
|
|
||||||
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
|
|
||||||
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
|
|
||||||
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
std::cout << "Mutex::trylock() NOT supported" << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests for Windows NT product family.
|
|
||||||
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion >= 4) {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
std::cout << "Mutex::trylock() SUPPORTED" << std::endl;
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 1
|
|
||||||
std::cout << "Mutex::trylock() NOT supported" << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Mutex::Mutex() {
|
|
||||||
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 7
|
|
||||||
std::cout << "Constructing Mutex" << std::endl;
|
|
||||||
#endif
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
InitializeCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutexattr_t attr;
|
|
||||||
pthread_mutexattr_init(&attr);
|
|
||||||
#if defined(__CYGWIN__) || defined(__APPLE__) || defined(FREEBSD)
|
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
|
||||||
#else
|
|
||||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
|
||||||
#endif
|
|
||||||
pthread_mutex_init(&CSMutex, &attr);
|
|
||||||
pthread_mutexattr_destroy(&attr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Mutex::~Mutex() {
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
DeleteCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex::lock() {
|
|
||||||
#if DEBUG_MUTEX_CLASS >= 5
|
|
||||||
if (!trylock()) {
|
|
||||||
std::cout << "Locking Mutex: Having to wait" << std::endl;
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_lock(&CSMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_lock(&CSMutex);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Mutex::trylock() {
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#if(_WIN32_WINNT >= 0x0400)
|
|
||||||
if (TrylockSupported)
|
|
||||||
return TryEnterCriticalSection(&CSMutex);
|
|
||||||
else {
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
EnterCriticalSection(&CSMutex);
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
return (pthread_mutex_trylock(&CSMutex) == 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mutex::unlock() {
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
LeaveCriticalSection(&CSMutex);
|
|
||||||
#else
|
|
||||||
pthread_mutex_unlock(&CSMutex);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LockMutex::LockMutex(Mutex* in_mut, bool iLock) {
|
|
||||||
mut = in_mut;
|
|
||||||
locked = iLock;
|
|
||||||
if (locked) {
|
|
||||||
mut->lock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LockMutex::~LockMutex() {
|
|
||||||
if (locked) {
|
|
||||||
mut->unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LockMutex::unlock() {
|
|
||||||
if (locked)
|
|
||||||
mut->unlock();
|
|
||||||
locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LockMutex::lock() {
|
|
||||||
if (!locked)
|
|
||||||
mut->lock();
|
|
||||||
locked = true;
|
|
||||||
}
|
|
||||||
@ -18,7 +18,6 @@
|
|||||||
#include "mysql_stmt.h"
|
#include "mysql_stmt.h"
|
||||||
|
|
||||||
#include "common/eqemu_logsys.h"
|
#include "common/eqemu_logsys.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
|
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
@ -31,14 +30,19 @@ void PreparedStmt::StmtDeleter::operator()(MYSQL_STMT* stmt) noexcept
|
|||||||
// The connection must be locked when closing the stmt to avoid mysql errors
|
// The connection must be locked when closing the stmt to avoid mysql errors
|
||||||
// in case another thread tries to use it during the close. If the mutex is
|
// in case another thread tries to use it during the close. If the mutex is
|
||||||
// changed to one that throws then exceptions need to be caught here.
|
// changed to one that throws then exceptions need to be caught here.
|
||||||
LockMutex lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
|
|
||||||
mysql_stmt_close(stmt);
|
mysql_stmt_close(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts)
|
PreparedStmt::PreparedStmt(MYSQL& mysql, std::string query, DBcore::Mutex& mutex, StmtOptions opts)
|
||||||
: m_stmt(mysql_stmt_init(&mysql), { mutex }), m_query(std::move(query)), m_mutex(mutex), m_options(opts)
|
: m_stmt(mysql_stmt_init(&mysql), { mutex })
|
||||||
|
, m_query(std::move(query))
|
||||||
|
, m_options(opts)
|
||||||
|
, m_mutex(mutex)
|
||||||
{
|
{
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
if (mysql_stmt_prepare(m_stmt.get(), m_query.c_str(), static_cast<unsigned long>(m_query.size())) != 0)
|
if (mysql_stmt_prepare(m_stmt.get(), m_query.c_str(), static_cast<unsigned long>(m_query.size())) != 0)
|
||||||
{
|
{
|
||||||
ThrowError(fmt::format("Prepare error: {}", GetStmtError()));
|
ThrowError(fmt::format("Prepare error: {}", GetStmtError()));
|
||||||
@ -186,7 +190,7 @@ void PreparedStmt::CheckArgs(size_t argc)
|
|||||||
StmtResult PreparedStmt::DoExecute()
|
StmtResult PreparedStmt::DoExecute()
|
||||||
{
|
{
|
||||||
BenchTimer timer;
|
BenchTimer timer;
|
||||||
LockMutex lock(m_mutex);
|
std::scoped_lock lock(m_mutex);
|
||||||
|
|
||||||
if (m_need_bind && mysql_stmt_bind_param(m_stmt.get(), m_params.data()) != 0)
|
if (m_need_bind && mysql_stmt_bind_param(m_stmt.get(), m_params.data()) != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -17,10 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mysql.h"
|
#include "common/dbcore.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -183,7 +185,7 @@ public:
|
|||||||
int64_t, uint64_t, float, double, bool, std::string_view, std::nullptr_t>;
|
int64_t, uint64_t, float, double, bool, std::string_view, std::nullptr_t>;
|
||||||
|
|
||||||
PreparedStmt() = delete;
|
PreparedStmt() = delete;
|
||||||
PreparedStmt(MYSQL& mysql, std::string query, Mutex* mutex, StmtOptions opts = {});
|
PreparedStmt(MYSQL& mysql, std::string query, DBcore::Mutex& mutex, StmtOptions opts = {});
|
||||||
|
|
||||||
const std::string& GetQuery() const { return m_query; }
|
const std::string& GetQuery() const { return m_query; }
|
||||||
StmtOptions GetOptions() const { return m_options; }
|
StmtOptions GetOptions() const { return m_options; }
|
||||||
@ -219,7 +221,8 @@ private:
|
|||||||
|
|
||||||
struct StmtDeleter
|
struct StmtDeleter
|
||||||
{
|
{
|
||||||
Mutex* mutex = nullptr;
|
DBcore::Mutex& mutex;
|
||||||
|
|
||||||
void operator()(MYSQL_STMT* stmt) noexcept;
|
void operator()(MYSQL_STMT* stmt) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -232,7 +235,7 @@ private:
|
|||||||
std::string m_query;
|
std::string m_query;
|
||||||
StmtOptions m_options = {};
|
StmtOptions m_options = {};
|
||||||
bool m_need_bind = true;
|
bool m_need_bind = true;
|
||||||
Mutex* m_mutex = nullptr; // connection mutex
|
DBcore::Mutex& m_mutex; // connection mutex
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mysql
|
} // namespace mysql
|
||||||
|
|||||||
131
common/net/dns.cpp
Normal file
131
common/net/dns.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/* EQEmu: EQEmulator
|
||||||
|
|
||||||
|
Copyright (C) 2001-2026 EQEmu Development Team
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dns.h"
|
||||||
|
|
||||||
|
#include "common/eqemu_logsys.h"
|
||||||
|
#include "common/event/event_loop.h"
|
||||||
|
#include "common/event/task_scheduler.h"
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
|
||||||
|
namespace EQ::Net {
|
||||||
|
|
||||||
|
struct DNSBaton
|
||||||
|
{
|
||||||
|
dns_callback_t cb;
|
||||||
|
bool ipv6;
|
||||||
|
};
|
||||||
|
|
||||||
|
void DNSLookup(const std::string& addr, int port, bool ipv6, dns_callback_t cb)
|
||||||
|
{
|
||||||
|
addrinfo hints = {};
|
||||||
|
hints.ai_family = PF_INET;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
uv_loop_t* loop = EQ::EventLoop::Get().Handle();
|
||||||
|
|
||||||
|
uv_getaddrinfo_t* resolver = new uv_getaddrinfo_t();
|
||||||
|
memset(resolver, 0, sizeof(uv_getaddrinfo_t));
|
||||||
|
std::string port_str = std::to_string(port);
|
||||||
|
DNSBaton* baton = new DNSBaton();
|
||||||
|
baton->cb = std::move(cb);
|
||||||
|
baton->ipv6 = ipv6;
|
||||||
|
resolver->data = baton;
|
||||||
|
|
||||||
|
uv_getaddrinfo(loop, resolver, [](uv_getaddrinfo_t* req, int status, addrinfo* result)
|
||||||
|
{
|
||||||
|
DNSBaton* baton = static_cast<DNSBaton*>(req->data);
|
||||||
|
|
||||||
|
dns_callback_t dns_callback = std::move(baton->cb);
|
||||||
|
bool ipv6 = baton->ipv6;
|
||||||
|
|
||||||
|
delete baton;
|
||||||
|
delete req;
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
{
|
||||||
|
dns_callback({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char addr[40] = {};
|
||||||
|
|
||||||
|
if (ipv6)
|
||||||
|
{
|
||||||
|
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(result->ai_addr), addr, 40);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uv_ip4_name(reinterpret_cast<sockaddr_in*>(result->ai_addr), addr, 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_freeaddrinfo(result);
|
||||||
|
|
||||||
|
dns_callback(addr);
|
||||||
|
}, addr.c_str(), port_str.c_str(), &hints);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DNSLookupSync(const std::string& addr, int port, bool ipv6 /* = false */)
|
||||||
|
{
|
||||||
|
EQ::Event::TaskScheduler task_runner;
|
||||||
|
|
||||||
|
auto res = task_runner.Enqueue(
|
||||||
|
[addr, port, ipv6]() -> std::string
|
||||||
|
{
|
||||||
|
bool running = true;
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
EQ::Net::DNSLookup(
|
||||||
|
addr, port, ipv6, [&](const std::string& addr) {
|
||||||
|
ret = addr;
|
||||||
|
running = !addr.empty();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
auto& loop = EQ::EventLoop::Get();
|
||||||
|
while (running) {
|
||||||
|
if (!ret.empty()) {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
||||||
|
if (std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() > 1500) {
|
||||||
|
LogInfo(
|
||||||
|
"Deadline exceeded [{}]",
|
||||||
|
1500
|
||||||
|
);
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop.Process();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace EQ::Net
|
||||||
@ -17,63 +17,15 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/event/event_loop.h"
|
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ::Net {
|
||||||
{
|
|
||||||
namespace Net
|
|
||||||
{
|
|
||||||
static void DNSLookup(const std::string &addr, int port, bool ipv6, std::function<void(const std::string&)> cb) {
|
|
||||||
struct DNSBaton
|
|
||||||
{
|
|
||||||
std::function<void(const std::string&)> cb;
|
|
||||||
bool ipv6;
|
|
||||||
};
|
|
||||||
|
|
||||||
addrinfo hints;
|
using dns_callback_t = std::function<void(const std::string&)>;
|
||||||
memset(&hints, 0, sizeof(addrinfo));
|
|
||||||
hints.ai_family = PF_INET;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
|
||||||
|
|
||||||
auto loop = EQ::EventLoop::Get().Handle();
|
void DNSLookup(const std::string& addr, int port, bool ipv6, dns_callback_t cb);
|
||||||
uv_getaddrinfo_t *resolver = new uv_getaddrinfo_t();
|
|
||||||
memset(resolver, 0, sizeof(uv_getaddrinfo_t));
|
|
||||||
auto port_str = std::to_string(port);
|
|
||||||
DNSBaton *baton = new DNSBaton();
|
|
||||||
baton->cb = cb;
|
|
||||||
baton->ipv6 = ipv6;
|
|
||||||
resolver->data = baton;
|
|
||||||
|
|
||||||
uv_getaddrinfo(loop, resolver, [](uv_getaddrinfo_t* req, int status, addrinfo* res) {
|
std::string DNSLookupSync(const std::string& addr, int port, bool ipv6 = false);
|
||||||
DNSBaton *baton = (DNSBaton*)req->data;
|
|
||||||
if (status < 0) {
|
|
||||||
auto cb = baton->cb;
|
|
||||||
delete baton;
|
|
||||||
delete req;
|
|
||||||
cb("");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char addr[40] = { 0 };
|
} // namespace EQ::Net
|
||||||
|
|
||||||
if (baton->ipv6) {
|
|
||||||
uv_ip6_name((struct sockaddr_in6*)res->ai_addr, addr, 40);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uv_ip4_name((struct sockaddr_in*)res->ai_addr, addr, 40);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cb = baton->cb;
|
|
||||||
delete baton;
|
|
||||||
delete req;
|
|
||||||
uv_freeaddrinfo(res);
|
|
||||||
|
|
||||||
cb(addr);
|
|
||||||
}, addr.c_str(), port_str.c_str(), &hints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
#include "common/net/tcp_connection_pooling.h"
|
#include "common/net/tcp_connection_pooling.h"
|
||||||
|
|
||||||
|
#include "common/platform/platform.h"
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|||||||
@ -49,9 +49,9 @@ namespace EQ
|
|||||||
WebsocketException(const std::string &msg)
|
WebsocketException(const std::string &msg)
|
||||||
: _msg(msg.empty() ? "Unknown Error" : msg) { }
|
: _msg(msg.empty() ? "Unknown Error" : msg) { }
|
||||||
|
|
||||||
~WebsocketException() throw() {}
|
~WebsocketException() noexcept {}
|
||||||
|
|
||||||
virtual char const *what() const throw() {
|
virtual char const *what() const noexcept override {
|
||||||
return _msg.c_str();
|
return _msg.c_str();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -17,17 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
static constexpr char OP_SessionRequest = 0x01;
|
||||||
static const char OP_SessionRequest = 0x01;
|
static constexpr char OP_SessionResponse = 0x02;
|
||||||
static const char OP_SessionResponse = 0x02;
|
static constexpr char OP_Combined = 0x03;
|
||||||
static const char OP_Combined = 0x03;
|
static constexpr char OP_SessionDisconnect = 0x05;
|
||||||
static const char OP_SessionDisconnect = 0x05;
|
static constexpr char OP_KeepAlive = 0x06;
|
||||||
static const char OP_KeepAlive = 0x06;
|
static constexpr char OP_SessionStatRequest = 0x07;
|
||||||
static const char OP_SessionStatRequest = 0x07;
|
static constexpr char OP_SessionStatResponse = 0x08;
|
||||||
static const char OP_SessionStatResponse= 0x08;
|
static constexpr char OP_Packet = 0x09;
|
||||||
static const char OP_Packet = 0x09;
|
static constexpr char OP_Fragment = 0x0d;
|
||||||
static const char OP_Fragment = 0x0d;
|
static constexpr char OP_OutOfOrderAck = 0x11;
|
||||||
static const char OP_OutOfOrderAck = 0x11;
|
static constexpr char OP_Ack = 0x15;
|
||||||
static const char OP_Ack = 0x15;
|
static constexpr char OP_AppCombined = 0x19;
|
||||||
static const char OP_AppCombined = 0x19;
|
static constexpr char OP_OutOfSession = 0x1d;
|
||||||
static const char OP_OutOfSession = 0x1d;
|
|
||||||
|
|||||||
@ -142,10 +142,12 @@ RegularOpcodeManager::~RegularOpcodeManager() {
|
|||||||
safe_delete_array(eq_to_emu);
|
safe_delete_array(eq_to_emu);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegularOpcodeManager::LoadOpcodes(const char *filename, bool report_errors) {
|
bool RegularOpcodeManager::LoadOpcodes(const char *filename, bool report_errors)
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(MOpcodes);
|
||||||
|
|
||||||
NormalMemStrategy s;
|
NormalMemStrategy s;
|
||||||
s.it = this;
|
s.it = this;
|
||||||
MOpcodes.lock();
|
|
||||||
|
|
||||||
loaded = true;
|
loaded = true;
|
||||||
eq_to_emu = new EmuOpcode[MAX_EQ_OPCODE];
|
eq_to_emu = new EmuOpcode[MAX_EQ_OPCODE];
|
||||||
@ -158,32 +160,30 @@ bool RegularOpcodeManager::LoadOpcodes(const char *filename, bool report_errors)
|
|||||||
memset(emu_to_eq, 0, sizeof(uint16)*_maxEmuOpcode);
|
memset(emu_to_eq, 0, sizeof(uint16)*_maxEmuOpcode);
|
||||||
|
|
||||||
bool ret = LoadOpcodesFile(filename, &s, report_errors);
|
bool ret = LoadOpcodesFile(filename, &s, report_errors);
|
||||||
MOpcodes.unlock();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegularOpcodeManager::ReloadOpcodes(const char *filename, bool report_errors) {
|
bool RegularOpcodeManager::ReloadOpcodes(const char* filename, bool report_errors)
|
||||||
if(!loaded)
|
{
|
||||||
return(LoadOpcodes(filename));
|
if (!loaded)
|
||||||
|
return LoadOpcodes(filename);
|
||||||
|
|
||||||
|
std::scoped_lock lock(MOpcodes);
|
||||||
|
|
||||||
NormalMemStrategy s;
|
NormalMemStrategy s;
|
||||||
s.it = this;
|
s.it = this;
|
||||||
MOpcodes.lock();
|
|
||||||
|
|
||||||
memset(eq_to_emu, 0, sizeof(uint16)*MAX_EQ_OPCODE);
|
memset(eq_to_emu, 0, sizeof(uint16) * MAX_EQ_OPCODE);
|
||||||
|
return LoadOpcodesFile(filename, &s, report_errors);
|
||||||
bool ret = LoadOpcodesFile(filename, &s, report_errors);
|
|
||||||
|
|
||||||
MOpcodes.unlock();
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
||||||
//opcode is checked for validity in GetEQOpcode
|
//opcode is checked for validity in GetEQOpcode
|
||||||
uint16 res;
|
uint16 res;
|
||||||
MOpcodes.lock();
|
{
|
||||||
res = emu_to_eq[emu_op];
|
std::scoped_lock lock(MOpcodes);
|
||||||
MOpcodes.unlock();
|
res = emu_to_eq[emu_op];
|
||||||
|
}
|
||||||
|
|
||||||
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
||||||
|
|
||||||
@ -193,15 +193,18 @@ uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
|||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmuOpcode RegularOpcodeManager::EQToEmu(const uint16 eq_op) {
|
EmuOpcode RegularOpcodeManager::EQToEmu(const uint16 eq_op)
|
||||||
|
{
|
||||||
//opcode is checked for validity in GetEmuOpcode
|
//opcode is checked for validity in GetEmuOpcode
|
||||||
//Disabled since current live EQ uses the entire uint16 bitspace for opcodes
|
//Disabled since current live EQ uses the entire uint16 bitspace for opcodes
|
||||||
// if(eq_op > MAX_EQ_OPCODE)
|
// if(eq_op > MAX_EQ_OPCODE)
|
||||||
// return(OP_Unknown);
|
// return(OP_Unknown);
|
||||||
EmuOpcode res;
|
EmuOpcode res;
|
||||||
MOpcodes.lock();
|
{
|
||||||
res = eq_to_emu[eq_op];
|
std::scoped_lock lock(MOpcodes);
|
||||||
MOpcodes.unlock();
|
res = eq_to_emu[eq_op];
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_TRANSLATE
|
#ifdef DEBUG_TRANSLATE
|
||||||
fprintf(stderr, "M Translate EQ 0x%.4x to Emu %s (%d)\n", eq_op, OpcodeNames[res], res);
|
fprintf(stderr, "M Translate EQ 0x%.4x to Emu %s (%d)\n", eq_op, OpcodeNames[res], res);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -18,10 +18,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/emu_opcodes.h"
|
#include "common/emu_opcodes.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
//enable the use of shared mem opcodes for world and zone only
|
//enable the use of shared mem opcodes for world and zone only
|
||||||
#ifdef ZONE
|
#ifdef ZONE
|
||||||
@ -31,7 +31,8 @@
|
|||||||
#define SHARED_OPCODES
|
#define SHARED_OPCODES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class OpcodeManager {
|
class OpcodeManager
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
OpcodeManager();
|
OpcodeManager();
|
||||||
virtual ~OpcodeManager() {}
|
virtual ~OpcodeManager() {}
|
||||||
@ -48,24 +49,27 @@ public:
|
|||||||
EmuOpcode NameSearch(const char *name);
|
EmuOpcode NameSearch(const char *name);
|
||||||
|
|
||||||
//This has to be public for stupid visual studio
|
//This has to be public for stupid visual studio
|
||||||
class OpcodeSetStrategy {
|
class OpcodeSetStrategy
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~OpcodeSetStrategy() {} //shut up compiler!
|
virtual ~OpcodeSetStrategy() = default;
|
||||||
virtual void Set(EmuOpcode emu_op, uint16 eq_op) = 0;
|
virtual void Set(EmuOpcode emu_op, uint16 eq_op) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool loaded; //true if all opcodes loaded
|
bool loaded; //true if all opcodes loaded
|
||||||
Mutex MOpcodes; //this only protects the local machine
|
std::mutex MOpcodes; //this only protects the local machine
|
||||||
//in a shared manager, this dosent protect others
|
//in a shared manager, this dosent protect others
|
||||||
|
|
||||||
static bool LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors);
|
static bool LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s, bool report_errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MutableOpcodeManager : public OpcodeManager {
|
class MutableOpcodeManager : public OpcodeManager
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MutableOpcodeManager() : OpcodeManager() {}
|
MutableOpcodeManager() = default;
|
||||||
virtual bool Mutable() { return(true); }
|
|
||||||
|
virtual bool Mutable() override { return true; }
|
||||||
virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op) = 0;
|
virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,16 +112,16 @@ public:
|
|||||||
virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op);
|
virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class NormalMemStrategy : public OpcodeManager::OpcodeSetStrategy {
|
class NormalMemStrategy : public OpcodeManager::OpcodeSetStrategy
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~NormalMemStrategy() {} //shut up compiler!
|
RegularOpcodeManager* it;
|
||||||
RegularOpcodeManager *it;
|
|
||||||
void Set(EmuOpcode emu_op, uint16 eq_op);
|
|
||||||
};
|
|
||||||
friend class NormalMemStrategy;
|
|
||||||
|
|
||||||
uint16 *emu_to_eq;
|
virtual void Set(EmuOpcode emu_op, uint16 eq_op) override;
|
||||||
EmuOpcode *eq_to_emu;
|
};
|
||||||
|
|
||||||
|
uint16* emu_to_eq;
|
||||||
|
EmuOpcode* eq_to_emu;
|
||||||
uint32 EQOpcodeCount;
|
uint32 EQOpcodeCount;
|
||||||
uint32 EmuOpcodeCount;
|
uint32 EmuOpcodeCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3221,7 +3221,7 @@ namespace RoF
|
|||||||
|
|
||||||
buf.WriteString(new_message);
|
buf.WriteString(new_message);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
dest->FastQueuePacket(&outapp, ack_req);
|
||||||
delete in;
|
delete in;
|
||||||
|
|||||||
@ -689,7 +689,7 @@ namespace RoF2
|
|||||||
EQApplicationPacket *outapp = nullptr;
|
EQApplicationPacket *outapp = nullptr;
|
||||||
if (eq->bufffade == 1)
|
if (eq->bufffade == 1)
|
||||||
{
|
{
|
||||||
outapp = new EQApplicationPacket(OP_BuffCreate, 29);
|
outapp = new EQApplicationPacket(OP_BuffCreate, 29u);
|
||||||
outapp->WriteUInt32(emu->entityid);
|
outapp->WriteUInt32(emu->entityid);
|
||||||
outapp->WriteUInt32(0); // tic timer
|
outapp->WriteUInt32(0); // tic timer
|
||||||
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
|
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
|
||||||
@ -753,7 +753,7 @@ namespace RoF2
|
|||||||
ar(bl);
|
ar(bl);
|
||||||
|
|
||||||
//packet size
|
//packet size
|
||||||
auto packet_size = bl.item_name.length() + 1 + 34;
|
size_t packet_size = bl.item_name.length() + 1 + 34;
|
||||||
for (auto const &b: bl.trade_items) {
|
for (auto const &b: bl.trade_items) {
|
||||||
packet_size += b.item_name.length() + 1;
|
packet_size += b.item_name.length() + 1;
|
||||||
packet_size += 12;
|
packet_size += 12;
|
||||||
@ -1622,7 +1622,7 @@ namespace RoF2
|
|||||||
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Yourname is %s", gu2->yourname);
|
//Log.LogDebugType(Logs::General, Logs::Netcode, "[ERROR] Yourname is %s", gu2->yourname);
|
||||||
|
|
||||||
int MemberCount = 1;
|
int MemberCount = 1;
|
||||||
int PacketLength = 8 + strlen(gu2->leadersname) + 1 + 22 + strlen(gu2->yourname) + 1;
|
uint32 PacketLength = 8 + strlen(gu2->leadersname) + 1 + 22 + strlen(gu2->yourname) + 1;
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
@ -2207,7 +2207,7 @@ namespace RoF2
|
|||||||
|
|
||||||
char *Buffer = (char *)in->pBuffer;
|
char *Buffer = (char *)in->pBuffer;
|
||||||
|
|
||||||
int PacketSize = sizeof(structs::MercenaryMerchantList_Struct) - 4 + emu->MercTypeCount * 4;
|
uint32 PacketSize = sizeof(structs::MercenaryMerchantList_Struct) - 4 + emu->MercTypeCount * 4;
|
||||||
PacketSize += (sizeof(structs::MercenaryListEntry_Struct) - sizeof(structs::MercenaryStance_Struct)) * emu->MercCount;
|
PacketSize += (sizeof(structs::MercenaryListEntry_Struct) - sizeof(structs::MercenaryStance_Struct)) * emu->MercCount;
|
||||||
|
|
||||||
uint32 r;
|
uint32 r;
|
||||||
@ -3820,7 +3820,7 @@ namespace RoF2
|
|||||||
|
|
||||||
buf.WriteString(new_message);
|
buf.WriteString(new_message);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
dest->FastQueuePacket(&outapp, ack_req);
|
||||||
delete in;
|
delete in;
|
||||||
@ -4120,8 +4120,8 @@ namespace RoF2
|
|||||||
std::begin(emu->items),
|
std::begin(emu->items),
|
||||||
std::end(emu->items),
|
std::end(emu->items),
|
||||||
std::begin(eq->items),
|
std::begin(eq->items),
|
||||||
[&](const uint32 x) {
|
[&](uint64 x) {
|
||||||
return x;
|
return static_cast<uint32>(x);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
std::copy_n(
|
std::copy_n(
|
||||||
@ -4599,7 +4599,7 @@ namespace RoF2
|
|||||||
int k;
|
int k;
|
||||||
for (r = 0; r < entrycount; r++, emu++) {
|
for (r = 0; r < entrycount; r++, emu++) {
|
||||||
|
|
||||||
int PacketSize = 206;
|
uint32 PacketSize = 206;
|
||||||
|
|
||||||
PacketSize += strlen(emu->name);
|
PacketSize += strlen(emu->name);
|
||||||
PacketSize += strlen(emu->lastName);
|
PacketSize += strlen(emu->lastName);
|
||||||
|
|||||||
@ -2128,7 +2128,7 @@ namespace SoD
|
|||||||
|
|
||||||
buf.WriteString(new_message);
|
buf.WriteString(new_message);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
dest->FastQueuePacket(&outapp, ack_req);
|
||||||
delete in;
|
delete in;
|
||||||
|
|||||||
@ -1785,7 +1785,7 @@ namespace SoF
|
|||||||
|
|
||||||
buf.WriteString(new_message);
|
buf.WriteString(new_message);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
dest->FastQueuePacket(&outapp, ack_req);
|
||||||
delete in;
|
delete in;
|
||||||
|
|||||||
@ -1991,7 +1991,7 @@ namespace Titanium
|
|||||||
|
|
||||||
buf.WriteString(new_message);
|
buf.WriteString(new_message);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
dest->FastQueuePacket(&outapp, ack_req);
|
||||||
delete in;
|
delete in;
|
||||||
|
|||||||
@ -2711,7 +2711,7 @@ namespace UF
|
|||||||
|
|
||||||
buf.WriteString(new_message);
|
buf.WriteString(new_message);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
dest->FastQueuePacket(&outapp, ack_req);
|
dest->FastQueuePacket(&outapp, ack_req);
|
||||||
delete in;
|
delete in;
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
|
|
||||||
|
#include "common/platform/win/include_windows.h"
|
||||||
#include <WinSock2.h>
|
#include <WinSock2.h>
|
||||||
|
|
||||||
#endif // _WINDOWS
|
#endif // _WINDOWS
|
||||||
|
|||||||
@ -23,11 +23,13 @@
|
|||||||
|
|
||||||
inline std::string random_string(size_t length)
|
inline std::string random_string(size_t length)
|
||||||
{
|
{
|
||||||
auto randchar = []() -> char {
|
auto randchar = []() -> char
|
||||||
|
{
|
||||||
const char charset[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
|
const char charset[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
|
||||||
const size_t max_index = (sizeof(charset) - 1);
|
const size_t max_index = (sizeof(charset) - 1);
|
||||||
return charset[static_cast<size_t>(std::rand()) % max_index];
|
return charset[static_cast<size_t>(std::rand()) % max_index];
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string str(length, 0);
|
std::string str(length, 0);
|
||||||
std::generate_n(str.begin(), length, randchar);
|
std::generate_n(str.begin(), length, randchar);
|
||||||
return str;
|
return str;
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
class SerializeBuffer
|
class SerializeBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SerializeBuffer() : m_buffer(nullptr), m_capacity(0), m_pos(0) {}
|
SerializeBuffer() = default;
|
||||||
|
|
||||||
explicit SerializeBuffer(size_t size) : m_capacity(size), m_pos(0)
|
explicit SerializeBuffer(size_t size) : m_capacity(size), m_pos(0)
|
||||||
{
|
{
|
||||||
@ -35,8 +35,10 @@ public:
|
|||||||
memset(m_buffer, 0, size);
|
memset(m_buffer, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializeBuffer(const SerializeBuffer &rhs)
|
SerializeBuffer(const SerializeBuffer& rhs)
|
||||||
: m_buffer(new unsigned char[rhs.m_capacity]), m_capacity(rhs.m_capacity), m_pos(rhs.m_pos)
|
: m_buffer(new unsigned char[rhs.m_capacity])
|
||||||
|
, m_capacity(rhs.m_capacity)
|
||||||
|
, m_pos(rhs.m_pos)
|
||||||
{
|
{
|
||||||
memcpy(m_buffer, rhs.m_buffer, rhs.m_capacity);
|
memcpy(m_buffer, rhs.m_buffer, rhs.m_capacity);
|
||||||
}
|
}
|
||||||
@ -53,30 +55,31 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializeBuffer(SerializeBuffer &&rhs) : m_buffer(rhs.m_buffer), m_capacity(rhs.m_capacity), m_pos(rhs.m_pos)
|
SerializeBuffer(SerializeBuffer&& rhs)
|
||||||
|
: m_buffer(std::exchange(rhs.m_buffer, nullptr))
|
||||||
|
, m_capacity(std::exchange(rhs.m_capacity, 0))
|
||||||
|
, m_pos(std::exchange(rhs.m_pos, 0))
|
||||||
{
|
{
|
||||||
rhs.m_buffer = nullptr;
|
|
||||||
rhs.m_capacity = 0;
|
|
||||||
rhs.m_pos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializeBuffer &operator=(SerializeBuffer &&rhs)
|
SerializeBuffer& operator=(SerializeBuffer&& rhs)
|
||||||
{
|
{
|
||||||
if (this != &rhs) {
|
if (this != &rhs)
|
||||||
|
{
|
||||||
delete[] m_buffer;
|
delete[] m_buffer;
|
||||||
|
|
||||||
m_buffer = rhs.m_buffer;
|
m_buffer = std::exchange(rhs.m_buffer, nullptr);
|
||||||
m_capacity = rhs.m_capacity;
|
m_capacity = std::exchange(rhs.m_capacity, 0);
|
||||||
m_pos = rhs.m_pos;
|
m_pos = std::exchange(rhs.m_pos, 0);
|
||||||
|
|
||||||
rhs.m_buffer = nullptr;
|
|
||||||
rhs.m_capacity = 0;
|
|
||||||
rhs.m_pos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~SerializeBuffer() { delete[] m_buffer; }
|
~SerializeBuffer()
|
||||||
|
{
|
||||||
|
delete[] m_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void WriteUInt8(uint8_t v)
|
void WriteUInt8(uint8_t v)
|
||||||
{
|
{
|
||||||
@ -209,7 +212,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void Grow(size_t new_size);
|
void Grow(size_t new_size);
|
||||||
void Reset();
|
void Reset();
|
||||||
unsigned char *m_buffer;
|
|
||||||
size_t m_capacity;
|
unsigned char* m_buffer = nullptr;
|
||||||
size_t m_pos;
|
size_t m_capacity = 0;
|
||||||
|
size_t m_pos = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -389,35 +389,31 @@ enum {
|
|||||||
class ServerPacket
|
class ServerPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~ServerPacket() { safe_delete_array(pBuffer); }
|
~ServerPacket()
|
||||||
ServerPacket(uint16 in_opcode = 0, uint32 in_size = 0) {
|
{
|
||||||
this->compressed = false;
|
safe_delete_array(pBuffer);
|
||||||
size = in_size;
|
}
|
||||||
opcode = in_opcode;
|
|
||||||
if (size == 0) {
|
ServerPacket(uint16 in_opcode = 0, size_t in_size = 0)
|
||||||
pBuffer = 0;
|
: size(static_cast<uint32>(in_size))
|
||||||
}
|
, opcode(in_opcode)
|
||||||
else {
|
{
|
||||||
|
if (size != 0)
|
||||||
|
{
|
||||||
pBuffer = new uchar[size];
|
pBuffer = new uchar[size];
|
||||||
memset(pBuffer, 0, size);
|
memset(pBuffer, 0, size);
|
||||||
}
|
}
|
||||||
_wpos = 0;
|
|
||||||
_rpos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerPacket(uint16 in_opcode, const EQ::Net::Packet &p) {
|
ServerPacket(uint16 in_opcode, const EQ::Net::Packet& p)
|
||||||
this->compressed = false;
|
: size(static_cast<uint32>(p.Length()))
|
||||||
size = (uint32)p.Length();
|
, opcode(in_opcode)
|
||||||
opcode = in_opcode;
|
{
|
||||||
if (size == 0) {
|
if (size != 0)
|
||||||
pBuffer = 0;
|
{
|
||||||
}
|
|
||||||
else {
|
|
||||||
pBuffer = new uchar[size];
|
pBuffer = new uchar[size];
|
||||||
memcpy(pBuffer, p.Data(), size);
|
memcpy(pBuffer, p.Data(), size);
|
||||||
}
|
}
|
||||||
_wpos = 0;
|
|
||||||
_rpos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerPacket* Copy() {
|
ServerPacket* Copy() {
|
||||||
@ -447,14 +443,14 @@ public:
|
|||||||
void ReadSkipBytes(uint32 count) { _rpos += count; }
|
void ReadSkipBytes(uint32 count) { _rpos += count; }
|
||||||
void SetReadPosition(uint32 Newrpos) { _rpos = Newrpos; }
|
void SetReadPosition(uint32 Newrpos) { _rpos = Newrpos; }
|
||||||
|
|
||||||
uint32 size;
|
uint32 size = 0;
|
||||||
uint16 opcode;
|
uint16 opcode = 0;
|
||||||
uchar* pBuffer;
|
uchar* pBuffer = nullptr;
|
||||||
uint32 _wpos;
|
uint32 _wpos = 0;
|
||||||
uint32 _rpos;
|
uint32 _rpos = 0;
|
||||||
bool compressed;
|
bool compressed = false;
|
||||||
uint32 InflatedSize;
|
uint32 InflatedSize = 0;
|
||||||
uint32 destination;
|
uint32 destination = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
@ -989,11 +985,12 @@ struct LauncherConnectInfo {
|
|||||||
char name[64];
|
char name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum ZoneRequestCommands {
|
||||||
ZR_Start,
|
ZR_Start,
|
||||||
ZR_Restart,
|
ZR_Restart,
|
||||||
ZR_Stop
|
ZR_Stop
|
||||||
} ZoneRequestCommands;
|
};
|
||||||
|
|
||||||
struct LauncherZoneRequest {
|
struct LauncherZoneRequest {
|
||||||
uint8 command;
|
uint8 command;
|
||||||
char short_name[33];
|
char short_name[33];
|
||||||
|
|||||||
@ -38,10 +38,10 @@
|
|||||||
#define RELOADTASKS 0
|
#define RELOADTASKS 0
|
||||||
#define RELOADTASKSETS 2
|
#define RELOADTASKSETS 2
|
||||||
|
|
||||||
typedef enum {
|
enum TaskMethodType {
|
||||||
METHODSINGLEID = 0,
|
METHODSINGLEID = 0,
|
||||||
METHODQUEST = 2
|
METHODQUEST = 2
|
||||||
} TaskMethodType;
|
};
|
||||||
|
|
||||||
enum class TaskActivityType : int32_t // task element/objective
|
enum class TaskActivityType : int32_t // task element/objective
|
||||||
{
|
{
|
||||||
|
|||||||
@ -94,7 +94,7 @@ namespace
|
|||||||
{
|
{
|
||||||
m_cache.insert(std::make_pair(
|
m_cache.insert(std::make_pair(
|
||||||
key_type(src, target, dynamic_id, object_offset)
|
key_type(src, target, dynamic_id, object_offset)
|
||||||
, cache_entry(offset, distance)
|
, cache_entry(offset, static_cast<int>(distance))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -547,7 +547,7 @@ void Client::SendExpansionPacketData(PlayerLoginReply &plrs)
|
|||||||
buf.WriteInt32(0xFFFFFFFF);
|
buf.WriteInt32(0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto out = std::make_unique<EQApplicationPacket>(OP_LoginExpansionPacketData, buf);
|
auto out = std::make_unique<EQApplicationPacket>(OP_LoginExpansionPacketData, std::move(buf));
|
||||||
m_connection->QueuePacket(out.get());
|
m_connection->QueuePacket(out.get());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -153,7 +153,7 @@ std::unique_ptr<EQApplicationPacket> WorldServerManager::CreateServerListPacket(
|
|||||||
s->SerializeForClientServerList(buf, use_local_ip, client->GetClientVersion());
|
s->SerializeForClientServerList(buf, use_local_ip, client->GetClientVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_unique<EQApplicationPacket>(OP_ServerListResponse, buf);
|
return std::make_unique<EQApplicationPacket>(OP_ServerListResponse, std::move(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldServerManager::SendUserLoginToWorldRequest(
|
void WorldServerManager::SendUserLoginToWorldRequest(
|
||||||
|
|||||||
@ -20,9 +20,12 @@
|
|||||||
#include "common/eqemu_config.h"
|
#include "common/eqemu_config.h"
|
||||||
#include "common/repositories/zone_repository.h"
|
#include "common/repositories/zone_repository.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
Database db;
|
Database db;
|
||||||
Database db2;
|
Database db2;
|
||||||
|
|
||||||
@ -60,8 +63,6 @@ void WorldserverCLI::TestDatabaseConcurrency(int argc, char **argv, argh::parser
|
|||||||
|
|
||||||
LogInfo("Database test");
|
LogInfo("Database test");
|
||||||
|
|
||||||
auto mutex = new Mutex;
|
|
||||||
|
|
||||||
auto c = EQEmuConfig::get();
|
auto c = EQEmuConfig::get();
|
||||||
LogInfo("Connecting to MySQL");
|
LogInfo("Connecting to MySQL");
|
||||||
if (!db.Connect(
|
if (!db.Connect(
|
||||||
@ -75,19 +76,19 @@ void WorldserverCLI::TestDatabaseConcurrency(int argc, char **argv, argh::parser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.SetMutex(mutex);
|
std::shared_ptr<DBcore::Mutex> sharedMutex = std::make_shared<DBcore::Mutex>();
|
||||||
|
|
||||||
|
db.SetMutex(sharedMutex);
|
||||||
|
|
||||||
db2.SetMySQL(db);
|
db2.SetMySQL(db);
|
||||||
|
|
||||||
db2.SetMutex(mutex);
|
db2.SetMutex(sharedMutex);
|
||||||
|
|
||||||
std::thread(DatabaseTest).detach();
|
std::thread(DatabaseTest).detach();
|
||||||
std::thread(DatabaseTest).detach();
|
std::thread(DatabaseTest).detach();
|
||||||
std::thread(DatabaseTestSecondConnection).detach();
|
std::thread(DatabaseTestSecondConnection).detach();
|
||||||
|
|
||||||
while (!stop) {
|
while (!stop) {
|
||||||
|
std::this_thread::sleep_for(0s);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete(mutex);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,8 +37,5 @@ void WorldserverCLI::DatabaseVersion(int argc, char **argv, argh::parser &cmd, s
|
|||||||
v["bots_database_version"] = RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0;
|
v["bots_database_version"] = RuleB(Bots, Enabled) ? CURRENT_BINARY_BOTS_DATABASE_VERSION : 0;
|
||||||
v["custom_database_version"] = CUSTOM_BINARY_DATABASE_VERSION;
|
v["custom_database_version"] = CUSTOM_BINARY_DATABASE_VERSION;
|
||||||
|
|
||||||
std::stringstream payload;
|
std::cout << v << std::endl;
|
||||||
payload << v;
|
|
||||||
|
|
||||||
std::cout << payload.str() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
#include "world/world_server_cli.h"
|
#include "world/world_server_cli.h"
|
||||||
|
|
||||||
#include "common/events/player_events.h"
|
#include "common/events/player_events.h"
|
||||||
#include "common/memory/ksm.hpp"
|
#include "common/memory/ksm.h"
|
||||||
|
|
||||||
#include "cereal/archives/json.hpp"
|
#include "cereal/archives/json.hpp"
|
||||||
#include "cereal/types/vector.hpp"
|
#include "cereal/types/vector.hpp"
|
||||||
|
|||||||
@ -39,8 +39,5 @@ void WorldserverCLI::Version(int argc, char **argv, argh::parser &cmd, std::stri
|
|||||||
j["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
j["database_version"] = CURRENT_BINARY_DATABASE_VERSION;
|
||||||
j["server_version"] = CURRENT_VERSION;
|
j["server_version"] = CURRENT_VERSION;
|
||||||
|
|
||||||
std::stringstream payload;
|
std::cout << j << std::endl;
|
||||||
payload << j;
|
|
||||||
|
|
||||||
std::cout << payload.str() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,14 +24,14 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
typedef enum {
|
enum CLE_Status {
|
||||||
Never,
|
Never,
|
||||||
Offline,
|
Offline,
|
||||||
Online,
|
Online,
|
||||||
CharSelect,
|
CharSelect,
|
||||||
Zoning,
|
Zoning,
|
||||||
InZone
|
InZone
|
||||||
} CLE_Status;
|
};
|
||||||
|
|
||||||
static const char *CLEStatusString[] = {
|
static const char *CLEStatusString[] = {
|
||||||
"Never",
|
"Never",
|
||||||
|
|||||||
@ -25,10 +25,10 @@
|
|||||||
|
|
||||||
class LauncherLink;
|
class LauncherLink;
|
||||||
|
|
||||||
typedef struct {
|
struct LauncherZone{
|
||||||
std::string name;
|
std::string name;
|
||||||
uint16 port;
|
uint16 port;
|
||||||
} LauncherZone;
|
};
|
||||||
|
|
||||||
//a class exported to perl representing a launcher's in-DB config
|
//a class exported to perl representing a launcher's in-DB config
|
||||||
class EQLConfig {
|
class EQLConfig {
|
||||||
|
|||||||
@ -69,10 +69,10 @@ protected:
|
|||||||
|
|
||||||
uint8 m_dynamicCount;
|
uint8 m_dynamicCount;
|
||||||
|
|
||||||
typedef struct {
|
struct ZoneState{
|
||||||
bool up;
|
bool up;
|
||||||
uint32 starts; //number of times this zone has started
|
uint32 starts; //number of times this zone has started
|
||||||
uint16 port; //the port this zone wants to use (0=pick one)
|
uint16 port; //the port this zone wants to use (0=pick one)
|
||||||
} ZoneState;
|
};
|
||||||
std::map<std::string, ZoneState> m_states;
|
std::map<std::string, ZoneState> m_states;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
#include "common/eq_packet_structs.h"
|
#include "common/eq_packet_structs.h"
|
||||||
#include "common/event/timer.h"
|
#include "common/event/timer.h"
|
||||||
#include "common/linked_list.h"
|
#include "common/linked_list.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/net/servertalk_client_connection.h"
|
#include "common/net/servertalk_client_connection.h"
|
||||||
#include "common/net/servertalk_legacy_client_connection.h"
|
#include "common/net/servertalk_legacy_client_connection.h"
|
||||||
#include "common/queue.h"
|
#include "common/queue.h"
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/eq_packet_structs.h"
|
#include "common/eq_packet_structs.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/queue.h"
|
#include "common/queue.h"
|
||||||
#include "common/servertalk.h"
|
#include "common/servertalk.h"
|
||||||
#include "common/timer.h"
|
#include "common/timer.h"
|
||||||
|
|||||||
@ -319,14 +319,14 @@ void SharedTaskManager::LoadSharedTaskState()
|
|||||||
// load character data for member names
|
// load character data for member names
|
||||||
std::vector<CharacterDataRepository::CharacterData> shared_task_character_data;
|
std::vector<CharacterDataRepository::CharacterData> shared_task_character_data;
|
||||||
if (!shared_task_members_data.empty()) {
|
if (!shared_task_members_data.empty()) {
|
||||||
std::vector<uint32_t> character_ids;
|
std::vector<int64_t> character_ids;
|
||||||
for (const auto &m: shared_task_members_data) {
|
for (const BaseSharedTaskMembersRepository::SharedTaskMembers& m: shared_task_members_data) {
|
||||||
character_ids.emplace_back(m.character_id);
|
character_ids.emplace_back(m.character_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_task_character_data = CharacterDataRepository::GetWhere(
|
shared_task_character_data = CharacterDataRepository::GetWhere(
|
||||||
*m_database,
|
*m_database,
|
||||||
fmt::format("id IN ({})", Strings::Join(character_ids, ","))
|
fmt::format("id IN ({})", fmt::join(character_ids, ","))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
|
inline std::string GetIP() const { return (connection && connection->Handle()) ? connection->Handle()->RemoteIP() : 0; }
|
||||||
std::shared_ptr<EQ::Net::ServertalkServerConnection> connection;
|
|
||||||
|
|
||||||
|
std::shared_ptr<EQ::Net::ServertalkServerConnection> connection;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,8 +24,7 @@
|
|||||||
#include "common/http/httplib.h"
|
#include "common/http/httplib.h"
|
||||||
#include "common/http/uri.h"
|
#include "common/http/uri.h"
|
||||||
#include "common/ip_util.h"
|
#include "common/ip_util.h"
|
||||||
#include "common/net/console_server.h"
|
#include "common/net/dns.h"
|
||||||
#include "common/net/servertalk_server.h"
|
|
||||||
#include "common/path_manager.h"
|
#include "common/path_manager.h"
|
||||||
#include "common/repositories/character_expedition_lockouts_repository.h"
|
#include "common/repositories/character_expedition_lockouts_repository.h"
|
||||||
#include "common/repositories/character_task_timers_repository.h"
|
#include "common/repositories/character_task_timers_repository.h"
|
||||||
@ -33,7 +32,6 @@
|
|||||||
#include "common/rulesys.h"
|
#include "common/rulesys.h"
|
||||||
#include "common/strings.h"
|
#include "common/strings.h"
|
||||||
#include "common/zone_store.h"
|
#include "common/zone_store.h"
|
||||||
#include "common/zone_store.h"
|
|
||||||
#include "world/adventure_manager.h"
|
#include "world/adventure_manager.h"
|
||||||
#include "world/dynamic_zone_manager.h"
|
#include "world/dynamic_zone_manager.h"
|
||||||
#include "world/login_server_list.h"
|
#include "world/login_server_list.h"
|
||||||
@ -49,8 +47,6 @@
|
|||||||
|
|
||||||
extern WorldConfig Config;
|
extern WorldConfig Config;
|
||||||
|
|
||||||
auto mutex = new Mutex;
|
|
||||||
|
|
||||||
void WorldBoot::GMSayHookCallBackProcessWorld(uint16 log_category, const char *func, std::string message)
|
void WorldBoot::GMSayHookCallBackProcessWorld(uint16 log_category, const char *func, std::string message)
|
||||||
{
|
{
|
||||||
// we don't want to loop up with chat messages
|
// we don't want to loop up with chat messages
|
||||||
@ -180,11 +176,13 @@ bool WorldBoot::LoadDatabaseConnections()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMySQL(database);
|
||||||
|
|
||||||
// when database and content_db share the same underlying mysql connection
|
// when database and content_db share the same underlying mysql connection
|
||||||
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
||||||
// when database actions are occurring in different threads
|
// when database actions are occurring in different threads
|
||||||
database.SetMutex(mutex);
|
std::shared_ptr<DBcore::Mutex> sharedMutex = std::make_shared<DBcore::Mutex>();
|
||||||
content_db.SetMutex(mutex);
|
database.SetMutex(sharedMutex);
|
||||||
|
content_db.SetMutex(sharedMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -456,7 +454,7 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
|
|||||||
|
|
||||||
std::string config_address = c->WorldAddress;
|
std::string config_address = c->WorldAddress;
|
||||||
if (!IpUtil::IsIPAddress(config_address)) {
|
if (!IpUtil::IsIPAddress(config_address)) {
|
||||||
config_address = IpUtil::DNSLookupSync(c->WorldAddress, 9000);
|
config_address = EQ::Net::DNSLookupSync(c->WorldAddress, 9000);
|
||||||
LogInfo(
|
LogInfo(
|
||||||
"World config address using DNS [{}] resolves to [{}]",
|
"World config address using DNS [{}] resolves to [{}]",
|
||||||
c->WorldAddress,
|
c->WorldAddress,
|
||||||
@ -634,7 +632,6 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
|
|||||||
|
|
||||||
void WorldBoot::Shutdown()
|
void WorldBoot::Shutdown()
|
||||||
{
|
{
|
||||||
safe_delete(mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
|
void WorldBoot::SendDiscordMessage(int webhook_id, const std::string &message)
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
#define MAX_SWARM_PETS 12 //this can change as long as you make more coords (swarm_pet_x/swarm_pet_y)
|
#define MAX_SWARM_PETS 12 //this can change as long as you make more coords (swarm_pet_x/swarm_pet_y)
|
||||||
#define WAKE_THE_DEAD_NPCTYPEID 500 //We use first pet in pets table as a template
|
#define WAKE_THE_DEAD_NPCTYPEID 500 //We use first pet in pets table as a template
|
||||||
|
|
||||||
typedef enum {
|
enum aaNonspellAction {
|
||||||
aaActionNone = 0,
|
aaActionNone = 0,
|
||||||
aaActionAETaunt = 1,
|
aaActionAETaunt = 1,
|
||||||
aaActionMassBuff = 2,
|
aaActionMassBuff = 2,
|
||||||
@ -38,7 +38,7 @@ typedef enum {
|
|||||||
aaActionLeechTouch = 14,
|
aaActionLeechTouch = 14,
|
||||||
aaActionProjectIllusion = 15,
|
aaActionProjectIllusion = 15,
|
||||||
aaActionFadingMemories = 16
|
aaActionFadingMemories = 16
|
||||||
} aaNonspellAction;
|
};
|
||||||
|
|
||||||
enum { //leadership AA indexes
|
enum { //leadership AA indexes
|
||||||
groupAAMarkNPC = 0,
|
groupAAMarkNPC = 0,
|
||||||
@ -116,7 +116,7 @@ static const uint8 LeadershipAACosts[_maxLeaderAA][MAX_LEADERSHIP_TIERS] = {
|
|||||||
{ 0, 0, 0, 0, 0, 0 }, //raidAA15
|
{ 0, 0, 0, 0, 0, 0 }, //raidAA15
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum { //AA IDs
|
enum aaID { //AA IDs
|
||||||
aaNone =0,
|
aaNone =0,
|
||||||
aaInnateStrength =2,//implemented as bonus
|
aaInnateStrength =2,//implemented as bonus
|
||||||
aaInnateStamina =7,//implemented as bonus
|
aaInnateStamina =7,//implemented as bonus
|
||||||
@ -1525,7 +1525,7 @@ typedef enum { //AA IDs
|
|||||||
|
|
||||||
aaHighestID //this should always be last, and should always
|
aaHighestID //this should always be last, and should always
|
||||||
//follow the highest AA ID
|
//follow the highest AA ID
|
||||||
} aaID;
|
};
|
||||||
|
|
||||||
//Structure representing the database's swarm pet configs
|
//Structure representing the database's swarm pet configs
|
||||||
struct SwarmPet_Struct {
|
struct SwarmPet_Struct {
|
||||||
|
|||||||
@ -10580,12 +10580,12 @@ void Bot::LoadDefaultBotSettings() {
|
|||||||
m_bot_spell_settings.push_back(t);
|
m_bot_spell_settings.push_back(t);
|
||||||
|
|
||||||
LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}] - [{} [#{}] stance]'", GetCleanName(), t.name, t.short_name, t.spell_type, Stance::GetName(bot_stance), bot_stance);
|
LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}] - [{} [#{}] stance]'", GetCleanName(), t.name, t.short_name, t.spell_type, Stance::GetName(bot_stance), bot_stance);
|
||||||
LogBotSettingsDetail("{} says, 'Hold = [{}] | Delay = [{}ms] | MinThreshold = [{}\%] | MaxThreshold = [{}\%]'", GetCleanName(),
|
LogBotSettingsDetail("{} says, 'Hold = [{}] | Delay = [{}ms] | MinThreshold = [{}%] | MaxThreshold = [{}%]'", GetCleanName(),
|
||||||
GetDefaultSpellTypeHold(i, bot_stance),
|
GetDefaultSpellTypeHold(i, bot_stance),
|
||||||
GetDefaultSpellTypeDelay(i, bot_stance),
|
GetDefaultSpellTypeDelay(i, bot_stance),
|
||||||
GetDefaultSpellTypeMinThreshold(i, bot_stance),
|
GetDefaultSpellTypeMinThreshold(i, bot_stance),
|
||||||
GetDefaultSpellTypeMaxThreshold(i, bot_stance));
|
GetDefaultSpellTypeMaxThreshold(i, bot_stance));
|
||||||
LogBotSettingsDetail("{} says, 'AggroCheck = [{}] | MinManaPCT = [{}\%] | MaxManaPCT = [{}\%] | MinHPPCT = [{}\% | MaxHPPCT = [{}\%]'", GetCleanName(), GetDefaultSpellTypeAggroCheck(i, bot_stance), GetDefaultSpellTypeMinManaLimit(i, bot_stance), GetDefaultSpellTypeMaxManaLimit(i, bot_stance), GetDefaultSpellTypeMinHPLimit(i, bot_stance), GetDefaultSpellTypeMaxHPLimit(i, bot_stance));
|
LogBotSettingsDetail("{} says, 'AggroCheck = [{}] | MinManaPCT = [{}%] | MaxManaPCT = [{}%] | MinHPPCT = [{}% | MaxHPPCT = [{}%]'", GetCleanName(), GetDefaultSpellTypeAggroCheck(i, bot_stance), GetDefaultSpellTypeMinManaLimit(i, bot_stance), GetDefaultSpellTypeMaxManaLimit(i, bot_stance), GetDefaultSpellTypeMinHPLimit(i, bot_stance), GetDefaultSpellTypeMaxHPLimit(i, bot_stance));
|
||||||
LogBotSettingsDetail("{} says, 'IdlePriority = [{}] | EngagedPriority = [{}] | PursuePriority = [{}]'", GetCleanName(), GetDefaultSpellTypeIdlePriority(i, GetClass(), bot_stance), GetDefaultSpellTypeEngagedPriority(i, GetClass(), bot_stance), GetDefaultSpellTypePursuePriority(i, GetClass(), bot_stance));
|
LogBotSettingsDetail("{} says, 'IdlePriority = [{}] | EngagedPriority = [{}] | PursuePriority = [{}]'", GetCleanName(), GetDefaultSpellTypeIdlePriority(i, GetClass(), bot_stance), GetDefaultSpellTypeEngagedPriority(i, GetClass(), bot_stance), GetDefaultSpellTypePursuePriority(i, GetClass(), bot_stance));
|
||||||
LogBotSettingsDetail("{} says, 'TargetCount = [{}] | AnnounceCast = [{}]'", GetCleanName(), GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance), GetDefaultSpellTypeAnnounceCast(i, bot_stance));
|
LogBotSettingsDetail("{} says, 'TargetCount = [{}] | AnnounceCast = [{}]'", GetCleanName(), GetDefaultSpellTypeAEOrGroupTargetCount(i, bot_stance), GetDefaultSpellTypeAnnounceCast(i, bot_stance));
|
||||||
}
|
}
|
||||||
@ -10636,7 +10636,7 @@ void Bot::SetBotSpellRecastTimer(uint16 spell_type, Mob* tar, bool precast) {
|
|||||||
|
|
||||||
BotSpell Bot::GetSpellByHealType(uint16 spell_type, Mob* tar) {
|
BotSpell Bot::GetSpellByHealType(uint16 spell_type, Mob* tar) {
|
||||||
if (!TargetValidation(tar)) {
|
if (!TargetValidation(tar)) {
|
||||||
BotSpell result;
|
BotSpell result{};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -458,9 +458,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
|||||||
return bot_id;
|
return bot_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool available_flag = false;
|
bool available_flag = database.botdb.QueryNameAvailability(bot_name);
|
||||||
|
|
||||||
!database.botdb.QueryNameAvailability(bot_name, available_flag);
|
|
||||||
|
|
||||||
if (!available_flag) {
|
if (!available_flag) {
|
||||||
bot_owner->Message(
|
bot_owner->Message(
|
||||||
|
|||||||
@ -24,26 +24,22 @@
|
|||||||
class Client;
|
class Client;
|
||||||
class Seperator;
|
class Seperator;
|
||||||
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
#define HP_RATIO_DELTA 5.0f
|
#define HP_RATIO_DELTA 5.0f
|
||||||
|
|
||||||
enum { EffectIDFirst = 1, EffectIDLast = 12 };
|
enum { EffectIDFirst = 1, EffectIDLast = 12 };
|
||||||
|
|
||||||
#define VALIDATECLASSID(x) ((x >= Class::Warrior && x <= Class::Berserker) ? (x) : (0))
|
#define VALIDATECLASSID(x) ((x >= Class::Warrior && x <= Class::Berserker) ? (x) : (0))
|
||||||
|
|
||||||
// ActionableTarget action_type
|
// ActionableTarget action_type
|
||||||
#define FRIENDLY true
|
#define FRIENDLY true
|
||||||
#define ENEMY false
|
#define ENEMY false
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AFT_None = 0,
|
AFT_None = 0,
|
||||||
AFT_Value,
|
AFT_Value,
|
||||||
AFT_GenderRace,
|
AFT_GenderRace,
|
||||||
AFT_Race
|
AFT_Race
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
namespace MyBots
|
namespace MyBots
|
||||||
{
|
{
|
||||||
|
|||||||
@ -145,9 +145,7 @@ void bot_command_clone(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool available_flag = false;
|
bool available_flag = database.botdb.QueryNameAvailability(bot_name);
|
||||||
|
|
||||||
!database.botdb.QueryNameAvailability(bot_name, available_flag);
|
|
||||||
|
|
||||||
if (!available_flag) {
|
if (!available_flag) {
|
||||||
c->Message(
|
c->Message(
|
||||||
|
|||||||
@ -82,8 +82,8 @@ void bot_command_pickpocket(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup variables for calcs
|
// Setup variables for calcs
|
||||||
bool steal_skill = my_bot->GetSkill(EQ::skills::SkillPickPockets);
|
uint16 steal_skill = my_bot->GetSkill(EQ::skills::SkillPickPockets);
|
||||||
bool steal_chance = steal_skill * 100 / (5 * over_level + 5);
|
int steal_chance = steal_skill * 100 / (5 * over_level + 5);
|
||||||
|
|
||||||
// Determine whether to steal money or an item.
|
// Determine whether to steal money or an item.
|
||||||
uint32 money[6] = {
|
uint32 money[6] = {
|
||||||
|
|||||||
@ -228,7 +228,7 @@ bool BotDatabase::LoadBotSpellCastingChances()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BotDatabase::QueryNameAvailability(const std::string& bot_name, bool& available_flag)
|
bool BotDatabase::QueryNameAvailability(const std::string& bot_name)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
bot_name.empty() ||
|
bot_name.empty() ||
|
||||||
@ -239,8 +239,6 @@ bool BotDatabase::QueryNameAvailability(const std::string& bot_name, bool& avail
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
available_flag = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/* Bot functions */
|
/* Bot functions */
|
||||||
bool QueryNameAvailability(const std::string& bot_name, bool& available_flag);
|
bool QueryNameAvailability(const std::string& bot_name);
|
||||||
bool QueryBotCount(const uint32 owner_id, int class_id, uint32& bot_count, uint32& bot_class_count);
|
bool QueryBotCount(const uint32 owner_id, int class_id, uint32& bot_count, uint32& bot_class_count);
|
||||||
bool LoadBotsList(const uint32 owner_id, std::list<BotsAvailableList>& bots_list, bool by_account = false);
|
bool LoadBotsList(const uint32 owner_id, std::list<BotsAvailableList>& bots_list, bool by_account = false);
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
class CheatManager;
|
class CheatManager;
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
typedef enum {
|
enum UpdateMovementType {
|
||||||
Collision = 1,
|
Collision = 1,
|
||||||
TeleportB,
|
TeleportB,
|
||||||
TeleportA,
|
TeleportA,
|
||||||
@ -37,18 +37,18 @@ typedef enum {
|
|||||||
SpellA, // Titanium - UF
|
SpellA, // Titanium - UF
|
||||||
Unknown0x8,
|
Unknown0x8,
|
||||||
SpellB // Used in RoF+
|
SpellB // Used in RoF+
|
||||||
} UpdateMovementType;
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum ExemptionType {
|
||||||
ShadowStep,
|
ShadowStep,
|
||||||
KnockBack,
|
KnockBack,
|
||||||
Port,
|
Port,
|
||||||
Assist,
|
Assist,
|
||||||
Sense,
|
Sense,
|
||||||
MAX_EXEMPTIONS
|
MAX_EXEMPTIONS
|
||||||
} ExemptionType;
|
};
|
||||||
|
|
||||||
typedef enum {
|
enum CheatTypes {
|
||||||
MQWarp,
|
MQWarp,
|
||||||
MQWarpShadowStep,
|
MQWarpShadowStep,
|
||||||
MQWarpKnockBack,
|
MQWarpKnockBack,
|
||||||
@ -59,7 +59,7 @@ typedef enum {
|
|||||||
MQGhost,
|
MQGhost,
|
||||||
MQFastMem,
|
MQFastMem,
|
||||||
MQWarpAbsolute
|
MQWarpAbsolute
|
||||||
} CheatTypes;
|
};
|
||||||
|
|
||||||
class CheatManager {
|
class CheatManager {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -1784,7 +1784,7 @@ void Client::Message(uint32 type, const char* message, ...) {
|
|||||||
buf.WriteInt32(0);
|
buf.WriteInt32(0);
|
||||||
buf.WriteString(buffer);
|
buf.WriteString(buffer);
|
||||||
|
|
||||||
auto app = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto app = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
FastQueuePacket(&app);
|
FastQueuePacket(&app);
|
||||||
|
|
||||||
@ -1813,7 +1813,7 @@ void Client::FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, cons
|
|||||||
buf.WriteInt32(0);
|
buf.WriteInt32(0);
|
||||||
buf.WriteString(buffer);
|
buf.WriteString(buffer);
|
||||||
|
|
||||||
auto app = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto app = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
FastQueuePacket(&app);
|
FastQueuePacket(&app);
|
||||||
|
|
||||||
@ -3869,7 +3869,7 @@ void Client::MessageString(uint32 type, uint32 string_id, const char* message1,
|
|||||||
|
|
||||||
buf.WriteInt8(0); // prevent oob in packet translation, maybe clean that up sometime
|
buf.WriteInt8(0); // prevent oob in packet translation, maybe clean that up sometime
|
||||||
|
|
||||||
auto outapp = std::make_unique<EQApplicationPacket>(OP_FormattedMessage, buf);
|
auto outapp = std::make_unique<EQApplicationPacket>(OP_FormattedMessage, std::move(buf));
|
||||||
|
|
||||||
if (distance > 0)
|
if (distance > 0)
|
||||||
entity_list.QueueCloseClients(this, outapp.get(), false, distance);
|
entity_list.QueueCloseClients(this, outapp.get(), false, distance);
|
||||||
@ -3987,7 +3987,7 @@ void Client::FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter
|
|||||||
|
|
||||||
buf.WriteInt8(0); // prevent oob in packet translation, maybe clean that up sometime
|
buf.WriteInt8(0); // prevent oob in packet translation, maybe clean that up sometime
|
||||||
|
|
||||||
auto outapp = std::make_unique<EQApplicationPacket>(OP_FormattedMessage, buf);
|
auto outapp = std::make_unique<EQApplicationPacket>(OP_FormattedMessage, std::move(buf));
|
||||||
|
|
||||||
QueuePacket(outapp.get());
|
QueuePacket(outapp.get());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -106,7 +106,7 @@ enum { //scribing argument to MemorizeSpell
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Modes for the zoning state of the client.
|
//Modes for the zoning state of the client.
|
||||||
typedef enum {
|
enum ZoneMode {
|
||||||
ZoneToSafeCoords, // Always send ZonePlayerToBind_Struct to client: Succor/Evac
|
ZoneToSafeCoords, // Always send ZonePlayerToBind_Struct to client: Succor/Evac
|
||||||
GMSummon, // Always send ZonePlayerToBind_Struct to client: Only a GM Summon
|
GMSummon, // Always send ZonePlayerToBind_Struct to client: Only a GM Summon
|
||||||
GMHiddenSummon, // Always send ZonePlayerToBind_Struct to client silently: Only a GM Summon
|
GMHiddenSummon, // Always send ZonePlayerToBind_Struct to client silently: Only a GM Summon
|
||||||
@ -117,7 +117,7 @@ typedef enum {
|
|||||||
SummonPC, // In-zone GMMove() always: Call of the Hero spell or some other type of in zone only summons
|
SummonPC, // In-zone GMMove() always: Call of the Hero spell or some other type of in zone only summons
|
||||||
Rewind, // Summon to /rewind location.
|
Rewind, // Summon to /rewind location.
|
||||||
EvacToSafeCoords
|
EvacToSafeCoords
|
||||||
} ZoneMode;
|
};
|
||||||
|
|
||||||
// translate above enum to a string
|
// translate above enum to a string
|
||||||
std::string GetZoneModeString(ZoneMode mode);
|
std::string GetZoneModeString(ZoneMode mode);
|
||||||
@ -130,13 +130,13 @@ enum {
|
|||||||
HideCorpseNPC = 5
|
HideCorpseNPC = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum
|
enum ShowSpellType
|
||||||
{
|
{
|
||||||
Disciplines,
|
Disciplines,
|
||||||
Spells
|
Spells
|
||||||
} ShowSpellType;
|
};
|
||||||
|
|
||||||
typedef enum
|
enum XTargetType
|
||||||
{
|
{
|
||||||
Empty = 0,
|
Empty = 0,
|
||||||
Auto = 1,
|
Auto = 1,
|
||||||
@ -165,8 +165,7 @@ typedef enum
|
|||||||
MyPetTarget = 24,
|
MyPetTarget = 24,
|
||||||
MyMercenary = 25,
|
MyMercenary = 25,
|
||||||
MyMercenaryTarget = 26
|
MyMercenaryTarget = 26
|
||||||
|
};
|
||||||
} XTargetType;
|
|
||||||
|
|
||||||
struct XTarget_Struct
|
struct XTarget_Struct
|
||||||
{
|
{
|
||||||
|
|||||||
@ -252,7 +252,7 @@ void Client::LoadDefaultBotSettings() {
|
|||||||
m_bot_spell_settings.push_back(t);
|
m_bot_spell_settings.push_back(t);
|
||||||
|
|
||||||
LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}]'", GetCleanName(), t.name, t.short_name, t.spell_type);
|
LogBotSettingsDetail("{} says, 'Setting defaults for {} ({}) [#{}]'", GetCleanName(), t.name, t.short_name, t.spell_type);
|
||||||
LogBotSettingsDetail("{} says, 'Delay = [{}ms] | MinThreshold = [{}\%] | MaxThreshold = [{}\%]'", GetCleanName(),
|
LogBotSettingsDetail("{} says, 'Delay = [{}ms] | MinThreshold = [{}%] | MaxThreshold = [{}%]'", GetCleanName(),
|
||||||
GetDefaultSpellTypeDelay(i),
|
GetDefaultSpellTypeDelay(i),
|
||||||
GetDefaultSpellTypeMinThreshold(i), GetDefaultSpellTypeMaxThreshold(i));
|
GetDefaultSpellTypeMinThreshold(i), GetDefaultSpellTypeMaxThreshold(i));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3239,10 +3239,10 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
((tobe_auged->IsAugmentSlotAvailable(new_aug->GetAugmentType(), in_augment->augment_index)) != -1) &&
|
tobe_auged->IsAugmentSlotAvailable(new_aug->GetAugmentType(), static_cast<uint8>(in_augment->augment_index)) &&
|
||||||
tobe_auged->AvailableWearSlot(new_aug->GetItem()->Slots)
|
tobe_auged->AvailableWearSlot(new_aug->GetItem()->Slots)
|
||||||
) {
|
) {
|
||||||
old_aug = tobe_auged->RemoveAugment(in_augment->augment_index);
|
old_aug = tobe_auged->RemoveAugment(static_cast<uint8>(in_augment->augment_index));
|
||||||
if (old_aug) { // An old augment was removed in order to be replaced with the new one (augment_action 2)
|
if (old_aug) { // An old augment was removed in order to be replaced with the new one (augment_action 2)
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
|
|
||||||
|
|||||||
@ -28,11 +28,11 @@ class Seperator;
|
|||||||
|
|
||||||
typedef void (*CmdFuncPtr)(Client *, const Seperator *);
|
typedef void (*CmdFuncPtr)(Client *, const Seperator *);
|
||||||
|
|
||||||
typedef struct {
|
struct CommandRecord {
|
||||||
uint8 admin;
|
uint8 admin;
|
||||||
std::string description;
|
std::string description;
|
||||||
CmdFuncPtr function; // null means perl function
|
CmdFuncPtr function; // null means perl function
|
||||||
} CommandRecord;
|
};
|
||||||
|
|
||||||
extern int (*command_dispatch)(Client *, std::string, bool);
|
extern int (*command_dispatch)(Client *, std::string, bool);
|
||||||
extern int command_count; // Commands Loaded Count
|
extern int command_count; // Commands Loaded Count
|
||||||
|
|||||||
@ -922,7 +922,7 @@ struct DataBucketCache
|
|||||||
|
|
||||||
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard, SPO_FeignDeath };
|
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard, SPO_FeignDeath };
|
||||||
|
|
||||||
typedef enum {
|
enum PetTypeOld {
|
||||||
petFamiliar, //only listens to /pet get lost
|
petFamiliar, //only listens to /pet get lost
|
||||||
petAnimation, //does not listen to any commands
|
petAnimation, //does not listen to any commands
|
||||||
petOther,
|
petOther,
|
||||||
@ -930,4 +930,4 @@ typedef enum {
|
|||||||
petNPCFollow,
|
petNPCFollow,
|
||||||
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||||
petNone = 0xFF // not a pet
|
petNone = 0xFF // not a pet
|
||||||
} PetTypeOld;
|
};
|
||||||
|
|||||||
@ -1108,7 +1108,7 @@ void EntityList::AESpell(
|
|||||||
max_targets_allowed = RuleI(Spells, TargetedAOEMaxTargets);
|
max_targets_allowed = RuleI(Spells, TargetedAOEMaxTargets);
|
||||||
} else if (
|
} else if (
|
||||||
IsPBAESpell(spell_id) &&
|
IsPBAESpell(spell_id) &&
|
||||||
IsDetrimentalSpell &&
|
is_detrimental_spell &&
|
||||||
!is_npc
|
!is_npc
|
||||||
) {
|
) {
|
||||||
max_targets_allowed = RuleI(Spells, PointBlankAOEMaxTargets);
|
max_targets_allowed = RuleI(Spells, PointBlankAOEMaxTargets);
|
||||||
|
|||||||
@ -4437,7 +4437,7 @@ void EntityList::QuestJournalledSayClose(
|
|||||||
buf.WriteString(message);
|
buf.WriteString(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf);
|
auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf));
|
||||||
|
|
||||||
// client only bothers logging if target spawn ID matches, safe to send to everyone
|
// client only bothers logging if target spawn ID matches, safe to send to everyone
|
||||||
QueueCloseClients(sender, outapp, false, dist);
|
QueueCloseClients(sender, outapp, false, dist);
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef enum {
|
enum QuestEventID {
|
||||||
EVENT_SAY = 0,
|
EVENT_SAY = 0,
|
||||||
EVENT_TRADE, //being given an item or money
|
EVENT_TRADE, //being given an item or money
|
||||||
EVENT_DEATH, //being killed
|
EVENT_DEATH, //being killed
|
||||||
@ -169,6 +169,6 @@ typedef enum {
|
|||||||
EVENT_SPELL_EFFECT_BOT,
|
EVENT_SPELL_EFFECT_BOT,
|
||||||
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
||||||
_LargestEventID
|
_LargestEventID
|
||||||
} QuestEventID;
|
};
|
||||||
|
|
||||||
extern const char *QuestEventSubroutines[_LargestEventID];
|
extern const char *QuestEventSubroutines[_LargestEventID];
|
||||||
|
|||||||
@ -447,15 +447,15 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
if (arg1 == "setinclineinc") {
|
if (arg1 == "setinclineinc") {
|
||||||
std::map<float, std::string> incline_values = {
|
std::map<float, std::string> incline_values = {
|
||||||
{.01, "Upright"},
|
{.01f, "Upright"},
|
||||||
{63.75, "45 Degrees",},
|
{63.75f, "45 Degrees",},
|
||||||
{130, "90 Degrees"},
|
{130.f, "90 Degrees"},
|
||||||
{192.5, "135 Degrees"},
|
{192.5f, "135 Degrees"},
|
||||||
{255, "180 Degrees"},
|
{255.f, "180 Degrees"},
|
||||||
{321.25, "225 Degrees"},
|
{321.25f, "225 Degrees"},
|
||||||
{385, "270 Degrees"},
|
{385.f, "270 Degrees"},
|
||||||
{448.75, "315 Degrees"},
|
{448.75f, "315 Degrees"},
|
||||||
{512.5, "360 Degrees"}
|
{512.5f, "360 Degrees"}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::string> incline_normal_options;
|
std::vector<std::string> incline_normal_options;
|
||||||
|
|||||||
@ -624,7 +624,7 @@ void Client::SendGuildMemberRankAltBanker(uint32 guild_id, uint32 rank, std::str
|
|||||||
|
|
||||||
out->guild_id = guild_id;
|
out->guild_id = guild_id;
|
||||||
out->rank_ = rank;
|
out->rank_ = rank;
|
||||||
out->alt_banker = (alt << 1) | banker;
|
out->alt_banker = (alt ? 2 : 0) | (banker ? 1 : 0);
|
||||||
strn0cpy(out->player_name, player_name.c_str(), sizeof(out->player_name));
|
strn0cpy(out->player_name, player_name.c_str(), sizeof(out->player_name));
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
@ -792,7 +792,7 @@ void EntityList::SendGuildMemberRankAltBanker(uint32 guild_id, uint32 rank_, std
|
|||||||
|
|
||||||
out->guild_id = guild_id;
|
out->guild_id = guild_id;
|
||||||
out->rank_ = rank_;
|
out->rank_ = rank_;
|
||||||
out->alt_banker = (alt << 1) | banker;
|
out->alt_banker = (alt ? 2 : 0) | (banker ? 1 : 0);
|
||||||
strn0cpy(out->player_name, player_name.c_str(), sizeof(out->player_name));
|
strn0cpy(out->player_name, player_name.c_str(), sizeof(out->player_name));
|
||||||
|
|
||||||
c.second->QueuePacket(outapp);
|
c.second->QueuePacket(outapp);
|
||||||
|
|||||||
@ -151,7 +151,7 @@ static const struct luaL_Reg bit_funcs[] = {
|
|||||||
*/
|
*/
|
||||||
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
|
#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
|
||||||
|
|
||||||
int luaopen_bit(lua_State *L)
|
int luaopen_bit_embed(lua_State *L)
|
||||||
{
|
{
|
||||||
UBits b;
|
UBits b;
|
||||||
lua_pushnumber(L, (lua_Number)1437217655L);
|
lua_pushnumber(L, (lua_Number)1437217655L);
|
||||||
|
|||||||
@ -17,4 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int luaopen_bit(lua_State *L);
|
struct lua_State;
|
||||||
|
|
||||||
|
int luaopen_bit_embed(lua_State *L);
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
#include "common/guilds.h"
|
#include "common/guilds.h"
|
||||||
#include "common/memory_mapped_file.h"
|
#include "common/memory_mapped_file.h"
|
||||||
#include "common/misc.h"
|
#include "common/misc.h"
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/net/eqstream.h"
|
#include "common/net/eqstream.h"
|
||||||
#include "common/opcodemgr.h"
|
#include "common/opcodemgr.h"
|
||||||
#include "common/patches/patches.h"
|
#include "common/patches/patches.h"
|
||||||
@ -216,8 +215,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mutex = new Mutex;
|
|
||||||
|
|
||||||
LogInfo("Connecting to MySQL");
|
LogInfo("Connecting to MySQL");
|
||||||
if (!database.Connect(
|
if (!database.Connect(
|
||||||
Config->DatabaseHost.c_str(),
|
Config->DatabaseHost.c_str(),
|
||||||
@ -245,11 +242,13 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
content_db.SetMySQL(database);
|
content_db.SetMySQL(database);
|
||||||
|
|
||||||
// when database and content_db share the same underlying mysql connection
|
// when database and content_db share the same underlying mysql connection
|
||||||
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
// it needs to be protected by a shared mutex otherwise we produce concurrency issues
|
||||||
// when database actions are occurring in different threads
|
// when database actions are occurring in different threads
|
||||||
database.SetMutex(mutex);
|
std::shared_ptr<DBcore::Mutex> sharedMutex = std::make_shared<DBcore::Mutex>();
|
||||||
content_db.SetMutex(mutex);
|
database.SetMutex(sharedMutex);
|
||||||
|
content_db.SetMutex(sharedMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
//rules:
|
//rules:
|
||||||
@ -661,7 +660,6 @@ int main(int argc, char **argv)
|
|||||||
LogInfo("Proper zone shutdown complete.");
|
LogInfo("Proper zone shutdown complete.");
|
||||||
EQEmuLogSys::Instance()->CloseFileLogs();
|
EQEmuLogSys::Instance()->CloseFileLogs();
|
||||||
|
|
||||||
safe_delete(mutex);
|
|
||||||
safe_delete(QServ);
|
safe_delete(QServ);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "common/compression.h"
|
#include "common/compression.h"
|
||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
#include "common/memory/ksm.hpp"
|
#include "common/memory/ksm.h"
|
||||||
#include "common/misc_functions.h"
|
#include "common/misc_functions.h"
|
||||||
#include "zone/client.h"
|
#include "zone/client.h"
|
||||||
#include "zone/map.h"
|
#include "zone/map.h"
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
typedef struct {
|
struct NPCProximity {
|
||||||
float min_x;
|
float min_x;
|
||||||
float max_x;
|
float max_x;
|
||||||
float min_y;
|
float min_y;
|
||||||
@ -41,7 +41,7 @@ typedef struct {
|
|||||||
float max_z;
|
float max_z;
|
||||||
bool say;
|
bool say;
|
||||||
bool proximity_set;
|
bool proximity_set;
|
||||||
} NPCProximity;
|
};
|
||||||
|
|
||||||
struct AISpells_Struct {
|
struct AISpells_Struct {
|
||||||
uint32 type; // 0 = never, must be one (and only one) of the defined values
|
uint32 type; // 0 = never, must be one (and only one) of the defined values
|
||||||
|
|||||||
@ -135,10 +135,11 @@ void PetitionList::AddPetition(Petition* pet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Return Values: 0 = Ok ; -1 = Error deleting petition.
|
//Return Values: 0 = Ok ; -1 = Error deleting petition.
|
||||||
int PetitionList::DeletePetition(uint32 petnumber) {
|
int PetitionList::DeletePetition(uint32 petnumber)
|
||||||
|
{
|
||||||
LinkedListIterator<Petition*> iterator(list);
|
LinkedListIterator<Petition*> iterator(list);
|
||||||
iterator.Reset();
|
iterator.Reset();
|
||||||
LockMutex lock(&PList_Mutex);
|
std::scoped_lock lock(PList_Mutex);
|
||||||
while(iterator.MoreElements()) {
|
while(iterator.MoreElements()) {
|
||||||
if (iterator.GetData()->GetID() == petnumber) {
|
if (iterator.GetData()->GetID() == petnumber) {
|
||||||
database.DeletePetitionFromDB(iterator.GetData());
|
database.DeletePetitionFromDB(iterator.GetData());
|
||||||
@ -179,18 +180,18 @@ void PetitionList::ClearPetitions() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetitionList::ReadDatabase() {
|
void PetitionList::ReadDatabase()
|
||||||
LockMutex lock(&PList_Mutex);
|
{
|
||||||
|
std::scoped_lock lock(PList_Mutex);
|
||||||
ClearPetitions();
|
ClearPetitions();
|
||||||
database.RefreshPetitionsFromDB();
|
database.RefreshPetitionsFromDB();
|
||||||
UpdateGMQueue();
|
UpdateGMQueue();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetitionList::UpdatePetition(Petition* pet) {
|
void PetitionList::UpdatePetition(Petition* pet)
|
||||||
LockMutex lock(&PList_Mutex);
|
{
|
||||||
|
std::scoped_lock lock(PList_Mutex);
|
||||||
database.UpdatePetitionToDB(pet);
|
database.UpdatePetitionToDB(pet);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) {
|
void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) {
|
||||||
|
|||||||
@ -18,12 +18,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/linked_list.h"
|
#include "common/linked_list.h"
|
||||||
#include "common/misc_functions.h"
|
|
||||||
#include "common/mutex.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "common/zone_store.h"
|
|
||||||
#include "zone/client.h"
|
#include <mutex>
|
||||||
#include "zone/zonedb.h"
|
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
@ -118,5 +115,5 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
LinkedList<Petition*> list;
|
LinkedList<Petition*> list;
|
||||||
Mutex PList_Mutex;
|
std::mutex PList_Mutex;
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user