Try to address #115
This commit is contained in:
parent
f0b4f82f1f
commit
2238279647
@ -1229,7 +1229,9 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
|
|||||||
if (packet.getSlotId() < -1 && packet.getSlotId() != -999) {
|
if (packet.getSlotId() < -1 && packet.getSlotId() != -999) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ArclightCaptures.captureContainerOwner(this.player);
|
||||||
InventoryView inventory = ((ContainerBridge) this.player.openContainer).bridge$getBukkitView();
|
InventoryView inventory = ((ContainerBridge) this.player.openContainer).bridge$getBukkitView();
|
||||||
|
ArclightCaptures.resetContainerOwner();
|
||||||
InventoryType.SlotType type = inventory.getSlotType(packet.getSlotId());
|
InventoryType.SlotType type = inventory.getSlotType(packet.getSlotId());
|
||||||
org.bukkit.event.inventory.ClickType click = org.bukkit.event.inventory.ClickType.UNKNOWN;
|
org.bukkit.event.inventory.ClickType click = org.bukkit.event.inventory.ClickType.UNKNOWN;
|
||||||
InventoryAction action = InventoryAction.UNKNOWN;
|
InventoryAction action = InventoryAction.UNKNOWN;
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
package io.izzel.arclight.common.mixin.forge;
|
||||||
|
|
||||||
|
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
||||||
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
|
import net.minecraft.inventory.container.Container;
|
||||||
|
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
|
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@Mixin(NetworkHooks.class)
|
||||||
|
public class NetworkHooksMixin {
|
||||||
|
|
||||||
|
@Inject(method = "openGui(Lnet/minecraft/entity/player/ServerPlayerEntity;Lnet/minecraft/inventory/container/INamedContainerProvider;Ljava/util/function/Consumer;)V",
|
||||||
|
cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/container/Container;getType()Lnet/minecraft/inventory/container/ContainerType;"))
|
||||||
|
private static void arclight$openContainer(ServerPlayerEntity player, INamedContainerProvider containerSupplier, Consumer<PacketBuffer> extraDataWriter, CallbackInfo ci,
|
||||||
|
int currentId, PacketBuffer extraData, PacketBuffer output, Container container) {
|
||||||
|
((ContainerBridge) container).bridge$setTitle(containerSupplier.getDisplayName());
|
||||||
|
container = CraftEventFactory.callInventoryOpenEvent(player, container);
|
||||||
|
if (container == null) {
|
||||||
|
if (containerSupplier instanceof IInventory) {
|
||||||
|
((IInventory) containerSupplier).closeInventory(player);
|
||||||
|
}
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,29 +2,37 @@ package io.izzel.arclight.common.mod.server;
|
|||||||
|
|
||||||
import io.izzel.arclight.api.Unsafe;
|
import io.izzel.arclight.api.Unsafe;
|
||||||
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
|
import io.izzel.arclight.common.bridge.inventory.container.PosContainerBridge;
|
||||||
import io.izzel.arclight.common.mod.ArclightMod;
|
import io.izzel.arclight.common.mod.ArclightMod;
|
||||||
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.inventory.CraftResultInventory;
|
|
||||||
import net.minecraft.inventory.IInventory;
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.inventory.container.Slot;
|
import net.minecraft.inventory.container.Slot;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.SlotItemHandler;
|
import net.minecraftforge.items.SlotItemHandler;
|
||||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||||
import net.minecraftforge.items.wrapper.RangedWrapper;
|
import net.minecraftforge.items.wrapper.RangedWrapper;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
||||||
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
|
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
|
||||||
import org.bukkit.craftbukkit.v.inventory.CraftInventoryCustom;
|
|
||||||
import org.bukkit.craftbukkit.v.inventory.CraftInventoryView;
|
import org.bukkit.craftbukkit.v.inventory.CraftInventoryView;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.InventoryView;
|
import org.bukkit.inventory.InventoryView;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashSet;
|
import java.util.ArrayList;
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
public class ArclightContainer {
|
public class ArclightContainer {
|
||||||
|
|
||||||
@ -76,50 +84,157 @@ public class ArclightContainer {
|
|||||||
|
|
||||||
// todo check this
|
// todo check this
|
||||||
public static InventoryView createInvView(Container container) {
|
public static InventoryView createInvView(Container container) {
|
||||||
PlayerEntity candidate = null;
|
PlayerEntity candidate = ArclightCaptures.getContainerOwner();
|
||||||
Set<IInventory> set = new HashSet<>();
|
int bottomBegin = -1, bottomEnd = -1;
|
||||||
for (Slot slot : container.inventorySlots) {
|
for (ListIterator<Slot> iterator = container.inventorySlots.listIterator(); iterator.hasNext(); ) {
|
||||||
|
Slot slot = iterator.next();
|
||||||
IInventory inventory = getActualInventoryForSlot(slot);
|
IInventory inventory = getActualInventoryForSlot(slot);
|
||||||
if (inventory != null) {
|
|
||||||
if (inventory instanceof PlayerInventory) {
|
if (inventory instanceof PlayerInventory) {
|
||||||
if (candidate != null && ((PlayerInventory) inventory).player != candidate) {
|
if (candidate != null && ((PlayerInventory) inventory).player != candidate) {
|
||||||
ArclightMod.LOGGER.warn("Multiple player found in {}/{}, previous {}, new {}", container, container.getClass(), candidate, ((PlayerInventory) inventory).player);
|
ArclightMod.LOGGER.warn("Multiple player found in {}/{}, previous {}, new {}", container, container.getClass(), candidate, ((PlayerInventory) inventory).player);
|
||||||
}
|
}
|
||||||
candidate = ((PlayerInventory) inventory).player;
|
candidate = ((PlayerInventory) inventory).player;
|
||||||
|
if (bottomBegin == -1 || bottomBegin < bottomEnd) {
|
||||||
|
bottomBegin = iterator.previousIndex();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (bottomEnd < bottomBegin) {
|
||||||
|
bottomEnd = iterator.previousIndex();
|
||||||
}
|
}
|
||||||
set.add(inventory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (candidate == null) {
|
if (candidate == null) {
|
||||||
if (ArclightCaptures.getContainerOwner() != null) {
|
|
||||||
candidate = ArclightCaptures.getContainerOwner();
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("candidate cannot be null, " + container + "/" + container.getClass());
|
throw new RuntimeException("candidate cannot be null, " + container + "/" + container.getClass());
|
||||||
}
|
}
|
||||||
|
if (bottomBegin < bottomEnd) {
|
||||||
|
bottomBegin = container.inventorySlots.size();
|
||||||
}
|
}
|
||||||
CraftResultInventory resultCandidate = null;
|
Inventory viewing = new CraftInventory(new ContainerInvWrapper(container, bottomBegin, candidate));
|
||||||
IInventory mainCandidate = null;
|
return new CraftInventoryView(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), viewing, container);
|
||||||
for (IInventory inventory : set) {
|
}
|
||||||
if (inventory instanceof CraftResultInventory) {
|
|
||||||
resultCandidate = (CraftResultInventory) inventory;
|
private static class ContainerInvWrapper implements IInventory, IInventoryBridge {
|
||||||
} else {
|
|
||||||
mainCandidate = inventory;
|
private final Container container;
|
||||||
|
private final int size;
|
||||||
|
private InventoryHolder owner;
|
||||||
|
private final List<HumanEntity> viewers = new ArrayList<>();
|
||||||
|
|
||||||
|
public ContainerInvWrapper(Container container, int size, PlayerEntity owner) {
|
||||||
|
this.container = container;
|
||||||
|
this.size = size;
|
||||||
|
this.owner = ((PlayerEntityBridge) owner).bridge$getBukkitEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSizeInventory() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
for (Slot slot : container.inventorySlots) {
|
||||||
|
if (!slot.getStack().isEmpty()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ItemStack getStackInSlot(int index) {
|
||||||
|
if (index >= size) return ItemStack.EMPTY;
|
||||||
|
return container.getSlot(index).getStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ItemStack decrStackSize(int index, int count) {
|
||||||
|
if (index >= size) return ItemStack.EMPTY;
|
||||||
|
return container.getSlot(index).decrStackSize(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ItemStack removeStackFromSlot(int index) {
|
||||||
|
if (index >= size) return ItemStack.EMPTY;
|
||||||
|
return container.getSlot(index).decrStackSize(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInventorySlotContents(int index, @NotNull ItemStack stack) {
|
||||||
|
if (index >= size) return;
|
||||||
|
container.putStackInSlot(index, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInventoryStackLimit() {
|
||||||
|
if (size <= 0) return 0;
|
||||||
|
return container.getSlot(0).getSlotStackLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markDirty() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUsableByPlayer(@NotNull PlayerEntity player) {
|
||||||
|
return this.container.canInteractWith(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
for (Slot slot : this.container.inventorySlots) {
|
||||||
|
slot.decrStackSize(Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Inventory inv;
|
|
||||||
if (mainCandidate == null && resultCandidate != null) {
|
@Override
|
||||||
mainCandidate = resultCandidate;
|
public List<ItemStack> getContents() {
|
||||||
resultCandidate = null;
|
container.detectAndSendChanges();
|
||||||
|
return container.inventoryItemStacks.subList(0, size);
|
||||||
}
|
}
|
||||||
if (mainCandidate != null) {
|
|
||||||
if (resultCandidate != null) {
|
@Override
|
||||||
inv = new org.bukkit.craftbukkit.v.inventory.CraftResultInventory(mainCandidate, resultCandidate);
|
public void onOpen(CraftHumanEntity who) {
|
||||||
} else {
|
viewers.add(who);
|
||||||
inv = new CraftInventory(mainCandidate);
|
|
||||||
}
|
}
|
||||||
} else { // container has no slots
|
|
||||||
inv = new CraftInventoryCustom(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), 0);
|
@Override
|
||||||
|
public void onClose(CraftHumanEntity who) {
|
||||||
|
viewers.remove(who);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<HumanEntity> getViewers() {
|
||||||
|
return viewers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InventoryHolder getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOwner(InventoryHolder owner) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxStackSize(int size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location getLocation() {
|
||||||
|
if (container instanceof PosContainerBridge) {
|
||||||
|
return ((PosContainerBridge) container).bridge$getWorldLocation();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IRecipe<?> getCurrentRecipe() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentRecipe(IRecipe<?> recipe) {
|
||||||
}
|
}
|
||||||
return new CraftInventoryView(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), inv, container);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
"mixins": [
|
"mixins": [
|
||||||
"ForgeEventFactoryMixin",
|
"ForgeEventFactoryMixin",
|
||||||
"ForgeHooksMixin",
|
"ForgeHooksMixin",
|
||||||
"ForgeInternalHandlerMixin"
|
"ForgeInternalHandlerMixin",
|
||||||
|
"NetworkHooksMixin"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user