Support for mod containers.
This commit is contained in:
parent
2e6ad0cfb0
commit
8b4a000bb9
|
@ -66,6 +66,7 @@ dependencies {
|
||||||
|
|
||||||
remapSpigotJar {
|
remapSpigotJar {
|
||||||
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
||||||
|
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
|
||||||
}
|
}
|
||||||
|
|
||||||
generateArclightMeta {
|
generateArclightMeta {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package io.izzel.arclight.common.mixin.bukkit;
|
||||||
|
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
|
import net.minecraft.tileentity.LecternTileEntity;
|
||||||
|
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
|
||||||
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(value = CraftInventory.class, remap = false)
|
||||||
|
public class CraftInventoryMixin {
|
||||||
|
|
||||||
|
@Shadow @Final protected IInventory inventory;
|
||||||
|
|
||||||
|
@Inject(method = "getType", cancellable = true, at = @At("HEAD"))
|
||||||
|
private void arclight$lecternType(CallbackInfoReturnable<InventoryType> cir) {
|
||||||
|
if (inventory.getClass().getDeclaringClass() == LecternTileEntity.class) {
|
||||||
|
cir.setReturnValue(InventoryType.LECTERN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
||||||
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
import io.izzel.arclight.common.bridge.util.FoodStatsBridge;
|
||||||
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
import io.izzel.arclight.common.bridge.world.WorldBridge;
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
import io.izzel.arclight.common.mod.util.ChestBlockDoubleInventoryHacks;
|
import io.izzel.arclight.common.mod.util.ChestBlockDoubleInventoryHacks;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
@ -397,9 +398,11 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
|
||||||
|
|
||||||
@Inject(method = "sendAllContents", at = @At("RETURN"))
|
@Inject(method = "sendAllContents", at = @At("RETURN"))
|
||||||
private void arclight$sendExtra(Container container, NonNullList<ItemStack> itemsList, CallbackInfo ci) {
|
private void arclight$sendExtra(Container container, NonNullList<ItemStack> itemsList, CallbackInfo ci) {
|
||||||
|
ArclightCaptures.captureContainerOwner((ServerPlayerEntity) (Object) this);
|
||||||
if (EnumSet.of(InventoryType.CRAFTING, InventoryType.WORKBENCH).contains(((ContainerBridge) container).bridge$getBukkitView().getType())) {
|
if (EnumSet.of(InventoryType.CRAFTING, InventoryType.WORKBENCH).contains(((ContainerBridge) container).bridge$getBukkitView().getType())) {
|
||||||
this.connection.sendPacket(new SSetSlotPacket(container.windowId, 0, container.getSlot(0).getStack()));
|
this.connection.sendPacket(new SSetSlotPacket(container.windowId, 0, container.getSlot(0).getStack()));
|
||||||
}
|
}
|
||||||
|
ArclightCaptures.resetContainerOwner();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "closeScreen", at = @At("HEAD"))
|
@Inject(method = "closeScreen", at = @At("HEAD"))
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package io.izzel.arclight.common.mixin.core.inventory.container;
|
package io.izzel.arclight.common.mixin.core.inventory.container;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
|
||||||
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
|
||||||
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
import io.izzel.arclight.common.bridge.inventory.container.ContainerBridge;
|
||||||
import io.izzel.arclight.common.bridge.inventory.container.SlotBridge;
|
import io.izzel.arclight.common.bridge.inventory.container.SlotBridge;
|
||||||
|
import io.izzel.arclight.common.mod.ArclightMod;
|
||||||
|
import io.izzel.arclight.common.mod.util.ArclightCaptures;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
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.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
|
import net.minecraft.inventory.CraftResultInventory;
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.inventory.container.ClickType;
|
import net.minecraft.inventory.container.ClickType;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.inventory.container.Slot;
|
import net.minecraft.inventory.container.Slot;
|
||||||
|
@ -18,10 +23,13 @@ import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
|
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.CraftItemStack;
|
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryView;
|
import org.bukkit.inventory.InventoryView;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -31,6 +39,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -54,8 +63,59 @@ public abstract class ContainerMixin implements ContainerBridge {
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
public boolean checkReachable = true;
|
public boolean checkReachable = true;
|
||||||
|
private InventoryView bukkitView;
|
||||||
|
|
||||||
public abstract InventoryView getBukkitView();
|
// todo check this
|
||||||
|
public InventoryView getBukkitView() {
|
||||||
|
if (bukkitView == null) {
|
||||||
|
PlayerEntity candidate = null;
|
||||||
|
Set<IInventory> set = new HashSet<>();
|
||||||
|
for (Slot slot : this.inventorySlots) {
|
||||||
|
if (slot.inventory != null) {
|
||||||
|
if (slot.inventory instanceof PlayerInventory) {
|
||||||
|
if (candidate != null && ((PlayerInventory) slot.inventory).player != candidate) {
|
||||||
|
ArclightMod.LOGGER.warn("Duplicate PlayerInventory inside {}, previous {}, new {}", this, candidate, slot.inventory);
|
||||||
|
}
|
||||||
|
candidate = ((PlayerInventory) slot.inventory).player;
|
||||||
|
} else {
|
||||||
|
set.add(slot.inventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidate == null) {
|
||||||
|
if (ArclightCaptures.getContainerOwner() != null) {
|
||||||
|
candidate = ArclightCaptures.getContainerOwner();
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("candidate cannot be null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CraftResultInventory resultCandidate = null;
|
||||||
|
IInventory mainCandidate = null;
|
||||||
|
for (IInventory inventory : set) {
|
||||||
|
if (inventory instanceof CraftResultInventory) {
|
||||||
|
resultCandidate = (CraftResultInventory) inventory;
|
||||||
|
} else {
|
||||||
|
mainCandidate = inventory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Inventory inv;
|
||||||
|
if (mainCandidate == null && resultCandidate != null) {
|
||||||
|
mainCandidate = resultCandidate;
|
||||||
|
resultCandidate = null;
|
||||||
|
}
|
||||||
|
if (mainCandidate != null) {
|
||||||
|
if (resultCandidate != null) {
|
||||||
|
inv = new org.bukkit.craftbukkit.v.inventory.CraftResultInventory(mainCandidate, resultCandidate);
|
||||||
|
} else {
|
||||||
|
inv = new CraftInventory(mainCandidate);
|
||||||
|
}
|
||||||
|
} else { // container has no slots
|
||||||
|
inv = new CraftInventoryCustom(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), 0);
|
||||||
|
}
|
||||||
|
bukkitView = new CraftInventoryView(((PlayerEntityBridge) candidate).bridge$getBukkitEntity(), inv, (Container) (Object) this);
|
||||||
|
}
|
||||||
|
return bukkitView;
|
||||||
|
}
|
||||||
|
|
||||||
public void transferTo(Container other, CraftHumanEntity player) {
|
public void transferTo(Container other, CraftHumanEntity player) {
|
||||||
InventoryView source = this.getBukkitView();
|
InventoryView source = this.getBukkitView();
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.izzel.arclight.common.mod.util;
|
||||||
import io.izzel.arclight.common.mod.ArclightConstants;
|
import io.izzel.arclight.common.mod.ArclightConstants;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
@ -180,6 +181,20 @@ public class ArclightCaptures {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static transient PlayerEntity containerOwner;
|
||||||
|
|
||||||
|
public static void captureContainerOwner(PlayerEntity entity) {
|
||||||
|
containerOwner = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerEntity getContainerOwner() {
|
||||||
|
return containerOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetContainerOwner() {
|
||||||
|
containerOwner = null;
|
||||||
|
}
|
||||||
|
|
||||||
private static void recapture(String type) {
|
private static void recapture(String type) {
|
||||||
throw new IllegalStateException("Recapturing " + type);
|
throw new IllegalStateException("Recapturing " + type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"CraftConsoleCommandSenderMixin",
|
"CraftConsoleCommandSenderMixin",
|
||||||
"CraftEntityMixin",
|
"CraftEntityMixin",
|
||||||
"CraftEventFactoryMixin",
|
"CraftEventFactoryMixin",
|
||||||
|
"CraftInventoryMixin",
|
||||||
"CraftItemFactoryMixin",
|
"CraftItemFactoryMixin",
|
||||||
"CraftMagicNumbersMixin",
|
"CraftMagicNumbersMixin",
|
||||||
"CraftServerMixin",
|
"CraftServerMixin",
|
||||||
|
|
|
@ -115,6 +115,7 @@ jar {
|
||||||
|
|
||||||
remapSpigotJar {
|
remapSpigotJar {
|
||||||
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
||||||
|
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
|
|
|
@ -115,6 +115,7 @@ jar {
|
||||||
|
|
||||||
remapSpigotJar {
|
remapSpigotJar {
|
||||||
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
|
||||||
|
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin {
|
mixin {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user