Skip to content

Commit e7c05b3

Browse files
committed
Refactor bank stack withdraw logic
- Reworked bank stacked withdraw flow to be DB-authoritative with cache reconciliation - Added inventory rails to prevent over-withdraw, slot overflow, and multi-stack loss - Implemented merge-first logic with fallback to empty inventory slot when required - Ensured consistent behavior across NPC withdraw, bundled withdraw, and edge cases - Left SQL procedures unchanged; correctness enforced at code boundary - Introduced PlayerSaveDirty flag on Aisling to track unsaved state - Added PlayerDirtySaveComponent to persist only dirty players on a short interval - Dirty flag is set on GiveTo() and cleared after successful DB commit - Avoids unnecessary full-server saves while preserving crash safety guarantees Overall: - Banking is now deterministic, loss-safe, and MMO-consistent - Player saving is more granular, efficient, and intention-driven
1 parent 6057fb1 commit e7c05b3

File tree

12 files changed

+1515
-435
lines changed

12 files changed

+1515
-435
lines changed

Server.Configurations/ZolianPlayers/PlayersDatabaseBuild.sql

Lines changed: 396 additions & 66 deletions
Large diffs are not rendered by default.

Zolian.Server.Base/Database/AislingStorage.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ private async Task PlayerSaveRoutine(Aisling player, CancellationToken ct)
402402
await ExecTvpAsync(conn, tx, "DeBuffSave", "@Debuffs", "dbo.DebuffType", debuffDt, ct).ConfigureAwait(false);
403403

404404
await tx.CommitAsync(ct).ConfigureAwait(false);
405+
406+
// Player has a synced database state
407+
player.PlayerSaveDirty = false;
405408
}
406409
catch (Exception e)
407410
{

Zolian.Server.Base/Enums/ItemEnumConverters.cs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,24 @@ public static string QualityToString(Item.Quality e)
2222
};
2323
}
2424

25+
public static Item.Quality StringToQuality(string? value)
26+
{
27+
return value switch
28+
{
29+
"Damaged" => Item.Quality.Damaged,
30+
"Common" => Item.Quality.Common,
31+
"Uncommon" => Item.Quality.Uncommon,
32+
"Rare" => Item.Quality.Rare,
33+
"Epic" => Item.Quality.Epic,
34+
"Legendary" => Item.Quality.Legendary,
35+
"Forsaken" => Item.Quality.Forsaken,
36+
"Mythic" => Item.Quality.Mythic,
37+
"Primordial" => Item.Quality.Primordial,
38+
"Transcendent" => Item.Quality.Transcendent,
39+
_ => Item.Quality.Common
40+
};
41+
}
42+
2543
public static string PaneToString(Item.ItemPanes e)
2644
{
2745
return e switch
@@ -35,6 +53,19 @@ public static string PaneToString(Item.ItemPanes e)
3553
};
3654
}
3755

56+
public static Item.ItemPanes StringToPane(string? value)
57+
{
58+
return value switch
59+
{
60+
"Ground" => Item.ItemPanes.Ground,
61+
"Inventory" => Item.ItemPanes.Inventory,
62+
"Equip" => Item.ItemPanes.Equip,
63+
"Bank" => Item.ItemPanes.Bank,
64+
"Archived" => Item.ItemPanes.Archived,
65+
_ => Item.ItemPanes.Ground
66+
};
67+
}
68+
3869
public static string ArmorVarianceToString(Item.Variance e)
3970
{
4071
return e switch
@@ -57,6 +88,28 @@ public static string ArmorVarianceToString(Item.Variance e)
5788
};
5889
}
5990

91+
public static Item.Variance StringToArmorVariance(string? value)
92+
{
93+
return value switch
94+
{
95+
"None" => Item.Variance.None,
96+
"Embunement" => Item.Variance.Embunement,
97+
"Blessing" => Item.Variance.Blessing,
98+
"Mana" => Item.Variance.Mana,
99+
"Gramail" => Item.Variance.Gramail,
100+
"Deoch" => Item.Variance.Deoch,
101+
"Ceannlaidir" => Item.Variance.Ceannlaidir,
102+
"Cail" => Item.Variance.Cail,
103+
"Fiosachd" => Item.Variance.Fiosachd,
104+
"Glioca" => Item.Variance.Glioca,
105+
"Luathas" => Item.Variance.Luathas,
106+
"Sgrios" => Item.Variance.Sgrios,
107+
"Reinforcement" => Item.Variance.Reinforcement,
108+
"Spikes" => Item.Variance.Spikes,
109+
_ => Item.Variance.None
110+
};
111+
}
112+
60113
public static string WeaponVarianceToString(Item.WeaponVariance e)
61114
{
62115
return e switch
@@ -79,6 +132,28 @@ public static string WeaponVarianceToString(Item.WeaponVariance e)
79132
};
80133
}
81134

135+
public static Item.WeaponVariance StringToWeaponVariance(string? value)
136+
{
137+
return value switch
138+
{
139+
"None" => Item.WeaponVariance.None,
140+
"Bleeding" => Item.WeaponVariance.Bleeding,
141+
"Rending" => Item.WeaponVariance.Rending,
142+
"Aegis" => Item.WeaponVariance.Aegis,
143+
"Reaping" => Item.WeaponVariance.Reaping,
144+
"Vampirism" => Item.WeaponVariance.Vampirism,
145+
"Ghosting" => Item.WeaponVariance.Ghosting,
146+
"Haste" => Item.WeaponVariance.Haste,
147+
"Gust" => Item.WeaponVariance.Gust,
148+
"Quake" => Item.WeaponVariance.Quake,
149+
"Rain" => Item.WeaponVariance.Rain,
150+
"Flame" => Item.WeaponVariance.Flame,
151+
"Dusk" => Item.WeaponVariance.Dusk,
152+
"Dawn" => Item.WeaponVariance.Dawn,
153+
_ => Item.WeaponVariance.None
154+
};
155+
}
156+
82157
public static string GearEnhancementToString(Item.GearEnhancements e)
83158
{
84159
return e switch
@@ -94,6 +169,21 @@ public static string GearEnhancementToString(Item.GearEnhancements e)
94169
};
95170
}
96171

172+
public static Item.GearEnhancements StringToGearEnhancement(string? value)
173+
{
174+
return value switch
175+
{
176+
"None" => Item.GearEnhancements.None,
177+
"One" => Item.GearEnhancements.One,
178+
"Two" => Item.GearEnhancements.Two,
179+
"Three" => Item.GearEnhancements.Three,
180+
"Four" => Item.GearEnhancements.Four,
181+
"Five" => Item.GearEnhancements.Five,
182+
"Six" => Item.GearEnhancements.Six,
183+
_ => Item.GearEnhancements.None
184+
};
185+
}
186+
97187
public static string ItemMaterialToString(Item.ItemMaterials e)
98188
{
99189
return e switch
@@ -115,4 +205,26 @@ public static string ItemMaterialToString(Item.ItemMaterials e)
115205
_ => "None"
116206
};
117207
}
208+
209+
public static Item.ItemMaterials StringToItemMaterial(string? value)
210+
{
211+
return value switch
212+
{
213+
"None" => Item.ItemMaterials.None,
214+
"Copper" => Item.ItemMaterials.Copper,
215+
"Iron" => Item.ItemMaterials.Iron,
216+
"Steel" => Item.ItemMaterials.Steel,
217+
"Forged" => Item.ItemMaterials.Forged,
218+
"Elven" => Item.ItemMaterials.Elven,
219+
"Dwarven" => Item.ItemMaterials.Dwarven,
220+
"Mythril" => Item.ItemMaterials.Mythril,
221+
"Hybrasyl" => Item.ItemMaterials.Hybrasyl,
222+
"Ebony" => Item.ItemMaterials.Ebony,
223+
"Chaos" => Item.ItemMaterials.Chaos,
224+
"MoonStone" => Item.ItemMaterials.MoonStone,
225+
"SunStone" => Item.ItemMaterials.SunStone,
226+
"Runic" => Item.ItemMaterials.Runic,
227+
_ => Item.ItemMaterials.None
228+
};
229+
}
118230
}

0 commit comments

Comments
 (0)