Compare commits
2
Commits
741d283f38
...
fc7e601f5b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc7e601f5b | ||
|
|
a2e4a68f9e |
@@ -1,23 +1,27 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using ProtoBuf;
|
using ProtoBuf;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
|
|
||||||
[ProtoContract]
|
[ProtoContract]
|
||||||
public class ClaimLink
|
public class ClaimLinkSaveData
|
||||||
{
|
{
|
||||||
[ProtoMember(1)]
|
[ProtoMember(1)]
|
||||||
public int GroupId;
|
public List<int> Links = new();
|
||||||
|
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public List<ClaimLinkEntrySaveData> Entries = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ProtoContract]
|
[ProtoContract]
|
||||||
public class ClaimLinkEntry
|
public class ClaimLinkEntrySaveData
|
||||||
{
|
{
|
||||||
[ProtoMember(1)]
|
[ProtoMember(1)]
|
||||||
public string OwnerPlayerUid = "";
|
public string OwnerPlayerUid = "";
|
||||||
|
|
||||||
[ProtoMember(2)]
|
[ProtoMember(2)]
|
||||||
public int ClaimIndex;
|
public int GroupId;
|
||||||
|
|
||||||
[ProtoMember(3)]
|
[ProtoMember(3)]
|
||||||
public int GroupId;
|
public List<int> ClaimIndicies = new();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,10 +212,9 @@ public static class ClaimLinkChatCommand
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextCommandResult? TryResolveClaimLink(PlayerGroup group, out ClaimLink link)
|
private static TextCommandResult? TryResolveClaimLink(PlayerGroup group)
|
||||||
{
|
{
|
||||||
link = ClaimLinkModSystem.Registry.Get(group.Uid)!;
|
return !ClaimLinkModSystem.Registry.Exists(group.Uid)
|
||||||
return link == null
|
|
||||||
? TextCommandResult.Error($"'{group.Name}' is not a claim link.")
|
? TextCommandResult.Error($"'{group.Name}' is not a claim link.")
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
@@ -258,7 +257,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (ClaimLinkModSystem.Registry.Get(group.Uid) != null)
|
if (ClaimLinkModSystem.Registry.Exists(group.Uid))
|
||||||
return TextCommandResult.Error($"'{groupName}' is already a claim link.");
|
return TextCommandResult.Error($"'{groupName}' is already a claim link.");
|
||||||
|
|
||||||
int groupId = group.Uid;
|
int groupId = group.Uid;
|
||||||
@@ -267,7 +266,7 @@ public static class ClaimLinkChatCommand
|
|||||||
$"'{groupName}' will become a claim link.",
|
$"'{groupName}' will become a claim link.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
ClaimLinkModSystem.Registry.Add(new ClaimLink { GroupId = groupId });
|
ClaimLinkModSystem.Registry.Add(groupId);
|
||||||
return TextCommandResult.Success($"'{groupName}' is now a claim link.");
|
return TextCommandResult.Success($"'{groupName}' is now a claim link.");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -303,7 +302,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out ClaimLink link);
|
err = TryResolveClaimLink(group);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -313,6 +312,7 @@ public static class ClaimLinkChatCommand
|
|||||||
return err;
|
return err;
|
||||||
|
|
||||||
string playerUid = player.PlayerUID;
|
string playerUid = player.PlayerUID;
|
||||||
|
int groupId = group.Uid;
|
||||||
|
|
||||||
if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _))
|
if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _))
|
||||||
return TextCommandResult.Error("You do not own that claim.");
|
return TextCommandResult.Error("You do not own that claim.");
|
||||||
@@ -326,7 +326,7 @@ public static class ClaimLinkChatCommand
|
|||||||
$"{claimDesc} will be linked into '{groupName}'.",
|
$"{claimDesc} will be linked into '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
ClaimLinkModSystem.Registry.AddEntry(playerUid, link.GroupId, claimIndex);
|
ClaimLinkModSystem.Registry.AddEntry(playerUid, groupId, claimIndex);
|
||||||
|
|
||||||
return TextCommandResult.Success($"Linked {claimDesc} to '{groupName}'.");
|
return TextCommandResult.Success($"Linked {claimDesc} to '{groupName}'.");
|
||||||
}
|
}
|
||||||
@@ -338,13 +338,13 @@ public static class ClaimLinkChatCommand
|
|||||||
int claimIndex = (int)args[0];
|
int claimIndex = (int)args[0];
|
||||||
string playerUid = args.Caller.Player.PlayerUID;
|
string playerUid = args.Caller.Player.PlayerUID;
|
||||||
|
|
||||||
ClaimLink? link = ClaimLinkModSystem.Registry.FindLinkContaining(playerUid, claimIndex);
|
int? groupId = ClaimLinkModSystem.Registry.FindGroupContaining(playerUid, claimIndex);
|
||||||
if (link == null)
|
if (groupId == null)
|
||||||
return TextCommandResult.Error(
|
return TextCommandResult.Error(
|
||||||
$"Claim {claimIndex} is not linked into any claim link by you."
|
$"Claim {claimIndex} is not linked into any claim link by you."
|
||||||
);
|
);
|
||||||
|
|
||||||
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[link.GroupId].Name;
|
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[(int)groupId].Name;
|
||||||
string claimDesc = DescribeClaim(playerUid, claimIndex);
|
string claimDesc = DescribeClaim(playerUid, claimIndex);
|
||||||
|
|
||||||
return Stage(
|
return Stage(
|
||||||
@@ -352,7 +352,7 @@ public static class ClaimLinkChatCommand
|
|||||||
$"{claimDesc} will be unlinked from '{groupName}'.",
|
$"{claimDesc} will be unlinked from '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
ClaimLinkModSystem.Registry.RemoveEntry(playerUid, link.GroupId, claimIndex);
|
ClaimLinkModSystem.Registry.RemoveEntry(playerUid, (int)groupId, claimIndex);
|
||||||
return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'.");
|
return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'.");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -367,7 +367,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out _);
|
err = TryResolveClaimLink(group);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -407,7 +407,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out _);
|
err = TryResolveClaimLink(group);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -447,7 +447,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out ClaimLink link);
|
err = TryResolveClaimLink(group);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -466,7 +466,7 @@ public static class ClaimLinkChatCommand
|
|||||||
return Stage(
|
return Stage(
|
||||||
playerUid,
|
playerUid,
|
||||||
$"Ownership of '{groupName}' will be transferred to {target.PlayerName}.",
|
$"Ownership of '{groupName}' will be transferred to {target.PlayerName}.",
|
||||||
() => ExecuteTransferOwnership(group, link, target)
|
() => ExecuteTransferOwnership(group, target)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,11 +495,7 @@ public static class ClaimLinkChatCommand
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextCommandResult ExecuteTransferOwnership(
|
private static TextCommandResult ExecuteTransferOwnership(PlayerGroup group, IPlayer target)
|
||||||
PlayerGroup group,
|
|
||||||
ClaimLink link,
|
|
||||||
IPlayer target
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
string oldOwnerUid = group.OwnerUID;
|
string oldOwnerUid = group.OwnerUID;
|
||||||
IPlayer? oldOwner = ClaimLinkModSystem.World.PlayerByUid(oldOwnerUid);
|
IPlayer? oldOwner = ClaimLinkModSystem.World.PlayerByUid(oldOwnerUid);
|
||||||
@@ -515,7 +511,7 @@ public static class ClaimLinkChatCommand
|
|||||||
string notice = $"'{group.Name}' is now owned by {target.PlayerName}.";
|
string notice = $"'{group.Name}' is now owned by {target.PlayerName}.";
|
||||||
|
|
||||||
HashSet<string> notifyUids = ClaimLinkModSystem
|
HashSet<string> notifyUids = ClaimLinkModSystem
|
||||||
.Registry.MemberUidsForGroup(link.GroupId)
|
.Registry.MemberUidsForGroup(group.Uid)
|
||||||
.ToHashSet();
|
.ToHashSet();
|
||||||
notifyUids.Add(oldOwnerUid);
|
notifyUids.Add(oldOwnerUid);
|
||||||
notifyUids.Add(target.PlayerUID);
|
notifyUids.Add(target.PlayerUID);
|
||||||
@@ -540,31 +536,29 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out ClaimLink link);
|
err = TryResolveClaimLink(group);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return TextCommandResult.Success(FormatInfo(groupName, link));
|
return TextCommandResult.Success(FormatInfo(groupName, group.Uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextCommandResult List(TextCommandCallingArgs args)
|
public static TextCommandResult List(TextCommandCallingArgs args)
|
||||||
{
|
{
|
||||||
List<ClaimLink> links = ClaimLinkModSystem
|
List<int> groupIds = ClaimLinkModSystem
|
||||||
.Registry.All.OrderByDescending(l =>
|
.Registry.All.OrderByDescending(id => ClaimLinkModSystem.Registry.MemberCountForGroup(id))
|
||||||
ClaimLinkModSystem.Registry.MemberCountForGroup(l.GroupId)
|
|
||||||
)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (links.Count == 0)
|
if (groupIds.Count == 0)
|
||||||
return TextCommandResult.Success("There are no claim links.");
|
return TextCommandResult.Success("There are no claim links.");
|
||||||
|
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.AppendLine($"Claim links ({links.Count}):");
|
sb.AppendLine($"Claim links ({groupIds.Count}):");
|
||||||
|
|
||||||
foreach (ClaimLink link in links)
|
foreach (int groupId in groupIds)
|
||||||
{
|
{
|
||||||
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[link.GroupId].Name;
|
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[groupId].Name;
|
||||||
int memberCount = ClaimLinkModSystem.Registry.MemberCountForGroup(link.GroupId);
|
int memberCount = ClaimLinkModSystem.Registry.MemberCountForGroup(groupId);
|
||||||
sb.AppendLine($" {groupName}: {memberCount} member{(memberCount == 1 ? "" : "s")}");
|
sb.AppendLine($" {groupName}: {memberCount} member{(memberCount == 1 ? "" : "s")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,20 +580,20 @@ public static class ClaimLinkChatCommand
|
|||||||
return string.IsNullOrEmpty(claim.Description) ? $"claim {claimIndex}" : claim.Description;
|
return string.IsNullOrEmpty(claim.Description) ? $"claim {claimIndex}" : claim.Description;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string FormatInfo(string groupName, ClaimLink link)
|
private static string FormatInfo(string groupName, int groupId)
|
||||||
{
|
{
|
||||||
int memberCount = ClaimLinkModSystem.Registry.MemberCountForGroup(link.GroupId);
|
int memberCount = ClaimLinkModSystem.Registry.MemberCountForGroup(groupId);
|
||||||
|
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.AppendLine(
|
sb.AppendLine(
|
||||||
$"Claim link '{groupName}' ({memberCount} member{(memberCount == 1 ? "" : "s")}):"
|
$"Claim link '{groupName}' ({memberCount} member{(memberCount == 1 ? "" : "s")}):"
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach (string uid in ClaimLinkModSystem.Registry.MemberUidsForGroup(link.GroupId))
|
foreach (string uid in ClaimLinkModSystem.Registry.MemberUidsForGroup(groupId))
|
||||||
{
|
{
|
||||||
string name = ClaimLinkModSystem.World.PlayerByUid(uid)?.PlayerName ?? uid;
|
string name = ClaimLinkModSystem.World.PlayerByUid(uid)?.PlayerName ?? uid;
|
||||||
IEnumerable<string> claims = ClaimLinkModSystem
|
IEnumerable<string> claims = ClaimLinkModSystem
|
||||||
.Registry.ClaimsForPlayerInGroup(uid, link.GroupId)
|
.Registry.ClaimsForPlayerInGroup(uid, groupId)
|
||||||
.Select(i => DescribeClaim(uid, i));
|
.Select(i => DescribeClaim(uid, i));
|
||||||
sb.AppendLine($" {name}: [{string.Join(", ", claims)}]");
|
sb.AppendLine($" {name}: [{string.Join(", ", claims)}]");
|
||||||
}
|
}
|
||||||
@@ -631,7 +625,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out ClaimLink link);
|
err = TryResolveClaimLink(group);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -643,7 +637,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return ExecuteTransferOwnership(group, link, target);
|
return ExecuteTransferOwnership(group, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) =>
|
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) =>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class ClaimLinkModSystem : ModSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool TryResolveOwnedClaim(
|
public static bool TryResolveOwnedClaim(
|
||||||
string ownerPlayerUid,
|
string ownerPlayerUid,
|
||||||
int claimIndex,
|
int claimIndex,
|
||||||
out LandClaim? claim
|
out LandClaim? claim
|
||||||
|
|||||||
+118
-101
@@ -1,171 +1,188 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using ProtoBuf;
|
|
||||||
using Vintagestory.API.Server;
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
|
|
||||||
[ProtoContract]
|
|
||||||
public class ClaimLinkData
|
|
||||||
{
|
|
||||||
[ProtoMember(1)]
|
|
||||||
public List<ClaimLink> Links = new();
|
|
||||||
|
|
||||||
[ProtoMember(2)]
|
|
||||||
public List<ClaimLinkEntry> Entries = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ClaimLinkRegistry
|
public class ClaimLinkRegistry
|
||||||
{
|
{
|
||||||
private const string SaveKey = "claimlink:links";
|
private const string SaveKey = "claimlink:claimlinkdata";
|
||||||
|
|
||||||
private readonly ISaveGame saveGame;
|
private readonly ISaveGame saveGame;
|
||||||
private readonly Dictionary<int, ClaimLink> byGroupId = new();
|
|
||||||
|
|
||||||
private readonly Dictionary<string, Dictionary<int, List<int>>> byPlayer = new();
|
private readonly List<int> claimLinks = new();
|
||||||
|
private readonly Dictionary<string, Dictionary<int, List<int>>> entries = new();
|
||||||
|
|
||||||
public ClaimLinkRegistry(ISaveGame saveGame)
|
public ClaimLinkRegistry(ISaveGame saveGame)
|
||||||
{
|
{
|
||||||
this.saveGame = saveGame;
|
this.saveGame = saveGame;
|
||||||
|
|
||||||
ClaimLinkData? data = saveGame.GetData<ClaimLinkData?>(SaveKey, null);
|
ClaimLinkSaveData? data = saveGame.GetData<ClaimLinkSaveData?>(SaveKey, null);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (ClaimLink link in data.Links)
|
claimLinks.AddRange(data.Links);
|
||||||
byGroupId[link.GroupId] = link;
|
|
||||||
|
|
||||||
foreach (ClaimLinkEntry entry in data.Entries)
|
foreach (var entry in data.Entries)
|
||||||
GetOrCreateIndices(entry.OwnerPlayerUid, entry.GroupId).Add(entry.ClaimIndex);
|
{
|
||||||
|
if (!entries.ContainsKey(entry.OwnerPlayerUid))
|
||||||
|
entries[entry.OwnerPlayerUid] = new Dictionary<int, List<int>>();
|
||||||
|
|
||||||
|
entries[entry.OwnerPlayerUid][entry.GroupId] = new(entry.ClaimIndicies);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClaimLink? Get(int groupId) =>
|
public IReadOnlyList<int> All => claimLinks;
|
||||||
byGroupId.TryGetValue(groupId, out ClaimLink? link) ? link : null;
|
|
||||||
|
|
||||||
public IReadOnlyCollection<ClaimLink> All => byGroupId.Values;
|
public bool Exists(int groupId) => claimLinks.Contains(groupId);
|
||||||
|
|
||||||
public void Add(ClaimLink link)
|
public void Add(int groupId)
|
||||||
{
|
{
|
||||||
byGroupId[link.GroupId] = link;
|
claimLinks.Add(groupId);
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(int groupId)
|
public void Remove(int groupId)
|
||||||
{
|
{
|
||||||
byGroupId.Remove(groupId);
|
claimLinks.Remove(groupId);
|
||||||
|
foreach (var groups in entries.Values)
|
||||||
List<string> emptyPlayerUids = new();
|
groups.Remove(groupId);
|
||||||
foreach (KeyValuePair<string, Dictionary<int, List<int>>> playerEntry in byPlayer)
|
Prune();
|
||||||
{
|
|
||||||
playerEntry.Value.Remove(groupId);
|
|
||||||
if (playerEntry.Value.Count == 0)
|
|
||||||
emptyPlayerUids.Add(playerEntry.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string uid in emptyPlayerUids)
|
|
||||||
byPlayer.Remove(uid);
|
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsClaimLinked(string ownerPlayerUid, int claimIndex) =>
|
public bool IsClaimLinked(string uid, int claimIndex) =>
|
||||||
FindLinkContaining(ownerPlayerUid, claimIndex) != null;
|
FindGroupContaining(uid, claimIndex) != null;
|
||||||
|
|
||||||
public ClaimLink? FindLinkContaining(string ownerPlayerUid, int claimIndex)
|
public int? FindGroupContaining(string uid, int claimIndex)
|
||||||
{
|
{
|
||||||
if (!byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup))
|
if (!entries.TryGetValue(uid, out var groups))
|
||||||
return null;
|
return null;
|
||||||
|
foreach (var (groupId, claims) in groups)
|
||||||
foreach (KeyValuePair<int, List<int>> entry in perGroup)
|
if (claims.Contains(claimIndex))
|
||||||
if (entry.Value.Contains(claimIndex))
|
return groupId;
|
||||||
return Get(entry.Key);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEntry(string ownerPlayerUid, int groupId, int claimIndex)
|
public void AddEntry(string uid, int groupId, int claimIndex)
|
||||||
{
|
{
|
||||||
GetOrCreateIndices(ownerPlayerUid, groupId).Add(claimIndex);
|
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();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveEntry(string ownerPlayerUid, int groupId, int claimIndex)
|
public void RemoveEntry(string uid, int groupId, int claimIndex)
|
||||||
{
|
{
|
||||||
if (
|
if (entries.TryGetValue(uid, out var groups) && groups.TryGetValue(groupId, out var claims))
|
||||||
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
claims.Remove(claimIndex);
|
||||||
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
Prune();
|
||||||
)
|
|
||||||
{
|
|
||||||
indices.Remove(claimIndex);
|
|
||||||
if (indices.Count == 0)
|
|
||||||
perGroup.Remove(groupId);
|
|
||||||
|
|
||||||
if (perGroup.Count == 0)
|
|
||||||
byPlayer.Remove(ownerPlayerUid);
|
|
||||||
}
|
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasAnyEntry(string ownerPlayerUid, int groupId) =>
|
public void ClaimRemoved(string uid, int removedIndex)
|
||||||
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
{
|
||||||
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
if (!entries.TryGetValue(uid, out var groups))
|
||||||
&& indices.Count > 0;
|
return;
|
||||||
|
|
||||||
public void RemoveAllForPlayerInGroup(string ownerPlayerUid, int groupId)
|
foreach (var claims in groups.Values)
|
||||||
{
|
{
|
||||||
if (byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup))
|
claims.Remove(removedIndex);
|
||||||
{
|
for (int i = 0; i < claims.Count; i++)
|
||||||
perGroup.Remove(groupId);
|
if (claims[i] > removedIndex)
|
||||||
if (perGroup.Count == 0)
|
claims[i]--;
|
||||||
byPlayer.Remove(ownerPlayerUid);
|
|
||||||
}
|
}
|
||||||
|
Prune();
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> MemberUidsForGroup(int groupId) =>
|
public void ClaimSaved(string uid, int claimIndex)
|
||||||
byPlayer
|
{
|
||||||
.Where(kv => kv.Value.TryGetValue(groupId, out List<int>? indices) && indices.Count > 0)
|
if (!entries.TryGetValue(uid, out var groups))
|
||||||
.Select(kv => kv.Key);
|
return;
|
||||||
|
|
||||||
public int MemberCountForGroup(int groupId) => MemberUidsForGroup(groupId).Count();
|
int count = 0;
|
||||||
|
foreach (Vintagestory.API.Common.LandClaim c in ClaimLinkModSystem.LandClaimAPI.All)
|
||||||
|
if (c.OwnedByPlayerUid == uid)
|
||||||
|
count++;
|
||||||
|
int newIndex = count - 1;
|
||||||
|
|
||||||
public IReadOnlyList<int> ClaimsForPlayerInGroup(string ownerPlayerUid, int groupId) =>
|
foreach (var claims in groups.Values)
|
||||||
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
{
|
||||||
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
int i = claims.IndexOf(claimIndex);
|
||||||
? indices
|
|
||||||
|
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 IEnumerable<string> MemberUidsForGroup(int groupId)
|
||||||
|
{
|
||||||
|
foreach (var (uid, groups) in entries)
|
||||||
|
if (groups.TryGetValue(groupId, out var claims) && claims.Count > 0)
|
||||||
|
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>();
|
: System.Array.Empty<int>();
|
||||||
|
|
||||||
private List<int> GetOrCreateIndices(string playerUid, int groupId)
|
private void Prune()
|
||||||
{
|
{
|
||||||
if (!byPlayer.TryGetValue(playerUid, out Dictionary<int, List<int>>? perGroup))
|
List<string>? empty = null;
|
||||||
byPlayer[playerUid] = perGroup = new Dictionary<int, List<int>>();
|
foreach (var (uid, groups) in entries)
|
||||||
|
if (groups.Count == 0)
|
||||||
if (!perGroup.TryGetValue(groupId, out List<int>? indices))
|
(empty ??= new()).Add(uid);
|
||||||
perGroup[groupId] = indices = new List<int>();
|
if (empty != null)
|
||||||
|
foreach (var uid in empty)
|
||||||
return indices;
|
entries.Remove(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
List<ClaimLinkEntry> entries = new();
|
var entryList = new List<ClaimLinkEntrySaveData>();
|
||||||
foreach (KeyValuePair<string, Dictionary<int, List<int>>> playerEntry in byPlayer)
|
foreach (var (uid, groups) in entries)
|
||||||
foreach (KeyValuePair<int, List<int>> groupEntry in playerEntry.Value)
|
foreach (var (groupId, claims) in groups)
|
||||||
foreach (int index in groupEntry.Value)
|
entryList.Add(
|
||||||
entries.Add(
|
new ClaimLinkEntrySaveData
|
||||||
new ClaimLinkEntry
|
|
||||||
{
|
{
|
||||||
OwnerPlayerUid = playerEntry.Key,
|
OwnerPlayerUid = uid,
|
||||||
GroupId = groupEntry.Key,
|
GroupId = groupId,
|
||||||
ClaimIndex = index,
|
ClaimIndicies = new(claims),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
saveGame.StoreData(
|
saveGame.StoreData(
|
||||||
SaveKey,
|
SaveKey,
|
||||||
new ClaimLinkData { Links = new List<ClaimLink>(byGroupId.Values), Entries = entries }
|
new ClaimLinkSaveData { Links = claimLinks, Entries = entryList }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,39 +15,23 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
|
|
||||||
internal static Dictionary<string, int> PendingLoads = new Dictionary<string, int>();
|
internal static Dictionary<string, int> PendingLoads = new Dictionary<string, int>();
|
||||||
|
|
||||||
private delegate void SubHandler(Caller caller, CmdArgs args, TextCommandResult? result);
|
private delegate void SubHandler(Caller caller, CmdArgs args);
|
||||||
|
|
||||||
private static readonly Dictionary<string, SubHandler> topLevel = new()
|
private static readonly Dictionary<string, SubHandler> topLevel = new()
|
||||||
{
|
{
|
||||||
["claim"] = Claim,
|
["claim"] = Claim,
|
||||||
["free"] = Free,
|
["free"] = Free,
|
||||||
["info"] = Info,
|
|
||||||
["list"] = List,
|
|
||||||
["adminfree"] = AdminFree,
|
["adminfree"] = AdminFree,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<string, SubHandler> claimSub = new()
|
private static readonly Dictionary<string, SubHandler> claimSub = new()
|
||||||
{
|
{
|
||||||
["load"] = ClaimLoad,
|
["load"] = ClaimLoad,
|
||||||
["new"] = ClaimNew,
|
|
||||||
["grant"] = ClaimGrant,
|
|
||||||
["revoke"] = ClaimRevoke,
|
|
||||||
["grantgroup"] = ClaimGrantGroup,
|
|
||||||
["revokegroup"] = ClaimRevokeGroup,
|
|
||||||
["start"] = ClaimStart,
|
|
||||||
["end"] = ClaimEnd,
|
|
||||||
["grow"] = ClaimGrow,
|
|
||||||
["shrink"] = ClaimShrink,
|
|
||||||
["add"] = ClaimAdd,
|
|
||||||
["allowuseeveryone"] = ClaimAllowUseEveryone,
|
|
||||||
["plevel"] = ClaimPLevel,
|
|
||||||
["fullheight"] = ClaimFullHeight,
|
|
||||||
["save"] = ClaimSave,
|
["save"] = ClaimSave,
|
||||||
["cancel"] = ClaimCancel,
|
["cancel"] = ClaimCancel,
|
||||||
["download"] = ClaimDownload,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private static void Dispatch(TextCommandCallingArgs args, TextCommandResult? result)
|
private static void Dispatch(TextCommandCallingArgs args)
|
||||||
{
|
{
|
||||||
CmdArgs rawArgs = args.RawArgs.Clone();
|
CmdArgs rawArgs = args.RawArgs.Clone();
|
||||||
|
|
||||||
@@ -58,7 +42,7 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
if (topLevel.TryGetValue(word, out SubHandler? handler))
|
if (topLevel.TryGetValue(word, out SubHandler? handler))
|
||||||
{
|
{
|
||||||
rawArgs.PopWord();
|
rawArgs.PopWord();
|
||||||
handler(args.Caller, rawArgs, result);
|
handler(args.Caller, rawArgs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -69,16 +53,13 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
|
|
||||||
private TextCommandResult? Before(TextCommandCallingArgs args)
|
private TextCommandResult? Before(TextCommandCallingArgs args)
|
||||||
{
|
{
|
||||||
Dispatch(args, null);
|
Dispatch(args);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void After(TextCommandCallingArgs args, TextCommandResult result)
|
private void After(TextCommandCallingArgs args, TextCommandResult result) { }
|
||||||
{
|
|
||||||
Dispatch(args, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Claim(Caller caller, CmdArgs args, TextCommandResult? result)
|
private static void Claim(Caller caller, CmdArgs args)
|
||||||
{
|
{
|
||||||
string? word = args.PeekWord();
|
string? word = args.PeekWord();
|
||||||
if (word == null)
|
if (word == null)
|
||||||
@@ -87,46 +68,46 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
if (claimSub.TryGetValue(word, out SubHandler? handler))
|
if (claimSub.TryGetValue(word, out SubHandler? handler))
|
||||||
{
|
{
|
||||||
args.PopWord();
|
args.PopWord();
|
||||||
handler(caller, args, result);
|
handler(caller, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ClaimLoad(Caller caller, CmdArgs args, TextCommandResult? result)
|
private static void ClaimSave(Caller caller, CmdArgs args)
|
||||||
{
|
{
|
||||||
int? claimIndex = args.PopInt();
|
|
||||||
if (caller.Player == null)
|
if (caller.Player == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ClaimLinkModSystem.Logger.Notification(
|
string uid = caller.Player.PlayerUID;
|
||||||
"CLAIM LOAD {0}",
|
if (!PendingLoads.TryGetValue(uid, out int pendingIndex))
|
||||||
result == null ? "BEFORE" : "AFTER"
|
return;
|
||||||
);
|
|
||||||
|
ClaimLinkModSystem.Registry.ClaimSaved(uid, pendingIndex);
|
||||||
|
PendingLoads.Remove(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ClaimLoad(Caller caller, CmdArgs args)
|
||||||
|
{
|
||||||
|
int? claimIndex = args.PopInt();
|
||||||
|
if (caller.Player == null || claimIndex == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
claimIndex != null
|
ClaimLinkModSystem.TryResolveOwnedClaim(caller.Player.PlayerUID, (int)claimIndex, out _)
|
||||||
&& ClaimLinkModSystem.TryResolveOwnedClaim(
|
|
||||||
caller.Player.PlayerUID,
|
|
||||||
(int)claimIndex,
|
|
||||||
out _
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
{
|
|
||||||
PendingLoads[caller.Player.PlayerUID] = (int)claimIndex;
|
PendingLoads[caller.Player.PlayerUID] = (int)claimIndex;
|
||||||
ClaimLinkModSystem.Logger.Notification($"Claim Index Loaded = {claimIndex}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ClaimCancel(Caller caller, CmdArgs args, TextCommandResult? result)
|
private static void ClaimCancel(Caller caller, CmdArgs args)
|
||||||
{
|
{
|
||||||
if (result != null || caller.Player == null)
|
if (caller.Player == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PendingLoads.Remove(caller.Player.PlayerUID);
|
PendingLoads.Remove(caller.Player.PlayerUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Free(Caller caller, CmdArgs args, TextCommandResult? result)
|
private static void Free(Caller caller, CmdArgs args)
|
||||||
{
|
{
|
||||||
if (result == null || result.Status != EnumCommandStatus.Success || caller.Player == null)
|
if (caller.Player == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string uid = caller.Player.PlayerUID;
|
string uid = caller.Player.PlayerUID;
|
||||||
@@ -137,19 +118,10 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
if (args.PopWord() != "confirm")
|
if (args.PopWord() != "confirm")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ClaimLink? link = ClaimLinkModSystem.Registry.FindLinkContaining(uid, (int)claimIndex);
|
ClaimLinkModSystem.Registry.ClaimRemoved(uid, (int)claimIndex);
|
||||||
ClaimLinkModSystem.Logger.Notification(
|
|
||||||
link != null
|
|
||||||
? $"claimlink: freed claim {claimIndex} for {uid} was linked to group {link.GroupId}"
|
|
||||||
: $"claimlink: freed claim {claimIndex} for {uid} was not linked"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Info(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
private static void AdminFree(Caller caller, CmdArgs args)
|
||||||
|
|
||||||
private static void List(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void AdminFree(Caller caller, CmdArgs args, TextCommandResult? result)
|
|
||||||
{
|
{
|
||||||
if (caller.Player == null)
|
if (caller.Player == null)
|
||||||
return;
|
return;
|
||||||
@@ -157,64 +129,12 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
LandClaim[] claims = ClaimLinkModSystem.LandClaimAPI.Get(
|
LandClaim[] claims = ClaimLinkModSystem.LandClaimAPI.Get(
|
||||||
caller.Player.Entity.Pos.AsBlockPos
|
caller.Player.Entity.Pos.AsBlockPos
|
||||||
);
|
);
|
||||||
string phase = result == null ? "before" : $"after (status={result.Status})";
|
|
||||||
|
|
||||||
ClaimLinkModSystem.Logger.Notification(
|
|
||||||
$"claimlink: adminfree {phase}: {claims.Length} claim(s) at position"
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach (LandClaim c in claims)
|
foreach (LandClaim c in claims)
|
||||||
ClaimLinkModSystem.Logger.Notification($"claimlink: owned by {c.OwnedByPlayerUid}");
|
if (ClaimLinkModSystem.TryResolveClaimIndex(c.OwnedByPlayerUid, c, out int claimIndex))
|
||||||
|
ClaimLinkModSystem.Registry.ClaimRemoved(c.OwnedByPlayerUid, claimIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ClaimNew(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimGrant(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimRevoke(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimGrantGroup(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimRevokeGroup(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimStart(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimEnd(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimGrow(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimShrink(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimAdd(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimAllowUseEveryone(
|
|
||||||
Caller caller,
|
|
||||||
CmdArgs args,
|
|
||||||
TextCommandResult? result
|
|
||||||
) { }
|
|
||||||
|
|
||||||
private static void ClaimPLevel(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimFullHeight(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
private static void ClaimSave(Caller caller, CmdArgs args, TextCommandResult? result)
|
|
||||||
{
|
|
||||||
if (result == null || result.Status != EnumCommandStatus.Success || caller.Player == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
string uid = caller.Player.PlayerUID;
|
|
||||||
int? claimIndex = args.PopInt();
|
|
||||||
|
|
||||||
if (PendingLoads.TryGetValue(uid, out int pendingIndex) && claimIndex != pendingIndex)
|
|
||||||
ClaimLinkModSystem.Logger.Error(
|
|
||||||
$"claimlink: claim save index mismatch for {uid}: pending={pendingIndex} saved={claimIndex}"
|
|
||||||
);
|
|
||||||
|
|
||||||
PendingLoads.Remove(uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ClaimDownload(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
|
||||||
|
|
||||||
internal static void OnPlayerDisconnect(IServerPlayer player)
|
internal static void OnPlayerDisconnect(IServerPlayer player)
|
||||||
{
|
{
|
||||||
PendingLoads.Remove(player.PlayerUID);
|
PendingLoads.Remove(player.PlayerUID);
|
||||||
|
|||||||
Reference in New Issue
Block a user