Compare commits

..

4 Commits

Author SHA1 Message Date
Jikoo
1dd28ac0eb Cursor/crafting progress 2019-10-02 07:09:42 -04:00
Jikoo
ff76f2b95a Update copyright
Practically should make it 2020 at this rate, whoops
2019-10-02 06:52:47 -04:00
Jikoo
b92543e078 Clean up maven instructions 2019-10-02 06:48:14 -04:00
Jikoo
252ca34e42 Initial attempt at #92 2019-10-01 11:55:59 -04:00
22 changed files with 858 additions and 796 deletions

View File

@@ -21,7 +21,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvparent</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvapi</artifactId>

View File

@@ -21,7 +21,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvparent</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvassembly</artifactId>

View File

@@ -21,7 +21,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvparent</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvcommon</artifactId>
@@ -31,7 +31,7 @@
<dependency>
<groupId>com.lishid</groupId>
<artifactId>openinvapi</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>

View File

@@ -19,11 +19,11 @@ package com.lishid.openinv.util;
import com.google.common.collect.Multimap;
import com.google.common.collect.TreeMultimap;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* A minimal thread-safe time-based cache implementation backed by a HashMap and TreeMultimap.
@@ -45,20 +45,9 @@ public class Cache<K, V> {
* @param postRemoval Function used to perform any operations required when a key is invalidated
*/
public Cache(final long retention, final Function<V> inUseCheck, final Function<V> postRemoval) {
this.internal = new HashMap<K, V>();
this.internal = new HashMap<>();
this.expiry = TreeMultimap.create(new Comparator<Long>() {
@Override
public int compare(final Long long1, final Long long2) {
return long1.compareTo(long2);
}
},
new Comparator<K>() {
@Override
public int compare(final K k1, final K k2) {
return k1 == k2 || k1 != null && k1.equals(k2) ? 0 : 1;
}
});
this.expiry = TreeMultimap.create(Long::compareTo, (k1, k2) -> Objects.equals(k1, k2) ? 0 : 1);
this.retention = retention;
this.inUseCheck = inUseCheck;
@@ -160,7 +149,7 @@ public class Cache<K, V> {
private void lazyCheck() {
long now = System.currentTimeMillis();
synchronized (this.internal) {
List<K> inUse = new ArrayList<K>();
List<K> inUse = new ArrayList<>();
for (Iterator<Map.Entry<Long, K>> iterator = this.expiry.entries().iterator(); iterator
.hasNext();) {
Map.Entry<Long, K> entry = iterator.next();

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2011-2019 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.util;
/**
* Simple tuple.
*
* @param <L> the left value
* @param <R> the right value
*
* @author Jikoo
*/
public class Pair<L, R> {
private L left;
private R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public L getLeft() {
return left;
}
public void setLeft(L left) {
this.left = left;
}
public R getRight() {
return right;
}
public void setRight(R right) {
this.right = right;
}
}

View File

@@ -0,0 +1,201 @@
/*
* Copyright (C) 2011-2019 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.util;
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;
/**
* A List implementation intended for wrapping a single field.
*
* @param <V> the type of the field
*
* @author Jikoo
*/
public class SingleFieldList<V> extends AbstractCollection<V> implements List<V> {
private final Supplier<V> fieldGetter;
private final Consumer<V> fieldSetter;
public SingleFieldList(@NotNull Supplier<V> fieldGetter, @NotNull Consumer<V> fieldSetter) {
this.fieldGetter = fieldGetter;
this.fieldSetter = fieldSetter;
}
@Override
public int size() {
return 1;
}
@Override
public boolean contains(Object o) {
return Objects.equals(o, fieldGetter.get());
}
@NotNull
@Override
public Iterator<V> iterator() {
return listIterator();
}
@Override
public boolean addAll(int index, @NotNull Collection<? extends V> c) {
return super.addAll(c);
}
@Override
public boolean equals(Object o) {
return o instanceof SingleFieldList
&& fieldGetter.equals(((SingleFieldList) o).fieldGetter)
&& fieldSetter.equals(((SingleFieldList) o).fieldSetter);
}
@Override
public int hashCode() {
return fieldSetter.hashCode() * 17 * fieldGetter.hashCode();
}
@Override
public V get(int index) {
if (index != 0) {
throw new IndexOutOfBoundsException();
}
return fieldGetter.get();
}
@Override
public V set(int index, V element) {
if (index != 0) {
throw new IndexOutOfBoundsException();
}
V old = fieldGetter.get();
fieldSetter.accept(element);
return old;
}
@Override
public void add(int index, V element) {
throw new UnsupportedOperationException();
}
@Override
public V remove(int index) {
throw new UnsupportedOperationException();
}
@Override
public int indexOf(Object o) {
return fieldGetter.get().equals(o) ? 0 : -1;
}
@Override
public int lastIndexOf(Object o) {
return indexOf(o);
}
@NotNull
@Override
public ListIterator<V> listIterator() {
return new ListIterator<V>() {
private boolean hasNext = true;
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public V next() {
if (!hasNext) {
throw new NoSuchElementException();
}
return fieldGetter.get();
}
@Override
public boolean hasPrevious() {
return !hasNext;
}
@Override
public V previous() {
if (hasNext) {
throw new NoSuchElementException();
}
return fieldGetter.get();
}
@Override
public int nextIndex() {
return hasNext ? 0 : 1;
}
@Override
public int previousIndex() {
return hasNext ? -1 : 0;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void set(V v) {
fieldSetter.accept(v);
}
@Override
public void add(V v) {
throw new UnsupportedOperationException();
}
};
}
@NotNull
@Override
public ListIterator<V> listIterator(int index) {
if (index != 0) {
throw new IndexOutOfBoundsException();
}
return listIterator();
}
@NotNull
@Override
public List<V> subList(int fromIndex, int toIndex) {
if (fromIndex != 0 || toIndex != 1) {
throw new IndexOutOfBoundsException();
}
return this;
}
@Override
public void clear() {}
}

View File

@@ -20,7 +20,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvparent</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvinternal</artifactId>
@@ -34,8 +34,8 @@
<id>all</id>
<modules>
<module>v1_8_R3</module>
<module>v1_13_R2</module>
<module>v1_14_R1</module>
<module>v1_15_R1</module>
</modules>
</profile>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (C) 2011-2019 lishid. All rights reserved.
~
@@ -22,23 +21,23 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvinternal</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvadapter1_15_R1</artifactId>
<name>OpenInvAdapter1_15_R1</name>
<artifactId>openinvadapter1_13_R2</artifactId>
<name>OpenInvAdapter1_13_R2</name>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.15-R0.1-SNAPSHOT</version>
<version>1.13.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.lishid</groupId>
<artifactId>openinvcommon</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -0,0 +1,309 @@
/*
* Copyright (C) 2011-2019 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_13_R2;
import com.lishid.openinv.internal.IAnySilentContainer;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import net.minecraft.server.v1_13_R2.AxisAlignedBB;
import net.minecraft.server.v1_13_R2.Block;
import net.minecraft.server.v1_13_R2.BlockChest;
import net.minecraft.server.v1_13_R2.BlockChestTrapped;
import net.minecraft.server.v1_13_R2.BlockEnderChest;
import net.minecraft.server.v1_13_R2.BlockPosition;
import net.minecraft.server.v1_13_R2.BlockPropertyChestType;
import net.minecraft.server.v1_13_R2.BlockShulkerBox;
import net.minecraft.server.v1_13_R2.ChatMessage;
import net.minecraft.server.v1_13_R2.Entity;
import net.minecraft.server.v1_13_R2.EntityOcelot;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.EnumDirection;
import net.minecraft.server.v1_13_R2.EnumGamemode;
import net.minecraft.server.v1_13_R2.IBlockData;
import net.minecraft.server.v1_13_R2.ITileInventory;
import net.minecraft.server.v1_13_R2.InventoryEnderChest;
import net.minecraft.server.v1_13_R2.InventoryLargeChest;
import net.minecraft.server.v1_13_R2.PlayerInteractManager;
import net.minecraft.server.v1_13_R2.TileEntity;
import net.minecraft.server.v1_13_R2.TileEntityChest;
import net.minecraft.server.v1_13_R2.TileEntityEnderChest;
import net.minecraft.server.v1_13_R2.TileEntityShulkerBox;
import net.minecraft.server.v1_13_R2.VoxelShape;
import net.minecraft.server.v1_13_R2.VoxelShapes;
import net.minecraft.server.v1_13_R2.World;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.NotNull;
public class AnySilentContainer implements IAnySilentContainer {
private Field playerInteractManagerGamemode;
public AnySilentContainer() {
try {
this.playerInteractManagerGamemode = PlayerInteractManager.class.getDeclaredField("gamemode");
this.playerInteractManagerGamemode.setAccessible(true);
} catch (NoSuchFieldException | SecurityException e) {
System.err.println("[OpenInv] Unable to directly write player gamemode! SilentChest will fail.");
e.printStackTrace();
}
}
@Override
public boolean isAnySilentContainer(@NotNull final org.bukkit.block.Block bukkitBlock) {
if (bukkitBlock.getType() == Material.ENDER_CHEST) {
return true;
}
BlockState state = bukkitBlock.getState();
return state instanceof org.bukkit.block.Chest
|| state instanceof org.bukkit.block.ShulkerBox;
}
@Override
public boolean isAnyContainerNeeded(@NotNull final Player bukkitPlayer, @NotNull final org.bukkit.block.Block bukkitBlock) {
World world = PlayerDataManager.getHandle(bukkitPlayer).world;
BlockPosition blockPosition = new BlockPosition(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ());
IBlockData blockData = world.getType(blockPosition);
Block block = blockData.getBlock();
if (block instanceof BlockShulkerBox) {
return this.isBlockedShulkerBox(world, blockPosition, blockData);
}
if (block instanceof BlockEnderChest) {
// Ender chests are not blocked by ocelots.
return world.getType(blockPosition.up()).isOccluding();
}
// Check if chest is blocked or has an ocelot on top
if (this.isBlockedChest(world, blockPosition)) {
return true;
}
// Check for matching adjacent chests that are blocked or have an ocelot on top
BlockPropertyChestType chestType = blockData.get(BlockChest.b);
if (chestType == BlockPropertyChestType.SINGLE) {
return false;
}
BlockPosition adjacentBlockPosition = blockPosition.shift(BlockChest.k(blockData));
IBlockData adjacentBlockData = world.getType(adjacentBlockPosition);
if (adjacentBlockData.getBlock() == block) {
BlockPropertyChestType adjacentChestType = adjacentBlockData.get(BlockChest.b);
if (adjacentChestType != BlockPropertyChestType.SINGLE && chestType != adjacentChestType
&& adjacentBlockData.get(BlockChest.FACING) == blockData.get(BlockChest.FACING)) {
return this.isBlockedChest(world, adjacentBlockPosition);
}
}
return false;
}
private boolean isBlockedShulkerBox(final World world, final BlockPosition blockPosition,
final IBlockData blockData) {
// For reference, look at net.minecraft.server.BlockShulkerBox
TileEntity tile = world.getTileEntity(blockPosition);
if (!(tile instanceof TileEntityShulkerBox)) {
return false;
}
EnumDirection enumDirection = blockData.get(BlockShulkerBox.a);
if (((TileEntityShulkerBox) tile).r() == TileEntityShulkerBox.AnimationPhase.CLOSED) {
AxisAlignedBB axisAlignedBB;
try {
Method method = VoxelShape.class.getMethod("a");
axisAlignedBB = (AxisAlignedBB) method.invoke(VoxelShapes.b());
} catch (NoSuchMethodException e) {
axisAlignedBB = VoxelShapes.b().getBoundingBox();
} catch (InvocationTargetException | IllegalAccessException e) {
return false;
}
axisAlignedBB = axisAlignedBB
.b(0.5F * enumDirection.getAdjacentX(), 0.5F * enumDirection.getAdjacentY(), 0.5F * enumDirection.getAdjacentZ())
.a(enumDirection.getAdjacentX(), enumDirection.getAdjacentY(), enumDirection.getAdjacentZ());
return !world.getCubes(null, axisAlignedBB.a(blockPosition.shift(enumDirection)));
}
return false;
}
private boolean isBlockedChest(final World world, final BlockPosition blockPosition) {
// For reference, loot at net.minecraft.server.BlockChest
return world.getType(blockPosition.up()).isOccluding() || this.hasOcelotOnTop(world, blockPosition);
}
private boolean hasOcelotOnTop(final World world, final BlockPosition blockPosition) {
for (Entity entity : world.a(EntityOcelot.class,
new AxisAlignedBB(blockPosition.getX(), blockPosition.getY() + 1,
blockPosition.getZ(), blockPosition.getX() + 1, blockPosition.getY() + 2,
blockPosition.getZ() + 1))) {
EntityOcelot entityOcelot = (EntityOcelot) entity;
if (entityOcelot.isSitting()) {
return true;
}
}
return false;
}
@Override
public boolean activateContainer(@NotNull final Player bukkitPlayer, final boolean silent,
@NotNull final org.bukkit.block.Block bukkitBlock) {
// Silent ender chest is API-only
if (silent && bukkitBlock.getType() == Material.ENDER_CHEST) {
bukkitPlayer.openInventory(bukkitPlayer.getEnderChest());
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
return true;
}
EntityPlayer player = PlayerDataManager.getHandle(bukkitPlayer);
final World world = player.world;
final BlockPosition blockPosition = new BlockPosition(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ());
final Object tile = world.getTileEntity(blockPosition);
if (tile == null) {
return false;
}
if (tile instanceof TileEntityEnderChest) {
// Anychest ender chest. See net.minecraft.server.BlockEnderChest
InventoryEnderChest enderChest = player.getEnderChest();
enderChest.a((TileEntityEnderChest) tile);
player.openContainer(enderChest);
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
return true;
}
if (!(tile instanceof ITileInventory)) {
return false;
}
ITileInventory tileInventory = (ITileInventory) tile;
IBlockData blockData = world.getType(blockPosition);
Block block = blockData.getBlock();
if (block instanceof BlockChest) {
BlockPropertyChestType chestType = blockData.get(BlockChest.b);
if (chestType != BlockPropertyChestType.SINGLE) {
BlockPosition adjacentBlockPosition = blockPosition.shift(BlockChest.k(blockData));
IBlockData adjacentBlockData = world.getType(adjacentBlockPosition);
if (adjacentBlockData.getBlock() == block) {
BlockPropertyChestType adjacentChestType = adjacentBlockData.get(BlockChest.b);
if (adjacentChestType != BlockPropertyChestType.SINGLE && chestType != adjacentChestType
&& adjacentBlockData.get(BlockChest.FACING) == blockData.get(BlockChest.FACING)) {
TileEntity adjacentTile = world.getTileEntity(adjacentBlockPosition);
if (adjacentTile instanceof TileEntityChest) {
ITileInventory rightChest = chestType == BlockPropertyChestType.RIGHT ? tileInventory : (ITileInventory) adjacentTile;
ITileInventory leftChest = chestType == BlockPropertyChestType.RIGHT ? (ITileInventory) adjacentTile : tileInventory;
tileInventory = new InventoryLargeChest(new ChatMessage("container.chestDouble"), rightChest, leftChest);
}
}
}
}
if (block instanceof BlockChestTrapped) {
bukkitPlayer.incrementStatistic(Statistic.TRAPPED_CHEST_TRIGGERED);
} else {
bukkitPlayer.incrementStatistic(Statistic.CHEST_OPENED);
}
}
if (block instanceof BlockShulkerBox) {
bukkitPlayer.incrementStatistic(Statistic.SHULKER_BOX_OPENED);
}
// AnyChest only - SilentChest not active, container unsupported, or unnecessary.
if (!silent || player.playerInteractManager.getGameMode() == EnumGamemode.SPECTATOR) {
player.openContainer(tileInventory);
return true;
}
// SilentChest requires access to setting players' gamemode directly.
if (this.playerInteractManagerGamemode == null) {
return false;
}
EnumGamemode gamemode = player.playerInteractManager.getGameMode();
this.forceGameMode(player, EnumGamemode.SPECTATOR);
player.openContainer(tileInventory);
this.forceGameMode(player, gamemode);
return true;
}
@Override
public void deactivateContainer(@NotNull final Player bukkitPlayer) {
if (this.playerInteractManagerGamemode == null) {
return;
}
InventoryView view = bukkitPlayer.getOpenInventory();
switch (view.getType()) {
case CHEST:
case ENDER_CHEST:
case SHULKER_BOX:
break;
default:
return;
}
EntityPlayer player = PlayerDataManager.getHandle(bukkitPlayer);
EnumGamemode gamemode = player.playerInteractManager.getGameMode();
this.forceGameMode(player, EnumGamemode.SPECTATOR);
player.activeContainer.b(player);
player.activeContainer = player.defaultContainer;
this.forceGameMode(player, gamemode);
}
private void forceGameMode(final EntityPlayer player, final EnumGamemode gameMode) {
if (this.playerInteractManagerGamemode == null) {
// No need to warn repeatedly, error on startup and lack of function should be enough.
return;
}
try {
if (!this.playerInteractManagerGamemode.isAccessible()) {
// Just in case, ensure accessible.
this.playerInteractManagerGamemode.setAccessible(true);
}
this.playerInteractManagerGamemode.set(player.playerInteractManager, gameMode);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2011-2019 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_13_R2;
import com.lishid.openinv.internal.IPlayerDataManager;
import com.lishid.openinv.internal.ISpecialInventory;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.v1_13_R2.DimensionManager;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.MinecraftServer;
import net.minecraft.server.v1_13_R2.PlayerInteractManager;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.craftbukkit.v1_13_R2.CraftServer;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.NotNull;
public class PlayerDataManager implements IPlayerDataManager {
public static EntityPlayer getHandle(final Player player) {
if (player instanceof CraftPlayer) {
return ((CraftPlayer) player).getHandle();
}
Server server = player.getServer();
EntityPlayer nmsPlayer = null;
if (server instanceof CraftServer) {
nmsPlayer = ((CraftServer) server).getHandle().getPlayer(player.getName());
}
if (nmsPlayer == null) {
// Could use reflection to examine fields, but it's honestly not worth the bother.
throw new RuntimeException("Unable to fetch EntityPlayer from provided Player implementation");
}
return nmsPlayer;
}
@Override
public Player loadPlayer(@NotNull final OfflinePlayer offline) {
// Ensure player has data
if (!offline.hasPlayedBefore()) {
return null;
}
// Create a profile and entity to load the player data
GameProfile profile = new GameProfile(offline.getUniqueId(), offline.getName());
MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(DimensionManager.OVERWORLD), profile,
new PlayerInteractManager(server.getWorldServer(DimensionManager.OVERWORLD)));
// Get the bukkit entity
Player target = entity.getBukkitEntity();
if (target != null) {
// Load data
target.loadData();
}
// Return the entity
return target;
}
@Override
public InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
return player.openInventory(inventory.getBukkitInventory());
}
}

View File

@@ -14,44 +14,50 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_15_R1;
package com.lishid.openinv.internal.v1_13_R2;
import com.lishid.openinv.internal.ISpecialEnderChest;
import java.util.List;
import net.minecraft.server.v1_15_R1.AutoRecipeStackManager;
import net.minecraft.server.v1_15_R1.ContainerUtil;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.IInventoryListener;
import net.minecraft.server.v1_15_R1.InventoryEnderChest;
import net.minecraft.server.v1_15_R1.ItemStack;
import net.minecraft.server.v1_15_R1.NonNullList;
import javax.annotation.Nullable;
import net.minecraft.server.v1_13_R2.AutoRecipeOutput;
import net.minecraft.server.v1_13_R2.AutoRecipeStackManager;
import net.minecraft.server.v1_13_R2.ContainerUtil;
import net.minecraft.server.v1_13_R2.EntityHuman;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.IChatBaseComponent;
import net.minecraft.server.v1_13_R2.IInventory;
import net.minecraft.server.v1_13_R2.IInventoryListener;
import net.minecraft.server.v1_13_R2.InventoryEnderChest;
import net.minecraft.server.v1_13_R2.ItemStack;
import net.minecraft.server.v1_13_R2.NonNullList;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftInventory;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;
public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEnderChest {
public class SpecialEnderChest implements IInventory, ISpecialEnderChest, AutoRecipeOutput {
private final CraftInventory inventory;
private EntityPlayer owner;
private final IChatBaseComponent displayName;
private final CraftInventory inventory;
private NonNullList<ItemStack> items;
private boolean playerOnline;
public SpecialEnderChest(final Player player, final Boolean online) {
super(PlayerDataManager.getHandle(player));
this.inventory = new CraftInventory(this);
this.owner = PlayerDataManager.getHandle(player);
this.playerOnline = online;
this.displayName = this.owner.getEnderChest().getDisplayName();
this.inventory = new CraftInventory(this);
this.items = this.owner.getEnderChest().items;
this.playerOnline = online;
}
@Override
public @NotNull CraftInventory getBukkitInventory() {
return inventory;
public @NotNull Inventory getBukkitInventory() {
return this.inventory;
}
@Override
@@ -84,57 +90,46 @@ public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEn
this.owner.getEnderChest().update();
}
@Override
public List<ItemStack> getContents() {
return this.items;
}
@Override
public void onOpen(CraftHumanEntity who) {
this.owner.getEnderChest().onOpen(who);
}
@Override
public void onClose(CraftHumanEntity who) {
this.owner.getEnderChest().onClose(who);
}
@Override
public List<HumanEntity> getViewers() {
return this.owner.getEnderChest().getViewers();
}
@Override
public void setMaxStackSize(int i) {
this.owner.getEnderChest().setMaxStackSize(i);
}
@Override
public InventoryHolder getOwner() {
return this.owner.getEnderChest().getOwner();
}
@Override
public Location getLocation() {
return null;
}
@Override
public void a(IInventoryListener iinventorylistener) {
this.owner.getEnderChest().a(iinventorylistener);
}
@Override
public void b(IInventoryListener iinventorylistener) {
this.owner.getEnderChest().b(iinventorylistener);
}
@Override
public ItemStack getItem(int i) {
return i >= 0 && i < this.items.size() ? this.items.get(i) : ItemStack.a;
}
@Override
public ItemStack splitStack(int i, int j) {
ItemStack itemstack = ContainerUtil.a(this.items, i, j);
if (!itemstack.isEmpty()) {
@@ -144,7 +139,6 @@ public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEn
return itemstack;
}
@Override
public ItemStack a(ItemStack itemstack) {
ItemStack itemstack1 = itemstack.cloneItemStack();
@@ -177,7 +171,6 @@ public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEn
return itemstack1;
}
@Override
public ItemStack splitWithoutUpdate(int i) {
ItemStack itemstack = this.items.get(i);
if (itemstack.isEmpty()) {
@@ -188,7 +181,6 @@ public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEn
}
}
@Override
public void setItem(int i, ItemStack itemstack) {
this.items.set(i, itemstack);
if (!itemstack.isEmpty() && itemstack.getCount() > this.getMaxStackSize()) {
@@ -198,13 +190,11 @@ public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEn
this.update();
}
@Override
public int getSize() {
return this.owner.getEnderChest().getSize();
}
@Override
public boolean isNotEmpty() {
public boolean P_() {
for (ItemStack itemstack : this.items) {
if (!itemstack.isEmpty()) {
@@ -215,35 +205,56 @@ public class SpecialEnderChest extends InventoryEnderChest implements ISpecialEn
return true;
}
@Override
public IChatBaseComponent getDisplayName() {
return this.displayName;
}
@Nullable
public IChatBaseComponent getCustomName() {
return this.displayName;
}
public boolean hasCustomName() {
return false;
}
public void a(@Nullable IChatBaseComponent ichatbasecomponent) {
// Ignored - name is always player's name.
}
public int getMaxStackSize() {
return 64;
}
@Override
public boolean a(EntityHuman entityhuman) {
return true;
}
@Override
public void startOpen(EntityHuman entityhuman) {
}
@Override
public void closeContainer(EntityHuman entityhuman) {
}
@Override
public boolean b(int i, ItemStack itemstack) {
return true;
}
@Override
public int getProperty(int i) {
return 0;
}
public void setProperty(int i, int j) {
}
public int h() {
return 0;
}
public void clear() {
this.items.clear();
}
@Override
public void a(AutoRecipeStackManager autorecipestackmanager) {
for (ItemStack itemstack : this.items) {

View File

@@ -14,56 +14,53 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_15_R1;
package com.lishid.openinv.internal.v1_13_R2;
import com.google.common.collect.ImmutableList;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import net.minecraft.server.v1_15_R1.AutoRecipeStackManager;
import net.minecraft.server.v1_15_R1.ChatMessage;
import net.minecraft.server.v1_15_R1.ContainerUtil;
import net.minecraft.server.v1_15_R1.CrashReport;
import net.minecraft.server.v1_15_R1.CrashReportSystemDetails;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.EnumItemSlot;
import net.minecraft.server.v1_15_R1.IBlockData;
import net.minecraft.server.v1_15_R1.IChatBaseComponent;
import net.minecraft.server.v1_15_R1.Item;
import net.minecraft.server.v1_15_R1.ItemArmor;
import net.minecraft.server.v1_15_R1.ItemStack;
import net.minecraft.server.v1_15_R1.NBTTagCompound;
import net.minecraft.server.v1_15_R1.NBTTagList;
import net.minecraft.server.v1_15_R1.NonNullList;
import net.minecraft.server.v1_15_R1.PacketPlayOutSetSlot;
import net.minecraft.server.v1_15_R1.PlayerInventory;
import net.minecraft.server.v1_15_R1.ReportedException;
import net.minecraft.server.v1_15_R1.World;
import javax.annotation.Nullable;
import net.minecraft.server.v1_13_R2.AutoRecipeStackManager;
import net.minecraft.server.v1_13_R2.ChatMessage;
import net.minecraft.server.v1_13_R2.ContainerUtil;
import net.minecraft.server.v1_13_R2.CrashReport;
import net.minecraft.server.v1_13_R2.CrashReportSystemDetails;
import net.minecraft.server.v1_13_R2.EntityHuman;
import net.minecraft.server.v1_13_R2.EntityPlayer;
import net.minecraft.server.v1_13_R2.IBlockData;
import net.minecraft.server.v1_13_R2.IChatBaseComponent;
import net.minecraft.server.v1_13_R2.Item;
import net.minecraft.server.v1_13_R2.ItemArmor;
import net.minecraft.server.v1_13_R2.ItemStack;
import net.minecraft.server.v1_13_R2.NBTTagCompound;
import net.minecraft.server.v1_13_R2.NBTTagList;
import net.minecraft.server.v1_13_R2.NonNullList;
import net.minecraft.server.v1_13_R2.PacketPlayOutSetSlot;
import net.minecraft.server.v1_13_R2.PlayerInventory;
import net.minecraft.server.v1_13_R2.ReportedException;
import net.minecraft.server.v1_13_R2.World;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftInventory;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SpecialPlayerInventory extends PlayerInventory implements ISpecialPlayerInventory {
private final CraftInventory inventory;
private final CraftInventory inventory = new CraftInventory(this);
private boolean playerOnline;
private EntityHuman player;
private NonNullList<ItemStack> items, armor, extraSlots;
private List<NonNullList<ItemStack>> f;
public SpecialPlayerInventory(final Player bukkitPlayer, final Boolean online) {
super(PlayerDataManager.getHandle(bukkitPlayer));
this.inventory = new CraftInventory(this);
this.playerOnline = online;
this.player = super.player;
this.items = this.player.inventory.items;
this.armor = this.player.inventory.armor;
this.extraSlots = this.player.inventory.extraSlots;
@@ -94,8 +91,8 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
@Override
public @NotNull CraftInventory getBukkitInventory() {
return this.inventory;
public @NotNull Inventory getBukkitInventory() {
return inventory;
}
@Override
@@ -171,7 +168,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
@Override
public int getSize() {
return 45;
return super.getSize() + 4;
}
@Override
@@ -212,7 +209,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
@Override
public ItemStack splitStack(int i, final int j) {
List<ItemStack> list = this.items;
NonNullList<ItemStack> list = this.items;
if (i >= list.size()) {
i -= list.size();
@@ -237,7 +234,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
@Override
public ItemStack splitWithoutUpdate(int i) {
List<ItemStack> list = this.items;
NonNullList<ItemStack> list = this.items;
if (i >= list.size()) {
i -= list.size();
@@ -267,44 +264,46 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return ItemStack.a;
}
@Override
public List<ItemStack> getContents() {
return this.f.stream().flatMap(List::stream).collect(Collectors.toList());
List<ItemStack> combined = new ArrayList<>(this.items.size() + this.armor.size() + this.extraSlots.size());
for (List<ItemStack> sub : this.f) {
combined.addAll(sub);
}
return combined;
}
@Override
public List<ItemStack> getArmorContents() {
return this.armor;
}
@Override
public void onOpen(CraftHumanEntity who) {
this.transaction.add(who);
}
@Override
public void onClose(CraftHumanEntity who) {
this.transaction.remove(who);
}
@Override
public List<HumanEntity> getViewers() {
return this.transaction;
}
@Override
public InventoryHolder getOwner() {
return this.player.getBukkitEntity();
}
@Override
public Location getLocation() {
return this.player.getBukkitEntity().getLocation();
}
@Override
public ItemStack getItemInHand() {
return d(this.itemInHandIndex) ? this.items.get(this.itemInHandIndex) : ItemStack.a;
return e(this.itemInHandIndex) ? this.items.get(this.itemInHandIndex) : ItemStack.a;
}
public static int getHotbarSize() {
return 9;
}
private boolean a(ItemStack itemstack, ItemStack itemstack1) {
@@ -315,7 +314,6 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return itemstack.getItem() == itemstack1.getItem() && ItemStack.equals(itemstack, itemstack1);
}
@Override
public int canHold(ItemStack itemstack) {
int remains = itemstack.getCount();
@@ -337,7 +335,6 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return itemstack.getCount() - remains;
}
@Override
public int getFirstEmptySlotIndex() {
for(int i = 0; i < this.items.size(); ++i) {
if (this.items.get(i).isEmpty()) {
@@ -348,15 +345,17 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return -1;
}
@Override
public void c(int i) {
this.itemInHandIndex = this.i();
public void d(int i) {
this.itemInHandIndex = this.l();
ItemStack itemstack = this.items.get(this.itemInHandIndex);
this.items.set(this.itemInHandIndex, this.items.get(i));
this.items.set(i, itemstack);
}
@Override
public static boolean e(int i) {
return i >= 0 && i < 9;
}
public int c(ItemStack itemstack) {
for(int i = 0; i < this.items.size(); ++i) {
ItemStack itemstack1 = this.items.get(i);
@@ -368,8 +367,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return -1;
}
@Override
public int i() {
public int l() {
int i;
int j;
for(j = 0; j < 9; ++j) {
@@ -389,7 +387,6 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return this.itemInHandIndex;
}
@Override
public int a(Predicate<ItemStack> predicate, int i) {
int j = 0;
@@ -471,7 +468,6 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
}
@Override
public int firstPartial(ItemStack itemstack) {
if (this.a(this.getItem(this.itemInHandIndex), itemstack)) {
return this.itemInHandIndex;
@@ -488,10 +484,9 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
}
@Override
public void j() {
public void p() {
for (List<ItemStack> itemStacks : this.f) {
for (NonNullList<ItemStack> itemStacks : this.f) {
for (int i = 0; i < itemStacks.size(); ++i) {
if (!itemStacks.get(i).isEmpty()) {
itemStacks.get(i).a(this.player.world, this.player, i, this.itemInHandIndex == i);
@@ -501,12 +496,10 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
@Override
public boolean pickup(ItemStack itemstack) {
return this.c(-1, itemstack);
}
@Override
public boolean c(int i, ItemStack itemstack) {
if (itemstack.isEmpty()) {
return false;
@@ -557,7 +550,6 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
}
@Override
public void a(World world, ItemStack itemstack) {
if (!world.isClientSide) {
while(!itemstack.isEmpty()) {
@@ -580,25 +572,22 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
@Override
public void f(ItemStack itemstack) {
for (List<ItemStack> list : this.f) {
for (int i = 0; i < list.size(); ++i) {
if (list.get(i) == itemstack) {
list.set(i, ItemStack.a);
for (NonNullList<ItemStack> nonnulllist : this.f) {
for (int i = 0; i < nonnulllist.size(); ++i) {
if (nonnulllist.get(i) == itemstack) {
nonnulllist.set(i, ItemStack.a);
break;
}
}
}
}
@Override
public float a(IBlockData iblockdata) {
return this.items.get(this.itemInHandIndex).a(iblockdata);
}
@Override
public NBTTagList a(NBTTagList nbttaglist) {
NBTTagCompound nbttagcompound;
int i;
@@ -632,7 +621,6 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return nbttaglist;
}
@Override
public void b(NBTTagList nbttaglist) {
this.items.clear();
this.armor.clear();
@@ -655,8 +643,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
@Override
public boolean isNotEmpty() {
public boolean P_() {
Iterator iterator = this.items.iterator();
ItemStack itemstack;
@@ -689,17 +676,14 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
@Nullable
@Override
public IChatBaseComponent getCustomName() {
return null;
}
@Override
public boolean b(IBlockData iblockdata) {
return this.getItem(this.itemInHandIndex).canDestroySpecialBlock(iblockdata);
return this.getItem(this.itemInHandIndex).b(iblockdata);
}
@Override
public void a(float f) {
if (f > 0.0F) {
f /= 4.0F;
@@ -707,19 +691,16 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
f = 1.0F;
}
for (int i = 0; i < this.armor.size(); ++i) {
ItemStack itemstack = this.armor.get(0);
int index = i;
for (ItemStack itemstack : this.armor) {
if (itemstack.getItem() instanceof ItemArmor) {
itemstack.damage((int) f, this.player, (entityhuman) -> entityhuman.c(EnumItemSlot.a(EnumItemSlot.Function.ARMOR, index)));
itemstack.damage((int) f, this.player);
}
}
}
}
@Override
public void dropContents() {
for (List<ItemStack> itemStacks : this.f) {
for (NonNullList<ItemStack> itemStacks : this.f) {
for (int i = 0; i < itemStacks.size(); ++i) {
ItemStack itemstack = itemStacks.get(i);
if (!itemstack.isEmpty()) {
@@ -730,12 +711,10 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
}
@Override
public boolean h(ItemStack itemstack) {
return this.f.stream().flatMap(List::stream).anyMatch(itemStack1 -> !itemStack1.isEmpty() && itemStack1.doMaterialsMatch(itemstack));
return this.f.stream().flatMap(NonNullList::stream).anyMatch(itemStack1 -> !itemStack1.isEmpty() && itemStack1.doMaterialsMatch(itemstack));
}
@Override
public void a(PlayerInventory playerinventory) {
for (int i = 0; i < playerinventory.getSize(); ++i) {
this.setItem(i, playerinventory.getItem(i));
@@ -744,12 +723,10 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
this.itemInHandIndex = playerinventory.itemInHandIndex;
}
@Override
public void clear() {
this.f.forEach(List::clear);
this.f.forEach(NonNullList::clear);
}
@Override
public void a(AutoRecipeStackManager autorecipestackmanager) {
for (ItemStack itemstack : this.items) {
autorecipestackmanager.a(itemstack);

View File

@@ -22,7 +22,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvinternal</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvadapter1_14_R1</artifactId>
@@ -38,7 +38,7 @@
<dependency>
<groupId>com.lishid</groupId>
<artifactId>openinvcommon</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -29,7 +29,6 @@ import net.minecraft.server.v1_14_R1.BlockShulkerBox;
import net.minecraft.server.v1_14_R1.ChatMessage;
import net.minecraft.server.v1_14_R1.Container;
import net.minecraft.server.v1_14_R1.ContainerChest;
import net.minecraft.server.v1_14_R1.Containers;
import net.minecraft.server.v1_14_R1.EntityHuman;
import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EnumChatFormat;
@@ -190,32 +189,8 @@ public class AnySilentContainer implements IAnySilentContainer {
// Anychest ender chest. See net.minecraft.server.BlockEnderChest
InventoryEnderChest enderChest = player.getEnderChest();
enderChest.a((TileEntityEnderChest) tile);
player.openContainer(new TileInventory((containerCounter, playerInventory, ignored) -> {
Containers containers;
int rows = enderChest.getSize() / 9;
switch (rows) {
case 1:
containers = Containers.GENERIC_9X1;
break;
case 2:
containers = Containers.GENERIC_9X2;
break;
case 3:
default:
containers = Containers.GENERIC_9X3;
break;
case 4:
containers = Containers.GENERIC_9X4;
break;
case 5:
containers = Containers.GENERIC_9X5;
break;
case 6:
containers = Containers.GENERIC_9X6;
break;
}
return new ContainerChest(containers, containerCounter, playerInventory, enderChest, rows);
}, BlockEnderChest.d));
player.openContainer(new TileInventory((containerCounter, playerInventory, ignored) ->
ContainerChest.a(containerCounter, playerInventory, enderChest), BlockEnderChest.d));
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
return true;
}
@@ -334,8 +309,6 @@ public class AnySilentContainer implements IAnySilentContainer {
EnumGamemode gamemode = player.playerInteractManager.getGameMode();
this.forceGameMode(player, EnumGamemode.SPECTATOR);
player.activeContainer.b(player);
player.activeContainer.a(player, false);
player.activeContainer.transferTo(player.defaultContainer, player.getBukkitEntity());
player.activeContainer = player.defaultContainer;
this.forceGameMode(player, gamemode);
}

View File

@@ -100,6 +100,7 @@ public class PlayerDataManager implements IPlayerDataManager {
String title;
if (inventory instanceof SpecialEnderChest) {
HumanEntity owner = (HumanEntity) ((SpecialEnderChest) inventory).getBukkitOwner();
//noinspection ConstantConditions // Owner name can be null when loaded under certain conditions.
title = (owner.getName() != null ? owner.getName() : owner.getUniqueId().toString()) + "'s Ender Chest";
} else if (inventory instanceof SpecialPlayerInventory) {
EntityHuman owner = ((PlayerInventory) inventory).player;
@@ -142,9 +143,9 @@ public class PlayerDataManager implements IPlayerDataManager {
return Containers.GENERIC_9X3;
case 36:
return Containers.GENERIC_9X4;
case 41: // PLAYER
case 45:
return Containers.GENERIC_9X5;
case 41: // PLAYER
case 54:
return Containers.GENERIC_9X6;
}

View File

@@ -18,6 +18,8 @@ package com.lishid.openinv.internal.v1_14_R1;
import com.google.common.collect.ImmutableList;
import com.lishid.openinv.internal.ISpecialPlayerInventory;
import com.lishid.openinv.util.Pair;
import com.lishid.openinv.util.SingleFieldList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
@@ -32,12 +34,12 @@ import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.EnumItemSlot;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
import net.minecraft.server.v1_14_R1.IInventory;
import net.minecraft.server.v1_14_R1.Item;
import net.minecraft.server.v1_14_R1.ItemArmor;
import net.minecraft.server.v1_14_R1.ItemStack;
import net.minecraft.server.v1_14_R1.NBTTagCompound;
import net.minecraft.server.v1_14_R1.NBTTagList;
import net.minecraft.server.v1_14_R1.NonNullList;
import net.minecraft.server.v1_14_R1.PacketPlayOutSetSlot;
import net.minecraft.server.v1_14_R1.PlayerInventory;
import net.minecraft.server.v1_14_R1.ReportedException;
@@ -45,6 +47,7 @@ import net.minecraft.server.v1_14_R1.World;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryCrafting;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryHolder;
@@ -56,8 +59,11 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
private final CraftInventory inventory;
private boolean playerOnline;
private EntityHuman player;
private NonNullList<ItemStack> items, armor, extraSlots;
private List<NonNullList<ItemStack>> f;
private List<ItemStack> items, armor, extraSlots, crafting;
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection") // Backing field is mutable.
// TODO: cursor requires an additional slot listener
private final List<ItemStack> cursor = new SingleFieldList<>(this::getCarried, this::setCarried);
private List<List<ItemStack>> f;
public SpecialPlayerInventory(final Player bukkitPlayer, final Boolean online) {
super(PlayerDataManager.getHandle(bukkitPlayer));
@@ -67,7 +73,12 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
this.items = this.player.inventory.items;
this.armor = this.player.inventory.armor;
this.extraSlots = this.player.inventory.extraSlots;
this.f = ImmutableList.of(this.items, this.armor, this.extraSlots);
this.crafting = this.getCrafting().getContents();
this.f = ImmutableList.of(this.items, this.armor, this.extraSlots, this.crafting, this.cursor);
}
private IInventory getCrafting() {
return ((CraftInventoryCrafting) this.player.defaultContainer.getBukkitView().getTopInventory()).getInventory();
}
@Override
@@ -79,11 +90,13 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
for (int i = 0; i < getSize(); ++i) {
this.player.inventory.setItem(i, getRawItem(i));
}
// Crafting/cursor are not insertable while player is offline and do not need special treatment.
this.player.inventory.itemInHandIndex = this.itemInHandIndex;
this.items = this.player.inventory.items;
this.armor = this.player.inventory.armor;
this.extraSlots = this.player.inventory.extraSlots;
this.f = ImmutableList.of(this.items, this.armor, this.extraSlots);
this.crafting = this.getCrafting().getContents();
this.f = ImmutableList.of(this.items, this.armor, this.extraSlots, this.crafting, this.cursor);
this.playerOnline = true;
}
}
@@ -124,8 +137,8 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
private ItemStack getRawItem(int i) {
NonNullList<ItemStack> list = null;
for (NonNullList<ItemStack> next : this.f) {
List<ItemStack> list = null;
for (List<ItemStack> next : this.f) {
if (i < next.size()) {
list = next;
break;
@@ -171,7 +184,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
@Override
public int getSize() {
return 45;
return 54;
}
@Override
@@ -179,30 +192,35 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
return !this.getViewers().isEmpty();
}
@Override
public void setItem(int i, final ItemStack itemstack) {
List<ItemStack> list = this.items;
if (i >= list.size()) {
private Pair<List<ItemStack>, Integer> getLocalizedIndex(int i) {
List<ItemStack> localList = null;
for (List<ItemStack> list : this.f) {
if (i < list.size()) {
localList = list;
break;
}
i -= list.size();
list = this.armor;
} else {
}
if (localList == this.armor) {
i = this.getReversedArmorSlotNum(i);
} else if (localList == this.items) {
i = this.getReversedItemSlotNum(i);
}
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = this.getReversedArmorSlotNum(i);
return new Pair<>(localList, i);
}
if (i >= list.size()) {
@Override
public void setItem(int i, final ItemStack itemstack) {
Pair<List<ItemStack>, Integer> localizedIndex = getLocalizedIndex(i);
if (localizedIndex.getLeft() == null
// TODO: should this be a constant instead of comparing to transient slot containers?
|| !playerOnline && (localizedIndex.getLeft() == crafting || localizedIndex.getLeft() == cursor)) {
this.player.drop(itemstack, true);
return;
} else {
localizedIndex.getLeft().set(localizedIndex.getRight(), itemstack);
}
list.set(i, itemstack);
}
@Override
@@ -212,51 +230,26 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
@Override
public ItemStack splitStack(int i, final int j) {
List<ItemStack> list = this.items;
Pair<List<ItemStack>, Integer> localizedIndex = getLocalizedIndex(i);
if (i >= list.size()) {
i -= list.size();
list = this.armor;
} else {
i = this.getReversedItemSlotNum(i);
}
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = this.getReversedArmorSlotNum(i);
}
if (i >= list.size()) {
if (localizedIndex.getLeft() == null) {
return ItemStack.a;
}
return list.get(i).isEmpty() ? ItemStack.a : ContainerUtil.a(list, i, j);
return localizedIndex.getLeft().get(i).isEmpty() ? ItemStack.a : ContainerUtil.a(localizedIndex.getLeft(), localizedIndex.getRight(), j);
}
@Override
public ItemStack splitWithoutUpdate(int i) {
List<ItemStack> list = this.items;
Pair<List<ItemStack>, Integer> localizedIndex = getLocalizedIndex(i);
if (i >= list.size()) {
i -= list.size();
list = this.armor;
} else {
i = this.getReversedItemSlotNum(i);
}
if (i >= list.size()) {
i -= list.size();
list = this.extraSlots;
} else if (list == this.armor) {
i = this.getReversedArmorSlotNum(i);
}
if (i >= list.size()) {
if (localizedIndex.getLeft() == null) {
return ItemStack.a;
}
List<ItemStack> list = localizedIndex.getLeft();
i = localizedIndex.getRight();
if (!list.get(i).isEmpty()) {
ItemStack itemstack = list.get(i);
@@ -280,11 +273,13 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
@Override
public void onOpen(CraftHumanEntity who) {
this.transaction.add(who);
this.getCrafting().getViewers().add(who);
}
@Override
public void onClose(CraftHumanEntity who) {
this.transaction.remove(who);
this.getCrafting().getViewers().remove(who);
}
@Override
@@ -326,7 +321,7 @@ public class SpecialPlayerInventory extends PlayerInventory implements ISpecialP
}
if (!this.a(itemstack, itemstack1)) {
remains -= (itemstack1.getMaxStackSize() < this.getMaxStackSize() ? itemstack1.getMaxStackSize() : this.getMaxStackSize()) - itemstack1.getCount();
remains -= Math.min(itemstack1.getMaxStackSize(), this.getMaxStackSize()) - itemstack1.getCount();
}
if (remains <= 0) {

View File

@@ -1,359 +0,0 @@
/*
* Copyright (C) 2011-2019 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_15_R1;
import com.lishid.openinv.internal.IAnySilentContainer;
import java.lang.reflect.Field;
import net.minecraft.server.v1_15_R1.Block;
import net.minecraft.server.v1_15_R1.BlockBarrel;
import net.minecraft.server.v1_15_R1.BlockChest;
import net.minecraft.server.v1_15_R1.BlockChestTrapped;
import net.minecraft.server.v1_15_R1.BlockEnderChest;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.BlockPropertyChestType;
import net.minecraft.server.v1_15_R1.BlockShulkerBox;
import net.minecraft.server.v1_15_R1.ChatMessage;
import net.minecraft.server.v1_15_R1.Container;
import net.minecraft.server.v1_15_R1.ContainerChest;
import net.minecraft.server.v1_15_R1.Containers;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.EnumChatFormat;
import net.minecraft.server.v1_15_R1.EnumGamemode;
import net.minecraft.server.v1_15_R1.IBlockData;
import net.minecraft.server.v1_15_R1.IChatBaseComponent;
import net.minecraft.server.v1_15_R1.ITileInventory;
import net.minecraft.server.v1_15_R1.InventoryEnderChest;
import net.minecraft.server.v1_15_R1.InventoryLargeChest;
import net.minecraft.server.v1_15_R1.PlayerInteractManager;
import net.minecraft.server.v1_15_R1.PlayerInventory;
import net.minecraft.server.v1_15_R1.TileEntity;
import net.minecraft.server.v1_15_R1.TileEntityChest;
import net.minecraft.server.v1_15_R1.TileEntityEnderChest;
import net.minecraft.server.v1_15_R1.TileEntityLootable;
import net.minecraft.server.v1_15_R1.TileInventory;
import net.minecraft.server.v1_15_R1.World;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.block.Barrel;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.EnderChest;
import org.bukkit.block.ShulkerBox;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.type.Chest;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryView;
import org.bukkit.util.BoundingBox;
import org.jetbrains.annotations.NotNull;
public class AnySilentContainer implements IAnySilentContainer {
private Field playerInteractManagerGamemode;
public AnySilentContainer() {
try {
this.playerInteractManagerGamemode = PlayerInteractManager.class.getDeclaredField("gamemode");
this.playerInteractManagerGamemode.setAccessible(true);
} catch (NoSuchFieldException | SecurityException e) {
System.err.println("[OpenInv] Unable to directly write player gamemode! SilentChest will fail.");
e.printStackTrace();
}
}
@Override
public boolean isAnySilentContainer(@NotNull final org.bukkit.block.Block bukkitBlock) {
if (bukkitBlock.getType() == Material.ENDER_CHEST) {
return true;
}
BlockState state = bukkitBlock.getState();
return state instanceof org.bukkit.block.Chest
|| state instanceof org.bukkit.block.ShulkerBox
|| state instanceof org.bukkit.block.Barrel;
}
@Override
public boolean isAnyContainerNeeded(@NotNull final Player p, @NotNull final org.bukkit.block.Block block) {
BlockState blockState = block.getState();
// Barrels do not require AnyContainer.
if (blockState instanceof Barrel) {
return false;
}
// Enderchests require a non-occluding block on top to open.
if (blockState instanceof EnderChest) {
return block.getRelative(0, 1, 0).getType().isOccluding();
}
// Shulker boxes require 1/2 a block clear in the direction they open.
if (blockState instanceof ShulkerBox) {
BoundingBox boundingBox = block.getBoundingBox();
if (boundingBox.getVolume() > 1) {
// Shulker box is already open.
return false;
}
BlockData blockData = block.getBlockData();
if (!(blockData instanceof Directional)) {
// Shouldn't be possible. Just in case, demand AnyChest.
return true;
}
Directional directional = (Directional) blockData;
BlockFace face = directional.getFacing();
boundingBox.shift(face.getDirection());
// Return whether or not bounding boxes overlap.
return block.getRelative(face, 1).getBoundingBox().overlaps(boundingBox);
}
if (!(blockState instanceof org.bukkit.block.Chest)) {
return false;
}
if (isBlockedChest(block)) {
return true;
}
BlockData blockData = block.getBlockData();
if (!(blockData instanceof Chest) || ((Chest) blockData).getType() == Chest.Type.SINGLE) {
return false;
}
Chest chest = (Chest) blockData;
int ordinal = (chest.getFacing().ordinal() + 4 + (chest.getType() == Chest.Type.RIGHT ? -1 : 1)) % 4;
BlockFace relativeFace = BlockFace.values()[ordinal];
org.bukkit.block.Block relative = block.getRelative(relativeFace);
if (relative.getType() != block.getType()) {
return false;
}
BlockData relativeData = relative.getBlockData();
if (!(relativeData instanceof Chest)) {
return false;
}
Chest relativeChest = (Chest) relativeData;
if (relativeChest.getFacing() != chest.getFacing()
|| relativeChest.getType() != (chest.getType() == Chest.Type.RIGHT ? Chest.Type.LEFT : Chest.Type.RIGHT)) {
return false;
}
return isBlockedChest(relative);
}
private boolean isBlockedChest(org.bukkit.block.Block block) {
org.bukkit.block.Block relative = block.getRelative(0, 1, 0);
return relative.getType().isOccluding()
|| block.getWorld().getNearbyEntities(BoundingBox.of(relative), entity -> entity instanceof Cat).size() > 0;
}
@Override
public boolean activateContainer(@NotNull final Player bukkitPlayer, final boolean silentchest,
@NotNull final org.bukkit.block.Block bukkitBlock) {
// Silent ender chest is API-only
if (silentchest && bukkitBlock.getType() == Material.ENDER_CHEST) {
bukkitPlayer.openInventory(bukkitPlayer.getEnderChest());
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
return true;
}
EntityPlayer player = PlayerDataManager.getHandle(bukkitPlayer);
final World world = player.world;
final BlockPosition blockPosition = new BlockPosition(bukkitBlock.getX(), bukkitBlock.getY(), bukkitBlock.getZ());
final TileEntity tile = world.getTileEntity(blockPosition);
if (tile == null) {
return false;
}
if (tile instanceof TileEntityEnderChest) {
// Anychest ender chest. See net.minecraft.server.BlockEnderChest
InventoryEnderChest enderChest = player.getEnderChest();
enderChest.a((TileEntityEnderChest) tile);
player.openContainer(new TileInventory((containerCounter, playerInventory, ignored) -> {
Containers containers;
int rows = enderChest.getSize() / 9;
switch (rows) {
case 1:
containers = Containers.GENERIC_9X1;
break;
case 2:
containers = Containers.GENERIC_9X2;
break;
case 3:
default:
containers = Containers.GENERIC_9X3;
break;
case 4:
containers = Containers.GENERIC_9X4;
break;
case 5:
containers = Containers.GENERIC_9X5;
break;
case 6:
containers = Containers.GENERIC_9X6;
break;
}
return new ContainerChest(containers, containerCounter, playerInventory, enderChest, rows);
}, BlockEnderChest.e));
bukkitPlayer.incrementStatistic(Statistic.ENDERCHEST_OPENED);
return true;
}
if (!(tile instanceof ITileInventory)) {
return false;
}
ITileInventory tileInventory = (ITileInventory) tile;
IBlockData blockData = world.getType(blockPosition);
Block block = blockData.getBlock();
if (block instanceof BlockChest) {
BlockPropertyChestType chestType = blockData.get(BlockChest.c);
if (chestType != BlockPropertyChestType.SINGLE) {
BlockPosition adjacentBlockPosition = blockPosition.shift(BlockChest.i(blockData));
IBlockData adjacentBlockData = world.getType(adjacentBlockPosition);
if (adjacentBlockData.getBlock() == block) {
BlockPropertyChestType adjacentChestType = adjacentBlockData.get(BlockChest.c);
if (adjacentChestType != BlockPropertyChestType.SINGLE && chestType != adjacentChestType
&& adjacentBlockData.get(BlockChest.FACING) == blockData.get(BlockChest.FACING)) {
TileEntity adjacentTile = world.getTileEntity(adjacentBlockPosition);
if (adjacentTile instanceof TileEntityChest && tileInventory instanceof TileEntityChest) {
TileEntityChest rightChest = chestType == BlockPropertyChestType.RIGHT ? ((TileEntityChest) tileInventory) : (TileEntityChest) adjacentTile;
TileEntityChest leftChest = chestType == BlockPropertyChestType.RIGHT ? (TileEntityChest) adjacentTile : ((TileEntityChest) tileInventory);
if (rightChest.lootTable != null || leftChest.lootTable != null) {
player.a(new ChatMessage("Loot not generated! Please disable /silentcontainer.").a(EnumChatFormat.RED), true);
return false;
}
tileInventory = new ITileInventory() {
public Container createMenu(int containerCounter, PlayerInventory playerInventory, EntityHuman entityHuman) {
leftChest.d(playerInventory.player);
rightChest.d(playerInventory.player);
return ContainerChest.b(containerCounter, playerInventory, new InventoryLargeChest(rightChest, leftChest));
}
public IChatBaseComponent getScoreboardDisplayName() {
return new ChatMessage("container.chestDouble");
}
};
}
}
}
}
if (block instanceof BlockChestTrapped) {
bukkitPlayer.incrementStatistic(Statistic.TRAPPED_CHEST_TRIGGERED);
} else {
bukkitPlayer.incrementStatistic(Statistic.CHEST_OPENED);
}
}
if (block instanceof BlockShulkerBox) {
bukkitPlayer.incrementStatistic(Statistic.SHULKER_BOX_OPENED);
}
if (block instanceof BlockBarrel) {
bukkitPlayer.incrementStatistic(Statistic.OPEN_BARREL);
}
// AnyChest only - SilentChest not active, container unsupported, or unnecessary.
if (!silentchest || player.playerInteractManager.getGameMode() == EnumGamemode.SPECTATOR) {
player.openContainer(tileInventory);
return true;
}
// SilentChest requires access to setting players' gamemode directly.
if (this.playerInteractManagerGamemode == null) {
return false;
}
if (tile instanceof TileEntityLootable) {
TileEntityLootable lootable = (TileEntityLootable) tile;
if (lootable.lootTable != null) {
player.a(new ChatMessage("Loot not generated! Please disable /silentcontainer.").a(EnumChatFormat.RED), true);
return false;
}
}
EnumGamemode gamemode = player.playerInteractManager.getGameMode();
this.forceGameMode(player, EnumGamemode.SPECTATOR);
player.openContainer(tileInventory);
this.forceGameMode(player, gamemode);
return true;
}
@Override
public void deactivateContainer(@NotNull final Player bukkitPlayer) {
if (this.playerInteractManagerGamemode == null) {
return;
}
InventoryView view = bukkitPlayer.getOpenInventory();
switch (view.getType()) {
case CHEST:
case ENDER_CHEST:
case SHULKER_BOX:
case BARREL:
break;
default:
return;
}
EntityPlayer player = PlayerDataManager.getHandle(bukkitPlayer);
EnumGamemode gamemode = player.playerInteractManager.getGameMode();
this.forceGameMode(player, EnumGamemode.SPECTATOR);
player.activeContainer.b(player);
player.activeContainer.a(player, false);
player.activeContainer.transferTo(player.defaultContainer, player.getBukkitEntity());
player.activeContainer = player.defaultContainer;
this.forceGameMode(player, gamemode);
}
private void forceGameMode(final EntityPlayer player, final EnumGamemode gameMode) {
if (this.playerInteractManagerGamemode == null) {
// No need to warn repeatedly, error on startup and lack of function should be enough.
return;
}
try {
if (!this.playerInteractManagerGamemode.isAccessible()) {
// Just in case, ensure accessible.
this.playerInteractManagerGamemode.setAccessible(true);
}
this.playerInteractManagerGamemode.set(player.playerInteractManager, gameMode);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,170 +0,0 @@
/*
* Copyright (C) 2011-2019 lishid. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.lishid.openinv.internal.v1_15_R1;
import com.lishid.openinv.internal.IPlayerDataManager;
import com.lishid.openinv.internal.ISpecialInventory;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.v1_15_R1.ChatComponentText;
import net.minecraft.server.v1_15_R1.Container;
import net.minecraft.server.v1_15_R1.Containers;
import net.minecraft.server.v1_15_R1.DimensionManager;
import net.minecraft.server.v1_15_R1.EntityHuman;
import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.MinecraftServer;
import net.minecraft.server.v1_15_R1.PacketPlayOutOpenWindow;
import net.minecraft.server.v1_15_R1.PlayerInteractManager;
import net.minecraft.server.v1_15_R1.PlayerInventory;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_15_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftContainer;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.NotNull;
public class PlayerDataManager implements IPlayerDataManager {
public static EntityPlayer getHandle(final Player player) {
if (player instanceof CraftPlayer) {
return ((CraftPlayer) player).getHandle();
}
Server server = player.getServer();
EntityPlayer nmsPlayer = null;
if (server instanceof CraftServer) {
nmsPlayer = ((CraftServer) server).getHandle().getPlayer(player.getName());
}
if (nmsPlayer == null) {
// Could use reflection to examine fields, but it's honestly not worth the bother.
throw new RuntimeException("Unable to fetch EntityPlayer from provided Player implementation");
}
return nmsPlayer;
}
@Override
public Player loadPlayer(@NotNull final OfflinePlayer offline) {
// Ensure player has data
if (!offline.hasPlayedBefore()) {
return null;
}
// Create a profile and entity to load the player data
GameProfile profile = new GameProfile(offline.getUniqueId(), offline.getName());
MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(DimensionManager.OVERWORLD), profile,
new PlayerInteractManager(server.getWorldServer(DimensionManager.OVERWORLD)));
// Get the bukkit entity
Player target = entity.getBukkitEntity();
if (target != null) {
// Load data
target.loadData();
}
// Return the entity
return target;
}
@Override
public InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
EntityPlayer nmsPlayer = getHandle(player);
if (nmsPlayer == null || nmsPlayer.playerConnection == null) {
return null;
}
String title;
if (inventory instanceof SpecialEnderChest) {
HumanEntity owner = (HumanEntity) ((SpecialEnderChest) inventory).getBukkitOwner();
title = (owner.getName() != null ? owner.getName() : owner.getUniqueId().toString()) + "'s Ender Chest";
} else if (inventory instanceof SpecialPlayerInventory) {
EntityHuman owner = ((PlayerInventory) inventory).player;
title = (owner.getName() != null ? owner.getName() : owner.getUniqueID().toString()) + "'s Inventory";
} else {
return player.openInventory(inventory.getBukkitInventory());
}
Container container = new CraftContainer(new InventoryView() {
@Override
public @NotNull Inventory getTopInventory() {
return inventory.getBukkitInventory();
}
@Override
public @NotNull Inventory getBottomInventory() {
return player.getInventory();
}
@Override
public @NotNull HumanEntity getPlayer() {
return player;
}
@Override
public @NotNull InventoryType getType() {
return inventory.getBukkitInventory().getType();
}
@Override
public @NotNull String getTitle() {
return title;
}
}, nmsPlayer, nmsPlayer.nextContainerCounter()) {
@Override
public Containers<?> getType() {
switch (inventory.getBukkitInventory().getSize()) {
case 9:
return Containers.GENERIC_9X1;
case 18:
return Containers.GENERIC_9X2;
case 27:
default:
return Containers.GENERIC_9X3;
case 36:
return Containers.GENERIC_9X4;
case 41: // PLAYER
case 45:
return Containers.GENERIC_9X5;
case 54:
return Containers.GENERIC_9X6;
}
}
};
container.setTitle(new ChatComponentText(title));
container = CraftEventFactory.callInventoryOpenEvent(nmsPlayer, container);
if (container == null) {
return null;
}
nmsPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(),
new ChatComponentText(container.getBukkitView().getTitle())));
nmsPlayer.activeContainer = container;
container.addSlotListener(nmsPlayer);
return container.getBukkitView();
}
}

View File

@@ -21,7 +21,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvinternal</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvadapter1_8_R3</artifactId>
@@ -37,7 +37,7 @@
<dependency>
<groupId>com.lishid</groupId>
<artifactId>openinvcommon</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -225,8 +225,6 @@ public class AnySilentContainer implements IAnySilentContainer {
EnumGamemode gamemode = player.playerInteractManager.getGameMode();
this.forceGameMode(player, EnumGamemode.SPECTATOR);
player.activeContainer.b(player);
player.activeContainer.a(player, false);
player.activeContainer.transferTo(player.defaultContainer, player.getBukkitEntity());
player.activeContainer = player.defaultContainer;
this.forceGameMode(player, gamemode);
}

View File

@@ -21,7 +21,7 @@
<parent>
<groupId>com.lishid</groupId>
<artifactId>openinvparent</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</parent>
<artifactId>openinvplugincore</artifactId>
@@ -31,7 +31,7 @@
<dependency>
<groupId>com.lishid</groupId>
<artifactId>openinvcommon</artifactId>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>

View File

@@ -21,7 +21,7 @@
<artifactId>openinvparent</artifactId>
<name>OpenInvParent</name>
<url>http://dev.bukkit.org/bukkit-plugins/openinv/</url>
<version>4.0.8</version>
<version>4.0.8-SNAPSHOT</version>
<packaging>pom</packaging>