feat: stage claimlink new behind confirm/cancel pending state

This commit is contained in:
2026-07-12 19:09:40 +02:00
parent c7e3f97a85
commit 65e00e2f57
2 changed files with 61 additions and 13 deletions
+58 -11
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Vintagestory.API.Common; using Vintagestory.API.Common;
using Vintagestory.API.Server; using Vintagestory.API.Server;
@@ -113,6 +114,10 @@ public static class ClaimLinkChatCommand
admin.EndSubCommand(); admin.EndSubCommand();
} }
private static readonly Dictionary<string, ClaimLink> pendingLinks = new();
internal static void RemovePending(string playerUid) => pendingLinks.Remove(playerUid);
private static TextCommandResult? TryResolveGroup(string groupName, out PlayerGroup group) private static TextCommandResult? TryResolveGroup(string groupName, out PlayerGroup group)
{ {
group = ClaimLinkModSystem.Groups.GetPlayerGroupByName(groupName)!; group = ClaimLinkModSystem.Groups.GetPlayerGroupByName(groupName)!;
@@ -125,6 +130,19 @@ public static class ClaimLinkChatCommand
return link == null ? TextCommandResult.Error($"'{group.Name}' is not a claim link.") : null; return link == null ? TextCommandResult.Error($"'{group.Name}' is not a claim link.") : null;
} }
private static TextCommandResult? TryResolveClaimLinkForEdit(string playerUid, PlayerGroup group, out ClaimLink link, out bool isPending)
{
if (pendingLinks.TryGetValue(playerUid, out ClaimLink? pending) && pending.GroupId == group.Uid)
{
link = pending;
isPending = true;
return null;
}
isPending = false;
return TryResolveClaimLink(group, out link);
}
private static TextCommandResult? RequireMember(IPlayer player, PlayerGroup group) private static TextCommandResult? RequireMember(IPlayer player, PlayerGroup group)
{ {
return player.GetGroup(group.Uid) == null ? TextCommandResult.Error($"You are not a member of '{group.Name}'.") : null; return player.GetGroup(group.Uid) == null ? TextCommandResult.Error($"You are not a member of '{group.Name}'.") : null;
@@ -138,6 +156,7 @@ public static class ClaimLinkChatCommand
public static TextCommandResult New(TextCommandCallingArgs args) public static TextCommandResult New(TextCommandCallingArgs args)
{ {
string groupName = (string)args[0]; string groupName = (string)args[0];
string playerUid = args.Caller.Player.PlayerUID;
TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group); TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group);
if (err != null) return err; if (err != null) return err;
@@ -145,11 +164,37 @@ public static class ClaimLinkChatCommand
err = RequireOwner(args.Caller.Player, group); err = RequireOwner(args.Caller.Player, group);
if (err != null) return err; if (err != null) return err;
if (pendingLinks.ContainsKey(playerUid))
return TextCommandResult.Error("You already have a pending claim link. Confirm or cancel it first.");
if (ClaimLinkModSystem.Registry.Get(group.Uid) != null) if (ClaimLinkModSystem.Registry.Get(group.Uid) != null)
return TextCommandResult.Error($"'{groupName}' is already a claim link."); return TextCommandResult.Error($"'{groupName}' is already a claim link.");
ClaimLinkModSystem.Registry.Add(new ClaimLink { GroupId = group.Uid }); pendingLinks[playerUid] = new ClaimLink { GroupId = group.Uid };
return TextCommandResult.Success($"'{groupName}' is now a claim link."); return TextCommandResult.Success($"'{groupName}' is now a pending claim link. Use /claimlink link to add claims, then confirm.");
}
public static TextCommandResult Confirm(TextCommandCallingArgs args)
{
string playerUid = args.Caller.Player.PlayerUID;
if (!pendingLinks.TryGetValue(playerUid, out ClaimLink? pending))
return TextCommandResult.Error("You do not have a pending claim link.");
ClaimLinkModSystem.Registry.Add(pending);
pendingLinks.Remove(playerUid);
return TextCommandResult.Success("Claim link confirmed.");
}
public static TextCommandResult Cancel(TextCommandCallingArgs args)
{
string playerUid = args.Caller.Player.PlayerUID;
if (!pendingLinks.Remove(playerUid))
return TextCommandResult.Error("You do not have a pending claim link.");
return TextCommandResult.Success("Pending claim link discarded.");
} }
public static TextCommandResult Link(TextCommandCallingArgs args) public static TextCommandResult Link(TextCommandCallingArgs args)
@@ -160,15 +205,15 @@ public static class ClaimLinkChatCommand
TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group); TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group);
if (err != null) return err; if (err != null) return err;
err = TryResolveClaimLink(group, out ClaimLink link); IPlayer player = args.Caller.Player;
string playerUid = player.PlayerUID;
err = TryResolveClaimLinkForEdit(playerUid, group, out ClaimLink link, out bool isPending);
if (err != null) return err; if (err != null) return err;
IPlayer player = args.Caller.Player;
err = RequireMember(player, group); err = RequireMember(player, group);
if (err != null) return err; if (err != null) return err;
string playerUid = player.PlayerUID;
if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _, out _)) if (!ClaimLinkModSystem.TryResolveOwnedClaim(playerUid, claimIndex, out _, out _))
return TextCommandResult.Error("You do not own a claim with that index."); return TextCommandResult.Error("You do not own a claim with that index.");
@@ -183,12 +228,12 @@ public static class ClaimLinkChatCommand
} }
member.LocalClaimIndices.Add(claimIndex); member.LocalClaimIndices.Add(claimIndex);
if (!isPending)
ClaimLinkModSystem.Registry.Save(); ClaimLinkModSystem.Registry.Save();
return TextCommandResult.Success($"Linked claim {claimIndex} into '{groupName}'."); return TextCommandResult.Success($"Linked claim {claimIndex} into '{groupName}'.");
} }
public static TextCommandResult Confirm(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink confirm");
public static TextCommandResult Cancel(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink cancel");
public static TextCommandResult Unlink(TextCommandCallingArgs args) public static TextCommandResult Unlink(TextCommandCallingArgs args)
{ {
string groupName = (string)args[0]; string groupName = (string)args[0];
@@ -197,11 +242,11 @@ public static class ClaimLinkChatCommand
TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group); TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group);
if (err != null) return err; if (err != null) return err;
err = TryResolveClaimLink(group, out ClaimLink link);
if (err != null) return err;
string playerUid = args.Caller.Player.PlayerUID; string playerUid = args.Caller.Player.PlayerUID;
err = TryResolveClaimLinkForEdit(playerUid, group, out ClaimLink link, out bool isPending);
if (err != null) return err;
ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == playerUid); ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == playerUid);
if (member == null || !member.LocalClaimIndices.Remove(claimIndex)) if (member == null || !member.LocalClaimIndices.Remove(claimIndex))
return TextCommandResult.Error($"Claim {claimIndex} is not linked into '{groupName}' by you."); return TextCommandResult.Error($"Claim {claimIndex} is not linked into '{groupName}' by you.");
@@ -209,7 +254,9 @@ public static class ClaimLinkChatCommand
if (member.LocalClaimIndices.Count == 0) if (member.LocalClaimIndices.Count == 0)
link.Members.Remove(member); link.Members.Remove(member);
if (!isPending)
ClaimLinkModSystem.Registry.Save(); ClaimLinkModSystem.Registry.Save();
return TextCommandResult.Success($"Unlinked claim {claimIndex} from '{groupName}'."); return TextCommandResult.Success($"Unlinked claim {claimIndex} from '{groupName}'.");
} }
public static TextCommandResult Kick(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink kick"); public static TextCommandResult Kick(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink kick");
+1
View File
@@ -131,5 +131,6 @@ public class ClaimLinkCommandListener : ICommandHookListener
internal static void OnPlayerDisconnect(IServerPlayer player) internal static void OnPlayerDisconnect(IServerPlayer player)
{ {
pendingLoads.Remove(player.PlayerUID); pendingLoads.Remove(player.PlayerUID);
ClaimLinkChatCommand.RemovePending(player.PlayerUID);
} }
} }