Compare commits
5
Commits
1c0a5f88a1
...
f699cd6d54
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f699cd6d54 | ||
|
|
94b6723456 | ||
|
|
de2026d239 | ||
|
|
fffc046126 | ||
|
|
eaa79f8f52 |
+11
-12
@@ -1,24 +1,23 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using ProtoBuf;
|
using ProtoBuf;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
|
|
||||||
[ProtoContract]
|
|
||||||
public class ClaimLinkMember
|
|
||||||
{
|
|
||||||
[ProtoMember(1)]
|
|
||||||
public string OwnerPlayerUid = "";
|
|
||||||
|
|
||||||
[ProtoMember(2)]
|
|
||||||
public List<int> LocalClaimIndices = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
[ProtoContract]
|
[ProtoContract]
|
||||||
public class ClaimLink
|
public class ClaimLink
|
||||||
{
|
{
|
||||||
[ProtoMember(1)]
|
[ProtoMember(1)]
|
||||||
public int GroupId;
|
public int GroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ProtoContract]
|
||||||
|
public class ClaimLinkEntry
|
||||||
|
{
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public string OwnerPlayerUid = "";
|
||||||
|
|
||||||
[ProtoMember(2)]
|
[ProtoMember(2)]
|
||||||
public List<ClaimLinkMember> Members = new();
|
public int ClaimIndex;
|
||||||
|
|
||||||
|
[ProtoMember(3)]
|
||||||
|
public int GroupId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Vintagestory.API.Common;
|
using Vintagestory.API.Common;
|
||||||
|
using Vintagestory.API.Config;
|
||||||
using Vintagestory.API.Server;
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
@@ -117,7 +118,7 @@ public static class ClaimLinkChatCommand
|
|||||||
new(
|
new(
|
||||||
new[] { "transferownership", "transfer", "to" },
|
new[] { "transferownership", "transfer", "to" },
|
||||||
"Transfer ownership of the claim link to another player.",
|
"Transfer ownership of the claim link to another player.",
|
||||||
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") },
|
new ICommandArgumentParser[] { p.Word("groupname"), p.PlayerUids("playername") },
|
||||||
true,
|
true,
|
||||||
TransferOwnership
|
TransferOwnership
|
||||||
),
|
),
|
||||||
@@ -170,7 +171,7 @@ public static class ClaimLinkChatCommand
|
|||||||
new(
|
new(
|
||||||
new[] { "transferownership", "transfer", "to" },
|
new[] { "transferownership", "transfer", "to" },
|
||||||
"Transfer ownership of any claim link to another player.",
|
"Transfer ownership of any claim link to another player.",
|
||||||
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") },
|
new ICommandArgumentParser[] { p.Word("groupname"), p.PlayerUids("playername") },
|
||||||
false,
|
false,
|
||||||
AdminTransferOwnership
|
AdminTransferOwnership
|
||||||
),
|
),
|
||||||
@@ -189,9 +190,7 @@ public static class ClaimLinkChatCommand
|
|||||||
admin.EndSubCommand();
|
admin.EndSubCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Dictionary<string, Func<TextCommandResult>> pendingActions = new();
|
internal static readonly Dictionary<string, Func<TextCommandResult>> PendingActions = new();
|
||||||
|
|
||||||
internal static void RemovePending(string playerUid) => pendingActions.Remove(playerUid);
|
|
||||||
|
|
||||||
private static TextCommandResult Stage(
|
private static TextCommandResult Stage(
|
||||||
string playerUid,
|
string playerUid,
|
||||||
@@ -199,7 +198,7 @@ public static class ClaimLinkChatCommand
|
|||||||
Func<TextCommandResult> action
|
Func<TextCommandResult> action
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
pendingActions[playerUid] = action;
|
PendingActions[playerUid] = action;
|
||||||
return TextCommandResult.Success(
|
return TextCommandResult.Success(
|
||||||
$"{prompt} Use /claimlink confirm to proceed, or /claimlink cancel to cancel."
|
$"{prompt} Use /claimlink confirm to proceed, or /claimlink cancel to cancel."
|
||||||
);
|
);
|
||||||
@@ -278,10 +277,10 @@ public static class ClaimLinkChatCommand
|
|||||||
{
|
{
|
||||||
string playerUid = args.Caller.Player.PlayerUID;
|
string playerUid = args.Caller.Player.PlayerUID;
|
||||||
|
|
||||||
if (!pendingActions.TryGetValue(playerUid, out Func<TextCommandResult>? action))
|
if (!PendingActions.TryGetValue(playerUid, out Func<TextCommandResult>? action))
|
||||||
return TextCommandResult.Error("You do not have a pending action.");
|
return TextCommandResult.Error("You do not have a pending action.");
|
||||||
|
|
||||||
pendingActions.Remove(playerUid);
|
PendingActions.Remove(playerUid);
|
||||||
return action();
|
return action();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +288,7 @@ public static class ClaimLinkChatCommand
|
|||||||
{
|
{
|
||||||
string playerUid = args.Caller.Player.PlayerUID;
|
string playerUid = args.Caller.Player.PlayerUID;
|
||||||
|
|
||||||
if (!pendingActions.Remove(playerUid))
|
if (!PendingActions.Remove(playerUid))
|
||||||
return TextCommandResult.Error("You do not have a pending action.");
|
return TextCommandResult.Error("You do not have a pending action.");
|
||||||
|
|
||||||
return TextCommandResult.Success("Pending action cancelled.");
|
return TextCommandResult.Success("Pending action cancelled.");
|
||||||
@@ -315,7 +314,7 @@ public static class ClaimLinkChatCommand
|
|||||||
|
|
||||||
string playerUid = player.PlayerUID;
|
string playerUid = player.PlayerUID;
|
||||||
|
|
||||||
if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _, 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.");
|
||||||
|
|
||||||
if (ClaimLinkModSystem.Registry.IsClaimLinked(playerUid, claimIndex))
|
if (ClaimLinkModSystem.Registry.IsClaimLinked(playerUid, claimIndex))
|
||||||
@@ -327,15 +326,7 @@ public static class ClaimLinkChatCommand
|
|||||||
$"{claimDesc} will be linked into '{groupName}'.",
|
$"{claimDesc} will be linked into '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == playerUid);
|
ClaimLinkModSystem.Registry.AddEntry(playerUid, link.GroupId, claimIndex);
|
||||||
if (member == null)
|
|
||||||
{
|
|
||||||
member = new ClaimLinkMember { OwnerPlayerUid = playerUid };
|
|
||||||
link.Members.Add(member);
|
|
||||||
}
|
|
||||||
|
|
||||||
member.LocalClaimIndices.Add(claimIndex);
|
|
||||||
ClaimLinkModSystem.Registry.Save();
|
|
||||||
|
|
||||||
return TextCommandResult.Success($"Linked {claimDesc} to '{groupName}'.");
|
return TextCommandResult.Success($"Linked {claimDesc} to '{groupName}'.");
|
||||||
}
|
}
|
||||||
@@ -361,12 +352,7 @@ public static class ClaimLinkChatCommand
|
|||||||
$"{claimDesc} will be unlinked from '{groupName}'.",
|
$"{claimDesc} will be unlinked from '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
ClaimLinkMember member = link.Members.Find(m => m.OwnerPlayerUid == playerUid)!;
|
ClaimLinkModSystem.Registry.RemoveEntry(playerUid, link.GroupId, claimIndex);
|
||||||
member.LocalClaimIndices.Remove(claimIndex);
|
|
||||||
if (member.LocalClaimIndices.Count == 0)
|
|
||||||
link.Members.Remove(member);
|
|
||||||
|
|
||||||
ClaimLinkModSystem.Registry.Save();
|
|
||||||
return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'.");
|
return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'.");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -381,7 +367,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out ClaimLink link);
|
err = TryResolveClaimLink(group, out _);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -392,8 +378,7 @@ public static class ClaimLinkChatCommand
|
|||||||
string targetUid = target.PlayerUID;
|
string targetUid = target.PlayerUID;
|
||||||
string playerUid = args.Caller.Player.PlayerUID;
|
string playerUid = args.Caller.Player.PlayerUID;
|
||||||
|
|
||||||
ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == targetUid);
|
if (!ClaimLinkModSystem.Registry.HasAnyEntry(targetUid, group.Uid))
|
||||||
if (member == null)
|
|
||||||
return TextCommandResult.Error(
|
return TextCommandResult.Error(
|
||||||
$"{target.PlayerName} has no claims linked in '{groupName}'."
|
$"{target.PlayerName} has no claims linked in '{groupName}'."
|
||||||
);
|
);
|
||||||
@@ -403,9 +388,8 @@ public static class ClaimLinkChatCommand
|
|||||||
$"All of {target.PlayerName}'s claims will be unlinked from '{groupName}'.",
|
$"All of {target.PlayerName}'s claims will be unlinked from '{groupName}'.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
link.Members.Remove(member);
|
ClaimLinkModSystem.Registry.RemoveAllForPlayerInGroup(targetUid, group.Uid);
|
||||||
RemovePending(targetUid);
|
ClaimLinkCommandListener.PendingLoads.Remove(targetUid);
|
||||||
ClaimLinkModSystem.Registry.Save();
|
|
||||||
|
|
||||||
return TextCommandResult.Success(
|
return TextCommandResult.Success(
|
||||||
$"Unlinked all claims of {target.PlayerName} from '{groupName}'."
|
$"Unlinked all claims of {target.PlayerName} from '{groupName}'."
|
||||||
@@ -423,7 +407,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out ClaimLink link);
|
err = TryResolveClaimLink(group, out _);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -437,8 +421,8 @@ public static class ClaimLinkChatCommand
|
|||||||
$"'{groupName}' will be deleted as a claim link.",
|
$"'{groupName}' will be deleted as a claim link.",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
foreach (ClaimLinkMember member in link.Members)
|
foreach (string uid in ClaimLinkModSystem.Registry.MemberUidsForGroup(groupId))
|
||||||
RemovePending(member.OwnerPlayerUid);
|
PendingActions.Remove(uid);
|
||||||
|
|
||||||
ClaimLinkModSystem.Registry.Remove(groupId);
|
ClaimLinkModSystem.Registry.Remove(groupId);
|
||||||
return TextCommandResult.Success($"'{groupName}' is no longer a claim link.");
|
return TextCommandResult.Success($"'{groupName}' is no longer a claim link.");
|
||||||
@@ -449,15 +433,21 @@ public static class ClaimLinkChatCommand
|
|||||||
public static TextCommandResult TransferOwnership(TextCommandCallingArgs args)
|
public static TextCommandResult TransferOwnership(TextCommandCallingArgs args)
|
||||||
{
|
{
|
||||||
string groupName = (string)args[0];
|
string groupName = (string)args[0];
|
||||||
IPlayer target = (IPlayer)args[1];
|
|
||||||
IPlayer player = args.Caller.Player;
|
IPlayer player = args.Caller.Player;
|
||||||
string playerUid = player.PlayerUID;
|
string playerUid = player.PlayerUID;
|
||||||
|
|
||||||
TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group);
|
TextCommandResult? err = TryResolveTargetPlayer(
|
||||||
|
(PlayerUidName[])args[1],
|
||||||
|
out IPlayer target
|
||||||
|
);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out _);
|
err = TryResolveGroup(groupName, out PlayerGroup group);
|
||||||
|
if (err != null)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = TryResolveClaimLink(group, out ClaimLink link);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -476,10 +466,28 @@ 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, target)
|
() => ExecuteTransferOwnership(group, link, target)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TextCommandResult? TryResolveTargetPlayer(
|
||||||
|
PlayerUidName[] matches,
|
||||||
|
out IPlayer target
|
||||||
|
)
|
||||||
|
{
|
||||||
|
target = null!;
|
||||||
|
|
||||||
|
if (matches.Length != 1)
|
||||||
|
return TextCommandResult.Error("Name a single player.");
|
||||||
|
|
||||||
|
IPlayer? resolved = ClaimLinkModSystem.World.PlayerByUid(matches[0].Uid);
|
||||||
|
if (resolved == null)
|
||||||
|
return TextCommandResult.Error($"No such player '{matches[0].Name}'.");
|
||||||
|
|
||||||
|
target = resolved;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static TextCommandResult? RequireNotAlreadyOwner(PlayerGroup group, IPlayer target)
|
private static TextCommandResult? RequireNotAlreadyOwner(PlayerGroup group, IPlayer target)
|
||||||
{
|
{
|
||||||
return target.PlayerUID == group.OwnerUID
|
return target.PlayerUID == group.OwnerUID
|
||||||
@@ -487,27 +495,41 @@ public static class ClaimLinkChatCommand
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextCommandResult ExecuteTransferOwnership(PlayerGroup group, IPlayer target)
|
private static TextCommandResult ExecuteTransferOwnership(
|
||||||
|
PlayerGroup group,
|
||||||
|
ClaimLink link,
|
||||||
|
IPlayer target
|
||||||
|
)
|
||||||
{
|
{
|
||||||
string oldOwnerUid = group.OwnerUID;
|
string oldOwnerUid = group.OwnerUID;
|
||||||
string targetUid = target.PlayerUID;
|
|
||||||
IPlayer? oldOwner = ClaimLinkModSystem.World.PlayerByUid(oldOwnerUid);
|
IPlayer? oldOwner = ClaimLinkModSystem.World.PlayerByUid(oldOwnerUid);
|
||||||
EnumPlayerGroupMemberShip? oldOwnerLevel = oldOwner?.GetGroup(group.Uid)?.Level;
|
PlayerGroupMembership? oldOwnerMembership = oldOwner?.GetGroup(group.Uid);
|
||||||
EnumPlayerGroupMemberShip targetLevel = target.GetGroup(group.Uid)!.Level;
|
PlayerGroupMembership targetMembership = target.GetGroup(group.Uid)!;
|
||||||
|
|
||||||
// TODO remove debug logging once transfer ownership persistence is confirmed tested
|
group.OwnerUID = target.PlayerUID;
|
||||||
ClaimLinkModSystem.Logger.Notification(
|
targetMembership.Level = EnumPlayerGroupMemberShip.Owner;
|
||||||
$"claimlink: transferownership '{group.Name}' (uid {group.Uid}) BEFORE OwnerUID={oldOwnerUid} "
|
|
||||||
+ $"(old owner {oldOwner?.PlayerName ?? oldOwnerUid} level={oldOwnerLevel}, new owner {target.PlayerName}/{targetUid} level={targetLevel})"
|
|
||||||
);
|
|
||||||
|
|
||||||
group.OwnerUID = targetUid;
|
if (oldOwnerMembership != null)
|
||||||
|
oldOwnerMembership.Level = EnumPlayerGroupMemberShip.Op;
|
||||||
|
|
||||||
ClaimLinkModSystem.Logger.Notification(
|
string notice = $"'{group.Name}' is now owned by {target.PlayerName}.";
|
||||||
$"claimlink: transferownership '{group.Name}' (uid {group.Uid}) AFTER OwnerUID={group.OwnerUID}"
|
|
||||||
);
|
|
||||||
|
|
||||||
return TextCommandResult.Success($"'{group.Name}' is now owned by {target.PlayerName}.");
|
HashSet<string> notifyUids = ClaimLinkModSystem
|
||||||
|
.Registry.MemberUidsForGroup(link.GroupId)
|
||||||
|
.ToHashSet();
|
||||||
|
notifyUids.Add(oldOwnerUid);
|
||||||
|
notifyUids.Add(target.PlayerUID);
|
||||||
|
|
||||||
|
foreach (string uid in notifyUids)
|
||||||
|
NotifyIfOnline(ClaimLinkModSystem.World.PlayerByUid(uid), notice);
|
||||||
|
|
||||||
|
return TextCommandResult.Success(notice);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void NotifyIfOnline(IPlayer? player, string message)
|
||||||
|
{
|
||||||
|
if (player is IServerPlayer sp && sp.ConnectionState == EnumClientState.Playing)
|
||||||
|
sp.SendMessage(GlobalConstants.GeneralChatGroup, message, EnumChatType.Notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextCommandResult Info(TextCommandCallingArgs args)
|
public static TextCommandResult Info(TextCommandCallingArgs args)
|
||||||
@@ -528,7 +550,9 @@ public static class ClaimLinkChatCommand
|
|||||||
public static TextCommandResult List(TextCommandCallingArgs args)
|
public static TextCommandResult List(TextCommandCallingArgs args)
|
||||||
{
|
{
|
||||||
List<ClaimLink> links = ClaimLinkModSystem
|
List<ClaimLink> links = ClaimLinkModSystem
|
||||||
.Registry.All.OrderByDescending(l => l.Members.Count)
|
.Registry.All.OrderByDescending(l =>
|
||||||
|
ClaimLinkModSystem.Registry.MemberCountForGroup(l.GroupId)
|
||||||
|
)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (links.Count == 0)
|
if (links.Count == 0)
|
||||||
@@ -540,45 +564,39 @@ public static class ClaimLinkChatCommand
|
|||||||
foreach (ClaimLink link in links)
|
foreach (ClaimLink link in links)
|
||||||
{
|
{
|
||||||
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[link.GroupId].Name;
|
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[link.GroupId].Name;
|
||||||
sb.AppendLine(
|
int memberCount = ClaimLinkModSystem.Registry.MemberCountForGroup(link.GroupId);
|
||||||
$" {groupName}: {link.Members.Count} member{(link.Members.Count == 1 ? "" : "s")}"
|
sb.AppendLine($" {groupName}: {memberCount} member{(memberCount == 1 ? "" : "s")}");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextCommandResult.Success(sb.ToString());
|
return TextCommandResult.Success(sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string DescribeClaim(string ownerPlayerUid, int localIndex)
|
private static string DescribeClaim(string ownerPlayerUid, int claimIndex)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
!ClaimLinkModSystem.TryResolveOwnedClaim(
|
!ClaimLinkModSystem.TryResolveOwnedClaim(ownerPlayerUid, claimIndex, out LandClaim? claim)
|
||||||
ownerPlayerUid,
|
|
||||||
localIndex,
|
|
||||||
out _,
|
|
||||||
out LandClaim? claim
|
|
||||||
)
|
|
||||||
|| claim == null
|
|| claim == null
|
||||||
)
|
)
|
||||||
return $"claim {localIndex}";
|
return $"claim {claimIndex}";
|
||||||
|
|
||||||
return string.IsNullOrEmpty(claim.Description) ? $"claim {localIndex}" : 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, ClaimLink link)
|
||||||
{
|
{
|
||||||
|
int memberCount = ClaimLinkModSystem.Registry.MemberCountForGroup(link.GroupId);
|
||||||
|
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.AppendLine(
|
sb.AppendLine(
|
||||||
$"Claim link '{groupName}' ({link.Members.Count} member{(link.Members.Count == 1 ? "" : "s")}):"
|
$"Claim link '{groupName}' ({memberCount} member{(memberCount == 1 ? "" : "s")}):"
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach (ClaimLinkMember member in link.Members)
|
foreach (string uid in ClaimLinkModSystem.Registry.MemberUidsForGroup(link.GroupId))
|
||||||
{
|
{
|
||||||
string name =
|
string name = ClaimLinkModSystem.World.PlayerByUid(uid)?.PlayerName ?? uid;
|
||||||
ClaimLinkModSystem.World.PlayerByUid(member.OwnerPlayerUid)?.PlayerName
|
IEnumerable<string> claims = ClaimLinkModSystem
|
||||||
?? member.OwnerPlayerUid;
|
.Registry.ClaimsForPlayerInGroup(uid, link.GroupId)
|
||||||
IEnumerable<string> claims = member.LocalClaimIndices.Select(i =>
|
.Select(i => DescribeClaim(uid, i));
|
||||||
DescribeClaim(member.OwnerPlayerUid, i)
|
|
||||||
);
|
|
||||||
sb.AppendLine($" {name}: [{string.Join(", ", claims)}]");
|
sb.AppendLine($" {name}: [{string.Join(", ", claims)}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,13 +615,19 @@ public static class ClaimLinkChatCommand
|
|||||||
public static TextCommandResult AdminTransferOwnership(TextCommandCallingArgs args)
|
public static TextCommandResult AdminTransferOwnership(TextCommandCallingArgs args)
|
||||||
{
|
{
|
||||||
string groupName = (string)args[0];
|
string groupName = (string)args[0];
|
||||||
IPlayer target = (IPlayer)args[1];
|
|
||||||
|
|
||||||
TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group);
|
TextCommandResult? err = TryResolveTargetPlayer(
|
||||||
|
(PlayerUidName[])args[1],
|
||||||
|
out IPlayer target
|
||||||
|
);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = TryResolveClaimLink(group, out _);
|
err = TryResolveGroup(groupName, out PlayerGroup group);
|
||||||
|
if (err != null)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = TryResolveClaimLink(group, out ClaimLink link);
|
||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -615,7 +639,7 @@ public static class ClaimLinkChatCommand
|
|||||||
if (err != null)
|
if (err != null)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return ExecuteTransferOwnership(group, target);
|
return ExecuteTransferOwnership(group, link, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) =>
|
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) =>
|
||||||
|
|||||||
@@ -29,13 +29,6 @@ public class ClaimLinkModSystem : ModSystem
|
|||||||
ClaimLinkChatCommand.Register(api);
|
ClaimLinkChatCommand.Register(api);
|
||||||
|
|
||||||
api.Event.PlayerDisconnect += ClaimLinkCommandListener.OnPlayerDisconnect;
|
api.Event.PlayerDisconnect += ClaimLinkCommandListener.OnPlayerDisconnect;
|
||||||
|
|
||||||
// TODO remove debug logging once transfer ownership persistence is confirmed tested
|
|
||||||
foreach (ClaimLink link in Registry.All)
|
|
||||||
{
|
|
||||||
PlayerGroup group = Groups.PlayerGroupsById[link.GroupId];
|
|
||||||
Logger.Notification($"claimlink: startup state '{group.Name}' (uid {group.Uid}) OwnerUID={group.OwnerUID}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
@@ -44,28 +37,48 @@ public class ClaimLinkModSystem : ModSystem
|
|||||||
CommandHookModSystem.Unregister(cmdListener);
|
CommandHookModSystem.Unregister(cmdListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool TryResolveOwnedClaim(string ownerPlayerUid, int localIndex, out int globalIndex, out LandClaim? claim)
|
private static IEnumerable<(int claimIndex, LandClaim claim)> EnumerateOwnedClaims(
|
||||||
|
string ownerPlayerUid
|
||||||
|
)
|
||||||
{
|
{
|
||||||
globalIndex = -1;
|
int index = 0;
|
||||||
claim = null;
|
foreach (LandClaim c in LandClaimAPI.All)
|
||||||
|
|
||||||
List<LandClaim> claims = LandClaimAPI.All;
|
|
||||||
int count = 0;
|
|
||||||
for (int i = 0; i < claims.Count; ++i)
|
|
||||||
{
|
{
|
||||||
if (claims[i].OwnedByPlayerUid != ownerPlayerUid)
|
if (c.OwnedByPlayerUid != ownerPlayerUid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (count == localIndex)
|
yield return (index, c);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool TryResolveOwnedClaim(string ownerPlayerUid, int claimIndex, out LandClaim? claim)
|
||||||
{
|
{
|
||||||
globalIndex = i;
|
foreach ((int index, LandClaim c) in EnumerateOwnedClaims(ownerPlayerUid))
|
||||||
claim = claims[i];
|
{
|
||||||
|
if (index == claimIndex)
|
||||||
|
{
|
||||||
|
claim = c;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
claim = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static bool TryResolveClaimIndex(string ownerPlayerUid, LandClaim target, out int claimIndex)
|
||||||
|
{
|
||||||
|
foreach ((int index, LandClaim c) in EnumerateOwnedClaims(ownerPlayerUid))
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(c, target))
|
||||||
|
{
|
||||||
|
claimIndex = index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
claimIndex = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using ProtoBuf;
|
using ProtoBuf;
|
||||||
using Vintagestory.API.Server;
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
@@ -9,6 +10,9 @@ public class ClaimLinkData
|
|||||||
{
|
{
|
||||||
[ProtoMember(1)]
|
[ProtoMember(1)]
|
||||||
public List<ClaimLink> Links = new();
|
public List<ClaimLink> Links = new();
|
||||||
|
|
||||||
|
[ProtoMember(2)]
|
||||||
|
public List<ClaimLinkEntry> Entries = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClaimLinkRegistry
|
public class ClaimLinkRegistry
|
||||||
@@ -18,6 +22,8 @@ public class ClaimLinkRegistry
|
|||||||
private readonly ISaveGame saveGame;
|
private readonly ISaveGame saveGame;
|
||||||
private readonly Dictionary<int, ClaimLink> byGroupId = new();
|
private readonly Dictionary<int, ClaimLink> byGroupId = new();
|
||||||
|
|
||||||
|
private readonly Dictionary<string, Dictionary<int, List<int>>> byPlayer = new();
|
||||||
|
|
||||||
public ClaimLinkRegistry(ISaveGame saveGame)
|
public ClaimLinkRegistry(ISaveGame saveGame)
|
||||||
{
|
{
|
||||||
this.saveGame = saveGame;
|
this.saveGame = saveGame;
|
||||||
@@ -28,9 +34,13 @@ public class ClaimLinkRegistry
|
|||||||
|
|
||||||
foreach (ClaimLink link in data.Links)
|
foreach (ClaimLink link in data.Links)
|
||||||
byGroupId[link.GroupId] = link;
|
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 ClaimLink? Get(int groupId) =>
|
||||||
|
byGroupId.TryGetValue(groupId, out ClaimLink? link) ? link : null;
|
||||||
|
|
||||||
public IReadOnlyCollection<ClaimLink> All => byGroupId.Values;
|
public IReadOnlyCollection<ClaimLink> All => byGroupId.Values;
|
||||||
|
|
||||||
@@ -43,23 +53,119 @@ public class ClaimLinkRegistry
|
|||||||
public void Remove(int groupId)
|
public void Remove(int groupId)
|
||||||
{
|
{
|
||||||
byGroupId.Remove(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();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsClaimLinked(string ownerPlayerUid, int localIndex) => FindLinkContaining(ownerPlayerUid, localIndex) != null;
|
public bool IsClaimLinked(string ownerPlayerUid, int claimIndex) =>
|
||||||
|
FindLinkContaining(ownerPlayerUid, claimIndex) != null;
|
||||||
|
|
||||||
public ClaimLink? FindLinkContaining(string ownerPlayerUid, int localIndex)
|
public ClaimLink? FindLinkContaining(string ownerPlayerUid, int claimIndex)
|
||||||
{
|
{
|
||||||
foreach (ClaimLink link in byGroupId.Values)
|
if (!byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup))
|
||||||
foreach (ClaimLinkMember member in link.Members)
|
return null;
|
||||||
if (member.OwnerPlayerUid == ownerPlayerUid && member.LocalClaimIndices.Contains(localIndex))
|
|
||||||
return link;
|
foreach (KeyValuePair<int, List<int>> entry in perGroup)
|
||||||
|
if (entry.Value.Contains(claimIndex))
|
||||||
|
return Get(entry.Key);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddEntry(string ownerPlayerUid, int groupId, int claimIndex)
|
||||||
|
{
|
||||||
|
GetOrCreateIndices(ownerPlayerUid, groupId).Add(claimIndex);
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveEntry(string ownerPlayerUid, int groupId, int claimIndex)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
byPlayer.TryGetValue(ownerPlayerUid, out Dictionary<int, List<int>>? perGroup)
|
||||||
|
&& perGroup.TryGetValue(groupId, out List<int>? indices)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
indices.Remove(claimIndex);
|
||||||
|
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()
|
public void Save()
|
||||||
{
|
{
|
||||||
saveGame.StoreData(SaveKey, new ClaimLinkData { Links = new List<ClaimLink>(byGroupId.Values) });
|
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 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Vintagestory.API.Common;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using CommandHook;
|
using CommandHook;
|
||||||
|
using Vintagestory.API.Common;
|
||||||
using Vintagestory.API.Server;
|
using Vintagestory.API.Server;
|
||||||
|
|
||||||
namespace ClaimLink;
|
namespace ClaimLink;
|
||||||
@@ -13,9 +13,9 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
|
|
||||||
public CommandRegistration Registration => new(Before, After);
|
public CommandRegistration Registration => new(Before, After);
|
||||||
|
|
||||||
private 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);
|
private delegate void SubHandler(Caller caller, CmdArgs args, TextCommandResult? result);
|
||||||
|
|
||||||
private static readonly Dictionary<string, SubHandler> topLevel = new()
|
private static readonly Dictionary<string, SubHandler> topLevel = new()
|
||||||
{
|
{
|
||||||
@@ -47,7 +47,7 @@ public class ClaimLinkCommandListener : ICommandHookListener
|
|||||||
["download"] = ClaimDownload,
|
["download"] = ClaimDownload,
|
||||||
};
|
};
|
||||||
|
|
||||||
private TextCommandResult? Before(TextCommandCallingArgs args)
|
private static void Dispatch(TextCommandCallingArgs args, TextCommandResult? result)
|
||||||
{
|
{
|
||||||
CmdArgs rawArgs = args.RawArgs.Clone();
|
CmdArgs rawArgs = args.RawArgs.Clone();
|
||||||
|
|
||||||
@@ -58,79 +58,152 @@ 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);
|
handler(args.Caller, rawArgs, result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rawArgs.PopWord();
|
rawArgs.PopWord();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextCommandResult? Before(TextCommandCallingArgs args)
|
||||||
|
{
|
||||||
|
Dispatch(args, null);
|
||||||
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)
|
private static void Claim(Caller caller, CmdArgs args, TextCommandResult? result)
|
||||||
{
|
{
|
||||||
string word = args.PeekWord();
|
string word = args.PeekWord();
|
||||||
|
|
||||||
if (claimSub.TryGetValue(word, out SubHandler? handler))
|
if (claimSub.TryGetValue(word, out SubHandler? handler))
|
||||||
{
|
{
|
||||||
args.PopWord();
|
args.PopWord();
|
||||||
handler(caller, args);
|
handler(caller, args, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ClaimLoad(Caller caller, CmdArgs args)
|
private static void ClaimLoad(Caller caller, CmdArgs args, TextCommandResult? result)
|
||||||
{
|
{
|
||||||
if (caller.Player == null)
|
if (result == null || result.Status != EnumCommandStatus.Success || caller.Player == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int? claimIndex = args.PopInt();
|
int? claimIndex = args.PopInt();
|
||||||
if (claimIndex == null || claimIndex < 0 || claimIndex > 999)
|
if (claimIndex == null || claimIndex < 0 || claimIndex > 999)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!ClaimLinkModSystem.TryResolveOwnedClaim(caller.Player.PlayerUID, (int)claimIndex, out int globalIndex, out _))
|
ClaimLinkModSystem.Logger.Notification($"Claim Index Loaded = {claimIndex}");
|
||||||
return;
|
PendingLoads[caller.Player.PlayerUID] = (int)claimIndex;
|
||||||
|
|
||||||
pendingLoads[caller.Player.PlayerUID] = globalIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ClaimCancel(Caller caller, CmdArgs args)
|
private static void ClaimCancel(Caller caller, CmdArgs args, TextCommandResult? result)
|
||||||
|
{
|
||||||
|
if (result != null || caller.Player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PendingLoads.Remove(caller.Player.PlayerUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Free(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 (claimIndex == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (args.PopWord() != "confirm")
|
||||||
|
return;
|
||||||
|
|
||||||
|
ClaimLink? link = ClaimLinkModSystem.Registry.FindLinkContaining(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 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;
|
||||||
|
|
||||||
pendingLoads.Remove(caller.Player.PlayerUID);
|
LandClaim[] claims = ClaimLinkModSystem.LandClaimAPI.Get(
|
||||||
|
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)
|
||||||
|
ClaimLinkModSystem.Logger.Notification($"claimlink: owned by {c.OwnedByPlayerUid}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Free(Caller caller, CmdArgs args) { }
|
private static void ClaimNew(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void Info(Caller caller, CmdArgs args) { }
|
|
||||||
private static void List(Caller caller, CmdArgs args) { }
|
|
||||||
private static void AdminFree(Caller caller, CmdArgs args) { }
|
|
||||||
|
|
||||||
private static void ClaimNew(Caller caller, CmdArgs args) { }
|
private static void ClaimGrant(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimGrant(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimRevoke(Caller caller, CmdArgs args) { }
|
private static void ClaimRevoke(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimGrantGroup(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimRevokeGroup(Caller caller, CmdArgs args) { }
|
private static void ClaimGrantGroup(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimStart(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimEnd(Caller caller, CmdArgs args) { }
|
private static void ClaimRevokeGroup(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimGrow(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimShrink(Caller caller, CmdArgs args) { }
|
private static void ClaimStart(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimAdd(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimAllowUseEveryone(Caller caller, CmdArgs args) { }
|
private static void ClaimEnd(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimPLevel(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimFullHeight(Caller caller, CmdArgs args) { }
|
private static void ClaimGrow(Caller caller, CmdArgs args, TextCommandResult? result) { }
|
||||||
private static void ClaimSave(Caller caller, CmdArgs args) { }
|
|
||||||
private static void ClaimDownload(Caller caller, CmdArgs args) { }
|
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);
|
||||||
ClaimLinkChatCommand.RemovePending(player.PlayerUID);
|
ClaimLinkChatCommand.PendingActions.Remove(player.PlayerUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user