From 4ebb97a4c073d8fad36cd1a3b4ba99c1a5193379 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Mon, 16 Sep 2024 21:24:58 -0400 Subject: [PATCH 1/2] enhancement: Handle multiple group edgecases - Created a new class UniqueIdPool to help with creating a pool of reusable 32bit IDs. - Created a new class TimerManager to help with generically using timers across the code base. - Added a timeout to board recruitment. - Added a timeout to board ready up. - Added the ability to kick a member from the entry board. - Added the ability to extend the ready up time. - Enhanced the vote to abandon content mechanism such that it will approve or reject the vote as soon as all members have voted. - Found the proper NTC to end the group content. - Synced timers shown in various UI elements so that they closer match the actual timer on the server. - Refactored existing classes to use new UniqueIdPool and TimerManager classes. --- .../Characters/BoardManager.cs | 188 +++++++++++++++--- .../Characters/PartyQuestContentManager.cs | 134 +++++++------ .../Characters/TimerManager.cs | 136 +++++++++++++ Arrowgene.Ddon.GameServer/DdonGameServer.cs | 9 +- .../EntryBoardEntryBoardItemCreateHandler.cs | 5 +- .../EntryBoardEntryBoardItemEntryHandler.cs | 2 + ...BoardEntryBoardItemExtendTimeoutHandler.cs | 47 +++++ ...tryBoardEntryBoardItemForceStartHandler.cs | 8 +- .../EntryBoardEntryBoardItemReadyHandler.cs | 2 + .../Handler/EntryBoardEntryRecreateHandler.cs | 3 + .../Handler/EntryBoardItemKickHandler.cs | 56 ++++++ .../Handler/PartyPartyLeaveHandler.cs | 1 + .../Handler/QuestPlayEndHandler.cs | 2 +- .../Handler/QuestPlayEntryCancelHandler.cs | 26 +++ .../QuestPlayInterruptAnswerHandler.cs | 35 ++-- .../Handler/QuestPlayInterruptHandler.cs | 19 +- .../Handler/QuestPlayStartTimerHandler.cs | 2 +- .../Quests/GenericQuest.cs | 2 +- .../Utils/UniqueIdPool.cs | 44 ++++ .../Entity/EntitySerializer.cs | 9 + ...C2SEntryBoardEntryBoardExtendTimeoutReq.cs | 30 +++ .../C2SEntryBoardItemKickReq.cs | 34 ++++ .../C2SQuestPlayEntryCancelReq.cs | 24 +++ ...S2CEntryBoardEntryBoardExtendTimeoutRes.cs | 36 ++++ .../S2CEntryBoardEntryBoardItemLeaveNtc.cs | 6 +- .../S2CEntryBoardItemKickRes.cs | 31 +++ .../S2CEntryBoardItemPartyNtc.cs | 27 +++ .../S2CEntryBoardItemTimeoutTimerNtc.cs | 31 +++ .../S2CEntryBoardItemUnreadyNtc.cs | 27 +++ .../S2CQuestPlayEntryCancelRes.cs | 31 +++ .../S2CQuestPlayInterruptAnswerNtc.cs | 2 +- .../Model/EntryBoardLeaveType.cs | 18 ++ Arrowgene.Ddon.Shared/Model/VoteAnswer.cs | 15 ++ Arrowgene.Ddon.Shared/Network/PacketId.cs | 33 ++- 34 files changed, 931 insertions(+), 144 deletions(-) create mode 100644 Arrowgene.Ddon.GameServer/Characters/TimerManager.cs create mode 100644 Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs create mode 100644 Arrowgene.Ddon.GameServer/Handler/EntryBoardItemKickHandler.cs create mode 100644 Arrowgene.Ddon.GameServer/Handler/QuestPlayEntryCancelHandler.cs create mode 100644 Arrowgene.Ddon.GameServer/Utils/UniqueIdPool.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardItemKickReq.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestPlayEntryCancelReq.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemKickRes.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemPartyNtc.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemTimeoutTimerNtc.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemUnreadyNtc.cs create mode 100644 Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayEntryCancelRes.cs create mode 100644 Arrowgene.Ddon.Shared/Model/EntryBoardLeaveType.cs create mode 100644 Arrowgene.Ddon.Shared/Model/VoteAnswer.cs diff --git a/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs b/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs index d86c9a0b7..23d92514c 100644 --- a/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs @@ -1,11 +1,11 @@ +using Arrowgene.Ddon.GameServer.Utils; using Arrowgene.Ddon.Server; +using Arrowgene.Ddon.Shared.Entity.PacketStructure; using Arrowgene.Ddon.Shared.Entity.Structure; using Arrowgene.Ddon.Shared.Model; using Arrowgene.Logging; -using System; using System.Collections.Generic; using System.Linq; -using System.Text.RegularExpressions; namespace Arrowgene.Ddon.GameServer.Characters { @@ -16,11 +16,13 @@ public class BoardManager private Dictionary> _Boards; private Dictionary _Groups; private Dictionary _CharacterToEntryIdMap; - private uint EntryItemIdCounter; - private Stack _FreeEntryItemIds; + private UniqueIdPool _EntryItemIdPool; private static readonly ServerLogger Logger = LogProvider.Logger(typeof(BoardManager)); + public static readonly ushort PARTY_BOARD_TIMEOUT = 3600; + public static readonly ushort ENTRY_BOARD_READY_TIMEOUT = 120; + public class GroupData { public ulong BoardId { get; set; } @@ -31,6 +33,8 @@ public class GroupData public Dictionary MemberReadyState { get; set; } public bool IsInRecreate { get; set; } public bool ContentInProgress { get; set; } + public uint RecruitmentTimerId { get; set; } + public uint ReadyUpTimerId { get; set; } public GroupData() { @@ -55,11 +59,7 @@ public BoardManager(DdonGameServer server) _Boards = new Dictionary>(); _Groups = new Dictionary(); _CharacterToEntryIdMap = new Dictionary(); - - // Entry ID Tracking - EntryItemIdCounter = 1; - _FreeEntryItemIds = new Stack(); - _FreeEntryItemIds.Push(EntryItemIdCounter); + _EntryItemIdPool = new UniqueIdPool(1); } public GroupData CreateNewGroup(ulong boardId, CDataEntryItemParam createParam, string password, uint leaderCharacterId) @@ -71,7 +71,7 @@ public GroupData CreateNewGroup(ulong boardId, CDataEntryItemParam createParam, PartyLeaderCharacterId = leaderCharacterId, }; data.EntryItem.Param = createParam; - data.EntryItem.Id = GenerateEntryItemId(); + data.EntryItem.Id = _EntryItemIdPool.GenerateId(); // TODO: Quest Manager look up min/max @@ -133,7 +133,17 @@ public bool RemoveGroup(uint entryItemId) } } - ReclaimEntryItemId(data.EntryItem.Id); + if (data.RecruitmentTimerId != 0) + { + _Server.TimerManager.CancelTimer(data.RecruitmentTimerId); + } + + if (data.ReadyUpTimerId != 0) + { + _Server.TimerManager.CancelTimer(data.ReadyUpTimerId); + } + + _EntryItemIdPool.ReclaimId(data.EntryItem.Id); } return true; @@ -346,28 +356,160 @@ public uint GetEntryItemIdForCharacter(Character character) return GetEntryItemIdForCharacter(character.CharacterId); } - private uint GenerateEntryItemId() + public bool StartRecruitmentTimer(uint entryItemId, uint timeoutInSeconds) + { + lock (_Boards) + { + var data = GetGroupData(entryItemId); + if (data == null) + { + return false; + } + + data.RecruitmentTimerId = _Server.TimerManager.CreateTimer(timeoutInSeconds, () => + { + lock (_Boards) + { + foreach (var characterId in data.Members) + { + var memberClient = _Server.ClientLookup.GetClientByCharacterId(characterId); + if (memberClient != null) + { + memberClient.Send(new S2CEntryBoardEntryBoardItemLeaveNtc() { LeaveType = EntryBoardLeaveType.EntryBoardTimeUp }); + } + } + } + }); + + if (!_Server.TimerManager.StartTimer(data.RecruitmentTimerId)) + { + _Server.TimerManager.CancelTimer(data.RecruitmentTimerId); + return false; + } + + return true; + } + } + + public ulong GetRecruitmentTimeLeft(uint entryItemId) + { + lock (_Boards) + { + var data = GetGroupData(entryItemId); + if (data == null) + { + return 0; + } + return _Server.TimerManager.GetTimeLeftInSeconds(data.RecruitmentTimerId); + } + } + + public bool CancelRecruitmentTimer(uint entryItemId) + { + lock (_Boards) + { + var data = GetGroupData(entryItemId); + if (data == null) + { + return false; + } + + _Server.TimerManager.CancelTimer(data.RecruitmentTimerId); + data.RecruitmentTimerId = 0; + return true; + } + } + + public bool StartReadyUpTimer(uint entryItemId, uint timeoutInSeconds) { - lock (_FreeEntryItemIds) + lock (_Boards) { - if (_FreeEntryItemIds.Count == 0) + var data = GetGroupData(entryItemId); + if (data == null) { - EntryItemIdCounter = EntryItemIdCounter + 1; - _FreeEntryItemIds.Push(EntryItemIdCounter); + return false; } - var entryItemId = _FreeEntryItemIds.Pop(); - Logger.Info($"Allocating EntryId={entryItemId}"); - return entryItemId; + data.ReadyUpTimerId = _Server.TimerManager.CreateTimer(timeoutInSeconds, () => + { + lock (_Boards) + { + foreach (var characterId in data.Members) + { + var memberClient = _Server.ClientLookup.GetClientByCharacterId(characterId); + if (memberClient != null) + { + memberClient.Send(new S2CEntryBoardItemUnreadyNtc()); + } + } + + // Restart the recruitment timer + data.EntryItem.TimeOut = 3600; + StartRecruitmentTimer(data.EntryItem.Id, 3600); + foreach (var characterId in data.Members) + { + var memberClient = _Server.ClientLookup.GetClientByCharacterId(characterId); + if (memberClient != null) + { + memberClient.Send(new S2CEntryBoardItemTimeoutTimerNtc() { TimeOut = 3600}); + } + } + } + }); + + if (!_Server.TimerManager.StartTimer(data.ReadyUpTimerId)) + { + _Server.TimerManager.CancelTimer(data.ReadyUpTimerId); + return false; + } + + return true; } } - private void ReclaimEntryItemId(uint entryItemId) + public bool CancelReadyUpTimer(uint entryItemId) { - lock (_FreeEntryItemIds) + lock (_Boards) { - Logger.Info($"Reclaiming EntryId={entryItemId}"); - _FreeEntryItemIds.Push(entryItemId); + var data = GetGroupData(entryItemId); + if (data == null) + { + return false; + } + + _Server.TimerManager.CancelTimer(data.ReadyUpTimerId); + data.ReadyUpTimerId = 0; + return true; + } + } + + public bool ExtendReadyUpTimer(uint entryItemId) + { + lock (_Boards) + { + var data = GetGroupData(entryItemId); + if (data == null) + { + return false; + } + + // UI only allows the count down to start from 120 + var ellapsedTime = BoardManager.ENTRY_BOARD_READY_TIMEOUT - _Server.TimerManager.GetTimeLeftInSeconds(data.ReadyUpTimerId); + _Server.TimerManager.ExtendTimer(data.ReadyUpTimerId, (uint)ellapsedTime); + return true; + } + } + + public ushort GetTimeLeftToReadyUp(uint entryItemId) + { + lock (_Boards) + { + var data = GetGroupData(entryItemId); + if (data == null) + { + return 0; + } + return (ushort) _Server.TimerManager.GetTimeLeftInSeconds(data.ReadyUpTimerId); } } } diff --git a/Arrowgene.Ddon.GameServer/Characters/PartyQuestContentManager.cs b/Arrowgene.Ddon.GameServer/Characters/PartyQuestContentManager.cs index f63c9282c..056856648 100644 --- a/Arrowgene.Ddon.GameServer/Characters/PartyQuestContentManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/PartyQuestContentManager.cs @@ -14,29 +14,22 @@ namespace Arrowgene.Ddon.GameServer.Characters public class PartyQuestContentManager { private DdonGameServer _Server; - private Dictionary _ContentTimers; + private Dictionary _ContentTimers; - private Dictionary _VoteTimers; - private Dictionary> _VoteStatus; + private Dictionary _VoteTimers; + private Dictionary> _VoteStatus; private static readonly ServerLogger Logger = LogProvider.Logger(typeof(PartyQuestContentManager)); - internal class TimerState - { - public DateTime TimeStart { get; set; } - public TimeSpan Duration { get; set; } - public Timer Timer { get; set; } - } - public PartyQuestContentManager(DdonGameServer server) { _Server = server; - _ContentTimers = new Dictionary(); - _VoteTimers = new Dictionary(); - _VoteStatus = new Dictionary>(); + _VoteStatus = new Dictionary>(); + _VoteTimers = new Dictionary(); + _ContentTimers = new Dictionary(); } - public void InitatePartyAbandonVote(PartyGroup party, uint timeoutInSeconds) + public void InitatePartyAbandonVote(GameClient client, PartyGroup party, uint timeoutInSeconds) { lock (_VoteStatus) { @@ -46,41 +39,56 @@ public void InitatePartyAbandonVote(PartyGroup party, uint timeoutInSeconds) return; } - _VoteStatus[party.Id] = new Dictionary(); - foreach (var client in party.Clients) + _VoteStatus[party.Id] = new Dictionary(); + foreach (var memberClient in party.Clients) { - _VoteStatus[party.Id][client.Character.CharacterId] = false; + _VoteStatus[party.Id][memberClient.Character.CharacterId] = VoteAnswer.Undecided; } - _VoteTimers[party.Id] = new TimerState(); - var timerState = _VoteTimers[party.Id]; - timerState.Duration = TimeSpan.FromSeconds(timeoutInSeconds); - timerState.TimeStart = DateTime.Now; - timerState.Timer = new Timer(task => + _VoteTimers[party.Id] = _Server.TimerManager.CreateTimer(timeoutInSeconds, () => { - TimeSpan alreadyElapsed = DateTime.Now.Subtract(timerState.TimeStart); - if (alreadyElapsed > timerState.Duration) - { - Logger.Info($"(VoteToAbandon) Timer expired for PartyId={party.Id}"); - CancelVoteToAbandonTimer(party.Id); - } - }, null, 0, 1000); + Logger.Info($"(VoteToAbandon) Timer expired for PartyId={party.Id}"); + client.Party.SendToAll(new S2CQuestPlayInterruptAnswerNtc() { IsInterrupt = false }); + CancelVoteToAbandonTimer(party.Id); + }); + _Server.TimerManager.StartTimer(_VoteTimers[party.Id]); } Logger.Info($"(VoteToAbandon) Started {timeoutInSeconds} seconds timer for PartyId={party.Id}"); } + public void RemovePartyMember(uint partyId, uint characterId) + { + lock (_VoteStatus) + { + if (!_VoteStatus.ContainsKey(partyId)) + { + return; + } + + if (_VoteStatus[partyId].ContainsKey(characterId)) + { + _VoteStatus[partyId].Remove(characterId); + } + } + } + + public void RemovePartyMember(uint partyId, Character character) + { + RemovePartyMember(partyId, character.CharacterId); + } + public void CancelVoteToAbandonTimer(uint partyId) { lock (_VoteStatus) { - _VoteTimers[partyId].Timer.Dispose(); + _Server.TimerManager.CancelTimer(_VoteTimers[partyId]); _VoteStatus.Remove(partyId); _VoteTimers.Remove(partyId); Logger.Info($"(VoteToAbandon) Canceling timer for PartyId={partyId}"); } } - public void VoteToAbandon(uint characterId, uint partyId, bool shouldAbandon) + public void VoteToAbandon(uint characterId, uint partyId, VoteAnswer answer) { lock (_VoteStatus) { @@ -94,16 +102,16 @@ public void VoteToAbandon(uint characterId, uint partyId, bool shouldAbandon) return; } - _VoteStatus[partyId][characterId] = shouldAbandon; + _VoteStatus[partyId][characterId] = answer; } } - public void VoteToAbandon(Character character, uint partyId, bool shouldAbandon) + public void VoteToAbandon(Character character, uint partyId, VoteAnswer answer) { - VoteToAbandon(character.CharacterId, partyId, shouldAbandon); + VoteToAbandon(character.CharacterId, partyId, answer); } - public bool VoteToAbandonPassed(uint partyId) + public bool AllMembersVoted(uint partyId) { lock (_VoteStatus) { @@ -112,12 +120,30 @@ public bool VoteToAbandonPassed(uint partyId) return false; } - bool shouldAbandon = true; - foreach (var (characterId, result) in _VoteStatus[partyId]) + bool allMembersVoted = true; + foreach (var (characterId, answer) in _VoteStatus[partyId]) { - shouldAbandon &= result; + allMembersVoted &= answer != VoteAnswer.Undecided; } - return shouldAbandon; + return allMembersVoted; + } + } + + public bool VotedPassed(uint partyId) + { + lock (_VoteStatus) + { + if (!_VoteStatus.ContainsKey(partyId)) + { + return false; + } + + bool allMembersVoted = true; + foreach (var (characterId, answer) in _VoteStatus[partyId]) + { + allMembersVoted &= (answer == VoteAnswer.Agree); + } + return allMembersVoted; } } @@ -125,21 +151,13 @@ public void StartTimer(uint partyId, GameClient client, uint playtimeInSeconds) { lock (_ContentTimers) { - _ContentTimers[partyId] = new TimerState(); - - var timerState = _ContentTimers[partyId]; - timerState.Duration = TimeSpan.FromSeconds(playtimeInSeconds); - timerState.TimeStart = DateTime.Now; - timerState.Timer = new Timer(task => + _ContentTimers[partyId] = _Server.TimerManager.CreateTimer(playtimeInSeconds, () => { - TimeSpan alreadyElapsed = DateTime.Now.Subtract(timerState.TimeStart); - if (alreadyElapsed > timerState.Duration) - { - Logger.Info($"(Content) Timer expired for Id={partyId}"); - client.Party.SendToAll(new S2CQuestPlayTimeupNtc()); - CancelTimer(partyId); - } - }, null, 0, 1000); + Logger.Info($"(Content) Timer expired for Id={partyId}"); + client.Party.SendToAll(new S2CQuestPlayTimeupNtc()); + CancelTimer(partyId); + }); + _Server.TimerManager.StartTimer(_ContentTimers[partyId]); Logger.Info($"Starting {playtimeInSeconds} second timer for PartyId={partyId}"); } } @@ -149,8 +167,7 @@ public ulong ExtendTimer(uint partyId, uint amountInSeconds) lock (_ContentTimers) { Logger.Info($"(Content) Extending time by {amountInSeconds} seconds for PartyId={partyId}"); - _ContentTimers[partyId].Duration += TimeSpan.FromSeconds(amountInSeconds); - return (ulong) ((DateTimeOffset)(_ContentTimers[partyId].TimeStart + _ContentTimers[partyId].Duration)).ToUnixTimeSeconds(); + return _Server.TimerManager.ExtendTimer(_ContentTimers[partyId], amountInSeconds); } } @@ -161,12 +178,7 @@ public ulong ExtendTimer(uint partyId, uint amountInSeconds) if (_ContentTimers.ContainsKey(partyId)) { Logger.Info($"(Content) Canceling timer for PartyId={partyId}"); - _ContentTimers[partyId].Timer.Dispose(); - - var timerState = _ContentTimers[partyId]; - - TimeSpan elapsed = DateTime.Now.Subtract(timerState.TimeStart); - var results = (elapsed, timerState.Duration); + var results = _Server.TimerManager.CancelTimer(_ContentTimers[partyId]); _ContentTimers.Remove(partyId); return results; } diff --git a/Arrowgene.Ddon.GameServer/Characters/TimerManager.cs b/Arrowgene.Ddon.GameServer/Characters/TimerManager.cs new file mode 100644 index 000000000..5bd41dcd5 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Characters/TimerManager.cs @@ -0,0 +1,136 @@ +using Arrowgene.Ddon.GameServer.Utils; +using Arrowgene.Ddon.Server; +using Arrowgene.Logging; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Threading; + +namespace Arrowgene.Ddon.GameServer.Characters +{ + public class TimerManager + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(TimerManager)); + + private DdonGameServer _Server; + private Dictionary _Timers; + private UniqueIdPool _IdPool; + + public TimerManager(DdonGameServer server) + { + _Server = server; + _Timers = new Dictionary(); + _IdPool = new UniqueIdPool(1); + } + + internal class TimerState + { + public DateTime TimeStart { get; set; } + public TimeSpan Duration { get; set; } + public Timer Timer { get; set; } + public Action Action { get; set; } + public bool TimerStarted { get; set; } + } + + public uint CreateTimer(uint timeoutInSeconds, Action action) + { + uint timerId = _IdPool.GenerateId(); + lock (_Timers) + { + if (_Timers.ContainsKey(timerId)) + { + throw new Exception($"TimerId={timerId} already has state associated with it. Unable to allocate additional state."); + } + + _Timers[timerId] = new TimerState() + { + Action = action, + Duration = TimeSpan.FromSeconds(timeoutInSeconds) + }; + } + + return timerId; + } + + public bool StartTimer(uint timerId) + { + lock (_Timers) + { + if (!_Timers.ContainsKey(timerId)) + { + return false; + } + + var timerState = _Timers[timerId]; + if (timerState.TimerStarted) + { + return false; + } + + timerState.TimeStart = DateTime.Now; + timerState.Timer = new Timer(task => + { + TimeSpan alreadyElapsed = DateTime.Now.Subtract(timerState.TimeStart); + if (alreadyElapsed > timerState.Duration) + { + Logger.Info($"TimerId={timerId} expired."); + if (timerState.Action != null) + { + timerState.Action.Invoke(); + } + CancelTimer(timerId); + } + }, null, 0, 1000); + Logger.Info($"Starting {timerState.Duration.TotalSeconds} second timer for TimerId={timerId}"); + } + + return true; + } + + public ulong ExtendTimer(uint timerId, uint amountInSeconds) + { + lock (_Timers) + { + Logger.Info($"Extending timer by {amountInSeconds} seconds for TimerId={timerId}"); + _Timers[timerId].Duration += TimeSpan.FromSeconds(amountInSeconds); + return (ulong)((DateTimeOffset)(_Timers[timerId].TimeStart + _Timers[timerId].Duration)).ToUnixTimeSeconds(); + } + } + + public ulong GetTimeLeftInSeconds(uint timerId) + { + lock (_Timers) + { + if (!_Timers.ContainsKey(timerId)) + { + return 0; + } + + var timeLeft = (_Timers[timerId].Duration - (DateTime.Now.Subtract(_Timers[timerId].TimeStart))).TotalSeconds; + + return (ulong) ((timeLeft < 0) ? 0 : timeLeft); + } + } + + public (TimeSpan Elapsed, TimeSpan MaximumDuration) CancelTimer(uint timerId) + { + lock (_Timers) + { + if (_Timers.ContainsKey(timerId)) + { + Logger.Info($"Canceling timer for TimerId={timerId}"); + _Timers[timerId].Timer.Dispose(); + + var timerState = _Timers[timerId]; + + TimeSpan elapsed = DateTime.Now.Subtract(timerState.TimeStart); + var results = (elapsed, timerState.Duration); + _Timers.Remove(timerId); + _IdPool.ReclaimId(timerId); + return results; + } + } + return (TimeSpan.Zero, TimeSpan.Zero); + } + } +} diff --git a/Arrowgene.Ddon.GameServer/DdonGameServer.cs b/Arrowgene.Ddon.GameServer/DdonGameServer.cs index 2b96472a4..8b75504ca 100644 --- a/Arrowgene.Ddon.GameServer/DdonGameServer.cs +++ b/Arrowgene.Ddon.GameServer/DdonGameServer.cs @@ -76,8 +76,9 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi HubManager = new HubManager(this); GpCourseManager = new GpCourseManager(this); WeatherManager = new WeatherManager(this); - ContentManager = new PartyQuestContentManager(this); + PartyQuestContentManager = new PartyQuestContentManager(this); BoardManager = new BoardManager(this); + TimerManager = new TimerManager(this); // Orb Management is slightly complex and requires updating fields across multiple systems OrbUnlockManager = new OrbUnlockManager(database, WalletManager, JobManager, CharacterManager); @@ -108,8 +109,9 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi public GameRouter Router { get; } public GpCourseManager GpCourseManager { get; } public WeatherManager WeatherManager { get; } - public PartyQuestContentManager ContentManager { get; } + public PartyQuestContentManager PartyQuestContentManager { get; } public BoardManager BoardManager { get; } + public TimerManager TimerManager { get; } public ChatLogHandler ChatLogHandler { get; } @@ -514,6 +516,7 @@ private void LoadPacketHandler() AddHandler(new QuestGetPartyBonusListHandler(this)); AddHandler(new QuestGetMobHuntQuestListHandler(this)); AddHandler(new QuestPlayEntryHandler(this)); + AddHandler(new QuestPlayEntryCancelHandler(this)); AddHandler(new QuestPlayStartHandler(this)); AddHandler(new QuestPlayStartTimerHandler(this)); AddHandler(new QuestPlayEndHandler(this)); @@ -534,6 +537,8 @@ private void LoadPacketHandler() AddHandler(new EntryBoardEntryBoardItemEntryHandler(this)); AddHandler(new EntryBoardEntryBoardItemListHandler(this)); AddHandler(new EntryBoardEntryRecreateHandler(this)); + AddHandler(new EntryBoardItemKickHandler(this)); + AddHandler(new EntryBoardEntryBoardItemExtendTimeoutHandler(this)); AddHandler(new ServerGameTimeGetBaseinfoHandler(this)); AddHandler(new ServerGetGameSettingHandler(this)); diff --git a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemCreateHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemCreateHandler.cs index dcc785b3a..8212d60e0 100644 --- a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemCreateHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemCreateHandler.cs @@ -35,7 +35,7 @@ public override S2CEntryBoardEntryBoardItemCreateRes Handle(GameClient client, C } data.EntryItem.PartyLeaderCharacterId = data.PartyLeaderCharacterId; - data.EntryItem.TimeOut = 3600; // TODO: Start a timer for 3600 + data.EntryItem.TimeOut = BoardManager.PARTY_BOARD_TIMEOUT; var member = new CDataEntryMemberData() { @@ -61,6 +61,7 @@ public override S2CEntryBoardEntryBoardItemCreateRes Handle(GameClient client, C }; client.Send(ntc); + Server.BoardManager.StartRecruitmentTimer(data.EntryItem.Id, BoardManager.PARTY_BOARD_TIMEOUT); Server.CharacterManager.UpdateOnlineStatus(client, client.Character, OnlineStatus.EntryBoard); return new S2CEntryBoardEntryBoardItemCreateRes() @@ -69,5 +70,5 @@ public override S2CEntryBoardEntryBoardItemCreateRes Handle(GameClient client, C EntryItem = data.EntryItem }; } - } + } } diff --git a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemEntryHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemEntryHandler.cs index 2217ddc18..5e503bb85 100644 --- a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemEntryHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemEntryHandler.cs @@ -65,6 +65,8 @@ public override S2CEntryBoardEntryBoardItemEntryRes Handle(GameClient client, C2 Server.CharacterManager.UpdateOnlineStatus(client, client.Character, OnlineStatus.EntryBoard); + data.EntryItem.TimeOut = (ushort)Server.BoardManager.GetRecruitmentTimeLeft(data.EntryItem.Id); + return new S2CEntryBoardEntryBoardItemEntryRes() { EntryItem = data.EntryItem diff --git a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs new file mode 100644 index 000000000..6455734a9 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs @@ -0,0 +1,47 @@ +using Arrowgene.Ddon.GameServer.Characters; +using Arrowgene.Ddon.Server; +using Arrowgene.Ddon.Shared.Entity.PacketStructure; +using Arrowgene.Ddon.Shared.Model; +using Arrowgene.Logging; + +namespace Arrowgene.Ddon.GameServer.Handler +{ + public class EntryBoardEntryBoardItemExtendTimeoutHandler : GameRequestPacketHandler + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(EntryBoardEntryBoardItemExtendTimeoutHandler)); + + public EntryBoardEntryBoardItemExtendTimeoutHandler(DdonGameServer server) : base(server) + { + } + + public override S2CEntryBoardEntryBoardExtendTimeoutRes Handle(GameClient client, C2SEntryBoardEntryBoardExtendTimeoutReq request) + { + // var pcap = new S2CEntryBoardEntryBoardItemForceStartRes.Serializer().Read(GameFull.Dump_711.AsBuffer()); + var data = Server.BoardManager.GetGroupDataForCharacter(client.Character); + + if (!Server.BoardManager.ExtendReadyUpTimer(data.EntryItem.Id)) + { + return new S2CEntryBoardEntryBoardExtendTimeoutRes() + { + Error = (uint) ErrorCode.ERROR_CODE_TIMER_INTERNAL_ERROR + }; + } + + foreach (var characterId in data.Members) + { + var memberClient = Server.ClientLookup.GetClientByCharacterId(characterId); + memberClient.Send(new S2CEntryBoardEntryBoardItemReadyNtc() + { + MaxMember = data.EntryItem.Param.MaxEntryNum, + TimeOut = Server.BoardManager.GetTimeLeftToReadyUp(data.EntryItem.Id), + }); + memberClient.Send(new S2CEntryBoardItemTimeoutTimerNtc() { TimeOut = Server.BoardManager.GetTimeLeftToReadyUp(data.EntryItem.Id) }); + } + + return new S2CEntryBoardEntryBoardExtendTimeoutRes() + { + TimeOut = Server.BoardManager.GetTimeLeftToReadyUp(data.EntryItem.Id) + }; + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemForceStartHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemForceStartHandler.cs index 07af9686a..7426dc4c3 100644 --- a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemForceStartHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemForceStartHandler.cs @@ -1,4 +1,5 @@ using Arrowgene.Buffers; +using Arrowgene.Ddon.GameServer.Characters; using Arrowgene.Ddon.GameServer.Dump; using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Server.Network; @@ -6,6 +7,7 @@ using Arrowgene.Ddon.Shared.Network; using Arrowgene.Logging; using Arrowgene.Networking.Tcp.Consumer.BlockingQueueConsumption; +using System.Threading; namespace Arrowgene.Ddon.GameServer.Handler { @@ -23,6 +25,7 @@ public override S2CEntryBoardEntryBoardItemForceStartRes Handle(GameClient clien var data = Server.BoardManager.GetGroupDataForCharacter(client.Character); + Server.BoardManager.CancelRecruitmentTimer(data.EntryItem.Id); foreach (var characterId in data.Members) { var memberClient = Server.ClientLookup.GetClientByCharacterId(characterId); @@ -30,12 +33,13 @@ public override S2CEntryBoardEntryBoardItemForceStartRes Handle(GameClient clien var ntc = new S2CEntryBoardEntryBoardItemReadyNtc() { MaxMember = data.EntryItem.Param.MaxEntryNum, - TimeOut = 120 + TimeOut = BoardManager.ENTRY_BOARD_READY_TIMEOUT, }; memberClient.Send(ntc); + memberClient.Send(new S2CEntryBoardItemTimeoutTimerNtc() {TimeOut = BoardManager.ENTRY_BOARD_READY_TIMEOUT }); } - // TODO: Start a timer for 120 seconds + Server.BoardManager.StartReadyUpTimer(data.EntryItem.Id, BoardManager.ENTRY_BOARD_READY_TIMEOUT); return new S2CEntryBoardEntryBoardItemForceStartRes(); } diff --git a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemReadyHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemReadyHandler.cs index 4ce76bcd2..288360248 100644 --- a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemReadyHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemReadyHandler.cs @@ -37,6 +37,8 @@ public override void Handle(GameClient client, StructurePacket + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(EntryBoardItemKickHandler)); + + public EntryBoardItemKickHandler(DdonGameServer server) : base(server) + { + } + + public override S2CEntryBoardItemKickRes Handle(GameClient client, C2SEntryBoardItemKickReq request) + { + var data = Server.BoardManager.RecreateGroup(client.Character); + + var kickedMemberClient = Server.ClientLookup.GetClientByCharacterId(request.CharacterId); + + CDataEntryMemberData memberData; + lock (data) + { + memberData = data.EntryItem.EntryMemberList.Where(x => x.CharacterListElement.CommunityCharacterBaseInfo.CharacterId == kickedMemberClient.Character.CharacterId).First(); + memberData.EntryFlag = false; + memberData.CharacterListElement = new CDataCharacterListElement(); + } + + S2CEntryBoardEntryBoardItemChangeMemberNtc ntc = new S2CEntryBoardEntryBoardItemChangeMemberNtc() + { + EntryFlag = false, + MemberData = memberData, + }; + + foreach (var characterId in data.Members) + { + var memberClient = Server.ClientLookup.GetClientByCharacterId(characterId); + if (memberClient != null) + { + memberClient.Send(ntc); + } + } + + kickedMemberClient.Send(new S2CEntryBoardEntryBoardItemLeaveNtc()); + + Server.BoardManager.RemoveCharacterFromGroup(kickedMemberClient.Character); + Server.CharacterManager.UpdateOnlineStatus(kickedMemberClient, kickedMemberClient.Character, OnlineStatus.Online); + + return new S2CEntryBoardItemKickRes(); + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/PartyPartyLeaveHandler.cs b/Arrowgene.Ddon.GameServer/Handler/PartyPartyLeaveHandler.cs index e5501a6c5..7388993bf 100644 --- a/Arrowgene.Ddon.GameServer/Handler/PartyPartyLeaveHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/PartyPartyLeaveHandler.cs @@ -35,6 +35,7 @@ public override void Handle(GameClient client, StructurePacket + { + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(QuestPlayEntryCancelHandler)); + + public QuestPlayEntryCancelHandler(DdonGameServer server) : base(server) + { + } + + public override S2CQuestPlayEntryCancelRes Handle(GameClient client, C2SQuestPlayEntryCancelReq request) + { + var ntc = new S2CQuestPlayEntryCancelNtc() + { + CharacterId = client.Character.CharacterId + }; + client.Party.SendToAll(ntc); + + return new S2CQuestPlayEntryCancelRes(); + } + } +} diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptAnswerHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptAnswerHandler.cs index 33397ea5f..2e0c1af53 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptAnswerHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptAnswerHandler.cs @@ -1,19 +1,7 @@ -using Arrowgene.Buffers; -using Arrowgene.Ddon.GameServer.Characters; -using Arrowgene.Ddon.GameServer.Dump; -using Arrowgene.Ddon.GameServer.Quests; using Arrowgene.Ddon.Server; -using Arrowgene.Ddon.Server.Network; -using Arrowgene.Ddon.Shared.Asset; -using Arrowgene.Ddon.Shared.Entity; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Ddon.Shared.Entity.Structure; using Arrowgene.Ddon.Shared.Model; -using Arrowgene.Ddon.Shared.Network; using Arrowgene.Logging; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; namespace Arrowgene.Ddon.GameServer.Handler { @@ -27,17 +15,20 @@ public QuestPlayInterruptAnswerHandler(DdonGameServer server) : base(server) public override S2CQuestPlayInterruptAnswerRes Handle(GameClient client, C2SQuestPlayInterruptAnswerReq packet) { - Server.ContentManager.VoteToAbandon(client.Character, client.Party.Id, packet.IsAnswer); - if (Server.ContentManager.VoteToAbandonPassed(client.Party.Id)) + Server.PartyQuestContentManager.VoteToAbandon(client.Character, client.Party.Id, packet.IsAnswer ? VoteAnswer.Agree : VoteAnswer.Disagree); + if (Server.PartyQuestContentManager.AllMembersVoted(client.Party.Id)) { - Server.ContentManager.CancelVoteToAbandonTimer(client.Party.Id); - - // TODO: There is supposed to be an NTC which - // reports the response of the cancel operation - // but I can't find it. This packet will give similar results - // which basically allows the party to quit. - Server.ContentManager.CancelTimer(client.Party.Id); - client.Party.SendToAll(new S2CQuestPlayTimeupNtc()); + if (Server.PartyQuestContentManager.VotedPassed(client.Party.Id)) + { + Server.PartyQuestContentManager.CancelVoteToAbandonTimer(client.Party.Id); + Server.PartyQuestContentManager.CancelTimer(client.Party.Id); + client.Party.SendToAll(new S2CQuestPlayInterruptAnswerNtc() { IsInterrupt = true }); + } + else + { + Server.PartyQuestContentManager.CancelVoteToAbandonTimer(client.Party.Id); + client.Party.SendToAll(new S2CQuestPlayInterruptAnswerNtc() { IsInterrupt = false }); + } } return new S2CQuestPlayInterruptAnswerRes(); diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptHandler.cs index 1c6d740f3..d9b14969f 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestPlayInterruptHandler.cs @@ -1,7 +1,6 @@ using Arrowgene.Ddon.Server; -using Arrowgene.Ddon.Server.Network; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Ddon.Shared.Network; +using Arrowgene.Ddon.Shared.Model; using Arrowgene.Logging; namespace Arrowgene.Ddon.GameServer.Handler @@ -18,14 +17,18 @@ public override S2CQuestPlayInterruptRes Handle(GameClient client, C2SQuestPlayI { if (client.Party.Clients.Count > 1) { - Server.ContentManager.InitatePartyAbandonVote(client.Party, 60); - Server.ContentManager.VoteToAbandon(client.Character, client.Party.Id, true); + Server.PartyQuestContentManager.InitatePartyAbandonVote(client, client.Party, 60); + Server.PartyQuestContentManager.VoteToAbandon(client.Character, client.Party.Id, VoteAnswer.Agree); + client.Party.SendToAllExcept(new S2CQuestPlayInterruptNtc() + { + CharacterId = client.Character.CharacterId, + DeadlineSec = 60 + }, client); } - - client.Party.SendToAll(new S2CQuestPlayInterruptNtc() + else { - DeadlineSec = 60 - }); + client.Party.SendToAll(new S2CQuestPlayInterruptAnswerNtc() { IsInterrupt = true }); + } return new S2CQuestPlayInterruptRes() { diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestPlayStartTimerHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestPlayStartTimerHandler.cs index 75e1e6320..e20ba9a70 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestPlayStartTimerHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestPlayStartTimerHandler.cs @@ -32,7 +32,7 @@ public override S2CQuestPlayStartTimerRes Handle(GameClient client, C2SQuestPlay }; client.Party.SendToAll(ntc); - Server.ContentManager.StartTimer(client.Party.Id, client, quest.MissionParams.PlaytimeInSeconds); + Server.PartyQuestContentManager.StartTimer(client.Party.Id, client, quest.MissionParams.PlaytimeInSeconds); return new S2CQuestPlayStartTimerRes(); } diff --git a/Arrowgene.Ddon.GameServer/Quests/GenericQuest.cs b/Arrowgene.Ddon.GameServer/Quests/GenericQuest.cs index 0eaa04270..bcb8cf81d 100644 --- a/Arrowgene.Ddon.GameServer/Quests/GenericQuest.cs +++ b/Arrowgene.Ddon.GameServer/Quests/GenericQuest.cs @@ -196,7 +196,7 @@ public override List StateMachineExecute(DdonGameServer if (questBlock.BlockType == QuestBlockType.ExtendTime && client.Party.ContentId != 0) { - var newEndTime = server.ContentManager.ExtendTimer(client.Party.Id, questBlock.TimeAmount); + var newEndTime = server.PartyQuestContentManager.ExtendTimer(client.Party.Id, questBlock.TimeAmount); client.Party.SendToAll(new S2CQuestPlayAddTimerNtc() { PlayEndDateTime = newEndTime }); } diff --git a/Arrowgene.Ddon.GameServer/Utils/UniqueIdPool.cs b/Arrowgene.Ddon.GameServer/Utils/UniqueIdPool.cs new file mode 100644 index 000000000..0c28bb676 --- /dev/null +++ b/Arrowgene.Ddon.GameServer/Utils/UniqueIdPool.cs @@ -0,0 +1,44 @@ +using Arrowgene.Ddon.Server; +using Arrowgene.Logging; +using System.Collections.Generic; + +namespace Arrowgene.Ddon.GameServer.Utils +{ + // If using dotnet 7+ we can use instead: + // where T : IBinaryInteger so the pool can be all numeric types + public class UniqueIdPool + { + private uint Counter; + private Stack FreeIdStack; + + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(UniqueIdPool)); + + public UniqueIdPool(uint defaultValue = 1) + { + Counter = defaultValue; + FreeIdStack = new Stack(); + FreeIdStack.Push(Counter); + } + + public uint GenerateId() + { + lock (FreeIdStack) + { + if (FreeIdStack.Count == 0) + { + Counter = Counter + 1; + FreeIdStack.Push(Counter); + } + return FreeIdStack.Pop(); + } + } + + public void ReclaimId(uint id) + { + lock (FreeIdStack) + { + FreeIdStack.Push(id); + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs index a17c8dc0b..cb18d4761 100644 --- a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs +++ b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs @@ -485,6 +485,8 @@ static EntitySerializer() Create(new C2SEntryBoardEntryBoardItemEntryReq.Serializer()); Create(new C2SEntryBoardEntryBoardItemListReq.Serializer()); Create(new C2SEntryBoardEntryBoardItemRecreateReq.Serializer()); + Create(new C2SEntryBoardItemKickReq.Serializer()); + Create(new C2SEntryBoardEntryBoardExtendTimeoutReq.Serializer()); Create(new C2SAchievementReceivableRewardNtc.Serializer()); Create(new C2SAchievementCompleteNtc.Serializer()); @@ -656,6 +658,7 @@ static EntitySerializer() Create(new C2SQuestPlayInterruptReq.Serializer()); Create(new C2SQuestGetQuestScheduleInfoReq.Serializer()); Create(new C2SQuestPlayInterruptAnswerReq.Serializer()); + Create(new C2SQuestPlayEntryCancelReq.Serializer()); Create(new C2SServerGameTimeGetBaseInfoReq.Serializer()); Create(new C2SServerGetRealTimeReq.Serializer()); @@ -892,6 +895,11 @@ static EntitySerializer() Create(new S2CEntryBoardEntryBoardItemListRes.Serializer()); Create(new S2CEntryBoardEntryBoardItemRecreateRes.Serializer()); Create(new S2CEntryBoardEntryBoardItemRecreateNtc.Serializer()); + Create(new S2CEntryBoardItemUnreadyNtc.Serializer()); + Create(new S2CEntryBoardItemTimeoutTimerNtc.Serializer()); + Create(new S2CEntryBoardItemPartyNtc.Serializer()); + Create(new S2CEntryBoardItemKickRes.Serializer()); + Create(new S2CEntryBoardEntryBoardExtendTimeoutRes.Serializer()); Create(new S2CEquipChangeCharacterEquipJobItemNtc.Serializer()); Create(new S2CEquipChangeCharacterEquipJobItemRes.Serializer()); @@ -1145,6 +1153,7 @@ static EntitySerializer() Create(new S2CQuestPlayInterruptNtc.Serializer()); Create(new S2CQuestPlayTimeupNtc.Serializer()); Create(new S2CQuestPlayAddTimerNtc.Serializer()); + Create(new S2CQuestPlayEntryCancelRes.Serializer()); Create(new S2CQuestPlayEntryCancelNtc.Serializer()); Create(new S2CQuestPlayInterruptAnswerRes.Serializer()); Create(new S2CQuestPlayInterruptAnswerNtc.Serializer()); diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs new file mode 100644 index 000000000..32f51b1fa --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SEntryBoardEntryBoardExtendTimeoutReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_ENTRY_BOARD_ENTRY_BOARD_ITEM_EXTEND_TIMEOUT_REQ; + + public C2SEntryBoardEntryBoardExtendTimeoutReq() + { + } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SEntryBoardEntryBoardExtendTimeoutReq obj) + { + } + + public override C2SEntryBoardEntryBoardExtendTimeoutReq Read(IBuffer buffer) + { + C2SEntryBoardEntryBoardExtendTimeoutReq obj = new C2SEntryBoardEntryBoardExtendTimeoutReq(); + return obj; + } + } + } +} + diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardItemKickReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardItemKickReq.cs new file mode 100644 index 000000000..65bb27b95 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardItemKickReq.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SEntryBoardItemKickReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_ENTRY_BOARD_ITEM_KICK_REQ; + + public C2SEntryBoardItemKickReq() + { + } + + public uint CharacterId { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SEntryBoardItemKickReq obj) + { + WriteUInt32(buffer, obj.CharacterId); + } + + public override C2SEntryBoardItemKickReq Read(IBuffer buffer) + { + C2SEntryBoardItemKickReq obj = new C2SEntryBoardItemKickReq(); + obj.CharacterId = ReadUInt32(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestPlayEntryCancelReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestPlayEntryCancelReq.cs new file mode 100644 index 000000000..8b257d6ab --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SQuestPlayEntryCancelReq.cs @@ -0,0 +1,24 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; +using System; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class C2SQuestPlayEntryCancelReq : IPacketStructure + { + public PacketId Id => PacketId.C2S_QUEST_PLAY_ENTRY_CANCEL_REQ; + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, C2SQuestPlayEntryCancelReq obj) + { + } + + public override C2SQuestPlayEntryCancelReq Read(IBuffer buffer) + { + C2SQuestPlayEntryCancelReq obj = new C2SQuestPlayEntryCancelReq(); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs new file mode 100644 index 000000000..d79803822 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs @@ -0,0 +1,36 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; +using System.Collections.Generic; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEntryBoardEntryBoardExtendTimeoutRes : ServerResponse + { + public override PacketId Id => PacketId.S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_EXTEND_TIMEOUT_RES; + + public S2CEntryBoardEntryBoardExtendTimeoutRes() + { + } + + public ushort TimeOut { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEntryBoardEntryBoardExtendTimeoutRes obj) + { + WriteServerResponse(buffer, obj); + WriteUInt16(buffer, obj.TimeOut); + } + + public override S2CEntryBoardEntryBoardExtendTimeoutRes Read(IBuffer buffer) + { + S2CEntryBoardEntryBoardExtendTimeoutRes obj = new S2CEntryBoardEntryBoardExtendTimeoutRes(); + ReadServerResponse(buffer, obj); + obj.TimeOut = ReadUInt16(buffer); + return obj; + } + } + } +} + diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemLeaveNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemLeaveNtc.cs index db7b2c244..d4ef3415f 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemLeaveNtc.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemLeaveNtc.cs @@ -14,19 +14,19 @@ public S2CEntryBoardEntryBoardItemLeaveNtc() { } - public uint LeaveType { get; set; } + public EntryBoardLeaveType LeaveType { get; set; } public class Serializer : PacketEntitySerializer { public override void Write(IBuffer buffer, S2CEntryBoardEntryBoardItemLeaveNtc obj) { - WriteUInt32(buffer, obj.LeaveType); + WriteUInt32(buffer, (uint) obj.LeaveType); } public override S2CEntryBoardEntryBoardItemLeaveNtc Read(IBuffer buffer) { S2CEntryBoardEntryBoardItemLeaveNtc obj = new S2CEntryBoardEntryBoardItemLeaveNtc(); - obj.LeaveType = ReadUInt32(buffer); + obj.LeaveType = (EntryBoardLeaveType) ReadUInt32(buffer); return obj; } } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemKickRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemKickRes.cs new file mode 100644 index 000000000..75480e515 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemKickRes.cs @@ -0,0 +1,31 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Entity.Structure; +using Arrowgene.Ddon.Shared.Network; +using System.Collections.Generic; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEntryBoardItemKickRes : ServerResponse + { + public override PacketId Id => PacketId.S2C_ENTRY_BOARD_ITEM_KICK_RES; + + public S2CEntryBoardItemKickRes() + { + } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEntryBoardItemKickRes obj) + { + WriteServerResponse(buffer, obj); + } + + public override S2CEntryBoardItemKickRes Read(IBuffer buffer) + { + S2CEntryBoardItemKickRes obj = new S2CEntryBoardItemKickRes(); + ReadServerResponse(buffer, obj); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemPartyNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemPartyNtc.cs new file mode 100644 index 000000000..0801fd068 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemPartyNtc.cs @@ -0,0 +1,27 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEntryBoardItemPartyNtc : IPacketStructure + { + public PacketId Id => PacketId.S2C_ENTRY_BOARD_ITEM_PARTY_NTC; + + public S2CEntryBoardItemPartyNtc() + { + } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEntryBoardItemPartyNtc obj) + { + } + + public override S2CEntryBoardItemPartyNtc Read(IBuffer buffer) + { + S2CEntryBoardItemPartyNtc obj = new S2CEntryBoardItemPartyNtc(); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemTimeoutTimerNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemTimeoutTimerNtc.cs new file mode 100644 index 000000000..a67119a9d --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemTimeoutTimerNtc.cs @@ -0,0 +1,31 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEntryBoardItemTimeoutTimerNtc : IPacketStructure + { + public PacketId Id => PacketId.S2C_ENTRY_BOARD_ITEM_TIMEOUT_TIMER_NTC; + + public S2CEntryBoardItemTimeoutTimerNtc() + { + } + + public ushort TimeOut { get; set; } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEntryBoardItemTimeoutTimerNtc obj) + { + WriteUInt16(buffer, obj.TimeOut); + } + + public override S2CEntryBoardItemTimeoutTimerNtc Read(IBuffer buffer) + { + S2CEntryBoardItemTimeoutTimerNtc obj = new S2CEntryBoardItemTimeoutTimerNtc(); + obj.TimeOut = ReadUInt16(buffer); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemUnreadyNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemUnreadyNtc.cs new file mode 100644 index 000000000..22369a31f --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardItemUnreadyNtc.cs @@ -0,0 +1,27 @@ +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CEntryBoardItemUnreadyNtc : IPacketStructure + { + public PacketId Id => PacketId.S2C_ENTRY_BOARD_ITEM_UNREADY_NTC; + + public S2CEntryBoardItemUnreadyNtc() + { + } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CEntryBoardItemUnreadyNtc obj) + { + } + + public override S2CEntryBoardItemUnreadyNtc Read(IBuffer buffer) + { + S2CEntryBoardItemUnreadyNtc obj = new S2CEntryBoardItemUnreadyNtc(); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayEntryCancelRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayEntryCancelRes.cs new file mode 100644 index 000000000..0b0a87043 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayEntryCancelRes.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using Arrowgene.Buffers; +using Arrowgene.Ddon.Shared.Network; + +namespace Arrowgene.Ddon.Shared.Entity.PacketStructure +{ + public class S2CQuestPlayEntryCancelRes : ServerResponse + { + public override PacketId Id => PacketId.S2C_QUEST_PLAY_ENTRY_CANCEL_RES; + + public S2CQuestPlayEntryCancelRes() + { + } + + public class Serializer : PacketEntitySerializer + { + public override void Write(IBuffer buffer, S2CQuestPlayEntryCancelRes obj) + { + WriteServerResponse(buffer, obj); + } + + public override S2CQuestPlayEntryCancelRes Read(IBuffer buffer) + { + S2CQuestPlayEntryCancelRes obj = new S2CQuestPlayEntryCancelRes(); + ReadServerResponse(buffer, obj); + return obj; + } + } + } +} diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayInterruptAnswerNtc.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayInterruptAnswerNtc.cs index e0f38fa3a..d0b89204f 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayInterruptAnswerNtc.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CQuestPlayInterruptAnswerNtc.cs @@ -7,7 +7,7 @@ namespace Arrowgene.Ddon.Shared.Entity.PacketStructure { public class S2CQuestPlayInterruptAnswerNtc : IPacketStructure { - public PacketId Id => PacketId.S2C_QUEST_11_86_16_NTC; // EMPTY ID + public PacketId Id => PacketId.S2C_QUEST_PLAY_INTERRUPT_RESULT_NTC; public S2CQuestPlayInterruptAnswerNtc() { diff --git a/Arrowgene.Ddon.Shared/Model/EntryBoardLeaveType.cs b/Arrowgene.Ddon.Shared/Model/EntryBoardLeaveType.cs new file mode 100644 index 000000000..0d1ade397 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Model/EntryBoardLeaveType.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Arrowgene.Ddon.Shared.Model +{ + public enum EntryBoardLeaveType : uint + { + EntryBoardRemoved = 0, + EntryBoardDisolved = 1, + EntryBoardTimeUp = 2, + EntryBoardReadyTimeUp = 3, + MemberReadyTimeup = 4, + EntryBoardAlarm = 5, + } +} diff --git a/Arrowgene.Ddon.Shared/Model/VoteAnswer.cs b/Arrowgene.Ddon.Shared/Model/VoteAnswer.cs new file mode 100644 index 000000000..5bb2d5564 --- /dev/null +++ b/Arrowgene.Ddon.Shared/Model/VoteAnswer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Arrowgene.Ddon.Shared.Model +{ + public enum VoteAnswer + { + Undecided, + Agree, + Disagree + } +} diff --git a/Arrowgene.Ddon.Shared/Network/PacketId.cs b/Arrowgene.Ddon.Shared/Network/PacketId.cs index b00861008..65bce0847 100644 --- a/Arrowgene.Ddon.Shared/Network/PacketId.cs +++ b/Arrowgene.Ddon.Shared/Network/PacketId.cs @@ -1,4 +1,3 @@ -using Arrowgene.Ddon.Shared.Entity.PacketStructure; using System; using System.Collections.Generic; @@ -662,8 +661,8 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId C2S_QUEST_PLAY_ENTRY_REQ = new PacketId(11, 39, 1, "C2S_QUEST_PLAY_ENTRY_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_QUEST_PLAY_ENTRY_RES = new PacketId(11, 39, 2, "S2C_QUEST_PLAY_ENTRY_RES", ServerType.Game, PacketSource.Server); // プレイエントリーに public static readonly PacketId S2C_QUEST_PLAY_ENTRY_NTC = new PacketId(11, 39, 16, "S2C_QUEST_PLAY_ENTRY_NTC", ServerType.Game, PacketSource.Server, "S2C_QUEST_11_39_16_NTC"); - public static readonly PacketId C2S_QUEST_11_40_1_REQ = new PacketId(11, 40, 1, "C2S_QUEST_11_40_1_REQ", ServerType.Game, PacketSource.Client); // PLAY_ENTRY_CANCEL? - public static readonly PacketId S2C_QUEST_11_40_2_RES = new PacketId(11, 40, 2, "S2C_QUEST_11_40_2_RES", ServerType.Game, PacketSource.Server); + public static readonly PacketId C2S_QUEST_PLAY_ENTRY_CANCEL_REQ = new PacketId(11, 40, 1, "C2S_QUEST_PLAY_ENTRY_CANCEL_REQ", ServerType.Game, PacketSource.Client, "C2S_QUEST_11_40_1_REQ"); + public static readonly PacketId S2C_QUEST_PLAY_ENTRY_CANCEL_RES = new PacketId(11, 40, 2, "S2C_QUEST_PLAY_ENTRY_CANCEL_RES", ServerType.Game, PacketSource.Server, "S2C_QUEST_11_40_2_RES"); public static readonly PacketId S2C_QUEST_PLAY_ENTRY_CANCEL_NTC = new PacketId(11, 40, 16, "S2C_QUEST_PLAY_ENTRY_CANCEL_NTC", ServerType.Game, PacketSource.Server, "S2C_QUEST_11_40_16_NTC"); public static readonly PacketId C2S_QUEST_PLAY_START_REQ = new PacketId(11, 41, 1, "C2S_QUEST_PLAY_START_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_QUEST_PLAY_START_RES = new PacketId(11, 41, 2, "S2C_QUEST_PLAY_START_RES", ServerType.Game, PacketSource.Server); // プレイスタートに @@ -750,12 +749,12 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId S2C_QUEST_11_79_2_RES = new PacketId(11, 79, 2, "S2C_QUEST_11_79_2_RES", ServerType.Game, PacketSource.Server); public static readonly PacketId C2S_QUEST_DEBUG_ENEMY_SET_PRESET_FIX_REQ = new PacketId(11, 80, 1, "C2S_QUEST_DEBUG_ENEMY_SET_PRESET_FIX_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_QUEST_DEBUG_ENEMY_SET_PRESET_FIX_RES = new PacketId(11, 80, 2, "S2C_QUEST_DEBUG_ENEMY_SET_PRESET_FIX_RES", ServerType.Game, PacketSource.Server); // (デバッグ用)敵セットプリセット固定に - public static readonly PacketId S2C_QUEST_11_81_16_NTC = new PacketId(11, 81, 16, "S2C_QUEST_11_81_16_NTC", ServerType.Game, PacketSource.Server); + public static readonly PacketId S2C_QUEST_11_81_16_NTC = new PacketId(11, 81, 16, "S2C_QUEST_11_81_16_NTC", ServerType.Game, PacketSource.Server); // Doesn't seem to have a handler? public static readonly PacketId S2C_QUEST_11_82_16_NTC = new PacketId(11, 82, 16, "S2C_QUEST_11_82_16_NTC", ServerType.Game, PacketSource.Server); public static readonly PacketId S2C_QUEST_11_83_16_NTC = new PacketId(11, 83, 16, "S2C_QUEST_11_83_16_NTC", ServerType.Game, PacketSource.Server); public static readonly PacketId S2C_QUEST_11_84_16_NTC = new PacketId(11, 84, 16, "S2C_QUEST_11_84_16_NTC", ServerType.Game, PacketSource.Server); - public static readonly PacketId S2C_QUEST_11_85_16_NTC = new PacketId(11, 85, 16, "S2C_QUEST_11_85_16_NTC", ServerType.Game, PacketSource.Server); - public static readonly PacketId S2C_QUEST_11_86_16_NTC = new PacketId(11, 86, 16, "S2C_QUEST_11_86_16_NTC", ServerType.Game, PacketSource.Server); + public static readonly PacketId S2C_QUEST_11_85_16_NTC = new PacketId(11, 85, 16, "S2C_QUEST_11_85_16_NTC", ServerType.Game, PacketSource.Server); // S2C_QUEST_ENABLE_NOTICE? + public static readonly PacketId S2C_QUEST_11_86_16_NTC = new PacketId(11, 86, 16, "S2C_QUEST_11_86_16_NTC", ServerType.Game, PacketSource.Server); // S2C_CYCLE_CONTENTS_ENABLE_NOTICE? public static readonly PacketId S2C_QUEST_11_87_16_NTC = new PacketId(11, 87, 16, "S2C_QUEST_11_87_16_NTC", ServerType.Game, PacketSource.Server); // S2C_QUEST_MASTER_DATA_RELOAD_NOTICE public static readonly PacketId S2C_QUEST_11_88_16_NTC = new PacketId(11, 88, 16, "S2C_QUEST_11_88_16_NTC", ServerType.Game, PacketSource.Server); public static readonly PacketId S2C_QUEST_JOIN_LOBBY_QUEST_INFO_NTC = new PacketId(11, 89, 16, "S2C_QUEST_JOIN_LOBBY_QUEST_INFO_NTC", ServerType.Game, PacketSource.Server, "S2C_QUEST_11_89_16_NTC"); @@ -776,8 +775,8 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId S2C_QUEST_11_104_16_NTC = new PacketId(11, 104, 16, "S2C_QUEST_11_104_16_NTC", ServerType.Game, PacketSource.Server); public static readonly PacketId S2C_QUEST_PLAY_TIMEUP_NTC = new PacketId(11, 105, 16, "S2C_QUEST_PLAY_TIMEUP_NTC", ServerType.Game, PacketSource.Server, "S2C_QUEST_11_105_16_NTC"); // Time is up (S2C_PLAY_TIMEUP_NOTICE) public static readonly PacketId S2C_QUEST_11_106_16_NTC = new PacketId(11, 106, 16, "S2C_QUEST_11_106_16_NTC", ServerType.Game, PacketSource.Server); // - public static readonly PacketId S2C_QUEST_11_107_16_NTC = new PacketId(11, 107, 16, "S2C_QUEST_11_107_16_NTC", ServerType.Game, PacketSource.Server); // The request to end the mission was successful - public static readonly PacketId S2C_QUEST_11_108_16_NTC = new PacketId(11, 108, 16, "S2C_QUEST_11_108_16_NTC", ServerType.Game, PacketSource.Server); // The request to end the mission was successful + public static readonly PacketId S2C_QUEST_PLAY_INTERRUPT_RESULT_NTC = new PacketId(11, 107, 16, "S2C_QUEST_PLAY_INTERRUPT_RESULT_NTC", ServerType.Game, PacketSource.Server, "S2C_QUEST_11_107_16_NTC"); + public static readonly PacketId S2C_QUEST_11_108_16_NTC = new PacketId(11, 108, 16, "S2C_QUEST_11_108_16_NTC", ServerType.Game, PacketSource.Server); // The request to end the mission was successful (S2C_PLAY_FORCE_INTERRUPT_NOTICE?) public static readonly PacketId S2C_QUEST_11_109_16_NTC = new PacketId(11, 109, 16, "S2C_QUEST_11_109_16_NTC", ServerType.Game, PacketSource.Server); public static readonly PacketId S2C_QUEST_11_110_16_NTC = new PacketId(11, 110, 16, "S2C_QUEST_11_110_16_NTC", ServerType.Game, PacketSource.Server); // (S2C_FORT_DEFENSE_PLAY_START_NOTICE) public static readonly PacketId S2C_QUEST_11_111_16_NTC = new PacketId(11, 111, 16, "S2C_QUEST_11_111_16_NTC", ServerType.Game, PacketSource.Server); @@ -1584,10 +1583,10 @@ private static Dictionary InitializeLoginPacketIds() public static readonly PacketId S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_INVITE_RES = new PacketId(34, 13, 2, "S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_INVITE_RES", ServerType.Game, PacketSource.Server); // エントリーボード招待に public static readonly PacketId S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_INVITE_NTC = new PacketId(34, 13, 16, "S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_INVITE_NTC", ServerType.Game, PacketSource.Server, "S2C_ENTRY_34_13_16_NTC"); public static readonly PacketId S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_CHANGE_MEMBER_NTC = new PacketId(34, 14, 16, "S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_CHANGE_MEMBER_NTC", ServerType.Game, PacketSource.Server, "S2C_ENTRY_34_14_16_NTC"); - public static readonly PacketId S2C_ENTRY_34_15_16_NTC = new PacketId(34, 15, 16, "S2C_ENTRY_34_15_16_NTC", ServerType.Game, PacketSource.Server); + public static readonly PacketId S2C_ENTRY_BOARD_ITEM_UNREADY_NTC = new PacketId(34, 15, 16, "S2C_ENTRY_BOARD_ITEM_UNREADY_NTC", ServerType.Game, PacketSource.Server, "S2C_ENTRY_34_15_16_NTC"); public static readonly PacketId S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_RESERVE_NTC = new PacketId(34, 16, 16, "S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_RESERVE_NTC", ServerType.Game, PacketSource.Server, "S2C_ENTRY_34_16_16_NTC"); - public static readonly PacketId S2C_ENTRY_34_17_16_NTC = new PacketId(34, 17, 16, "S2C_ENTRY_34_17_16_NTC", ServerType.Game, PacketSource.Server); - public static readonly PacketId S2C_ENTRY_34_18_16_NTC = new PacketId(34, 18, 16, "S2C_ENTRY_34_18_16_NTC", ServerType.Game, PacketSource.Server); + public static readonly PacketId S2C_ENTRY_BOARD_ITEM_PARTY_NTC = new PacketId(34, 17, 16, "S2C_ENTRY_BOARD_ITEM_PARTY_NTC", ServerType.Game, PacketSource.Server, "S2C_ENTRY_34_17_16_NTC"); + public static readonly PacketId S2C_ENTRY_BOARD_ITEM_TIMEOUT_TIMER_NTC = new PacketId(34, 18, 16, "S2C_ENTRY_BOARD_ITEM_TIMEOUT_TIMER_NTC", ServerType.Game, PacketSource.Server, "S2C_ENTRY_34_18_16_NTC"); public static readonly PacketId C2S_ENTRY_BOARD_PARTY_RECRUIT_CATEGORY_LIST_REQ = new PacketId(34, 19, 1, "C2S_ENTRY_BOARD_PARTY_RECRUIT_CATEGORY_LIST_REQ", ServerType.Game, PacketSource.Client); public static readonly PacketId S2C_ENTRY_BOARD_PARTY_RECRUIT_CATEGORY_LIST_RES = new PacketId(34, 19, 2, "S2C_ENTRY_BOARD_PARTY_RECRUIT_CATEGORY_LIST_RES", ServerType.Game, PacketSource.Server); // パーティ募集掲示板リスト取得に public static readonly PacketId C2S_ENTRY_BOARD_ITEM_KICK_REQ = new PacketId(34, 20, 1, "C2S_ENTRY_BOARD_ITEM_KICK_REQ", ServerType.Game, PacketSource.Client); @@ -2591,8 +2590,8 @@ private static Dictionary InitializeGamePacketIds() AddPacketIdEntry(packetIds, C2S_QUEST_PLAY_ENTRY_REQ); AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_ENTRY_RES); AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_ENTRY_NTC); - AddPacketIdEntry(packetIds, C2S_QUEST_11_40_1_REQ); - AddPacketIdEntry(packetIds, S2C_QUEST_11_40_2_RES); + AddPacketIdEntry(packetIds, C2S_QUEST_PLAY_ENTRY_CANCEL_REQ); + AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_ENTRY_CANCEL_RES); AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_ENTRY_CANCEL_NTC); AddPacketIdEntry(packetIds, C2S_QUEST_PLAY_START_REQ); AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_START_RES); @@ -2705,7 +2704,7 @@ private static Dictionary InitializeGamePacketIds() AddPacketIdEntry(packetIds, S2C_QUEST_11_104_16_NTC); AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_TIMEUP_NTC); AddPacketIdEntry(packetIds, S2C_QUEST_11_106_16_NTC); - AddPacketIdEntry(packetIds, S2C_QUEST_11_107_16_NTC); + AddPacketIdEntry(packetIds, S2C_QUEST_PLAY_INTERRUPT_RESULT_NTC); AddPacketIdEntry(packetIds, S2C_QUEST_11_108_16_NTC); AddPacketIdEntry(packetIds, S2C_QUEST_11_109_16_NTC); AddPacketIdEntry(packetIds, S2C_QUEST_11_110_16_NTC); @@ -3513,10 +3512,10 @@ private static Dictionary InitializeGamePacketIds() AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_INVITE_RES); AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_INVITE_NTC); AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_CHANGE_MEMBER_NTC); - AddPacketIdEntry(packetIds, S2C_ENTRY_34_15_16_NTC); + AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ITEM_UNREADY_NTC); AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_RESERVE_NTC); - AddPacketIdEntry(packetIds, S2C_ENTRY_34_17_16_NTC); - AddPacketIdEntry(packetIds, S2C_ENTRY_34_18_16_NTC); + AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ITEM_PARTY_NTC); + AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_ITEM_TIMEOUT_TIMER_NTC); AddPacketIdEntry(packetIds, C2S_ENTRY_BOARD_PARTY_RECRUIT_CATEGORY_LIST_REQ); AddPacketIdEntry(packetIds, S2C_ENTRY_BOARD_PARTY_RECRUIT_CATEGORY_LIST_RES); AddPacketIdEntry(packetIds, C2S_ENTRY_BOARD_ITEM_KICK_REQ); From 9fa0493177c18f44329c2e018d78b270e7f1e717 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 17 Sep 2024 17:42:49 -0400 Subject: [PATCH 2/2] Code Review Feedback - Renamed packets missing "Item". - Replaced literals with constant. --- Arrowgene.Ddon.GameServer/Characters/BoardManager.cs | 6 +++--- .../EntryBoardEntryBoardItemExtendTimeoutHandler.cs | 8 ++++---- Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs | 4 ++-- ...> C2SEntryBoardEntryBoardItemExtendTimeoutReq.cs} | 12 ++++++------ ...> S2CEntryBoardEntryBoardItemExtendTimeoutRes.cs} | 12 ++++++------ 5 files changed, 21 insertions(+), 21 deletions(-) rename Arrowgene.Ddon.Shared/Entity/PacketStructure/{C2SEntryBoardEntryBoardExtendTimeoutReq.cs => C2SEntryBoardEntryBoardItemExtendTimeoutReq.cs} (56%) rename Arrowgene.Ddon.Shared/Entity/PacketStructure/{S2CEntryBoardEntryBoardExtendTimeoutRes.cs => S2CEntryBoardEntryBoardItemExtendTimeoutRes.cs} (65%) diff --git a/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs b/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs index 23d92514c..b86c5607f 100644 --- a/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/BoardManager.cs @@ -444,14 +444,14 @@ public bool StartReadyUpTimer(uint entryItemId, uint timeoutInSeconds) } // Restart the recruitment timer - data.EntryItem.TimeOut = 3600; - StartRecruitmentTimer(data.EntryItem.Id, 3600); + data.EntryItem.TimeOut = BoardManager.PARTY_BOARD_TIMEOUT; + StartRecruitmentTimer(data.EntryItem.Id, BoardManager.PARTY_BOARD_TIMEOUT); foreach (var characterId in data.Members) { var memberClient = _Server.ClientLookup.GetClientByCharacterId(characterId); if (memberClient != null) { - memberClient.Send(new S2CEntryBoardItemTimeoutTimerNtc() { TimeOut = 3600}); + memberClient.Send(new S2CEntryBoardItemTimeoutTimerNtc() { TimeOut = BoardManager.PARTY_BOARD_TIMEOUT }); } } } diff --git a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs index 6455734a9..3d0211442 100644 --- a/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/EntryBoardEntryBoardItemExtendTimeoutHandler.cs @@ -6,7 +6,7 @@ namespace Arrowgene.Ddon.GameServer.Handler { - public class EntryBoardEntryBoardItemExtendTimeoutHandler : GameRequestPacketHandler + public class EntryBoardEntryBoardItemExtendTimeoutHandler : GameRequestPacketHandler { private static readonly ServerLogger Logger = LogProvider.Logger(typeof(EntryBoardEntryBoardItemExtendTimeoutHandler)); @@ -14,14 +14,14 @@ public EntryBoardEntryBoardItemExtendTimeoutHandler(DdonGameServer server) : bas { } - public override S2CEntryBoardEntryBoardExtendTimeoutRes Handle(GameClient client, C2SEntryBoardEntryBoardExtendTimeoutReq request) + public override S2CEntryBoardEntryBoardItemExtendTimeoutRes Handle(GameClient client, C2SEntryBoardEntryBoardItemExtendTimeoutReq request) { // var pcap = new S2CEntryBoardEntryBoardItemForceStartRes.Serializer().Read(GameFull.Dump_711.AsBuffer()); var data = Server.BoardManager.GetGroupDataForCharacter(client.Character); if (!Server.BoardManager.ExtendReadyUpTimer(data.EntryItem.Id)) { - return new S2CEntryBoardEntryBoardExtendTimeoutRes() + return new S2CEntryBoardEntryBoardItemExtendTimeoutRes() { Error = (uint) ErrorCode.ERROR_CODE_TIMER_INTERNAL_ERROR }; @@ -38,7 +38,7 @@ public override S2CEntryBoardEntryBoardExtendTimeoutRes Handle(GameClient client memberClient.Send(new S2CEntryBoardItemTimeoutTimerNtc() { TimeOut = Server.BoardManager.GetTimeLeftToReadyUp(data.EntryItem.Id) }); } - return new S2CEntryBoardEntryBoardExtendTimeoutRes() + return new S2CEntryBoardEntryBoardItemExtendTimeoutRes() { TimeOut = Server.BoardManager.GetTimeLeftToReadyUp(data.EntryItem.Id) }; diff --git a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs index cb18d4761..a9834d7cd 100644 --- a/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs +++ b/Arrowgene.Ddon.Shared/Entity/EntitySerializer.cs @@ -486,7 +486,7 @@ static EntitySerializer() Create(new C2SEntryBoardEntryBoardItemListReq.Serializer()); Create(new C2SEntryBoardEntryBoardItemRecreateReq.Serializer()); Create(new C2SEntryBoardItemKickReq.Serializer()); - Create(new C2SEntryBoardEntryBoardExtendTimeoutReq.Serializer()); + Create(new C2SEntryBoardEntryBoardItemExtendTimeoutReq.Serializer()); Create(new C2SAchievementReceivableRewardNtc.Serializer()); Create(new C2SAchievementCompleteNtc.Serializer()); @@ -899,7 +899,7 @@ static EntitySerializer() Create(new S2CEntryBoardItemTimeoutTimerNtc.Serializer()); Create(new S2CEntryBoardItemPartyNtc.Serializer()); Create(new S2CEntryBoardItemKickRes.Serializer()); - Create(new S2CEntryBoardEntryBoardExtendTimeoutRes.Serializer()); + Create(new S2CEntryBoardEntryBoardItemExtendTimeoutRes.Serializer()); Create(new S2CEquipChangeCharacterEquipJobItemNtc.Serializer()); Create(new S2CEquipChangeCharacterEquipJobItemRes.Serializer()); diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardItemExtendTimeoutReq.cs similarity index 56% rename from Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs rename to Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardItemExtendTimeoutReq.cs index 32f51b1fa..79fed2320 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardExtendTimeoutReq.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/C2SEntryBoardEntryBoardItemExtendTimeoutReq.cs @@ -5,23 +5,23 @@ namespace Arrowgene.Ddon.Shared.Entity.PacketStructure { - public class C2SEntryBoardEntryBoardExtendTimeoutReq : IPacketStructure + public class C2SEntryBoardEntryBoardItemExtendTimeoutReq : IPacketStructure { public PacketId Id => PacketId.C2S_ENTRY_BOARD_ENTRY_BOARD_ITEM_EXTEND_TIMEOUT_REQ; - public C2SEntryBoardEntryBoardExtendTimeoutReq() + public C2SEntryBoardEntryBoardItemExtendTimeoutReq() { } - public class Serializer : PacketEntitySerializer + public class Serializer : PacketEntitySerializer { - public override void Write(IBuffer buffer, C2SEntryBoardEntryBoardExtendTimeoutReq obj) + public override void Write(IBuffer buffer, C2SEntryBoardEntryBoardItemExtendTimeoutReq obj) { } - public override C2SEntryBoardEntryBoardExtendTimeoutReq Read(IBuffer buffer) + public override C2SEntryBoardEntryBoardItemExtendTimeoutReq Read(IBuffer buffer) { - C2SEntryBoardEntryBoardExtendTimeoutReq obj = new C2SEntryBoardEntryBoardExtendTimeoutReq(); + C2SEntryBoardEntryBoardItemExtendTimeoutReq obj = new C2SEntryBoardEntryBoardItemExtendTimeoutReq(); return obj; } } diff --git a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemExtendTimeoutRes.cs similarity index 65% rename from Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs rename to Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemExtendTimeoutRes.cs index d79803822..ba642007b 100644 --- a/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardExtendTimeoutRes.cs +++ b/Arrowgene.Ddon.Shared/Entity/PacketStructure/S2CEntryBoardEntryBoardItemExtendTimeoutRes.cs @@ -5,27 +5,27 @@ namespace Arrowgene.Ddon.Shared.Entity.PacketStructure { - public class S2CEntryBoardEntryBoardExtendTimeoutRes : ServerResponse + public class S2CEntryBoardEntryBoardItemExtendTimeoutRes : ServerResponse { public override PacketId Id => PacketId.S2C_ENTRY_BOARD_ENTRY_BOARD_ITEM_EXTEND_TIMEOUT_RES; - public S2CEntryBoardEntryBoardExtendTimeoutRes() + public S2CEntryBoardEntryBoardItemExtendTimeoutRes() { } public ushort TimeOut { get; set; } - public class Serializer : PacketEntitySerializer + public class Serializer : PacketEntitySerializer { - public override void Write(IBuffer buffer, S2CEntryBoardEntryBoardExtendTimeoutRes obj) + public override void Write(IBuffer buffer, S2CEntryBoardEntryBoardItemExtendTimeoutRes obj) { WriteServerResponse(buffer, obj); WriteUInt16(buffer, obj.TimeOut); } - public override S2CEntryBoardEntryBoardExtendTimeoutRes Read(IBuffer buffer) + public override S2CEntryBoardEntryBoardItemExtendTimeoutRes Read(IBuffer buffer) { - S2CEntryBoardEntryBoardExtendTimeoutRes obj = new S2CEntryBoardEntryBoardExtendTimeoutRes(); + S2CEntryBoardEntryBoardItemExtendTimeoutRes obj = new S2CEntryBoardEntryBoardItemExtendTimeoutRes(); ReadServerResponse(buffer, obj); obj.TimeOut = ReadUInt16(buffer); return obj;