172 lines
5.3 KiB
C#
172 lines
5.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ProtoBuf;
|
|
using Vintagestory.API.Server;
|
|
|
|
namespace ClaimLink;
|
|
|
|
[ProtoContract]
|
|
public class ClaimLinkData
|
|
{
|
|
[ProtoMember(1)]
|
|
public List<ClaimLink> Links = new();
|
|
|
|
[ProtoMember(2)]
|
|
public List<ClaimLinkEntry> Entries = new();
|
|
}
|
|
|
|
public class ClaimLinkRegistry
|
|
{
|
|
private const string SaveKey = "claimlink:links";
|
|
|
|
private readonly ISaveGame saveGame;
|
|
private readonly Dictionary<int, ClaimLink> byGroupId = new();
|
|
|
|
private readonly Dictionary<string, Dictionary<int, List<int>>> byPlayer = 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;
|
|
|
|
foreach (ClaimLinkEntry entry in data.Entries)
|
|
GetOrCreateIndices(entry.OwnerPlayerUid, entry.GroupId).Add(entry.ClaimIndex);
|
|
}
|
|
|
|
public ClaimLink? Get(int groupId) =>
|
|
byGroupId.TryGetValue(groupId, out ClaimLink? link) ? link : null;
|
|
|
|
public IReadOnlyCollection<ClaimLink> All => byGroupId.Values;
|
|
|
|
public void Add(ClaimLink link)
|
|
{
|
|
byGroupId[link.GroupId] = link;
|
|
Save();
|
|
}
|
|
|
|
public void Remove(int groupId)
|
|
{
|
|
byGroupId.Remove(groupId);
|
|
|
|
List<string> emptyPlayerUids = new();
|
|
foreach (KeyValuePair<string, Dictionary<int, List<int>>> playerEntry in byPlayer)
|
|
{
|
|
playerEntry.Value.Remove(groupId);
|
|
if (playerEntry.Value.Count == 0)
|
|
emptyPlayerUids.Add(playerEntry.Key);
|
|
}
|
|
|
|
foreach (string uid in emptyPlayerUids)
|
|
byPlayer.Remove(uid);
|
|
|
|
Save();
|
|
}
|
|
|
|
public bool IsClaimLinked(string ownerPlayerUid, int localIndex) =>
|
|
FindLinkContaining(ownerPlayerUid, localIndex) != null;
|
|
|
|
public ClaimLink? FindLinkContaining(string ownerPlayerUid, int localIndex)
|
|
{
|
|
if (!byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup))
|
|
return null;
|
|
|
|
foreach (KeyValuePair<int, List<int>> entry in perGroup)
|
|
if (entry.Value.Contains(localIndex))
|
|
return Get(entry.Key);
|
|
|
|
return null;
|
|
}
|
|
|
|
public void AddEntry(string ownerPlayerUid, int groupId, int localClaimIndex)
|
|
{
|
|
GetOrCreateIndices(ownerPlayerUid, groupId).Add(localClaimIndex);
|
|
Save();
|
|
}
|
|
|
|
public void RemoveEntry(string ownerPlayerUid, int groupId, int localClaimIndex)
|
|
{
|
|
if (
|
|
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
|
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
|
)
|
|
{
|
|
indices.Remove(localClaimIndex);
|
|
if (indices.Count == 0)
|
|
perGroup.Remove(groupId);
|
|
|
|
if (perGroup.Count == 0)
|
|
byPlayer.Remove(ownerPlayerUid);
|
|
}
|
|
|
|
Save();
|
|
}
|
|
|
|
public bool HasAnyEntry(string ownerPlayerUid, int groupId) =>
|
|
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
|
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
|
&& indices.Count > 0;
|
|
|
|
public void RemoveAllForPlayerInGroup(string ownerPlayerUid, int groupId)
|
|
{
|
|
if (byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup))
|
|
{
|
|
perGroup.Remove(groupId);
|
|
if (perGroup.Count == 0)
|
|
byPlayer.Remove(ownerPlayerUid);
|
|
}
|
|
|
|
Save();
|
|
}
|
|
|
|
public IEnumerable<string> MemberUidsForGroup(int groupId) =>
|
|
byPlayer
|
|
.Where(kv => kv.Value.TryGetValue(groupId, out List<int>? indices) && indices.Count > 0)
|
|
.Select(kv => kv.Key);
|
|
|
|
public int MemberCountForGroup(int groupId) => MemberUidsForGroup(groupId).Count();
|
|
|
|
public IReadOnlyList<int> ClaimsForPlayerInGroup(string ownerPlayerUid, int groupId) =>
|
|
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
|
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
|
? indices
|
|
: System.Array.Empty<int>();
|
|
|
|
private List<int> GetOrCreateIndices(string playerUid, int groupId)
|
|
{
|
|
if (!byPlayer.TryGetValue(playerUid, out Dictionary<int, List<int>>? perGroup))
|
|
byPlayer[playerUid] = perGroup = new Dictionary<int, List<int>>();
|
|
|
|
if (!perGroup.TryGetValue(groupId, out List<int>? indices))
|
|
perGroup[groupId] = indices = new List<int>();
|
|
|
|
return indices;
|
|
}
|
|
|
|
public void Save()
|
|
{
|
|
List<ClaimLinkEntry> entries = new();
|
|
foreach (KeyValuePair<string, Dictionary<int, List<int>>> playerEntry in byPlayer)
|
|
foreach (KeyValuePair<int, List<int>> groupEntry in playerEntry.Value)
|
|
foreach (int index in groupEntry.Value)
|
|
entries.Add(
|
|
new ClaimLinkEntry
|
|
{
|
|
OwnerPlayerUid = playerEntry.Key,
|
|
GroupId = groupEntry.Key,
|
|
ClaimIndex = index,
|
|
}
|
|
);
|
|
|
|
saveGame.StoreData(
|
|
SaveKey,
|
|
new ClaimLinkData { Links = new List<ClaimLink>(byGroupId.Values), Entries = entries }
|
|
);
|
|
}
|
|
}
|