From b145fbaba8ebaf54ee37660ec523ad7f17da6fbc Mon Sep 17 00:00:00 2001 From: Lyft <127234178+Lyfts@users.noreply.github.com> Date: Fri, 17 Jan 2025 14:33:49 +0100 Subject: [PATCH] Make `/inv view` work for offline players (#177) Signed-off-by: Lyfts <127234178+Lyfts@users.noreply.github.com> --- src/main/java/serverutils/command/CmdInv.java | 43 ++++++++++++++++--- .../serverutils/command/InvSeeInventory.java | 23 +++++++--- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/main/java/serverutils/command/CmdInv.java b/src/main/java/serverutils/command/CmdInv.java index 09cc5a25f..3e0d71119 100644 --- a/src/main/java/serverutils/command/CmdInv.java +++ b/src/main/java/serverutils/command/CmdInv.java @@ -4,11 +4,16 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.stream.Collectors; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraftforge.common.util.Constants; import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; @@ -16,7 +21,8 @@ import serverutils.lib.command.CmdBase; import serverutils.lib.command.CmdTreeBase; import serverutils.lib.command.CmdTreeHelp; -import serverutils.lib.command.CommandUtils; +import serverutils.lib.data.ForgePlayer; +import serverutils.lib.data.Universe; public class CmdInv extends CmdTreeBase { @@ -27,21 +33,44 @@ public CmdView() { } @Override - public List getCommandAliases() { - return Collections.singletonList("edit"); + public List addTabCompletionOptions(ICommandSender sender, String[] args) { + if (args.length == 1) { + return Universe.get().getPlayers().stream().map(ForgePlayer::getName).collect(Collectors.toList()); + } + return super.addTabCompletionOptions(sender, args); } @Override - public boolean isUsernameIndex(String[] args, int index) { - return index == 0; + public List getCommandAliases() { + return Collections.singletonList("edit"); } @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { checkArgs(sender, args, 1); EntityPlayerMP self = getCommandSenderAsPlayer(sender); - EntityPlayerMP other = CommandUtils.getForgePlayer(sender, args[0]).getCommandPlayer(sender); - self.displayGUIChest(new InvSeeInventory(other.inventory, other)); + ForgePlayer other = Universe.get().getPlayer(args[0]); + + if (other == null || other.isFake() || other.getPlayerNBT() == null) { + throw new CommandException("commands.generic.player.notFound", args[0]); + } + + if (other.isOnline()) { + self.displayGUIChest(new InvSeeInventory(other.getPlayer().inventory, other.getPlayer())); + } else { + NBTTagCompound tag = other.getPlayerNBT(); + InventoryPlayer playerInv = new InventoryPlayer(null); + playerInv.readFromNBT(tag.getTagList("Inventory", Constants.NBT.TAG_COMPOUND)); + InvSeeInventory invSee = new InvSeeInventory(playerInv, null); + invSee.setSaveCallback(inv -> { + InventoryPlayer invPlayer = inv.getPlayerInv(); + NBTTagList invTag = new NBTTagList(); + invPlayer.writeToNBT(invTag); + tag.setTag("Inventory", invTag); + other.setPlayerNBT(tag); + }); + self.displayGUIChest(invSee); + } } } diff --git a/src/main/java/serverutils/command/InvSeeInventory.java b/src/main/java/serverutils/command/InvSeeInventory.java index ad4bc4ea5..7acc34b49 100644 --- a/src/main/java/serverutils/command/InvSeeInventory.java +++ b/src/main/java/serverutils/command/InvSeeInventory.java @@ -1,11 +1,13 @@ package serverutils.command; import java.lang.reflect.Method; +import java.util.function.Consumer; import javax.annotation.Nullable; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -20,6 +22,8 @@ public class InvSeeInventory implements IInventory { private final EntityPlayerMP player; private final IInventory baubles; private static Method getBaubles = null; + public boolean hasChanged; + private Consumer saveCallback; public InvSeeInventory(IInventory inv, @Nullable EntityPlayerMP ep) { inventory = inv; @@ -81,7 +85,11 @@ public boolean hasCustomInventoryName() { } @Override - public void closeInventory() {} + public void closeInventory() { + if (hasChanged && saveCallback != null) { + saveCallback.accept(this); + } + } @Override public ItemStack getStackInSlotOnClosing(int index) { @@ -105,6 +113,7 @@ public int getInventoryStackLimit() { @Override public void markDirty() { + hasChanged = true; inventory.markDirty(); if (player != null) { @@ -115,10 +124,6 @@ public void markDirty() { } } - public boolean isUsableByPlayer(EntityPlayer player) { - return true; - } - @Override public boolean isItemValidForSlot(int index, ItemStack stack) { int slot = slotMapping[index]; @@ -131,6 +136,14 @@ public void clear() { InvUtils.clear(baubles); } + public void setSaveCallback(Consumer callback) { + saveCallback = callback; + } + + public InventoryPlayer getPlayerInv() { + return (InventoryPlayer) inventory; + } + public static IInventory getBaubles(EntityPlayer player) { IInventory ot = null;