fix: transferownership correctly sets owner level and demotes old owner to op, works for offline players, notifies members
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Vintagestory.API.Common;
|
||||
using Vintagestory.API.Config;
|
||||
using Vintagestory.API.Server;
|
||||
|
||||
namespace ClaimLink;
|
||||
@@ -117,7 +118,7 @@ public static class ClaimLinkChatCommand
|
||||
new(
|
||||
new[] { "transferownership", "transfer", "to" },
|
||||
"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,
|
||||
TransferOwnership
|
||||
),
|
||||
@@ -170,7 +171,7 @@ public static class ClaimLinkChatCommand
|
||||
new(
|
||||
new[] { "transferownership", "transfer", "to" },
|
||||
"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,
|
||||
AdminTransferOwnership
|
||||
),
|
||||
@@ -449,15 +450,21 @@ public static class ClaimLinkChatCommand
|
||||
public static TextCommandResult TransferOwnership(TextCommandCallingArgs args)
|
||||
{
|
||||
string groupName = (string)args[0];
|
||||
IPlayer target = (IPlayer)args[1];
|
||||
IPlayer player = args.Caller.Player;
|
||||
string playerUid = player.PlayerUID;
|
||||
|
||||
TextCommandResult? err = TryResolveGroup(groupName, out PlayerGroup group);
|
||||
TextCommandResult? err = TryResolveTargetPlayer(
|
||||
(PlayerUidName[])args[1],
|
||||
out IPlayer target
|
||||
);
|
||||
if (err != null)
|
||||
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)
|
||||
return err;
|
||||
|
||||
@@ -476,10 +483,28 @@ public static class ClaimLinkChatCommand
|
||||
return Stage(
|
||||
playerUid,
|
||||
$"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)
|
||||
{
|
||||
return target.PlayerUID == group.OwnerUID
|
||||
@@ -487,27 +512,39 @@ public static class ClaimLinkChatCommand
|
||||
: null;
|
||||
}
|
||||
|
||||
private static TextCommandResult ExecuteTransferOwnership(PlayerGroup group, IPlayer target)
|
||||
private static TextCommandResult ExecuteTransferOwnership(
|
||||
PlayerGroup group,
|
||||
ClaimLink link,
|
||||
IPlayer target
|
||||
)
|
||||
{
|
||||
string oldOwnerUid = group.OwnerUID;
|
||||
string targetUid = target.PlayerUID;
|
||||
IPlayer? oldOwner = ClaimLinkModSystem.World.PlayerByUid(oldOwnerUid);
|
||||
EnumPlayerGroupMemberShip? oldOwnerLevel = oldOwner?.GetGroup(group.Uid)?.Level;
|
||||
EnumPlayerGroupMemberShip targetLevel = target.GetGroup(group.Uid)!.Level;
|
||||
PlayerGroupMembership? oldOwnerMembership = oldOwner?.GetGroup(group.Uid);
|
||||
PlayerGroupMembership targetMembership = target.GetGroup(group.Uid)!;
|
||||
|
||||
// TODO remove debug logging once transfer ownership persistence is confirmed tested
|
||||
ClaimLinkModSystem.Logger.Notification(
|
||||
$"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 = target.PlayerUID;
|
||||
targetMembership.Level = EnumPlayerGroupMemberShip.Owner;
|
||||
|
||||
group.OwnerUID = targetUid;
|
||||
if (oldOwnerMembership != null)
|
||||
oldOwnerMembership.Level = EnumPlayerGroupMemberShip.Op;
|
||||
|
||||
ClaimLinkModSystem.Logger.Notification(
|
||||
$"claimlink: transferownership '{group.Name}' (uid {group.Uid}) AFTER OwnerUID={group.OwnerUID}"
|
||||
);
|
||||
string notice = $"'{group.Name}' is now owned by {target.PlayerName}.";
|
||||
|
||||
return TextCommandResult.Success($"'{group.Name}' is now owned by {target.PlayerName}.");
|
||||
HashSet<string> notifyUids = link.Members.Select(m => m.OwnerPlayerUid).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)
|
||||
@@ -597,13 +634,19 @@ public static class ClaimLinkChatCommand
|
||||
public static TextCommandResult AdminTransferOwnership(TextCommandCallingArgs args)
|
||||
{
|
||||
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)
|
||||
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)
|
||||
return err;
|
||||
|
||||
@@ -615,7 +658,7 @@ public static class ClaimLinkChatCommand
|
||||
if (err != null)
|
||||
return err;
|
||||
|
||||
return ExecuteTransferOwnership(group, target);
|
||||
return ExecuteTransferOwnership(group, link, target);
|
||||
}
|
||||
|
||||
public static TextCommandResult AdminInfo(TextCommandCallingArgs args) =>
|
||||
|
||||
Reference in New Issue
Block a user