fix(CS): persist config via non-caching typed context (caching context saved nothing)
Some checks failed
.NET Core / build (push) Has been cancelled

CreateNewContext(config) returns a caching context whose returned config objects
aren't tracked by that context, so SetConfiguration+SaveChanges was a silent no-op
(DB row never updated). Load a fresh change-tracked PlugInConfiguration by id in a
non-caching typed context, rewrite the JSON, save. Adds a confirmation log line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Acentech Dev
2026-07-15 12:30:18 +03:00
parent 9bdd57703f
commit 05a10d495d

View File

@@ -12,6 +12,7 @@ using MUnique.OpenMU.GameLogic.NPC;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Pathfinding;
using MUnique.OpenMU.Persistence;
using MUnique.OpenMU.PlugIns;
/// <summary>
@@ -150,11 +151,18 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
config.PersistedPhaseStartedUtc = context.PhaseStartedUtc;
config.PersistedRegisteredGuilds = context.RegisteredGuilds.ToList();
// Write the plugin's custom-configuration JSON row back to the database (durable across restarts).
// Find our plugin-configuration row via the in-memory config graph to get its id.
var pluginTypeId = typeof(CastleSiegeEventPlugIn).GUID;
using var ctx = gameContext.PersistenceContextProvider.CreateNewContext(gameContext.Configuration);
var configurations = await ctx.GetAsync<PlugInConfiguration>().ConfigureAwait(false);
var row = configurations.FirstOrDefault(c => c.TypeId == pluginTypeId);
var inMemory = gameContext.Configuration.PlugInConfigurations.FirstOrDefault(c => c.TypeId == pluginTypeId);
if (inMemory is null)
{
return;
}
// Load a fresh, change-tracked copy of that row in its own (non-caching) context, rewrite its
// custom-configuration JSON, and save — this is what actually persists to PostgreSQL.
using var ctx = gameContext.PersistenceContextProvider.CreateNewTypedContext(typeof(PlugInConfiguration), false, gameContext.Configuration);
var row = await ctx.GetByIdAsync<PlugInConfiguration>(inMemory.GetId()).ConfigureAwait(false);
if (row is null)
{
return;
@@ -162,6 +170,9 @@ public sealed class CastleSiegeEventPlugIn : IPeriodicTaskPlugIn, ISupportCustom
row.SetConfiguration(config, gameContext.PlugInManager.CustomConfigReferenceHandler);
await ctx.SaveChangesAsync().ConfigureAwait(false);
gameContext.LoggerFactory.CreateLogger<CastleSiegeEventPlugIn>()
.LogInformation("Castle Siege: persisted state (owner={owner}, phase={phase}).", config.PersistedOwnerGuildName ?? "(none)", config.PersistedPhase);
}
catch (Exception ex)
{