diff --git a/Framework/Constants/LFGConst.cs b/Framework/Constants/LFGConst.cs index 1e6583800..52475db68 100644 --- a/Framework/Constants/LFGConst.cs +++ b/Framework/Constants/LFGConst.cs @@ -41,14 +41,18 @@ namespace Framework.Constants ProposalDeclined = 10, GroupFound = 11, AddedToQueue = 13, - ProposalBegin = 14, - UpdateStatus = 15, - GroupMemberOffline = 16, - GroupDisbandUnk16 = 17, // Fixme: Sometimes At Group Disband - JoinQueueInitial = 24, - DungeonFinished = 25, - PartyRoleNotAvailable = 43, - JoinLfgObjectFailed = 45, + SuspendedQueue = 14, + ProposalBegin = 15, + UpdateStatus = 16, + GroupMemberOffline = 17, + GroupDisbandUnk16 = 18, // FIXME: Sometimes at group disband + JoinQueueInitial = 25, + DungeonFinished = 26, + PartyRoleNotAvailable = 46, + JoinLfgObjectFailed = 48, + RemovedLevelup = 49, + RemovedXpToggle = 50, + RemovedFactionChange = 51 } public enum LfgState @@ -63,6 +67,15 @@ namespace Framework.Constants Raidbrowser } + public enum LfgQueueType + { + Dungeon = 1, + LRF = 2, + Scenario = 3, + Flex = 4, + WorldPvP = 5 + } + public enum LfgLockStatusType { InsufficientExpansion = 1, @@ -113,36 +126,47 @@ namespace Framework.Constants public enum LfgTeleportResult { // 7 = "You Can'T Do That Right Now" | 5 = No Client Reaction - Ok = 0, // Internal Use - PlayerDead = 1, + None = 0, // Internal Use + Dead = 1, Falling = 2, - InVehicle = 3, - Fatigue = 4, - InvalidLocation = 6, - Charming = 8 // Fixme - It Can Be 7 Or 8 (Need Proper Data) + OnTransport = 3, + Exhaustion = 4, + NoReturnLocation = 6, + ImmuneToSummons = 8 // Fixme - It Can Be 7 Or 8 (Need Proper Data) + + // unknown values + //LFG_TELEPORT_RESULT_NOT_IN_DUNGEON, + //LFG_TELEPORT_RESULT_NOT_ALLOWED, + //LFG_TELEPORT_RESULT_ALREADY_IN_DUNGEON } public enum LfgJoinResult { - // 3 = No Client Reaction | 18 = "Rolecheck Failed" - Ok = 0x00, // Joined (No Client Msg) - Failed = 0x1b, // Rolecheck Failed - Groupfull = 0x1c, // Your Group Is Full - InternalError = 0x1e, // Internal Lfg Error - NotMeetReqs = 0x1f, // You Do Not Meet The Requirements For The Chosen Dungeons - PartyNotMeetReqs = 6, // One Or More Party Members Do Not Meet The Requirements For The Chosen Dungeons - MixedRaidDungeon = 0x20, // You Cannot Mix Dungeons, Raids, And Random When Picking Dungeons - MultiRealm = 0x21, // The Dungeon You Chose Does Not Support Players From Multiple Realms - Disconnected = 0x22, // One Or More Party Members Are Pending Invites Or Disconnected - PartyInfoFailed = 0x23, // Could Not Retrieve Information About Some Party Members - DungeonInvalid = 0x24, // One Or More Dungeons Was Not Valid - Deserter = 0x25, // You Can Not Queue For Dungeons Until Your Deserter Debuff Wears Off - PartyDeserter = 0x26, // One Or More Party Members Has A Deserter Debuff - RandomCooldown = 0x27, // You Can Not Queue For Random Dungeons While On Random Dungeon Cooldown - PartyRandomCooldown = 0x28, // One Or More Party Members Are On Random Dungeon Cooldown - TooMuchMembers = 0x29, // You Can Not Enter Dungeons With More That 5 Party Members - UsingBgSystem = 0x2a, // You Can Not Use The Dungeon System While In Bg Or Arenas - RoleCheckFailed = 0x2b // Role Check Failed, Client Shows Special Error + // 3 = No client reaction | 18 = "Rolecheck failed" + Ok = 0x00, // Joined (No Client Msg) + GroupFull = 0x1f, // Your Group Is Already Full. + NoLfgObject = 0x21, // Internal Lfg Error. + NoSlotsPlayer = 0x22, // You Do Not Meet The Requirements For The Chosen Dungeons. + MismatchedSlots = 0x23, // You Cannot Mix Dungeons, Raids, And Random When Picking Dungeons. + PartyPlayersFromDifferentRealms = 0x24, // The Dungeon You Chose Does Not Support Players From Multiple Realms. + MembersNotPresent = 0x25, // One Or More Group Members Are Pending Invites Or Disconnected. + GetInfoTimeout = 0x26, // Could Not Retrieve Information About Some Party Members. + InvalidSlot = 0x27, // One Or More Dungeons Was Not Valid. + DeserterPlayer = 0x28, // You Can Not Queue For Dungeons Until Your Deserter Debuff Wears Off. + DeserterParty = 0x29, // One Or More Party Members Has A Deserter Debuff. + RandomCooldownPlayer = 0x2a, // You Can Not Queue For Random Dungeons While On Random Dungeon Cooldown. + RandomCooldownParty = 0x2b, // One Or More Party Members Are On Random Dungeon Cooldown. + TooManyMembers = 0x2c, // You Have Too Many Group Members To Queue For That. + CantUseDungeons = 0x2d, // You Cannot Queue For A Dungeon Or Raid While Using Battlegrounds Or Arenas. + RoleCheckFailed = 0x2e, // The Role Check Has Failed. + TooFewMembers = 0x34, // You Do Not Have Enough Group Members To Queue For That. + ReasonTooManyLfg = 0x35, // You Are Queued For Too Many Instances. + MismatchedSlotsLocalXrealm = 0x37, // You Cannot Mix Realm-Only And X-Realm Entries When Listing Your Name In Other Raids. + AlreadyUsingLfgList = 0x3f, // You Can'T Do That While Using Premade Groups. + NotLeader = 0x45, // You Are Not The Party Leader. + Dead = 0x49, + + PartyNotMeetReqs = 6, // One Or More Party Members Do Not Meet The Requirements For The Chosen Dungeons (Fixme) } public enum LfgRoleCheckState diff --git a/Game/BattleGrounds/BattleGround.cs b/Game/BattleGrounds/BattleGround.cs index 84314a57a..5421d6db0 100644 --- a/Game/BattleGrounds/BattleGround.cs +++ b/Game/BattleGrounds/BattleGround.cs @@ -857,7 +857,7 @@ namespace Game.BattleGrounds if (SendPacket) { BattlefieldStatusNone battlefieldStatus; - Global.BattlegroundMgr.BuildBattlegroundStatusNone(out battlefieldStatus, player, player.GetBattlegroundQueueIndex(bgQueueTypeId), player.GetBattlegroundQueueJoinTime(bgQueueTypeId), m_ArenaType); + Global.BattlegroundMgr.BuildBattlegroundStatusNone(out battlefieldStatus, player, player.GetBattlegroundQueueIndex(bgQueueTypeId), player.GetBattlegroundQueueJoinTime(bgQueueTypeId)); player.SendPacket(battlefieldStatus); } diff --git a/Game/BattleGrounds/BattleGroundManager.cs b/Game/BattleGrounds/BattleGroundManager.cs index f94484aef..bfc2e84a1 100644 --- a/Game/BattleGrounds/BattleGroundManager.cs +++ b/Game/BattleGrounds/BattleGroundManager.cs @@ -127,8 +127,8 @@ namespace Game.BattleGrounds { header.Ticket.RequesterGuid = player.GetGUID(); header.Ticket.Id = ticketId; - header.Ticket.Type = bg.isArena() ? (int)arenaType : 1; - header.Ticket.Time = joinTime; + header.Ticket.Type = RideType.Battlegrounds; + header.Ticket.Time = (int)joinTime; header.QueueID = bg.GetQueueId(); header.RangeMin = (byte)bg.GetMinLevel(); header.RangeMax = (byte)bg.GetMaxLevel(); @@ -138,13 +138,13 @@ namespace Game.BattleGrounds header.TournamentRules = false; } - public void BuildBattlegroundStatusNone(out BattlefieldStatusNone battlefieldStatus, Player player, uint ticketId, uint joinTime, ArenaTypes arenaType) + public void BuildBattlegroundStatusNone(out BattlefieldStatusNone battlefieldStatus, Player player, uint ticketId, uint joinTime) { battlefieldStatus = new BattlefieldStatusNone(); battlefieldStatus.Ticket.RequesterGuid = player.GetGUID(); battlefieldStatus.Ticket.Id = ticketId; - battlefieldStatus.Ticket.Type = (int)arenaType; - battlefieldStatus.Ticket.Time = joinTime; + battlefieldStatus.Ticket.Type = RideType.Battlegrounds; + battlefieldStatus.Ticket.Time = (int)joinTime; } public void BuildBattlegroundStatusNeedConfirmation(out BattlefieldStatusNeedConfirmation battlefieldStatus, Battleground bg, Player player, uint ticketId, uint joinTime, uint timeout, ArenaTypes arenaType) @@ -183,8 +183,8 @@ namespace Game.BattleGrounds battlefieldStatus = new BattlefieldStatusFailed(); battlefieldStatus.Ticket.RequesterGuid = pPlayer.GetGUID(); battlefieldStatus.Ticket.Id = ticketId; - battlefieldStatus.Ticket.Type = (int)arenaType; - battlefieldStatus.Ticket.Time = pPlayer.GetBattlegroundQueueJoinTime(BGQueueTypeId(bg.GetTypeID(), arenaType)); + battlefieldStatus.Ticket.Type = RideType.Battlegrounds; + battlefieldStatus.Ticket.Time = (int)pPlayer.GetBattlegroundQueueJoinTime(BGQueueTypeId(bg.GetTypeID(), arenaType)); battlefieldStatus.QueueID = bg.GetQueueId(); battlefieldStatus.Reason = (int)result; if (!errorGuid.IsEmpty() && (result == GroupJoinBattlegroundResult.NotInBattleground || result == GroupJoinBattlegroundResult.JoinTimedOut)) diff --git a/Game/BattleGrounds/BattleGroundQueue.cs b/Game/BattleGrounds/BattleGroundQueue.cs index 68e9f1cec..c3da68919 100644 --- a/Game/BattleGrounds/BattleGroundQueue.cs +++ b/Game/BattleGrounds/BattleGroundQueue.cs @@ -336,7 +336,7 @@ namespace Game.BattleGrounds // queue.removeplayer, it causes bugs BattlefieldStatusNone battlefieldStatus; - Global.BattlegroundMgr.BuildBattlegroundStatusNone(out battlefieldStatus, plr2, queueSlot, plr2.GetBattlegroundQueueJoinTime(bgQueueTypeId), group.ArenaType); + Global.BattlegroundMgr.BuildBattlegroundStatusNone(out battlefieldStatus, plr2, queueSlot, plr2.GetBattlegroundQueueJoinTime(bgQueueTypeId)); plr2.SendPacket(battlefieldStatus); } // then actually delete, this may delete the group as well! @@ -411,7 +411,7 @@ namespace Game.BattleGrounds BGQueueInviteEvent inviteEvent = new BGQueueInviteEvent(player.GetGUID(), ginfo.IsInvitedToBGInstanceGUID, bgTypeId, ginfo.ArenaType, ginfo.RemoveInviteTime); m_events.AddEvent(inviteEvent, m_events.CalculateTime(BattlegroundConst.InvitationRemindTime)); // create automatic remove events - BGQueueRemoveEvent removeEvent = new BGQueueRemoveEvent(player.GetGUID(), ginfo.IsInvitedToBGInstanceGUID, bgTypeId, ginfo.ArenaType, bgQueueTypeId, ginfo.RemoveInviteTime); + BGQueueRemoveEvent removeEvent = new BGQueueRemoveEvent(player.GetGUID(), ginfo.IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo.RemoveInviteTime); m_events.AddEvent(removeEvent, m_events.CalculateTime(BattlegroundConst.InviteAcceptWaitTime)); uint queueSlot = player.GetBattlegroundQueueIndex(bgQueueTypeId); @@ -1134,12 +1134,11 @@ namespace Game.BattleGrounds /// class BGQueueRemoveEvent : BasicEvent { - public BGQueueRemoveEvent(ObjectGuid pl_guid, uint bgInstanceGUID, BattlegroundTypeId BgTypeId, ArenaTypes arenaType, BattlegroundQueueTypeId bgQueueTypeId, uint removeTime) + public BGQueueRemoveEvent(ObjectGuid pl_guid, uint bgInstanceGUID, BattlegroundTypeId BgTypeId, BattlegroundQueueTypeId bgQueueTypeId, uint removeTime) { m_PlayerGuid = pl_guid; m_BgInstanceGUID = bgInstanceGUID; m_RemoveTime = removeTime; - m_ArenaType = arenaType; m_BgTypeId = BgTypeId; m_BgQueueTypeId = bgQueueTypeId; } @@ -1171,7 +1170,7 @@ namespace Game.BattleGrounds Global.BattlegroundMgr.ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg.GetBracketId()); BattlefieldStatusNone battlefieldStatus; - Global.BattlegroundMgr.BuildBattlegroundStatusNone(out battlefieldStatus, player, queueSlot, player.GetBattlegroundQueueJoinTime(m_BgQueueTypeId), m_ArenaType); + Global.BattlegroundMgr.BuildBattlegroundStatusNone(out battlefieldStatus, player, queueSlot, player.GetBattlegroundQueueJoinTime(m_BgQueueTypeId)); player.SendPacket(battlefieldStatus); } } @@ -1186,7 +1185,6 @@ namespace Game.BattleGrounds uint m_BgInstanceGUID; uint m_RemoveTime; BattlegroundTypeId m_BgTypeId; - ArenaTypes m_ArenaType; BattlegroundQueueTypeId m_BgQueueTypeId; } } diff --git a/Game/DungeonFinding/LFGManager.cs b/Game/DungeonFinding/LFGManager.cs index 478e3ecb5..25982a858 100644 --- a/Game/DungeonFinding/LFGManager.cs +++ b/Game/DungeonFinding/LFGManager.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Text; +using Game.Network.Packets; namespace Game.DungeonFinding { @@ -382,21 +383,21 @@ namespace Game.DungeonFinding // Check player or group member restrictions if (!player.GetSession().HasPermission(RBACPermissions.JoinDungeonFinder)) - joinData.result = LfgJoinResult.NotMeetReqs; + joinData.result = LfgJoinResult.NoSlotsPlayer; else if (player.InBattleground() || player.InArena() || player.InBattlegroundQueue()) - joinData.result = LfgJoinResult.UsingBgSystem; + joinData.result = LfgJoinResult.CantUseDungeons; else if (player.HasAura(SharedConst.LFGSpellDungeonDeserter)) - joinData.result = LfgJoinResult.Deserter; + joinData.result = LfgJoinResult.DeserterPlayer; else if (player.HasAura(SharedConst.LFGSpellDungeonCooldown)) - joinData.result = LfgJoinResult.RandomCooldown; + joinData.result = LfgJoinResult.RandomCooldownPlayer; else if (dungeons.Empty()) - joinData.result = LfgJoinResult.NotMeetReqs; + joinData.result = LfgJoinResult.NoSlotsPlayer; else if (player.HasAura(9454)) // check Freeze debuff - joinData.result = LfgJoinResult.NotMeetReqs; + joinData.result = LfgJoinResult.NoSlotsPlayer; else if (grp) { if (grp.GetMembersCount() > MapConst.MaxGroupSize) - joinData.result = LfgJoinResult.TooMuchMembers; + joinData.result = LfgJoinResult.TooManyMembers; else { byte memberCount = 0; @@ -406,13 +407,13 @@ namespace Game.DungeonFinding if (plrg) { if (!plrg.GetSession().HasPermission(RBACPermissions.JoinDungeonFinder)) - joinData.result = LfgJoinResult.InternalError; + joinData.result = LfgJoinResult.NoLfgObject; if (plrg.HasAura(SharedConst.LFGSpellDungeonDeserter)) - joinData.result = LfgJoinResult.PartyDeserter; + joinData.result = LfgJoinResult.DeserterParty; else if (plrg.HasAura(SharedConst.LFGSpellDungeonCooldown)) - joinData.result = LfgJoinResult.PartyRandomCooldown; + joinData.result = LfgJoinResult.RandomCooldownParty; else if (plrg.InBattleground() || plrg.InArena() || plrg.InBattlegroundQueue()) - joinData.result = LfgJoinResult.UsingBgSystem; + joinData.result = LfgJoinResult.CantUseDungeons; else if (plrg.HasAura(9454)) // check Freeze debuff joinData.result = LfgJoinResult.PartyNotMeetReqs; ++memberCount; @@ -421,7 +422,7 @@ namespace Game.DungeonFinding } if (joinData.result == LfgJoinResult.Ok && memberCount != grp.GetMembersCount()) - joinData.result = LfgJoinResult.Disconnected; + joinData.result = LfgJoinResult.MembersNotPresent; } } else @@ -442,23 +443,23 @@ namespace Game.DungeonFinding { case LfgType.RandomDungeon: if (dungeons.Count > 1) // Only allow 1 random dungeon - joinData.result = LfgJoinResult.DungeonInvalid; + joinData.result = LfgJoinResult.InvalidSlot; else rDungeonId = dungeons.First(); goto case LfgType.Dungeon; case LfgType.Dungeon: if (isRaid) - joinData.result = LfgJoinResult.MixedRaidDungeon; + joinData.result = LfgJoinResult.MismatchedSlots; isDungeon = true; break; case LfgType.Raid: if (isDungeon) - joinData.result = LfgJoinResult.MixedRaidDungeon; + joinData.result = LfgJoinResult.MismatchedSlots; isRaid = true; break; default: Log.outError(LogFilter.Lfg, "Wrong dungeon type {0} for dungeon {1}", type, it); - joinData.result = LfgJoinResult.DungeonInvalid; + joinData.result = LfgJoinResult.InvalidSlot; break; } } @@ -473,7 +474,7 @@ namespace Game.DungeonFinding // if we have lockmap then there are no compatible dungeons GetCompatibleDungeons(dungeons, players, joinData.lockmap, isContinue); if (dungeons.Empty()) - joinData.result = grp ? LfgJoinResult.InternalError : LfgJoinResult.NotMeetReqs; + joinData.result = grp ? LfgJoinResult.NoLfgObject : LfgJoinResult.NoSlotsPlayer; } } @@ -493,6 +494,7 @@ namespace Game.DungeonFinding return; } + RideTicket ticket = new RideTicket(guid, GetQueueId(gguid), RideType.Lfg, (int)Time.UnixTime); string debugNames = ""; if (grp) // Begin rolecheck { @@ -523,6 +525,7 @@ namespace Game.DungeonFinding ObjectGuid pguid = plrg.GetGUID(); plrg.GetSession().SendLfgUpdateStatus(updateData, true); SetState(pguid, LfgState.Rolecheck); + SetTicket(pguid, ticket); if (!isContinue) SetSelectedDungeons(pguid, dungeons); roleCheck.roles[pguid] = 0; @@ -551,10 +554,12 @@ namespace Game.DungeonFinding SetSelectedDungeons(guid, dungeons); } // Send update to player + SetTicket(guid, ticket); SetRoles(guid, roles); - player.GetSession().SendLfgUpdateStatus(new LfgUpdateData(LfgUpdateType.JoinQueue, dungeons), false); - player.GetSession().SendLfgJoinResult(joinData); + player.GetSession().SendLfgUpdateStatus(new LfgUpdateData(LfgUpdateType.JoinQueueInitial, dungeons), false); SetState(gguid, LfgState.Queued); + player.GetSession().SendLfgUpdateStatus(new LfgUpdateData(LfgUpdateType.AddedToQueue, dungeons), false); + player.GetSession().SendLfgJoinResult(joinData); debugNames += player.GetName(); } StringBuilder o = new StringBuilder(); @@ -628,6 +633,15 @@ namespace Game.DungeonFinding } } + public RideTicket GetTicket(ObjectGuid guid) + { + var palyerData = PlayersStore.LookupByKey(guid); + if (palyerData != null) + return palyerData.GetTicket(); + + return null; + } + public void UpdateRoleCheck(ObjectGuid gguid, ObjectGuid guid = default(ObjectGuid), LfgRoles roles = LfgRoles.None) { if (gguid.IsEmpty()) @@ -671,11 +685,7 @@ namespace Game.DungeonFinding else dungeons = roleCheck.dungeons; - LfgJoinResult joinResult = LfgJoinResult.Failed; - if (roleCheck.state == LfgRoleCheckState.MissingRole || roleCheck.state == LfgRoleCheckState.WrongRoles) - joinResult = LfgJoinResult.RoleCheckFailed; - - LfgJoinResultData joinData = new LfgJoinResultData(joinResult, roleCheck.state); + LfgJoinResultData joinData = new LfgJoinResultData(LfgJoinResult.RoleCheckFailed, roleCheck.state); foreach (var it in roleCheck.roles) { ObjectGuid pguid = it.Key; @@ -1184,7 +1194,7 @@ namespace Game.DungeonFinding if (dungeon == null) { Log.outDebug(LogFilter.Lfg, "TeleportPlayer: Player {0} not in group/lfggroup or dungeon not found!", player.GetName()); - player.GetSession().SendLfgTeleportError(LfgTeleportResult.InvalidLocation); + player.GetSession().SendLfgTeleportError(LfgTeleportResult.NoReturnLocation); return; } @@ -1197,19 +1207,19 @@ namespace Game.DungeonFinding return; } - LfgTeleportResult error = LfgTeleportResult.Ok; + LfgTeleportResult error = LfgTeleportResult.None; if (!player.IsAlive()) - error = LfgTeleportResult.PlayerDead; + error = LfgTeleportResult.Dead; else if (player.IsFalling() || player.HasUnitState(UnitState.Jumping)) error = LfgTeleportResult.Falling; else if (player.IsMirrorTimerActive(MirrorTimerType.Fatigue)) - error = LfgTeleportResult.Fatigue; + error = LfgTeleportResult.Exhaustion; else if (player.GetVehicle()) - error = LfgTeleportResult.InVehicle; + error = LfgTeleportResult.OnTransport; else if (!player.GetCharmGUID().IsEmpty()) - error = LfgTeleportResult.Charming; + error = LfgTeleportResult.ImmuneToSummons; else if (player.HasAura(9454)) // check Freeze debuff - error = LfgTeleportResult.InvalidLocation; + error = LfgTeleportResult.NoReturnLocation; else if (player.GetMapId() != dungeon.map) // Do not teleport players in dungeon to the entrance { uint mapid = dungeon.map; @@ -1246,12 +1256,12 @@ namespace Game.DungeonFinding } if (!player.TeleportTo(mapid, x, y, z, orientation)) - error = LfgTeleportResult.InvalidLocation; + error = LfgTeleportResult.NoReturnLocation; } else - error = LfgTeleportResult.InvalidLocation; + error = LfgTeleportResult.NoReturnLocation; - if (error != LfgTeleportResult.Ok) + if (error != LfgTeleportResult.None) player.GetSession().SendLfgTeleportError(error); Log.outDebug(LogFilter.Lfg, "TeleportPlayer: Player {0} is being teleported in to map {1} (x: {2}, y: {3}, z: {4}) Result: {5}", player.GetName(), dungeon.map, dungeon.x, dungeon.y, dungeon.z, error); @@ -1323,7 +1333,6 @@ namespace Game.DungeonFinding if (reward == null) continue; - bool done = false; Quest quest = Global.ObjectMgr.GetQuestTemplate(reward.firstQuest); if (quest == null) continue; @@ -1333,7 +1342,6 @@ namespace Game.DungeonFinding player.RewardQuest(quest, 0, null, false); else { - done = true; quest = Global.ObjectMgr.GetQuestTemplate(reward.otherQuest); if (quest == null) continue; @@ -1617,6 +1625,11 @@ namespace Game.DungeonFinding PlayersStore[guid] = new LFGPlayerData(); } + void SetTicket(ObjectGuid guid, RideTicket ticket) + { + PlayersStore[guid].SetTicket(ticket); + } + void RemovePlayerData(ObjectGuid guid) { Log.outDebug(LogFilter.Lfg, "RemovePlayerData: [{0}]", guid); @@ -2003,12 +2016,11 @@ namespace Game.DungeonFinding public class LfgQueueStatusData { - public LfgQueueStatusData(byte _queueId = 0, uint _dungeonId = 0, long _joinTime = 0, int _waitTime = -1, int _waitTimeAvg = -1, int _waitTimeTank = -1, int _waitTimeHealer = -1, + public LfgQueueStatusData(byte _queueId = 0, uint _dungeonId = 0, int _waitTime = -1, int _waitTimeAvg = -1, int _waitTimeTank = -1, int _waitTimeHealer = -1, int _waitTimeDps = -1, uint _queuedTime = 0, byte _tanks = 0, byte _healers = 0, byte _dps = 0) { queueId = _queueId; dungeonId = _dungeonId; - joinTime = _joinTime; waitTime = _waitTime; waitTimeAvg = _waitTimeAvg; waitTimeTank = _waitTimeTank; @@ -2022,7 +2034,6 @@ namespace Game.DungeonFinding public byte queueId; public uint dungeonId; - public long joinTime; public int waitTime; public int waitTimeAvg; public int waitTimeTank; diff --git a/Game/DungeonFinding/LFGPlayerData.cs b/Game/DungeonFinding/LFGPlayerData.cs index 105a1040e..2aefb71cf 100644 --- a/Game/DungeonFinding/LFGPlayerData.cs +++ b/Game/DungeonFinding/LFGPlayerData.cs @@ -18,6 +18,7 @@ using Framework.Constants; using Game.Entities; using System.Collections.Generic; +using Game.Network.Packets; namespace Game.DungeonFinding { @@ -29,6 +30,11 @@ namespace Game.DungeonFinding m_OldState = LfgState.None; } + public void SetTicket(RideTicket ticket) + { + m_Ticket = ticket; + } + public void SetState(LfgState state) { switch (state) @@ -75,6 +81,11 @@ namespace Game.DungeonFinding m_SelectedDungeons = dungeons; } + public RideTicket GetTicket() + { + return m_Ticket; + } + public LfgState GetState() { return m_State; @@ -106,6 +117,7 @@ namespace Game.DungeonFinding } // General + RideTicket m_Ticket; LfgState m_State; LfgState m_OldState; // Player diff --git a/Game/DungeonFinding/LFGQueue.cs b/Game/DungeonFinding/LFGQueue.cs index 381abd1fc..0749f5776 100644 --- a/Game/DungeonFinding/LFGQueue.cs +++ b/Game/DungeonFinding/LFGQueue.cs @@ -616,7 +616,7 @@ namespace Game.DungeonFinding if (string.IsNullOrEmpty(queueinfo.bestCompatible)) FindBestCompatibleInQueue(itQueue.Key, itQueue.Value); - LfgQueueStatusData queueData = new LfgQueueStatusData(queueId, dungeonId, queueinfo.joinTime, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps); + LfgQueueStatusData queueData = new LfgQueueStatusData(queueId, dungeonId, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps); foreach (var itPlayer in queueinfo.roles) { ObjectGuid pguid = itPlayer.Key; diff --git a/Game/DungeonFinding/LFGScripts.cs b/Game/DungeonFinding/LFGScripts.cs index efef8fb8e..ba378a712 100644 --- a/Game/DungeonFinding/LFGScripts.cs +++ b/Game/DungeonFinding/LFGScripts.cs @@ -34,10 +34,7 @@ namespace Game.DungeonFinding return; if (!player.GetGroup()) - { - player.GetSession().SendLfgLfrList(false); Global.LFGMgr.LeaveLfg(player.GetGUID()); - } else if (player.GetSession().PlayerDisconnected()) Global.LFGMgr.LeaveLfg(player.GetGUID(), true); } diff --git a/Game/Groups/Group.cs b/Game/Groups/Group.cs index bf3d70405..41b3f4d48 100644 --- a/Game/Groups/Group.cs +++ b/Game/Groups/Group.cs @@ -1391,7 +1391,7 @@ namespace Game.Groups { partyUpdate.LfgInfos.HasValue = true; - partyUpdate.LfgInfos.Value.Slot = Global.LFGMgr.GetDungeon(m_guid); + partyUpdate.LfgInfos.Value.Slot = Global.LFGMgr.GetLFGDungeonEntry(Global.LFGMgr.GetDungeon(m_guid)); partyUpdate.LfgInfos.Value.BootCount = 0; partyUpdate.LfgInfos.Value.Aborted = false; diff --git a/Game/Handlers/LFGHandler.cs b/Game/Handlers/LFGHandler.cs index 88411b8a3..83fd9b990 100644 --- a/Game/Handlers/LFGHandler.cs +++ b/Game/Handlers/LFGHandler.cs @@ -23,48 +23,14 @@ using Game.Network; using Game.Network.Packets; using System.Collections.Generic; using System.Linq; +using Game.DataStorage; namespace Game { public partial class WorldSession { - void BuildQuestReward(LfgPlayerQuestReward questReward, Quest quest, Player player) - { - byte rewCount = (byte)(quest.GetRewItemsCount() + quest.GetRewCurrencyCount()); - - questReward.RewardMoney = player.GetQuestMoneyReward(quest); - questReward.RewardXP = player.GetQuestXPReward(quest); - if (rewCount != 0) - { - for (byte i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i) - { - var rewardCurrency = new LfgPlayerQuestReward.LfgPlayerQuestRewardCurrency(); - uint currencyId = quest.RewardCurrencyId[i]; - if (currencyId != 0) - { - rewardCurrency.CurrencyID = currencyId; - rewardCurrency.Quantity = quest.RewardCurrencyCount[i]; - questReward.Currency.Add(rewardCurrency); - } - } - - for (byte i = 0; i < SharedConst.QuestRewardItemCount; ++i) - { - var rewardItem = new LfgPlayerQuestReward.LfgPlayerQuestRewardItem(); - uint itemId = quest.RewardItemId[i]; - if (itemId != 0) - { - ItemTemplate item = Global.ObjectMgr.GetItemTemplate(itemId); - rewardItem.ItemID = itemId; - rewardItem.Quantity = quest.RewardItemCount[i]; - questReward.Items.Add(rewardItem); - } - } - } - } - [WorldPacketHandler(ClientOpcodes.DfJoin)] - void HandleDfJoin(DFJoin dfJoin) + void HandleLfgJoin(DFJoin dfJoin) { if (!Global.LFGMgr.isOptionEnabled(LfgOptions.EnableDungeonFinder | LfgOptions.EnableRaidBrowser) || (GetPlayer().GetGroup() && GetPlayer().GetGroup().GetLeaderGUID() != GetPlayer().GetGUID() && @@ -73,73 +39,74 @@ namespace Game if (dfJoin.Slots.Empty()) { - Log.outDebug(LogFilter.Lfg, "ClientOpcodes.DfJoin {0} no dungeons selected", GetPlayerInfo()); + Log.outDebug(LogFilter.Lfg, "CMSG_DF_JOIN {0} no dungeons selected", GetPlayerInfo()); return; } List newDungeons = new List(); - for (int i = 0; i < dfJoin.Slots.Count; ++i) + foreach (uint slot in dfJoin.Slots) { - uint dungeon = dfJoin.Slots[i]; - if (dungeon != 0) + uint dungeon = slot & 0x00FFFFFF; + if (CliDB.LfgDungeonsStorage.ContainsKey(dungeon)) newDungeons.Add(dungeon); - } + Log.outDebug(LogFilter.Lfg, "CMSG_DF_JOIN {0} roles: {1}, Dungeons: {2}", GetPlayerInfo(), dfJoin.Roles, newDungeons.Count); + Global.LFGMgr.JoinLfg(GetPlayer(), dfJoin.Roles, newDungeons); } [WorldPacketHandler(ClientOpcodes.DfLeave)] - void HandleDfLeave(DFLeave dfLeave) + void HandleLfgLeave(DFLeave dfLeave) { - ObjectGuid leaveGuid = dfLeave.Ticket.RequesterGuid; Group group = GetPlayer().GetGroup(); - ObjectGuid guid = GetPlayer().GetGUID(); - ObjectGuid gguid = group ? group.GetGUID() : guid; + + Log.outDebug(LogFilter.Lfg, "CMSG_DF_LEAVE {0} in group: {1} sent guid {2}.", GetPlayerInfo(), group ? 1 : 0, dfLeave.Ticket.RequesterGuid.ToString()); // Check cheating - only leader can leave the queue - if (!group || group.GetLeaderGUID() == leaveGuid) - Global.LFGMgr.LeaveLfg(gguid); + if (!group || group.GetLeaderGUID() == dfLeave.Ticket.RequesterGuid) + Global.LFGMgr.LeaveLfg(dfLeave.Ticket.RequesterGuid); } [WorldPacketHandler(ClientOpcodes.DfProposalResponse)] - void HandleDfProposalResponse(DFProposalResponse dfProposalResponse) + void HandleLfgProposalResult(DFProposalResponse dfProposalResponse) { - Global.LFGMgr.UpdateProposal(dfProposalResponse.ProposalID, dfProposalResponse.Ticket.RequesterGuid, dfProposalResponse.Accepted); + Log.outDebug(LogFilter.Lfg, "CMSG_LFG_PROPOSAL_RESULT {0} proposal: {1} accept: {2}", GetPlayerInfo(), dfProposalResponse.ProposalID, dfProposalResponse.Accepted ? 1 : 0); + Global.LFGMgr.UpdateProposal(dfProposalResponse.ProposalID, GetPlayer().GetGUID(), dfProposalResponse.Accepted); } [WorldPacketHandler(ClientOpcodes.DfSetRoles)] - void HandleDfSetRoles(DFSetRoles setRoles) + void HandleLfgSetRoles(DFSetRoles dfSetRoles) { ObjectGuid guid = GetPlayer().GetGUID(); Group group = GetPlayer().GetGroup(); if (!group) { - Log.outDebug(LogFilter.Lfg, "CMSG_LFG_SET_ROLES {0} Not in group", + Log.outDebug(LogFilter.Lfg, "CMSG_DF_SET_ROLES {0} Not in group", GetPlayerInfo()); return; } ObjectGuid gguid = group.GetGUID(); - Log.outDebug(LogFilter.Lfg, "CMSG_LFG_SET_ROLES: Group {0}, Player {1}, Roles: {2}", gguid.ToString(), GetPlayerInfo(), setRoles.RolesDesired); - Global.LFGMgr.UpdateRoleCheck(gguid, guid, setRoles.RolesDesired); + Log.outDebug(LogFilter.Lfg, "CMSG_DF_SET_ROLES: Group {0}, Player {1}, Roles: {2}", gguid.ToString(), GetPlayerInfo(), dfSetRoles.RolesDesired); + Global.LFGMgr.UpdateRoleCheck(gguid, guid, dfSetRoles.RolesDesired); } [WorldPacketHandler(ClientOpcodes.DfBootPlayerVote)] - void HandleDfBootPlayerVote(DFBootPlayerVote bootPlayerVote) + void HandleLfgSetBootVote(DFBootPlayerVote dfBootPlayerVote) { ObjectGuid guid = GetPlayer().GetGUID(); - Log.outDebug(LogFilter.Lfg, "ClientOpcodes.DfBootPlayerVote: {0} agree: {1}", GetPlayerInfo(), bootPlayerVote.Vote); - Global.LFGMgr.UpdateBoot(guid, bootPlayerVote.Vote); + Log.outDebug(LogFilter.Lfg, "CMSG_LFG_SET_BOOT_VOTE {0} agree: {1}", GetPlayerInfo(), dfBootPlayerVote.Vote ? 1 : 0); + Global.LFGMgr.UpdateBoot(guid, dfBootPlayerVote.Vote); } [WorldPacketHandler(ClientOpcodes.DfTeleport)] - void HandleDfTeleport(DFTeleport teleport) + void HandleLfgTeleport(DFTeleport dfTeleport) { - Log.outDebug(LogFilter.Lfg, "CMSG_LFG_TELEPORT {0} out: {1}", GetPlayerInfo(), teleport.TeleportOut); - Global.LFGMgr.TeleportPlayer(GetPlayer(), teleport.TeleportOut, true); + Log.outDebug(LogFilter.Lfg, "CMSG_DF_TELEPORT {0} out: {1}", GetPlayerInfo(), dfTeleport.TeleportOut ? 1 : 0); + Global.LFGMgr.TeleportPlayer(GetPlayer(), dfTeleport.TeleportOut, true); } - //[WorldPacketHandler(ClientOpcodes.DfGetSystemInfo, Processing = PacketProcessing.ThreadSafe)] + [WorldPacketHandler(ClientOpcodes.DfGetSystemInfo, Processing = PacketProcessing.ThreadSafe)] void HandleDfGetSystemInfo(DFGetSystemInfo dfGetSystemInfo) { Log.outDebug(LogFilter.Lfg, "CMSG_LFG_Lock_INFO_REQUEST {0} for {1}", GetPlayerInfo(), (dfGetSystemInfo.Player ? "player" : "party")); @@ -175,56 +142,67 @@ namespace Game public void SendLfgPlayerLockInfo() { - ObjectGuid guid = GetPlayer().GetGUID(); - // Get Random dungeons that can be done at a certain level and expansion uint level = GetPlayer().getLevel(); List randomDungeons = Global.LFGMgr.GetRandomAndSeasonalDungeons(level, (uint)GetExpansion()); - // Get player Locked Dungeons - Dictionary Lock = Global.LFGMgr.GetLockedDungeons(guid); - uint rsize = (uint)randomDungeons.Count; - uint lsize = (uint)Lock.Count; - LfgPlayerInfo lfgPlayerInfo = new LfgPlayerInfo(); - lfgPlayerInfo.BlackList = new LFGBlackList(Lock); + + // Get player locked Dungeons + foreach (var locked in Global.LFGMgr.GetLockedDungeons(_player.GetGUID())) + lfgPlayerInfo.BlackList.Slot.Add(new LFGBlackListSlot(locked.Key, (uint)locked.Value.lockStatus, locked.Value.requiredItemLevel, (int)locked.Value.currentItemLevel)); foreach (var slot in randomDungeons) { - var dungeonInfo = new LfgPlayerDungeonInfo(); - dungeonInfo.Slot = slot; - dungeonInfo.FirstReward = true; + var playerDungeonInfo = new LfgPlayerDungeonInfo(); + playerDungeonInfo.Slot = slot; + playerDungeonInfo.CompletionQuantity = 1; + playerDungeonInfo.CompletionLimit = 1; + playerDungeonInfo.CompletionCurrencyID = 0; + playerDungeonInfo.SpecificQuantity = 0; + playerDungeonInfo.SpecificLimit = 1; + playerDungeonInfo.OverallQuantity = 0; + playerDungeonInfo.OverallLimit = 1; + playerDungeonInfo.PurseWeeklyQuantity = 0; + playerDungeonInfo.PurseWeeklyLimit = 0; + playerDungeonInfo.PurseQuantity = 0; + playerDungeonInfo.PurseLimit = 0; + playerDungeonInfo.Quantity = 1; + playerDungeonInfo.CompletedMask = 0; + playerDungeonInfo.EncounterMask = 0; LfgReward reward = Global.LFGMgr.GetRandomDungeonReward(slot, level); - Quest quest = null; - bool done = false; if (reward != null) { - quest = Global.ObjectMgr.GetQuestTemplate(reward.firstQuest); + Quest quest = Global.ObjectMgr.GetQuestTemplate(reward.firstQuest); if (quest != null) { - done = !GetPlayer().CanRewardQuest(quest, false); - if (done) - { + playerDungeonInfo.FirstReward = !GetPlayer().CanRewardQuest(quest, false); + if (!playerDungeonInfo.FirstReward) quest = Global.ObjectMgr.GetQuestTemplate(reward.otherQuest); - dungeonInfo.FirstReward = false; + + if (quest != null) + { + playerDungeonInfo.Rewards.RewardMoney = _player.GetQuestMoneyReward(quest); + playerDungeonInfo.Rewards.RewardXP = _player.GetQuestXPReward(quest); + for (byte i = 0; i < SharedConst.QuestRewardItemCount; ++i) + { + uint itemId = quest.RewardItemId[i]; + if (itemId != 0) + playerDungeonInfo.Rewards.Item.Add(new LfgPlayerQuestRewardItem(itemId, quest.RewardItemCount[i])); + } + + for (byte i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i) + { + uint curencyId = quest.RewardCurrencyId[i]; + if (curencyId != 0) + playerDungeonInfo.Rewards.Currency.Add(new LfgPlayerQuestRewardCurrency(curencyId, quest.RewardCurrencyCount[i])); + } } } } - if (quest != null) - { - dungeonInfo.ShortageEligible = true; - - dungeonInfo.CompletionQuantity = 1; - dungeonInfo.CompletionLimit = 1; - dungeonInfo.SpecificLimit = 1; - dungeonInfo.OverallLimit = 1; - dungeonInfo.Quantity = 1; - - BuildQuestReward(dungeonInfo.Rewards, quest, GetPlayer()); - } - lfgPlayerInfo.Dungeons.Add(dungeonInfo); + lfgPlayerInfo.Dungeons.Add(playerDungeonInfo); } SendPacket(lfgPlayerInfo); @@ -237,8 +215,9 @@ namespace Game if (!group) return; + LfgPartyInfo lfgPartyInfo = new LfgPartyInfo(); + // Get the Locked dungeons of the other party members - Dictionary> LockMap = new Dictionary>(); for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.next()) { Player plrg = refe.GetSource(); @@ -249,62 +228,65 @@ namespace Game if (pguid == guid) continue; - LockMap[pguid] = Global.LFGMgr.GetLockedDungeons(pguid); + LFGBlackList lfgBlackList = new LFGBlackList(); + lfgBlackList.PlayerGuid.Set(pguid); + foreach (var locked in Global.LFGMgr.GetLockedDungeons(pguid)) + lfgBlackList.Slot.Add(new LFGBlackListSlot(locked.Key, (uint)locked.Value.lockStatus, locked.Value.requiredItemLevel, (int)locked.Value.currentItemLevel)); + + lfgPartyInfo.Player.Add(lfgBlackList); } Log.outDebug(LogFilter.Lfg, "SMSG_LFG_PARTY_INFO {0}", GetPlayerInfo()); - - LfgPartyInfo partyInfo = new LfgPartyInfo(); - foreach (var it in LockMap) - { - var blackList = new LFGBlackList(it.Value); - blackList.PlayerGuid.Set(it.Key); - - partyInfo.Players.Add(blackList); - } - - SendPacket(partyInfo); + SendPacket(lfgPartyInfo); } public void SendLfgUpdateStatus(LfgUpdateData updateData, bool party) { - ObjectGuid guid = GetPlayer().GetGUID(); - - LFGUpdateStatus updateStatus = new LFGUpdateStatus(); - updateStatus.Ticket.RequesterGuid = guid; - updateStatus.Ticket.Id = Global.LFGMgr.GetQueueId(guid); - updateStatus.Ticket.Type = (byte)updateData.state; - updateStatus.Ticket.Time = (uint)Global.LFGMgr.GetQueueJoinTime(guid); - - updateStatus.SubType = (byte)(updateData.dungeons.Count > 0 ? Global.LFGMgr.GetDungeonType(updateData.dungeons[0]) : 0); - updateStatus.Reason = (byte)updateData.updateType; - - updateStatus.Slots = updateData.dungeons; - updateStatus.RequestedRoles = (uint)Global.LFGMgr.GetRoles(guid); - updateStatus.IsParty = party; + bool join = false; + bool queued = false; switch (updateData.updateType) { case LfgUpdateType.JoinQueueInitial: // Joined queue outside the dungeon - updateStatus.Joined = updateStatus.LfgJoined = true; + join = true; break; case LfgUpdateType.JoinQueue: case LfgUpdateType.AddedToQueue: // Rolecheck Success - updateStatus.Joined = updateStatus.LfgJoined = true; - updateStatus.Queued = true; + join = true; + queued = true; break; case LfgUpdateType.ProposalBegin: - updateStatus.Joined = updateStatus.LfgJoined = true; + join = true; break; case LfgUpdateType.UpdateStatus: - updateStatus.Joined = updateStatus.LfgJoined = updateData.state != LfgState.Rolecheck && updateData.state != LfgState.None; - updateStatus.Queued = updateData.state == LfgState.Queued; + join = updateData.state != LfgState.Rolecheck && updateData.state != LfgState.None; + queued = updateData.state == LfgState.Queued; break; default: break; } - SendPacket(updateStatus); + LFGUpdateStatus lfgUpdateStatus = new LFGUpdateStatus(); + + RideTicket ticket = Global.LFGMgr.GetTicket(_player.GetGUID()); + if (ticket != null) + lfgUpdateStatus.Ticket = ticket; + + lfgUpdateStatus.SubType = (byte)LfgQueueType.Dungeon; // other types not implemented + lfgUpdateStatus.Reason = (byte)updateData.updateType; + + foreach (var dungeonId in updateData.dungeons) + lfgUpdateStatus.Slots.Add(Global.LFGMgr.GetLFGDungeonEntry(dungeonId)); + + lfgUpdateStatus.RequestedRoles = (uint)Global.LFGMgr.GetRoles(_player.GetGUID()); + //lfgUpdateStatus.SuspendedPlayers; + lfgUpdateStatus.IsParty = party; + lfgUpdateStatus.NotifyUI = true; + lfgUpdateStatus.Joined = join; + lfgUpdateStatus.LfgJoined = updateData.updateType != LfgUpdateType.RemovedFromQueue; + lfgUpdateStatus.Queued = queued; + + SendPacket(lfgUpdateStatus); } public void SendLfgRoleChosen(ObjectGuid guid, LfgRoles roles) @@ -326,71 +308,62 @@ namespace Game Log.outDebug(LogFilter.Lfg, "SMSG_LFG_ROLE_CHECK_UPDATE {0}", GetPlayerInfo()); - LFGRoleCheckUpdate roleCheckUpdate = new LFGRoleCheckUpdate(); - roleCheckUpdate.PartyIndex = (byte)roleCheck.rDungeonId; //Wrong - roleCheckUpdate.RoleCheckStatus = (byte)roleCheck.state; - roleCheckUpdate.IsBeginning = roleCheck.state == LfgRoleCheckState.Initialiting; + LFGRoleCheckUpdate lfgRoleCheckUpdate = new LFGRoleCheckUpdate(); + lfgRoleCheckUpdate.PartyIndex = 127; + lfgRoleCheckUpdate.RoleCheckStatus = (byte)roleCheck.state; + lfgRoleCheckUpdate.IsBeginning = roleCheck.state == LfgRoleCheckState.Initialiting; - if (!dungeons.Empty()) - foreach (var it in dungeons) - roleCheckUpdate.JoinSlots.Add(Global.LFGMgr.GetLFGDungeonEntry(it)); // Dungeon + foreach (var dungeonId in dungeons) + lfgRoleCheckUpdate.JoinSlots.Add(Global.LFGMgr.GetLFGDungeonEntry(dungeonId)); + lfgRoleCheckUpdate.BgQueueID = 0; + lfgRoleCheckUpdate.GroupFinderActivityID = 0; if (!roleCheck.roles.Empty()) { // Leader info MUST be sent 1st :S - ObjectGuid guid = roleCheck.leader; - LfgRoles roles = roleCheck.roles.LookupByKey(guid); - Player player = Global.ObjAccessor.FindPlayer(guid); - - var roleCheckUpdateMember = new LFGRoleCheckUpdate.LFGRoleCheckUpdateMember(); - - roleCheckUpdateMember.Guid = guid; - roleCheckUpdateMember.RolesDesired = (uint)roles; - - roleCheckUpdateMember.Level = (byte)(player ? player.getLevel() : 0); - roleCheckUpdateMember.RoleCheckComplete = roles > 0; - - roleCheckUpdate.Members.Add(roleCheckUpdateMember); + byte roles = (byte)roleCheck.roles.Find(roleCheck.leader).Value; + lfgRoleCheckUpdate.Members.Add(new LFGRoleCheckUpdateMember(roleCheck.leader, roles, Global.WorldMgr.GetCharacterInfo(roleCheck.leader).Level, roles > 0)); foreach (var it in roleCheck.roles) { if (it.Key == roleCheck.leader) continue; - roleCheckUpdateMember = new LFGRoleCheckUpdate.LFGRoleCheckUpdateMember(); - - guid = it.Key; - roles = it.Value; - player = Global.ObjAccessor.FindPlayer(guid); - roleCheckUpdateMember.Guid = guid; - roleCheckUpdateMember.RolesDesired = (uint)roles; - roleCheckUpdateMember.Level = (byte)(player ? player.getLevel() : 0); - roleCheckUpdateMember.RoleCheckComplete = roles > 0; - - roleCheckUpdate.Members.Add(roleCheckUpdateMember); + roles = (byte)it.Value; + lfgRoleCheckUpdate.Members.Add(new LFGRoleCheckUpdateMember(it.Key, roles, Global.WorldMgr.GetCharacterInfo(it.Key).Level, roles > 0)); } } - SendPacket(roleCheckUpdate); + SendPacket(lfgRoleCheckUpdate); } public void SendLfgJoinResult(LfgJoinResultData joinData) { - ObjectGuid guid = GetPlayer().GetGUID(); + LFGJoinResult lfgJoinResult = new LFGJoinResult(); - LFGJoinResult joinResult = new LFGJoinResult(); - joinResult.Ticket = new RideTicket(guid, Global.LFGMgr.GetQueueId(guid), (int)Global.LFGMgr.GetState(guid), (uint)Time.UnixTime); + RideTicket ticket = Global.LFGMgr.GetTicket(GetPlayer().GetGUID()); + if (ticket != null) + lfgJoinResult.Ticket = ticket; + + lfgJoinResult.Result = (byte)joinData.result; + if (joinData.result == LfgJoinResult.RoleCheckFailed) + lfgJoinResult.ResultDetail = (byte)joinData.state; - joinResult.Result = (byte)joinData.result; - joinResult.ResultDetail= (byte)joinData.state; foreach (var it in joinData.lockmap) { - var blackList = new LFGBlackList(it.Value); - blackList.PlayerGuid.Set(it.Key); - joinResult.BlackList.Add(blackList); + var blackList = new LFGJoinBlackList(); + blackList.PlayerGuid = it.Key; + + foreach (var lockInfo in it.Value) + { + Log.outTrace(LogFilter.Lfg, "SendLfgJoinResult:: {0} DungeonID: {1} Lock status: {2} Required itemLevel: {3} Current itemLevel: {4}", + it.Key.ToString(), (lockInfo.Key & 0x00FFFFFF), lockInfo.Value.lockStatus, lockInfo.Value.requiredItemLevel, lockInfo.Value.currentItemLevel); + + blackList.Slots.Add(new LFGJoinBlackListSlot((int)lockInfo.Key, (int)lockInfo.Value.lockStatus, lockInfo.Value.requiredItemLevel, (int)lockInfo.Value.currentItemLevel)); + } } - SendPacket(joinResult); + SendPacket(lfgJoinResult); } public void SendLfgQueueStatus(LfgQueueStatusData queueData) @@ -400,22 +373,23 @@ namespace Game GetPlayerInfo(), Global.LFGMgr.GetState(GetPlayer().GetGUID()), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps); - LFGQueueStatus queueStatus = new LFGQueueStatus(); - queueStatus.Ticket = new RideTicket(GetPlayer().GetGUID(), queueData.dungeonId, 3, (uint)queueData.joinTime); - queueStatus.Slot = queueData.queueId; - queueStatus.AvgWaitTime = (uint)queueData.waitTimeAvg; - queueStatus.QueuedTime = queueData.queuedTime; + LFGQueueStatus lfgQueueStatus = new LFGQueueStatus(); + RideTicket ticket = Global.LFGMgr.GetTicket(GetPlayer().GetGUID()); + if (ticket != null) + lfgQueueStatus.Ticket = ticket; + lfgQueueStatus.Slot = queueData.queueId; + lfgQueueStatus.AvgWaitTimeMe = (uint)queueData.waitTime; + lfgQueueStatus.AvgWaitTime = (uint)queueData.waitTimeAvg; + lfgQueueStatus.AvgWaitTimeByRole[0] = (uint)queueData.waitTimeTank; + lfgQueueStatus.AvgWaitTimeByRole[1] = (uint)queueData.waitTimeHealer; + lfgQueueStatus.AvgWaitTimeByRole[2] = (uint)queueData.waitTimeDps; + lfgQueueStatus.LastNeeded[0] = queueData.tanks; + lfgQueueStatus.LastNeeded[1] = queueData.healers; + lfgQueueStatus.LastNeeded[2] = queueData.dps; + lfgQueueStatus.QueuedTime = queueData.queuedTime; - queueStatus.LastNeeded[0] = queueData.tanks; - queueStatus.AvgWaitTimeByRole[0] = (uint)queueData.waitTimeTank; - queueStatus.LastNeeded[1] = queueData.healers; - queueStatus.AvgWaitTimeByRole[1] = (uint)queueData.waitTimeHealer; - queueStatus.LastNeeded[2] = queueData.dps; - queueStatus.AvgWaitTimeByRole[2] = (uint)queueData.waitTimeDps; - queueStatus.AvgWaitTimeMe = (uint)queueData.waitTime; - - SendPacket(queueStatus); + SendPacket(lfgQueueStatus); } public void SendLfgPlayerReward(LfgPlayerRewardData rewardData) @@ -426,49 +400,32 @@ namespace Game Log.outDebug(LogFilter.Lfg, "SMSG_LFG_PLAYER_REWARD {0} rdungeonEntry: {1}, sdungeonEntry: {2}, done: {3}", GetPlayerInfo(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done); - byte itemNum = (byte)(rewardData.quest.GetRewItemsCount() + rewardData.quest.GetRewCurrencyCount()); - - LFGPlayerReward playerReward = new LFGPlayerReward(); - playerReward.ActualSlot = rewardData.rdungeonEntry; // Random Dungeon Finished - playerReward.QueuedSlot = rewardData.sdungeonEntry; // Dungeon Finished - - playerReward.RewardMoney = GetPlayer().GetQuestMoneyReward(rewardData.quest); - playerReward.AddedXP = GetPlayer().GetQuestXPReward(rewardData.quest); - - for (byte i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i) - { - var playerRewards = new LFGPlayerReward.LFGPlayerRewards(); - uint currencyId = rewardData.quest.RewardCurrencyId[i]; - if (currencyId != 0) - { - playerRewards.RewardItem = currencyId; - playerRewards.RewardItemQuantity = rewardData.quest.RewardCurrencyCount[i]; - playerRewards.IsCurrency = true; - playerReward.Rewards.Add(playerRewards); - } - } + LFGPlayerReward lfgPlayerReward = new LFGPlayerReward(); + lfgPlayerReward.QueuedSlot = rewardData.rdungeonEntry; + lfgPlayerReward.ActualSlot = rewardData.sdungeonEntry; + lfgPlayerReward.RewardMoney = GetPlayer().GetQuestMoneyReward(rewardData.quest); + lfgPlayerReward.AddedXP = GetPlayer().GetQuestXPReward(rewardData.quest); for (byte i = 0; i < SharedConst.QuestRewardItemCount; ++i) { - var playerRewards = new LFGPlayerReward.LFGPlayerRewards(); uint itemId = rewardData.quest.RewardItemId[i]; if (itemId != 0) - { - ItemTemplate item = Global.ObjectMgr.GetItemTemplate(itemId); - playerRewards.RewardItem = itemId; - playerRewards.RewardItemQuantity = rewardData.quest.RewardItemCount[i]; - playerRewards.IsCurrency = false; - playerReward.Rewards.Add(playerRewards); - } + lfgPlayerReward.Rewards.Add(new LFGPlayerRewards(itemId, rewardData.quest.RewardItemCount[i], 0, false)); } - SendPacket(playerReward); + for (byte i = 0; i < SharedConst.QuestRewardCurrencyCount; ++i) + { + uint currencyId = rewardData.quest.RewardCurrencyId[i]; + if (currencyId != 0) + lfgPlayerReward.Rewards.Add(new LFGPlayerRewards(currencyId, rewardData.quest.RewardCurrencyCount[i], 0, true)); + } + + SendPacket(lfgPlayerReward); } public void SendLfgBootProposalUpdate(LfgPlayerBoot boot) { - ObjectGuid guid = GetPlayer().GetGUID(); - LfgAnswer playerVote = boot.votes.LookupByKey(guid); + LfgAnswer playerVote = boot.votes.LookupByKey(GetPlayer().GetGUID()); byte votesNum = 0; byte agreeNum = 0; uint secsleft = (uint)((boot.cancelTime - Time.UnixTime) / 1000); @@ -515,42 +472,34 @@ namespace Game dungeonEntry = playerDungeons.First(); } - dungeonEntry = Global.LFGMgr.GetLFGDungeonEntry(dungeonEntry); + LFGProposalUpdate lfgProposalUpdate = new LFGProposalUpdate(); - LFGProposalUpdate proposalUpdate = new LFGProposalUpdate(); - proposalUpdate.Ticket = new RideTicket(playerGuid, Global.LFGMgr.GetQueueId(playerGuid), 3, (uint)Global.LFGMgr.GetQueueJoinTime(playerGuid)); - - proposalUpdate.InstanceID = dungeonEntry; - proposalUpdate.ProposalID = proposal.id; - proposalUpdate.Slot = proposal.dungeonId; - proposalUpdate.State = (byte)proposal.state; - proposalUpdate.CompletedMask = proposal.encounters; - - proposalUpdate.ValidCompletedMask = false; - proposalUpdate.ProposalSilent = silent; + RideTicket ticket = Global.LFGMgr.GetTicket(GetPlayer().GetGUID()); + if (ticket != null) + lfgProposalUpdate.Ticket = ticket; + lfgProposalUpdate.InstanceID = 0; + lfgProposalUpdate.ProposalID = proposal.id; + lfgProposalUpdate.Slot = Global.LFGMgr.GetLFGDungeonEntry(dungeonEntry); + lfgProposalUpdate.State = (byte)proposal.state; + lfgProposalUpdate.CompletedMask = proposal.encounters; + lfgProposalUpdate.ValidCompletedMask = true; + lfgProposalUpdate.ProposalSilent = silent; + lfgProposalUpdate.IsRequeue = !proposal.isNew; foreach (var pair in proposal.players) { - var updatePlayer = new LFGProposalUpdate.LFGProposalUpdatePlayer(); - updatePlayer.Roles = (uint)pair.Value.role; - updatePlayer.Me = (pair.Key == playerGuid); - updatePlayer.SameParty = (pair.Value.group == guildGuid); - updatePlayer.MyParty = (pair.Value.group == proposal.group); - updatePlayer.Responded = (pair.Value.accept != LfgAnswer.Pending); - updatePlayer.Accepted = (pair.Value.accept == LfgAnswer.Agree); + var proposalPlayer = new LFGProposalUpdatePlayer(); + proposalPlayer.Roles = (uint)pair.Value.role; + proposalPlayer.Me = (pair.Key == playerGuid); + proposalPlayer.MyParty = !pair.Value.group.IsEmpty() && pair.Value.group == proposal.group; + proposalPlayer.SameParty = !pair.Value.group.IsEmpty() && pair.Value.group == guildGuid; + proposalPlayer.Responded = (pair.Value.accept != LfgAnswer.Pending); + proposalPlayer.Accepted = (pair.Value.accept == LfgAnswer.Agree); - proposalUpdate.Players.Add(updatePlayer); + lfgProposalUpdate.Players.Add(proposalPlayer); } - SendPacket(proposalUpdate); - } - - public void SendLfgLfrList(bool update) - { - /* WorldPacket data = new WorldPacket(ServerOpcodes.LfgUpdateSearch); - data.WriteUInt8(update); // In Lfg Queue? - SendPacket(data); - */ + SendPacket(lfgProposalUpdate); } public void SendLfgDisabled() @@ -561,17 +510,13 @@ namespace Game public void SendLfgOfferContinue(uint dungeonEntry) { Log.outDebug(LogFilter.Lfg, "SMSG_LFG_OFFER_CONTINUE {0} dungeon entry: {1}", GetPlayerInfo(), dungeonEntry); - LfgOfferContinue lfgOfferContinue = new LfgOfferContinue(); - lfgOfferContinue.Slot = dungeonEntry; - SendPacket(lfgOfferContinue); + SendPacket(new LfgOfferContinue(Global.LFGMgr.GetLFGDungeonEntry(dungeonEntry))); } public void SendLfgTeleportError(LfgTeleportResult err) { Log.outDebug(LogFilter.Lfg, "SMSG_LFG_TELEPORT_DENIED {0} reason: {1}", GetPlayerInfo(), err); - LfgTeleportDenied lfgTeleportDenied = new LfgTeleportDenied(); - lfgTeleportDenied.Reason = err; - SendPacket(lfgTeleportDenied); + SendPacket(new LfgTeleportDenied(err)); } } } \ No newline at end of file diff --git a/Game/Network/Packets/LFGPackets.cs b/Game/Network/Packets/LFGPackets.cs index 315090724..54ebadc28 100644 --- a/Game/Network/Packets/LFGPackets.cs +++ b/Game/Network/Packets/LFGPackets.cs @@ -22,99 +22,6 @@ using System.Collections.Generic; namespace Game.Network.Packets { - class LfgDisabled : ServerPacket - { - public LfgDisabled() : base(ServerOpcodes.LfgDisabled, ConnectionType.Instance) { } - - public override void Write() { } - } - - class LfgOfferContinue : ServerPacket - { - public LfgOfferContinue() : base(ServerOpcodes.LfgOfferContinue, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WriteUInt32(Slot); - } - - public uint Slot; - } - - class LfgTeleportDenied : ServerPacket - { - public LfgTeleportDenied() : base(ServerOpcodes.LfgTeleportDenied, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WriteUInt32(Reason); - } - - public LfgTeleportResult Reason; - } - - class LfgBootPlayer : ServerPacket - { - public LfgBootPlayer() : base(ServerOpcodes.LfgBootPlayer, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WriteBit(Info.VoteInProgress); - _worldPacket.WriteBit(Info.VotePassed); - _worldPacket.WriteBit(Info.MyVoteCompleted); - _worldPacket.WriteBit(Info.MyVote); - _worldPacket.WriteBits(Info.Reason.Length, 8); - _worldPacket.FlushBits(); - - _worldPacket.WritePackedGuid(Info.Target); - _worldPacket.WriteUInt32(Info.TotalVotes); - _worldPacket.WriteUInt32(Info.BootVotes); - _worldPacket.WriteUInt32(Info.TimeLeft); - _worldPacket.WriteUInt32(Info.VotesNeeded); - _worldPacket.WriteString(Info.Reason); - } - - public LfgBootInfo Info = new LfgBootInfo(); - } - - class RoleChosen : ServerPacket - { - public RoleChosen() : base(ServerOpcodes.RoleChosen) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(Player); - _worldPacket.WriteUInt32(RoleMask); - _worldPacket.WriteBit(Accepted); - _worldPacket.FlushBits(); - } - - public bool Accepted; - public LfgRoles RoleMask; - public ObjectGuid Player; - } - - class DFGetSystemInfo : ClientPacket - { - public DFGetSystemInfo(WorldPacket packet) : base(packet) { } - - public override void Read() - { - Player = _worldPacket.HasBit(); - PartyIndex = _worldPacket.ReadUInt8(); - } - - public bool Player; - public byte PartyIndex; - } - - class DFGetJoinStatus : ClientPacket - { - public DFGetJoinStatus(WorldPacket packet) : base(packet) { } - - public override void Read() { } - } - class DFJoin : ClientPacket { public DFJoin(WorldPacket packet) : base(packet) { } @@ -122,27 +29,20 @@ namespace Game.Network.Packets public override void Read() { QueueAsGroup = _worldPacket.HasBit(); - var commentLength = _worldPacket.ReadBits(8); - + Unknown = _worldPacket.HasBit(); PartyIndex = _worldPacket.ReadUInt8(); Roles = (LfgRoles)_worldPacket.ReadUInt32(); + var slotsCount = _worldPacket.ReadInt32(); - - for (var i = 0; i < 3; ++i) // Needs - Needs[i] = _worldPacket.ReadUInt32(); - - Comment = _worldPacket.ReadString(commentLength); - for (var i = 0; i < slotsCount; ++i) // Slots Slots.Add(_worldPacket.ReadUInt32()); } public bool QueueAsGroup; - public LfgRoles Roles; + bool Unknown; // Always false in 7.2.5 public byte PartyIndex; - public string Comment = ""; + public LfgRoles Roles; public List Slots = new List(); - public uint[] Needs = new uint[3]; } class DFLeave : ClientPacket @@ -157,90 +57,6 @@ namespace Game.Network.Packets public RideTicket Ticket; } - class LFGJoinResult : ServerPacket - { - public LFGJoinResult() : base(ServerOpcodes.LfgJoinResult) { } - - public override void Write() - { - Ticket.Write(_worldPacket); - - _worldPacket.WriteUInt8(Result); - _worldPacket.WriteUInt8(ResultDetail); - - _worldPacket.WriteUInt32(BlackList.Count); - foreach (var blackList in BlackList) - { - _worldPacket.WritePackedGuid(blackList.PlayerGuid.Value); - - _worldPacket.WriteUInt32(blackList.BlackListSlots.Count); - foreach (var blackListSlot in blackList.BlackListSlots) - { - _worldPacket.WriteUInt32(blackListSlot.Slot); - _worldPacket.WriteUInt32(blackListSlot.Reason); - _worldPacket.WriteInt32(blackListSlot.SubReason1); - _worldPacket.WriteInt32(blackListSlot.SubReason2); - } - } - } - - public byte Result; - public List BlackList = new List(); - public byte ResultDetail; - public RideTicket Ticket; - } - - class LFGUpdateStatus : ServerPacket - { - public LFGUpdateStatus() : base(ServerOpcodes.LfgUpdateStatus) { } - - public override void Write() - { - Ticket.Write(_worldPacket); - - _worldPacket.WriteUInt8(SubType); - _worldPacket.WriteUInt8(Reason); - - for (int i = 0; i < 3; i++) - _worldPacket.WriteUInt8(Needs[i]); - - _worldPacket.WriteUInt32(Slots.Count); - _worldPacket.WriteUInt32(RequestedRoles); - _worldPacket.WriteUInt32(SuspendedPlayers.Count); - - foreach (var slot in Slots) - _worldPacket.WriteUInt32(slot); - - foreach (var player in SuspendedPlayers) - _worldPacket.WritePackedGuid(player); - - _worldPacket.WriteBit(IsParty); - _worldPacket.WriteBit(NotifyUI); - _worldPacket.WriteBit(Joined); - _worldPacket.WriteBit(LfgJoined); - _worldPacket.WriteBit(Queued); - - _worldPacket.WriteBits(Comment.Length, 8); - _worldPacket.WriteString(Comment); - } - - public RideTicket Ticket; - public byte SubType; - public byte Reason; - public byte[] Needs = new byte[3]; - public uint RequestedRoles; - - public List Slots = new List(); - public List SuspendedPlayers = new List(); - - public bool IsParty; - public bool NotifyUI; - public bool Joined; - public bool LfgJoined; - public bool Queued; - public string Comment = ""; - } - class DFProposalResponse : ClientPacket { public DFProposalResponse(WorldPacket packet) : base(packet) { } @@ -259,230 +75,6 @@ namespace Game.Network.Packets public bool Accepted; } - class LFGProposalUpdate : ServerPacket - { - public LFGProposalUpdate() : base(ServerOpcodes.LfgProposalUpdate) { } - - public override void Write() - { - Ticket.Write(_worldPacket); - - _worldPacket.WriteUInt64(InstanceID); - _worldPacket.WriteUInt32(ProposalID); - _worldPacket.WriteUInt32(Slot); - _worldPacket.WriteUInt8(State); - _worldPacket.WriteUInt32(CompletedMask); - - _worldPacket.WriteUInt32(Players.Count); - foreach (var player in Players) - { - _worldPacket.WriteUInt32(player.Roles); - - _worldPacket.WriteBit(player.Me); - _worldPacket.WriteBit(player.SameParty); - _worldPacket.WriteBit(player.MyParty); - _worldPacket.WriteBit(player.Responded); - _worldPacket.WriteBit(player.Accepted); - _worldPacket.FlushBits(); - } - - _worldPacket.WriteBit(ValidCompletedMask); - _worldPacket.WriteBit(ProposalSilent); - _worldPacket.FlushBits(); - } - - public RideTicket Ticket; - public ulong InstanceID; - public uint ProposalID; - public uint Slot; - public byte State; - public uint CompletedMask; - public List Players = new List(); - public bool ValidCompletedMask; - public bool ProposalSilent; - - public struct LFGProposalUpdatePlayer - { - public uint Roles; - public bool Me; - public bool SameParty; - public bool MyParty; - public bool Responded; - public bool Accepted; - } - } - - class LFGQueueStatus : ServerPacket - { - public LFGQueueStatus() : base(ServerOpcodes.LfgQueueStatus) { } - - public override void Write() - { - Ticket.Write(_worldPacket); - - _worldPacket.WriteUInt32(Slot); - _worldPacket.WriteUInt32(AvgWaitTime); - _worldPacket.WriteUInt32(QueuedTime); - - for (int i = 0; i < 3; i++) - { - _worldPacket.WriteUInt32(AvgWaitTimeByRole[i]); - _worldPacket.WriteUInt8(LastNeeded[i]); - } - - _worldPacket.WriteUInt32(AvgWaitTimeMe); - } - - public RideTicket Ticket; - public uint Slot; - public uint AvgWaitTime; - public uint QueuedTime; - public byte[] LastNeeded = new byte[3]; - public uint[] AvgWaitTimeByRole = new uint[3]; - public uint AvgWaitTimeMe; - } - - class LfgPlayerInfo : ServerPacket - { - public LfgPlayerInfo() : base(ServerOpcodes.LfgPlayerInfo) { } - - public override void Write() - { - _worldPacket.WriteUInt32(Dungeons.Count); - - _worldPacket.WriteBit(BlackList.PlayerGuid.HasValue); - _worldPacket.WriteUInt32(BlackList.BlackListSlots.Count); - - if (BlackList.PlayerGuid.HasValue) - _worldPacket.WritePackedGuid(BlackList.PlayerGuid.Value); - - foreach (var blackListSlot in BlackList.BlackListSlots) - { - _worldPacket.WriteUInt32(blackListSlot.Slot); - _worldPacket.WriteUInt32(blackListSlot.Reason); - _worldPacket.WriteInt32(blackListSlot.SubReason1); - _worldPacket.WriteInt32(blackListSlot.SubReason2); - } - - foreach (var dungeonInfo in Dungeons) - { - dungeonInfo.Write(_worldPacket); - } - } - - public LFGBlackList BlackList; - public List Dungeons = new List(); - } - - class LfgPartyInfo : ServerPacket - { - public LfgPartyInfo() : base(ServerOpcodes.LfgPartyInfo) { } - - public override void Write() - { - _worldPacket.WriteUInt32(Players.Count); - foreach (var blackList in Players) - { - _worldPacket.WriteBit(blackList.PlayerGuid.HasValue); - _worldPacket.WriteUInt32(blackList.BlackListSlots.Count); - - if (blackList.PlayerGuid.HasValue) - _worldPacket.WritePackedGuid(blackList.PlayerGuid.Value); - - foreach (var blackListSlot in blackList.BlackListSlots) - { - _worldPacket.WriteUInt32(blackListSlot.Slot); - _worldPacket.WriteUInt32(blackListSlot.Reason); - _worldPacket.WriteInt32(blackListSlot.SubReason1); - _worldPacket.WriteInt32(blackListSlot.SubReason2); - } - } - } - - public List Players = new List(); - } - - class LFGPlayerReward : ServerPacket - { - public LFGPlayerReward() : base(ServerOpcodes.LfgPlayerReward) { } - - public override void Write() - { - _worldPacket.WriteUInt32(ActualSlot); // unconfirmed order - _worldPacket.WriteUInt32(QueuedSlot); // unconfirmed order - _worldPacket.WriteUInt32(RewardMoney); - _worldPacket.WriteUInt32(AddedXP); - - _worldPacket.WriteUInt32(Rewards.Count); - foreach (var reward in Rewards) - { - _worldPacket.WriteUInt32(reward.RewardItem); - _worldPacket.WriteUInt32(reward.RewardItemQuantity); - _worldPacket.WriteUInt32(reward.BonusCurrency); - _worldPacket.WriteBit(reward.IsCurrency); - _worldPacket.FlushBits(); - } - } - - public uint ActualSlot; - public uint QueuedSlot; - public uint RewardMoney; - public uint AddedXP; - public List Rewards = new List(); - - public struct LFGPlayerRewards - { - public uint RewardItem; - public uint RewardItemQuantity; - public int BonusCurrency; - public bool IsCurrency; - } - } - - class LFGRoleCheckUpdate : ServerPacket - { - public LFGRoleCheckUpdate() : base(ServerOpcodes.LfgRoleCheckUpdate) { } - - public override void Write() - { - _worldPacket.WriteUInt8(PartyIndex); - _worldPacket.WriteUInt8(RoleCheckStatus); - _worldPacket.WriteUInt32(JoinSlots.Count); - _worldPacket.WriteUInt64(BgQueueID); - _worldPacket.WriteUInt32(0);// ActivityID);//Not in jam - _worldPacket.WriteUInt32(Members.Count); - - foreach (var slot in JoinSlots) - _worldPacket.WriteUInt32(slot); - - foreach (var member in Members) - { - _worldPacket.WritePackedGuid(member.Guid); - _worldPacket.WriteUInt32(member.RolesDesired); - _worldPacket.WriteUInt8(member.Level); - _worldPacket.WriteBit(member.RoleCheckComplete); - } - - _worldPacket.WriteBit(IsBeginning); - _worldPacket.WriteBit(true);// ShowRoleCheck);//Not in jam - } - - public byte PartyIndex; - public byte RoleCheckStatus; - public ulong BgQueueID; - public List JoinSlots = new List(); - public List Members = new List(); - public bool IsBeginning; - - public class LFGRoleCheckUpdateMember - { - public ObjectGuid Guid; - public bool RoleCheckComplete; - public uint RolesDesired; - public byte Level; - } - } - class DFSetRoles : ClientPacket { public DFSetRoles(WorldPacket packet) : base(packet) { } @@ -521,79 +113,438 @@ namespace Game.Network.Packets public bool TeleportOut; } - //Structs - public class LfgBootInfo + class DFGetSystemInfo : ClientPacket { - public bool VoteInProgress; - public bool VotePassed; - public bool MyVoteCompleted; - public bool MyVote; - public ObjectGuid Target; - public uint TotalVotes; - public uint BootVotes; - public uint TimeLeft; - public uint VotesNeeded; - public string Reason; + public DFGetSystemInfo(WorldPacket packet) : base(packet) { } + + public override void Read() + { + Player = _worldPacket.HasBit(); + PartyIndex = _worldPacket.ReadUInt8(); + } + + public byte PartyIndex; + public bool Player; } - public struct RideTicket + class DFGetJoinStatus : ClientPacket { - public RideTicket(ObjectGuid requesterGuid, uint id, int type, uint time) + public DFGetJoinStatus(WorldPacket packet) : base(packet) { } + + public override void Read() { } + } + + class LfgPlayerInfo : ServerPacket + { + public LfgPlayerInfo() : base(ServerOpcodes.LfgPlayerInfo, ConnectionType.Instance) { } + + public override void Write() { - RequesterGuid = requesterGuid; - Id = id; - Type = type; - Time = time; + _worldPacket.WriteUInt32(Dungeons.Count); + BlackList.Write(_worldPacket); + + foreach (var dungeonInfo in Dungeons) + dungeonInfo.Write(_worldPacket); } - public void Read(WorldPacket data) + public LFGBlackList BlackList = new LFGBlackList(); + public List Dungeons = new List(); + } + + class LfgPartyInfo : ServerPacket + { + public LfgPartyInfo() : base(ServerOpcodes.LfgPartyInfo, ConnectionType.Instance) { } + + public override void Write() { - RequesterGuid = data.ReadPackedGuid(); - Id = data.ReadUInt32(); - Type = data.ReadInt32(); - Time = data.ReadUInt32(); + _worldPacket.WriteUInt32(Player.Count); + foreach (var blackList in Player) + blackList.Write(_worldPacket); } - public void Write(WorldPacket data) + public List Player = new List(); + } + + class LFGUpdateStatus : ServerPacket + { + public LFGUpdateStatus() : base(ServerOpcodes.LfgUpdateStatus) { } + + public override void Write() { - data.WritePackedGuid(RequesterGuid); - data.WriteUInt32(Id); - data.WriteInt32(Type); - data.WriteUInt32(Time); + Ticket.Write(_worldPacket); + + _worldPacket.WriteUInt8(SubType); + _worldPacket.WriteUInt8(Reason); + _worldPacket.WriteUInt32(Slots.Count); + _worldPacket.WriteUInt32(RequestedRoles); + _worldPacket.WriteUInt32(SuspendedPlayers.Count); + + foreach (var slot in Slots) + _worldPacket.WriteUInt32(slot); + + foreach (var player in SuspendedPlayers) + _worldPacket.WritePackedGuid(player); + + _worldPacket.WriteBit(IsParty); + _worldPacket.WriteBit(NotifyUI); + _worldPacket.WriteBit(Joined); + _worldPacket.WriteBit(LfgJoined); + _worldPacket.WriteBit(Queued); + _worldPacket.WriteBit(Unused); + _worldPacket.FlushBits(); } - public ObjectGuid RequesterGuid; - public uint Id; - public int Type; - public uint Time; + public RideTicket Ticket; + public byte SubType; + public byte Reason; + public List Slots = new List(); + public uint RequestedRoles; + public List SuspendedPlayers = new List(); + public bool NotifyUI; + public bool IsParty; + public bool Joined; + public bool LfgJoined; + public bool Queued; + public bool Unused; + } + + class RoleChosen : ServerPacket + { + public RoleChosen() : base(ServerOpcodes.RoleChosen) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(Player); + _worldPacket.WriteUInt32(RoleMask); + _worldPacket.WriteBit(Accepted); + _worldPacket.FlushBits(); + } + + public ObjectGuid Player; + public LfgRoles RoleMask; + public bool Accepted; + } + + class LFGRoleCheckUpdate : ServerPacket + { + public LFGRoleCheckUpdate() : base(ServerOpcodes.LfgRoleCheckUpdate) { } + + public override void Write() + { + _worldPacket.WriteUInt8(PartyIndex); + _worldPacket.WriteUInt8(RoleCheckStatus); + _worldPacket.WriteUInt32(JoinSlots.Count); + _worldPacket.WriteUInt64(BgQueueID); + _worldPacket.WriteUInt32(GroupFinderActivityID); + _worldPacket.WriteUInt32(Members.Count); + + foreach (var slot in JoinSlots) + _worldPacket.WriteUInt32(slot); + + _worldPacket.WriteBit(IsBeginning); + _worldPacket.WriteBit(IsRequeue); + _worldPacket.FlushBits(); + + foreach (var member in Members) + member.Write(_worldPacket); + } + + public byte PartyIndex; + public byte RoleCheckStatus; + public List JoinSlots = new List(); + public ulong BgQueueID; + public int GroupFinderActivityID = 0; + public List Members = new List(); + public bool IsBeginning; + public bool IsRequeue; + } + + class LFGJoinResult : ServerPacket + { + public LFGJoinResult() : base(ServerOpcodes.LfgJoinResult) { } + + public override void Write() + { + Ticket.Write(_worldPacket); + + _worldPacket.WriteUInt8(Result); + _worldPacket.WriteUInt8(ResultDetail); + _worldPacket.WriteUInt32(BlackList.Count); + + foreach (LFGJoinBlackList blackList in BlackList) + blackList.Write(_worldPacket); + } + + public RideTicket Ticket; + public byte Result; + public byte ResultDetail; + public List BlackList = new List(); + } + + class LFGQueueStatus : ServerPacket + { + public LFGQueueStatus() : base(ServerOpcodes.LfgQueueStatus) { } + + public override void Write() + { + Ticket.Write(_worldPacket); + + _worldPacket.WriteUInt32(Slot); + _worldPacket.WriteUInt32(AvgWaitTimeMe); + _worldPacket.WriteUInt32(AvgWaitTime); + + for (int i = 0; i < 3; i++) + { + _worldPacket.WriteUInt32(AvgWaitTimeByRole[i]); + _worldPacket.WriteUInt8(LastNeeded[i]); + } + + _worldPacket.WriteUInt32(QueuedTime); + } + + public RideTicket Ticket; + public uint Slot; + public uint AvgWaitTimeMe; + public uint AvgWaitTime; + public uint[] AvgWaitTimeByRole = new uint[3]; + public byte[] LastNeeded = new byte[3]; + public uint QueuedTime; + } + + class LFGPlayerReward : ServerPacket + { + public LFGPlayerReward() : base(ServerOpcodes.LfgPlayerReward) { } + + public override void Write() + { + _worldPacket.WriteUInt32(QueuedSlot); + _worldPacket.WriteUInt32(ActualSlot); + _worldPacket.WriteUInt32(RewardMoney); + _worldPacket.WriteUInt32(AddedXP); + _worldPacket.WriteUInt32(Rewards.Count); + + foreach (var reward in Rewards) + reward.Write(_worldPacket); + } + + public uint QueuedSlot; + public uint ActualSlot; + public uint RewardMoney; + public uint AddedXP; + public List Rewards = new List(); + } + + class LfgBootPlayer : ServerPacket + { + public LfgBootPlayer() : base(ServerOpcodes.LfgBootPlayer, ConnectionType.Instance) { } + + public override void Write() + { + Info.Write(_worldPacket); + } + + public LfgBootInfo Info = new LfgBootInfo(); + } + + class LFGProposalUpdate : ServerPacket + { + public LFGProposalUpdate() : base(ServerOpcodes.LfgProposalUpdate) { } + + public override void Write() + { + Ticket.Write(_worldPacket); + + _worldPacket.WriteUInt64(InstanceID); + _worldPacket.WriteUInt32(ProposalID); + _worldPacket.WriteUInt32(Slot); + _worldPacket.WriteUInt8(State); + _worldPacket.WriteUInt32(CompletedMask); + _worldPacket.WriteUInt32(Players.Count); + _worldPacket.WriteUInt8(Unused); + _worldPacket.WriteBit(ValidCompletedMask); + _worldPacket.WriteBit(ProposalSilent); + _worldPacket.WriteBit(IsRequeue); + _worldPacket.FlushBits(); + + foreach (var player in Players) + player.Write(_worldPacket); + } + + public RideTicket Ticket; + public ulong InstanceID; + public uint ProposalID; + public uint Slot; + public byte State; + public uint CompletedMask; + public byte Unused; + public bool ValidCompletedMask; + public bool ProposalSilent; + public bool IsRequeue; + public List Players = new List(); + } + + class LfgDisabled : ServerPacket + { + public LfgDisabled() : base(ServerOpcodes.LfgDisabled, ConnectionType.Instance) { } + + public override void Write() { } + } + + class LfgOfferContinue : ServerPacket + { + public LfgOfferContinue(uint slot) : base(ServerOpcodes.LfgOfferContinue, ConnectionType.Instance) + { + Slot = slot; + } + + public override void Write() + { + _worldPacket.WriteUInt32(Slot); + } + + public uint Slot; + } + + class LfgTeleportDenied : ServerPacket + { + public LfgTeleportDenied(LfgTeleportResult reason) : base(ServerOpcodes.LfgTeleportDenied, ConnectionType.Instance) + { + Reason = reason; + } + + public override void Write() + { + _worldPacket.WriteBits(Reason, 4); + _worldPacket.FlushBits(); + } + + public LfgTeleportResult Reason; + } + + //Structs + public class LFGBlackListSlot + { + public LFGBlackListSlot(uint slot, uint reason, int subReason1, int subReason2) + { + Slot = slot; + Reason = reason; + SubReason1 = subReason1; + SubReason2 = subReason2; + } + + public uint Slot { get; set; } + public uint Reason { get; set; } + public int SubReason1 { get; set; } + public int SubReason2 { get; set; } } public class LFGBlackList { - public LFGBlackList(Dictionary lockInfoData) + public void Write(WorldPacket data) { - foreach (var lockInfo in lockInfoData) - { - var blackListSlot = new LFGBlackList.LFGBlackListSlot(); - blackListSlot.Slot = lockInfo.Key; // Dungeon entry (id + type) - blackListSlot.Reason = (uint)lockInfo.Value.lockStatus; - blackListSlot.SubReason1 = lockInfo.Value.requiredItemLevel; - blackListSlot.SubReason2 = (int)lockInfo.Value.currentItemLevel; + data.WriteBit(PlayerGuid.HasValue); + data.WriteUInt32(Slot.Count); + if (PlayerGuid.HasValue) + data.WritePackedGuid(PlayerGuid.Value); - BlackListSlots.Add(blackListSlot); + foreach (LFGBlackListSlot lfgBlackListSlot in Slot) + { + data.WriteUInt32(lfgBlackListSlot.Slot); + data.WriteUInt32(lfgBlackListSlot.Reason); + data.WriteInt32(lfgBlackListSlot.SubReason1); + data.WriteInt32(lfgBlackListSlot.SubReason2); } } public Optional PlayerGuid; - public List BlackListSlots = new List(); + public List Slot = new List(); + } - public class LFGBlackListSlot + public struct LfgPlayerQuestRewardItem + { + public LfgPlayerQuestRewardItem(uint itemId, uint quantity) { - public uint Slot { get; set; } - public uint Reason { get; set; } - public int SubReason1 { get; set; } - public int SubReason2 { get; set; } + ItemID = itemId; + Quantity = quantity; } + + public uint ItemID; + public uint Quantity; + } + + public struct LfgPlayerQuestRewardCurrency + { + public LfgPlayerQuestRewardCurrency(uint currencyId, uint quantity) + { + CurrencyID = currencyId; + Quantity = quantity; + } + + public uint CurrencyID; + public uint Quantity; + } + + public class LfgPlayerQuestReward + { + public void Write(WorldPacket data) + { + data.WriteInt32(Mask); + data.WriteUInt32(RewardMoney); + data.WriteUInt32(RewardXP); + data.WriteInt32(Item.Count); + data.WriteInt32(Currency.Count); + data.WriteInt32(BonusCurrency.Count); + + // Item + foreach (var item in Item) + { + data.WriteUInt32(item.ItemID); + data.WriteUInt32(item.Quantity); + } + + // Currency + foreach (var currency in Currency) + { + data.WriteUInt32(currency.CurrencyID); + data.WriteUInt32(currency.Quantity); + } + + // BonusCurrency + foreach (var bonusCurrency in BonusCurrency) + { + data.WriteUInt32(bonusCurrency.CurrencyID); + data.WriteUInt32(bonusCurrency.Quantity); + } + + data.WriteBit(RewardSpellID.HasValue); + data.WriteBit(Unused1.HasValue); + data.WriteBit(Unused2.HasValue); + data.WriteBit(Honor.HasValue); + data.FlushBits(); + + if (RewardSpellID.HasValue) + data.WriteInt32(RewardSpellID.Value); + + if (Unused1.HasValue) + data.WriteInt32(Unused1.Value); + + if (Unused2.HasValue) + data.WriteUInt64(Unused2.Value); + + if (Honor.HasValue) + data.WriteInt32(Honor.Value); + } + + public uint Mask; + public uint RewardMoney; + public uint RewardXP; + public List Item = new List(); + public List Currency = new List(); + public List BonusCurrency = new List(); + public Optional RewardSpellID; // Only used by SMSG_LFG_PLAYER_INFO + public Optional Unused1; + public Optional Unused2; + public Optional Honor; // Only used by SMSG_REQUEST_PVP_REWARDS_RESPONSE } public class LfgPlayerDungeonInfo @@ -614,22 +565,18 @@ namespace Game.Network.Packets data.WriteInt32(PurseLimit); data.WriteInt32(Quantity); data.WriteInt32(CompletedMask); - + data.WriteUInt32(EncounterMask); data.WriteInt32(ShortageReward.Count); - - Rewards.Write(data); - - // ShortageReward - foreach (var shortage in ShortageReward) - shortage.Write(data); - data.WriteBit(FirstReward); data.WriteBit(ShortageEligible); data.FlushBits(); + + Rewards.Write(data); + foreach (var shortageReward in ShortageReward) + shortageReward.Write(data); } public uint Slot; - public bool FirstReward; public int CompletionQuantity; public int CompletionLimit; public int CompletionCurrencyID; @@ -643,68 +590,185 @@ namespace Game.Network.Packets public int PurseLimit; public int Quantity; public uint CompletedMask; + public uint EncounterMask; + public bool FirstReward; public bool ShortageEligible; - public List ShortageReward = new List(); public LfgPlayerQuestReward Rewards = new LfgPlayerQuestReward(); + public List ShortageReward = new List(); } - public class LfgPlayerQuestReward + public class LFGRoleCheckUpdateMember { + public LFGRoleCheckUpdateMember(ObjectGuid guid, uint rolesDesired, byte level, bool roleCheckComplete) + { + Guid = guid; + RolesDesired = rolesDesired; + Level = level; + RoleCheckComplete = roleCheckComplete; + } + public void Write(WorldPacket data) { - data.WriteInt32(Mask); - data.WriteUInt32(RewardMoney); - data.WriteUInt32(RewardXP); - - data.WriteInt32(Items.Count); - data.WriteInt32(Currency.Count); - data.WriteInt32(BonusCurrency.Count); - - // Item - foreach (var item in Items) - { - data.WriteUInt32(item.ItemID); - data.WriteUInt32(item.Quantity); - } - - // Currency - foreach (var currency in Currency) - { - data.WriteUInt32(currency.CurrencyID); - data.WriteUInt32(currency.Quantity); - } - - // BonusCurrency - foreach (var currency in BonusCurrency) - { - data.WriteUInt32(currency.CurrencyID); - data.WriteUInt32(currency.Quantity); - } - - var bit30 = data.WriteBit(false); - if (bit30) - data.WriteUInt32(0); - + data.WritePackedGuid(Guid); + data.WriteUInt32(RolesDesired); + data.WriteUInt8(Level); + data.WriteBit(RoleCheckComplete); data.FlushBits(); } - public uint Mask; - public uint RewardMoney; - public uint RewardXP; - public List Items = new List(); - public List Currency = new List(); - public List BonusCurrency = new List(); + public ObjectGuid Guid; + public uint RolesDesired; + public byte Level; + public bool RoleCheckComplete; + } - public struct LfgPlayerQuestRewardItem + public struct LFGJoinBlackListSlot + { + public LFGJoinBlackListSlot(int slot, int reason, int subReason1, int subReason2) { - public uint ItemID; - public uint Quantity; + Slot = slot; + Reason = reason; + SubReason1 = subReason1; + SubReason2 = subReason2; } - public struct LfgPlayerQuestRewardCurrency + public int Slot { get; set; } + public int Reason { get; set; } + public int SubReason1 { get; set; } + public int SubReason2 { get; set; } + } + + public class LFGJoinBlackList + { + public void Write(WorldPacket data) { - public uint CurrencyID; - public uint Quantity; + data.WritePackedGuid(PlayerGuid); + data.WriteUInt32(Slots.Count); + + foreach (LFGJoinBlackListSlot lfgBlackListSlot in Slots) + { + data.WriteInt32(lfgBlackListSlot.Slot); + data.WriteInt32(lfgBlackListSlot.Reason); + data.WriteInt32(lfgBlackListSlot.SubReason1); + data.WriteInt32(lfgBlackListSlot.SubReason2); + } } + + public ObjectGuid PlayerGuid; + public List Slots = new List(); + } + + public struct LFGPlayerRewards + { + public LFGPlayerRewards(uint rewardItem, uint rewardItemQuantity, int bonusCurrency, bool isCurrency) + { + RewardItem = rewardItem; + RewardItemQuantity = rewardItemQuantity; + BonusCurrency = bonusCurrency; + IsCurrency = isCurrency; + } + + public void Write(WorldPacket data) + { + data.WriteInt32(RewardItem); + data.WriteUInt32(RewardItemQuantity); + data.WriteInt32(BonusCurrency); + data.WriteBit(IsCurrency); + data.FlushBits(); + } + + public uint RewardItem; + public uint RewardItemQuantity; + public int BonusCurrency; + public bool IsCurrency; + } + + public class LfgBootInfo + { + public void Write(WorldPacket data) + { + data.WriteBit(VoteInProgress); + data.WriteBit(VotePassed); + data.WriteBit(MyVoteCompleted); + data.WriteBit(MyVote); + data.WriteBits(Reason.Length, 8); + data.WritePackedGuid(Target); + data.WriteUInt32(TotalVotes); + data.WriteUInt32(BootVotes); + data.WriteInt32(TimeLeft); + data.WriteUInt32(VotesNeeded); + data.WriteString(Reason); + } + + public bool VoteInProgress; + public bool VotePassed; + public bool MyVoteCompleted; + public bool MyVote; + public ObjectGuid Target; + public uint TotalVotes; + public uint BootVotes; + public uint TimeLeft; + public uint VotesNeeded; + public string Reason = ""; + } + + public struct LFGProposalUpdatePlayer + { + public void Write(WorldPacket data) + { + data.WriteUInt32(Roles); + data.WriteBit(Me); + data.WriteBit(SameParty); + data.WriteBit(MyParty); + data.WriteBit(Responded); + data.WriteBit(Accepted); + data.FlushBits(); + } + + public uint Roles; + public bool Me; + public bool SameParty; + public bool MyParty; + public bool Responded; + public bool Accepted; + } + + public class RideTicket + { + public RideTicket(ObjectGuid requesterGuid, uint id, RideType type, int time) + { + RequesterGuid = requesterGuid; + Id = id; + Type = type; + Time = time; + } + + public void Read(WorldPacket data) + { + RequesterGuid = data.ReadPackedGuid(); + Id = data.ReadUInt32(); + Type = (RideType)data.ReadUInt32(); + Time = data.ReadInt32(); + } + + public void Write(WorldPacket data) + { + data.WritePackedGuid(RequesterGuid); + data.WriteUInt32(Id); + data.WriteUInt32(Type); + data.WriteInt32(Time); + } + + public ObjectGuid RequesterGuid; + public uint Id; + public RideType Type; + public int Time; + } + + public enum RideType + { + None = 0, + Battlegrounds = 1, + Lfg = 2 } }