Files
ClaimLink/ClaimLink/ClaimLinkRegistry.cs
T

204 lines
5.6 KiB
C#

using System.Collections.Generic;
using Vintagestory.API.Server;
namespace ClaimLink;
public class ClaimLinkRegistry
{
private const string SaveKey = "claimlink:claimlinkdata";
private readonly ISaveGame saveGame;
private readonly List<int> claimLinks = new();
private readonly Dictionary<string, Dictionary<int, List<int>>> entries = new();
public ClaimLinkRegistry(ISaveGame saveGame)
{
this.saveGame = saveGame;
ClaimLinkSaveData? data = saveGame.GetData<ClaimLinkSaveData?>(SaveKey, null);
if (data == null)
return;
claimLinks.AddRange(data.Links);
foreach (var entry in data.Entries)
{
if (!entries.ContainsKey(entry.OwnerPlayerUid))
entries[entry.OwnerPlayerUid] = new Dictionary<int, List<int>>();
entries[entry.OwnerPlayerUid][entry.GroupId] = new(entry.ClaimIndicies);
}
}
public IReadOnlyList<int> All => claimLinks;
public bool Exists(int groupId) => claimLinks.Contains(groupId);
public void Add(int groupId)
{
claimLinks.Add(groupId);
Save();
}
public void Remove(int groupId)
{
claimLinks.Remove(groupId);
foreach (var groups in entries.Values)
groups.Remove(groupId);
Prune();
Save();
}
public bool IsClaimLinked(string uid, int claimIndex) =>
FindGroupContaining(uid, claimIndex) != null;
public int? FindGroupContaining(string uid, int claimIndex)
{
if (!entries.TryGetValue(uid, out var groups))
return null;
foreach (var (groupId, claims) in groups)
if (claims.Contains(claimIndex))
return groupId;
return null;
}
public bool AddEntry(string uid, int groupId, int claimIndex)
{
if (CommandListener.PendingLoads.ContainsKey(uid))
return false;
if (!Exists(groupId))
return false;
if (!entries.TryGetValue(uid, out var groups))
entries[uid] = groups = new();
if (!groups.TryGetValue(groupId, out var claims))
groups[groupId] = claims = new();
claims.Add(claimIndex);
Save();
return true;
}
public void RemoveEntry(string uid, int groupId, int claimIndex)
{
if (entries.TryGetValue(uid, out var groups) && groups.TryGetValue(groupId, out var claims))
claims.Remove(claimIndex);
Prune();
Save();
}
public void ClaimRemoved(string uid, int removedIndex)
{
if (!entries.TryGetValue(uid, out var groups))
return;
foreach (var claims in groups.Values)
{
claims.Remove(removedIndex);
for (int i = 0; i < claims.Count; i++)
if (claims[i] > removedIndex)
claims[i]--;
}
Prune();
Save();
}
public void ClaimSaved(string uid, int claimIndex)
{
if (!entries.TryGetValue(uid, out var groups))
return;
int count = 0;
foreach (Vintagestory.API.Common.LandClaim c in ClaimLinkModSystem.LandClaimAPI.All)
if (c.OwnedByPlayerUid == uid)
count++;
int newIndex = count - 1;
foreach (var claims in groups.Values)
{
int i = claims.IndexOf(claimIndex);
for (int j = 0; j < claims.Count; j++)
if (j != i && claims[j] > claimIndex)
claims[j]--;
if (i >= 0)
claims[i] = newIndex;
}
Save();
}
public bool HasAnyEntry(string uid, int groupId) =>
entries.TryGetValue(uid, out var groups)
&& groups.TryGetValue(groupId, out var claims)
&& claims.Count > 0;
public void RemoveAllForPlayerInGroup(string uid, int groupId)
{
if (entries.TryGetValue(uid, out var groups))
groups.Remove(groupId);
Prune();
Save();
}
public void ClearAllForPlayer(string uid)
{
entries.Remove(uid);
Save();
}
public IEnumerable<string> MemberUidsForGroup(int groupId)
{
foreach (var (uid, groups) in entries)
if (groups.ContainsKey(groupId))
yield return uid;
}
public int MemberCountForGroup(int groupId)
{
int count = 0;
foreach (var uid in MemberUidsForGroup(groupId))
count++;
return count;
}
public IReadOnlyList<int> ClaimsForPlayerInGroup(string uid, int groupId) =>
entries.TryGetValue(uid, out var groups) && groups.TryGetValue(groupId, out var claims)
? claims
: System.Array.Empty<int>();
private void Prune()
{
List<string>? empty = null;
foreach (var (uid, groups) in entries)
if (groups.Count == 0)
(empty ??= new()).Add(uid);
if (empty != null)
foreach (var uid in empty)
entries.Remove(uid);
}
public void Save()
{
var entryList = new List<ClaimLinkEntrySaveData>();
foreach (var (uid, groups) in entries)
foreach (var (groupId, claims) in groups)
entryList.Add(
new ClaimLinkEntrySaveData
{
OwnerPlayerUid = uid,
GroupId = groupId,
ClaimIndicies = new(claims),
}
);
saveGame.StoreData(
SaveKey,
new ClaimLinkSaveData { Links = claimLinks, Entries = entryList }
);
ClaimLinkBufferIndex.Rebuild();
}
}