TrinityCore
Loading...
Searching...
No Matches
LFGScripts.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Interaction between core and LFGScripts
20 */
21
22#include "LFGScripts.h"
23#include "Common.h"
24#include "Group.h"
25#include "LFGMgr.h"
26#include "Log.h"
27#include "Map.h"
28#include "Player.h"
29#include "ObjectAccessor.h"
30#include "ScriptMgr.h"
31#include "SharedDefines.h"
32#include "WorldSession.h"
33
34namespace lfg
35{
36
38
40{
42 return;
43
44 if (!player->GetGroup())
45 {
46 player->GetSession()->SendLfgLfrList(false);
47 sLFGMgr->LeaveLfg(player->GetGUID());
48 }
49 else if (player->GetSession()->PlayerDisconnected())
50 sLFGMgr->LeaveLfg(player->GetGUID(), true);
51}
52
53void LFGPlayerScript::OnLogin(Player* player, bool /*loginFirst*/)
54{
56 return;
57
58 // Temporal: Trying to determine when group data and LFG data gets desynched
59 ObjectGuid guid = player->GetGUID();
60 ObjectGuid gguid = sLFGMgr->GetGroup(guid);
61
62 if (Group const* group = player->GetGroup())
63 {
64 ObjectGuid gguid2 = group->GetGUID();
65 if (gguid != gguid2)
66 {
67 TC_LOG_ERROR("lfg", "{} on group {} but LFG has group {} saved... Fixing.",
68 player->GetSession()->GetPlayerInfo(), gguid2.ToString(), gguid.ToString());
69 sLFGMgr->SetupGroupMember(guid, group->GetGUID());
70 }
71 }
72
73 sLFGMgr->SetTeam(player->GetGUID(), player->GetTeam());
75}
76
78{
79 Map const* map = player->GetMap();
80
81 if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficulty()))
82 {
83 Group* group = player->GetGroup();
84 // This function is also called when players log in
85 // if for some reason the LFG system recognises the player as being in a LFG dungeon,
86 // but the player was loaded without a valid group, we'll teleport to homebind to prevent
87 // crashes or other undefined behaviour
88 if (!group)
89 {
90 sLFGMgr->LeaveLfg(player->GetGUID());
92 player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, 0.0f);
93 TC_LOG_ERROR("lfg", "LFGPlayerScript::OnMapChanged, Player {} {} is in LFG dungeon map but does not have a valid group! "
94 "Teleporting to homebind.", player->GetName(), player->GetGUID().ToString());
95 return;
96 }
97
98 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
99 if (Player* member = itr->GetSource())
100 player->GetSession()->SendNameQueryOpcode(member->GetGUID());
101
102 if (sLFGMgr->selectedRandomLfgDungeon(player->GetGUID()))
103 player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
104 }
105 else
106 {
107 Group* group = player->GetGroup();
108 if (group && group->GetMembersCount() == 1)
109 {
110 sLFGMgr->LeaveLfg(group->GetGUID());
111 group->Disband();
112 TC_LOG_DEBUG("lfg", "LFGPlayerScript::OnMapChanged, Player {}({}) is last in the lfggroup so we disband the group.",
113 player->GetName(), player->GetGUID().ToString());
114 }
116 }
117}
118
120
122{
124 return;
125
126 ObjectGuid gguid = group->GetGUID();
127 ObjectGuid leader = group->GetLeaderGUID();
128
129 if (leader == guid)
130 {
131 TC_LOG_DEBUG("lfg", "LFGScripts::OnAddMember [{}]: added [{}] leader [{}]", gguid.ToString(), guid.ToString(), leader.ToString());
132 sLFGMgr->SetLeader(gguid, guid);
133 }
134 else
135 {
136 LfgState gstate = sLFGMgr->GetState(gguid);
137 LfgState state = sLFGMgr->GetState(guid);
138 TC_LOG_DEBUG("lfg", "LFGScripts::OnAddMember [{}]: added [{}] leader [{}] gstate: {}, state: {}", gguid.ToString(), guid.ToString(), leader.ToString(), gstate, state);
139
140 if (state == LFG_STATE_QUEUED)
141 sLFGMgr->LeaveLfg(guid);
142
143 if (gstate == LFG_STATE_QUEUED)
144 sLFGMgr->LeaveLfg(gguid);
145 }
146
147 sLFGMgr->SetGroup(guid, gguid);
148 sLFGMgr->AddPlayerToGroup(gguid, guid);
149}
150
151void LFGGroupScript::OnRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, char const* reason)
152{
154 return;
155
156 ObjectGuid gguid = group->GetGUID();
157 TC_LOG_DEBUG("lfg", "LFGScripts::OnRemoveMember [{}]: remove [{}] Method: {} Kicker: [{}] Reason: {}",
158 gguid.ToString(), guid.ToString(), method, kicker.ToString(), (reason ? reason : ""));
159
160 bool isLFG = group->isLFGGroup();
161
162 if (isLFG && method == GROUP_REMOVEMETHOD_KICK) // Player have been kicked
163 {
165 std::string str_reason = "";
166 if (reason)
167 str_reason = std::string(reason);
168 sLFGMgr->InitBoot(gguid, kicker, guid, str_reason);
169 return;
170 }
171
172 LfgState state = sLFGMgr->GetState(gguid);
173
174 // If group is being formed after proposal success do nothing more
175 if (state == LFG_STATE_PROPOSAL && method == GROUP_REMOVEMETHOD_DEFAULT)
176 {
177 // LfgData: Remove player from group
178 sLFGMgr->SetGroup(guid, ObjectGuid::Empty);
179 sLFGMgr->RemovePlayerFromGroup(gguid, guid);
180 return;
181 }
182
183 sLFGMgr->LeaveLfg(guid);
184 sLFGMgr->SetGroup(guid, ObjectGuid::Empty);
185 uint8 players = sLFGMgr->RemovePlayerFromGroup(gguid, guid);
186
187 if (Player* player = ObjectAccessor::FindPlayer(guid))
188 {
189 if (method == GROUP_REMOVEMETHOD_LEAVE && state == LFG_STATE_DUNGEON &&
191 player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, true);
192 else if (method == GROUP_REMOVEMETHOD_KICK_LFG)
193 player->RemoveAurasDueToSpell(LFG_SPELL_DUNGEON_COOLDOWN);
194 //else if (state == LFG_STATE_BOOT)
195 // Update internal kick cooldown of kicked
196
197 player->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_LEADER_UNK1));
198 if (isLFG && player->GetMap()->IsDungeon()) // Teleport player out the dungeon
199 sLFGMgr->TeleportPlayer(player, true);
200 }
201
202 if (isLFG && state != LFG_STATE_FINISHED_DUNGEON) // Need more players to finish the dungeon
203 if (Player* leader = ObjectAccessor::FindConnectedPlayer(sLFGMgr->GetLeader(gguid)))
204 leader->GetSession()->SendLfgOfferContinue(sLFGMgr->GetDungeon(gguid, false));
205}
206
208{
210 return;
211
212 ObjectGuid gguid = group->GetGUID();
213 TC_LOG_DEBUG("lfg", "LFGScripts::OnDisband [{}]", gguid.ToString());
214
215 sLFGMgr->RemoveGroupData(gguid);
216}
217
218void LFGGroupScript::OnChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid)
219{
221 return;
222
223 ObjectGuid gguid = group->GetGUID();
224
225 TC_LOG_DEBUG("lfg", "LFGScripts::OnChangeLeader [{}]: old [{}] new [{}]",
226 gguid.ToString(), newLeaderGuid.ToString(), oldLeaderGuid.ToString());
227
228 sLFGMgr->SetLeader(gguid, newLeaderGuid);
229}
230
232{
234 return;
235
236 ObjectGuid gguid = group->GetGUID();
237 ObjectGuid leader = group->GetLeaderGUID();
238 TC_LOG_DEBUG("lfg", "LFGScripts::OnInviteMember [{}]: invite [{}] leader [{}]",
239 gguid.ToString(), guid.ToString(), leader.ToString());
240
241 // No gguid == new group being formed
242 // No leader == after group creation first invite is new leader
243 // leader and no gguid == first invite after leader is added to new group (this is the real invite)
244 if (!leader.IsEmpty() && gguid.IsEmpty())
245 sLFGMgr->LeaveLfg(leader);
246}
247
249{
250 new LFGPlayerScript();
251 new LFGGroupScript();
252}
253
254} // namespace lfg
uint8_t uint8
Definition Define.h:135
#define sLFGMgr
Definition LFGMgr.h:492
#define TC_LOG_DEBUG(filterType__,...)
Definition Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
RemoveMethod
@ GROUP_REMOVEMETHOD_KICK_LFG
@ GROUP_REMOVEMETHOD_DEFAULT
@ GROUP_REMOVEMETHOD_KICK
@ GROUP_REMOVEMETHOD_LEAVE
Definition Group.h:165
bool isLFGGroup() const
Definition Group.cpp:2443
void Disband(bool hideDestroy=false)
Definition Group.cpp:809
ObjectGuid GetGUID() const
Definition Group.cpp:2473
uint32 GetMembersCount() const
Definition Group.h:249
GroupReference * GetFirstMember()
Definition Group.h:247
ObjectGuid GetLeaderGUID() const
Definition Group.cpp:2468
Definition Map.h:281
uint32 GetId() const
Definition Map.cpp:4216
Difficulty GetDifficulty() const
Definition Map.h:412
static ObjectGuid const Empty
Definition ObjectGuid.h:140
bool IsEmpty() const
Definition ObjectGuid.h:172
std::string ToString() const
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
uint32 GetTeam() const
Definition Player.h:1832
float m_homebindZ
Definition Player.h:2089
uint32 m_homebindMapId
Definition Player.h:2085
WorldSession * GetSession() const
Definition Player.h:1719
float m_homebindY
Definition Player.h:2088
Group * GetGroup()
Definition Player.h:2171
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:1524
float m_homebindX
Definition Player.h:2087
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3784
Map * GetMap() const
Definition Object.h:449
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
std::string const & GetName() const
Definition Object.h:382
bool PlayerDisconnected() const
void SendNameQueryOpcode(ObjectGuid guid)
void SendLfgLfrList(bool update)
std::string GetPlayerInfo() const
void OnRemoveMember(Group *group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, char const *reason) override
void OnInviteMember(Group *group, ObjectGuid guid) override
void OnChangeLeader(Group *group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid) override
void OnAddMember(Group *group, ObjectGuid guid) override
void OnDisband(Group *group) override
void OnLogout(Player *player) override
void OnMapChanged(Player *player) override
void OnLogin(Player *player, bool loginFirst) override
TC_GAME_API Player * FindPlayer(ObjectGuid const &)
TC_GAME_API Player * FindConnectedPlayer(ObjectGuid const &)
Definition LFG.cpp:24
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
Definition LFGMgr.h:42
@ LFG_OPTION_ENABLE_RAID_BROWSER
Definition LFGMgr.h:43
LfgState
Definition LFG.h:66
@ LFG_STATE_FINISHED_DUNGEON
Definition LFG.h:73
@ LFG_STATE_DUNGEON
Definition LFG.h:72
@ LFG_STATE_PROPOSAL
Definition LFG.h:70
@ LFG_STATE_QUEUED
Definition LFG.h:69
@ LFG_UPDATETYPE_LEADER_UNK1
Definition LFG.h:50
@ LFG_SPELL_DUNGEON_COOLDOWN
Definition LFGMgr.h:52
@ LFG_GROUP_KICK_VOTES_NEEDED
Definition LFGMgr.h:55
@ LFG_SPELL_LUCK_OF_THE_DRAW
Definition LFGMgr.h:54
@ LFG_SPELL_DUNGEON_DESERTER
Definition LFGMgr.h:53
void AddSC_LFGScripts()