From d3a3eaa15ea65730c7c1f0e389fec1ba4064f469 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 8 Nov 2024 09:28:49 -0500 Subject: [PATCH 1/2] feat: Add new settings to be configured Added the following new configuration settings - ExpModifier - PpModifier - BoModifier - HoMOdifier - JpModifier - RewardBoxMax - QuestOrderMax --- .../Characters/ExpManager.cs | 10 +-- .../Characters/RewardManager.cs | 4 +- .../Handler/InstanceEnemyKillHandler.cs | 8 +-- .../QuestGetCycleContentsStateListHandler.cs | 2 + .../Quests/QuestStateManager.cs | 23 +++++- Arrowgene.Ddon.Server/GameLogicSetting.cs | 72 +++++++++++++++++++ 6 files changed, 104 insertions(+), 15 deletions(-) diff --git a/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs b/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs index 8ba100d0d..2a0808ffe 100644 --- a/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/ExpManager.cs @@ -509,7 +509,7 @@ public PacketQueue AddExp(GameClient client, CharacterCommon characterToAddExpTo if (client.GameMode == GameMode.Normal) { - addJobPoint += LEVEL_UP_JOB_POINTS_EARNED[targetLevel]; + addJobPoint += (uint)(LEVEL_UP_JOB_POINTS_EARNED[targetLevel] * _Server.Setting.GameLogicSetting.JpModifier); } } @@ -903,7 +903,7 @@ public uint GetAdjustedExp(GameMode gameMode, RewardSource source, PartyGroup pa { if (_Server.GpCourseManager.DisablePartyExpAdjustment()) { - return baseExpAmount; + return (uint)(baseExpAmount * _GameSettings.ExpModifier); } double multiplier = 1.0; @@ -914,7 +914,7 @@ public uint GetAdjustedExp(GameMode gameMode, RewardSource source, PartyGroup pa multiplier = Math.Min(partyRangeMultiplier, targetMultiplier); } - return (uint)(multiplier * baseExpAmount); + return (uint)(multiplier * baseExpAmount * _GameSettings.ExpModifier); } private uint GetMaxAllowedPartyRange() @@ -996,13 +996,13 @@ public uint GetAdjustedPawnExp(GameMode gameMode, RewardSource source, PartyGrou { if (!_GameSettings.EnablePawnCatchup || gameMode == GameMode.BitterblackMaze) { - return baseExpAmount; + return (uint)(baseExpAmount * _GameSettings.ExpModifier); } var targetMultiplier = CalculatePawnCatchupTargetLvMultiplier(gameMode, pawn, targetLv); var multiplier = _GameSettings.PawnCatchupMultiplier * targetMultiplier; - return (uint)(multiplier * baseExpAmount); + return (uint)(multiplier * baseExpAmount * _GameSettings.ExpModifier); } } } diff --git a/Arrowgene.Ddon.GameServer/Characters/RewardManager.cs b/Arrowgene.Ddon.GameServer/Characters/RewardManager.cs index 9dd05f679..606bed6e3 100644 --- a/Arrowgene.Ddon.GameServer/Characters/RewardManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/RewardManager.cs @@ -11,8 +11,6 @@ namespace Arrowgene.Ddon.GameServer.Characters { public class RewardManager { - private readonly int MAX_REWARD_BOX_RESULTS = 100; - private static readonly ServerLogger Logger = LogProvider.Logger(typeof(RewardManager)); private readonly DdonGameServer _Server; @@ -26,7 +24,7 @@ public bool AddQuestRewards(GameClient client, Quest quest, DbConnection? connec var rewards = quest.GenerateBoxRewards(); var currentRewards = GetQuestBoxRewards(client, connectionIn); - if (currentRewards.Count >= MAX_REWARD_BOX_RESULTS) + if (currentRewards.Count >= _Server.Setting.GameLogicSetting.RewardBoxMax) { return false; } diff --git a/Arrowgene.Ddon.GameServer/Handler/InstanceEnemyKillHandler.cs b/Arrowgene.Ddon.GameServer/Handler/InstanceEnemyKillHandler.cs index b13b41714..a6efe3ebd 100644 --- a/Arrowgene.Ddon.GameServer/Handler/InstanceEnemyKillHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/InstanceEnemyKillHandler.cs @@ -164,7 +164,7 @@ public override S2CInstanceEnemyKillRes Handle(GameClient client, C2SInstanceEne uint calcExp = _gameServer.ExpManager.GetAdjustedExp(client.GameMode, RewardSource.Enemy, client.Party, enemyKilled.GetDroppedExperience(), enemyKilled.Lv); - uint calcPP = enemyKilled.GetDroppedPlayPoints(); + uint calcPP = (uint)(enemyKilled.GetDroppedPlayPoints() * _gameServer.Setting.GameLogicSetting.PpModifier); foreach (PartyMember member in client.Party.Members) { @@ -199,8 +199,8 @@ public override S2CInstanceEnemyKillRes Handle(GameClient client, C2SInstanceEne if (enemyKilled.BloodOrbs > 0) { // Drop BO - uint gainedBo = enemyKilled.BloodOrbs; - uint bonusBo = (uint)(enemyKilled.BloodOrbs * _gameServer.GpCourseManager.EnemyBloodOrbBonus()); + uint gainedBo = (uint) (enemyKilled.BloodOrbs * _gameServer.Setting.GameLogicSetting.BoModifier); + uint bonusBo = (uint)(gainedBo * _gameServer.GpCourseManager.EnemyBloodOrbBonus()); CDataUpdateWalletPoint boUpdateWalletPoint = _gameServer.WalletManager.AddToWallet(memberClient.Character, WalletType.BloodOrbs, gainedBo + bonusBo, bonusBo, connectionIn: connectionIn); updateCharacterItemNtc.UpdateWalletList.Add(boUpdateWalletPoint); } @@ -208,7 +208,7 @@ public override S2CInstanceEnemyKillRes Handle(GameClient client, C2SInstanceEne if (enemyKilled.HighOrbs > 0) { // Drop HO - uint gainedHo = enemyKilled.HighOrbs; + uint gainedHo = (uint)(enemyKilled.HighOrbs * _gameServer.Setting.GameLogicSetting.HoModifier); CDataUpdateWalletPoint hoUpdateWalletPoint = _gameServer.WalletManager.AddToWallet(memberClient.Character, WalletType.HighOrbs, gainedHo, connectionIn: connectionIn); } diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestGetCycleContentsStateListHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestGetCycleContentsStateListHandler.cs index f6c854439..45a3c99a4 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestGetCycleContentsStateListHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestGetCycleContentsStateListHandler.cs @@ -35,6 +35,8 @@ public override S2CQuestGetCycleContentsStateListRes Handle(GameClient client, C ntc.WorldManageQuestOrderList = pcap.WorldManageQuestOrderList; // Recover paths + change vocation ntc.QuestDefine = pcap.QuestDefine; // Recover quest log data to be able to accept quests + ntc.QuestDefine.OrderMaxNum = Server.Setting.GameLogicSetting.QuestOrderMax; + ntc.QuestDefine.RewardBoxMaxNum = Server.Setting.GameLogicSetting.RewardBoxMax; // pcap.MainQuestIdList; (this will add back all missing functionality which depends on complete MSQ) var completedMsq = client.Character.CompletedQuests.Values.Where(x => x.QuestType == QuestType.Main); diff --git a/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs b/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs index bf08923d5..556715880 100644 --- a/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs +++ b/Arrowgene.Ddon.GameServer/Quests/QuestStateManager.cs @@ -576,19 +576,36 @@ protected PacketQueue SendWalletRewards(DdonGameServer server, GameClient client foreach (var expPoint in quest.ExpRewards) { + uint amount = expPoint.Reward; + double modifier = 1.0; + switch (expPoint.Type) + { + case ExpType.ExperiencePoints: + modifier = server.Setting.GameLogicSetting.ExpModifier; + break; + case ExpType.JobPoints: + modifier = server.Setting.GameLogicSetting.JpModifier; + break; + case ExpType.PlayPoints: + modifier = server.Setting.GameLogicSetting.PpModifier; + break; + } + + amount = (uint)(amount * modifier); + if (expPoint.Type == ExpType.ExperiencePoints) { - var ntcs = server.ExpManager.AddExp(client, client.Character, expPoint.Reward, RewardSource.Quest, quest.QuestType, connectionIn); + var ntcs = server.ExpManager.AddExp(client, client.Character, amount, RewardSource.Quest, quest.QuestType, connectionIn); packets.AddRange(ntcs); } else if (expPoint.Type == ExpType.JobPoints) { - var ntcs = server.ExpManager.AddJp(client, client.Character, expPoint.Reward, RewardSource.Quest, quest.QuestType, connectionIn); + var ntcs = server.ExpManager.AddJp(client, client.Character, amount, RewardSource.Quest, quest.QuestType, connectionIn); packets.AddRange(ntcs); } else if (expPoint.Type == ExpType.PlayPoints) { - var ntc = server.PPManager.AddPlayPoint(client, expPoint.Reward, type: 1, connectionIn: connectionIn); + var ntc = server.PPManager.AddPlayPoint(client, amount, type: 1, connectionIn: connectionIn); client.Enqueue(ntc, packets); } } diff --git a/Arrowgene.Ddon.Server/GameLogicSetting.cs b/Arrowgene.Ddon.Server/GameLogicSetting.cs index 4a0aec73e..b3788e147 100644 --- a/Arrowgene.Ddon.Server/GameLogicSetting.cs +++ b/Arrowgene.Ddon.Server/GameLogicSetting.cs @@ -166,6 +166,42 @@ public class GameLogicSetting /// [DataMember(Order = 26)] public bool DisableExpCorrectionForMyPawn { get; set; } + /// + /// Global modifier for exp calculations to scale up or down. + /// + [DataMember(Order = 26)] public double ExpModifier { get; set; } + + /// + /// Global modifier for pp calculations to scale up or down. + /// + [DataMember(Order = 26)] public double PpModifier { get; set; } + + /// + /// Global modifier for BO calculations to scale up or down. + /// + [DataMember(Order = 26)] public double BoModifier { get; set; } + + /// + /// Global modifier for HO calculations to scale up or down. + /// + [DataMember(Order = 26)] public double HoModifier { get; set; } + + /// + /// Global modifier for JP calculations to scale up or down. + /// + [DataMember(Order = 26)] public double JpModifier { get; set; } + + /// + /// Configures the maximum amount of reward box slots. + /// + [DataMember(Order = 27)] public byte RewardBoxMax { get; set; } + + /// + /// Configures the maximum amount of quests that can be ordered at one time. + /// + [DataMember(Order = 27)] public byte QuestOrderMax { get; set; } + + /// /// Various URLs used by the client. /// Shared with the login server. @@ -249,6 +285,14 @@ public GameLogicSetting() DefaultMaxBazaarExhibits = 5; DefaultWarpFavorites = 3; + ExpModifier = 1.0; + PpModifier = 1.0; + BoModifier = 1.0; + HoModifier = 1.0; + JpModifier = 1.0; + RewardBoxMax = 100; + QuestOrderMax = 20; + string urlDomain = $"http://localhost:{52099}"; UrlManual = $"{urlDomain}/manual_nfb/"; UrlShopDetail = $"{urlDomain}/shop/ingame/stone/detail"; @@ -301,6 +345,14 @@ public GameLogicSetting(GameLogicSetting setting) DefaultMaxBazaarExhibits = setting.DefaultMaxBazaarExhibits; DefaultWarpFavorites = setting.DefaultWarpFavorites; + ExpModifier = setting.ExpModifier; + PpModifier = setting.PpModifier; + BoModifier = setting.BoModifier; + HoModifier = setting.HoModifier; + JpModifier = setting.JpModifier; + RewardBoxMax = setting.RewardBoxMax; + QuestOrderMax = setting.QuestOrderMax; + UrlManual = setting.UrlManual; UrlShopDetail = setting.UrlShopDetail; UrlShopCounterA = setting.UrlShopCounterA; @@ -375,6 +427,26 @@ void OnDeserialized(StreamingContext context) { PawnCatchupMultiplier = 1.0; } + if (ExpModifier < 0) + { + ExpModifier = 1.0; + } + if (PpModifier < 0) + { + PpModifier = 1.0; + } + if (BoModifier < 0) + { + BoModifier = 1.0; + } + if (HoModifier < 0) + { + HoModifier = 1.0; + } + if (JpModifier < 0) + { + JpModifier = 1.0; + } foreach (var walletMax in DefaultWalletLimits) { From 2aa64029b8feab9c8e73d8732755bc3e05ae3821 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sat, 9 Nov 2024 09:19:13 -0500 Subject: [PATCH 2/2] Fix issue with reward manager - Fix issue with indexing when rewards for disabled/non-existing quests are present. - Added rewards to transaction where possible. --- .../Handler/QuestGetRewardBoxItemHandler.cs | 36 +++++++++---------- .../Handler/QuestGetRewardBoxListHandler.cs | 1 + 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxItemHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxItemHandler.cs index a10314b62..f7b1a569f 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxItemHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxItemHandler.cs @@ -63,34 +63,34 @@ public override S2CQuestGetRewardBoxItemRes Handle(GameClient client, C2SQuestGe } var distinctRewards = packet.GetRewardBoxItemList.Select(x => x.UID).Distinct().ToList(); - var slotCount = coalescedRewards.Sum(x => - distinctRewards.Contains(x.Key) - ? Server.ItemManager.PredictAddItemSlots(client.Character, StorageType.StorageBoxNormal, x.Value.ItemId, x.Value.Num) - : 0); + var slotCount = coalescedRewards.Sum(x => distinctRewards.Contains(x.Key) ? Server.ItemManager.PredictAddItemSlots(client.Character, StorageType.StorageBoxNormal, x.Value.ItemId, x.Value.Num) : 0); if (slotCount > client.Character.Storage.GetStorage(StorageType.StorageBoxNormal).EmptySlots()) { throw new ResponseErrorException(ErrorCode.ERROR_CODE_ITEM_STORAGE_OVERFLOW); } - foreach (var rewardUID in distinctRewards) + Server.Database.ExecuteInTransaction(connection => { - var reward = coalescedRewards[rewardUID]; - if (Server.ItemManager.IsItemWalletPoint(reward.ItemId)) + foreach (var rewardUID in distinctRewards) { - (WalletType walletType, uint amount) = Server.ItemManager.ItemToWalletPoint(reward.ItemId); - var result = Server.WalletManager.AddToWallet(client.Character, walletType, amount * reward.Num); - updateCharacterItemNtc.UpdateWalletList.Add(result); + var reward = coalescedRewards[rewardUID]; + if (Server.ItemManager.IsItemWalletPoint(reward.ItemId)) + { + (WalletType walletType, uint amount) = Server.ItemManager.ItemToWalletPoint(reward.ItemId); + var result = Server.WalletManager.AddToWallet(client.Character, walletType, amount * reward.Num, connectionIn: connection); + updateCharacterItemNtc.UpdateWalletList.Add(result); + } + else if (reward.Num > 0) + { + var result = Server.ItemManager.AddItem(Server, client.Character, false, reward.ItemId, reward.Num, connectionIn: connection); + updateCharacterItemNtc.UpdateItemList.AddRange(result); + } } - else if (reward.Num > 0) - { - var result = Server.ItemManager.AddItem(Server, client.Character, false, reward.ItemId, reward.Num); - updateCharacterItemNtc.UpdateItemList.AddRange(result); - } - } - client.Send(updateCharacterItemNtc); + Server.RewardManager.DeleteQuestBoxReward(client, questBoxReward.UniqRewardId, connectionIn: connection); + }); - Server.RewardManager.DeleteQuestBoxReward(client, questBoxReward.UniqRewardId); + client.Send(updateCharacterItemNtc); return new S2CQuestGetRewardBoxItemRes(); } diff --git a/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxListHandler.cs b/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxListHandler.cs index 869f63f86..5a02a9248 100644 --- a/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxListHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/QuestGetRewardBoxListHandler.cs @@ -36,6 +36,7 @@ public override S2CQuestGetRewardBoxListRes Handle(GameClient client, C2SQuestGe var quest = QuestManager.GetQuestByScheduleId(boxReward.QuestScheduleId); if (quest == null) { + listNo += 1; Logger.Error($"Quest reward for QuestScheduleId={boxReward.QuestScheduleId}, but no definition of quest exists."); continue; }