From c3f4cc0e422336b27be7c6f22e9cf938958f512f Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Sat, 6 Sep 2025 21:43:05 -0500 Subject: [PATCH] clean up mutex --- source/LoginServer/LWorld.h | 14 +- source/LoginServer/LoginDatabase.h | 6 +- .../WorldServer/Achievements/Achievements.h | 8 +- source/WorldServer/Chat/Chat.h | 8 +- source/WorldServer/Collections/Collections.h | 4 +- source/WorldServer/Entity.h | 220 ++++---- source/WorldServer/Factions.h | 3 +- source/WorldServer/GroundSpawn.h | 5 +- source/WorldServer/Guilds/Guild.h | 2 +- source/WorldServer/LoginServer.h | 2 +- source/WorldServer/LuaInterface.h | 58 +- source/WorldServer/MutexHelper.h | 12 +- source/WorldServer/Recipes/Recipe.h | 16 +- source/WorldServer/Rules/Rules.h | 8 +- source/WorldServer/Spawn.h | 153 +++--- source/WorldServer/Spells.h | 13 +- source/WorldServer/Titles.h | 6 +- source/WorldServer/Tradeskills/Tradeskills.h | 8 +- source/WorldServer/Traits/Traits.h | 12 +- source/WorldServer/WorldDatabase.h | 31 +- source/WorldServer/Zone/ChestTrap.h | 4 +- source/WorldServer/Zone/map.h | 10 +- .../WorldServer/Zone/mob_movement_manager.h | 2 +- source/WorldServer/zoneserver.h | 148 ++--- source/common/ConfigReader.h | 5 +- source/common/EQEMuError.cpp | 6 +- source/common/EQStream.cpp | 514 +++++++++--------- source/common/EQStream.h | 2 +- source/common/Mutex.cpp | 361 ------------ source/common/Mutex.h | 86 --- source/common/TCPConnection.h | 4 +- source/common/database.h | 6 +- source/common/dbcore.h | 8 +- source/common/mutex.cpp | 238 ++++++++ source/common/mutex.h | 83 +++ source/common/opcodemgr.h | 42 +- 36 files changed, 985 insertions(+), 1123 deletions(-) delete mode 100644 source/common/Mutex.cpp delete mode 100644 source/common/Mutex.h create mode 100644 source/common/mutex.cpp create mode 100644 source/common/mutex.h diff --git a/source/LoginServer/LWorld.h b/source/LoginServer/LWorld.h index d9e3361..c4d4a08 100644 --- a/source/LoginServer/LWorld.h +++ b/source/LoginServer/LWorld.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) @@ -7,7 +7,7 @@ #ifndef LWORLD_H #define LWORLD_H -#include "../common/Mutex.h" +#include "../common/mutex.h" #define ERROR_BADPASSWORD "Bad password" #define INVALID_ACCOUNT "Invalid Server Account." @@ -63,7 +63,7 @@ public: ~LWorld(); static bool CheckServerName(const char* name); - + bool Process(); void SendPacket(ServerPacket* pack); void Message(const char* to, const char* message, ...); @@ -118,7 +118,7 @@ public: void SendDeleteCharacter( int32 char_id, int32 account_id ); bool IsDevelServer(){ return devel_server; } - + inline int8 GetMaxWorldLevel() { return world_max_level; } bool IsInit; @@ -166,7 +166,7 @@ public: LWorldList(); ~LWorldList(); - LWorld* FindByID(int32 WorldID); + LWorld* FindByID(int32 WorldID); LWorld* FindByIP(int32 ip); LWorld* FindByAddress(char* address); LWorld* FindByLink(TCPConnection* in_link, int32 in_id); @@ -197,7 +197,7 @@ public: void InitWorlds(); void Shutdown(); bool WriteXML(); - + int32 GetCount(ConType type); void PopulateWorldList(http::response& res); @@ -229,7 +229,7 @@ private: int32 NextID; LinkedList list; - + map worldmap; TCPServer* tcplistener; diff --git a/source/LoginServer/LoginDatabase.h b/source/LoginServer/LoginDatabase.h index 27ba85b..0c51705 100644 --- a/source/LoginServer/LoginDatabase.h +++ b/source/LoginServer/LoginDatabase.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) @@ -21,7 +21,7 @@ #include "../common/types.h" #include "../common/MiscFunctions.h" #include "../common/servertalk.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "PacketHeaders.h" #include "LoginAccount.h" #include "LWorld.h" @@ -93,4 +93,4 @@ public: DatabaseNew dbLogin; }; -#endif \ No newline at end of file +#endif diff --git a/source/WorldServer/Achievements/Achievements.h b/source/WorldServer/Achievements/Achievements.h index 7b1895c..6409257 100644 --- a/source/WorldServer/Achievements/Achievements.h +++ b/source/WorldServer/Achievements/Achievements.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) @@ -22,7 +22,7 @@ along with EQ2Emulator. If not, see . #define ACHIEVEMENTS_H_ #include "../../common/types.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../Items/Items.h" #include #include @@ -139,7 +139,7 @@ public: private: Mutex mutex_achievements; map achievements; - + bool m_packetsCreated; }; @@ -173,4 +173,4 @@ public: private: map achievement_updates; }; -#endif \ No newline at end of file +#endif diff --git a/source/WorldServer/Chat/Chat.h b/source/WorldServer/Chat/Chat.h index 9318f33..aec52a9 100644 --- a/source/WorldServer/Chat/Chat.h +++ b/source/WorldServer/Chat/Chat.h @@ -6,7 +6,7 @@ #include #include "../../common/types.h" #include "../../common/EQPacket.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../client.h" #include "ChatChannel.h" @@ -25,7 +25,7 @@ CREATING A CHANNEL -- OP_RemoteCmdMsg -- 3/14/2012 20:17:06 192.168.1.198 -> 69.174.200.73 -0000: 00 09 05 9A 2A 0E 00 0F 00 63 75 73 74 6F 6D 20 ....*....custom +0000: 00 09 05 9A 2A 0E 00 0F 00 63 75 73 74 6F 6D 20 ....*....custom 0010 70 61 73 73 77 6F 72 64 password @@ -34,7 +34,7 @@ TALKING IN A CHANNEL [11:52.23] <@Xinux> -- OP_RemoteCmdMsg -- [11:52.23] <@Xinux> 3/14/2012 20:17:25 [11:52.23] <@Xinux> 192.168.1.198 -> 69.174.200.73 -[11:52.23] <@Xinux> 0000: 00 09 06 2D 2A 11 00 21 00 63 75 73 74 6F 6D 20 ...-*..!.custom +[11:52.23] <@Xinux> 0000: 00 09 06 2D 2A 11 00 21 00 63 75 73 74 6F 6D 20 ...-*..!.custom [11:52.23] <@Xinux> 0010: 20 74 68 69 73 20 69 73 20 6D 79 20 63 75 73 74 this is my cust [11:52.23] <@Xinux> 0020 6F 6D 20 63 68 61 6E 6E 65 6C om channel @@ -44,7 +44,7 @@ TALKING IN A CHANNEL [08:37.46] <@Xinux_Work> 00 4B 6F 65 63 68 6F 68 00 02 00 00 00 00 01 00 .Koechoh........ [08:37.46] <@Xinux_Work> 00 00 22 00 18 00 62 65 74 74 65 72 20 74 68 61 .."...better tha [08:37.46] <@Xinux_Work> 6E 20 61 20 72 65 64 20 6F 6E 65 20 3A 50 09 00 n a red one :P.. -[08:37.46] <@Xinux_Work> 4C 65 76 65 6C 5F 31 2D 39 01 01 00 00 Level_1-9.... +[08:37.46] <@Xinux_Work> 4C 65 76 65 6C 5F 31 2D 39 01 01 00 00 Level_1-9.... OTHERS LEAVING AND JOINING A CHANNEL diff --git a/source/WorldServer/Collections/Collections.h b/source/WorldServer/Collections/Collections.h index eb39873..baeb287 100644 --- a/source/WorldServer/Collections/Collections.h +++ b/source/WorldServer/Collections/Collections.h @@ -2,7 +2,7 @@ #define COLLECTIONS_H_ #include "../../common/types.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../Items/Items.h" #include #include @@ -104,4 +104,4 @@ private: map collections; }; -#endif \ No newline at end of file +#endif diff --git a/source/WorldServer/Entity.h b/source/WorldServer/Entity.h index 23702d7..ffb168d 100644 --- a/source/WorldServer/Entity.h +++ b/source/WorldServer/Entity.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net) @@ -20,7 +20,7 @@ #ifndef __EQ2_ENTITY__ #define __EQ2_ENTITY__ #include "Spawn.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "Skills.h" #include "MutexList.h" #include "MutexVector.h" @@ -57,9 +57,9 @@ struct MaintainedEffects{ char name[60]; //name of the spell int32 target; int8 target_type; - int32 spell_id; - int32 inherited_spell_id; - int32 slot_pos; + int32 spell_id; + int32 inherited_spell_id; + int32 slot_pos; int16 icon; int16 icon_backdrop; int8 conc_used; @@ -70,8 +70,8 @@ struct MaintainedEffects{ }; struct SpellEffects{ - int32 spell_id; - int32 inherited_spell_id; + int32 spell_id; + int32 inherited_spell_id; Entity* caster; float total_time; int32 expire_timestamp; @@ -82,8 +82,8 @@ struct SpellEffects{ }; struct DetrimentalEffects { - int32 spell_id; - int32 inherited_spell_id; + int32 spell_id; + int32 inherited_spell_id; Entity* caster; int32 expire_timestamp; int16 icon; @@ -238,11 +238,11 @@ struct InfoStruct{ pet_movement_ = 0; pet_behavior_ = 0; vision_ = 0; - + redlight_ = 0; greenlight_ = 0; bluelight_ = 0; - + breathe_underwater_ = 0; biography_ = std::string(""); drunk_ = 0; @@ -260,7 +260,7 @@ struct InfoStruct{ interaction_flag_ = 0; tag1_ = 0; mood_ = 0; - + range_last_attack_time_ = 0; primary_last_attack_time_ = 0; secondary_last_attack_time_ = 0; @@ -281,20 +281,20 @@ struct InfoStruct{ primary_weapon_delay_ = 0; secondary_weapon_delay_ = 0; ranged_weapon_delay_ = 0; - + override_primary_weapon_ = 0; override_secondary_weapon_ = 0; override_ranged_weapon_ = 0; - + friendly_target_npc_ = 0; last_claim_time_ = 0; - + engaged_encounter_ = 0; lockable_encounter_ = 1; - + first_world_login_ = 0; reload_player_spells_ = 0; - + group_loot_method_ = 1; group_loot_items_rarity_ = 0; group_auto_split_ = 1; @@ -304,10 +304,10 @@ struct InfoStruct{ group_solo_autolock_ = 0; group_auto_loot_method_ = 0; assist_auto_attack_ = 0; - + action_state_ = std::string(""); combat_action_state_ = std::string(""); - + max_spell_reduction_ = .1f; max_spell_reduction_override_ = 0; max_chase_distance_ = 0.0f; @@ -433,10 +433,10 @@ struct InfoStruct{ spell_reuse_speed_ = oldStruct->get_spell_reuse_speed(); spell_multi_attack_ = oldStruct->get_spell_multi_attack(); dps_ = oldStruct->get_dps(); - + size_mod_ = oldStruct->get_size_mod(); ignore_size_mod_calc_ = oldStruct->get_ignore_size_mod_calc(); - + dps_multiplier_ = oldStruct->get_dps_multiplier(); attackspeed_ = oldStruct->get_attackspeed(); haste_ = oldStruct->get_haste(); @@ -456,11 +456,11 @@ struct InfoStruct{ pet_movement_ = oldStruct->get_pet_movement(); pet_behavior_ = oldStruct->get_pet_behavior(); vision_ = oldStruct->get_vision(); - + redlight_ = oldStruct->get_redlight(); greenlight_ = oldStruct->get_greenlight(); bluelight_ = oldStruct->get_bluelight(); - + breathe_underwater_ = oldStruct->get_breathe_underwater(); biography_ = std::string(oldStruct->get_biography()); drunk_ = oldStruct->get_drunk(); @@ -478,7 +478,7 @@ struct InfoStruct{ interaction_flag_ = oldStruct->get_interaction_flag(); tag1_ = oldStruct->get_tag1(); mood_ = oldStruct->get_mood(); - + range_last_attack_time_ = oldStruct->get_range_last_attack_time(); primary_last_attack_time_ = oldStruct->get_primary_last_attack_time();; secondary_last_attack_time_ = oldStruct->get_secondary_last_attack_time();; @@ -499,22 +499,22 @@ struct InfoStruct{ primary_weapon_delay_ = oldStruct->get_primary_weapon_delay(); secondary_weapon_delay_ = oldStruct->get_secondary_weapon_delay(); ranged_weapon_delay_ = oldStruct->get_ranged_weapon_delay(); - + override_primary_weapon_ = oldStruct->get_override_primary_weapon(); override_secondary_weapon_ = oldStruct->get_override_secondary_weapon(); override_ranged_weapon_ = oldStruct->get_override_ranged_weapon(); friendly_target_npc_ = oldStruct->get_friendly_target_npc(); last_claim_time_ = oldStruct->get_last_claim_time(); - + engaged_encounter_ = oldStruct->get_engaged_encounter(); lockable_encounter_ = oldStruct->get_lockable_encounter(); - + first_world_login_ = oldStruct->get_first_world_login(); reload_player_spells_ = oldStruct->get_reload_player_spells(); - + action_state_ = oldStruct->get_action_state(); combat_action_state_ = oldStruct->get_combat_action_state(); - + group_loot_method_ = oldStruct->get_group_loot_method(); group_loot_items_rarity_ = oldStruct->get_group_loot_items_rarity(); group_auto_split_ = oldStruct->get_group_auto_split(); @@ -524,7 +524,7 @@ struct InfoStruct{ group_solo_autolock_ = oldStruct->get_group_solo_autolock(); group_auto_loot_method_ = oldStruct->get_group_auto_loot_method(); assist_auto_attack_ = oldStruct->get_assist_auto_attack(); - + max_spell_reduction_ = oldStruct->get_max_spell_reduction(); max_spell_reduction_override_ = oldStruct->get_max_spell_reduction_override(); max_chase_distance_ = oldStruct->get_max_chase_distance(); @@ -538,7 +538,7 @@ struct InfoStruct{ int8 get_gender() { std::lock_guard lk(classMutex); return gender_; } int16 get_level() { std::lock_guard lk(classMutex); return level_; } int16 get_max_level() { std::lock_guard lk(classMutex); return max_level_; } - int16 get_effective_level() { std::lock_guard lk(classMutex); return effective_level_; } + int16 get_effective_level() { std::lock_guard lk(classMutex); return effective_level_; } int16 get_tradeskill_level() { std::lock_guard lk(classMutex); return tradeskill_level_; } int16 get_tradeskill_max_level() { std::lock_guard lk(classMutex); return tradeskill_max_level_; } @@ -559,7 +559,7 @@ struct InfoStruct{ float get_parry() { std::lock_guard lk(classMutex); return parry_; } float get_parry_base() { std::lock_guard lk(classMutex); return parry_base_; } - + int16 get_max_avoidance() { std::lock_guard lk(classMutex); return max_avoidance_; } float get_deflection() { std::lock_guard lk(classMutex); return deflection_; } @@ -608,7 +608,7 @@ struct InfoStruct{ int32 get_weight() { std::lock_guard lk(classMutex); return weight_; } int32 get_max_weight() { std::lock_guard lk(classMutex); return max_weight_; } - + //SpellEffects* & get_spell_effects() { std::lock_guard lk(classMutex); return spell_effects_; } //MaintainedEffects* & get_maintained_effects() { std::lock_guard lk(classMutex); return maintained_effects_; } int8 get_tradeskill_class1() { std::lock_guard lk(classMutex); return tradeskill_class1_; } @@ -638,7 +638,7 @@ struct InfoStruct{ int16 get_mitigation_skill1() { std::lock_guard lk(classMutex); return mitigation_skill1_; } int16 get_mitigation_skill2() { std::lock_guard lk(classMutex); return mitigation_skill2_; } int16 get_mitigation_skill3() { std::lock_guard lk(classMutex); return mitigation_skill3_; } - + int16 get_mitigation_pve() { std::lock_guard lk(classMutex); return mitigation_pve_; } int16 get_mitigation_pvp() { std::lock_guard lk(classMutex); return mitigation_pvp_; } @@ -681,11 +681,11 @@ struct InfoStruct{ int8 get_pet_movement() { std::lock_guard lk(classMutex); return pet_movement_; } int8 get_pet_behavior() { std::lock_guard lk(classMutex); return pet_behavior_; } int32 get_vision() { std::lock_guard lk(classMutex); return vision_; } - + int32 get_redlight() { std::lock_guard lk(classMutex); return redlight_; } int32 get_greenlight() { std::lock_guard lk(classMutex); return greenlight_; } int32 get_bluelight() { std::lock_guard lk(classMutex); return bluelight_; } - + int8 get_breathe_underwater() { std::lock_guard lk(classMutex); return breathe_underwater_; } std::string get_biography() { std::lock_guard lk(classMutex); return biography_; } float get_drunk() { std::lock_guard lk(classMutex); return drunk_; } @@ -708,11 +708,11 @@ struct InfoStruct{ int32 get_range_last_attack_time() { std::lock_guard lk(classMutex); return range_last_attack_time_; } int32 get_primary_last_attack_time() { std::lock_guard lk(classMutex); return primary_last_attack_time_; } int32 get_secondary_last_attack_time() { std::lock_guard lk(classMutex); return secondary_last_attack_time_; } - + int16 get_primary_attack_delay() { std::lock_guard lk(classMutex); return primary_attack_delay_; } int16 get_secondary_attack_delay() { std::lock_guard lk(classMutex); return secondary_attack_delay_; } int16 get_ranged_attack_delay() { std::lock_guard lk(classMutex); return ranged_attack_delay_; } - + int8 get_primary_weapon_type() { std::lock_guard lk(classMutex); return primary_weapon_type_; } int8 get_secondary_weapon_type() { std::lock_guard lk(classMutex); return secondary_weapon_type_; } int8 get_ranged_weapon_type() { std::lock_guard lk(classMutex); return ranged_weapon_type_; } @@ -730,21 +730,21 @@ struct InfoStruct{ int16 get_primary_weapon_delay() { std::lock_guard lk(classMutex); return primary_weapon_delay_; } int16 get_secondary_weapon_delay() { std::lock_guard lk(classMutex); return secondary_weapon_delay_; } int16 get_ranged_weapon_delay() { std::lock_guard lk(classMutex); return ranged_weapon_delay_; } - + int8 get_override_primary_weapon() { std::lock_guard lk(classMutex); return override_primary_weapon_; } int8 get_override_secondary_weapon() { std::lock_guard lk(classMutex); return override_secondary_weapon_; } int8 get_override_ranged_weapon() { std::lock_guard lk(classMutex); return override_ranged_weapon_; } - + int8 get_friendly_target_npc() { std::lock_guard lk(classMutex); return friendly_target_npc_; } int32 get_last_claim_time() { std::lock_guard lk(classMutex); return last_claim_time_; } - + int8 get_engaged_encounter() { std::lock_guard lk(classMutex); return engaged_encounter_; } int8 get_lockable_encounter() { std::lock_guard lk(classMutex); return lockable_encounter_; } - + int8 get_first_world_login() { std::lock_guard lk(classMutex); return first_world_login_; } - + int8 get_reload_player_spells() { std::lock_guard lk(classMutex); return reload_player_spells_; } - + int8 get_group_loot_method() { std::lock_guard lk(classMutex); return group_loot_method_; } int8 get_group_loot_items_rarity() { std::lock_guard lk(classMutex); return group_loot_items_rarity_; } int8 get_group_auto_split() { std::lock_guard lk(classMutex); return group_auto_split_; } @@ -754,18 +754,18 @@ struct InfoStruct{ int8 get_group_solo_autolock() { std::lock_guard lk(classMutex); return group_solo_autolock_; } int8 get_group_auto_loot_method() { std::lock_guard lk(classMutex); return group_auto_loot_method_; } int8 get_assist_auto_attack() { std::lock_guard lk(classMutex); return assist_auto_attack_; } - + std::string get_action_state() { std::lock_guard lk(classMutex); return action_state_; } - + std::string get_combat_action_state() { std::lock_guard lk(classMutex); return combat_action_state_; } - + float get_max_spell_reduction() { std::lock_guard lk(classMutex); return max_spell_reduction_; } int8 get_max_spell_reduction_override() { std::lock_guard lk(classMutex); return max_spell_reduction_override_; } - + float get_max_chase_distance() { std::lock_guard lk(classMutex); return max_chase_distance_; } - + void set_name(std::string value) { std::lock_guard lk(classMutex); name_ = value; } - + void set_deity(std::string value) { std::lock_guard lk(classMutex); deity_ = value; } void set_class1(int8 value) { std::lock_guard lk(classMutex); class1_ = value; } @@ -910,11 +910,11 @@ struct InfoStruct{ void set_status_points(int32 value) { std::lock_guard lk(classMutex); status_points_ = value; } void add_status_points(int32 value) { std::lock_guard lk(classMutex); if((sint64)status_points_ + value < 0) status_points_ = 0; else status_points_ += value; } bool subtract_status_points(int32 value) { std::lock_guard lk(classMutex); if(value > status_points_) return false; status_points_ -= value; return true; } - + void set_mitigation_skill1(int16 value) { std::lock_guard lk(classMutex); mitigation_skill1_ = value; } void set_mitigation_skill2(int16 value) { std::lock_guard lk(classMutex); mitigation_skill2_ = value; } void set_mitigation_skill3(int16 value) { std::lock_guard lk(classMutex); mitigation_skill3_ = value; } - + void set_mitigation_pve(int16 value) { std::lock_guard lk(classMutex); mitigation_pve_ = value; } void set_mitigation_pvp(int16 value) { std::lock_guard lk(classMutex); mitigation_pvp_ = value; } @@ -956,13 +956,13 @@ struct InfoStruct{ void set_strikethrough(float value) { std::lock_guard lk(classMutex); strikethrough_ = value; } void set_accuracy(float value) { std::lock_guard lk(classMutex); accuracy_ = value; } void set_offensivespeed(float value) { std::lock_guard lk(classMutex); offensivespeed_ = value; } - + // crash client if float values above 1.0 are sent void set_rain(float value) { std::lock_guard lk(classMutex); if(value > 1.0f) value = 1.0f; else if(value < 0.0f) value = 0.0f; rain_ = value; } void set_wind(float value) { std::lock_guard lk(classMutex); if(value > 1.0f) value = 1.0f; else if(value < 0.0f) value = 0.0f; wind_ = value; } void set_max_chase_distance(float value) { std::lock_guard lk(classMutex); max_chase_distance_ = value; } - + void add_block_chance(float value) { std::lock_guard lk(classMutex); if(block_chance_ + value < 0.0f) block_chance_ = 0.0f; else block_chance_ += value; } void add_uncontested_parry(float value) { std::lock_guard lk(classMutex); if(uncontested_parry_ + value < 0.0f) uncontested_parry_ = 0.0f; else uncontested_parry_ += value; } void add_uncontested_block(float value) { std::lock_guard lk(classMutex); if(uncontested_block_ + value < 0.0f) uncontested_block_ = 0.0f; else uncontested_block_ += value; } @@ -1005,11 +1005,11 @@ struct InfoStruct{ void set_max_weight(int32 value) { std::lock_guard lk(classMutex); max_weight_ = value; } void set_vision(int32 value) { std::lock_guard lk(classMutex); vision_ = value; } - + void set_redlight(int32 value) { std::lock_guard lk(classMutex); redlight_ = value; } void set_greenlight(int32 value) { std::lock_guard lk(classMutex); greenlight_ = value; } void set_bluelight(int32 value) { std::lock_guard lk(classMutex); bluelight_ = value; } - + void set_breathe_underwater(int8 value) { std::lock_guard lk(classMutex); breathe_underwater_ = value; } void set_drunk(float value) { std::lock_guard lk(classMutex); drunk_ = value; } @@ -1033,7 +1033,7 @@ struct InfoStruct{ void set_range_last_attack_time(int32 value) { std::lock_guard lk(classMutex); range_last_attack_time_ = value; } void set_primary_last_attack_time(int32 value) { std::lock_guard lk(classMutex); primary_last_attack_time_ = value; } void set_secondary_last_attack_time(int32 value) { std::lock_guard lk(classMutex); secondary_last_attack_time_ = value; } - + void set_primary_attack_delay(int16 value) { std::lock_guard lk(classMutex); primary_attack_delay_ = value; } void set_secondary_attack_delay(int16 value) { std::lock_guard lk(classMutex); secondary_attack_delay_ = value; } void set_ranged_attack_delay(int16 value) { std::lock_guard lk(classMutex); ranged_attack_delay_ = value; } @@ -1041,34 +1041,34 @@ struct InfoStruct{ void set_primary_weapon_type(int8 value) { std::lock_guard lk(classMutex); primary_weapon_type_ = value; } void set_secondary_weapon_type(int8 value) { std::lock_guard lk(classMutex); secondary_weapon_type_ = value; } void set_ranged_weapon_type(int8 value) { std::lock_guard lk(classMutex); ranged_weapon_type_ = value; } - + void set_primary_weapon_damage_low(int32 value) { std::lock_guard lk(classMutex); primary_weapon_damage_low_ = value; } void set_primary_weapon_damage_high(int32 value) { std::lock_guard lk(classMutex); primary_weapon_damage_high_ = value; } void set_secondary_weapon_damage_low(int32 value) { std::lock_guard lk(classMutex); secondary_weapon_damage_low_ = value; } void set_secondary_weapon_damage_high(int32 value) { std::lock_guard lk(classMutex); secondary_weapon_damage_high_ = value; } void set_ranged_weapon_damage_low(int32 value) { std::lock_guard lk(classMutex); ranged_weapon_damage_low_ = value; } void set_ranged_weapon_damage_high(int32 value) { std::lock_guard lk(classMutex); ranged_weapon_damage_high_ = value; } - + void set_wield_type(int8 value) { std::lock_guard lk(classMutex); wield_type_ = value; } void set_attack_type(int8 value) { std::lock_guard lk(classMutex); attack_type_ = value; } - + void set_primary_weapon_delay(int16 value) { std::lock_guard lk(classMutex); primary_weapon_delay_ = value; } void set_secondary_weapon_delay(int16 value) { std::lock_guard lk(classMutex); secondary_weapon_delay_ = value; } void set_ranged_weapon_delay(int16 value) { std::lock_guard lk(classMutex); ranged_weapon_delay_ = value; } - + void set_override_primary_weapon(int8 value) { std::lock_guard lk(classMutex); override_primary_weapon_ = value; } void set_override_secondary_weapon(int8 value) { std::lock_guard lk(classMutex); override_secondary_weapon_ = value; } void set_override_ranged_weapon(int8 value) { std::lock_guard lk(classMutex); override_ranged_weapon_ = value; } void set_friendly_target_npc(int8 value) { std::lock_guard lk(classMutex); friendly_target_npc_ = value; } void set_last_claim_time(int32 value) { std::lock_guard lk(classMutex); last_claim_time_ = value; } - + void set_engaged_encounter(int8 value) { std::lock_guard lk(classMutex); engaged_encounter_ = value; } void set_lockable_encounter(int8 value) { std::lock_guard lk(classMutex); lockable_encounter_ = value; } - + void set_first_world_login(int8 value) { std::lock_guard lk(classMutex); first_world_login_ = value; } - + void set_reload_player_spells(int8 value) { std::lock_guard lk(classMutex); reload_player_spells_ = value; } - + void set_group_loot_method(int8 value) { std::lock_guard lk(classMutex); if(value <= GroupLootMethod::METHOD_MAX_COUNT) group_loot_method_ = value; } void set_group_loot_items_rarity(int8 value) { std::lock_guard lk(classMutex); group_loot_items_rarity_ = value; } void set_group_auto_split(int8 value) { std::lock_guard lk(classMutex); group_auto_split_ = value; } @@ -1077,17 +1077,17 @@ struct InfoStruct{ void set_group_lock_method(int8 value) { std::lock_guard lk(classMutex); group_lock_method_ = value; } void set_group_solo_autolock(int8 value) { std::lock_guard lk(classMutex); group_solo_autolock_ = value; } void set_group_auto_loot_method(int8 value) { std::lock_guard lk(classMutex); group_auto_loot_method_ = value; } - + void set_assist_auto_attack(int8 value) { std::lock_guard lk(classMutex); assist_auto_attack_ = value; } void set_action_state(std::string value) { std::lock_guard lk(classMutex); action_state_ = value; } - + void set_combat_action_state(std::string value) { std::lock_guard lk(classMutex); combat_action_state_ = value; } - + void set_max_spell_reduction(float value) { std::lock_guard lk(classMutex); max_spell_reduction_ = value; } - + void set_max_spell_reduction_override(int8 value) { std::lock_guard lk(classMutex); max_spell_reduction_override_ = value; } - + void ResetEffects(Spawn* spawn) { for(int i=0;i<45;i++){ @@ -1099,8 +1099,8 @@ struct InfoStruct{ maintained_effects[i].spell = nullptr; } - spell_effects[i].icon = 0; - spell_effects[i].spell_id = 0xFFFFFFFF; + spell_effects[i].icon = 0; + spell_effects[i].spell_id = 0xFFFFFFFF; spell_effects[i].inherited_spell_id = 0; spell_effects[i].icon_backdrop = 0; spell_effects[i].tier = 0; @@ -1109,7 +1109,7 @@ struct InfoStruct{ spell_effects[i].spell = nullptr; } } - + // maintained via their own mutex SpellEffects spell_effects[45]; MaintainedEffects maintained_effects[30]; @@ -1129,7 +1129,7 @@ private: int16 effective_level_; int16 tradeskill_level_; int16 tradeskill_max_level_; - + int8 cur_concentration_; int8 max_concentration_; int8 max_concentration_base_; @@ -1187,7 +1187,7 @@ private: int32 bank_coin_silver_; int32 bank_coin_gold_; int32 bank_coin_plat_; - + int32 status_points_; std::string deity_; int32 weight_; @@ -1282,7 +1282,7 @@ private: int8 interaction_flag_; int8 tag1_; int16 mood_; - + int32 range_last_attack_time_; int32 primary_last_attack_time_; int32 secondary_last_attack_time_; @@ -1303,20 +1303,20 @@ private: int16 primary_weapon_delay_; int16 secondary_weapon_delay_; int16 ranged_weapon_delay_; - + int8 override_primary_weapon_; int8 override_secondary_weapon_; int8 override_ranged_weapon_; - + int8 friendly_target_npc_; int32 last_claim_time_; - + int8 engaged_encounter_; int8 lockable_encounter_; - + int8 first_world_login_; int8 reload_player_spells_; - + int8 group_loot_method_; int8 group_loot_items_rarity_; int8 group_auto_split_; @@ -1325,15 +1325,15 @@ private: int8 group_lock_method_; int8 group_solo_autolock_; int8 group_auto_loot_method_; - + int8 assist_auto_attack_; - + std::string action_state_; std::string combat_action_state_; - + float max_spell_reduction_; int8 max_spell_reduction_override_; - + float max_chase_distance_; }; @@ -1347,7 +1347,7 @@ struct WardInfo { int32 DamageAbsorptionPercentage; int32 DamageAbsorptionMaxHealthPercent; int32 RedirectDamagePercent; - + int32 LastRedirectDamage; int32 LastAbsorbedDamage; @@ -1355,9 +1355,9 @@ struct WardInfo { int32 MaxHitCount; bool AbsorbAllDamage; // damage is always absorbed, usually spells based on hits, when we pass damage in AddWard as 0 this will be set to true - + bool RoundTriggered; - + bool DeleteWard; // removal after process CheckWard while loop }; @@ -1458,7 +1458,7 @@ public: float CalculateBonusMod(); float CalculateDPSMultiplier(); float CalculateCastingSpeedMod(); - + InfoStruct* GetInfoStruct(); int16 GetStr(); @@ -1549,7 +1549,7 @@ public: bool IsDualWield(); bool BehindTarget(Spawn* target); bool FlankingTarget(Spawn* target); - + void GetWeaponDamage(Item* item, int32* low_damage, int32* high_damage); void ChangePrimaryWeapon(); void ChangeSecondaryWeapon(); @@ -1585,7 +1585,7 @@ public: bool EngagedInCombat(); virtual void InCombat(bool val); void RefreshRegen(bool override_ = false); - + bool IsCasting(); void IsCasting(bool val); void SetMount(int16 mount_id, int8 red = 0xFF, int8 green = 0xFF, int8 blue = 0xFF, bool setUpdateFlags = true) @@ -1615,7 +1615,7 @@ public: std::lock_guard lk(MEquipment); if(slot >= NUM_SLOTS) return; - + SetInfo(&equipment.equip_id[slot], type); SetInfo(&equipment.color[slot].red, red); SetInfo(&equipment.color[slot].green, green); @@ -1689,16 +1689,16 @@ public: } void SetSogaHairType(int16 new_val, bool setUpdateFlags = true){ SetInfo(&features.soga_hair_type, new_val, setUpdateFlags); - } + } void SetSogaFacialHairType(int16 new_val, bool setUpdateFlags = true){ SetInfo(&features.soga_hair_face_type, new_val, setUpdateFlags); - } + } void SetSogaChestType(int16 new_val, bool setUpdateFlags = true){ SetInfo(&features.soga_chest_type, new_val, setUpdateFlags); - } + } void SetSogaLegType(int16 new_val, bool setUpdateFlags = true){ SetInfo(&features.soga_legs_type, new_val, setUpdateFlags); - } + } void SetSkinColor(EQ2_Color color){ SetInfo(&features.skin_color, color); } @@ -1711,11 +1711,11 @@ public: void SetSogaModelColor(EQ2_Color color){ SetInfo(&features.soga_model_color, color); } - void SetCombatVoice(int16 val, bool setUpdateFlags = true) { - SetInfo(&features.combat_voice, val, setUpdateFlags); + void SetCombatVoice(int16 val, bool setUpdateFlags = true) { + SetInfo(&features.combat_voice, val, setUpdateFlags); } - void SetEmoteVoice(int16 val, bool setUpdateFlags = true) { - SetInfo(&features.emote_voice, val, setUpdateFlags); + void SetEmoteVoice(int16 val, bool setUpdateFlags = true) { + SetInfo(&features.emote_voice, val, setUpdateFlags); } int16 GetCombatVoice(){ return features.combat_voice; } int16 GetEmoteVoice(){ return features.emote_voice; } @@ -1776,10 +1776,10 @@ public: } EQ2_Color* GetMountColor(){ return &features.mount_color; - } + } // should only be accessed through MEquipment mutex EQ2_Equipment equipment; - CharFeatures features; + CharFeatures features; void AddSpellBonus(LuaSpell* spell, int16 type, float value, int64 class_req =0, vector race_req = vector(), vector faction_req = vector()); BonusValues* GetSpellBonus(int32 spell_id); @@ -2017,7 +2017,7 @@ public: int32 CalculateFormulaByStat(int32 value, int16 stat); int32 CalculateFormulaBonus(int32 value, float percent_bonus); float CalculateSpellDamageReduction(float spellDamage, float resistancePercentage, int16 attackerLevel); - + float GetStat(int32 item_stat) { float item_chance_or_skill = 0.0f; MStats.lock(); @@ -2025,11 +2025,11 @@ public: MStats.unlock(); return item_chance_or_skill; } - + bool IsEngagedInEncounter(Spawn** res = nullptr); bool IsEngagedBySpawnID(int32 id); void SendControlEffectDetailsToClient(Client* client); - + std::string GetControlEffectName(int8 control_effect_type) { switch(control_effect_type) { case CONTROL_EFFECT_TYPE_MEZ: { @@ -2098,9 +2098,9 @@ public: } } } - + void TerminateTrade(); - + void CalculateMaxReduction(); // when PacketStruct is fixed for C++17 this should become a shared_mutex and handle read/write lock std::mutex MEquipment; @@ -2178,7 +2178,7 @@ private: map > get_sint32_funcs; map > get_sint16_funcs; map > get_sint8_funcs; - + map > get_string_funcs; // SETs @@ -2192,9 +2192,9 @@ private: map > set_sint32_funcs; map > set_sint16_funcs; map > set_sint8_funcs; - + map > set_string_funcs; - + mutable std::shared_mutex propertiesMutex; }; diff --git a/source/WorldServer/Factions.h b/source/WorldServer/Factions.h index 0e22032..f89fea9 100644 --- a/source/WorldServer/Factions.h +++ b/source/WorldServer/Factions.h @@ -4,7 +4,7 @@ #define EQ2_FACTIONS #include "../common/ConfigReader.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" struct Faction { int32 id; @@ -119,4 +119,3 @@ private: map faction_percent; }; #endif - diff --git a/source/WorldServer/GroundSpawn.h b/source/WorldServer/GroundSpawn.h index 04c6182..3dc9148 100644 --- a/source/WorldServer/GroundSpawn.h +++ b/source/WorldServer/GroundSpawn.h @@ -5,7 +5,7 @@ #include "Spawn.h" #include "client.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" class GroundSpawn : public Spawn { public: @@ -53,7 +53,7 @@ public: string GetHarvestSpellType(); string GetHarvestSpellName(); void HandleUse(Client* client, string type); - + void SetRandomizeHeading(bool val) { randomize_heading = val; } bool GetRandomizeHeading() { return randomize_heading; } private: @@ -66,4 +66,3 @@ private: bool randomize_heading; }; #endif - diff --git a/source/WorldServer/Guilds/Guild.h b/source/WorldServer/Guilds/Guild.h index d1a11b9..2daf356 100644 --- a/source/WorldServer/Guilds/Guild.h +++ b/source/WorldServer/Guilds/Guild.h @@ -7,7 +7,7 @@ #include #include #include -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../MutexMap.h" using namespace std; diff --git a/source/WorldServer/LoginServer.h b/source/WorldServer/LoginServer.h index 6d20b0e..334f71c 100644 --- a/source/WorldServer/LoginServer.h +++ b/source/WorldServer/LoginServer.h @@ -7,7 +7,7 @@ #include "../common/linked_list.h" #include "../common/timer.h" #include "../common/queue.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "../common/TCPConnection.h" #include #include "MutexMap.h" diff --git a/source/WorldServer/LuaInterface.h b/source/WorldServer/LuaInterface.h index 80526b9..ed015de 100644 --- a/source/WorldServer/LuaInterface.h +++ b/source/WorldServer/LuaInterface.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net) @@ -27,7 +27,7 @@ #include "Spawn.h" #include "Spells.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "Quests.h" #include "zoneserver.h" #include "client.h" @@ -123,17 +123,17 @@ struct LuaSpell{ ZoneServer* zone; int16 initial_caster_level; bool is_loaded_recast; - - std::unordered_set modified_fields; + + std::unordered_set modified_fields; mutable std::shared_mutex spell_modify_mutex; - + void AddTarget(int32 target_id) { std::unique_lock lock(targets_mutex); bool hasTarget = std::find(targets.begin(), targets.end(), target_id) != targets.end(); if(!hasTarget) targets.push_back(target_id); } - + int32 GetPrimaryTargetID() const { std::shared_lock lock(targets_mutex); return targets.empty() ? -1 : targets[0]; @@ -151,22 +151,22 @@ struct LuaSpell{ std::shared_lock lock(targets_mutex); return targets; } - + bool HasNoTargets() const { std::shared_lock lock(targets_mutex); return targets.empty(); } - + int32 GetTargetCount() const { std::shared_lock lock(targets_mutex); return static_cast(targets.size()); } - + bool HasTarget(int32 id) const { std::shared_lock lock(targets_mutex); return std::find(targets.begin(), targets.end(), id) != targets.end(); } - + bool HasAnyTarget(const std::vector& ids) const { std::shared_lock lock(targets_mutex); return std::any_of( @@ -188,12 +188,12 @@ struct LuaSpell{ v.erase(std::remove(v.begin(), v.end(), target_id), v.end()); removed_targets.push_back(target_id); } - + void AddRemoveTarget(int32 target_id) { std::unique_lock lock(targets_mutex); removed_targets.push_back(target_id); } - + void SwapTargets(std::vector& new_targets) { std::unique_lock lock(targets_mutex); targets.swap(new_targets); @@ -204,15 +204,15 @@ struct LuaSpell{ targets.clear(); removed_targets.clear(); } - + std::multimap GetCharIDTargets() const { std::shared_lock lock(char_id_targets_mutex); return char_id_targets; } - + void AddCharIDTarget(int32 char_id, int8 value) { std::unique_lock lock(char_id_targets_mutex); - + bool exists = false; auto range = char_id_targets.equal_range(char_id); for (auto it = range.first; it != range.second; ++it) { @@ -221,7 +221,7 @@ struct LuaSpell{ break; } } - + if(!exists) char_id_targets.insert({char_id, value}); } @@ -230,7 +230,7 @@ struct LuaSpell{ std::shared_lock lock(char_id_targets_mutex); return char_id_targets.empty(); } - + void RemoveCharIDTarget(int32 char_id) { std::unique_lock lock(char_id_targets_mutex); char_id_targets.erase(char_id); // removes all entries with that key @@ -252,7 +252,7 @@ struct LuaSpell{ std::unique_lock lock(char_id_targets_mutex); char_id_targets.clear(); } - + void MarkFieldModified(const std::string& field) { std::unique_lock lock(spell_modify_mutex); modified_fields.insert(field); @@ -267,12 +267,12 @@ struct LuaSpell{ std::unique_lock lock(spell_modify_mutex); modified_fields.clear(); } - + std::unordered_set GetModifiedFieldsCopy() const { std::shared_lock lock(spell_modify_mutex); return modified_fields; // safe shallow copy } - + bool SetSpellDataGeneric(const std::string& field, int value) { return SetSpellDataGeneric(field, std::to_string(value)); } @@ -284,7 +284,7 @@ struct LuaSpell{ bool SetSpellDataGeneric(const std::string& field, bool value) { return SetSpellDataGeneric(field, value ? "1" : "0"); } - + bool SetSpellDataGeneric(const std::string& field, const std::string& value) { auto it = SpellFieldGenericSetters.find(field); if (it == SpellFieldGenericSetters.end()) @@ -296,9 +296,9 @@ struct LuaSpell{ it->second(spell, value); return true; } - + bool SetSpellDataIndex(int idx, const std::string& value, const std::string& value2 = ""); - + bool SetSpellDataIndex(int idx, int value, int value2) { return SetSpellDataIndex(idx, std::to_string(value), std::to_string(value2)); } @@ -450,7 +450,7 @@ public: Skill* GetSkill(lua_State* state, int8 arg_num = 1); LuaSpell* GetSpell(lua_State* state, int8 arg_num = 1); vector* GetConversation(lua_State* state, int8 arg_num = 1); - + vector* GetOptionWindow(lua_State* state, int8 arg_num = 1); int8 GetInt8Value(lua_State* state, int8 arg_num = 1); int16 GetInt16Value(lua_State* state, int8 arg_num = 1); @@ -497,7 +497,7 @@ public: lua_State* GetRegionScript(const char* name, bool create_new = true, bool use = false); LuaSpell* GetSpellScript(const char* name, bool create_new = true, bool use = true); LuaSpell* CreateSpellScript(const char* name, lua_State* existState); - + Quest* LoadQuest(int32 id, const char* name, const char* type, const char* zone, int8 level, const char* description, char* script_name); const char* GetScriptName(lua_State* state); @@ -547,7 +547,7 @@ public: void SetLuaSystemReloading(bool val) { lua_system_reloading = val; } bool IsLuaSystemReloading() { return lua_system_reloading; } - + void AddPendingSpellDelete(LuaSpell* spell); void AddCustomSpell(LuaSpell* spell); @@ -558,10 +558,10 @@ public: LuaSpell* FindCustomSpell(int32 id); int32 GetFreeCustomSpellID(); - + void SetLuaUserDataStale(void* ptr); bool IsLuaUserDataValid(void* ptr); - + private: bool shutting_down; bool lua_system_reloading; @@ -615,7 +615,7 @@ private: Mutex MCustomSpell; Mutex MRegionScripts; Mutex MSpellScripts; - + mutable std::shared_mutex MLUAUserData; }; #endif diff --git a/source/WorldServer/MutexHelper.h b/source/WorldServer/MutexHelper.h index 455021b..b2e9a11 100644 --- a/source/WorldServer/MutexHelper.h +++ b/source/WorldServer/MutexHelper.h @@ -4,12 +4,12 @@ #define MUTEXHELPER_H #include "../common/timer.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include #include template -class IsPointer { +class IsPointer { public: static bool ValidPointer(T key){ return false; @@ -74,7 +74,7 @@ private: }; template -class IsPointer { +class IsPointer { public: static bool ValidPointer(T* key){ return true; @@ -117,7 +117,7 @@ private: int type; KeyT key; ValueT value; - unsigned int time; + unsigned int time; }; template @@ -149,7 +149,7 @@ public: Sleep(1); } if(has_pending_deletes && (force || (Timer::GetCurrentTime2() > next_delete_attempt && access_count == 0))){ - changing = true; + changing = true; while(access_count > 0){ Sleep(1); } @@ -179,7 +179,7 @@ private: volatile bool changing; volatile int access_count; volatile unsigned int next_delete_attempt; - volatile bool has_pending_deletes; + volatile bool has_pending_deletes; std::map pending_deletes; }; #endif diff --git a/source/WorldServer/Recipes/Recipe.h b/source/WorldServer/Recipes/Recipe.h index 596e3fc..fb97ad9 100644 --- a/source/WorldServer/Recipes/Recipe.h +++ b/source/WorldServer/Recipes/Recipe.h @@ -21,7 +21,7 @@ #define RECIPE_H_ #include "../../common/types.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../classes.h" #include @@ -34,7 +34,7 @@ struct RecipeComp { int32 RecipeComp; - + }; struct RecipeProducts { int32 product_id; @@ -107,7 +107,7 @@ public: bool CanUseRecipeByClass(Item* item, int8 class_id) { /* any can use bit combination of 1+2 adornments = 1 - artisan = 2 + artisan = 2 */ return item->generic_info.tradeskill_classes < 4 || (1 << class_id) & item->generic_info.tradeskill_classes; } @@ -137,7 +137,7 @@ public: ///Item id of the component ///Slot id for this component void AddBuildComp(int32 itemID, int8 slot, bool preferred = 0); - + // int8 = slot, vector = itemid map > components; @@ -146,7 +146,7 @@ public: int8 GetHighestStage() { return highestStage; } void SetHighestStage(int8 val) { highestStage = val; } - + int8 GetTotalBuildComponents(); bool ProvidedAllRequiredComponents(Client* client, vector* player_components, vector>* player_component_pair_qty); bool PlayerHasComponentByItemID(Client* client, vector* player_components, vector>* player_component_pair_qty, int32 item_id, int8 required_qty); @@ -189,7 +189,7 @@ private: int16 fuel_comp_qty; int16 primary_comp_qty; int8 highestStage; - + }; class MasterRecipeList { @@ -203,12 +203,12 @@ public: void ClearRecipes(); int32 Size(); EQ2Packet* GetRecipePacket(int32 recipe_id, Client *client = 0, bool display = false, int8 packet_type = 0); - + /// Gets all the recipes for the given book name /// Book name to get recipes for /// A vector of all the recipes for the given book vector GetRecipes(const char* book_name); - + /// Gets a recipe with the given name /// The name of the recipe to get /// Recipe* whos name matches the given name diff --git a/source/WorldServer/Rules/Rules.h b/source/WorldServer/Rules/Rules.h index de6e937..9f72919 100644 --- a/source/WorldServer/Rules/Rules.h +++ b/source/WorldServer/Rules/Rules.h @@ -22,7 +22,7 @@ #include #include -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../../common/types.h" using namespace std; @@ -213,7 +213,7 @@ enum RuleType { UseMapUnderworldCoords, MapUnderworldCoordOffset, SharedZoneMaxPlayers, - + /* LOOT */ LootRadius, AutoDisarmChest, // if enabled disarm only works if you right click and disarm, clicking and opening chest won't attempt auto disarm @@ -222,7 +222,7 @@ enum RuleType { AllowChestUnlockByDropTime, ChestUnlockedTimeTrap, AllowChestUnlockByTrapTime, - + /* SPELLS */ NoInterruptBaseChance, EnableFizzleSpells, @@ -367,4 +367,4 @@ private: map zone_rule_sets; /* references to a zone's rule set. map */ }; -#endif \ No newline at end of file +#endif diff --git a/source/WorldServer/Spawn.h b/source/WorldServer/Spawn.h index ee31e81..5582b97 100644 --- a/source/WorldServer/Spawn.h +++ b/source/WorldServer/Spawn.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net) @@ -38,7 +38,7 @@ #include "Zone/map.h" #include "Zone/region_map.h" #include "Zone/region_map_v1.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "MutexList.h" #include #include // needed for LS to compile properly on linux @@ -59,7 +59,7 @@ #define DAMAGE_PACKET_TYPE_RANGE_SPELL_DMG2 0xEA #define DAMAGE_PACKET_RESULT_NO_DAMAGE 0 -#define DAMAGE_PACKET_RESULT_SUCCESSFUL 1 +#define DAMAGE_PACKET_RESULT_SUCCESSFUL 1 #define DAMAGE_PACKET_RESULT_MISS 4 #define DAMAGE_PACKET_RESULT_DODGE 8 #define DAMAGE_PACKET_RESULT_PARRY 12 @@ -426,8 +426,8 @@ public: void SetEmoteState(int8 new_val, bool updateFlags = true){ SetInfo(&appearance.emote_state, new_val, updateFlags); } - void SetName(const char* new_name, bool updateFlags = true){ - SetInfo(appearance.name, new_name, updateFlags); + void SetName(const char* new_name, bool updateFlags = true){ + SetInfo(appearance.name, new_name, updateFlags); } void SetPrefixTitle(const char* new_prefix_title, bool updateFlags = true) { SetInfo(appearance.prefix_title, new_prefix_title, updateFlags); @@ -441,14 +441,14 @@ public: void SetLastName(const char* new_last_name, bool updateFlags = true) { SetInfo(appearance.last_name, new_last_name, updateFlags); } - void SetAdventureClass(int8 new_class, bool updateFlags = true) { - SetInfo(&appearance.adventure_class, new_class, updateFlags); + void SetAdventureClass(int8 new_class, bool updateFlags = true) { + SetInfo(&appearance.adventure_class, new_class, updateFlags); } - void SetTradeskillClass(int8 new_class, bool updateFlags = true) { - SetInfo(&appearance.tradeskill_class, new_class, updateFlags); + void SetTradeskillClass(int8 new_class, bool updateFlags = true) { + SetInfo(&appearance.tradeskill_class, new_class, updateFlags); } - void SetSize(int16 new_size, bool updateFlags = true) { - SetPos(&size, new_size, updateFlags); + void SetSize(int16 new_size, bool updateFlags = true) { + SetPos(&size, new_size, updateFlags); } void SetSpeedX(float speed_x, bool updateFlags = true) { SetPos(&appearance.pos.SpeedX, speed_x, updateFlags); @@ -459,14 +459,14 @@ public: void SetSpeedZ(float speed_z, bool updateFlags = true) { SetPos(&appearance.pos.SpeedZ, speed_z, updateFlags); } - void SetX(float x, bool updateFlags = true){ - SetPos(&appearance.pos.X, x, updateFlags); + void SetX(float x, bool updateFlags = true){ + SetPos(&appearance.pos.X, x, updateFlags); } void SetY(float y, bool updateFlags = true, bool disableYMapFix = false); - void SetZ(float z, bool updateFlags = true){ + void SetZ(float z, bool updateFlags = true){ SetPos(&appearance.pos.Z, z, updateFlags); } - void SetHeading(sint16 dir1, sint16 dir2, bool updateFlags = true){ + void SetHeading(sint16 dir1, sint16 dir2, bool updateFlags = true){ SetPos(&appearance.pos.Dir1, dir1, false); // we set the update for heading on the second direction do not duplicate the process SetPos(&appearance.pos.Dir2, dir2, updateFlags); } @@ -500,22 +500,22 @@ public: roll = (roll - 180) * 64; SetPos(&appearance.pos.Roll, (sint16)roll, updateFlags); } - void SetVisualState(int16 state, bool updateFlags = true){ + void SetVisualState(int16 state, bool updateFlags = true){ SetInfo(&appearance.visual_state, state, updateFlags); } - void SetActionState(int16 state, bool updateFlags = true){ + void SetActionState(int16 state, bool updateFlags = true){ SetInfo(&appearance.action_state, state, updateFlags); } - void SetMoodState(int16 state, bool updateFlags = true){ + void SetMoodState(int16 state, bool updateFlags = true){ SetInfo(&appearance.mood_state, state, updateFlags); } - void SetInitialState(int16 state, bool updateFlags = true){ + void SetInitialState(int16 state, bool updateFlags = true){ SetPos(&appearance.pos.state, state, updateFlags); } - void SetActivityStatus(int16 state, bool updateFlags = true){ + void SetActivityStatus(int16 state, bool updateFlags = true){ SetInfo(&appearance.activity_status, state, updateFlags); } - void SetCollisionRadius(int32 radius, bool updateFlags = true){ + void SetCollisionRadius(int32 radius, bool updateFlags = true){ SetPos(&appearance.pos.collision_radius, radius, updateFlags); } int16 GetCollisionRadius(){ @@ -550,10 +550,10 @@ public: } virtual void SetLevel(int16 level, bool setUpdateFlags = true){ SetInfo(&appearance.level, level, setUpdateFlags); - } + } void SetTSLevel(int16 tradeskill_level, bool setUpdateFlags = true){ SetInfo(&appearance.tradeskill_level, tradeskill_level, setUpdateFlags); - } + } void SetGender(int8 gender, bool setUpdateFlags = true){ SetInfo(&appearance.gender, gender, setUpdateFlags); } @@ -571,7 +571,7 @@ public: } void SetShowCommandIcon(int8 new_val, bool setUpdateFlags = true){ SetVis(&appearance.show_command_icon, new_val, setUpdateFlags); - } + } void SetShowHandIcon(int8 new_val, bool setUpdateFlags = true){ SetVis(&appearance.display_hand_icon, new_val, setUpdateFlags); } @@ -641,7 +641,7 @@ public: int8 GetShowCommandIcon(){ return appearance.show_command_icon; } - char* GetName(){ + char* GetName(){ return appearance.name; } char* GetPrefixTitle(){ @@ -656,11 +656,11 @@ public: char* GetLastName() { return appearance.last_name; } - int8 GetAdventureClass() { - return appearance.adventure_class; + int8 GetAdventureClass() { + return appearance.adventure_class; } - int8 GetTradeskillClass() { - return appearance.tradeskill_class; + int8 GetTradeskillClass() { + return appearance.tradeskill_class; } float GetDestinationX(){ return appearance.pos.X2; @@ -680,14 +680,14 @@ public: float GetDestinationY(){ return appearance.pos.Y2; } - float GetY(){ - return appearance.pos.Y; + float GetY(){ + return appearance.pos.Y; } float GetDestinationZ(){ return appearance.pos.Z2; } - float GetZ(){ - return appearance.pos.Z; + float GetZ(){ + return appearance.pos.Z; } float GetHeading(){ float heading = 0; @@ -698,7 +698,7 @@ public: else heading += 180; } - return heading; + return heading; } float GetPitch(){ float pitch = 0; @@ -709,7 +709,7 @@ public: else pitch += 180; } - return pitch; + return pitch; } float GetRoll(){ float roll = 0; @@ -720,7 +720,7 @@ public: else roll += 180; } - return roll; + return roll; } int32 GetID(){ return id; @@ -745,7 +745,7 @@ public: sint32 GetTotalPowerBaseInstance(); float GetHPRatio() { return GetHP() == 0 || GetTotalHP() == 0 ? 0 : ((float) GetHP() / GetTotalHP() * 100); } int GetIntHPRatio() { return GetTotalHP() == 0 ? 0 : static_cast(GetHPRatio()); } - + sint32 GetTotalSavagery(); sint32 GetSavagery(); sint32 GetTotalDissonance(); @@ -794,7 +794,7 @@ public: bool Alive(){ return is_alive; } void SetAlive(bool val) { is_alive = val; } - + int16 GetLevel(){ return appearance.level; } @@ -867,7 +867,7 @@ public: int16 GetModelType(){ return appearance.model_type; } - + bool IsFlyingCreature(); bool IsWaterCreature(); bool InWater(); @@ -875,7 +875,7 @@ public: void SetFlyingCreature(); void SetWaterCreature(); - + void SetPrimaryCommand(const char* name, const char* command, float distance = 10); void SetPrimaryCommands(vector* commands); void SetSecondaryCommands(vector* commands); @@ -905,7 +905,7 @@ public: virtual bool IsBot() { return false; } bool HasInfoChanged(){ return info_changed; } - bool HasPositionChanged(){ return position_changed; } + bool HasPositionChanged(){ return position_changed; } bool HasTarget(){ return target ? true : false; } int32 GetRespawnTime(); @@ -946,7 +946,7 @@ public: void SetTrapTriggered(bool triggered, int32 state) { if(!trap_triggered && triggered) trap_opened_time = Timer::GetCurrentTime2(); - + trap_triggered = triggered; trap_state = state; } @@ -1015,10 +1015,10 @@ public: MLootItems.lock(); loot_item_count = loot_items.size(); MLootItems.unlock(); - + return loot_item_count; } - + void ClearNonBodyLoot() { MLootItems.lock(); @@ -1035,7 +1035,7 @@ public: } MLootItems.unlock(); } - + int32 GetLootCoins() { LockLoot(); int32 coins = loot_coins; @@ -1045,9 +1045,9 @@ public: void SetLootCoins(int32 val, bool lockloot = true) { if(lockloot) LockLoot(); - + loot_coins = val; - + if(lockloot) UnlockLoot(); } @@ -1078,7 +1078,7 @@ public: id_lock.unlock(); return NextID(); } - + id_lock.unlock(); return ret; } @@ -1102,7 +1102,7 @@ public: void UpdateEncounterState(int8 new_state); void CheckEncounterState(Entity* victim, bool test_auto_lock = false); void AddTargetToEncounter(Entity* entity); - + void SendSpawnChanges(bool val){ send_spawn_changes = val; } void SetSpawnGroupID(int32 id); int32 GetSpawnGroupID(); @@ -1158,7 +1158,7 @@ public: bool IsRunning(); void CalculateRunningLocation(bool stop = false); void RunToLocation(float x, float y, float z, float following_x = 0, float following_y = 0, float following_z = 0); - + MovementLocation* GetCurrentRunningLocation(); MovementLocation* GetLastRunningLocation(); void NewWaypointChange(MovementLocation* data); @@ -1174,7 +1174,7 @@ public: bool NeedsToResumeMovement(){ return attack_resume_needed; } void NeedsToResumeMovement(bool val) { attack_resume_needed = val; } bool HasMovementLoop(){ return movement_loop.size() > 0; } - bool HasMovementLocations() { + bool HasMovementLocations() { bool hasLocations = false; MMovementLocations.lock_shared(); hasLocations = movement_locations ? movement_locations->size() > 0 : false; @@ -1216,7 +1216,7 @@ public: bool is_water_creature; bool is_flying_creature; int32 trigger_widget_id; - + std::atomic following; bool IsPet() { return is_pet; } void SetPet(bool val) { is_pet = val; } @@ -1324,7 +1324,7 @@ public: { pickup_unique_item_id = uniqueid; } - + void SetHouseCharacterID(int32 charid) { house_character_id = charid; @@ -1340,11 +1340,11 @@ public: RegionMap* GetRegionMap() { return region_map; } Map* GetMap() { return current_map; } std::map established_grid_id; - + void DeleteRegion(Region_Node* inNode, ZBSP_Node* rootNode); bool InRegion(Region_Node* inNode, ZBSP_Node* rootNode); int32 GetRegionType(Region_Node* inNode, ZBSP_Node* rootNode); - + float SpawnAngle(Spawn* target, float selfx, float selfz); bool BehindSpawn(Spawn *target, float selfx, float selfz) { return (!target || target == this) ? false : SpawnAngle(target, selfx, selfz) > 90.0f; } @@ -1361,7 +1361,7 @@ public: virtual bool IsPauseMovementTimerActive(); bool IsTransportSpawn() { return is_transport_spawn; } void SetTransportSpawn(bool val) { is_transport_spawn = val; } - + sint64 GetRailID() { return rail_id; } void SetRailID(sint64 val) { rail_id = val; } void AddRailPassenger(int32 char_id); @@ -1375,23 +1375,23 @@ public: int32 GetLootTier() { return loot_tier; } void SetLootTier(int32 tier) { loot_tier = tier; } - + int32 GetLootDropType() { return loot_drop_type; } void SetLootDropType(int32 type) { loot_drop_type = type; } void SetDeletedSpawn(bool val) { deleted_spawn = val; } bool IsDeletedSpawn() { return deleted_spawn; } - - + + int32 InsertRegionToSpawn(Region_Node* node, ZBSP_Node* bsp_root, WaterRegionType regionType, bool in_region = true); bool HasRegionTracked(Region_Node* node, ZBSP_Node* bsp_root, bool in_region); - + int8 GetArrowColor(int8 spawn_level); - + void AddIgnoredWidget(int32 id); - + void SendGroupUpdate(); - + void OverrideLootMethod(GroupLootMethod newMethod) { loot_method = newMethod; } void SetLootMethod(GroupLootMethod method, int8 item_rarity = 0, int32 group_id = 0); int32 GetLootGroupID() { return loot_group_id; } @@ -1413,7 +1413,7 @@ public: void GetSpawnLottoEntries(int32 item_id, std::map* out_entries); void GetLootItemsList(std::vector* out_entries); void GetSpawnNeedGreedEntries(int32 item_id, bool need_item, std::map* out_entries); - + bool HasLootWindowCompleted(); bool IsLootWindowComplete() { return is_loot_complete; } void SetLootDispensed() { is_loot_dispensed = true; } @@ -1421,18 +1421,18 @@ public: std::map* GetLootWindowList() { return &loot_complete; } void StartLootTimer(Spawn* looter); void CloseLoot(Spawn* sender); - + void SetLootName(char* name) { if(name != nullptr) { - loot_name = std::string(name); + loot_name = std::string(name); } } - + const char* GetLootName() { return loot_name.c_str(); } - + bool IsItemInLootTier(Item* item); void DistributeGroupLoot_RoundRobin(std::vector* item_list, bool roundRobinTrashLoot = false); // trash loot is what falls under the item tier requirement by group options - + void CalculateInitialVelocity(float heading, float distanceHorizontal, float distanceVertical, float distanceDepth, float duration); glm::vec3 CalculateProjectilePosition(glm::vec3 initialVelocity, float time); bool CalculateSpawnProjectilePosition(float x, float y, float z); @@ -1441,10 +1441,10 @@ public: mutable std::shared_mutex MIgnoredWidgets; std::map ignored_widgets; - + EquipmentItemList equipment_list; EquipmentItemList appearance_equipment_list; - + protected: bool has_quests_required; @@ -1463,7 +1463,7 @@ protected: int32 movement_start_time; Mutex MMovementLoop; map allowed_access; - vector quest_ids; + vector quest_ids; int32 database_id; int32 packet_num; int32 target; @@ -1485,7 +1485,7 @@ protected: void CheckProximities(); Timer pause_timer; - + bool IsKnockedBack() { return knocked_back; } private: int32 loot_group_id; @@ -1497,12 +1497,12 @@ private: int32 loot_coins; std::multimap lotto_items; std::multimap> need_greed_items; - + std::map loot_complete; bool is_loot_complete; bool is_loot_dispensed; std::string loot_name; - + bool trap_triggered; int32 trap_state; int32 chest_drop_time; @@ -1590,8 +1590,7 @@ private: int32 knocked_back_end_time; float knocked_angle; glm::vec3 knocked_velocity; - + }; #endif - diff --git a/source/WorldServer/Spells.h b/source/WorldServer/Spells.h index c879002..1fd5cbe 100644 --- a/source/WorldServer/Spells.h +++ b/source/WorldServer/Spells.h @@ -11,7 +11,7 @@ #include "../common/MiscFunctions.h" #include "client.h" #include "classes.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "AltAdvancement/AltAdvancement.h" #include @@ -368,7 +368,7 @@ public: vector effects; vector lua_data; - + mutable std::shared_mutex MSpellInfo; private: bool stay_locked = false; @@ -380,7 +380,7 @@ private: bool copied_spell; SpellData* spell; - + //vector effects; vector levels; }; @@ -404,7 +404,7 @@ public: EQ2Packet* GetSpecialSpellPacket(int32 id, int8 tier, Client* client = 0, bool display = false, int8 packet_type = 0); void AddSpell(int32 id, int8 tier, Spell* spell); Mutex MMasterSpellList; - + /// Gets the correct spell error value for the given version /// Client version /// ID of the error @@ -417,13 +417,13 @@ public: /// Value for the error void AddSpellError(int16 version, int8 error_index, int16 error_value); - int32 GetNewMaxSpellID() { + int32 GetNewMaxSpellID() { int32 id = 0; MMasterSpellList.lock(); max_spell_id++; id = max_spell_id; MMasterSpellList.unlock(); - return id; + return id; } private: /// Helper function that gets the closest version in the spell_errors map that is less then or equal to the given version @@ -435,4 +435,3 @@ private: int32 max_spell_id; }; #endif - diff --git a/source/WorldServer/Titles.h b/source/WorldServer/Titles.h index 2ee43ee..6df35f4 100644 --- a/source/WorldServer/Titles.h +++ b/source/WorldServer/Titles.h @@ -6,7 +6,7 @@ #include #include #include -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "../common/types.h" using namespace std; @@ -25,7 +25,7 @@ public: const char* GetName() {return name;} int8 GetPrefix() {return prefix;} bool GetSaveNeeded() {return save_needed;} - + private: sint32 id; int8 prefix; @@ -63,4 +63,4 @@ private: vector player_titles_list; Mutex MPlayerTitleMutex; }; -#endif \ No newline at end of file +#endif diff --git a/source/WorldServer/Tradeskills/Tradeskills.h b/source/WorldServer/Tradeskills/Tradeskills.h index 6fe2cf6..4da4a99 100644 --- a/source/WorldServer/Tradeskills/Tradeskills.h +++ b/source/WorldServer/Tradeskills/Tradeskills.h @@ -4,7 +4,7 @@ #define __EQ2_TRADESKILLS__ #include "../../common/types.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../Items/Items.h" #include class Player; @@ -86,13 +86,13 @@ public: /// Function name that is releasing the lock /// Line number that is releasing the lock void ReleaseReadLock(const char* function = (const char*)0, int32 line = 0) { m_tradeskills.releasereadlock(function, line); } - + int32 GetTechniqueSuccessAnim(int16 version, int32 technique); int32 GetTechniqueFailureAnim(int16 version, int32 technique); int32 GetTechniqueIdleAnim(int16 version, int32 technique); int32 GetMissTargetAnim(int16 version); int32 GetKillMissTargetAnim(int16 version); - + void SetClientIdleVisualState(Client* client, Tradeskill* ts); private: /// Sends the creation window @@ -123,7 +123,7 @@ public: /// The skill id of the technique /// Vector of TradeskillEvent* for the given technique vector* GetEventByTechnique(int32 technique); - + /// Get the size of the event list /// int32 containing the size of the list int32 Size(); diff --git a/source/WorldServer/Traits/Traits.h b/source/WorldServer/Traits/Traits.h index 678a59c..111045c 100644 --- a/source/WorldServer/Traits/Traits.h +++ b/source/WorldServer/Traits/Traits.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) @@ -23,7 +23,7 @@ along with EQ2Emulator. If not, see . #include #include -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../../common/types.h" #include "../../common/EQPacket.h" @@ -56,14 +56,14 @@ class MasterTraitList public: MasterTraitList(); ~MasterTraitList(); - + bool IdentifyNextTrait(Client* client, map >* traitList, vector* collectTraits, vector* tieredTraits, std::map* previousMatchedSpells, bool omitFoundMatches = false); bool ChooseNextTrait(Client* client); int16 GetSpellCount(Client* client, map >* traits, bool onlyCharTraits = false); bool IsPlayerAllowedTrait(Client* client, TraitData* trait); bool GenerateTraitLists(Client* client, map > >* sortedTraitList, map >* classTraining, map >* raceTraits, map >* innateRaceTraits, map >* focusEffects, int16 max_level = 0, int8 trait_group = 255); - + /// Sorts the traits for the given client and creats and sends the trait packet. /// The Client calling this function /// EQ2Packet* @@ -79,7 +79,7 @@ public: /// Get the trait data for the given spell. /// Spell ID to get trait data for. TraitData* GetTrait(int32 spellID); - + /// Get the trait data for the given item. /// Item ID to map to the trait data. TraitData* GetTraitByItemID(int32 itemID); @@ -91,4 +91,4 @@ private: Mutex MMasterTraitList; }; -#endif \ No newline at end of file +#endif diff --git a/source/WorldServer/WorldDatabase.h b/source/WorldServer/WorldDatabase.h index 0ef5067..1be542f 100644 --- a/source/WorldServer/WorldDatabase.h +++ b/source/WorldServer/WorldDatabase.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net) @@ -34,7 +34,7 @@ #include "../common/database.h" #include "../common/types.h" #include "../common/MiscFunctions.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "../common/DatabaseNew.h" #include "client.h" #include "Object.h" @@ -272,7 +272,7 @@ public: bool SpawnGroupRemoveSpawn(Spawn* spawn, int32 group_id); int32 CreateSpawnGroup(Spawn* spawn, string name); void DeleteSpawnGroup(int32 id); - bool SetGroupSpawnChance(int32 id, float chance); + bool SetGroupSpawnChance(int32 id, float chance); void LoadGroundSpawnEntries(ZoneServer* zone); void LoadGroundSpawnItems(ZoneServer* zone); void LoadSpawns(ZoneServer* zone); @@ -385,15 +385,15 @@ public: int32 LoadQuests(); void LoadQuestDetails(Quest* quest); - + bool DeleteCharacter(int32 account_id, int32 character_id); int32 GetMaxHotBarID(); int8 CheckNameFilter(const char* name, int8 min_length = 4, int8 max_length = 15); - static int32 NextUniqueHotbarID(){ + static int32 NextUniqueHotbarID(){ next_id++; - return next_id; + return next_id; } void LoadFogInit(string zone, PacketStruct* packet); static int32 next_id; @@ -417,7 +417,7 @@ public: bool DeleteInstanceSpawnRemoved(int32 instance_id, int32 spawn_location_entry_id); bool DeleteCharacterFromInstance(int32 char_id, int32 instance_id); bool LoadCharacterInstances(Client* client); - + bool DeletePersistedRespawn(int32 zone_id, int32 spawn_location_entry_id); int32 CreatePersistedRespawn(int32 spawn_location_entry_id, int32 spawn_type, int32 respawn_time, int32 zone_id); map* GetPersistedSpawns(int32 zone_id, int8 type); @@ -465,7 +465,7 @@ public: void SavePlayerCollection(Client *client, Collection *collection); void SavePlayerCollectionItems(Client *client, Collection *collection); void SavePlayerCollectionItem(Client *client, Collection *collection, int32 item_id); - + /* Commands */ map* GetSpawnTemplateListByName(const char* name); map* GetSpawnTemplateListByID(int32 location_id); @@ -652,11 +652,11 @@ public: void LoadStartingSpells(World* world); void LoadVoiceOvers(World* world); - int32 CreateSpiritShard(const char* name, int32 level, int8 race, int8 gender, int8 adventure_class, + int32 CreateSpiritShard(const char* name, int32 level, int8 race, int8 gender, int8 adventure_class, int16 model_type, int16 soga_model_type, int16 hair_type, int16 hair_face_type, int16 wing_type, - int16 chest_type, int16 legs_type, int16 soga_hair_type, int16 soga_hair_face_type, int8 hide_hood, - int16 size, int16 collision_radius, int16 action_state, int16 visual_state, int16 mood_state, int16 emote_state, - int16 pos_state, int16 activity_status, char* sub_title, char* prefix_title, char* suffix_title, char* lastname, + int16 chest_type, int16 legs_type, int16 soga_hair_type, int16 soga_hair_face_type, int8 hide_hood, + int16 size, int16 collision_radius, int16 action_state, int16 visual_state, int16 mood_state, int16 emote_state, + int16 pos_state, int16 activity_status, char* sub_title, char* prefix_title, char* suffix_title, char* lastname, float x, float y, float z, float heading, int32 gridid, int32 charid, int32 zoneid, int32 instanceid); bool DeleteSpiritShard(int32 id); @@ -666,7 +666,7 @@ public: void LoadCharacterSpellEffects(int32 char_id, Client *client, int8 db_spell_type); int32 GetMysqlExpCurve(int level); - + bool RemoveBrokerItem(int32 cid, int64 uid, int32 quantity); int32 LoadBrokerSellers(BrokerManager &broker); int32 LoadBrokerItems(BrokerManager &broker); @@ -674,8 +674,8 @@ public: void ClearSellerSession(int32 character_id); void AddToSellerSession(int32 character_id, int64 amount); - int64 GetSellerSession(int32 character_id); - + int64 GetSellerSession(int32 character_id); + bool UpdateHouseSpawnScript(int32 dbid, std::string scriptName); private: DatabaseNew database_new; @@ -686,4 +686,3 @@ private: std::map zone_instance_types; }; #endif - diff --git a/source/WorldServer/Zone/ChestTrap.h b/source/WorldServer/Zone/ChestTrap.h index 9d4c9d3..645d00a 100644 --- a/source/WorldServer/Zone/ChestTrap.h +++ b/source/WorldServer/Zone/ChestTrap.h @@ -1,7 +1,7 @@ #include #include #include -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "../../common/types.h" #pragma once @@ -114,7 +114,7 @@ private: void SetupMutexes(); void InstantiateLists(bool parent); - + void shuffleMap(ChestTrapList* list); bool ChestTrapParent; diff --git a/source/WorldServer/Zone/map.h b/source/WorldServer/Zone/map.h index b6cdd92..92b9da5 100644 --- a/source/WorldServer/Zone/map.h +++ b/source/WorldServer/Zone/map.h @@ -24,7 +24,7 @@ #include "../../common/types.h" #include "../../common/MiscFunctions.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" #include "position.h" #include @@ -87,20 +87,20 @@ public: float GetMaxY() { return m_MaxY; } float GetMinZ() { return m_MinZ; } float GetMaxZ() { return m_MaxZ; } - + bool isPointWithinMap(double x, double y, double z, double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { return (x >= m_MinX && x <= m_MaxX && y >= m_MinY && y <= m_MaxY && z >= m_MinZ && z <= m_MaxZ); } void SetFileName(std::string newfile) { m_FileName = string(newfile); } - + void MapMinMaxY(float y); void MapGridMinMaxBorderArray(GridMapBorder* border, glm::vec3 a, glm::vec3 b, glm::vec3 c); void MapGridMinMaxBorder(GridMapBorder* border, glm::vec3 a); bool IsPointInGrid(GridMapBorder* border, glm::vec3 a, float radius); std::vector GetGridsByPoint(glm::vec3 a, float radius); GridMapBorder* GetMapGridBorder(int32 grid_id, bool instantiate_border = true); - + std::map widget_map; std::map grid_map_border; private: @@ -137,7 +137,7 @@ public: ~MapRange(); void Clear(); - + void AddVersionRange(std::string zoneName); map::iterator FindVersionRange(int32 min_version, int32 max_version); diff --git a/source/WorldServer/Zone/mob_movement_manager.h b/source/WorldServer/Zone/mob_movement_manager.h index 9520261..2889e77 100644 --- a/source/WorldServer/Zone/mob_movement_manager.h +++ b/source/WorldServer/Zone/mob_movement_manager.h @@ -1,7 +1,7 @@ #pragma once #include #include "../Entity.h" -#include "../../common/Mutex.h" +#include "../../common/mutex.h" class Mob; class Client; diff --git a/source/WorldServer/zoneserver.h b/source/WorldServer/zoneserver.h index 458da60..ea6e90d 100644 --- a/source/WorldServer/zoneserver.h +++ b/source/WorldServer/zoneserver.h @@ -1,4 +1,4 @@ -/* +/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2005 - 2026 EQ2EMulator Development Team (http://www.eq2emu.com formerly http://www.eq2emulator.net) @@ -30,7 +30,7 @@ #include "../common/servertalk.h" #include "../common/TCPConnection.h" #include "WorldTCPConnection.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "../common/DataBuffer.h" #include "net.h" #include "Player.h" @@ -279,7 +279,7 @@ class ZoneServer { public: ZoneServer(const char* file); ~ZoneServer(); - + void IncrementIncomingClients(); void DecrementIncomingClients(); void Init(); @@ -287,31 +287,31 @@ public: bool SpawnProcess(); ZoneInfoSlideStruct* GenerateSlideStruct(float unknown1a, float unknown1b, int32 unknown2a, int32 unknown2b, int32 unknown3, int32 unknown4, const char* slide, const char* voiceover, int32 key1, int32 key2); - void AddZoneInfoSlideStructTransitionInfo(ZoneInfoSlideStruct* info, int32 x, int32 y, float zoom, float transition_time); + void AddZoneInfoSlideStructTransitionInfo(ZoneInfoSlideStruct* info, int32 x, int32 y, float zoom, float transition_time); vector* GenerateTutorialSlides(); - + void LoadRevivePoints(vector* revive_points); vector* GetRevivePoints(Client* client); RevivePoint* GetRevivePoint(int32 id); void AddClient(Client* client); - + void SimpleMessage(int8 type, const char* message, Spawn* from, float distance, bool send_to_sender = true); void HandleChatMessage(Spawn* from, const char* to, int16 channel, const char* message, float distance = 0, const char* channel_name = 0, bool show_bubble = true, int32 language = 0); void HandleChatMessage(Client* client, Spawn* from, const char* to, int16 channel, const char* message, float distance = 0, const char* channel_name = 0, bool show_bubble = true, int32 language = 0); void HandleChatMessage(Client* client, std::string fromName, const char* to, int16 channel, const char* message, float distance = 0, const char* channel_name = 0, int32 language = 0); void HandleChatMessage(std::string fromName, const char* to, int16 channel, const char* message, float distance, const char* channel_name, int32 language); - + void HandleBroadcast(const char* message); void HandleAnnouncement(const char* message); - + int16 SetSpawnTargetable(Spawn* spawn, float distance); int16 SetSpawnTargetable(int32 spawn_id); void ApplySetSpawnCommand(Client* client, Spawn* target, int8 type, const char* value); void SetSpawnCommand(Spawn* spawn, int8 type, char* value, Client* client = 0); void SetSpawnCommand(int32 spawn_id, int8 type, char* value, Client* client = 0); void AddLoot(NPC* npc, Spawn* killer = nullptr, GroupLootMethod loot_method = GroupLootMethod::METHOD_FFA, int8 item_rarity = 0, int32 group_id = 0); - + NPC* AddNPCSpawn(SpawnLocation* spawnlocation, SpawnEntry* spawnentry); Object* AddObjectSpawn(SpawnLocation* spawnlocation, SpawnEntry* spawnentry); GroundSpawn* AddGroundSpawn(SpawnLocation* spawnlocation, SpawnEntry* spawnentry); @@ -320,16 +320,16 @@ public: void AddSpawn(Spawn* spawn); void RemoveDeadEnemyList(Spawn* spawn); void RemoveDeadSpawn(Spawn* spawn); - + void AddSpawnGroupLocation(int32 group_id, int32 location_id, int32 spawn_location_id); void AddSpawnGroupAssociation(int32 group_id1, int32 group_id2); - + void AddSpawnGroupChance(int32 group_id, float percent); - + void RemoveSpawn(Spawn* spawn, bool delete_spawn = true, bool respawn = true, bool lock = true, bool erase_from_spawn_list = true, bool lock_spell_process = false); void ProcessSpawnLocations(); void SendQuestUpdates(Client* client, Spawn* spawn = 0); - + EQ2Packet* GetZoneInfoPacket(Client* client); Spawn* FindSpawn(Player* searcher, const char* name); bool CallSpawnScript(Spawn* npc, int8 type, Spawn* spawn = 0, const char* message = 0, bool is_door_open = false, sint32 input_value = 0, sint32* return_value = 0); @@ -339,7 +339,7 @@ public: void HandleEmote(Spawn* originator, string name, Spawn* opt_target = nullptr, bool no_target = false); Spawn* GetSpawnByDatabaseID(int32 id); Spawn* GetSpawnByID(int32 id, bool spawnListLocked=false); - + void PlaySoundFile(Client* client, const char* name, float origin_x, float origin_y, float origin_z); void SendZoneSpawns(Client* client); void StartZoneInitialSpawnThread(Client* client); @@ -348,28 +348,28 @@ public: void SendSpawnChanges(Spawn* spawn, Client* client, bool override_changes = false, bool override_vis_changes = false); void SendSpawnChangesByDBID(int32 spawn_id, Client* client, bool override_changes = false, bool override_vis_changes = false); void SendPlayerPositionChanges(Player* player); - + void UpdateVitality(float amount); - + vector GetPlayers(); - + void KillSpawn(bool spawnListLocked, Spawn* dead, Spawn* killer, bool send_packet = true, int8 type = 0, int8 damage_type = 0, int16 kill_blow_type = 0); - + void SendDamagePacket(Spawn* attacker, Spawn* victim, int8 type1, int8 type2, int8 damage_type, int16 damage, const char* spell_name); void SendHealPacket(Spawn* caster, Spawn* target, int16 type, int32 heal_amt, const char* spell_name); - + void SendCastSpellPacket(LuaSpell* spell, Entity* caster, int32 spell_visual_override = 0, int16 casttime_override = 0xFFFF); void SendCastSpellPacket(int32 spell_visual, Spawn* target, Spawn* caster = 0); void SendCastEntityCommandPacket(EntityCommand* entity_command, int32 spawn_id, int32 target_id); void TriggerCharSheetTimer(); - + /// Sends the game time packet to all connected clients void SendTimeUpdateToAllClients(); void AddWidgetTimer(Spawn* widget, float time); bool HasWidgetTimer(Spawn* widget); - + void Despawn(Spawn* spawn, int32 timer); - + void RepopSpawns(Client* client, Spawn* spawn); bool AddCloseSpawnsToSpawnGroup(Spawn* spawn, float radius); void Depop(bool respawns = false, bool repop = false); @@ -377,19 +377,19 @@ public: Spawn* GetSpawnGroup(int32 id); bool IsSpawnGroupAlive(int32 id); void AddEnemyList(NPC* npc); - + void ReloadClientQuests(); void SendAllSpawnsForLevelChange(Client* client); void SendAllSpawnsForSeeInvisChange(Client* client); void SendAllSpawnsForVisChange(Client* client, bool limitToEntities=true); - + void AddLocationGrid(LocationGrid* grid); void RemoveLocationGrids(); void DeleteTransporters(); - + void CheckTransporters(Client* client); - + void WritePlayerStatistics(); bool SendRadiusSpawnInfo(Client* client, float radius); @@ -400,13 +400,13 @@ public: volatile int8 initial_spawn_threads_active; volatile bool client_thread_active; void AddChangedSpawn(Spawn* spawn); - + void AddDamagedSpawn(Spawn* spawn); - + void AddDrowningVictim(Player* player); void RemoveDrowningVictim(Player* player); Client* GetDrowningVictim(Player* player); - + void DeleteSpellProcess(); void LoadSpellProcess(); void LockAllSpells(Player* player); @@ -418,10 +418,10 @@ public: void ProcessEntityCommand(EntityCommand* entity_command, Entity* caster, Spawn* target, bool lock = true); void AddPlayerTracking(Player* player); void RemovePlayerTracking(Player* player, int8 mode); - + void SendUpdateTitles(Client *client, Title *suffix = 0, Title *prefix = 0); void SendUpdateTitles(Spawn *spawn, Title *suffix = 0, Title *prefix = 0); - + void RemoveTargetFromSpell(LuaSpell* spell, Spawn* target, bool remove_caster = false); /// Set the rain levl in the zone @@ -434,16 +434,16 @@ public: /// Handles zone-wide weather changes void ProcessWeather(); - + Spawn* GetClosestTransportSpawn(float x, float y, float z); Spawn* GetTransportByRailID(sint64 rail_id); - + void ResurrectSpawn(Spawn* spawn, Client* client); void HidePrivateSpawn(Spawn* spawn); Client* GetClientByName(char* name); Client* GetClientByCharID(int32 charid); - + bool SetPlayerTargetByName(Client* originator, char* targetName, float distance); std::vector GetGridsByLocation(Spawn* originator, glm::vec3 loc, float distance); /// Gets spawns for a true AoE spell @@ -501,10 +501,10 @@ public: ****************************************************/ inline const char* GetZoneName() { return zone_name; } - void SetZoneName(char* new_zone) { + void SetZoneName(char* new_zone) { if( strlen(new_zone) >= sizeof zone_name ) return; - strcpy(zone_name, new_zone); + strcpy(zone_name, new_zone); } inline const char* GetZoneFile() { return zone_file; } void SetZoneFile(char* zone) { @@ -519,18 +519,18 @@ public: strcpy(zonesky_file, zone); } inline const char* GetZoneDescription() { return zone_description; } - void SetZoneDescription(char* desc) { + void SetZoneDescription(char* desc) { if( strlen(desc) >= sizeof zone_description ) return; - strncpy(zone_description, desc, 255); + strncpy(zone_description, desc, 255); } - + void SetUnderWorld(float under){ underworld = under; } float GetUnderWorld(){ return underworld; } - + inline int32 GetZoneID() { return zoneID; } void SetZoneID(int32 new_id){ zoneID = new_id; } - + inline bool IsCityZone() { return cityzone; } inline bool AlwaysLoaded() { return always_loaded; } inline bool DuplicatedZone() { return duplicated_zone; } @@ -553,7 +553,7 @@ public: int32 GetInstanceID() { return instanceID; } bool IsInstanceZone() { return isInstance; } void SetInstanceID(int32 newInstanceID) { instanceID = newInstanceID; } - void SetShutdownTimer(int val){ + void SetShutdownTimer(int val){ shutdownTimer.SetTimer(val*1000); } @@ -564,7 +564,7 @@ public: spawn_location_list[id] = spawnlocation; MSpawnLocationList.releasewritelock(__FUNCTION__, __LINE__); } - + void SetInstanceType(int16 type) { InstanceType = (Instance_Type)type; if(type>0)isInstance=true; else isInstance=false; } Instance_Type GetInstanceType() { return InstanceType; } float GetSafeX(){ return safe_x; } @@ -595,7 +595,7 @@ public: /// Returns the Tradeskill Manager for this zone TradeskillMgr* GetTradeskillMgr() { return tradeskillMgr; } - + // had to add these to access weather from Commands bool isWeatherEnabled() { return weather_enabled; } @@ -720,7 +720,7 @@ public: void StopSpawnScriptTimer(Spawn* spawn, std::string functionName); Client* RemoveZoneServerFromClient(ZoneServer* zone); - + void SendSubSpawnUpdates(SUBSPAWN_TYPES subtype); bool HouseItemSpawnExists(int32 item_id); void ProcessPendingSpawns(); @@ -728,12 +728,12 @@ public: void RemoveSpawnFromGrid(Spawn* spawn, int32 grid_id); int32 GetSpawnCountInGrid(int32 grid_id); void SendClientSpawnListInGrid(Client* client, int32 grid_id); - - void AddIgnoredWidget(int32 id); - + + void AddIgnoredWidget(int32 id); + void AddRespawn(Spawn* spawn); void AddRespawn(int32 locationID, int32 respawnTime); - + void SendRespawnTimerList(Client* client); private: #ifndef WIN32 @@ -815,7 +815,7 @@ private: void InitWeather(); // never used outside zone server ///Dismiss all pets in the zone, useful when the spell process needs to be reloaded void DismissAllPets(); // never used outside zone server - + /* Mutex Lists */ std::map changed_spawns; // int32 = spawn id vector clients; @@ -829,7 +829,7 @@ private: set remove_spawn_script_timers_list; Mutex MRemoveSpawnScriptTimersList; list transporter_locations; - + /* Mutex Maps */ MutexMap drowning_victims; MutexMap movement_spawns; // 1st int32 = spawn id @@ -852,11 +852,11 @@ private: map widget_timers; // 1st int32 = spawn id std::map grid_maps; - + /* Mutexs */ mutable std::shared_mutex MGridMaps; mutable std::shared_mutex MChangedSpawns; - + Mutex m_enemy_faction_list; Mutex m_npc_faction_list; Mutex m_reverse_enemy_faction_list; @@ -875,7 +875,7 @@ private: Mutex MSpawnDeleteList; Mutex MClientList; Mutex MIncomingClients; - + /* Maps */ map dead_spawns; map* > enemy_faction_list; @@ -887,11 +887,11 @@ private: /* Lists */ list pending_spawn_list_add; - + /* Specialized Lists to update specific scenarios */ std::map subspawn_list[SUBSPAWN_TYPES::MAX_SUBSPAWN_TYPE]; std::map housing_spawn_map; - + /* Vectors */ vector* revive_points; vector transport_spawns; @@ -899,7 +899,7 @@ private: /* Classes */ SpellProcess* spellProcess; TradeskillMgr* tradeskillMgr; - + /* Timers */ Timer aggro_timer; Timer charsheet_changes; @@ -923,7 +923,7 @@ private: Timer queue_updates; Timer shutdownDelayTimer; Timer delete_timer; - + /* Enums */ Instance_Type InstanceType; @@ -940,8 +940,8 @@ private: bool always_loaded; bool duplicated_zone; int32 duplicated_id; - bool isInstance; - + bool isInstance; + std::atomic pNumPlayers; sint16 minimumStatus; int16 minimumLevel; @@ -1025,17 +1025,17 @@ private: Mutex MTransportMaps; // Map map m_transportMaps; - + int32 watchdogTimestamp; std::map lua_queued_state_commands; std::map> lua_spawn_update_command; std::mutex MLuaQueueStateCmd; - + mutable std::shared_mutex MIgnoredWidgets; std::map ignored_widgets; Map* default_zone_map; // this is the map that npcs, ground spawns, so on use. May not be the same as the clients! - + int32 groupraidMinLevel; int32 groupraidMaxLevel; int32 groupraidAvgLevel; @@ -1054,11 +1054,11 @@ public: void AddNPC(int32 id, NPC* npc); NPC* GetNPC(int32 id, bool override_loading = false) { if((!reloading || override_loading) && npc_list.count(id) > 0) - return npc_list[id]; + return npc_list[id]; else return 0; } - NPC* GetNewNPC(int32 id) { + NPC* GetNewNPC(int32 id) { if(!reloading && npc_list.count(id) > 0) return new NPC(npc_list[id]); else @@ -1075,30 +1075,30 @@ public: /* Objects */ void AddObject(int32 id, Object* object){ object_list[id] = object; } - Object* GetObject(int32 id, bool override_loading = false) { + Object* GetObject(int32 id, bool override_loading = false) { if((!reloading || override_loading) && object_list.count(id) > 0) - return object_list[id]; + return object_list[id]; else return 0; } Object* GetNewObject(int32 id) { if(!reloading && object_list.count(id) > 0) - return object_list[id]->Copy(); + return object_list[id]->Copy(); else return 0; } /* Signs */ void AddSign(int32 id, Sign* sign){ sign_list[id] = sign; } - Sign* GetSign(int32 id, bool override_loading = false) { + Sign* GetSign(int32 id, bool override_loading = false) { if((!reloading || override_loading) && sign_list.count(id) > 0) - return sign_list[id]; + return sign_list[id]; else return 0; } Sign* GetNewSign(int32 id) { if(!reloading && sign_list.count(id) > 0) - return sign_list[id]->Copy(); + return sign_list[id]->Copy(); else return 0; } @@ -1141,7 +1141,7 @@ public: /* Transporters */ void AddLocationTransporter(int32 zone_id, string message, float trigger_x, float trigger_y, float trigger_z, float trigger_radius, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id, bool force_zone); - void AddTransporter(int32 transport_id, int8 type, string name, string message, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, + void AddTransporter(int32 transport_id, int8 type, string name, string message, int32 destination_zone_id, float destination_x, float destination_y, float destination_z, float destination_heading, int32 cost, int32 unique_id, int8 min_level, int8 max_level, int32 quest_req, int16 quest_step_req, int32 quest_complete, int32 map_x, int32 map_y, int32 expansion_flag, int32 holiday_flag, int32 min_client_version, int32 max_client_version, int32 flight_path_id, int16 mount_id, int8 mount_red_color, int8 mount_green_color, int8 mount_blue_color); void GetTransporters(vector* returnList, Client* client, int32 transport_id); @@ -1165,7 +1165,7 @@ public: ///Clears the list of transporter maps void DeleteTransporterMaps(); - + void DeleteGlobalSpawns(); void ReloadSpawns(); @@ -1187,7 +1187,7 @@ public: int32 getGroupraidFirstLevel() const { return groupraidFirstLevel; } - + void setGroupRaidLevels(int32 min_level, int32 max_level, int32 avg_level, int32 first_level) { groupraidMinLevel = min_level; groupraidMaxLevel = max_level; diff --git a/source/common/ConfigReader.h b/source/common/ConfigReader.h index 3c9187d..73f8c2c 100644 --- a/source/common/ConfigReader.h +++ b/source/common/ConfigReader.h @@ -8,7 +8,7 @@ #include #include #include "xmlParser.h" -#include "Mutex.h" +#include "mutex.h" using namespace std; @@ -28,8 +28,7 @@ public: private: Mutex MStructs; vector load_files; - map*> structs; + map*> structs; //vector structs; }; #endif - diff --git a/source/common/EQEMuError.cpp b/source/common/EQEMuError.cpp index 04390a3..bd8700a 100644 --- a/source/common/EQEMuError.cpp +++ b/source/common/EQEMuError.cpp @@ -6,7 +6,7 @@ #endif #include "EQEMuError.h" #include "linked_list.h" -#include "Mutex.h" +#include "mutex.h" #include "MiscFunctions.h" #include #include @@ -53,7 +53,7 @@ void AddEQEMuError(eEQEMuError iError, bool iExitNow) { } iterator.Advance(); } - + char* tmp = new char[6]; tmp[0] = 1; tmp[5] = 0; @@ -110,5 +110,3 @@ void CheckEQEMuErrorAndPause() { getchar(); } } - - diff --git a/source/common/EQStream.cpp b/source/common/EQStream.cpp index fb2b1ef..7aa58b3 100644 --- a/source/common/EQStream.cpp +++ b/source/common/EQStream.cpp @@ -27,7 +27,7 @@ #include "EQStream.h" #include "EQStreamFactory.h" #include "misc.h" -#include "Mutex.h" +#include "mutex.h" #include "op_codes.h" #include "crypto/crc.h" #include "packet_dump.h" @@ -46,7 +46,7 @@ uint16 EQStream::MaxWindowSize = 2048; /** * Initialize the EQ stream with default values. - * + * * @param resetSession - Whether to reset session-specific data */ void EQStream::init(bool resetSession) @@ -82,7 +82,7 @@ void EQStream::init(bool resetSession) LastSeqSent = -1; MaxSends = 5; LastPacket = Timer::GetCurrentTime2(); - + // Initialize buffers oversize_buffer = nullptr; oversize_length = 0; @@ -113,11 +113,11 @@ void EQStream::init(bool resetSession) // Initialize reconnection reconnectAttempt = 0; - + // Validate queue consistency if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - LogWrite(PACKET__DEBUG, 9, "Packet", - "init Invalid Sequenced queue: BS %u + SQ %u != NOS %u", + LogWrite(PACKET__DEBUG, 9, "Packet", + "init Invalid Sequenced queue: BS %u + SQ %u != NOS %u", SequencedBase, SequencedQueue.size(), NextOutSeq); } } @@ -125,7 +125,7 @@ void EQStream::init(bool resetSession) /** * EQStream constructor with socket address. * Initializes all stream components and sets up compression. - * + * * @param addr - Socket address of remote endpoint */ EQStream::EQStream(sockaddr_in addr) @@ -136,28 +136,28 @@ EQStream::EQStream(sockaddr_in addr) combine_timer = new Timer(250); // 250 milliseconds combine_timer->Start(); resend_que_timer->Start(); - + // Initialize base stream init(); - + // Set remote endpoint remote_ip = addr.sin_addr.s_addr; remote_port = addr.sin_port; - + // Set initial state State = CLOSED; StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2; - + // Initialize compression stream (Unix only) bzero(&stream, sizeof(z_stream)); stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; deflateInit2(&stream, 9, Z_DEFLATED, 13, 9, Z_DEFAULT_STRATEGY); - + // Initialize compression state compressed_offset = 0; client_version = 0; @@ -168,7 +168,7 @@ EQStream::EQStream(sockaddr_in addr) // Initialize packet logging write_packets = nullptr; char write_packets_filename[64]; - snprintf(write_packets_filename, sizeof(write_packets_filename), + snprintf(write_packets_filename, sizeof(write_packets_filename), "PacketLog%i.log", Timer::GetCurrentTime2()); write_packets = fopen(write_packets_filename, "w+"); #endif @@ -177,7 +177,7 @@ EQStream::EQStream(sockaddr_in addr) /** * Process encrypted packet data and extract the embedded packet. * Decrypts the data and extracts the opcode and payload. - * + * * @param data - Encrypted data buffer * @param size - Size of encrypted data * @param opcode - Reference to opcode (will be modified) @@ -187,7 +187,7 @@ EQProtocolPacket* EQStream::ProcessEncryptedData(uchar* data, int32 size, int16 { // Decrypt the data using RC4 crypto->RC4Decrypt(data, size); - + int8 offset = 0; if (data[0] == 0xFF && size > 2) { // Extended opcode format (2-byte opcode) @@ -198,21 +198,21 @@ EQProtocolPacket* EQStream::ProcessEncryptedData(uchar* data, int32 size, int16 offset = 1; memcpy(&opcode, data, sizeof(int8)); } - + return new EQProtocolPacket(opcode, data + offset, size - offset); } /** * Process an encrypted protocol packet. * Determines the correct offset and calls ProcessEncryptedData. - * + * * @param p - Encrypted protocol packet to process * @return Newly created EQProtocolPacket with decrypted data */ EQProtocolPacket* EQStream::ProcessEncryptedPacket(EQProtocolPacket* p) { EQProtocolPacket* ret = nullptr; - + if (p->opcode == OP_Packet && p->size > 2) { // Skip the first 2 bytes for OP_Packet ret = ProcessEncryptedData(p->pBuffer + 2, p->size - 2, p->opcode); @@ -220,14 +220,14 @@ EQProtocolPacket* EQStream::ProcessEncryptedPacket(EQProtocolPacket* p) // Process entire buffer for other opcodes ret = ProcessEncryptedData(p->pBuffer, p->size, p->opcode); } - + return ret; } /** * Process an embedded encrypted packet within another packet. * Decrypts and queues the embedded packet for processing. - * + * * @param pBuffer - Buffer containing embedded packet data * @param length - Length of embedded packet * @param opcode - Opcode for the embedded packet @@ -243,35 +243,35 @@ bool EQStream::ProcessEmbeddedPacket(uchar* pBuffer, int16 length, int8 opcode) MCombineQueueLock.lock(); EQProtocolPacket* newpacket = ProcessEncryptedData(pBuffer, length, opcode); MCombineQueueLock.unlock(); - + if (newpacket) { #ifdef DEBUG_EMBEDDED_PACKETS printf("Embedded Packet - Opcode: %u\n", newpacket->opcode); DumpPacket(newpacket->pBuffer, newpacket->size); #endif - + // Convert to application packet and queue EQApplicationPacket* ap = newpacket->MakeApplicationPacket(2); if (ap->version == 0) { ap->version = client_version; } InboundQueuePush(ap); - + #ifdef WRITE_PACKETS WritePackets(ap->GetOpcodeName(), pBuffer, length, false); #endif - + safe_delete(newpacket); return true; } - + return false; } /** * Handle embedded packets within a protocol packet. * Processes different types of embedded packet formats. - * + * * @param p - Protocol packet containing embedded data * @param offset - Offset to start of embedded data * @param length - Length of embedded data (0 = auto-detect) @@ -282,21 +282,21 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket* p, int16 offset, int16 len if (!p) { return false; } - + #ifdef DEBUG_EMBEDDED_PACKETS - printf("HandleEmbeddedPacket - offset: %u, length: %u, size: %u\n", + printf("HandleEmbeddedPacket - offset: %u, length: %u, size: %u\n", offset, length, p->size); #endif - + // Ensure we have enough data for the offset if (p->size < static_cast(offset + 2)) { return false; } - + // Check for OP_AppCombined embedded packet (0x00 0x19) if (p->pBuffer[offset] == 0 && p->pBuffer[offset + 1] == 0x19) { uint32 data_length = 0; - + if (length == 0) { // Auto-detect length data_length = p->size - offset - 2; @@ -307,21 +307,21 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket* p, int16 offset, int16 len } data_length = length - 2; } - + #ifdef DEBUG_EMBEDDED_PACKETS - printf("Processing OP_AppCombined - offset: %u, data_length: %u\n", + printf("Processing OP_AppCombined - offset: %u, data_length: %u\n", offset, data_length); DumpPacket(p->pBuffer, p->size); #endif - + // Verify bounds if (offset + 2 + data_length > p->size) { return false; // Out of bounds } - + // Create and process sub-packet - auto subp = new EQProtocolPacket(OP_AppCombined, - p->pBuffer + offset + 2, + auto subp = new EQProtocolPacket(OP_AppCombined, + p->pBuffer + offset + 2, data_length); subp->copyInfo(p); ProcessPacket(subp, p); @@ -340,10 +340,10 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket* p, int16 offset, int16 len printf("Processing null opcode embedded packet\n"); DumpPacket(p->pBuffer + 1 + offset, length); #endif - + uchar* buffer = (p->pBuffer + 1 + offset); bool valid = ProcessEmbeddedPacket(buffer, length); - + if (valid) { return true; } @@ -353,12 +353,12 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket* p, int16 offset, int16 len #ifdef DEBUG_EMBEDDED_PACKETS uint16 seq = NextInSeq - 1; sint8 check = 0; - + if (offset == 2) { seq = ntohs(*(uint16*)(p->pBuffer)); check = CompareSequence(NextInSeq, seq); } - printf("Processing general embedded packet - offset: %u, length: %u, size: %u, check: %i, seq: %u\n", + printf("Processing general embedded packet - offset: %u, length: %u, size: %u, check: %i, seq: %u\n", offset, length, p->size, check, seq); DumpPacket(p->pBuffer, p->size); #endif @@ -366,28 +366,28 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket* p, int16 offset, int16 len if (length == 0) { length = p->size - offset; } - + uchar* buffer = (p->pBuffer + offset); bool valid = ProcessEmbeddedPacket(buffer, length); - + if (valid) { return true; } } // Check for length-prefixed embedded packet (not 0xff, then 0xff) - else if (p->pBuffer[offset] != 0xff && - p->pBuffer[offset + 1] == 0xff && + else if (p->pBuffer[offset] != 0xff && + p->pBuffer[offset + 1] == 0xff && p->size >= offset + 3) { - + // Get total length from first byte uint16 total_length = p->pBuffer[offset]; - + // Verify packet size matches expected length if (total_length + offset + 2 == p->size && total_length >= 2) { uint32 data_length = total_length - 2; - + // Create and process sub-packet - auto subp = new EQProtocolPacket(p->pBuffer + offset + 2, + auto subp = new EQProtocolPacket(p->pBuffer + offset + 2, data_length, OP_Packet); subp->copyInfo(p); ProcessPacket(subp, p); @@ -395,14 +395,14 @@ bool EQStream::HandleEmbeddedPacket(EQProtocolPacket* p, int16 offset, int16 len return true; } } - + return false; } /** * Process a protocol packet and handle various packet types. * This is the main packet processing dispatcher for the stream. - * + * * @param p - Protocol packet to process * @param lastp - Previous packet in sequence (for context) */ @@ -416,17 +416,17 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) } // Ensure session is initialized for non-session packets - if (p->opcode != OP_SessionRequest && - p->opcode != OP_SessionResponse && + if (p->opcode != OP_SessionRequest && + p->opcode != OP_SessionResponse && !Session) { #ifdef EQN_DEBUG - LogWrite(PACKET__ERROR, 0, "Packet", + LogWrite(PACKET__ERROR, 0, "Packet", "Session not initialized, packet ignored"); #endif return; } - + // Process packet based on opcode switch (p->opcode) { case OP_Combined: { @@ -434,17 +434,17 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) processed = 0; int8 offset = 0; int count = 0; - + #ifdef LE_DEBUG printf("Processing OP_Combined packet\n"); DumpPacket(p); #endif - + // Process all sub-packets within the combined packet while (processed < p->size) { // Determine sub-packet length and offset subpacket_length = static_cast(*(p->pBuffer + processed)); - + if (subpacket_length == 0xff) { // Extended length format (2-byte length) subpacket_length = ntohs(*(uint16*)(p->pBuffer + processed + 1)); @@ -453,49 +453,49 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) // Standard format (1-byte length) offset = 1; } - + count++; - + #ifdef LE_DEBUG - printf("Processing sub-packet %i: length=%u, offset=%u\n", + printf("Processing sub-packet %i: length=%u, offset=%u\n", count, subpacket_length, processed); #endif - + // Check if this is a valid protocol packet bool isSubPacket = EQProtocolPacket::IsProtocolPacket( p->pBuffer + processed + offset, subpacket_length, false); - + if (isSubPacket) { // Create and process sub-packet auto subp = new EQProtocolPacket( p->pBuffer + processed + offset, subpacket_length); subp->copyInfo(p); - + #ifdef LE_DEBUG printf("Sub-packet opcode: %i\n", subp->opcode); DumpPacket(subp); #endif - + ProcessPacket(subp, p); delete subp; } else { // Handle non-protocol packet data (encrypted) offset = 1; - + // Check for potential garbage packet uint16 header_check = ntohs(*reinterpret_cast( p->pBuffer + processed + offset)); - + if (header_check <= 0x1e) { // Process as potential OP_Packet subpacket_length = static_cast( *(p->pBuffer + processed)); - - LogWrite(PACKET__ERROR, 0, "Packet", + + LogWrite(PACKET__ERROR, 0, "Packet", "Processing suspected garbage packet as OP_Packet"); DumpPacket(p->pBuffer + processed + offset, subpacket_length); - + uchar* newbuf = p->pBuffer + processed + offset; auto subp = new EQProtocolPacket(newbuf, subpacket_length); subp->copyInfo(p); @@ -504,18 +504,18 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) } else { // Decrypt the data and process crypto->RC4Decrypt(p->pBuffer + processed + offset, subpacket_length); - - LogWrite(PACKET__ERROR, 0, "Packet", + + LogWrite(PACKET__ERROR, 0, "Packet", "Processing encrypted sub-packet: " - "processed=%u, offset=%u, count=%i, length=%u", + "processed=%u, offset=%u, count=%i, length=%u", processed, offset, count, subpacket_length); - + if (p->pBuffer[processed + offset] == 0xff) { // Skip 0xff marker and process data uchar* newbuf = p->pBuffer + processed + offset + 1; - + DumpPacket(p->pBuffer + processed + offset, subpacket_length); - + auto subp = new EQProtocolPacket( newbuf, subpacket_length, OP_Packet); subp->copyInfo(p); @@ -527,7 +527,7 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) } } } - + // Move to next sub-packet processed += subpacket_length + offset; } @@ -538,18 +538,18 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) processed = 0; int8 offset = 0; int count = 0; - + #ifdef DEBUG_EMBEDDED_PACKETS printf("Processing OP_AppCombined packet\n"); DumpPacket(p); #endif - + while (processed < p->size) { count++; - + // Determine sub-packet length and offset subpacket_length = static_cast(*(p->pBuffer + processed)); - + if (subpacket_length == 0xff) { // Extended length format subpacket_length = ntohs(*(uint16*)(p->pBuffer + processed + 1)); @@ -558,7 +558,7 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) // Standard length format offset = 1; } - + // Handle RSA key exchange if no encryption key is set if (crypto->getRC4Key() == 0 && p && subpacket_length > 8 + offset) { #ifdef DEBUG_EMBEDDED_PACKETS @@ -570,20 +570,20 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) } else if (crypto->isEncrypted()) { // Process encrypted embedded packet #ifdef DEBUG_EMBEDDED_PACKETS - printf("Processing encrypted sub-packet %i: length=%u, offset=%u\n", + printf("Processing encrypted sub-packet %i: length=%u, offset=%u\n", count, subpacket_length, processed); DumpPacket(p->pBuffer + processed + offset, subpacket_length); #endif - + if (!HandleEmbeddedPacket(p, processed + offset, subpacket_length)) { uchar* buffer = (p->pBuffer + processed + offset); if (!ProcessEmbeddedPacket(buffer, subpacket_length, OP_AppCombined)) { - LogWrite(PACKET__ERROR, 0, "Packet", + LogWrite(PACKET__ERROR, 0, "Packet", "ProcessEmbeddedPacket failed for OP_AppCombined"); } } } - + // Move to next sub-packet processed += subpacket_length + offset; } @@ -598,46 +598,46 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) // Extract sequence number and check ordering uint16 seq = ntohs(*(uint16*)(p->pBuffer)); sint8 check = CompareSequence(NextInSeq, seq); - + if (check == SeqFuture) { // Future packet - store for later processing #ifdef EQN_DEBUG - LogWrite(PACKET__DEBUG, 1, "Packet", + LogWrite(PACKET__DEBUG, 1, "Packet", "Future packet: Expected=%i, Got=%i", NextInSeq, seq); p->DumpRawHeader(seq); #endif - + OutOfOrderpackets[seq] = p->Copy(); // Note: Not sending out-of-order ACK to prevent loops - + } else if (check == SeqPast) { // Duplicate/old packet - acknowledge but don't process #ifdef EQN_DEBUG - LogWrite(PACKET__DEBUG, 1, "Packet", + LogWrite(PACKET__DEBUG, 1, "Packet", "Duplicate packet: Expected=%i, Got=%i", NextInSeq, seq); p->DumpRawHeader(seq); #endif - + SendOutOfOrderAck(seq); - + } else { // In-order packet - process normally EQProtocolPacket* qp = RemoveQueue(seq); if (qp) { - LogWrite(PACKET__DEBUG, 1, "Packet", + LogWrite(PACKET__DEBUG, 1, "Packet", "Removing older queued packet with sequence %i", seq); delete qp; } - + // Update sequence tracking SetNextAckToSend(seq); NextInSeq++; - + // Try to handle as embedded packet first if (HandleEmbeddedPacket(p)) { break; } - + // Handle RSA key exchange if no encryption key is set if (crypto->getRC4Key() == 0 && p && p->size >= 69) { #ifdef DEBUG_EMBEDDED_PACKETS @@ -649,18 +649,18 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) MCombineQueueLock.lock(); EQProtocolPacket* newpacket = ProcessEncryptedPacket(p); MCombineQueueLock.unlock(); - + if (newpacket) { // Convert to application packet and queue EQApplicationPacket* ap = newpacket->MakeApplicationPacket(2); if (ap->version == 0) { ap->version = client_version; } - + #ifdef WRITE_PACKETS WritePackets(ap->GetOpcodeName(), p->pBuffer, p->size, false); #endif - + InboundQueuePush(ap); safe_delete(newpacket); } @@ -715,7 +715,7 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) ProcessPacket(subp, p); delete subp; } else { - + if(crypto->isEncrypted() && p && p->size > 2){ MCombineQueueLock.lock(); EQProtocolPacket* p2 = ProcessEncryptedData(oversize_buffer, oversize_offset, p->opcode); @@ -824,33 +824,33 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) LogWrite(PACKET__ERROR, 0, "Packet", "SessionResponse packet too small: %d bytes", p->Size()); break; } - + // Initialize stream and clear outbound queue init(); OutboundQueueClear(); SetActive(true); - + // Extract session response data auto Response = reinterpret_cast(p->pBuffer); SetMaxLen(ntohl(Response->MaxLength)); Key = ntohl(Response->Key); NextInSeq = 0; SetState(ESTABLISHED); - + // Set session ID if not already established if (!Session) { Session = ntohl(Response->Session); } - + LogWrite(PACKET__INFO, 0, "Packet", "SessionResponse: Session=0x%08X, Key=0x%08X, MaxLength=%d", Session, Key, MaxLen); - + // Extract compression and encoding flags compressed = (Response->Format & FLAG_COMPRESSED); encoded = (Response->Format & FLAG_ENCODED); - LogWrite(PACKET__INFO, 0, "Packet", "Stream flags: Format=0x%02X, Compressed=%s, Encoded=%s", + LogWrite(PACKET__INFO, 0, "Packet", "Stream flags: Format=0x%02X, Compressed=%s, Encoded=%s", Response->Format, compressed ? "YES" : "NO", encoded ? "YES" : "NO"); - + // Determine stream type based on format flags and port if (compressed) { @@ -900,36 +900,36 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) LogWrite(PACKET__DEBUG, 9, "Packet", "Received OP_OutOfOrderAck that was of malformed size"); break; } - + // Extract sequence number from packet uint16 seq = ntohs(*reinterpret_cast(p->pBuffer)); MOutboundQueue.lock(); - + // Validate sequenced queue integrity (pre-processing) if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { LogWrite(PACKET__DEBUG, 9, "Packet", "Pre-OOA Invalid Sequenced queue: BS %u + SQ %u != NOS %u", SequencedBase, SequencedQueue.size(), NextOutSeq); } - + // Verify that acknowledged packet is within valid window if (CompareSequence(SequencedBase, seq) != SeqPast && CompareSequence(NextOutSeq, seq) == SeqPast) { uint16 sqsize = SequencedQueue.size(); uint16 index = seq - SequencedBase; - + LogWrite(PACKET__DEBUG, 9, "Packet", "OP_OutOfOrderAck marking packet acked in queue (queue index = %u, queue size = %u)", index, sqsize); - + // Mark the specific packet as acknowledged if (index < sqsize) { SequencedQueue[index]->acked = true; - + // Flag earlier unacknowledged packets for retransmission uint16 count = 0; uint32 timeout = AverageDelta * 2 + 100; - + for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end() && count < index; ++sitr, ++count) { // Check if packet needs retransmission based on timeout @@ -942,7 +942,7 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) } } } - + // Update retransmit timer if enabled if (RETRANSMIT_TIMEOUT_MULT) { @@ -954,14 +954,14 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) LogWrite(PACKET__DEBUG, 9, "Packet", "Received OP_OutOfOrderAck for out-of-window %u. Window (%u->%u)", seq, SequencedBase, NextOutSeq); } - + // Validate sequenced queue integrity (post-processing) if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { LogWrite(PACKET__DEBUG, 9, "Packet", "Post-OOA Invalid Sequenced queue: BS %u + SQ %u != NOS %u", SequencedBase, SequencedQueue.size(), NextOutSeq); } - + MOutboundQueue.unlock(); } break; @@ -976,14 +976,14 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) { break; } - + // Extract client session statistics auto Stats = reinterpret_cast(p->pBuffer); int16 request_id = Stats->RequestID; - + // Adjust transmission rates based on client feedback AdjustRates(ntohl(Stats->average_delta)); - + // Prepare server session statistics response auto stats = reinterpret_cast(p->pBuffer); memset(stats, 0, sizeof(ServerSessionStats)); @@ -993,10 +993,10 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) stats->sent_packets2 = ntohl(sent_packets); stats->received_packets = ntohl(received_packets); stats->received_packets2 = ntohl(received_packets); - + // Send session statistics response NonSequencedPush(new EQProtocolPacket(OP_SessionStatResponse, p->pBuffer, p->size)); - + // Initiate appropriate response based on encryption state if (!crypto->isEncrypted()) { @@ -1037,18 +1037,18 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) // Debug output for original packet std::cout << "Orig Packet: " << p->opcode << std::endl; DumpPacket(p->pBuffer, p->size); - + // Process RSA key if packet is large enough if (p && p->size >= 69) { processRSAKey(p); } - + // Attempt to decrypt packet data MCombineQueueLock.lock(); EQProtocolPacket* p2 = ProcessEncryptedData(p->pBuffer, p->size, OP_Packet); MCombineQueueLock.unlock(); - + // Debug output for decrypted packet if (p2) { @@ -1056,12 +1056,12 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) DumpPacket(p2->pBuffer, p2->size); safe_delete(p2); } - + #ifdef WRITE_PACKETS // Write packet data to file if enabled WritePackets("Unknown", p->pBuffer, p->size, false); #endif - + // Log unknown packet type LogWrite(PACKET__INFO, 0, "Packet", "Received unknown packet type, not adding to inbound queue"); } @@ -1072,7 +1072,7 @@ void EQStream::ProcessPacket(EQProtocolPacket* p, EQProtocolPacket* lastp) /** * Compress EQ2 packet data using zlib deflate compression * Compresses packet data starting from the specified offset and updates packet buffer - * + * * @param app - EQ2Packet to compress (modified in-place) * @param offset - Starting offset for compression data * @return Compression flag offset, or 0 on failure @@ -1088,7 +1088,7 @@ int8 EQStream::EQ2_Compress(EQ2Packet* app, int8 offset) uchar* pDataPtr = app->pBuffer + offset; int xpandSize = app->size * 2; // Allocate double size for compression buffer auto deflate_buff = std::make_unique(xpandSize); - + // Lock compression data and configure zlib stream MCompressData.lock(); stream.next_in = pDataPtr; @@ -1112,11 +1112,11 @@ int8 EQStream::EQ2_Compress(EQ2Packet* app, int8 offset) safe_delete_array(app->pBuffer); app->size = newsize + offset; app->pBuffer = new uchar[app->size]; - + // Set compression flag and copy compressed data app->pBuffer[offset - 1] = 1; // Compression flag std::memcpy(app->pBuffer + offset, deflate_buff.get(), newsize); - + MCompressData.unlock(); #ifdef LE_DEBUG @@ -1130,7 +1130,7 @@ int8 EQStream::EQ2_Compress(EQ2Packet* app, int8 offset) /** * Process RSA key from protocol packet and initialize RC4 encryption * Extracts RSA-encrypted RC4 key from packet and configures stream encryption - * + * * @param p - Protocol packet containing RSA key data * @param subpacket_length - Length of subpacket, 0 to use full packet * @return Always returns 0 (legacy return value) @@ -1139,7 +1139,7 @@ int16 EQStream::processRSAKey(EQProtocolPacket *p, uint16 subpacket_length) { LogWrite(PACKET__INFO, 0, "Packet", "=== RSA KEY PROCESSING ==="); LogWrite(PACKET__INFO, 0, "Packet", "Processing RSA key from packet size %d, subpacket_length %d", p->size, subpacket_length); - + // Extract RSA key from appropriate location in packet uchar* rsa_data; if (subpacket_length) @@ -1156,11 +1156,11 @@ int16 EQStream::processRSAKey(EQProtocolPacket *p, uint16 subpacket_length) LogWrite(PACKET__DEBUG, 0, "Packet", "Using full packet RSA data at offset %d", p->size - 8); crypto->setRC4Key(Crypto::RSADecrypt(rsa_data, 8)); } - + LogWrite(PACKET__DEBUG, 0, "Packet", "RSA encrypted data (8 bytes): %02X %02X %02X %02X %02X %02X %02X %02X", rsa_data[0], rsa_data[1], rsa_data[2], rsa_data[3], rsa_data[4], rsa_data[5], rsa_data[6], rsa_data[7]); LogWrite(PACKET__INFO, 0, "Packet", "RC4 key set from RSA decryption, current RC4 key: 0x%08X", crypto->getRC4Key()); - + return 0; } @@ -1172,38 +1172,38 @@ void EQStream::SendKeyRequest() { LogWrite(PACKET__INFO, 0, "Packet", "=== SENDING KEY REQUEST ==="); LogWrite(PACKET__INFO, 0, "Packet", "Initiating encryption key exchange handshake"); - + // Define key generation packet parameters constexpr int32 crypto_key_size = 60; const int16 size = sizeof(KeyGen_Struct) + sizeof(KeyGen_End_Struct) + crypto_key_size; - + LogWrite(PACKET__DEBUG, 0, "Packet", "Key request packet size: %d bytes (crypto_key_size=%d)", size, crypto_key_size); - + // Create key request packet auto outapp = new EQ2Packet(OP_WSLoginRequestMsg, nullptr, size); - + // Set crypto key size in packet header std::memcpy(&outapp->pBuffer[0], &crypto_key_size, sizeof(int32)); - + // Fill crypto key area with placeholder data std::memset(&outapp->pBuffer[4], 0xFF, crypto_key_size); - + // Set packet termination markers std::memset(&outapp->pBuffer[size - 5], 1, 1); std::memset(&outapp->pBuffer[size - 1], 1, 1); - + LogWrite(PACKET__INFO, 0, "Packet", "Key request packet prepared, queuing for transmission"); - + // Queue packet for transmission EQ2QueuePacket(outapp, true); - + LogWrite(PACKET__INFO, 0, "Packet", "Key request sent successfully"); } /** * Encrypt packet data using RC4 encryption * Applies encryption to packet payload, skipping headers and unencrypted sections - * + * * @param app - EQ2Packet to encrypt (modified in-place) * @param compress_offset - Offset for compressed data encryption * @param offset - Additional offset for uncompressed data @@ -1215,7 +1215,7 @@ void EQStream::EncryptPacket(EQ2Packet* app, int8 compress_offset, int8 offset) { app->packet_encrypted = true; uchar* crypt_buff = app->pBuffer; - + // Choose encryption range based on compression status if (app->eq2_compressed) { @@ -1233,7 +1233,7 @@ void EQStream::EncryptPacket(EQ2Packet* app, int8 compress_offset, int8 offset) /** * Queue EQ2 packet for transmission with optional combining * Either adds packet to combine queue for batching or sends immediately - * + * * @param app - EQ2Packet to queue for transmission * @param attempted_combine - If true, send immediately; if false, queue for combining */ @@ -1255,7 +1255,7 @@ void EQStream::EQ2QueuePacket(EQ2Packet* app, bool attempted_combine) MCombineQueueLock.lock(); PreparePacket(app); MCombineQueueLock.unlock(); - + #ifdef LE_DEBUG std::printf("After B in %s, line %i:\n", __FUNCTION__, __LINE__); DumpPacket(app); @@ -1268,7 +1268,7 @@ void EQStream::EQ2QueuePacket(EQ2Packet* app, bool attempted_combine) /** * Remove packet preparation headers from EQ2 packet * Strips protocol-specific headers that were added during packet preparation - * + * * @param app - EQ2Packet to unprepare (modified in-place) */ void EQStream::UnPreparePacket(EQ2Packet* app) @@ -1279,7 +1279,7 @@ void EQStream::UnPreparePacket(EQ2Packet* app) // Create new buffer without preparation headers auto new_buffer = std::make_unique(app->size - 3); std::memcpy(new_buffer.get() + 2, app->pBuffer + 5, app->size - 3); - + // Replace packet buffer with unprepared version delete[] app->pBuffer; app->size -= 3; @@ -1291,7 +1291,7 @@ void EQStream::UnPreparePacket(EQ2Packet* app) /** * Convert byte to printable character for packet dumps * Returns '.' for non-printable characters - * + * * @param in - Input byte to convert * @return Printable character representation */ @@ -1306,7 +1306,7 @@ char EQStream::GetChar(uchar in) /** * Write formatted output to packet dump file * Provides printf-style formatting for packet logging - * + * * @param pFormat - Printf-style format string * @param ... - Variable arguments for formatting */ @@ -1321,7 +1321,7 @@ void EQStream::WriteToFile(char* pFormat, ...) /** * Write packet data to debug file with hex dump format * Creates formatted hex dump with ASCII representation for debugging - * + * * @param opcodeName - Name of packet opcode for header * @param data - Raw packet data to dump * @param size - Size of packet data in bytes @@ -1330,18 +1330,18 @@ void EQStream::WriteToFile(char* pFormat, ...) void EQStream::WritePackets(const char* opcodeName, uchar* data, int32 size, bool outgoing) { MWritePackets.lock(); - + // Format connection information struct in_addr ip_addr; ip_addr.s_addr = remote_ip; char timebuffer[80]; time_t rawtime; struct tm* timeinfo; - + std::time(&rawtime); timeinfo = std::localtime(&rawtime); std::strftime(timebuffer, 80, "%m/%d/%Y %H:%M:%S", timeinfo); - + // Write packet header if (outgoing) { @@ -1351,12 +1351,12 @@ void EQStream::WritePackets(const char* opcodeName, uchar* data, int32 size, boo { WriteToFile("-- %s --\n%s\n%s -> SERVER\n", opcodeName, timebuffer, inet_ntoa(ip_addr)); } - + // Calculate hex dump layout int nLines = size / 16; int nExtra = size % 16; uchar* pPtr = data; - + // Write full 16-byte lines for (int i = 0; i < nLines; i++) { @@ -1369,24 +1369,24 @@ void EQStream::WritePackets(const char* opcodeName, uchar* data, int32 size, boo GetChar(pPtr[12]), GetChar(pPtr[13]), GetChar(pPtr[14]), GetChar(pPtr[15])); pPtr += 16; } - + // Write partial line if remaining bytes if (nExtra) { WriteToFile("%4.4X\t", nLines * 16); - + // Write hex bytes for (int i = 0; i < nExtra; i++) { WriteToFile("%2.2X ", pPtr[i]); } - + // Pad with spaces for (int i = nExtra; i < 16; i++) { WriteToFile(" "); } - + // Write ASCII representation for (int i = 0; i < nExtra; i++) { @@ -1394,7 +1394,7 @@ void EQStream::WritePackets(const char* opcodeName, uchar* data, int32 size, boo } WriteToFile("\n"); } - + WriteToFile("\n\n"); std::fflush(write_packets); MWritePackets.unlock(); @@ -1403,7 +1403,7 @@ void EQStream::WritePackets(const char* opcodeName, uchar* data, int32 size, boo /** * Write EQ2 packet to debug file with automatic version handling * Convenience wrapper for WritePackets that handles version setup - * + * * @param app - EQ2Packet to write to debug file * @param outgoing - True if outgoing packet, false if incoming */ @@ -1420,7 +1420,7 @@ void EQStream::WritePackets(EQ2Packet* app, bool outgoing) /** * Prepare EQ2 packet for transmission * Handles packet preparation, compression, and encryption in sequence - * + * * @param app - EQ2Packet to prepare (modified in-place) * @param offset - Additional offset for encryption */ @@ -1466,12 +1466,12 @@ void EQStream::PreparePacket(EQ2Packet* app, int8 offset) app->eq2_compressed = true; } } - + // Encrypt packet if not already encrypted if (!app->packet_encrypted) { EncryptPacket(app, compressed_offset, offset); - + // Handle special case for zero byte at offset 2 if (app->size > 2 && app->pBuffer[2] == 0) { @@ -1493,7 +1493,7 @@ void EQStream::PreparePacket(EQ2Packet* app, int8 offset) /** * Send EQProtocolPacket with automatic fragmentation for large packets * Fragments packets that exceed maximum transmission unit into smaller chunks - * + * * @param p - EQProtocolPacket to send (ownership transferred, will be deleted) */ void EQStream::SendPacket(EQProtocolPacket *p) @@ -1526,7 +1526,7 @@ void EQStream::SendPacket(EQProtocolPacket *p) chunksize = std::min(length - used, MaxLen - 6); out = new EQProtocolPacket(OP_Fragment, nullptr, chunksize + 2); std::memcpy(out->pBuffer + 2, tmpbuff + used + 2, chunksize); - + #ifdef LE_DEBUG std::printf("Chunk: \n"); DumpPacket(out); @@ -1551,7 +1551,7 @@ void EQStream::SendPacket(EQProtocolPacket *p) /** * Send EQApplicationPacket with automatic fragmentation for large packets * Serializes application packet and fragments if necessary for transmission - * + * * @param p - EQApplicationPacket to send (ownership transferred, will be deleted) */ void EQStream::SendPacket(EQApplicationPacket *p) @@ -1583,7 +1583,7 @@ void EQStream::SendPacket(EQApplicationPacket *p) SequencedPush(out); used += chunksize; } - + delete p; } else @@ -1599,36 +1599,36 @@ void EQStream::SendPacket(EQApplicationPacket *p) /** * Add packet to sequenced transmission queue * Assigns sequence number and queues packet for reliable delivery - * + * * @param p - EQProtocolPacket to queue (ownership transferred) */ void EQStream::SequencedPush(EQProtocolPacket *p) { // Set client version for compatibility p->setVersion(client_version); - + MOutboundQueue.lock(); - + // Assign sequence number to packet header *reinterpret_cast(p->pBuffer) = htons(NextOutSeq); SequencedQueue.push_back(p); p->sequence = NextOutSeq; NextOutSeq++; - + MOutboundQueue.unlock(); } /** * Add packet to non-sequenced transmission queue * Queues packet for immediate transmission without sequence numbering - * + * * @param p - EQProtocolPacket to queue (ownership transferred) */ void EQStream::NonSequencedPush(EQProtocolPacket *p) { // Set client version for compatibility p->setVersion(client_version); - + MOutboundQueue.lock(); NonSequencedQueue.push(p); MOutboundQueue.unlock(); @@ -1637,7 +1637,7 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p) /** * Send acknowledgment packet for received sequence number * Confirms successful receipt of sequenced packet to peer - * + * * @param seq - Sequence number to acknowledge */ void EQStream::SendAck(uint16 seq) @@ -1650,7 +1650,7 @@ void EQStream::SendAck(uint16 seq) /** * Send out-of-order acknowledgment packet * Notifies peer that a specific packet was received out of sequence - * + * * @param seq - Sequence number that was received out of order */ void EQStream::SendOutOfOrderAck(uint16 seq) @@ -1662,21 +1662,21 @@ void EQStream::SendOutOfOrderAck(uint16 seq) /** * Process packet combination queue to optimize transmission * Combines multiple small packets into larger ones for efficiency - * + * * @return true if all packets processed, false if processing was limited */ bool EQStream::CheckCombineQueue() { bool ret = true; // Processed all packets flag - + MCombineQueueLock.lock(); - + if (combine_queue.size() > 0) { // Get first packet from queue EQ2Packet* first = combine_queue.front(); combine_queue.pop_front(); - + if (combine_queue.size() == 0) { // Nothing to combine with, send immediately @@ -1689,7 +1689,7 @@ bool EQStream::CheckCombineQueue() EQ2Packet* second = nullptr; bool combine_worked = false; int16 count = 0; - + // Attempt to combine with additional packets while (combine_queue.size()) { @@ -1697,7 +1697,7 @@ bool EQStream::CheckCombineQueue() second = combine_queue.front(); combine_queue.pop_front(); PreparePacket(second); - + // Try to combine second packet with first if (!first->AppCombine(second)) { @@ -1711,7 +1711,7 @@ bool EQStream::CheckCombineQueue() { EQ2QueuePacket(first, true); } - + // Make second packet the new first first = second; combine_worked = false; @@ -1721,7 +1721,7 @@ bool EQStream::CheckCombineQueue() // Combination succeeded combine_worked = true; } - + // Limit processing to prevent blocking other clients if (count >= 60 || first->size > 4000) { @@ -1729,7 +1729,7 @@ bool EQStream::CheckCombineQueue() break; } } - + // Send final packet if (first) { @@ -1745,7 +1745,7 @@ bool EQStream::CheckCombineQueue() } } } - + MCombineQueueLock.unlock(); return ret; } @@ -1753,20 +1753,20 @@ bool EQStream::CheckCombineQueue() /** * Check and handle packet retransmission for unacknowledged packets * Retries failed packet deliveries up to maximum attempt limit - * + * * @param eq_fd - Socket file descriptor for transmission */ void EQStream::CheckResend(int eq_fd) { int32 curr = Timer::GetCurrentTime2(); EQProtocolPacket* packet = nullptr; - + MResendQue.lock(); - + for (auto itr = resend_que.begin(); itr != resend_que.end();) { packet = *itr; - + // Check if packet has exceeded maximum retry attempts if (packet->attempt_count >= 5) { @@ -1786,7 +1786,7 @@ void EQStream::CheckResend(int eq_fd) ++itr; continue; } - + // Retry packet transmission packet->sent_time -= 1000; packet->attempt_count++; @@ -1794,7 +1794,7 @@ void EQStream::CheckResend(int eq_fd) ++itr; } } - + MResendQue.unlock(); } @@ -1803,7 +1803,7 @@ void EQStream::CheckResend(int eq_fd) /** * Compare two sequence numbers considering wraparound behavior * Determines temporal relationship between sequence numbers within sliding window - * + * * @param expected_seq - Expected sequence number * @param seq - Actual sequence number to compare * @return SeqOrder indicating temporal relationship (past, in-order, future) @@ -1831,7 +1831,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq, uint16 seq) /** * Process acknowledgment packet and remove acknowledged packets from queue * Handles sliding window advancement and packet cleanup for reliable delivery - * + * * @param seq - Highest sequence number being acknowledged */ void EQStream::AckPackets(uint16 seq) @@ -1839,7 +1839,7 @@ void EQStream::AckPackets(uint16 seq) MOutboundQueue.lock(); SeqOrder ord = CompareSequence(SequencedBase, seq); - + if (ord == SeqInOrder) { // No new acknowledgments - duplicate ack @@ -1857,7 +1857,7 @@ void EQStream::AckPackets(uint16 seq) // Process all packets up to acknowledgment point seq++; // Stop at block right after their ack - + while (SequencedBase != seq) { if (SequencedQueue.empty()) @@ -1867,18 +1867,18 @@ void EQStream::AckPackets(uint16 seq) SequencedBase = NextOutSeq; break; } - + LogWrite(PACKET__DEBUG, 9, "Packet", "Removing acked packet with sequence %u", static_cast(SequencedBase)); - + // Remove acknowledged packet from queue delete SequencedQueue.front(); SequencedQueue.pop_front(); - + // Advance base sequence number SequencedBase++; } - + // Validate queue consistency if (uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { @@ -1893,7 +1893,7 @@ void EQStream::AckPackets(uint16 seq) /** * Main packet transmission loop - processes outbound queues and sends packets * Handles rate limiting, packet combining, acknowledgments, and transmission scheduling - * + * * @param eq_fd - Socket file descriptor for transmission */ void EQStream::Write(int eq_fd) @@ -2078,7 +2078,7 @@ void EQStream::Write(int eq_fd) //this packet will not actually go out until the next call to Write(). SendDisconnect(); //SetState(CLOSED); - } + } MOutboundQueue.unlock(); } } @@ -2087,7 +2087,7 @@ void EQStream::Write(int eq_fd) /** * Write individual protocol packet to network socket * Handles packet serialization, compression, encoding, and UDP transmission - * + * * @param eq_fd - Socket file descriptor for transmission * @param p - EQProtocolPacket to transmit */ @@ -2095,14 +2095,14 @@ void EQStream::WritePacket(int eq_fd, EQProtocolPacket *p) { uint32 length = 0; sockaddr_in address; - + // Set up destination address address.sin_family = AF_INET; address.sin_addr.s_addr = remote_ip; address.sin_port = remote_port; #ifdef NOWAY uint32 ip=address.sin_addr.s_addr; - cout << "Sending to: " + cout << "Sending to: " << (int)*(unsigned char *)&ip << "." << (int)*((unsigned char *)&ip+1) << "." << (int)*((unsigned char *)&ip+2) @@ -2161,7 +2161,7 @@ char temp[15]; ntohs(from->sin_port)); //cout << timestamp() << "Data from: " << temp << " OpCode 0x" << hex << setw(2) << setfill('0') << (int)p->opcode << dec << endl; //dump_message(p->pBuffer,p->size,timestamp()); - + } return p; } @@ -2176,16 +2176,16 @@ void EQStream::SendSessionResponse() struct in_addr addr; addr.s_addr = GetRemoteIP(); LogWrite(PACKET__INFO, 0, "Packet", "Preparing SessionResponse to %s:%d", inet_ntoa(addr), GetRemotePort()); - + auto out = new EQProtocolPacket(OP_SessionResponse, nullptr, sizeof(SessionResponse)); auto Response = reinterpret_cast(out->pBuffer); - + // Set session parameters Response->Session = htonl(Session); Response->MaxLength = htonl(MaxLen); Response->UnknownA = 2; Response->Format = 0; - + // Set format flags based on stream configuration if (compressed) { @@ -2195,14 +2195,14 @@ void EQStream::SendSessionResponse() { Response->Format |= FLAG_ENCODED; } - + Response->Key = htonl(Key); out->size = sizeof(SessionResponse); - - LogWrite(PACKET__INFO, 0, "Packet", "SessionResponse: Session=0x%08X, Key=0x%08X, MaxLength=%d, Format=0x%02X", + + LogWrite(PACKET__INFO, 0, "Packet", "SessionResponse: Session=0x%08X, Key=0x%08X, MaxLength=%d, Format=0x%02X", Session, Key, MaxLen, Response->Format); LogWrite(PACKET__DEBUG, 0, "Packet", "SessionResponse packet size: %d bytes", out->size); - + NonSequencedPush(out); LogWrite(PACKET__INFO, 0, "Packet", "SessionResponse sent successfully"); } @@ -2215,19 +2215,19 @@ void EQStream::SendSessionRequest() { auto out = new EQProtocolPacket(OP_SessionRequest, nullptr, sizeof(SessionRequest)); auto Request = reinterpret_cast(out->pBuffer); - + // Initialize request structure std::memset(Request, 0, sizeof(SessionRequest)); Request->Session = htonl(std::time(nullptr)); Request->MaxLength = htonl(512); - + NonSequencedPush(out); } /** * Send session disconnect packet to peer * Initiates graceful connection termination sequence - * + * * @param setstate - If true, set stream state to CLOSING */ void EQStream::SendDisconnect(bool setstate) @@ -2239,15 +2239,15 @@ void EQStream::SendDisconnect(bool setstate) { return; } - + // Create disconnect packet auto out = new EQProtocolPacket(OP_SessionDisconnect, nullptr, sizeof(uint32) + sizeof(int16)); *reinterpret_cast(out->pBuffer) = htonl(Session); out->pBuffer[4] = 0; out->pBuffer[5] = 6; - + NonSequencedPush(out); - + // Update state if requested if (setstate) { @@ -2263,7 +2263,7 @@ void EQStream::SendDisconnect(bool setstate) /** * Add application packet to inbound queue for processing * Thread-safe method to queue received packets for application layer - * + * * @param p - EQApplicationPacket to add to inbound queue */ void EQStream::InboundQueuePush(EQApplicationPacket *p) @@ -2276,7 +2276,7 @@ void EQStream::InboundQueuePush(EQApplicationPacket *p) /** * Retrieve next application packet from inbound queue * Thread-safe method to get received packets for application processing - * + * * @return Next EQApplicationPacket from queue, or nullptr if queue is empty */ EQApplicationPacket *EQStream::PopPacket() @@ -2290,7 +2290,7 @@ EQApplicationPacket *EQStream::PopPacket() InboundQueue.pop_front(); } MInboundQueue.unlock(); - + // Set client version for compatibility if (p) { @@ -2316,7 +2316,7 @@ void EQStream::InboundQueueClear() /** * Legacy packet encryption function (currently unused) * Placeholder for packet-level encryption functionality - * + * * @param data - Packet data buffer * @param size - Size of packet data */ @@ -2330,19 +2330,19 @@ void EQStream::EncryptPacket(uchar* data, int16 size) /** * Check if stream has pending outbound data * Determines if there are packets waiting to be transmitted - * + * * @return true if outbound data is available, false otherwise */ bool EQStream::HasOutgoingData() { bool flag; - + // Once closed, we have nothing more to say if (CheckClosed()) { return false; } - + // Check for queued packets MOutboundQueue.lock(); flag = (!NonSequencedQueue.empty()); @@ -2378,28 +2378,28 @@ bool EQStream::HasOutgoingData() void EQStream::OutboundQueueClear() { MOutboundQueue.lock(); - + // Clear non-sequenced queue while (NonSequencedQueue.size()) { delete NonSequencedQueue.front(); NonSequencedQueue.pop(); } - + // Clear sequenced queue while (SequencedQueue.size()) { delete SequencedQueue.front(); SequencedQueue.pop_front(); } - + MOutboundQueue.unlock(); } /** * Process incoming raw network data into protocol packets * Handles decompression, decoding, validation, and packet creation - * + * * @param buffer - Raw network data buffer * @param length - Length of network data */ @@ -2438,7 +2438,7 @@ DumpPacket(buffer, length); { if (buffer[1]!=0x01 && buffer[1]!=0x02 && buffer[1]!=0x1d) newlength-=2; - + EQProtocolPacket p(newbuffer,newlength); ProcessPacket(&p); } @@ -2458,7 +2458,7 @@ DumpPacket(buffer, length); /** * Get the highest sequence number that has been acknowledged * Thread-safe accessor for maximum acknowledged sequence number - * + * * @return Highest acknowledged sequence number */ long EQStream::GetMaxAckReceived() @@ -2473,7 +2473,7 @@ long EQStream::GetMaxAckReceived() /** * Get the next sequence number that should be acknowledged * Thread-safe accessor for next acknowledgment to send - * + * * @return Next sequence number to acknowledge */ long EQStream::GetNextAckToSend() @@ -2488,7 +2488,7 @@ long EQStream::GetNextAckToSend() /** * Get the last sequence number that was acknowledged * Thread-safe accessor for last sent acknowledgment - * + * * @return Last acknowledged sequence number */ long EQStream::GetLastAckSent() @@ -2503,7 +2503,7 @@ long EQStream::GetLastAckSent() /** * Set the maximum acknowledged sequence number * Updates acknowledgment tracking and cleans up acknowledged packets from resend queue - * + * * @param seq - New maximum acknowledged sequence number */ void EQStream::SetMaxAckReceived(uint32 seq) @@ -2511,13 +2511,13 @@ void EQStream::SetMaxAckReceived(uint32 seq) MAcks.lock(); MaxAckReceived = seq; MAcks.unlock(); - + MOutboundQueue.lock(); if (static_cast(seq) > LastSeqSent) { LastSeqSent = seq; } - + // Clean up acknowledged packets from resend queue MResendQue.lock(); for (auto itr = resend_que.begin(); itr != resend_que.end();) @@ -2544,7 +2544,7 @@ void EQStream::SetMaxAckReceived(uint32 seq) /** * Set the next sequence number to acknowledge * Thread-safe setter for next acknowledgment to send - * + * * @param seq - Next sequence number to acknowledge */ void EQStream::SetNextAckToSend(uint32 seq) @@ -2557,7 +2557,7 @@ void EQStream::SetNextAckToSend(uint32 seq) /** * Set the last sequence number that was acknowledged * Thread-safe setter for last sent acknowledgment - * + * * @param seq - Last acknowledged sequence number */ void EQStream::SetLastAckSent(uint32 seq) @@ -2570,7 +2570,7 @@ void EQStream::SetLastAckSent(uint32 seq) /** * Set the last sequence number that was sent * Thread-safe setter for last transmitted sequence number - * + * * @param seq - Last sent sequence number */ void EQStream::SetLastSeqSent(uint32 seq) @@ -2583,13 +2583,13 @@ void EQStream::SetLastSeqSent(uint32 seq) /** * Configure stream parameters based on stream type * Sets opcode size, compression, and encoding flags for different stream types - * + * * @param type - EQStreamType to configure stream for */ void EQStream::SetStreamType(EQStreamType type) { StreamType = type; - + switch (StreamType) { case LoginStream: @@ -2597,13 +2597,13 @@ void EQStream::SetStreamType(EQStreamType type) compressed = false; encoded = false; break; - + case EQ2Stream: app_opcode_size = 2; compressed = false; encoded = false; break; - + case ChatOrMailStream: case ChatStream: case MailStream: @@ -2611,7 +2611,7 @@ void EQStream::SetStreamType(EQStreamType type) compressed = false; encoded = true; break; - + case ZoneStream: case WorldStream: default: @@ -2645,7 +2645,7 @@ void EQStream::ProcessQueue() /** * Remove and return packet with specific sequence number from queue * Searches out-of-order packet queue for specified sequence - * + * * @param seq - Sequence number of packet to remove * @return EQProtocolPacket if found, nullptr if not found */ @@ -2671,7 +2671,7 @@ void EQStream::Decay() MRate.lock(); uint32 rate = DecayRate; MRate.unlock(); - + if (BytesWritten > 0) { BytesWritten -= rate; @@ -2684,7 +2684,7 @@ void EQStream::Decay() // Check for packet timeouts and flag for retransmission int count = 0; MOutboundQueue.lock(); - + for (auto sitr = SequencedQueue.begin(); sitr != SequencedQueue.end(); ++sitr, count++) { if (!(*sitr)->acked && (*sitr)->sent_time > 0 && @@ -2695,14 +2695,14 @@ void EQStream::Decay() SequencedBase + count); } } - + MOutboundQueue.unlock(); } /** * Adjust transmission rates based on network conditions * Calculates rate thresholds and decay rates from average delta timing - * + * * @param average_delta - Average packet transmission time in milliseconds */ void EQStream::AdjustRates(uint32 average_delta) @@ -2710,18 +2710,18 @@ void EQStream::AdjustRates(uint32 average_delta) if (average_delta && (average_delta <= AVERAGE_DELTA_MAX)) { MRate.lock(); - + // Calculate transmission parameters based on network timing AverageDelta = average_delta; RateThreshold = RATEBASE / average_delta; DecayRate = DECAYBASE / average_delta; - + // Adjust current byte counter if needed if (BytesWritten > RateThreshold) { BytesWritten = RateThreshold + DecayRate; } - + MRate.unlock(); } else diff --git a/source/common/EQStream.h b/source/common/EQStream.h index 7b395ca..55e072e 100644 --- a/source/common/EQStream.h +++ b/source/common/EQStream.h @@ -18,7 +18,7 @@ // Project headers #include "EQPacket.h" -#include "Mutex.h" +#include "mutex.h" #include "opcodemgr.h" #include "misc.h" #include "crypto/crypto.h" diff --git a/source/common/Mutex.cpp b/source/common/Mutex.cpp deleted file mode 100644 index 732e451..0000000 --- a/source/common/Mutex.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - EQ2Emulator: Everquest II Server Emulator - Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) - - This file is part of EQ2Emulator. - - EQ2Emulator 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. - - EQ2Emulator 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 EQ2Emulator. If not, see . -*/ -#include "../common/Log.h" -#include "../common/debug.h" -#include "../common/Mutex.h" - -Mutex::Mutex() { - readers = 0; - mlocked = false; - writing = false; - name = ""; -#ifdef DEBUG - stack.clear(); -#endif - //CSLock is a pointer so we can use a different attribute type on create - CSLock = new CriticalSection(MUTEX_ATTRIBUTE_RECURSIVE); -} - -Mutex::~Mutex() { - safe_delete(CSLock); -#ifdef DEBUG - stack.clear(); -#endif -} - -void Mutex::SetName(string in_name) { -#ifdef DEBUG - name = in_name; -#endif -} - -void Mutex::lock() { -#ifdef DEBUG - int i = 0; -#endif - if (name.length() > 0) { - while (mlocked) { -#ifdef DEBUG - if (i > MUTEX_TIMEOUT_MILLISECONDS) { - LogWrite(MUTEX__ERROR, 0, "Mutex", "Possible deadlock attempt by '%s'!", name.c_str()); - return; - } - i++; -#endif - Sleep(1); - } - } - mlocked = true; - CSLock->lock(); -} - -bool Mutex::trylock() { - return CSLock->trylock(); -} - -void Mutex::unlock() { - CSLock->unlock(); - mlocked = false; -} - -void Mutex::readlock(const char* function, int32 line) { -#ifdef DEBUG - int32 i = 0; -#endif - while (true) { - //Loop until there isn't a writer, then we can read! - CSRead.lock(); - if (!writing) { - readers++; - CSRead.unlock(); -#ifdef DEBUG - CSStack.lock(); - if (function) - stack[(string)function]++; - CSStack.unlock(); -#endif - return; - } - CSRead.unlock(); -#ifdef DEBUG - if (i > MUTEX_TIMEOUT_MILLISECONDS) { - LogWrite(MUTEX__ERROR, 0, "Mutex", "The mutex %s called from %s at line %u timed out waiting for a readlock!", name.c_str(), function ? function : "name_not_provided", line); - LogWrite(MUTEX__ERROR, 0, "Mutex", "The following functions had locks:"); - map::iterator itr; - CSStack.lock(); - for (itr = stack.begin(); itr != stack.end(); itr++) { - if (itr->second > 0 && itr->first.length() > 0) - LogWrite(MUTEX__ERROR, 0, "Mutex", "%s, number of locks = %u", itr->first.c_str(), itr->second); - } - CSStack.unlock(); - i = 0; - continue; - } - i++; -#endif - Sleep(1); - } -} - -void Mutex::releasereadlock(const char* function, int32 line) { - //Wait for the readcount lock - CSRead.lock(); - //Lower the readcount by one, when readcount is 0 writers may start writing - readers--; - CSRead.unlock(); -#ifdef DEBUG - CSStack.lock(); - if (function) { - map::iterator itr = stack.find((string)function); - if (itr != stack.end()) { - if (--(itr->second) == 0) { - stack.erase(itr); - } - } - } - CSStack.unlock(); -#endif -} - -bool Mutex::tryreadlock(const char* function) { - //This returns true if able to instantly obtain a readlock, false if not - CSRead.lock(); - if (!writing) { - readers++; - CSRead.unlock(); - } - else { - CSRead.unlock(); - return false; - } - -#ifdef DEBUG - CSStack.lock(); - if (function) - stack[(string)function]++; - CSStack.unlock(); -#endif - - return true; -} - -void Mutex::writelock(const char* function, int32 line) { - //Wait until the writer lock becomes available, then we can be the only writer! -#ifdef DEBUG - int32 i = 0; -#endif - while (!CSWrite.trylock()) { -#ifdef DEBUG - if (i > MUTEX_TIMEOUT_MILLISECONDS) { - LogWrite(MUTEX__ERROR, 0, "Mutex", "The mutex %s called from %s at line %u timed out waiting on another writelock!", name.c_str(), function ? function : "name_not_provided", line); - LogWrite(MUTEX__ERROR, 0, "Mutex", "The following functions had locks:"); - map::iterator itr; - CSStack.lock(); - for (itr = stack.begin(); itr != stack.end(); itr++) { - if (itr->second > 0 && itr->first.length() > 0) - LogWrite(MUTEX__ERROR, 0, "Mutex", "%s, number of locks = %u", itr->first.c_str(), itr->second); - } - CSStack.unlock(); - i = 0; - continue; - } - i++; -#endif - Sleep(1); - } - waitReaders(function, line); -#ifdef DEBUG - CSStack.lock(); - if (function) - stack[(string)function]++; - CSStack.unlock(); -#endif -} - -void Mutex::releasewritelock(const char* function, int32 line) { - //Wait for the readcount lock - CSRead.lock(); - //Readers are aloud again - writing = false; - CSRead.unlock(); - //Allow other writers to write - CSWrite.unlock(); -#ifdef DEBUG - CSStack.lock(); - if (function) { - map::iterator itr = stack.find((string)function); - if (itr != stack.end()) { - if (--(itr->second) == 0) { - stack.erase(itr); - } - } - } - CSStack.unlock(); -#endif -} - -bool Mutex::trywritelock(const char* function) { - //This returns true if able to instantly obtain a writelock, false if not - if (CSWrite.trylock()) { - CSRead.lock(); - if (readers == 0) - writing = true; - CSRead.unlock(); - if (!writing) { - CSWrite.unlock(); - return false; - } - } - else - return false; - -#ifdef DEBUG - CSStack.lock(); - if (function) - stack[(string)function]++; - CSStack.unlock(); -#endif - - return true; -} - -void Mutex::waitReaders(const char* function, int32 line) -{ - //Wait for all current readers to stop, then we can write! -#ifdef DEBUG - int32 i = 0; -#endif - while (true) - { - CSRead.lock(); - if (readers == 0) - { - writing = true; - CSRead.unlock(); - break; - } - CSRead.unlock(); -#ifdef DEBUG - if (i > MUTEX_TIMEOUT_MILLISECONDS) { - LogWrite(MUTEX__ERROR, 0, "Mutex", "The mutex %s called from %s at line %u timed out while waiting on readers!", name.c_str(), function ? function : "name_not_provided", line); - LogWrite(MUTEX__ERROR, 0, "Mutex", "The following functions had locks:"); - map::iterator itr; - CSStack.lock(); - for (itr = stack.begin(); itr != stack.end(); itr++) { - if (itr->second > 0 && itr->first.length() > 0) - LogWrite(MUTEX__ERROR, 0, "Mutex", "%s, number of locks = %u", itr->first.c_str(), itr->second); - } - CSStack.unlock(); - i = 0; - continue; - } - i++; -#endif - Sleep(1); - } -} - -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; -} - -CriticalSection::CriticalSection(int attribute) { -#ifdef WIN32 - InitializeCriticalSection(&CSMutex); -#else - pthread_mutexattr_init(&type_attribute); - switch (attribute) - { - case MUTEX_ATTRIBUTE_FAST: - pthread_mutexattr_settype(&type_attribute, PTHREAD_MUTEX_FAST_NP); - break; - case MUTEX_ATTRIBUTE_RECURSIVE: - pthread_mutexattr_settype(&type_attribute, PTHREAD_MUTEX_RECURSIVE_NP); - break; - case MUTEX_ATTRIBUTE_ERRORCHK: - pthread_mutexattr_settype(&type_attribute, PTHREAD_MUTEX_ERRORCHECK_NP); - break; - default: - LogWrite(MUTEX__DEBUG, 0, "Critical Section", "Invalid mutex attribute type! Using PTHREAD_MUTEX_FAST_NP"); - pthread_mutexattr_settype(&type_attribute, PTHREAD_MUTEX_FAST_NP); - break; - } - pthread_mutex_init(&CSMutex, &type_attribute); -#endif -} - -CriticalSection::~CriticalSection() { -#ifdef WIN32 - DeleteCriticalSection(&CSMutex); -#else - pthread_mutex_destroy(&CSMutex); - pthread_mutexattr_destroy(&type_attribute); -#endif -} - -void CriticalSection::lock() { - //Waits for a lock on this critical section -#ifdef WIN32 - EnterCriticalSection(&CSMutex); -#else - pthread_mutex_lock(&CSMutex); -#endif -} - -void CriticalSection::unlock() { - //Gets rid of one of the current thread's locks on this critical section -#ifdef WIN32 - LeaveCriticalSection(&CSMutex); -#else - pthread_mutex_unlock(&CSMutex); -#endif -} - -bool CriticalSection::trylock() { - //Returns true if able to instantly get a lock on this critical section, false if not -#ifdef WIN32 - return TryEnterCriticalSection(&CSMutex); -#else - return (pthread_mutex_trylock(&CSMutex) == 0); -#endif -} - diff --git a/source/common/Mutex.h b/source/common/Mutex.h deleted file mode 100644 index 0446f27..0000000 --- a/source/common/Mutex.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2007-2025 EQ2EMulator -// Licensed under GPL v3 -#ifndef MYMUTEX_H -#define MYMUTEX_H -#ifdef WIN32 - #include - #include -#else - #include - #include "../common/unix.h" -#endif -#include "../common/types.h" -#include -#include - -#define MUTEX_ATTRIBUTE_FAST 1 -#define MUTEX_ATTRIBUTE_RECURSIVE 2 -#define MUTEX_ATTRIBUTE_ERRORCHK 3 -#define MUTEX_TIMEOUT_MILLISECONDS 10000 - -class CriticalSection { -public: - CriticalSection(int attribute = MUTEX_ATTRIBUTE_FAST); - ~CriticalSection(); - void lock(); - void unlock(); - bool trylock(); -private: -#ifdef WIN32 - CRITICAL_SECTION CSMutex; -#else - pthread_mutex_t CSMutex; - pthread_mutexattr_t type_attribute; -#endif -}; - -class Mutex { -public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - bool trylock(); - - void readlock(const char* function = 0, int32 line = 0); - void releasereadlock(const char* function = 0, int32 line = 0); - bool tryreadlock(const char* function = 0); - - void writelock(const char* function = 0, int32 line = 0); - void releasewritelock(const char* function = 0, int32 line = 0); - bool trywritelock(const char* function = 0); - - void waitReaders(const char* function = 0, int32 line = 0); - - void SetName(string in_name); -private: - CriticalSection CSRead; - CriticalSection CSWrite; - CriticalSection* CSLock; - -#ifdef DEBUG //Used for debugging only - CriticalSection CSStack; - map stack; -#endif - - int readers; - bool writing; - volatile bool mlocked; - string name; -}; - - -class LockMutex { -public: - LockMutex(Mutex* in_mut, bool iLock = true); - ~LockMutex(); - void unlock(); - void lock(); -private: - bool locked; - Mutex* mut; -}; - - -#endif diff --git a/source/common/TCPConnection.h b/source/common/TCPConnection.h index 92a612e..bc21ac5 100644 --- a/source/common/TCPConnection.h +++ b/source/common/TCPConnection.h @@ -30,7 +30,7 @@ #endif #include "types.h" -#include "Mutex.h" +#include "mutex.h" #include "linked_list.h" #include "queue.h" #include "servertalk.h" @@ -139,7 +139,7 @@ protected: bool GetAsyncConnect(); bool SetAsyncConnect(bool iValue); char* charAsyncConnect; - + #ifdef WIN32 friend class TCPConnection; #endif diff --git a/source/common/database.h b/source/common/database.h index e4f1200..605f3bc 100644 --- a/source/common/database.h +++ b/source/common/database.h @@ -14,7 +14,7 @@ #include "linked_list.h" #include "EQStream.h" #include "MiscFunctions.h" -#include "Mutex.h" +#include "mutex.h" #include #include #include @@ -46,7 +46,7 @@ public: void AddActiveQuery(Query* query); bool IsActiveQuery(int32 id, Query* skip=0); void PingAsyncDatabase(); - + void AddPeerActiveQuery(int32 charID); void RemovePeerActiveQuery(int32 charID); #endif @@ -138,7 +138,7 @@ public: *row = mysql_fetch_row(result); if(row && result && field_num < mysql_num_fields(result)) return *row[field_num]; - else + else return NULL; } void NextRow(){ diff --git a/source/common/dbcore.h b/source/common/dbcore.h index f7a08cc..6d3d40a 100644 --- a/source/common/dbcore.h +++ b/source/common/dbcore.h @@ -10,7 +10,7 @@ #endif #include #include "../common/types.h" -#include "../common/Mutex.h" +#include "../common/mutex.h" #include "../common/linked_list.h" #include "../common/queue.h" #include "../common/timer.h" @@ -38,7 +38,7 @@ public: char* getEscapeString(const char* from_string); string getSafeEscapeString(const char* from_string); string getSafeEscapeString(string* from_string); - + protected: bool Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase, int32 iPort, int32* errnum = 0, char* errbuf = 0, bool iCompress = false, bool iSSL = false); bool ReadDBINI(char *host, char *user, char *pass, char *db, unsigned int* port, bool* compress, bool *items); @@ -48,7 +48,7 @@ private: MYSQL mysql; Mutex MDatabase; eStatus pStatus; - + char* pHost; char* pUser; char* pPassword; @@ -58,5 +58,3 @@ private: bool pSSL; }; #endif - - diff --git a/source/common/mutex.cpp b/source/common/mutex.cpp new file mode 100644 index 0000000..42e6582 --- /dev/null +++ b/source/common/mutex.cpp @@ -0,0 +1,238 @@ +// Copyright (C) 2007-2025 EQ2EMulator +// Licensed under GPL v3 + +#include "mutex.h" + +// CriticalSection implementation +CriticalSection::CriticalSection(int attribute) : mutex_type(attribute) +{ + if (mutex_type == MUTEX_ATTRIBUTE_RECURSIVE) { + recursive_mutex = std::make_unique(); + } else { + regular_mutex = std::make_unique(); + } +} + +void CriticalSection::lock() +{ + if (recursive_mutex) { + recursive_mutex->lock(); + } else { + regular_mutex->lock(); + } +} + +void CriticalSection::unlock() +{ + if (recursive_mutex) { + recursive_mutex->unlock(); + } else { + regular_mutex->unlock(); + } +} + +bool CriticalSection::trylock() +{ + if (recursive_mutex) { + return recursive_mutex->try_lock(); + } else { + return regular_mutex->try_lock(); + } +} + +// Mutex implementation +Mutex::Mutex() : name("") +{ +#ifdef DEBUG + stack.clear(); +#endif +} + +void Mutex::SetName(std::string in_name) +{ + name = in_name; +} + +void Mutex::lock() +{ +#ifdef DEBUG + if (!name.empty()) { + auto start = std::chrono::steady_clock::now(); + while (!basic_mutex.try_lock()) { + auto elapsed = std::chrono::duration_cast( + std::chrono::steady_clock::now() - start).count(); + if (elapsed > MUTEX_TIMEOUT_MILLISECONDS) { + LogWrite(MUTEX__ERROR, 0, "Mutex", "Possible deadlock attempt by '%s'!", name.c_str()); + return; + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } else { + basic_mutex.lock(); + } +#else + basic_mutex.lock(); +#endif +} + +bool Mutex::trylock() +{ + return basic_mutex.try_lock(); +} + +void Mutex::unlock() +{ + basic_mutex.unlock(); +} + +void Mutex::readlock([[maybe_unused]] const char* function, [[maybe_unused]] std::int32_t line) +{ +#ifdef DEBUG + auto start = std::chrono::steady_clock::now(); + while (!rw_mutex.try_lock_shared()) { + auto elapsed = std::chrono::duration_cast( + std::chrono::steady_clock::now() - start).count(); + if (elapsed > MUTEX_TIMEOUT_MILLISECONDS) { + logDeadlock(function, line, "readlock"); + start = std::chrono::steady_clock::now(); // Reset timer and continue + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + addDebugLock(function); +#else + rw_mutex.lock_shared(); +#endif +} + +void Mutex::releasereadlock([[maybe_unused]] const char* function, [[maybe_unused]] std::int32_t line) +{ + rw_mutex.unlock_shared(); +#ifdef DEBUG + removeDebugLock(function); +#endif +} + +bool Mutex::tryreadlock([[maybe_unused]] const char* function) +{ + bool result = rw_mutex.try_lock_shared(); +#ifdef DEBUG + if (result && function) { + addDebugLock(function); + } +#endif + return result; +} + +void Mutex::writelock([[maybe_unused]] const char* function, [[maybe_unused]] std::int32_t line) +{ +#ifdef DEBUG + auto start = std::chrono::steady_clock::now(); + while (!rw_mutex.try_lock()) { + auto elapsed = std::chrono::duration_cast( + std::chrono::steady_clock::now() - start).count(); + if (elapsed > MUTEX_TIMEOUT_MILLISECONDS) { + logDeadlock(function, line, "writelock"); + start = std::chrono::steady_clock::now(); // Reset timer and continue + } + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + addDebugLock(function); +#else + rw_mutex.lock(); +#endif +} + +void Mutex::releasewritelock([[maybe_unused]] const char* function, [[maybe_unused]] std::int32_t line) +{ + rw_mutex.unlock(); +#ifdef DEBUG + removeDebugLock(function); +#endif +} + +bool Mutex::trywritelock([[maybe_unused]] const char* function) +{ + bool result = rw_mutex.try_lock(); +#ifdef DEBUG + if (result && function) { + addDebugLock(function); + } +#endif + return result; +} + +void Mutex::waitReaders(const char* function, std::int32_t line) +{ + // Wait until we can get a write lock (which means no readers) + writelock(function, line); + releasewritelock(function, line); +} + +#ifdef DEBUG +void Mutex::addDebugLock(const char* function) +{ + if (function) { + std::lock_guard guard(debug_mutex); + stack[std::string(function)]++; + } +} + +void Mutex::removeDebugLock(const char* function) +{ + if (function) { + std::lock_guard guard(debug_mutex); + auto itr = stack.find(std::string(function)); + if (itr != stack.end()) { + if (--(itr->second) == 0) { + stack.erase(itr); + } + } + } +} + +void Mutex::logDeadlock(const char* function, std::int32_t line, const char* lock_type) +{ + LogWrite(MUTEX__ERROR, 0, "Mutex", "The mutex %s called from %s at line %u timed out waiting for a %s!", + name.c_str(), function ? function : "name_not_provided", line, lock_type); + LogWrite(MUTEX__ERROR, 0, "Mutex", "The following functions had locks:"); + + std::lock_guard guard(debug_mutex); + for (const auto& [func_name, count] : stack) { + if (count > 0 && !func_name.empty()) { + LogWrite(MUTEX__ERROR, 0, "Mutex", "%s, number of locks = %u", func_name.c_str(), count); + } + } +} +#endif + +// LockMutex implementation +LockMutex::LockMutex(Mutex* in_mut, bool iLock) + : locked(false), mut(in_mut) +{ + if (mut && iLock) { + lock(); + } +} + +LockMutex::~LockMutex() +{ + if (locked) { + unlock(); + } +} + +void LockMutex::lock() +{ + if (mut && !locked) { + mut->lock(); + locked = true; + } +} + +void LockMutex::unlock() +{ + if (mut && locked) { + mut->unlock(); + locked = false; + } +} diff --git a/source/common/mutex.h b/source/common/mutex.h new file mode 100644 index 0000000..e8bc7e2 --- /dev/null +++ b/source/common/mutex.h @@ -0,0 +1,83 @@ +// Copyright (C) 2007-2025 EQ2EMulator +// Licensed under GPL v3 + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#define MUTEX_ATTRIBUTE_FAST 1 +#define MUTEX_ATTRIBUTE_RECURSIVE 2 +#define MUTEX_ATTRIBUTE_ERRORCHK 3 +#define MUTEX_TIMEOUT_MILLISECONDS 10000 + +class CriticalSection +{ +public: + CriticalSection(int attribute = MUTEX_ATTRIBUTE_FAST); + ~CriticalSection() = default; + + void lock(); + void unlock(); + bool trylock(); + +private: + std::unique_ptr regular_mutex; + std::unique_ptr recursive_mutex; + int mutex_type; +}; + +class Mutex +{ +public: + Mutex(); + ~Mutex() = default; + + void lock(); + void unlock(); + bool trylock(); + + void readlock(const char* function = nullptr, std::int32_t line = 0); + void releasereadlock(const char* function = nullptr, std::int32_t line = 0); + bool tryreadlock(const char* function = nullptr); + + void writelock(const char* function = nullptr, std::int32_t line = 0); + void releasewritelock(const char* function = nullptr, std::int32_t line = 0); + bool trywritelock(const char* function = nullptr); + + void waitReaders(const char* function = nullptr, std::int32_t line = 0); + + void SetName(std::string in_name); + +private: + std::shared_mutex rw_mutex; + std::mutex basic_mutex; + std::string name; + +#ifdef DEBUG + std::mutex debug_mutex; + std::map stack; + void addDebugLock(const char* function); + void removeDebugLock(const char* function); + void logDeadlock(const char* function, std::int32_t line, const char* lock_type); +#endif +}; + +class LockMutex +{ +public: + LockMutex(Mutex* in_mut, bool iLock = true); + ~LockMutex(); + + void unlock(); + void lock(); + +private: + bool locked; + Mutex* mut; +}; diff --git a/source/common/opcodemgr.h b/source/common/opcodemgr.h index 24e378f..1464eaa 100644 --- a/source/common/opcodemgr.h +++ b/source/common/opcodemgr.h @@ -4,7 +4,7 @@ #define OPCODE_MANAGER_H #include "types.h" -#include "Mutex.h" +#include "mutex.h" #include "emu_opcodes.h" #include @@ -14,19 +14,19 @@ class OpcodeManager { public: OpcodeManager(); virtual ~OpcodeManager() {} - + virtual bool Mutable() { return(false); } virtual bool LoadOpcodes(const char *filename) = 0; virtual bool LoadOpcodes(map* eq, std::string* missingOpcodes = nullptr) = 0; virtual bool ReloadOpcodes(const char *filename) = 0; - + virtual uint16 EmuToEQ(const EmuOpcode emu_op) = 0; virtual EmuOpcode EQToEmu(const uint16 eq_op) = 0; - + static const char *EmuToName(const EmuOpcode emu_op); const char *EQToName(const uint16 emu_op); EmuOpcode NameSearch(const char *name); - + //This has to be public for stupid visual studio class OpcodeSetStrategy { public: @@ -38,7 +38,7 @@ protected: bool loaded; //true if all opcodes loaded Mutex MOpcodes; //this only protects the local machine //in a shared manager, this dosent protect others - + static bool LoadOpcodesFile(const char *filename, OpcodeSetStrategy *s); static bool LoadOpcodesMap(map* eq, OpcodeSetStrategy *s, std::string* missingOpcodes = nullptr); }; @@ -55,14 +55,14 @@ public: class SharedOpcodeManager : public OpcodeManager { public: virtual ~SharedOpcodeManager() {} - + virtual bool LoadOpcodes(const char *filename); virtual bool LoadOpcodes(map* eq, std::string* missingOpcodes = nullptr); virtual bool ReloadOpcodes(const char *filename); - + virtual uint16 EmuToEQ(const EmuOpcode emu_op); virtual EmuOpcode EQToEmu(const uint16 eq_op); - + protected: class SharedMemStrategy : public OpcodeManager::OpcodeSetStrategy { public: @@ -77,18 +77,18 @@ class RegularOpcodeManager : public MutableOpcodeManager { public: RegularOpcodeManager(); virtual ~RegularOpcodeManager(); - + virtual bool Editable() { return(true); } virtual bool LoadOpcodes(const char *filename); virtual bool LoadOpcodes(map* eq, std::string* missingOpcodes = nullptr); virtual bool ReloadOpcodes(const char *filename); - + virtual uint16 EmuToEQ(const EmuOpcode emu_op); virtual EmuOpcode EQToEmu(const uint16 eq_op); - + //implement our editing interface virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op); - + protected: class NormalMemStrategy : public OpcodeManager::OpcodeSetStrategy { public: @@ -96,7 +96,7 @@ protected: void Set(EmuOpcode emu_op, uint16 eq_op); }; friend class NormalMemStrategy; - + uint16 *emu_to_eq; EmuOpcode *eq_to_emu; uint32 EQOpcodeCount; @@ -107,14 +107,14 @@ protected: class NullOpcodeManager : public MutableOpcodeManager { public: NullOpcodeManager(); - + virtual bool LoadOpcodes(const char *filename); virtual bool LoadOpcodes(map* eq, std::string* missingOpcodes = nullptr); virtual bool ReloadOpcodes(const char *filename); - + virtual uint16 EmuToEQ(const EmuOpcode emu_op); virtual EmuOpcode EQToEmu(const uint16 eq_op); - + //fake it, just used for testing anyways virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op) {} }; @@ -125,14 +125,14 @@ public: class EmptyOpcodeManager : public MutableOpcodeManager { public: EmptyOpcodeManager(); - + virtual bool LoadOpcodes(const char *filename); virtual bool LoadOpcodes(map* eq, std::string* missingOpcodes = nullptr); virtual bool ReloadOpcodes(const char *filename); - + virtual uint16 EmuToEQ(const EmuOpcode emu_op); virtual EmuOpcode EQToEmu(const uint16 eq_op); - + //fake it, just used for testing anyways virtual void SetOpcode(EmuOpcode emu_op, uint16 eq_op); protected: @@ -141,5 +141,3 @@ protected: }; #endif - -