feat: add ClaimLink persistence via savegame-backed registry
Adds a ClaimLink data model and ClaimLinkRegistry that loads from and writes to the savegame's keyed data store (protobuf-net, via WorldManager.SaveGame), so claim link state survives restarts without touching vanilla claim data. Also silences nullable warnings on statics that are guaranteed set by StartServerSide before any use, and on TryGetValue out-params guarded by the if.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
using ProtoBuf;
|
||||
|
||||
namespace ClaimLink;
|
||||
|
||||
[ProtoContract]
|
||||
public class ClaimLink
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public int GroupId;
|
||||
}
|
||||
@@ -16,6 +16,10 @@
|
||||
<HintPath>$(COMMANDHOOK)/CommandHook.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="protobuf-net">
|
||||
<HintPath>$(VINTAGE_STORY)/Lib/protobuf-net.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,8 +6,9 @@ namespace ClaimLink;
|
||||
|
||||
public class ClaimLinkModSystem : ModSystem
|
||||
{
|
||||
internal static ILandClaimAPI LandClaimAPI;
|
||||
internal static ILogger Logger;
|
||||
internal static ILandClaimAPI LandClaimAPI = null!;
|
||||
internal static ILogger Logger = null!;
|
||||
internal static ClaimLinkRegistry Registry = null!;
|
||||
internal ClaimLinkCommandListener? cmdListener;
|
||||
|
||||
public override bool ShouldLoad(EnumAppSide forSide) => forSide == EnumAppSide.Server;
|
||||
@@ -16,6 +17,7 @@ public class ClaimLinkModSystem : ModSystem
|
||||
{
|
||||
LandClaimAPI = api.World.Claims;
|
||||
Logger = api.Logger;
|
||||
Registry = new ClaimLinkRegistry(api.WorldManager.SaveGame);
|
||||
|
||||
cmdListener = new ClaimLinkCommandListener();
|
||||
CommandHookModSystem.Register(cmdListener);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
using Vintagestory.API.Server;
|
||||
|
||||
namespace ClaimLink;
|
||||
|
||||
[ProtoContract]
|
||||
public class ClaimLinkData
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public List<ClaimLink> Links = new();
|
||||
}
|
||||
|
||||
public class ClaimLinkRegistry
|
||||
{
|
||||
private const string SaveKey = "claimlink:links";
|
||||
|
||||
private readonly ISaveGame saveGame;
|
||||
private readonly Dictionary<int, ClaimLink> byGroupId = new();
|
||||
|
||||
public ClaimLinkRegistry(ISaveGame saveGame)
|
||||
{
|
||||
this.saveGame = saveGame;
|
||||
|
||||
ClaimLinkData? data = saveGame.GetData<ClaimLinkData?>(SaveKey, null);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
foreach (ClaimLink link in data.Links)
|
||||
byGroupId[link.GroupId] = link;
|
||||
}
|
||||
|
||||
public ClaimLink? Get(int groupId) => byGroupId.TryGetValue(groupId, out ClaimLink? link) ? link : null;
|
||||
|
||||
public void Add(ClaimLink link)
|
||||
{
|
||||
byGroupId[link.GroupId] = link;
|
||||
Save();
|
||||
}
|
||||
|
||||
public void Remove(int groupId)
|
||||
{
|
||||
byGroupId.Remove(groupId);
|
||||
Save();
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
saveGame.StoreData(SaveKey, new ClaimLinkData { Links = new List<ClaimLink>(byGroupId.Values) });
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
||||
{
|
||||
string word = rawArgs.PeekWord();
|
||||
|
||||
if (topLevel.TryGetValue(word, out SubHandler handler))
|
||||
if (topLevel.TryGetValue(word, out SubHandler? handler))
|
||||
{
|
||||
rawArgs.PopWord();
|
||||
handler(args.Caller, rawArgs);
|
||||
@@ -77,7 +77,7 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
||||
{
|
||||
string word = args.PeekWord();
|
||||
|
||||
if (claimSub.TryGetValue(word, out SubHandler handler))
|
||||
if (claimSub.TryGetValue(word, out SubHandler? handler))
|
||||
{
|
||||
args.PopWord();
|
||||
handler(caller, args);
|
||||
|
||||
Reference in New Issue
Block a user