PlayerGroups.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #ifndef __PLAYERGROUPS_H__
  17. #define __PLAYERGROUPS_H__
  18. #include <deque>
  19. #include <map>
  20. #include <mutex>
  21. #include <shared_mutex>
  22. #include "Spells.h"
  23. #include "../common/types.h"
  24. #include "Entity.h"
  25. using namespace std;
  26. // GroupOptions isn't used yet
  27. struct GroupOptions {
  28. int8 loot_method;
  29. int8 loot_items_rarity;
  30. int8 auto_split;
  31. int8 default_yell;
  32. int8 group_lock_method;
  33. int8 group_autolock;
  34. int8 solo_autolock;
  35. int8 auto_loot_method;
  36. int8 last_looted_index;
  37. };
  38. /// <summary>All the generic info for the group window, plus a client pointer for players</summary>
  39. struct GroupMemberInfo {
  40. int32 group_id;
  41. string name;
  42. string zone;
  43. sint32 hp_current;
  44. sint32 hp_max;
  45. sint32 power_current;
  46. sint32 power_max;
  47. int16 level_current;
  48. int16 level_max;
  49. int8 race_id;
  50. int8 class_id;
  51. bool leader;
  52. Client* client;
  53. Entity* member;
  54. int32 mentor_target_char_id;
  55. bool is_client;
  56. int32 zone_id;
  57. int32 instance_id;
  58. string client_peer_address;
  59. int16 client_peer_port;
  60. bool is_raid_looter;
  61. };
  62. /// <summary>Represents a players group in game</summary>
  63. class PlayerGroup {
  64. public:
  65. PlayerGroup(int32 id);
  66. ~PlayerGroup();
  67. /// <summary>Adds a new member to the players group</summary>
  68. /// <param name='member'>Entity to add to the group, can be a Player or NPC</param>
  69. /// <returns>True if the member was added</returns>
  70. bool AddMember(Entity* member, bool is_leader);
  71. bool AddMemberFromPeer(std::string name, bool isleader, bool isclient, int8 class_id, sint32 hp_cur, sint32 hp_max, int16 level_cur, int16 level_max,
  72. sint32 power_cur, sint32 power_max, int8 race_id, std::string zonename, int32 mentor_target_char_id, int32 zone_id, int32 instance_id,
  73. std::string peer_client_address, int16 peer_client_port, bool is_raid_looter);
  74. /// <summary>Removes a member from the players group</summary>
  75. /// <param name='member'>Entity to remove from the player group</param>
  76. /// <returns>True if the member was removed</param>
  77. bool RemoveMember(Entity* member);
  78. bool RemoveMember(std::string name, bool is_client, int32 charID);
  79. /// <summary>Removes all members from the group and destroys the group</summary>
  80. void Disband();
  81. /// <summary>Sends updates to all the clients in the group</summary>
  82. /// <param name='exclude'>Client to exclude from the update</param>
  83. void SendGroupUpdate(Client* exclude = 0, bool forceRaidUpdate = false);
  84. /// <summary>Gets the total number of members in the group</summary>
  85. /// <returns>int32, number of members in the group</returns>
  86. int32 Size() { return m_members.size(); }
  87. /// <summary>Gets a pointer to the list of members</summary>
  88. /// <returns>deque pointer</returns>
  89. deque<GroupMemberInfo*>* GetMembers() { return &m_members; }
  90. void SimpleGroupMessage(const char* message);
  91. void SendGroupMessage(int8 type, const char* message, ...);
  92. void GroupChatMessage(Spawn* from, int32 language, const char* message, int16 channel = CHANNEL_GROUP_SAY);
  93. void GroupChatMessage(std::string fromName, int32 language, const char* message, int16 channel = CHANNEL_GROUP_SAY);
  94. bool MakeLeader(Entity* new_leader);
  95. std::string GetLeaderName();
  96. bool ShareQuestWithGroup(Client* quest_sharer, Quest* quest);
  97. void RemoveClientReference(Client* remove);
  98. void UpdateGroupMemberInfo(Entity* ent, bool groupMembersLocked = false);
  99. Entity* GetGroupMemberByPosition(Entity* seeker, int32 mapped_position);
  100. void SetDefaultGroupOptions(GroupOptions* options = nullptr);
  101. bool GetDefaultGroupOptions(GroupOptions* options);
  102. GroupOptions* GetGroupOptions() { return &group_options; }
  103. int8 GetLastLooterIndex() { return group_options.last_looted_index; }
  104. void SetNextLooterIndex(int8 new_index) { group_options.last_looted_index = new_index; }
  105. int32 GetID() { return m_id; }
  106. void GetRaidGroups(std::vector<int32>* groups);
  107. void ReplaceRaidGroups(std::vector<int32>* groups);
  108. bool IsInRaidGroup(int32 groupID, bool isLeaderGroup = false);
  109. void AddGroupToRaid(int32 groupID);
  110. void RemoveGroupFromRaid(int32 groupID);
  111. bool IsGroupRaid();
  112. void ClearGroupRaid();
  113. Mutex MGroupMembers; // Mutex for the group members
  114. private:
  115. GroupOptions group_options;
  116. int32 m_id; // ID of this group
  117. deque<GroupMemberInfo*> m_members; // List of members in this group
  118. std::vector<int32> m_raidgroups;
  119. mutable std::shared_mutex MRaidGroups; // mutex for std vector
  120. };
  121. /// <summary>Responsible for managing all the player groups in the world</summary>
  122. class PlayerGroupManager {
  123. public:
  124. PlayerGroupManager();
  125. ~PlayerGroupManager();
  126. /// <summary>Adds a member to a group</summary>
  127. /// <param name='group_id'>ID of the group to add a member to</param>
  128. /// <param name='member'>Entity* to add to the group</param>
  129. /// <returns>True if the member was added to the group</returns>
  130. bool AddGroupMember(int32 group_id, Entity* member, bool is_leader = false);
  131. bool AddGroupMemberFromPeer(int32 group_id, GroupMemberInfo* info);
  132. /// <summary>Removes a member from a group</summary>
  133. /// <param name='group_id'>ID of the group to remove a member from</param>
  134. /// <param name='member'>Entity* to remove from the group</param>
  135. /// <returns>True if the member was removed from the group</returns>
  136. bool RemoveGroupMember(int32 group_id, Entity* member);
  137. bool RemoveGroupMember(int32 group_id, std::string name, bool is_client, int32 charID);
  138. /// <summary>Creates a new group with the provided Entity* as the leader</summary>
  139. /// <param name='leader'>The Entity* that will be the leader of the group</param>
  140. int32 NewGroup(Entity* leader, GroupOptions* goptions, int32 override_group_id = 0);
  141. /// <summary>Removes the group from the group manager</summary>
  142. /// <param name='group_id'>ID of the group to remove</param>
  143. void RemoveGroup(int32 group_id);
  144. /// <summary>Handles a player inviting another player or NPC to a group</summary>
  145. /// <param name='leader'>Player that sent the invite</param>
  146. /// <param name='member'>Player or NPC that is the target of the invite</param>
  147. /// <returns>Error code if invite was unsuccessful, 0 if successful</returns>
  148. int8 Invite(Player* leader, Entity* member);
  149. bool AddInvite(Player* leader, Entity* member);
  150. /// <summary>Handles accepting of a group invite</summary>
  151. /// <param name='member'>Entity* that is accepting the invite</param>
  152. /// <returns>Error code if accepting the invite failed, 0 if successful<returns>
  153. int8 AcceptInvite(Entity* member, int32* group_override_id = nullptr, bool auto_add_group = true);
  154. /// <summary>Handles declining of a group invite</summary>
  155. /// <param name='member'>Entity* that is declining the invite</param>
  156. void DeclineInvite(Entity* member);
  157. /// <summary>Checks to see if there is a group with the given id in the group manager</summary>
  158. /// <param name='group_id'>ID to check for</param>
  159. /// <returns>True if a group with the given ID is found</returns>
  160. bool IsGroupIDValid(int32 group_id);
  161. /// <summary>Send updates to all the clients in the group</summary>
  162. /// <param name='group_id'>ID of the group to send updates to</param>
  163. /// <param name='exclude'>Client* to exclude from the update, usually the one that triggers the update</param>
  164. void SendGroupUpdate(int32 group_id, Client* exclude = 0, bool forceRaidUpdate = false);
  165. PlayerGroup* GetGroup(int32 group_id);
  166. /// <summary>Read locks the group list, no changes to the list should be made when using this</summary>
  167. /// <param name='function'>Name of the function called from, used for better debugging in the event of a deadlock</param>
  168. /// <param name='line'>Line number that this was called from, used for better debugging in the event of a deadlock</param>
  169. void GroupHardLock(const char* function = 0, int32 line = 0U) { MGroups.lock(); }
  170. void GroupLock(const char* function = 0, int32 line = 0U) { MGroups.lock_shared(); }
  171. /// <summary>Releases the readlock acquired from GroupLock()</summary>
  172. /// <param name='function'>Name of the function called from, used for better debugging in the event of a deadlock</param>
  173. /// <param name='line'>Line number that this was called from, used for better debugging in the event of a deadlock</param>
  174. void ReleaseGroupHardLock(const char* function = 0, int32 line = 0U) { MGroups.unlock(); }
  175. void ReleaseGroupLock(const char* function = 0, int32 line = 0U) { MGroups.unlock_shared(); }
  176. void ClearPendingInvite(Entity* member);
  177. std::string HasPendingInvite(Entity* member);
  178. void RemoveGroupBuffs(int32 group_id, Client* client);
  179. int32 GetGroupSize(int32 group_id);
  180. void SendGroupQuests(int32 group_id, Client* client);
  181. bool HasGroupCompletedQuest(int32 group_id, int32 quest_id);
  182. void SimpleGroupMessage(int32 group_id, const char* message);
  183. void SendGroupMessage(int32 group_id, int8 type, const char* message, ...);
  184. void GroupMessage(int32 group_id, const char* message, ...);
  185. void GroupChatMessage(int32 group_id, Spawn* from, int32 language, const char* message, int16 channel = CHANNEL_GROUP_SAY);
  186. void GroupChatMessage(int32 group_id, std::string fromName, int32 language, const char* message, int16 channel = CHANNEL_GROUP_SAY);
  187. void SendGroupChatMessage(int32 group_id, int16 channel, const char* message, ...);
  188. bool MakeLeader(int32 group_id, Entity* new_leader);
  189. void UpdateGroupBuffs();
  190. bool IsInGroup(int32 group_id, Entity* member);
  191. Entity* IsPlayerInGroup(int32 group_id, int32 char_id);
  192. // TODO: Any function below this comment
  193. bool IsSpawnInGroup(int32 group_id, string name); // used in follow
  194. Player* GetGroupLeader(int32 group_id);
  195. void UpdateGroupMemberInfoFromPeer(int32 group_id, std::string name, bool is_client, GroupMemberInfo* updateinfo);
  196. void SendPeerGroupData(std::string peerId);
  197. void ClearGroupRaid(int32 groupID);
  198. void RemoveGroupFromRaid(int32 groupID, int32 targetGroupID);
  199. bool IsInRaidGroup(int32 groupID, int32 targetGroupID, bool isLeaderGroup = false);
  200. bool GetDefaultGroupOptions(int32 group_id, GroupOptions* options);
  201. void GetRaidGroups(int32 group_id, std::vector<int32>* groups);
  202. void ReplaceRaidGroups(int32 groupID, std::vector<int32>* newGroups);
  203. void SetGroupOptions(int32 groupID, GroupOptions* options);
  204. void SendWhoGroupMembers(Client* client, int32 groupID);
  205. void SendWhoRaidMembers(Client* client, int32 groupID);
  206. int8 AcceptRaidInvite(std::string acceptorName, int32 groupID);
  207. bool SendRaidInvite(Client* sender, Entity* target);
  208. void SplitWithGroupOrRaid(Client* client, int32 coin_plat, int32 coin_gold, int32 coin_silver, int32 coin_copper);
  209. bool IdentifyMemberInGroupOrRaid(ZoneChangeDetails* details, Client* client, int32 zoneID, int32 instanceID = 0);
  210. void ClearGroupRaidLooterFlag(int32 groupID);
  211. private:
  212. int32 m_nextGroupID; // Used to generate a new unique id for new groups
  213. map<int32, PlayerGroup*> m_groups; // int32 is the group id, PlayerGroup* is a pointer to the actual group
  214. map<string, string> m_pendingInvites; // First string is the person invited to the group, second string is the leader of the group
  215. map<string, string> m_raidPendingInvites; // First string is the other group leader invited to the group, second string is the leader of the raid
  216. mutable std::shared_mutex MGroups; // Mutex for the group map (m_groups)
  217. Mutex MPendingInvites; // Mutex for the pending invites map (m_pendingInvites)
  218. };
  219. #endif