From 9f3ac98edc7fbdc25441c6fa6d00d9bf8aa80e16 Mon Sep 17 00:00:00 2001 From: Somebody Date: Sat, 3 Aug 2024 11:00:06 +0800 Subject: [PATCH] Enhancement: Improve Quest PlayerSyncScNotify performance --- GameServer/Game/Mission/MissionManager.cs | 7 ++- GameServer/Game/Player/PlayerInstance.cs | 3 +- GameServer/Game/Quest/QuestManager.cs | 60 +++++++++++++------ GameServer/Server/Connection.cs | 2 - .../Send/Player/PacketPlayerSyncScNotify.cs | 7 +++ 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/GameServer/Game/Mission/MissionManager.cs b/GameServer/Game/Mission/MissionManager.cs index bb9f443b..2202cbcb 100644 --- a/GameServer/Game/Mission/MissionManager.cs +++ b/GameServer/Game/Mission/MissionManager.cs @@ -400,7 +400,7 @@ public class MissionManager : BasePlayerManager await Player.SendPacket(new PacketScenePlaneEventScNotify(itemList)); } - public async ValueTask HandleFinishType(MissionFinishTypeEnum finishType, object? arg = null) + public async ValueTask HandleFinishType(MissionFinishTypeEnum finishType, object? arg = null, bool pushQuest = true) { FinishTypeHandlers.TryGetValue(finishType, out var handler); foreach (var mission in GetRunningSubMissionList()) @@ -417,11 +417,14 @@ public class MissionManager : BasePlayerManager if (handler != null) await handler.HandleQuestFinishType(Player, excel, finishWay, arg); } + if (pushQuest) + await Player.QuestManager!.SyncQuest(); } public async ValueTask HandleAllFinishType(object? arg = null) { - foreach (var handler in FinishTypeHandlers) await HandleFinishType(handler.Key, arg); + foreach (var handler in FinishTypeHandlers) await HandleFinishType(handler.Key, arg, false); + await Player.QuestManager!.SyncQuest(); } public async ValueTask HandleTalkStr(string talkString) diff --git a/GameServer/Game/Player/PlayerInstance.cs b/GameServer/Game/Player/PlayerInstance.cs index 9972778f..611c2215 100644 --- a/GameServer/Game/Player/PlayerInstance.cs +++ b/GameServer/Game/Player/PlayerInstance.cs @@ -205,8 +205,9 @@ public class PlayerInstance(PlayerData data) if (ConfigManager.Config.ServerOption.EnableMission) { await MissionManager!.AcceptMainMissionByCondition(); - await QuestManager!.AcceptQuestByCondition(); } + + await QuestManager!.AcceptQuestByCondition(); } public T InitializeDatabase() where T : class, new() diff --git a/GameServer/Game/Quest/QuestManager.cs b/GameServer/Game/Quest/QuestManager.cs index a77cdd3f..d5ff4c9a 100644 --- a/GameServer/Game/Quest/QuestManager.cs +++ b/GameServer/Game/Quest/QuestManager.cs @@ -7,6 +7,7 @@ using EggLink.DanhengServer.Enums.Quest; using EggLink.DanhengServer.GameServer.Game.Player; using EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Util; namespace EggLink.DanhengServer.GameServer.Game.Quest; @@ -14,18 +15,21 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) { public UnlockHandler UnlockHandler { get; } = new(player); public QuestData QuestData { get; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew(player.Uid); + public List WaitToSync { get; } = []; #region Actions public async ValueTask AcceptQuestByCondition() { + var syncList = new List(); foreach (var quest in GameData.QuestDataData.Values) { if (QuestData.Quests.ContainsKey(quest.QuestID)) continue; // Already accepted + QuestInfo? acceptQuest = null; switch (quest.UnlockType) { case QuestUnlockTypeEnum.AutoUnlock: - await AcceptQuest(quest.QuestID); + acceptQuest = await AcceptQuest(quest.QuestID, false); break; case QuestUnlockTypeEnum.FinishMission: var accept = true; @@ -37,7 +41,10 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) break; } - if (accept) await AcceptQuest(quest.QuestID); + if (accept) + { + acceptQuest = await AcceptQuest(quest.QuestID, false); + } break; case QuestUnlockTypeEnum.FinishQuest: var accept2 = true; @@ -50,7 +57,7 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) break; } - if (accept2) await AcceptQuest(quest.QuestID); + if (accept2) acceptQuest = await AcceptQuest(quest.QuestID, false); break; case QuestUnlockTypeEnum.ManualUnlock: // idk what this is break; @@ -59,15 +66,20 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) default: break; } + + if (acceptQuest != null) syncList.Add(acceptQuest); } + + if (syncList.Count > 0) + await Player.SendPacket(new PacketPlayerSyncScNotify(syncList)); } - public async ValueTask AcceptQuest(int questId) + public async ValueTask AcceptQuest(int questId, bool sync = true) { GameData.QuestDataData.TryGetValue(questId, out var questExcel); - if (questExcel == null) return; + if (questExcel == null) return null; - if (QuestData.Quests.ContainsKey(questId)) return; + if (QuestData.Quests.ContainsKey(questId)) return null; var questInfo = new QuestInfo { @@ -78,10 +90,12 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) QuestData.Quests.Add(questId, questInfo); - await Player.SendPacket(new PacketPlayerSyncScNotify(questInfo)); + if (sync) await Player.SendPacket(new PacketPlayerSyncScNotify(questInfo)); + + return questInfo; } - public async ValueTask FinishQuest(int questId) + public async ValueTask FinishQuest(int questId, bool push = true) { GameData.QuestDataData.TryGetValue(questId, out var questExcel); if (questExcel == null) return; @@ -93,7 +107,10 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) questInfo.QuestStatus = QuestStatus.QuestFinish; questInfo.Progress = finishWayExcel.Progress; - await Player.SendPacket(new PacketPlayerSyncScNotify(questInfo)); + if (push) + await Player.SendPacket(new PacketPlayerSyncScNotify(questInfo)); + else + WaitToSync.SafeAdd(questInfo); // accept next quest await AcceptQuestByCondition(); @@ -134,7 +151,7 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) return (Retcode.RetSucc, items); } - public async ValueTask AddQuestProgress(int questId, int progress) + public async ValueTask AddQuestProgress(int questId, int progress, bool push = false) { GameData.QuestDataData.TryGetValue(questId, out var questExcel); if (questExcel == null) return; @@ -145,13 +162,14 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) if (questInfo.QuestStatus != QuestStatus.QuestDoing) return; questInfo.Progress += progress; - if (questInfo.Progress >= finishWayExcel.Progress) - await FinishQuest(questId); - else + if (questInfo.Progress >= finishWayExcel.Progress) await FinishQuest(questId, push); + else if (push) await Player.SendPacket(new PacketPlayerSyncScNotify(questInfo)); + else + WaitToSync.SafeAdd(questInfo); } - public async ValueTask UpdateQuestProgress(int questId, int progress) + public async ValueTask UpdateQuestProgress(int questId, int progress, bool push = false) { GameData.QuestDataData.TryGetValue(questId, out var questExcel); if (questExcel == null) return; @@ -164,10 +182,18 @@ public class QuestManager(PlayerInstance player) : BasePlayerManager(player) if (progress < questInfo.Progress) return; // prevent rollback if (progress == questInfo.Progress) return; questInfo.Progress = progress; - if (questInfo.Progress >= finishWayExcel.Progress) - await FinishQuest(questId); - else + if (questInfo.Progress >= finishWayExcel.Progress) await FinishQuest(questId, push); + else if (push) await Player.SendPacket(new PacketPlayerSyncScNotify(questInfo)); + else + WaitToSync.SafeAdd(questInfo); + } + + public async ValueTask SyncQuest() + { + if (WaitToSync.Count == 0) return; + await Player.SendPacket(new PacketPlayerSyncScNotify(WaitToSync)); + WaitToSync.Clear(); } #endregion diff --git a/GameServer/Server/Connection.cs b/GameServer/Server/Connection.cs index 2d73678c..4202e686 100644 --- a/GameServer/Server/Connection.cs +++ b/GameServer/Server/Connection.cs @@ -31,8 +31,6 @@ public class Connection : DanhengConnection Player?.OnLogoutAsync(); DanhengListener.UnregisterConnection(this); base.Stop(); - - IsOnline = false; } protected async Task ReceiveLoop() diff --git a/GameServer/Server/Packet/Send/Player/PacketPlayerSyncScNotify.cs b/GameServer/Server/Packet/Send/Player/PacketPlayerSyncScNotify.cs index f3468f6f..dd294255 100644 --- a/GameServer/Server/Packet/Send/Player/PacketPlayerSyncScNotify.cs +++ b/GameServer/Server/Packet/Send/Player/PacketPlayerSyncScNotify.cs @@ -131,6 +131,13 @@ public class PacketPlayerSyncScNotify : BasePacket SetData(proto); } + public PacketPlayerSyncScNotify(List quest) : base(CmdIds.PlayerSyncScNotify) + { + var proto = new PlayerSyncScNotify(); + proto.QuestList.Add(quest.Select(x => x.ToProto())); + + SetData(proto); + } private void AddItemToProto(ItemData item, PlayerSyncScNotify notify) {