Compare commits

..
2 Commits
+297 -135
View File
@@ -17,7 +17,13 @@ public static class ClaimLinkChatCommand
public readonly bool IsPlayerOnly; public readonly bool IsPlayerOnly;
public readonly OnCommandDelegate Handler; public readonly OnCommandDelegate Handler;
public CommandSpec(string[] names, string description, ICommandArgumentParser[] args, bool isPlayerOnly, OnCommandDelegate handler) public CommandSpec(
string[] names,
string description,
ICommandArgumentParser[] args,
bool isPlayerOnly,
OnCommandDelegate handler
)
{ {
Names = names; Names = names;
Description = description; Description = description;
@@ -29,9 +35,10 @@ public static class ClaimLinkChatCommand
private static void BuildSubCommand(IChatCommand parent, CommandSpec spec) private static void BuildSubCommand(IChatCommand parent, CommandSpec spec)
{ {
var sub = spec.Names.Length > 1 var sub =
? parent.BeginSubCommands(spec.Names) spec.Names.Length > 1
: parent.BeginSubCommand(spec.Names[0]); ? parent.BeginSubCommands(spec.Names)
: parent.BeginSubCommand(spec.Names[0]);
sub.WithDescription(spec.Description); sub.WithDescription(spec.Description);
@@ -50,42 +57,84 @@ public static class ClaimLinkChatCommand
{ {
var p = api.ChatCommands.Parsers; var p = api.ChatCommands.Parsers;
var root = api.ChatCommands.Create("claimlink") var root = api
.ChatCommands.Create("claimlink")
.WithAlias("clink", "claiml", "cl") .WithAlias("clink", "claiml", "cl")
.WithDescription("Link vanilla land claims together via group.") .WithDescription("Link vanilla land claims together via group.")
.RequiresPrivilege(Privilege.chat); .RequiresPrivilege(Privilege.chat);
CommandSpec[] playerCommands = CommandSpec[] playerCommands =
{ {
new(new[] { "new", "n" }, "Promote a group you own to a claim link.", new(
new ICommandArgumentParser[] { p.Word("groupname") }, true, New), new[] { "new", "n" },
"Promote a group you own to a claim link.",
new(new[] { "link", "l" }, "Link a claim you own to a claim link.", new ICommandArgumentParser[] { p.Word("groupname") },
new ICommandArgumentParser[] { p.Word("groupname"), p.IntRange("claim", 0, 999) }, true, Link), true,
New
new(new[] { "confirm", "c" }, "Confirm pending action.", ),
Array.Empty<ICommandArgumentParser>(), true, Confirm), new(
new[] { "link", "l" },
new(new[] { "cancel" }, "Cancel pending action.", "Link a claim you own to a claim link.",
Array.Empty<ICommandArgumentParser>(), true, Cancel), new ICommandArgumentParser[] { p.Word("groupname"), p.IntRange("claim", 0, 999) },
true,
new(new[] { "unlink", "ul" }, "Remove a claim you own from its claim link.", Link
new ICommandArgumentParser[] { p.IntRange("claim", 0, 999) }, true, Unlink), ),
new(
new(new[] { "kick" }, "Force-unlink all of a player's claims from the claim link.", new[] { "confirm", "c" },
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") }, true, Kick), "Confirm pending action.",
Array.Empty<ICommandArgumentParser>(),
new(new[] { "delete" }, "Delete a claim link.", true,
new ICommandArgumentParser[] { p.Word("groupname") }, true, Delete), Confirm
),
new(new[] { "transferownership", "transfer", "to" }, "Transfer ownership of the claim link to another player.", new(
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") }, true, TransferOwnership), new[] { "cancel" },
"Cancel pending action.",
new(new[] { "info", "i" }, "Show a claim link's members and linked claims.", Array.Empty<ICommandArgumentParser>(),
new ICommandArgumentParser[] { p.Word("groupname") }, true, Info), true,
Cancel
new(new[] { "list", "ls" }, "List all claim links.", ),
Array.Empty<ICommandArgumentParser>(), true, List), new(
new[] { "unlink", "ul" },
"Remove a claim you own from its claim link.",
new ICommandArgumentParser[] { p.IntRange("claim", 0, 999) },
true,
Unlink
),
new(
new[] { "kick" },
"Force-unlink all of a player's claims from the claim link.",
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") },
true,
Kick
),
new(
new[] { "delete" },
"Delete a claim link.",
new ICommandArgumentParser[] { p.Word("groupname") },
true,
Delete
),
new(
new[] { "transferownership", "transfer", "to" },
"Transfer ownership of the claim link to another player.",
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") },
true,
TransferOwnership
),
new(
new[] { "info", "i" },
"Show a claim link's members and linked claims.",
new ICommandArgumentParser[] { p.Word("groupname") },
true,
Info
),
new(
new[] { "list", "ls" },
"List all claim links.",
Array.Empty<ICommandArgumentParser>(),
true,
List
),
}; };
foreach (var spec in playerCommands) foreach (var spec in playerCommands)
@@ -97,20 +146,41 @@ public static class ClaimLinkChatCommand
CommandSpec[] adminCommands = CommandSpec[] adminCommands =
{ {
new(new[] { "delete", "del" }, "Delete a claim link.", new(
new ICommandArgumentParser[] { p.Word("groupname") }, false, AdminDelete), new[] { "delete", "del" },
"Delete a claim link.",
new(new[] { "unlink" }, "Unlink a claim.", new ICommandArgumentParser[] { p.Word("groupname") },
new ICommandArgumentParser[] { p.OnlinePlayer("playername"), p.Word("claim") }, false, AdminUnlink), false,
AdminDelete
new(new[] { "kick" }, "Force-unlink all of a player's claims.", ),
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") }, false, AdminKick), new(
new[] { "unlink" },
new(new[] { "transferownership", "transfer", "to" }, "Transfer ownership of any claim link to another player.", "Unlink a claim.",
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") }, false, AdminTransferOwnership), new ICommandArgumentParser[] { p.OnlinePlayer("playername"), p.Word("claim") },
false,
new(new[] { "info", "i" }, "Show a claim link's members and linked claims.", AdminUnlink
new ICommandArgumentParser[] { p.Word("groupname") }, false, AdminInfo), ),
new(
new[] { "kick" },
"Force-unlink all of a player's claims.",
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") },
false,
AdminKick
),
new(
new[] { "transferownership", "transfer", "to" },
"Transfer ownership of any claim link to another player.",
new ICommandArgumentParser[] { p.Word("groupname"), p.OnlinePlayer("playername") },
false,
AdminTransferOwnership
),
new(
new[] { "info", "i" },
"Show a claim link's members and linked claims.",
new ICommandArgumentParser[] { p.Word("groupname") },
false,
AdminInfo
),
}; };
foreach (var spec in adminCommands) foreach (var spec in adminCommands)
@@ -123,32 +193,46 @@ public static class ClaimLinkChatCommand
internal static void RemovePending(string playerUid) => pendingActions.Remove(playerUid); internal static void RemovePending(string playerUid) => pendingActions.Remove(playerUid);
private static TextCommandResult Stage(string playerUid, string prompt, Func<TextCommandResult> action) private static TextCommandResult Stage(
string playerUid,
string prompt,
Func<TextCommandResult> action
)
{ {
pendingActions[playerUid] = action; pendingActions[playerUid] = action;
return TextCommandResult.Success($"{prompt} Use /claimlink confirm to proceed, or /claimlink cancel to cancel."); return TextCommandResult.Success(
$"{prompt} Use /claimlink confirm to proceed, or /claimlink cancel to cancel."
);
} }
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)!;
return group == null ? TextCommandResult.Error($"No group named '{groupName}' exists.") : null; return group == null
? TextCommandResult.Error($"No group named '{groupName}' exists.")
: null;
} }
private static TextCommandResult? TryResolveClaimLink(PlayerGroup group, out ClaimLink link) private static TextCommandResult? TryResolveClaimLink(PlayerGroup group, out ClaimLink link)
{ {
link = ClaimLinkModSystem.Registry.Get(group.Uid)!; link = ClaimLinkModSystem.Registry.Get(group.Uid)!;
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? 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($"'{player.PlayerName}' is not a member of '{group.Name}'.")
: null;
} }
private static TextCommandResult? RequireOwner(IPlayer player, PlayerGroup group) private static TextCommandResult? RequireOwner(IPlayer player, PlayerGroup group)
{ {
return group.OwnerUID != player.PlayerUID ? TextCommandResult.Error($"You do not own '{group.Name}'.") : null; return group.OwnerUID != player.PlayerUID
? TextCommandResult.Error($"You do not own '{group.Name}'.")
: null;
} }
private static TextCommandResult? RequireOpOrOwner(IPlayer player, PlayerGroup group) private static TextCommandResult? RequireOpOrOwner(IPlayer player, PlayerGroup group)
@@ -168,20 +252,26 @@ public static class ClaimLinkChatCommand
string playerUid = args.Caller.Player.PlayerUID; 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;
err = RequireOwner(args.Caller.Player, group); err = RequireOwner(args.Caller.Player, group);
if (err != null) return err; if (err != null)
return err;
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.");
int groupId = group.Uid; int groupId = group.Uid;
return Stage(playerUid, $"'{groupName}' will become a claim link.", () => return Stage(
{ playerUid,
ClaimLinkModSystem.Registry.Add(new ClaimLink { GroupId = groupId }); $"'{groupName}' will become a claim link.",
return TextCommandResult.Success($"'{groupName}' is now a claim link."); () =>
}); {
ClaimLinkModSystem.Registry.Add(new ClaimLink { GroupId = groupId });
return TextCommandResult.Success($"'{groupName}' is now a claim link.");
}
);
} }
public static TextCommandResult Confirm(TextCommandCallingArgs args) public static TextCommandResult Confirm(TextCommandCallingArgs args)
@@ -211,14 +301,17 @@ public static class ClaimLinkChatCommand
int claimIndex = (int)args[1]; int claimIndex = (int)args[1];
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); err = TryResolveClaimLink(group, out ClaimLink link);
if (err != null) return err; if (err != null)
return err;
IPlayer player = args.Caller.Player; 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; string playerUid = player.PlayerUID;
@@ -229,20 +322,24 @@ public static class ClaimLinkChatCommand
return TextCommandResult.Error("That claim is already part of a claim link."); return TextCommandResult.Error("That claim is already part of a claim link.");
string claimDesc = DescribeClaim(playerUid, claimIndex); string claimDesc = DescribeClaim(playerUid, claimIndex);
return Stage(playerUid, $"{claimDesc} will be linked into '{groupName}'.", () => return Stage(
{ playerUid,
ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == playerUid); $"{claimDesc} will be linked into '{groupName}'.",
if (member == null) () =>
{ {
member = new ClaimLinkMember { OwnerPlayerUid = playerUid }; ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == playerUid);
link.Members.Add(member); 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}'.");
} }
);
member.LocalClaimIndices.Add(claimIndex);
ClaimLinkModSystem.Registry.Save();
return TextCommandResult.Success($"Linked {claimDesc} to '{groupName}'.");
});
} }
public static TextCommandResult Unlink(TextCommandCallingArgs args) public static TextCommandResult Unlink(TextCommandCallingArgs args)
@@ -252,21 +349,27 @@ public static class ClaimLinkChatCommand
ClaimLink? link = ClaimLinkModSystem.Registry.FindLinkContaining(playerUid, claimIndex); ClaimLink? link = ClaimLinkModSystem.Registry.FindLinkContaining(playerUid, claimIndex);
if (link == null) if (link == null)
return TextCommandResult.Error($"Claim {claimIndex} is not linked into any claim link by you."); return TextCommandResult.Error(
$"Claim {claimIndex} is not linked into any claim link by you."
);
string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[link.GroupId].Name; string groupName = ClaimLinkModSystem.Groups.PlayerGroupsById[link.GroupId].Name;
string claimDesc = DescribeClaim(playerUid, claimIndex); string claimDesc = DescribeClaim(playerUid, claimIndex);
return Stage(playerUid, $"{claimDesc} will be unlinked from '{groupName}'.", () => return Stage(
{ playerUid,
ClaimLinkMember member = link.Members.Find(m => m.OwnerPlayerUid == playerUid)!; $"{claimDesc} will be unlinked from '{groupName}'.",
member.LocalClaimIndices.Remove(claimIndex); () =>
if (member.LocalClaimIndices.Count == 0) {
link.Members.Remove(member); ClaimLinkMember member = link.Members.Find(m => m.OwnerPlayerUid == playerUid)!;
member.LocalClaimIndices.Remove(claimIndex);
if (member.LocalClaimIndices.Count == 0)
link.Members.Remove(member);
ClaimLinkModSystem.Registry.Save(); ClaimLinkModSystem.Registry.Save();
return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'."); return TextCommandResult.Success($"Unlinked {claimDesc} from '{groupName}'.");
}); }
);
} }
public static TextCommandResult Kick(TextCommandCallingArgs args) public static TextCommandResult Kick(TextCommandCallingArgs args)
@@ -275,29 +378,40 @@ public static class ClaimLinkChatCommand
IPlayer target = (IPlayer)args[1]; IPlayer target = (IPlayer)args[1];
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); err = TryResolveClaimLink(group, out ClaimLink link);
if (err != null) return err; if (err != null)
return err;
err = RequireOpOrOwner(args.Caller.Player, group); err = RequireOpOrOwner(args.Caller.Player, group);
if (err != null) return err; if (err != null)
return err;
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); ClaimLinkMember? member = link.Members.Find(m => m.OwnerPlayerUid == targetUid);
if (member == null) if (member == null)
return TextCommandResult.Error($"{target.PlayerName} has no claims linked in '{groupName}'."); return TextCommandResult.Error(
$"{target.PlayerName} has no claims linked in '{groupName}'."
);
return Stage(playerUid, $"All of {target.PlayerName}'s claims will be unlinked from '{groupName}'.", () => return Stage(
{ playerUid,
link.Members.Remove(member); $"All of {target.PlayerName}'s claims will be unlinked from '{groupName}'.",
RemovePending(targetUid); () =>
ClaimLinkModSystem.Registry.Save(); {
link.Members.Remove(member);
RemovePending(targetUid);
ClaimLinkModSystem.Registry.Save();
return TextCommandResult.Success($"Unlinked all claims of {target.PlayerName} from '{groupName}'."); return TextCommandResult.Success(
}); $"Unlinked all claims of {target.PlayerName} from '{groupName}'."
);
}
);
} }
public static TextCommandResult Delete(TextCommandCallingArgs args) public static TextCommandResult Delete(TextCommandCallingArgs args)
@@ -306,24 +420,32 @@ public static class ClaimLinkChatCommand
string playerUid = args.Caller.Player.PlayerUID; 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;
err = TryResolveClaimLink(group, out ClaimLink link); err = TryResolveClaimLink(group, out ClaimLink link);
if (err != null) return err; if (err != null)
return err;
err = RequireOwner(args.Caller.Player, group); err = RequireOwner(args.Caller.Player, group);
if (err != null) return err; if (err != null)
return err;
int groupId = group.Uid; int groupId = group.Uid;
return Stage(playerUid, $"'{groupName}' will be deleted as a claim link.", () => return Stage(
{ playerUid,
foreach (ClaimLinkMember member in link.Members) $"'{groupName}' will be deleted as a claim link.",
RemovePending(member.OwnerPlayerUid); () =>
{
foreach (ClaimLinkMember member in link.Members)
RemovePending(member.OwnerPlayerUid);
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.");
}); }
);
} }
public static TextCommandResult TransferOwnership(TextCommandCallingArgs args) public static TextCommandResult TransferOwnership(TextCommandCallingArgs args)
{ {
string groupName = (string)args[0]; string groupName = (string)args[0];
@@ -332,22 +454,30 @@ public static class ClaimLinkChatCommand
string playerUid = player.PlayerUID; string playerUid = 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;
err = TryResolveClaimLink(group, out _); err = TryResolveClaimLink(group, out _);
if (err != null) return err; if (err != null)
return err;
err = RequireOwner(player, group); err = RequireOwner(player, group);
if (err != null) return err; if (err != null)
return err;
err = RequireMember(target, group); err = RequireMember(target, group);
if (err != null) return err; if (err != null)
return err;
err = RequireNotAlreadyOwner(group, target); err = RequireNotAlreadyOwner(group, target);
if (err != null) return err; if (err != null)
return err;
return Stage(playerUid, $"Ownership of '{groupName}' will be transferred to {target.PlayerName}.", return Stage(
() => ExecuteTransferOwnership(group, target)); playerUid,
$"Ownership of '{groupName}' will be transferred to {target.PlayerName}.",
() => ExecuteTransferOwnership(group, target)
);
} }
private static TextCommandResult? RequireNotAlreadyOwner(PlayerGroup group, IPlayer target) private static TextCommandResult? RequireNotAlreadyOwner(PlayerGroup group, IPlayer target)
@@ -367,13 +497,15 @@ public static class ClaimLinkChatCommand
// TODO remove debug logging once transfer ownership persistence is confirmed tested // TODO remove debug logging once transfer ownership persistence is confirmed tested
ClaimLinkModSystem.Logger.Notification( ClaimLinkModSystem.Logger.Notification(
$"claimlink: transferownership '{group.Name}' (uid {group.Uid}) BEFORE OwnerUID={oldOwnerUid} " + $"claimlink: transferownership '{group.Name}' (uid {group.Uid}) BEFORE OwnerUID={oldOwnerUid} "
$"(old owner {oldOwner?.PlayerName ?? oldOwnerUid} level={oldOwnerLevel}, new owner {target.PlayerName}/{targetUid} level={targetLevel})"); + $"(old owner {oldOwner?.PlayerName ?? oldOwnerUid} level={oldOwnerLevel}, new owner {target.PlayerName}/{targetUid} level={targetLevel})"
);
group.OwnerUID = targetUid; group.OwnerUID = targetUid;
ClaimLinkModSystem.Logger.Notification( ClaimLinkModSystem.Logger.Notification(
$"claimlink: transferownership '{group.Name}' (uid {group.Uid}) AFTER OwnerUID={group.OwnerUID}"); $"claimlink: transferownership '{group.Name}' (uid {group.Uid}) AFTER OwnerUID={group.OwnerUID}"
);
return TextCommandResult.Success($"'{group.Name}' is now owned by {target.PlayerName}."); return TextCommandResult.Success($"'{group.Name}' is now owned by {target.PlayerName}.");
} }
@@ -383,18 +515,20 @@ public static class ClaimLinkChatCommand
string groupName = (string)args[0]; string groupName = (string)args[0];
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); err = TryResolveClaimLink(group, out ClaimLink link);
if (err != null) return err; if (err != null)
return err;
return TextCommandResult.Success(FormatInfo(groupName, link)); return TextCommandResult.Success(FormatInfo(groupName, link));
} }
public static TextCommandResult List(TextCommandCallingArgs args) public static TextCommandResult List(TextCommandCallingArgs args)
{ {
List<ClaimLink> links = ClaimLinkModSystem.Registry.All List<ClaimLink> links = ClaimLinkModSystem
.OrderByDescending(l => l.Members.Count) .Registry.All.OrderByDescending(l => l.Members.Count)
.ToList(); .ToList();
if (links.Count == 0) if (links.Count == 0)
@@ -406,7 +540,9 @@ 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($" {groupName}: {link.Members.Count} member{(link.Members.Count == 1 ? "" : "s")}"); sb.AppendLine(
$" {groupName}: {link.Members.Count} member{(link.Members.Count == 1 ? "" : "s")}"
);
} }
return TextCommandResult.Success(sb.ToString()); return TextCommandResult.Success(sb.ToString());
@@ -414,7 +550,15 @@ public static class ClaimLinkChatCommand
private static string DescribeClaim(string ownerPlayerUid, int localIndex) private static string DescribeClaim(string ownerPlayerUid, int localIndex)
{ {
if (!ClaimLinkModSystem.TryResolveOwnedClaim(ownerPlayerUid, localIndex, out _, out LandClaim? claim) || claim == null) if (
!ClaimLinkModSystem.TryResolveOwnedClaim(
ownerPlayerUid,
localIndex,
out _,
out LandClaim? claim
)
|| claim == null
)
return $"claim {localIndex}"; return $"claim {localIndex}";
return string.IsNullOrEmpty(claim.Description) ? $"claim {localIndex}" : claim.Description; return string.IsNullOrEmpty(claim.Description) ? $"claim {localIndex}" : claim.Description;
@@ -423,39 +567,57 @@ public static class ClaimLinkChatCommand
private static string FormatInfo(string groupName, ClaimLink link) private static string FormatInfo(string groupName, ClaimLink link)
{ {
StringBuilder sb = new(); StringBuilder sb = new();
sb.AppendLine($"Claim link '{groupName}' ({link.Members.Count} member{(link.Members.Count == 1 ? "" : "s")}):"); sb.AppendLine(
$"Claim link '{groupName}' ({link.Members.Count} member{(link.Members.Count == 1 ? "" : "s")}):"
);
foreach (ClaimLinkMember member in link.Members) foreach (ClaimLinkMember member in link.Members)
{ {
string name = ClaimLinkModSystem.World.PlayerByUid(member.OwnerPlayerUid)?.PlayerName ?? member.OwnerPlayerUid; string name =
IEnumerable<string> claims = member.LocalClaimIndices.Select(i => DescribeClaim(member.OwnerPlayerUid, i)); ClaimLinkModSystem.World.PlayerByUid(member.OwnerPlayerUid)?.PlayerName
sb.AppendLine($" {name}: claims [{string.Join(", ", claims)}]"); ?? member.OwnerPlayerUid;
IEnumerable<string> claims = member.LocalClaimIndices.Select(i =>
DescribeClaim(member.OwnerPlayerUid, i)
);
sb.AppendLine($" {name}: [{string.Join(", ", claims)}]");
} }
return sb.ToString(); return sb.ToString();
} }
public static TextCommandResult AdminDelete(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink admin delete"); public static TextCommandResult AdminDelete(TextCommandCallingArgs args) =>
public static TextCommandResult AdminUnlink(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink admin unlink"); TextCommandResult.Success("stub: claimlink admin delete");
public static TextCommandResult AdminKick(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink admin kick");
public static TextCommandResult AdminUnlink(TextCommandCallingArgs args) =>
TextCommandResult.Success("stub: claimlink admin unlink");
public static TextCommandResult AdminKick(TextCommandCallingArgs args) =>
TextCommandResult.Success("stub: claimlink admin kick");
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]; IPlayer target = (IPlayer)args[1];
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 _); err = TryResolveClaimLink(group, out _);
if (err != null) return err; if (err != null)
return err;
err = RequireMember(target, group); err = RequireMember(target, group);
if (err != null) return err; if (err != null)
return err;
err = RequireNotAlreadyOwner(group, target); err = RequireNotAlreadyOwner(group, target);
if (err != null) return err; if (err != null)
return err;
return ExecuteTransferOwnership(group, target); return ExecuteTransferOwnership(group, target);
} }
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) => TextCommandResult.Success("stub: claimlink admin info");
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) =>
TextCommandResult.Success("stub: claimlink admin info");
} }