204 lines
5.6 KiB
C#
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();
|
|
}
|
|
}
|