From 62792e97a31f5732357a7ef602146885566cbcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Mon, 21 Jul 2025 13:07:18 -0300 Subject: [PATCH 1/2] Delete unowned items on world startup --- .gitignore | 1 + Maple2.Database/Storage/Game/GameStorage.Item.cs | 16 +++++++++++++++- Maple2.Server.World/WorldServer.cs | 11 +++++------ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index f90f34245..2de4dc35a 100644 --- a/.gitignore +++ b/.gitignore @@ -376,3 +376,4 @@ FodyWeavers.xsd .idea/.idea.Maple2/.idea/sqldialects.xml .idea/.idea.Maple2/.idea/dataSources.xml /Maple2.Server.Game/DebugTriggers +.idea/.idea.Maple2/.idea/AugmentWebviewStateStore.xml diff --git a/Maple2.Database/Storage/Game/GameStorage.Item.cs b/Maple2.Database/Storage/Game/GameStorage.Item.cs index 3d1f46d2b..88434976a 100644 --- a/Maple2.Database/Storage/Game/GameStorage.Item.cs +++ b/Maple2.Database/Storage/Game/GameStorage.Item.cs @@ -3,6 +3,7 @@ using Maple2.Model.Enum; using Maple2.Model.Metadata; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using Item = Maple2.Model.Game.Item; using PetConfig = Maple2.Model.Game.PetConfig; using UgcItemLook = Maple2.Model.Game.UgcItemLook; @@ -58,7 +59,10 @@ public partial class Request { } public UgcItemLook? GetTemplate(long itemUid) { - ItemSubType? model = Context.Item.Select(item => new { item.Id, item.SubType }) + ItemSubType? model = Context.Item.Select(item => new { + item.Id, + item.SubType + }) .FirstOrDefault(result => result.Id == itemUid)?.SubType; if (model is not ItemUgc ugcModel) { return null; @@ -159,6 +163,16 @@ public bool UpdateItem(Item item) { return Context.TrySaveChanges(); } + // Delete all items that are unowned. (Character, account, etc.) + public void DeleteUnownedItems() { + int deletedCount = Context.Database.ExecuteSqlRaw("DELETE FROM `item` WHERE OwnerId = 0"); + if (deletedCount == 0) { + return; + } + + Logger.LogInformation("Deleted {Count} unowned items.", deletedCount); + } + public bool SaveStorageInfo(long accountId, long mesos, short expand) { ItemStorage? info = Context.ItemStorage.Find(accountId); if (info == null) { diff --git a/Maple2.Server.World/WorldServer.cs b/Maple2.Server.World/WorldServer.cs index 7ca8a5b35..39b4a3a21 100644 --- a/Maple2.Server.World/WorldServer.cs +++ b/Maple2.Server.World/WorldServer.cs @@ -47,7 +47,10 @@ public WorldServer(GameStorage gameStorage, ChannelClientLookup channelClients, scheduler.Start(); memoryStringBoards = []; - SetAllCharacterToOffline(); + // World initialization: set all characters offline and cleanup unowned items + using GameStorage.Request db = gameStorage.Context(); + db.SetAllCharacterToOffline(); + db.DeleteUnownedItems(); StartDailyReset(); StartWorldEvents(); @@ -60,11 +63,6 @@ public WorldServer(GameStorage gameStorage, ChannelClientLookup channelClients, heartbeatThread.Start(); } - private void SetAllCharacterToOffline() { - using GameStorage.Request db = gameStorage.Context(); - db.SetAllCharacterToOffline(); - } - private void Heartbeat() { while (!tokenSource.Token.IsCancellationRequested) { try { @@ -138,6 +136,7 @@ private void Loop() { public void Stop() { tokenSource.Cancel(); thread.Join(); + heartbeatThread.Join(); scheduler.Stop(); } From 36bb5010f43b0cb6837e8009394f94e5a40b6fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=82ngelo=20Tadeucci?= Date: Mon, 21 Jul 2025 13:12:34 -0300 Subject: [PATCH 2/2] format --- Maple2.Database/Storage/Game/GameStorage.Item.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Maple2.Database/Storage/Game/GameStorage.Item.cs b/Maple2.Database/Storage/Game/GameStorage.Item.cs index 88434976a..4a0ea0376 100644 --- a/Maple2.Database/Storage/Game/GameStorage.Item.cs +++ b/Maple2.Database/Storage/Game/GameStorage.Item.cs @@ -60,10 +60,9 @@ public partial class Request { public UgcItemLook? GetTemplate(long itemUid) { ItemSubType? model = Context.Item.Select(item => new { - item.Id, - item.SubType - }) - .FirstOrDefault(result => result.Id == itemUid)?.SubType; + item.Id, + item.SubType, + }).FirstOrDefault(result => result.Id == itemUid)?.SubType; if (model is not ItemUgc ugcModel) { return null; }