From 65359f557772d02a262c513314bcf85eb330671c Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 30 Aug 2024 09:49:20 -0400 Subject: [PATCH 1/3] feat: Items not equipped are lost in BBM on homepoint Implemented a mechanic for BBM where if the player chooses to homepoint inside the maze, any item which is not currently equipped to the character will be lost. --- .../Characters/ItemManager.cs | 34 +++++++++++++++++++ Arrowgene.Ddon.GameServer/DdonGameServer.cs | 2 +- .../BattleContentContentResetHandler.cs | 24 +------------ .../CharacterCharacterPenaltyReviveHandler.cs | 27 +++++++++++++-- Arrowgene.Ddon.Shared/Model/Storages.cs | 11 ++++++ 5 files changed, 71 insertions(+), 27 deletions(-) diff --git a/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs b/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs index 30ab1759a..be0ab005c 100644 --- a/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs @@ -1,5 +1,6 @@ #nullable enable using Arrowgene.Ddon.Database; +using Arrowgene.Ddon.Database.Model; using Arrowgene.Ddon.Server; using Arrowgene.Ddon.Shared.Entity.PacketStructure; using Arrowgene.Ddon.Shared.Entity.Structure; @@ -14,6 +15,12 @@ namespace Arrowgene.Ddon.GameServer.Characters { public class ItemManager { + private DdonGameServer _Server; + public ItemManager(DdonGameServer server) + { + _Server = server; + } + private static readonly ServerLogger Logger = LogProvider.Logger(typeof(ItemManager)); private static readonly uint STACK_BOX_MAX = 999; @@ -727,6 +734,33 @@ public static bool SendToItemBag(uint storageType) } return toBag; } + + public List RemoveAllItemsFromInventory(Character character, Storages storages, List storageTypes, DbConnection connection = null) + { + var results = new List(); + foreach (var storageType in storageTypes) + { + for (int i = 0; i < character.Storage.GetStorage(storageType).Items.Count; i++) + { + ushort slotNo = (ushort)(i + 1); + + var storageItem = storages.GetStorage(storageType).GetItem(slotNo); + if (storageItem != null) + { + results.Add(_Server.ItemManager.CreateItemUpdateResult(null, storageItem.Item1, storageType, slotNo, 0, 0)); + results.Add(_Server.ItemManager.CreateItemUpdateResult(null, storageItem.Item1, storageType, slotNo, 0, storageItem.Item2)); + } + + character.Storage.GetStorage(storageType).SetItem(null, 0, slotNo); + if (connection != null) + { + _Server.Database.DeleteStorageItem(character.ContentCharacterId, storageType, slotNo, connection); + } + } + } + + return results; + } } [Serializable] diff --git a/Arrowgene.Ddon.GameServer/DdonGameServer.cs b/Arrowgene.Ddon.GameServer/DdonGameServer.cs index 17c87d729..6e0150e04 100644 --- a/Arrowgene.Ddon.GameServer/DdonGameServer.cs +++ b/Arrowgene.Ddon.GameServer/DdonGameServer.cs @@ -60,7 +60,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi ClientLookup = new GameClientLookup(); ChatLogHandler = new ChatLogHandler(); ChatManager = new ChatManager(this, Router); - ItemManager = new ItemManager(); + ItemManager = new ItemManager(this); CraftManager = new CraftManager(this); PartyManager = new PartyManager(this); ExpManager = new ExpManager(this, ClientLookup); diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs index 97ad13fc0..22e3b5873 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs @@ -26,8 +26,7 @@ public BattleContentContentResetHandler(DdonGameServer server) : base(server) public override S2CBattleContentContentResetRes Handle(GameClient client, C2SBattleContentContentResetReq request) { // Reset Inventory - var updateItemList = RemoveAllItemsFromInventory(client.Character, client.Character.Storage, ItemManager.ItemBagStorageTypes); - client.Character.Storage.Clear(); + var updateItemList = Server.ItemManager.RemoveAllItemsFromInventory(client.Character, client.Character.Storage, ItemManager.ItemBagStorageTypes); // Flush Storage S2CItemUpdateCharacterItemNtc updateCharacterItemNtc = new S2CItemUpdateCharacterItemNtc() @@ -81,26 +80,5 @@ public override S2CBattleContentContentResetRes Handle(GameClient client, C2SBat return new S2CBattleContentContentResetRes(); } - - private List RemoveAllItemsFromInventory(Character character, Storages storages, List storageTypes) - { - var results = new List(); - foreach (var storageType in storageTypes) - { - for (int i = 0; i < character.Storage.GetStorage(storageType).Items.Count; i++) - { - ushort slotNo = (ushort)(i + 1); - - var storageItem = storages.GetStorage(storageType).GetItem(slotNo); - if (storageItem != null) - { - results.Add(Server.ItemManager.CreateItemUpdateResult(null, storageItem.Item1, storageType, slotNo, 0, 0)); - results.Add(Server.ItemManager.CreateItemUpdateResult(null, storageItem.Item1, storageType, slotNo, 0, storageItem.Item2)); - } - } - } - - return results; - } } } diff --git a/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs b/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs index 1b2aa918f..8693bbab8 100644 --- a/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs @@ -7,10 +7,13 @@ using Arrowgene.Ddon.Shared.Network; using Arrowgene.Logging; using Arrowgene.Ddon.Shared.Model; +using Arrowgene.Ddon.GameServer.Characters; +using System.Collections.Generic; +using Arrowgene.Ddon.Shared.Entity.Structure; namespace Arrowgene.Ddon.GameServer.Handler { - public class CharacterCharacterPenaltyReviveHandler : StructurePacketHandler + public class CharacterCharacterPenaltyReviveHandler : GameRequestPacketHandler { private static readonly ServerLogger Logger = LogProvider.Logger(typeof(CharacterCharacterPenaltyReviveHandler)); @@ -21,10 +24,9 @@ public CharacterCharacterPenaltyReviveHandler(DdonGameServer server) : base(serv { } - public override void Handle(GameClient client, StructurePacket packet) + public override S2CCharacterCharacterPenaltyReviveRes Handle(GameClient client, C2SCharacterCharacterPenaltyReviveReq packet) { S2CCharacterCharacterPenaltyReviveRes res = new S2CCharacterCharacterPenaltyReviveRes(); - client.Send(res); if (client.GameMode != GameMode.BitterblackMaze) { @@ -37,6 +39,25 @@ public override void Handle(GameClient client, StructurePacket client.Send(new S2CCharacterFinishDeathPenaltyNtc())); } + else if (client.GameMode == GameMode.BitterblackMaze) + { + // The player will lose all items in their bag when homepoints after a death (equipped items stay) + List updateItemList = new List(); + Server.Database.ExecuteInTransaction(connection => + { + updateItemList = Server.ItemManager.RemoveAllItemsFromInventory(client.Character, client.Character.Storage, ItemManager.ItemBagStorageTypes, connection); + }); + + // Flush Storage + S2CItemUpdateCharacterItemNtc updateCharacterItemNtc = new S2CItemUpdateCharacterItemNtc() + { + UpdateType = ItemNoticeType.SwitchingStorage, + UpdateItemList = updateItemList + }; + client.Send(updateCharacterItemNtc); + } + + return res; } } } diff --git a/Arrowgene.Ddon.Shared/Model/Storages.cs b/Arrowgene.Ddon.Shared/Model/Storages.cs index a4a29130c..66546884b 100644 --- a/Arrowgene.Ddon.Shared/Model/Storages.cs +++ b/Arrowgene.Ddon.Shared/Model/Storages.cs @@ -68,6 +68,17 @@ public void Clear() } } + public void Clear(List storageTypes) + { + foreach (var (type, storage) in storages) + { + if (storageTypes.Contains(type)) + { + storage.Clear(); + } + } + } + public Equipment GetCharacterEquipment() { return new Equipment(GetStorage(StorageType.CharacterEquipment), 0); From f0304ac01b6fb7e15b7bbd634c60ecf4c75d98bc Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sat, 31 Aug 2024 14:18:54 -0400 Subject: [PATCH 2/3] Code Review changes Adjust deleting all items. --- .../Characters/ItemManager.cs | 11 +++++---- .../BattleContentContentResetHandler.cs | 23 ++++++++----------- Arrowgene.Ddon.Shared/Model/Storages.cs | 5 ++++ 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs b/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs index be0ab005c..1154730bd 100644 --- a/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs +++ b/Arrowgene.Ddon.GameServer/Characters/ItemManager.cs @@ -25,6 +25,7 @@ public ItemManager(DdonGameServer server) private static readonly uint STACK_BOX_MAX = 999; + public static readonly List AllItemStorages = Enum.GetValues(typeof(StorageType)).Cast().ToList(); public static readonly List ItemBagStorageTypes = new List { StorageType.ItemBagConsumable, StorageType.ItemBagMaterial, StorageType.ItemBagEquipment, StorageType.ItemBagJob, StorageType.KeyItems @@ -740,6 +741,11 @@ public List RemoveAllItemsFromInventory(Character charact var results = new List(); foreach (var storageType in storageTypes) { + if (!character.Storage.HasStorage(storageType)) + { + continue; + } + for (int i = 0; i < character.Storage.GetStorage(storageType).Items.Count; i++) { ushort slotNo = (ushort)(i + 1); @@ -752,10 +758,7 @@ public List RemoveAllItemsFromInventory(Character charact } character.Storage.GetStorage(storageType).SetItem(null, 0, slotNo); - if (connection != null) - { - _Server.Database.DeleteStorageItem(character.ContentCharacterId, storageType, slotNo, connection); - } + _Server.Database.DeleteStorageItem(character.ContentCharacterId, storageType, slotNo, connection); } } diff --git a/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs b/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs index 22e3b5873..d96dbbdf2 100644 --- a/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/BattleContentContentResetHandler.cs @@ -25,24 +25,14 @@ public BattleContentContentResetHandler(DdonGameServer server) : base(server) public override S2CBattleContentContentResetRes Handle(GameClient client, C2SBattleContentContentResetReq request) { - // Reset Inventory - var updateItemList = Server.ItemManager.RemoveAllItemsFromInventory(client.Character, client.Character.Storage, ItemManager.ItemBagStorageTypes); - - // Flush Storage - S2CItemUpdateCharacterItemNtc updateCharacterItemNtc = new S2CItemUpdateCharacterItemNtc() - { - UpdateType = ItemNoticeType.SwitchingStorage, - UpdateItemList = updateItemList - }; - client.Send(updateCharacterItemNtc); - // Add back equipment templates client.Character.EquipmentTemplate = new EquipmentTemplate(Server.AssetRepository.BitterblackMazeAsset.GenerateStarterEquipment(), Server.AssetRepository.BitterblackMazeAsset.GenerateStarterJobEquipment()); + List updateItemList = null; Server.Database.ExecuteInTransaction(connection => { - // Delete all existing storage items - Server.Database.DeleteAllStorageItems(connection, client.Character.ContentCharacterId); + // Remove all items from the player inventory + updateItemList = Server.ItemManager.RemoveAllItemsFromInventory(client.Character, client.Character.Storage, ItemManager.AllItemStorages, connection); // Remove items equipped in the database Server.Database.DeleteAllEquipItems(client.Character.CommonId, connection); @@ -51,6 +41,13 @@ public override S2CBattleContentContentResetRes Handle(GameClient client, C2SBat Server.Database.CreateItems(connection, client.Character); }); + S2CItemUpdateCharacterItemNtc updateCharacterItemNtc = new S2CItemUpdateCharacterItemNtc() + { + UpdateType = ItemNoticeType.SwitchingStorage, + UpdateItemList = updateItemList + }; + client.Send(updateCharacterItemNtc); + // Add back equipment client.Character.Equipment = client.Character.Storage.GetCharacterEquipment(); diff --git a/Arrowgene.Ddon.Shared/Model/Storages.cs b/Arrowgene.Ddon.Shared/Model/Storages.cs index 66546884b..176f8f5e3 100644 --- a/Arrowgene.Ddon.Shared/Model/Storages.cs +++ b/Arrowgene.Ddon.Shared/Model/Storages.cs @@ -55,6 +55,11 @@ public Storage GetStorage(StorageType storageType) return storages[storageType]; } + public bool HasStorage(StorageType storageType) + { + return storages.ContainsKey(storageType); + } + public void AddStorage(StorageType storageType, Storage storage) { storages[storageType] = storage; From 0ad3fe34974bc6bc6846d6720c8d035c5738f946 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Sat, 31 Aug 2024 15:49:36 -0400 Subject: [PATCH 3/3] Sort using statements --- .../CharacterCharacterPenaltyReviveHandler.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs b/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs index 8693bbab8..08fd3e39c 100644 --- a/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs +++ b/Arrowgene.Ddon.GameServer/Handler/CharacterCharacterPenaltyReviveHandler.cs @@ -1,15 +1,12 @@ -using System.Threading.Tasks; -using System; -using System.Threading; +using Arrowgene.Ddon.GameServer.Characters; using Arrowgene.Ddon.Server; -using Arrowgene.Ddon.Server.Network; using Arrowgene.Ddon.Shared.Entity.PacketStructure; -using Arrowgene.Ddon.Shared.Network; -using Arrowgene.Logging; +using Arrowgene.Ddon.Shared.Entity.Structure; using Arrowgene.Ddon.Shared.Model; -using Arrowgene.Ddon.GameServer.Characters; +using Arrowgene.Logging; +using System; using System.Collections.Generic; -using Arrowgene.Ddon.Shared.Entity.Structure; +using System.Threading.Tasks; namespace Arrowgene.Ddon.GameServer.Handler {