Added Cartography Window

This commit is contained in:
NichtStudioCode 2021-10-30 14:15:05 +02:00
parent 4d79d6eb7e
commit 4b9486eef7
70 changed files with 151432 additions and 367 deletions

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -19,12 +19,6 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>16.0.1</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>

@ -166,14 +166,6 @@ public interface GUI extends GUIParent {
*/ */
void addItems(@NotNull Item... items); void addItems(@NotNull Item... items);
/**
* Sets the {@link ItemProvider} that will be used if nothing else
* is placed on a slot.
*
* @param itemProvider The {@link ItemProvider}
*/
void setBackground(@Nullable ItemProvider itemProvider);
/** /**
* Gets the {@link ItemProvider} that will be used if nothing else * Gets the {@link ItemProvider} that will be used if nothing else
* is placed on a slot. * is placed on a slot.
@ -182,6 +174,14 @@ public interface GUI extends GUIParent {
*/ */
ItemProvider getBackground(); ItemProvider getBackground();
/**
* Sets the {@link ItemProvider} that will be used if nothing else
* is placed on a slot.
*
* @param itemProvider The {@link ItemProvider}
*/
void setBackground(@Nullable ItemProvider itemProvider);
/** /**
* Removes an {@link Item} by its coordinates. * Removes an {@link Item} by its coordinates.
* *

@ -545,13 +545,13 @@ public abstract class BaseGUI implements GUI, Controllable {
} }
@Override @Override
public void setBackground(ItemProvider itemProvider) { public ItemProvider getBackground() {
this.background = itemProvider; return background;
} }
@Override @Override
public ItemProvider getBackground() { public void setBackground(ItemProvider itemProvider) {
return background; this.background = itemProvider;
} }
@Override @Override

@ -40,14 +40,14 @@ public abstract class ScrollGUI extends BaseGUI {
applyStructure(structure); applyStructure(structure);
} }
public void setCurrentLine(int line) {
this.offset = line * lineLength;
}
public int getCurrentLine() { public int getCurrentLine() {
return offset / lineLength; return offset / lineLength;
} }
public void setCurrentLine(int line) {
this.offset = line * lineLength;
}
private int getMaxLineIndex() { private int getMaxLineIndex() {
int maxLineIndex = (int) Math.ceil((double) getElementAmount() / (double) lineLength); int maxLineIndex = (int) Math.ceil((double) getElementAmount() / (double) lineLength);
return Math.max(0, maxLineIndex - getLineAmount()); return Math.max(0, maxLineIndex - getLineAmount());

@ -34,7 +34,7 @@ public class IngredientList extends ArrayList<Ingredient> {
if (ingredient != null && ingredient.isMarker() && ingredient.getMarker().equals(marker)) if (ingredient != null && ingredient.isMarker() && ingredient.getMarker().equals(marker))
indices.add(i); indices.add(i);
} }
return indices.stream().mapToInt(Integer::intValue).toArray(); return indices.stream().mapToInt(Integer::intValue).toArray();
} }

@ -169,36 +169,6 @@ public class ItemBuilder implements ItemProvider {
return get(); return get();
} }
public ItemBuilder setMaterial(@NotNull Material material) {
this.material = material;
return this;
}
public ItemBuilder setAmount(int amount) {
this.amount = amount;
return this;
}
public ItemBuilder setDamage(int damage) {
this.damage = damage;
return this;
}
public ItemBuilder setCustomModelData(int customModelData) {
this.customModelData = customModelData;
return this;
}
public ItemBuilder setDisplayName(String displayName) {
this.displayName = ComponentUtils.withoutPreFormatting(displayName);
return this;
}
public ItemBuilder setDisplayName(BaseComponent... displayName) {
this.displayName = ComponentUtils.withoutPreFormatting(displayName);
return this;
}
public ItemBuilder setLegacyLore(@NotNull List<String> lore) { public ItemBuilder setLegacyLore(@NotNull List<String> lore) {
this.lore = lore.stream() this.lore = lore.stream()
.map(ComponentUtils::withoutPreFormatting) .map(ComponentUtils::withoutPreFormatting)
@ -206,11 +176,6 @@ public class ItemBuilder implements ItemProvider {
return this; return this;
} }
public ItemBuilder setLore(List<BaseComponent[]> lore) {
this.lore = lore;
return this;
}
public ItemBuilder addLoreLines(@NotNull String... lines) { public ItemBuilder addLoreLines(@NotNull String... lines) {
if (lore == null) lore = new ArrayList<>(); if (lore == null) lore = new ArrayList<>();
@ -236,11 +201,6 @@ public class ItemBuilder implements ItemProvider {
return this; return this;
} }
public ItemBuilder setItemFlags(@NotNull List<ItemFlag> itemFlags) {
this.itemFlags = itemFlags;
return this;
}
public ItemBuilder addItemFlags(@NotNull ItemFlag... itemFlags) { public ItemBuilder addItemFlags(@NotNull ItemFlag... itemFlags) {
if (this.itemFlags == null) this.itemFlags = new ArrayList<>(); if (this.itemFlags == null) this.itemFlags = new ArrayList<>();
this.itemFlags.addAll(Arrays.asList(itemFlags)); this.itemFlags.addAll(Arrays.asList(itemFlags));
@ -258,11 +218,6 @@ public class ItemBuilder implements ItemProvider {
return this; return this;
} }
public ItemBuilder setEnchantments(@NotNull HashMap<Enchantment, Pair<Integer, Boolean>> enchantments) {
this.enchantments = enchantments;
return this;
}
public ItemBuilder addEnchantment(Enchantment enchantment, int level, boolean ignoreLevelRestriction) { public ItemBuilder addEnchantment(Enchantment enchantment, int level, boolean ignoreLevelRestriction) {
if (enchantments == null) enchantments = new HashMap<>(); if (enchantments == null) enchantments = new HashMap<>();
enchantments.put(enchantment, new Pair<>(level, ignoreLevelRestriction)); enchantments.put(enchantment, new Pair<>(level, ignoreLevelRestriction));
@ -299,34 +254,79 @@ public class ItemBuilder implements ItemProvider {
return material; return material;
} }
public ItemBuilder setMaterial(@NotNull Material material) {
this.material = material;
return this;
}
public int getAmount() { public int getAmount() {
return amount; return amount;
} }
public ItemBuilder setAmount(int amount) {
this.amount = amount;
return this;
}
public int getDamage() { public int getDamage() {
return damage; return damage;
} }
public ItemBuilder setDamage(int damage) {
this.damage = damage;
return this;
}
public int getCustomModelData() { public int getCustomModelData() {
return customModelData; return customModelData;
} }
public ItemBuilder setCustomModelData(int customModelData) {
this.customModelData = customModelData;
return this;
}
public BaseComponent[] getDisplayName() { public BaseComponent[] getDisplayName() {
return displayName; return displayName;
} }
public ItemBuilder setDisplayName(String displayName) {
this.displayName = ComponentUtils.withoutPreFormatting(displayName);
return this;
}
public ItemBuilder setDisplayName(BaseComponent... displayName) {
this.displayName = ComponentUtils.withoutPreFormatting(displayName);
return this;
}
public List<BaseComponent[]> getLore() { public List<BaseComponent[]> getLore() {
return lore; return lore;
} }
public ItemBuilder setLore(List<BaseComponent[]> lore) {
this.lore = lore;
return this;
}
public List<ItemFlag> getItemFlags() { public List<ItemFlag> getItemFlags() {
return itemFlags; return itemFlags;
} }
public ItemBuilder setItemFlags(@NotNull List<ItemFlag> itemFlags) {
this.itemFlags = itemFlags;
return this;
}
public HashMap<Enchantment, Pair<Integer, Boolean>> getEnchantments() { public HashMap<Enchantment, Pair<Integer, Boolean>> getEnchantments() {
return enchantments; return enchantments;
} }
public ItemBuilder setEnchantments(@NotNull HashMap<Enchantment, Pair<Integer, Boolean>> enchantments) {
this.enchantments = enchantments;
return this;
}
public GameProfile getGameProfile() { public GameProfile getGameProfile() {
return gameProfile; return gameProfile;
} }

@ -0,0 +1,51 @@
package de.studiocode.invui.map;
import de.studiocode.invui.util.IOUtils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class ColorPalette {
private static final byte[] colorCache;
static {
ByteArrayOutputStream out = new ByteArrayOutputStream(256 * 256 * 256);
try {
InputStream in = ColorPalette.class.getResourceAsStream("/colors.bin");
IOUtils.copy(in, out, 8192);
} catch (IOException e) {
e.printStackTrace();
}
colorCache = out.toByteArray();
}
public static byte getColor(int red, int green, int blue) {
return colorCache[(red << 16) | (green << 8) | blue];
}
public static byte getColor(int rgba) {
if ((rgba >> 24 & 0xFF) < 255) return 0;
return colorCache[rgba & 0xFFFFFF];
}
public static byte getColor(Color color) {
return getColor(color.getRGB());
}
public static byte[] convertImage(BufferedImage image) {
byte[] colors = new byte[image.getWidth() * image.getHeight()];
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
colors[x + y * image.getWidth()] = getColor(image.getRGB(x, y));
}
}
return colors;
}
}

@ -43,6 +43,10 @@ public class ForceResourcePack implements Listener {
return INSTANCE; return INSTANCE;
} }
public String getResourcePackUrl() {
return resourcePackUrl;
}
/** /**
* Sets the URL String for the custom ResourcePack every {@link Player} is required to download. * Sets the URL String for the custom ResourcePack every {@link Player} is required to download.
* Can be set to null to stop forcing the Resource Pack. * Can be set to null to stop forcing the Resource Pack.
@ -54,10 +58,6 @@ public class ForceResourcePack implements Listener {
if (resourcePackUrl != null) Bukkit.getOnlinePlayers().forEach(this::sendResourcePack); if (resourcePackUrl != null) Bukkit.getOnlinePlayers().forEach(this::sendResourcePack);
} }
public String getResourcePackUrl() {
return resourcePackUrl;
}
@EventHandler @EventHandler
public void handleJoin(PlayerJoinEvent event) { public void handleJoin(PlayerJoinEvent event) {
if (resourcePackUrl != null) sendResourcePack(event.getPlayer()); if (resourcePackUrl != null) sendResourcePack(event.getPlayer());

@ -0,0 +1,17 @@
package de.studiocode.invui.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class IOUtils {
public static void copy(InputStream in, OutputStream out, int bufferSize) throws IOException {
byte[] buffer = new byte[bufferSize];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
}

@ -0,0 +1,20 @@
package de.studiocode.invui.util;
import java.util.Random;
public class MathUtils {
public static final Random RANDOM = new Random();
/**
* Generates a pseudorandom number between min and max.
*
* @param min The lower bound (inclusive)
* @param max The upper bound (exclusive)
* @return A pseudorandom number between min and max.
*/
public static int randInt(int min, int max) {
return RANDOM.nextInt(max - min) + min;
}
}

@ -26,10 +26,10 @@ import static java.lang.Math.min;
public class VirtualInventory implements ConfigurationSerializable { public class VirtualInventory implements ConfigurationSerializable {
private final UUID uuid; private final UUID uuid;
private final Set<Window> windows = new HashSet<>();
private int size; private int size;
private ItemStack[] items; private ItemStack[] items;
private int[] stackSizes; private int[] stackSizes;
private final Set<Window> windows = new HashSet<>();
private Consumer<ItemUpdateEvent> itemUpdateHandler; private Consumer<ItemUpdateEvent> itemUpdateHandler;
private int guiShiftPriority = 0; private int guiShiftPriority = 0;
@ -166,6 +166,16 @@ public class VirtualInventory implements ConfigurationSerializable {
this.itemUpdateHandler = itemUpdateHandler; this.itemUpdateHandler = itemUpdateHandler;
} }
/**
* Gets the priority for shift-clicking {@link ItemStack ItemStacks} into a {@link GUI}
*
* @return The priority for shift-clicking, {@link VirtualInventory VirtualInventories} with
* a higher priority get prioritized.
*/
public int getGuiShiftPriority() {
return guiShiftPriority;
}
/** /**
* Sets the priority for shift-clicking {@link ItemStack ItemStacks} into a {@link GUI} * Sets the priority for shift-clicking {@link ItemStack ItemStacks} into a {@link GUI}
* with multiple {@link VirtualInventory}. * with multiple {@link VirtualInventory}.
@ -178,16 +188,6 @@ public class VirtualInventory implements ConfigurationSerializable {
this.guiShiftPriority = guiShiftPriority; this.guiShiftPriority = guiShiftPriority;
} }
/**
* Gets the priority for shift-clicking {@link ItemStack ItemStacks} into a {@link GUI}
*
* @return The priority for shift-clicking, {@link VirtualInventory VirtualInventories} with
* a higher priority get prioritized.
*/
public int getGuiShiftPriority() {
return guiShiftPriority;
}
/** /**
* Gets the {@link UUID} of this {@link VirtualInventory}. * Gets the {@link UUID} of this {@link VirtualInventory}.
* *

@ -13,10 +13,9 @@ public class ItemUpdateEvent {
private final VirtualInventory virtualInventory; private final VirtualInventory virtualInventory;
private final ItemStack previousItemStack; private final ItemStack previousItemStack;
private ItemStack newItemStack;
private final UpdateReason updateReason; private final UpdateReason updateReason;
private final int slot; private final int slot;
private ItemStack newItemStack;
private boolean cancelled; private boolean cancelled;
/** /**

@ -125,12 +125,14 @@ public interface Window extends GUIParent {
/** /**
* Adds a close handler that will be called when this window gets closed. * Adds a close handler that will be called when this window gets closed.
*
* @param closeHandler The close handler to add * @param closeHandler The close handler to add
*/ */
void addCloseHandler(Runnable closeHandler); void addCloseHandler(Runnable closeHandler);
/** /**
* Removes a close handler that has been added previously. * Removes a close handler that has been added previously.
*
* @param closeHandler The close handler to remove * @param closeHandler The close handler to remove
*/ */
void removeCloseHandler(Runnable closeHandler); void removeCloseHandler(Runnable closeHandler);

@ -10,7 +10,10 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.*; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;

@ -33,14 +33,11 @@ public abstract class BaseWindow implements Window {
private final UUID viewerUUID; private final UUID viewerUUID;
private final boolean closeOnEvent; private final boolean closeOnEvent;
private final SlotElement[] elementsDisplayed; private final SlotElement[] elementsDisplayed;
private final ArrayList<Runnable> closeHandlers = new ArrayList<>();
private BaseComponent[] title; private BaseComponent[] title;
private boolean closeable; private boolean closeable;
private boolean closed; private boolean closed;
private final ArrayList<Runnable> closeHandlers = new ArrayList<>();
public BaseWindow(UUID viewerUUID, BaseComponent[] title, int size, boolean closeable, boolean closeOnEvent) { public BaseWindow(UUID viewerUUID, BaseComponent[] title, int size, boolean closeable, boolean closeOnEvent) {
this.viewerUUID = viewerUUID; this.viewerUUID = viewerUUID;
this.title = title; this.title = title;

@ -55,7 +55,8 @@ public abstract class SplitWindow extends MergedWindow {
@Override @Override
protected Pair<GUI, Integer> getGuiAt(int index) { protected Pair<GUI, Integer> getGuiAt(int index) {
if (index < upperGui.getSize()) return new Pair<>(upperGui, index); if (index < upperGui.getSize()) return new Pair<>(upperGui, index);
else if (index < (upperGui.getSize() + lowerGui.getSize())) return new Pair<>(lowerGui, index - upperGui.getSize()); else if (index < (upperGui.getSize() + lowerGui.getSize()))
return new Pair<>(lowerGui, index - upperGui.getSize());
else return null; else return null;
} }

@ -18,7 +18,7 @@ public class AnvilWindow extends SingleWindow {
super(player.getUniqueId(), title, gui, null, false, closable, true); super(player.getUniqueId(), title, gui, null, false, closable, true);
anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandler); anvilInventory = InventoryAccess.createAnvilInventory(player, title, renameHandler);
inventory = anvilInventory.getBukkitInventory(); inventory = anvilInventory.getBukkitInventory();
initItems(); initItems();
} }

@ -0,0 +1,95 @@
package de.studiocode.invui.window.impl.single;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.map.MapIcon;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.version.InventoryAccess;
import de.studiocode.invui.gui.GUI;
import de.studiocode.invui.util.MathUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@SuppressWarnings("deprecation")
public class CartographyWindow extends SingleWindow {
private final CartographyInventory cartographyInventory;
private int mapId;
public CartographyWindow(Player player, String title, GUI gui) {
this(player, TextComponent.fromLegacyText(title), gui, true);
}
public CartographyWindow(Player player, String title, GUI gui, boolean closeable) {
this(player, TextComponent.fromLegacyText(title), gui, closeable);
}
public CartographyWindow(Player player, BaseComponent[] title, GUI gui) {
this(player, title, gui, true);
}
public CartographyWindow(Player player, BaseComponent[] title, GUI gui, boolean closeable) {
super(player.getUniqueId(), title, gui, null, false, closeable, true);
if (gui.getWidth() != 2 || gui.getHeight() != 1) throw new IllegalArgumentException("GUI has to be 2x1");
cartographyInventory = InventoryAccess.createCartographyInventory(player, title);
inventory = cartographyInventory.getBukkitInventory();
initItems();
resetMap();
}
public void updateMap(@Nullable MapPatch patch, @Nullable List<MapIcon> icons) {
InventoryAccess.getPlayerUtils().sendMapUpdate(getViewer(), mapId, (byte) 0, false, patch, icons);
}
public void updateMap(MapPatch patch) {
updateMap(patch, null);
}
public void updateMap(List<MapIcon> icons) {
updateMap(null, icons);
}
public void resetMap() {
mapId = -MathUtils.RANDOM.nextInt(Integer.MAX_VALUE);
ItemStack map = new ItemStack(Material.FILLED_MAP);
MapMeta mapMeta = (MapMeta) map.getItemMeta();
mapMeta.setMapId(mapId);
map.setItemMeta(mapMeta);
cartographyInventory.setItem(0, map);
getViewer().getInventory().addItem(map);
}
@Override
protected void setInvItem(int slot, ItemStack itemStack) {
cartographyInventory.setItem(slot + 1, itemStack);
}
@Override
public void handleClick(InventoryClickEvent event) {
if (event.getSlot() != 0) {
getGui().handleClick(event.getSlot() - 1, (Player) event.getWhoClicked(), event.getClick(), event);
} else {
event.setCancelled(true);
}
}
@Override
public void show() {
if (isClosed()) throw new IllegalStateException("The Window has already been closed.");
Player viewer = getViewer();
if (viewer == null) throw new IllegalStateException("The player is not online.");
cartographyInventory.open();
}
}

@ -103,4 +103,7 @@ public abstract class SingleWindow extends BaseWindow {
return new GUI[] {gui}; return new GUI[] {gui};
} }
public GUI getGui() {
return gui;
}
} }

File diff suppressed because one or more lines are too long

@ -1,8 +1,8 @@
package de.studiocode.inventoryaccess.r1.inventory; package de.studiocode.inventoryaccess.r1.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.AnvilInventory; import de.studiocode.inventoryaccess.abstraction.inventory.AnvilInventory;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import de.studiocode.inventoryaccess.r1.util.InventoryUtilsImpl; import de.studiocode.inventoryaccess.r1.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.server.v1_14_R1.*; import net.minecraft.server.v1_14_R1.*;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
@ -13,6 +13,7 @@ import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -34,7 +35,7 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -69,11 +70,11 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
// send initial items // send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.a, getItem(0), getItem(1), getItem(2)); NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.a, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(getActiveWindowId(player), itemsList)); player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
} }
public void sendItem(int slot) { public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(getActiveWindowId(player), slot, getItem(slot))); player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
} }
public void setItem(int slot, ItemStack item) { public void setItem(int slot, ItemStack item) {
@ -88,18 +89,13 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
else return resultInventory.getItem(0); else return resultInventory.getItem(0);
} }
private int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack)); setItem(slot, CraftItemStack.asNMSCopy(itemStack));
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }

@ -0,0 +1,122 @@
package de.studiocode.inventoryaccess.r1.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r1.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.server.v1_14_R1.*;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_14_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends ContainerCartography implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(ContainerCartography.class, true, "resultInventory");
private final InventoryCraftResult resultInventory = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final IChatBaseComponent title;
private final CraftInventoryView view;
private final EntityPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(EntityPlayer player, IChatBaseComponent title) {
super(player.nextContainerCounter(), player.inventory, ContainerAccess.at(player.getWorld(), new BlockPosition(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(this.inventory, resultInventory);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.activeContainer = this;
// send open packet
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, Containers.CARTOGRAPHY, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.a, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) inventory.setItem(slot, item);
else resultInventory.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return inventory.getItem(slot);
else return resultInventory.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void a(IInventory inventory) {
}
@Override
public ItemStack shiftClick(EntityHuman entityhuman, int i) {
return ItemStack.a;
}
@Override
public boolean a(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean canUse(EntityHuman entityhuman) {
return true;
}
@Override
public void b(EntityHuman entityHuman) {
// empty
}
}

@ -11,46 +11,10 @@ import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftInventory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
@Override
public void openCustomInventory(Player player, Inventory inventory) {
openCustomInventory(player, inventory, null);
}
@Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Containers<?> windowType = getNotchInventoryType(inventory);
if (entityPlayer.playerConnection != null) {
Container container = new CraftContainer(inventory, entityPlayer, entityPlayer.nextContainerCounter());
container = CraftEventFactory.callInventoryOpenEvent(entityPlayer, container);
if (container != null) {
IInventory iinventory = ((CraftInventory) inventory).getInventory();
IChatBaseComponent titleComponent;
if (title == null) {
if (iinventory instanceof ITileInventory)
titleComponent = ((ITileInventory) iinventory).getScoreboardDisplayName();
else titleComponent = new ChatComponentText(container.getBukkitView().getTitle());
} else titleComponent = createNMSComponent(title);
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, titleComponent));
entityPlayer.activeContainer = container;
entityPlayer.activeContainer.addSlotListener(entityPlayer);
}
}
}
@Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Container container = entityPlayer.activeContainer;
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title)));
entityPlayer.updateInventory(container);
}
private static Containers<?> getNotchInventoryType(Inventory inventory) { private static Containers<?> getNotchInventoryType(Inventory inventory) {
InventoryType type = inventory.getType(); InventoryType type = inventory.getType();
if (type == InventoryType.CHEST) { if (type == InventoryType.CHEST) {
@ -78,4 +42,46 @@ public class InventoryUtilsImpl implements InventoryUtils {
return IChatBaseComponent.ChatSerializer.a(json); return IChatBaseComponent.ChatSerializer.a(json);
} }
public static int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override
public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null);
}
@Override
public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Containers<?> windowType = getNotchInventoryType(inventory);
if (entityPlayer.playerConnection != null) {
Container container = new CraftContainer(inventory, entityPlayer, entityPlayer.nextContainerCounter());
container = CraftEventFactory.callInventoryOpenEvent(entityPlayer, container);
if (container != null) {
IInventory iinventory = ((CraftInventory) inventory).getInventory();
IChatBaseComponent titleComponent;
if (title == null) {
if (iinventory instanceof ITileInventory)
titleComponent = ((ITileInventory) iinventory).getScoreboardDisplayName();
else titleComponent = new ChatComponentText(container.getBukkitView().getTitle());
} else titleComponent = createNMSComponent(title);
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, titleComponent));
entityPlayer.activeContainer = container;
entityPlayer.activeContainer.addSlotListener(entityPlayer);
}
}
}
@Override
public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Container container = entityPlayer.activeContainer;
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title)));
entityPlayer.updateInventory(container);
}
} }

@ -9,6 +9,7 @@ import net.minecraft.server.v1_14_R1.NBTCompressedStreamTools;
import net.minecraft.server.v1_14_R1.NBTTagCompound; import net.minecraft.server.v1_14_R1.NBTTagCompound;
import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -20,14 +21,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream out, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream out, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -57,7 +58,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream in, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream in, boolean compressed) {
try { try {
NBTTagCompound nbt; NBTTagCompound nbt;
if (compressed) { if (compressed) {
@ -78,7 +79,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -87,7 +88,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,13 +1,21 @@
package de.studiocode.inventoryaccess.r1.util; package de.studiocode.inventoryaccess.r1.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.server.v1_14_R1.AdvancementDataPlayer; import net.minecraft.server.v1_14_R1.AdvancementDataPlayer;
import net.minecraft.server.v1_14_R1.EntityPlayer; import net.minecraft.server.v1_14_R1.EntityPlayer;
import net.minecraft.server.v1_14_R1.MapIcon;
import net.minecraft.server.v1_14_R1.PacketPlayOutMap;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -15,24 +23,56 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "d"); ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "d");
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((EntityPlayer) player).getAdvancementData().a(); // stops listening ((EntityPlayer) player).getAdvancementData().a(); // stops listening
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData(); AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<de.studiocode.inventoryaccess.map.MapIcon> icons) {
List<MapIcon> decorations = icons != null
? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new))
: new ArrayList<>();
int width = 0;
int height = 0;
int startX = 0;
int startY = 0;
byte[] colors = new byte[0];
if (mapPatch != null) {
width = mapPatch.getWidth();
height = mapPatch.getHeight();
startX = mapPatch.getStartX();
startY = mapPatch.getStartY();
colors = mapPatch.getColors();
}
PacketPlayOutMap packet = new PacketPlayOutMap(mapId, scale, !decorations.isEmpty(), locked, decorations, colors, startX, startY, width, height);
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
private MapIcon toMapDecoration(de.studiocode.inventoryaccess.map.MapIcon icon) {
return new MapIcon(
MapIcon.Type.a(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
} }

@ -13,6 +13,7 @@ import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -34,7 +35,7 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -69,11 +70,11 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
// send initial items // send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.a, getItem(0), getItem(1), getItem(2)); NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.a, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(getActiveWindowId(player), itemsList)); player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
} }
public void sendItem(int slot) { public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(getActiveWindowId(player), slot, getItem(slot))); player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
} }
public void setItem(int slot, ItemStack item) { public void setItem(int slot, ItemStack item) {
@ -88,18 +89,13 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
else return resultInventory.getItem(0); else return resultInventory.getItem(0);
} }
private int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack)); setItem(slot, CraftItemStack.asNMSCopy(itemStack));
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }

@ -0,0 +1,122 @@
package de.studiocode.inventoryaccess.r2.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r2.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.server.v1_15_R1.*;
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.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends ContainerCartography implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(ContainerCartography.class, true, "resultInventory");
private final InventoryCraftResult resultInventory = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final IChatBaseComponent title;
private final CraftInventoryView view;
private final EntityPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(EntityPlayer player, IChatBaseComponent title) {
super(player.nextContainerCounter(), player.inventory, ContainerAccess.at(player.getWorld(), new BlockPosition(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(this.inventory, resultInventory);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.activeContainer = this;
// send open packet
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, Containers.CARTOGRAPHY_TABLE, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.a, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) inventory.setItem(slot, item);
else resultInventory.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return inventory.getItem(slot);
else return resultInventory.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void a(IInventory inventory) {
}
@Override
public ItemStack shiftClick(EntityHuman entityhuman, int i) {
return ItemStack.a;
}
@Override
public boolean a(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean canUse(EntityHuman entityhuman) {
return true;
}
@Override
public void b(EntityHuman entityHuman) {
// empty
}
}

@ -10,16 +10,27 @@ import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftContainer;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftInventory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return IChatBaseComponent.ChatSerializer.a(json);
}
public static int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void openCustomInventory(Player player, Inventory inventory) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null); openCustomInventory(player, inventory, null);
} }
@Override @Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory); Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory);
@ -43,16 +54,11 @@ public class InventoryUtilsImpl implements InventoryUtils {
} }
@Override @Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) { public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Container container = entityPlayer.activeContainer; Container container = entityPlayer.activeContainer;
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title))); entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title)));
entityPlayer.updateInventory(container); entityPlayer.updateInventory(container);
} }
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return IChatBaseComponent.ChatSerializer.a(json);
}
} }

@ -9,6 +9,7 @@ import net.minecraft.server.v1_15_R1.NBTCompressedStreamTools;
import net.minecraft.server.v1_15_R1.NBTTagCompound; import net.minecraft.server.v1_15_R1.NBTTagCompound;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -20,14 +21,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream out, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream out, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -57,7 +58,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream in, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream in, boolean compressed) {
try { try {
NBTTagCompound nbt; NBTTagCompound nbt;
if (compressed) { if (compressed) {
@ -78,7 +79,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -87,7 +88,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,13 +1,21 @@
package de.studiocode.inventoryaccess.r2.util; package de.studiocode.inventoryaccess.r2.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.server.v1_15_R1.AdvancementDataPlayer; import net.minecraft.server.v1_15_R1.AdvancementDataPlayer;
import net.minecraft.server.v1_15_R1.EntityPlayer; import net.minecraft.server.v1_15_R1.EntityPlayer;
import net.minecraft.server.v1_15_R1.MapIcon;
import net.minecraft.server.v1_15_R1.PacketPlayOutMap;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -15,24 +23,56 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "d"); ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "d");
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((EntityPlayer) player).getAdvancementData().a(); // stops listening ((EntityPlayer) player).getAdvancementData().a(); // stops listening
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData(); AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<de.studiocode.inventoryaccess.map.MapIcon> icons) {
List<MapIcon> decorations = icons != null
? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new))
: new ArrayList<>();
int width = 0;
int height = 0;
int startX = 0;
int startY = 0;
byte[] colors = new byte[0];
if (mapPatch != null) {
width = mapPatch.getWidth();
height = mapPatch.getHeight();
startX = mapPatch.getStartX();
startY = mapPatch.getStartY();
colors = mapPatch.getColors();
}
PacketPlayOutMap packet = new PacketPlayOutMap(mapId, scale, !decorations.isEmpty(), locked, decorations, colors, startX, startY, width, height);
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
private MapIcon toMapDecoration(de.studiocode.inventoryaccess.map.MapIcon icon) {
return new MapIcon(
MapIcon.Type.a(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
} }

@ -12,6 +12,7 @@ import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -25,7 +26,7 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -56,11 +57,11 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
// send initial items // send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2)); NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(getActiveWindowId(player), itemsList)); player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
} }
public void sendItem(int slot) { public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(getActiveWindowId(player), slot, getItem(slot))); player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
} }
public void setItem(int slot, ItemStack item) { public void setItem(int slot, ItemStack item) {
@ -75,18 +76,13 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
else return resultInventory.getItem(0); else return resultInventory.getItem(0);
} }
private int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack)); setItem(slot, CraftItemStack.asNMSCopy(itemStack));
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }

@ -0,0 +1,122 @@
package de.studiocode.inventoryaccess.r3.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r3.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.server.v1_16_R1.*;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends ContainerCartography implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(ContainerCartography.class, true, "resultInventory");
private final InventoryCraftResult resultInventory = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final IChatBaseComponent title;
private final CraftInventoryView view;
private final EntityPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(EntityPlayer player, IChatBaseComponent title) {
super(player.nextContainerCounter(), player.inventory, ContainerAccess.at(player.getWorld(), new BlockPosition(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(this.inventory, resultInventory);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.activeContainer = this;
// send open packet
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, Containers.CARTOGRAPHY_TABLE, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) inventory.setItem(slot, item);
else resultInventory.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return inventory.getItem(slot);
else return resultInventory.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void a(IInventory inventory) {
}
@Override
public ItemStack shiftClick(EntityHuman entityhuman, int i) {
return ItemStack.b;
}
@Override
public boolean a(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean canUse(EntityHuman entityhuman) {
return true;
}
@Override
public void b(EntityHuman entityHuman) {
// empty
}
}

@ -11,16 +11,27 @@ import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_16_R1.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_16_R1.util.CraftChatMessage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return IChatBaseComponent.ChatSerializer.a(json);
}
public static int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void openCustomInventory(Player player, Inventory inventory) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null); openCustomInventory(player, inventory, null);
} }
@Override @Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory); Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory);
@ -35,7 +46,7 @@ public class InventoryUtilsImpl implements InventoryUtils {
titleComponent = ((ITileInventory) iinventory).getScoreboardDisplayName(); titleComponent = ((ITileInventory) iinventory).getScoreboardDisplayName();
else titleComponent = CraftChatMessage.fromString(container.getBukkitView().getTitle())[0]; else titleComponent = CraftChatMessage.fromString(container.getBukkitView().getTitle())[0];
} else titleComponent = createNMSComponent(title); } else titleComponent = createNMSComponent(title);
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, titleComponent)); entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, titleComponent));
entityPlayer.activeContainer = container; entityPlayer.activeContainer = container;
entityPlayer.activeContainer.addSlotListener(entityPlayer); entityPlayer.activeContainer.addSlotListener(entityPlayer);
@ -44,16 +55,11 @@ public class InventoryUtilsImpl implements InventoryUtils {
} }
@Override @Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) { public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Container container = entityPlayer.activeContainer; Container container = entityPlayer.activeContainer;
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title))); entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title)));
entityPlayer.updateInventory(container); entityPlayer.updateInventory(container);
} }
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return IChatBaseComponent.ChatSerializer.a(json);
}
} }

@ -9,6 +9,7 @@ import net.minecraft.server.v1_16_R1.NBTCompressedStreamTools;
import net.minecraft.server.v1_16_R1.NBTTagCompound; import net.minecraft.server.v1_16_R1.NBTTagCompound;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -20,14 +21,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream out, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream out, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -57,7 +58,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream in, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream in, boolean compressed) {
try { try {
NBTTagCompound nbt; NBTTagCompound nbt;
if (compressed) { if (compressed) {
@ -78,7 +79,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -87,7 +88,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,16 +1,20 @@
package de.studiocode.inventoryaccess.r3.util; package de.studiocode.inventoryaccess.r3.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.server.v1_16_R1.AdvancementDataPlayer; import net.minecraft.server.v1_16_R1.*;
import net.minecraft.server.v1_16_R1.AdvancementDataWorld;
import net.minecraft.server.v1_16_R1.EntityPlayer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_16_R1.CraftServer; import org.bukkit.craftbukkit.v1_16_R1.CraftServer;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -18,25 +22,57 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "b", AdvancementDataWorld.class); ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "b", AdvancementDataWorld.class);
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((EntityPlayer) player).getAdvancementData().a(); // stops listening ((EntityPlayer) player).getAdvancementData().a(); // stops listening
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData(); AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData();
AdvancementDataWorld manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancementData(); AdvancementDataWorld manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancementData();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<de.studiocode.inventoryaccess.map.MapIcon> icons) {
List<MapIcon> decorations = icons != null
? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new))
: new ArrayList<>();
int width = 0;
int height = 0;
int startX = 0;
int startY = 0;
byte[] colors = new byte[0];
if (mapPatch != null) {
width = mapPatch.getWidth();
height = mapPatch.getHeight();
startX = mapPatch.getStartX();
startY = mapPatch.getStartY();
colors = mapPatch.getColors();
}
PacketPlayOutMap packet = new PacketPlayOutMap(mapId, scale, !decorations.isEmpty(), locked, decorations, colors, startX, startY, width, height);
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
private MapIcon toMapDecoration(de.studiocode.inventoryaccess.map.MapIcon icon) {
return new MapIcon(
MapIcon.Type.a(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
} }

@ -12,6 +12,7 @@ import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -25,7 +26,7 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -56,11 +57,11 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
// send initial items // send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2)); NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(getActiveWindowId(player), itemsList)); player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
} }
public void sendItem(int slot) { public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(getActiveWindowId(player), slot, getItem(slot))); player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
} }
public void setItem(int slot, ItemStack item) { public void setItem(int slot, ItemStack item) {
@ -75,18 +76,13 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
else return resultInventory.getItem(0); else return resultInventory.getItem(0);
} }
private int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack)); setItem(slot, CraftItemStack.asNMSCopy(itemStack));
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }

@ -0,0 +1,122 @@
package de.studiocode.inventoryaccess.r4.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r4.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.server.v1_16_R2.*;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R2.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends ContainerCartography implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(ContainerCartography.class, true, "resultInventory");
private final InventoryCraftResult resultInventory = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final IChatBaseComponent title;
private final CraftInventoryView view;
private final EntityPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(EntityPlayer player, IChatBaseComponent title) {
super(player.nextContainerCounter(), player.inventory, ContainerAccess.at(player.getWorld(), new BlockPosition(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(this.inventory, resultInventory);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.activeContainer = this;
// send open packet
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, Containers.CARTOGRAPHY_TABLE, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) inventory.setItem(slot, item);
else resultInventory.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return inventory.getItem(slot);
else return resultInventory.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void a(IInventory inventory) {
}
@Override
public ItemStack shiftClick(EntityHuman entityhuman, int i) {
return ItemStack.b;
}
@Override
public boolean a(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean canUse(EntityHuman entityhuman) {
return true;
}
@Override
public void b(EntityHuman entityHuman) {
// empty
}
}

@ -11,16 +11,27 @@ import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_16_R2.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_16_R2.util.CraftChatMessage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return IChatBaseComponent.ChatSerializer.a(json);
}
public static int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void openCustomInventory(Player player, Inventory inventory) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null); openCustomInventory(player, inventory, null);
} }
@Override @Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory); Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory);
@ -44,16 +55,11 @@ public class InventoryUtilsImpl implements InventoryUtils {
} }
@Override @Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) { public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Container container = entityPlayer.activeContainer; Container container = entityPlayer.activeContainer;
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title))); entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title)));
entityPlayer.updateInventory(container); entityPlayer.updateInventory(container);
} }
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return IChatBaseComponent.ChatSerializer.a(json);
}
} }

@ -9,6 +9,7 @@ import net.minecraft.server.v1_16_R2.NBTCompressedStreamTools;
import net.minecraft.server.v1_16_R2.NBTTagCompound; import net.minecraft.server.v1_16_R2.NBTTagCompound;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -20,14 +21,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream out, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream out, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -57,7 +58,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream in, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream in, boolean compressed) {
try { try {
NBTTagCompound nbt; NBTTagCompound nbt;
if (compressed) { if (compressed) {
@ -78,7 +79,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -87,7 +88,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,16 +1,20 @@
package de.studiocode.inventoryaccess.r4.util; package de.studiocode.inventoryaccess.r4.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.server.v1_16_R2.AdvancementDataPlayer; import net.minecraft.server.v1_16_R2.*;
import net.minecraft.server.v1_16_R2.AdvancementDataWorld;
import net.minecraft.server.v1_16_R2.EntityPlayer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_16_R2.CraftServer; import org.bukkit.craftbukkit.v1_16_R2.CraftServer;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -18,25 +22,57 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "b", AdvancementDataWorld.class); ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "b", AdvancementDataWorld.class);
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((EntityPlayer) player).getAdvancementData().a(); // stops listening ((EntityPlayer) player).getAdvancementData().a(); // stops listening
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData(); AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData();
AdvancementDataWorld manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancementData(); AdvancementDataWorld manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancementData();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<de.studiocode.inventoryaccess.map.MapIcon> icons) {
List<MapIcon> decorations = icons != null
? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new))
: new ArrayList<>();
int width = 0;
int height = 0;
int startX = 0;
int startY = 0;
byte[] colors = new byte[0];
if (mapPatch != null) {
width = mapPatch.getWidth();
height = mapPatch.getHeight();
startX = mapPatch.getStartX();
startY = mapPatch.getStartY();
colors = mapPatch.getColors();
}
PacketPlayOutMap packet = new PacketPlayOutMap(mapId, scale, !decorations.isEmpty(), locked, decorations, colors, startX, startY, width, height);
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
private MapIcon toMapDecoration(de.studiocode.inventoryaccess.map.MapIcon icon) {
return new MapIcon(
MapIcon.Type.a(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
} }

@ -12,6 +12,7 @@ import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -25,7 +26,7 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -56,11 +57,11 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
// send initial items // send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2)); NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(getActiveWindowId(player), itemsList)); player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
} }
public void sendItem(int slot) { public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(getActiveWindowId(player), slot, getItem(slot))); player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
} }
public void setItem(int slot, ItemStack item) { public void setItem(int slot, ItemStack item) {
@ -75,18 +76,13 @@ public class AnvilInventoryImpl extends ContainerAnvil implements AnvilInventory
else return resultInventory.getItem(0); else return resultInventory.getItem(0);
} }
private int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack)); setItem(slot, CraftItemStack.asNMSCopy(itemStack));
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }

@ -0,0 +1,122 @@
package de.studiocode.inventoryaccess.r5.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r5.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.server.v1_16_R3.*;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R3.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends ContainerCartography implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(ContainerCartography.class, true, "resultInventory");
private final InventoryCraftResult resultInventory = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final IChatBaseComponent title;
private final CraftInventoryView view;
private final EntityPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(EntityPlayer player, IChatBaseComponent title) {
super(player.nextContainerCounter(), player.inventory, ContainerAccess.at(player.getWorld(), new BlockPosition(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(this.inventory, resultInventory);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.activeContainer = this;
// send open packet
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(windowId, Containers.CARTOGRAPHY_TABLE, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.a(ItemStack.b, getItem(0), getItem(1), getItem(2));
player.playerConnection.sendPacket(new PacketPlayOutWindowItems(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.playerConnection.sendPacket(new PacketPlayOutSetSlot(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) inventory.setItem(slot, item);
else resultInventory.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return inventory.getItem(slot);
else return resultInventory.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void a(IInventory inventory) {
}
@Override
public ItemStack shiftClick(EntityHuman entityhuman, int i) {
return ItemStack.b;
}
@Override
public boolean a(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean canUse(EntityHuman entityhuman) {
return true;
}
@Override
public void b(EntityHuman entityHuman) {
// empty
}
}

@ -11,16 +11,27 @@ import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_16_R3.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_16_R3.util.CraftChatMessage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
public static int getActiveWindowId(EntityPlayer player) {
Container container = player.activeContainer;
return container == null ? -1 : container.windowId;
}
@Override @Override
public void openCustomInventory(Player player, Inventory inventory) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null); openCustomInventory(player, inventory, null);
} }
@Override @Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory); Containers<?> windowType = CraftContainer.getNotchInventoryType(inventory);
@ -44,16 +55,11 @@ public class InventoryUtilsImpl implements InventoryUtils {
} }
@Override @Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) { public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
Container container = entityPlayer.activeContainer; Container container = entityPlayer.activeContainer;
entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title))); entityPlayer.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, container.getType(), createNMSComponent(title)));
entityPlayer.updateInventory(container); entityPlayer.updateInventory(container);
} }
public static IChatBaseComponent createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
} }

@ -10,6 +10,7 @@ import net.minecraft.server.v1_16_R3.NBTCompressedStreamTools;
import net.minecraft.server.v1_16_R3.NBTTagCompound; import net.minecraft.server.v1_16_R3.NBTTagCompound;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -21,14 +22,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream out, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream out, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -58,7 +59,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream in, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream in, boolean compressed) {
try { try {
NBTTagCompound nbt; NBTTagCompound nbt;
if (compressed) { if (compressed) {
@ -79,7 +80,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -88,7 +89,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,16 +1,20 @@
package de.studiocode.inventoryaccess.r5.util; package de.studiocode.inventoryaccess.r5.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.server.v1_16_R3.AdvancementDataPlayer; import net.minecraft.server.v1_16_R3.*;
import net.minecraft.server.v1_16_R3.AdvancementDataWorld;
import net.minecraft.server.v1_16_R3.EntityPlayer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_16_R3.CraftServer; import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -18,25 +22,57 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "b", AdvancementDataWorld.class); ReflectionUtils.getMethod(AdvancementDataPlayer.class, true, "b", AdvancementDataWorld.class);
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((EntityPlayer) player).getAdvancementData().a(); // stops listening ((EntityPlayer) player).getAdvancementData().a(); // stops listening
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData(); AdvancementDataPlayer advancements = ((EntityPlayer) player).getAdvancementData();
AdvancementDataWorld manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancementData(); AdvancementDataWorld manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancementData();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<de.studiocode.inventoryaccess.map.MapIcon> icons) {
List<net.minecraft.server.v1_16_R3.MapIcon> decorations = icons != null
? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new))
: new ArrayList<>();
int width = 0;
int height = 0;
int startX = 0;
int startY = 0;
byte[] colors = new byte[0];
if (mapPatch != null) {
width = mapPatch.getWidth();
height = mapPatch.getHeight();
startX = mapPatch.getStartX();
startY = mapPatch.getStartY();
colors = mapPatch.getColors();
}
PacketPlayOutMap packet = new PacketPlayOutMap(mapId, scale, !decorations.isEmpty(), locked, decorations, colors, startX, startY, width, height);
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
}
private MapIcon toMapDecoration(de.studiocode.inventoryaccess.map.MapIcon icon) {
return new MapIcon(
MapIcon.Type.a(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
} }

@ -17,7 +17,7 @@
<maven.compiler.target>16</maven.compiler.target> <maven.compiler.target>16</maven.compiler.target>
<spigotVersion>1.17-R0.1-SNAPSHOT</spigotVersion> <spigotVersion>1.17-R0.1-SNAPSHOT</spigotVersion>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
@ -32,7 +32,7 @@
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -49,7 +49,8 @@
<configuration> <configuration>
<srgIn>org.spigotmc:minecraft-server:${spigotVersion}:txt:maps-mojang</srgIn> <srgIn>org.spigotmc:minecraft-server:${spigotVersion}:txt:maps-mojang</srgIn>
<reverse>true</reverse> <reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-mojang</remappedDependencies> <remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-mojang
</remappedDependencies>
<remappedArtifactAttached>true</remappedArtifactAttached> <remappedArtifactAttached>true</remappedArtifactAttached>
<remappedClassifierName>remapped-obf</remappedClassifierName> <remappedClassifierName>remapped-obf</remappedClassifierName>
</configuration> </configuration>
@ -61,9 +62,12 @@
</goals> </goals>
<id>remap-spigot</id> <id>remap-spigot</id>
<configuration> <configuration>
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile> <inputFile>
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
</inputFile>
<srgIn>org.spigotmc:minecraft-server:${spigotVersion}:csrg:maps-spigot</srgIn> <srgIn>org.spigotmc:minecraft-server:${spigotVersion}:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-obf</remappedDependencies> <remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-obf
</remappedDependencies>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>

@ -12,7 +12,6 @@ import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container; import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.AnvilMenu; import net.minecraft.world.inventory.AnvilMenu;
import net.minecraft.world.inventory.ContainerLevelAccess; import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
@ -24,6 +23,7 @@ import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -37,7 +37,7 @@ public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -68,14 +68,14 @@ public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
// send initial items // send initial items
NonNullList<ItemStack> itemsList = NonNullList.of(ItemStack.EMPTY, getItem(0), getItem(1), getItem(2)); NonNullList<ItemStack> itemsList = NonNullList.of(ItemStack.EMPTY, getItem(0), getItem(1), getItem(2));
player.connection.send(new ClientboundContainerSetContentPacket(getActiveWindowId(player), itemsList)); player.connection.send(new ClientboundContainerSetContentPacket(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
// init menu // init menu
player.initMenu(this); player.initMenu(this);
} }
public void sendItem(int slot) { public void sendItem(int slot) {
player.connection.send(new ClientboundContainerSetSlotPacket(getActiveWindowId(player), slot, getItem(slot))); player.connection.send(new ClientboundContainerSetSlotPacket(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
} }
public void setItem(int slot, ItemStack item) { public void setItem(int slot, ItemStack item) {
@ -90,18 +90,13 @@ public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
else return resultSlots.getItem(0); else return resultSlots.getItem(0);
} }
private int getActiveWindowId(ServerPlayer player) {
AbstractContainerMenu container = player.containerMenu;
return container == null ? -1 : container.containerId;
}
@Override @Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack)); setItem(slot, CraftItemStack.asNMSCopy(itemStack));
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }

@ -0,0 +1,134 @@
package de.studiocode.inventoryaccess.r6.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r6.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends CartographyTableMenu implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(CartographyTableMenu.class, true, "u");
private final ResultContainer resultContainer = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final Component title;
private final CraftInventoryView view;
private final ServerPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(ServerPlayer player, Component title) {
super(player.nextContainerCounter(), player.getInventory(), ContainerLevelAccess.create(player.level, new BlockPos(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(container, resultContainer);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.containerMenu = this;
// send open packet
player.connection.send(new ClientboundOpenScreenPacket(containerId, MenuType.CARTOGRAPHY_TABLE, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.of(ItemStack.EMPTY, getItem(0), getItem(1), getItem(2));
player.connection.send(new ClientboundContainerSetContentPacket(InventoryUtilsImpl.getActiveWindowId(player), itemsList));
// init menu
player.initMenu(this);
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.connection.send(new ClientboundContainerSetSlotPacket(InventoryUtilsImpl.getActiveWindowId(player), slot, getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) container.setItem(slot, item);
else resultContainer.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return container.getItem(slot);
else return resultContainer.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void slotsChanged(Container container) {
}
@Override
public ItemStack quickMoveStack(net.minecraft.world.entity.player.Player entityhuman, int i) {
return ItemStack.EMPTY;
}
@Override
public boolean canTakeItemForPickAll(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean stillValid(net.minecraft.world.entity.player.Player entityhuman) {
return true;
}
@Override
protected void clearContainer(net.minecraft.world.entity.player.Player entityhuman, Container container) {
// empty
}
}

@ -17,16 +17,27 @@ import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
public static Component createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
public static int getActiveWindowId(ServerPlayer player) {
AbstractContainerMenu container = player.containerMenu;
return container == null ? -1 : container.containerId;
}
@Override @Override
public void openCustomInventory(Player player, Inventory inventory) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null); openCustomInventory(player, inventory, null);
} }
@Override @Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
MenuType<?> menuType = CraftContainer.getNotchInventoryType(inventory); MenuType<?> menuType = CraftContainer.getNotchInventoryType(inventory);
@ -52,16 +63,11 @@ public class InventoryUtilsImpl implements InventoryUtils {
} }
@Override @Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) { public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
AbstractContainerMenu menu = serverPlayer.containerMenu; AbstractContainerMenu menu = serverPlayer.containerMenu;
serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), createNMSComponent(title))); serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), createNMSComponent(title)));
serverPlayer.initMenu(menu); serverPlayer.initMenu(menu);
} }
public static Component createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
} }

@ -10,6 +10,7 @@ import net.minecraft.nbt.NbtIo;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -21,14 +22,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream outputStream, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream outputStream, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -58,7 +59,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream inputStream, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream inputStream, boolean compressed) {
try { try {
CompoundTag nbt; CompoundTag nbt;
if (compressed) { if (compressed) {
@ -79,7 +80,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -88,7 +89,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,16 +1,26 @@
package de.studiocode.inventoryaccess.r6.util; package de.studiocode.inventoryaccess.r6.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapIcon;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket;
import net.minecraft.server.PlayerAdvancements; import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.ServerAdvancementManager; import net.minecraft.server.ServerAdvancementManager;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.saveddata.maps.MapDecoration;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_17_R1.CraftServer; import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -18,25 +28,52 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(PlayerAdvancements.class, true, "b", ServerAdvancementManager.class); ReflectionUtils.getMethod(PlayerAdvancements.class, true, "b", ServerAdvancementManager.class);
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((ServerPlayer) player).getAdvancements().stopListening(); ((ServerPlayer) player).getAdvancements().stopListening();
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
PlayerAdvancements advancements = ((ServerPlayer) player).getAdvancements(); PlayerAdvancements advancements = ((ServerPlayer) player).getAdvancements();
ServerAdvancementManager manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancements(); ServerAdvancementManager manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancements();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<MapIcon> icons) {
List<MapDecoration> decorations = icons != null ? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new)) : null;
MapItemSavedData.MapPatch patch = toMapPatch(mapPatch);
ClientboundMapItemDataPacket packet = new ClientboundMapItemDataPacket(mapId, scale, locked, decorations, patch);
((CraftPlayer) player).getHandle().connection.send(packet);
}
private MapDecoration toMapDecoration(MapIcon icon) {
return new MapDecoration(
MapDecoration.Type.byIcon(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
private MapItemSavedData.MapPatch toMapPatch(MapPatch patch) {
if (patch == null) return null;
return new MapItemSavedData.MapPatch(
patch.getStartX(), patch.getStartY(),
patch.getWidth(), patch.getHeight(),
patch.getColors()
);
}
} }

@ -17,7 +17,7 @@
<maven.compiler.target>16</maven.compiler.target> <maven.compiler.target>16</maven.compiler.target>
<spigotVersion>1.17.1-R0.1-SNAPSHOT</spigotVersion> <spigotVersion>1.17.1-R0.1-SNAPSHOT</spigotVersion>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
@ -32,7 +32,7 @@
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
@ -49,7 +49,8 @@
<configuration> <configuration>
<srgIn>org.spigotmc:minecraft-server:${spigotVersion}:txt:maps-mojang</srgIn> <srgIn>org.spigotmc:minecraft-server:${spigotVersion}:txt:maps-mojang</srgIn>
<reverse>true</reverse> <reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-mojang</remappedDependencies> <remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-mojang
</remappedDependencies>
<remappedArtifactAttached>true</remappedArtifactAttached> <remappedArtifactAttached>true</remappedArtifactAttached>
<remappedClassifierName>remapped-obf</remappedClassifierName> <remappedClassifierName>remapped-obf</remappedClassifierName>
</configuration> </configuration>
@ -61,9 +62,12 @@
</goals> </goals>
<id>remap-spigot</id> <id>remap-spigot</id>
<configuration> <configuration>
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile> <inputFile>
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
</inputFile>
<srgIn>org.spigotmc:minecraft-server:${spigotVersion}:csrg:maps-spigot</srgIn> <srgIn>org.spigotmc:minecraft-server:${spigotVersion}:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-obf</remappedDependencies> <remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-obf
</remappedDependencies>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>

@ -24,6 +24,7 @@ import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.event.inventory.PrepareAnvilEvent; import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -37,7 +38,7 @@ public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private String text; private String text;
private boolean open; private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, BaseComponent[] title, Consumer<String> renameHandler) { public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler); this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
} }
@ -101,7 +102,7 @@ public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
} }
@Override @Override
public Inventory getBukkitInventory() { public @NotNull Inventory getBukkitInventory() {
return view.getTopInventory(); return view.getTopInventory();
} }
@ -115,7 +116,7 @@ public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
return open; return open;
} }
// --- ContainerAnvil --- // --- AnvilMenu ---
@Override @Override
public CraftInventoryView getBukkitView() { public CraftInventoryView getBukkitView() {

@ -0,0 +1,134 @@
package de.studiocode.inventoryaccess.r7.inventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.r7.util.InventoryUtilsImpl;
import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket;
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryCartography;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class CartographyInventoryImpl extends CartographyTableMenu implements CartographyInventory {
private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField(CartographyTableMenu.class, true, "u");
private final ResultContainer resultContainer = ReflectionUtils.getFieldValue(RESULT_CONTAINER_FIELD, this);
private final Component title;
private final CraftInventoryView view;
private final ServerPlayer player;
private boolean open;
public CartographyInventoryImpl(Player player, @NotNull BaseComponent[] title) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title));
}
public CartographyInventoryImpl(ServerPlayer player, Component title) {
super(player.nextContainerCounter(), player.getInventory(), ContainerLevelAccess.create(player.level, new BlockPos(Integer.MAX_VALUE, 0, 0)));
this.player = player;
this.title = title;
CraftInventoryCartography inventory = new CraftInventoryCartography(container, resultContainer);
view = new CraftInventoryView(player.getBukkitEntity(), inventory, this);
}
public void open() {
open = true;
// call the InventoryOpenEvent
CraftEventFactory.callInventoryOpenEvent(player, this);
// set active container
player.containerMenu = this;
// send open packet
player.connection.send(new ClientboundOpenScreenPacket(containerId, MenuType.CARTOGRAPHY_TABLE, title));
// send initial items
NonNullList<ItemStack> itemsList = NonNullList.of(ItemStack.EMPTY, getItem(0), getItem(1), getItem(2));
player.connection.send(new ClientboundContainerSetContentPacket(InventoryUtilsImpl.getActiveWindowId(player), incrementStateId(), itemsList, ItemStack.EMPTY));
// init menu
player.initMenu(this);
}
@Override
public boolean isOpen() {
return open;
}
public void sendItem(int slot) {
player.connection.send(new ClientboundContainerSetSlotPacket(InventoryUtilsImpl.getActiveWindowId(player), slot, incrementStateId(), getItem(slot)));
}
public void setItem(int slot, ItemStack item) {
if (slot < 2) container.setItem(slot, item);
else resultContainer.setItem(0, item);
if (open) sendItem(slot);
}
private ItemStack getItem(int slot) {
if (slot < 2) return container.getItem(slot);
else return resultContainer.getItem(0);
}
@Override
public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) {
setItem(slot, CraftItemStack.asNMSCopy(itemStack));
}
@Override
public Inventory getBukkitInventory() {
return view.getTopInventory();
}
// --- CartographyTableMenu ---
@Override
public CraftInventoryView getBukkitView() {
return view;
}
@Override
public void slotsChanged(Container container) {
}
@Override
public ItemStack quickMoveStack(net.minecraft.world.entity.player.Player entityhuman, int i) {
return ItemStack.EMPTY;
}
@Override
public boolean canTakeItemForPickAll(ItemStack itemstack, Slot slot) {
return true;
}
@Override
public boolean stillValid(net.minecraft.world.entity.player.Player entityhuman) {
return true;
}
@Override
protected void clearContainer(net.minecraft.world.entity.player.Player entityhuman, Container container) {
// empty
}
}

@ -17,16 +17,27 @@ import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage; import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class InventoryUtilsImpl implements InventoryUtils { public class InventoryUtilsImpl implements InventoryUtils {
public static Component createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
public static int getActiveWindowId(ServerPlayer player) {
AbstractContainerMenu container = player.containerMenu;
return container == null ? -1 : container.containerId;
}
@Override @Override
public void openCustomInventory(Player player, Inventory inventory) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) {
openCustomInventory(player, inventory, null); openCustomInventory(player, inventory, null);
} }
@Override @Override
public void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title) { public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
MenuType<?> menuType = CraftContainer.getNotchInventoryType(inventory); MenuType<?> menuType = CraftContainer.getNotchInventoryType(inventory);
@ -52,16 +63,11 @@ public class InventoryUtilsImpl implements InventoryUtils {
} }
@Override @Override
public void updateOpenInventoryTitle(Player player, BaseComponent[] title) { public void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
AbstractContainerMenu menu = serverPlayer.containerMenu; AbstractContainerMenu menu = serverPlayer.containerMenu;
serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), createNMSComponent(title))); serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), createNMSComponent(title)));
serverPlayer.initMenu(menu); serverPlayer.initMenu(menu);
} }
public static Component createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
} }

@ -10,6 +10,7 @@ import net.minecraft.nbt.NbtIo;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -21,14 +22,14 @@ public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle"); private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override @Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) { public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed); serializeItemStack(itemStack, out, compressed);
return out.toByteArray(); return out.toByteArray();
} }
@Override @Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream outputStream, boolean compressed) { public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream outputStream, boolean compressed) {
try { try {
ItemStack nmsStack; ItemStack nmsStack;
@ -58,7 +59,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public org.bukkit.inventory.ItemStack deserializeItemStack(InputStream inputStream, boolean compressed) { public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream inputStream, boolean compressed) {
try { try {
CompoundTag nbt; CompoundTag nbt;
if (compressed) { if (compressed) {
@ -79,7 +80,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setDisplayName(ItemMeta itemMeta, BaseComponent[] name) { public void setDisplayName(@NotNull ItemMeta itemMeta, BaseComponent[] name) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD,
itemMeta, itemMeta,
@ -88,7 +89,7 @@ public class ItemUtilsImpl implements ItemUtils {
} }
@Override @Override
public void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore) { public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore) {
ReflectionUtils.setFieldValue( ReflectionUtils.setFieldValue(
ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD,
itemMeta, itemMeta,

@ -1,16 +1,26 @@
package de.studiocode.inventoryaccess.r7.util; package de.studiocode.inventoryaccess.r7.util;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.map.MapIcon;
import de.studiocode.inventoryaccess.map.MapPatch;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket;
import net.minecraft.server.PlayerAdvancements; import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.ServerAdvancementManager; import net.minecraft.server.ServerAdvancementManager;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.saveddata.maps.MapDecoration;
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_17_R1.CraftServer; import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PlayerUtilsImpl implements PlayerUtils { public class PlayerUtilsImpl implements PlayerUtils {
@ -18,25 +28,52 @@ public class PlayerUtilsImpl implements PlayerUtils {
ReflectionUtils.getMethod(PlayerAdvancements.class, true, "b", ServerAdvancementManager.class); ReflectionUtils.getMethod(PlayerAdvancements.class, true, "b", ServerAdvancementManager.class);
@Override @Override
public void stopAdvancementListening(Player player) { public void stopAdvancementListening(@NotNull Player player) {
stopAdvancementListening(((CraftPlayer) player).getHandle()); stopAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void stopAdvancementListening(Object player) { public void stopAdvancementListening(@NotNull Object player) {
((ServerPlayer) player).getAdvancements().stopListening(); ((ServerPlayer) player).getAdvancements().stopListening();
} }
@Override @Override
public void startAdvancementListening(Player player) { public void startAdvancementListening(@NotNull Player player) {
startAdvancementListening(((CraftPlayer) player).getHandle()); startAdvancementListening(((CraftPlayer) player).getHandle());
} }
@Override @Override
public void startAdvancementListening(Object player) { public void startAdvancementListening(@NotNull Object player) {
PlayerAdvancements advancements = ((ServerPlayer) player).getAdvancements(); PlayerAdvancements advancements = ((ServerPlayer) player).getAdvancements();
ServerAdvancementManager manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancements(); ServerAdvancementManager manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancements();
ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager); ReflectionUtils.invokeMethod(REGISTER_LISTENERS_METHOD, advancements, manager);
} }
@Override
public void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<MapIcon> icons) {
List<MapDecoration> decorations = icons != null ? icons.stream().map(this::toMapDecoration).collect(Collectors.toCollection(ArrayList::new)) : null;
MapItemSavedData.MapPatch patch = toMapPatch(mapPatch);
ClientboundMapItemDataPacket packet = new ClientboundMapItemDataPacket(mapId, scale, locked, decorations, patch);
((CraftPlayer) player).getHandle().connection.send(packet);
}
private MapDecoration toMapDecoration(MapIcon icon) {
return new MapDecoration(
MapDecoration.Type.byIcon(icon.getType().getId()),
icon.getX(), icon.getY(),
icon.getRot(),
icon.getComponents() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponents()) : null
);
}
private MapItemSavedData.MapPatch toMapPatch(MapPatch patch) {
if (patch == null) return null;
return new MapItemSavedData.MapPatch(
patch.getStartX(), patch.getStartY(),
patch.getWidth(), patch.getHeight(),
patch.getColors()
);
}
} }

@ -2,6 +2,8 @@ package de.studiocode.inventoryaccess.abstraction.inventory;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AnvilInventory { public interface AnvilInventory {
@ -10,6 +12,7 @@ public interface AnvilInventory {
* *
* @return The {@link Inventory} * @return The {@link Inventory}
*/ */
@NotNull
Inventory getBukkitInventory(); Inventory getBukkitInventory();
/** /**
@ -23,7 +26,7 @@ public interface AnvilInventory {
* @param slot The slot * @param slot The slot
* @param itemStack The {@link ItemStack} * @param itemStack The {@link ItemStack}
*/ */
void setItem(int slot, ItemStack itemStack); void setItem(int slot, @Nullable ItemStack itemStack);
/** /**
* Gets the rename text the user has typed in the renaming section of the anvil. * Gets the rename text the user has typed in the renaming section of the anvil.

@ -0,0 +1,35 @@
package de.studiocode.inventoryaccess.abstraction.inventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public interface CartographyInventory {
/**
* Gets Bukkit's {@link Inventory} associated to this {@link AnvilInventory}
*
* @return The {@link Inventory}
*/
Inventory getBukkitInventory();
/**
* Sets an {@link ItemStack} on one of the three slots.
*
* @param slot The slot
* @param itemStack The {@link ItemStack}
*/
void setItem(int slot, ItemStack itemStack);
/**
* Opens the inventory.
*/
void open();
/**
* Gets if this inventory is currently open.
*
* @return If the inventory is currently open
*/
boolean isOpen();
}

@ -4,6 +4,7 @@ import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
import org.jetbrains.annotations.NotNull;
public interface InventoryUtils { public interface InventoryUtils {
@ -16,7 +17,7 @@ public interface InventoryUtils {
* @param player The {@link Player} to open the {@link Inventory} for * @param player The {@link Player} to open the {@link Inventory} for
* @param inventory The {@link Inventory} * @param inventory The {@link Inventory}
*/ */
void openCustomInventory(Player player, Inventory inventory); void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory);
/** /**
* Opens an {@link Inventory} as a custom inventory with a title that differs from the * Opens an {@link Inventory} as a custom inventory with a title that differs from the
@ -29,7 +30,7 @@ public interface InventoryUtils {
* @param inventory The {@link Inventory} * @param inventory The {@link Inventory}
* @param title The title of the inventory * @param title The title of the inventory
*/ */
void openCustomInventory(Player player, Inventory inventory, BaseComponent[] title); void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @NotNull BaseComponent[] title);
/** /**
* Changes the title of the {@link Inventory} the player is currently viewing. * Changes the title of the {@link Inventory} the player is currently viewing.
@ -37,6 +38,6 @@ public interface InventoryUtils {
* @param player The {@link Player} * @param player The {@link Player}
* @param title The new title * @param title The new title
*/ */
void updateOpenInventoryTitle(Player player, BaseComponent[] title); void updateOpenInventoryTitle(@NotNull Player player, @NotNull BaseComponent[] title);
} }

@ -3,6 +3,7 @@ package de.studiocode.inventoryaccess.abstraction.util;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -18,7 +19,7 @@ public interface ItemUtils {
* @return The serialized data * @return The serialized data
* @see #deserializeItemStack(byte[], boolean) * @see #deserializeItemStack(byte[], boolean)
*/ */
byte[] serializeItemStack(ItemStack itemStack, boolean compressed); byte[] serializeItemStack(@NotNull ItemStack itemStack, boolean compressed);
/** /**
* Serializes an {@link ItemStack} to a byte[] * Serializes an {@link ItemStack} to a byte[]
@ -28,7 +29,7 @@ public interface ItemUtils {
* @param compressed If the data should be compressed * @param compressed If the data should be compressed
* @see #deserializeItemStack(InputStream, boolean) * @see #deserializeItemStack(InputStream, boolean)
*/ */
void serializeItemStack(ItemStack itemStack, OutputStream outputStream, boolean compressed); void serializeItemStack(@NotNull ItemStack itemStack, @NotNull OutputStream outputStream, boolean compressed);
/** /**
* Deserializes an {@link ItemStack} from a byte[] * Deserializes an {@link ItemStack} from a byte[]
@ -48,20 +49,22 @@ public interface ItemUtils {
* @return The {@link ItemStack} * @return The {@link ItemStack}
* @see #serializeItemStack(ItemStack, OutputStream, boolean) * @see #serializeItemStack(ItemStack, OutputStream, boolean)
*/ */
ItemStack deserializeItemStack(InputStream inputStream, boolean compressed); ItemStack deserializeItemStack(@NotNull InputStream inputStream, boolean compressed);
/** /**
* Sets the display name of an {@link ItemMeta} * Sets the display name of an {@link ItemMeta}
*
* @param itemMeta The {@link ItemMeta} * @param itemMeta The {@link ItemMeta}
* @param name The display name as a {@link BaseComponent BaseComponent[]} * @param name The display name as a {@link BaseComponent BaseComponent[]}
*/ */
void setDisplayName(ItemMeta itemMeta, BaseComponent[] name); void setDisplayName(@NotNull ItemMeta itemMeta, @NotNull BaseComponent[] name);
/** /**
* Sets the lore of an {@link ItemMeta} * Sets the lore of an {@link ItemMeta}
*
* @param itemMeta The {@link ItemMeta} * @param itemMeta The {@link ItemMeta}
* @param lore The lore as a list of {@link BaseComponent BaseComponent[]} * @param lore The lore as a list of {@link BaseComponent BaseComponent[]}
*/ */
void setLore(ItemMeta itemMeta, List<BaseComponent[]> lore); void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull BaseComponent[]> lore);
} }

@ -1,6 +1,12 @@
package de.studiocode.inventoryaccess.abstraction.util; package de.studiocode.inventoryaccess.abstraction.util;
import de.studiocode.inventoryaccess.map.MapIcon;
import de.studiocode.inventoryaccess.map.MapPatch;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface PlayerUtils { public interface PlayerUtils {
@ -9,27 +15,40 @@ public interface PlayerUtils {
* *
* @param player The {@link Player} * @param player The {@link Player}
*/ */
void stopAdvancementListening(Player player); void stopAdvancementListening(@NotNull Player player);
/** /**
* Stops the advancement listener for a player * Stops the advancement listener for a {@link Player}
* *
* @param player The player * @param player The {@link Player}
*/ */
void stopAdvancementListening(Object player); void stopAdvancementListening(@NotNull Object player);
/** /**
* Starts the advancement listener for a {@link Player} * Starts the advancement listener for a {@link Player}
* *
* @param player The {@link Player} * @param player The {@link Player}
*/ */
void startAdvancementListening(Player player); void startAdvancementListening(@NotNull Player player);
/** /**
* Stops the advancement listener for a player * Stops the advancement listener for a {@link Player}
* *
* @param player The player * @param player The {@link Player}
*/ */
void startAdvancementListening(Object player); void startAdvancementListening(@NotNull Object player);
/**
* Sends a map update to a {@link Player}
*
* @param player The {@link Player} to receive the map update
* @param mapId The id of the map to update
* @param scale The scale of the map. From 0 for a fully zoomed-in map
* (1 block per pixel) to 4 for a fully zoomed-out map (16 blocks per pixel)
* @param locked If the map has been locked in the cartography table
* @param mapPatch The {@link MapPatch} to update, can be null
* @param icons The {@link MapIcon new icons} to be displayed, can be null
*/
void sendMapUpdate(@NotNull Player player, int mapId, byte scale, boolean locked, @Nullable MapPatch mapPatch, @Nullable List<MapIcon> icons);
} }

@ -0,0 +1,116 @@
package de.studiocode.inventoryaccess.map;
import net.md_5.bungee.api.chat.BaseComponent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MapIcon {
private final MapIconType type;
private final byte x;
private final byte y;
private final byte rot;
private final BaseComponent[] components;
public MapIcon(@NotNull MapIconType type, int x, int y, int rot, @Nullable BaseComponent[] components) {
this.type = type;
this.x = (byte) (x - 128);
this.y = (byte) (y - 128);
this.rot = (byte) rot;
this.components = components;
}
public MapIcon(MapIconType type, byte x, byte y, byte rot) {
this(type, x, y, rot, null);
}
@NotNull
public MapIconType getType() {
return type;
}
public byte getX() {
return x;
}
public byte getY() {
return y;
}
public byte getRot() {
return rot;
}
@Nullable
public BaseComponent[] getComponents() {
return components;
}
public enum MapIconType {
WHITE_ARROW(false, true),
GREEN_ARROW(true, true),
RED_ARROW(false, true),
BLUE_ARROW(false, true),
WHITE_CROSS(true, false),
RED_POINTER(true, false),
WHITE_CIRCLE(false, true),
SMALL_WHITE_CIRCLE(false, true),
MANSION(true, false, 5393476),
TEMPLE(true, false, 3830373),
WHITE_BANNER(true, true),
ORANGE_BANNER(true, true),
MAGENTA_BANNER(true, true),
LIGHT_BLUE_BANNER(true, true),
YELLOW_BANNER(true, true),
LIME_BANNER(true, true),
PINK_BANNER(true, true),
GRAY_BANNER(true, true),
LIGHT_GRAY_BANNER(true, true),
CYAN_BANNER(true, true),
PURPLE_BANNER(true, true),
BLUE_BANNER(true, true),
BROWN_BANNER(true, true),
GREEN_BANNER(true, true),
RED_BANNER(true, true),
BLACK_BANNER(true, true),
RED_CROSS(true, false);
private final byte id;
private final boolean renderedOnFrame;
private final int mapColor;
private final boolean trackCount;
MapIconType(boolean renderedOnFrame, boolean trackCount) {
this(renderedOnFrame, trackCount, -1);
}
MapIconType(boolean renderedOnFrame, boolean trackCount, int mapColor) {
this.trackCount = trackCount;
this.id = (byte) this.ordinal();
this.renderedOnFrame = renderedOnFrame;
this.mapColor = mapColor;
}
public byte getId() {
return this.id;
}
public boolean isRenderedOnFrame() {
return this.renderedOnFrame;
}
public boolean hasMapColor() {
return this.mapColor >= 0;
}
public int getMapColor() {
return this.mapColor;
}
public boolean shouldTrackCount() {
return this.trackCount;
}
}
}

@ -0,0 +1,41 @@
package de.studiocode.inventoryaccess.map;
import java.io.Serializable;
public class MapPatch implements Serializable {
private final int startX;
private final int startY;
private final int width;
private final int height;
private final byte[] colors;
public MapPatch(int startX, int startY, int width, int height, byte[] colors) {
this.startX = startX;
this.startY = startY;
this.width = width;
this.height = height;
this.colors = colors;
}
public int getStartX() {
return startX;
}
public int getStartY() {
return startY;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public byte[] getColors() {
return colors;
}
}

@ -14,16 +14,12 @@ public class ReflectionRegistry {
// Classes // Classes
public static final Class<?> CB_CRAFT_META_SKULL_CLASS = getCBClass("inventory.CraftMetaSkull"); public static final Class<?> CB_CRAFT_META_SKULL_CLASS = getCBClass("inventory.CraftMetaSkull");
public static final Class<?> PLUGIN_CLASS_LOADER_CLASS = getBukkitClass("plugin.java.PluginClassLoader");
public static final Class<?> CB_CRAFT_META_ITEM_CLASS = getCBClass("inventory.CraftMetaItem");
public static final Class<?> CB_CRAFT_ITEM_STACK_CLASS = getCBClass("inventory.CraftItemStack");
// Fields // Fields
public static final Field CB_CRAFT_META_SKULL_PROFILE_FIELD = getField(CB_CRAFT_META_SKULL_CLASS, true, "profile"); public static final Field CB_CRAFT_META_SKULL_PROFILE_FIELD = getField(CB_CRAFT_META_SKULL_CLASS, true, "profile");
public static final Class<?> PLUGIN_CLASS_LOADER_CLASS = getBukkitClass("plugin.java.PluginClassLoader");
public static final Field PLUGIN_CLASS_LOADER_PLUGIN_FIELD = getField(PLUGIN_CLASS_LOADER_CLASS, true, "plugin"); public static final Field PLUGIN_CLASS_LOADER_PLUGIN_FIELD = getField(PLUGIN_CLASS_LOADER_CLASS, true, "plugin");
public static final Field CB_CRAFT_META_ITEM_INTERNAL_TAG_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "internalTag"); public static final Class<?> CB_CRAFT_META_ITEM_CLASS = getCBClass("inventory.CraftMetaItem");
public static final Field CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "displayName"); public static final Field CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "displayName");
public static final Field CB_CRAFT_META_ITEM_LORE_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "lore"); public static final Field CB_CRAFT_META_ITEM_LORE_FIELD = getField(CB_CRAFT_META_ITEM_CLASS, true, "lore");
public static final Field CB_CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CB_CRAFT_ITEM_STACK_CLASS, true, "handle");
} }

@ -32,7 +32,7 @@ public class ReflectionUtils {
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }

@ -1,12 +1,14 @@
package de.studiocode.inventoryaccess.version; package de.studiocode.inventoryaccess.version;
import de.studiocode.inventoryaccess.abstraction.inventory.AnvilInventory; import de.studiocode.inventoryaccess.abstraction.inventory.AnvilInventory;
import de.studiocode.inventoryaccess.abstraction.inventory.CartographyInventory;
import de.studiocode.inventoryaccess.abstraction.util.InventoryUtils; import de.studiocode.inventoryaccess.abstraction.util.InventoryUtils;
import de.studiocode.inventoryaccess.abstraction.util.ItemUtils; import de.studiocode.inventoryaccess.abstraction.util.ItemUtils;
import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils; import de.studiocode.inventoryaccess.abstraction.util.PlayerUtils;
import de.studiocode.inventoryaccess.util.ReflectionUtils; import de.studiocode.inventoryaccess.util.ReflectionUtils;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -17,9 +19,12 @@ public class InventoryAccess {
private static final Class<ItemUtils> ITEM_UTILS_CLASS = ReflectionUtils.getImplClass("util.ItemUtilsImpl"); private static final Class<ItemUtils> ITEM_UTILS_CLASS = ReflectionUtils.getImplClass("util.ItemUtilsImpl");
private static final Class<PlayerUtils> PLAYER_UTILS_CLASS = ReflectionUtils.getImplClass("util.PlayerUtilsImpl"); private static final Class<PlayerUtils> PLAYER_UTILS_CLASS = ReflectionUtils.getImplClass("util.PlayerUtilsImpl");
private static final Class<AnvilInventory> ANVIL_INVENTORY_CLASS = ReflectionUtils.getImplClass("inventory.AnvilInventoryImpl"); private static final Class<AnvilInventory> ANVIL_INVENTORY_CLASS = ReflectionUtils.getImplClass("inventory.AnvilInventoryImpl");
private static final Class<CartographyInventory> CARTOGRAPHY_INVENTORY_CLASS = ReflectionUtils.getImplClass("inventory.CartographyInventoryImpl");
private static final Constructor<AnvilInventory> ANVIL_INVENTORY_CONSTRUCTOR private static final Constructor<AnvilInventory> ANVIL_INVENTORY_CONSTRUCTOR =
= ReflectionUtils.getConstructor(ANVIL_INVENTORY_CLASS, false, Player.class, BaseComponent[].class, Consumer.class); ReflectionUtils.getConstructor(ANVIL_INVENTORY_CLASS, false, Player.class, BaseComponent[].class, Consumer.class);
private static final Constructor<CartographyInventory> CARTOGRAPHY_INVENTORY_CONSTRUCTOR =
ReflectionUtils.getConstructor(CARTOGRAPHY_INVENTORY_CLASS, false, Player.class, BaseComponent[].class);
private static final InventoryUtils INVENTORY_UTILS = ReflectionUtils.constructEmpty(INVENTORY_UTILS_CLASS); private static final InventoryUtils INVENTORY_UTILS = ReflectionUtils.constructEmpty(INVENTORY_UTILS_CLASS);
private static final ItemUtils ITEM_UTILS = ReflectionUtils.constructEmpty(ITEM_UTILS_CLASS); private static final ItemUtils ITEM_UTILS = ReflectionUtils.constructEmpty(ITEM_UTILS_CLASS);
@ -56,13 +61,24 @@ public class InventoryAccess {
* Creates a new {@link AnvilInventory}. * Creates a new {@link AnvilInventory}.
* *
* @param player The {@link Player} that should see this {@link AnvilInventory} * @param player The {@link Player} that should see this {@link AnvilInventory}
* @param title The title {@link String} of the {@link AnvilInventory} * @param title The inventory title as a {@link BaseComponent BaseComponent[]}
* @param renameHandler A {@link Consumer} that is called whenever the {@link Player} * @param renameHandler A {@link Consumer} that is called whenever the {@link Player}
* types something in the renaming section of the anvil * types something in the renaming section of the anvil
* @return The {@link AnvilInventory} * @return The {@link AnvilInventory}
*/ */
public static AnvilInventory createAnvilInventory(Player player, BaseComponent[] title, Consumer<String> renameHandler) { public static AnvilInventory createAnvilInventory(@NotNull Player player, @NotNull BaseComponent[] title, Consumer<String> renameHandler) {
return ReflectionUtils.construct(ANVIL_INVENTORY_CONSTRUCTOR, player, title, renameHandler); return ReflectionUtils.construct(ANVIL_INVENTORY_CONSTRUCTOR, player, title, renameHandler);
} }
/**
* Creates a new {@link CartographyInventory}.
*
* @param player The {@link Player} that should see this {@link CartographyInventory}
* @param title The inventory title as a {@link BaseComponent BaseComponent[]}
* @return The {@link CartographyInventory}
*/
public static CartographyInventory createCartographyInventory(@NotNull Player player, @NotNull BaseComponent[] title) {
return ReflectionUtils.construct(CARTOGRAPHY_INVENTORY_CONSTRUCTOR, player, title);
}
} }

@ -23,6 +23,13 @@ public enum InventoryAccessRevision {
this.since = VersionUtils.toMajorMinorPatch(since); this.since = VersionUtils.toMajorMinorPatch(since);
} }
private static InventoryAccessRevision getRequiredRevision() {
for (InventoryAccessRevision revision : values())
if (VersionUtils.isServerHigherOrEqual(revision.getSince())) return revision;
throw new UnsupportedOperationException("Your version of Minecraft is not supported by InventoryAccess");
}
public String getPackageName() { public String getPackageName() {
return packageName; return packageName;
} }
@ -31,11 +38,4 @@ public enum InventoryAccessRevision {
return since; return since;
} }
private static InventoryAccessRevision getRequiredRevision() {
for (InventoryAccessRevision revision : values())
if (VersionUtils.isServerHigherOrEqual(revision.getSince())) return revision;
throw new UnsupportedOperationException("Your version of Minecraft is not supported by InventoryAccess");
}
} }

@ -6,6 +6,7 @@
![License](https://img.shields.io/github/license/NichtStudioCode/InvUI) ![License](https://img.shields.io/github/license/NichtStudioCode/InvUI)
# InvUI # InvUI
An Inventory API for Minecraft Spigot servers. An Inventory API for Minecraft Spigot servers.
Supports all versions from 1.14 to 1.17. Supports all versions from 1.14 to 1.17.
@ -13,15 +14,17 @@ Supports all versions from 1.14 to 1.17.
[Wiki](https://github.com/NichtStudioCode/InvUI/wiki) [Wiki](https://github.com/NichtStudioCode/InvUI/wiki)
## Features ## Features
* Different types of inventories (Chest, Anvil, Dropper...)
* Different GUI types (Normal, Paged, Tab, Scroll) * Different types of inventories (Chest, Anvil, Dropper...)
* Nested GUIs (For example use another PagedGUI as a page) * Different GUI types (Normal, Paged, Tab, Scroll)
* Easily customizable (Create your own GUI types and Items) * Nested GUIs (For example use another PagedGUI as a page)
* Easy way to add localization using the built-in ItemBuilder * Easily customizable (Create your own GUI types and Items)
* Supports custom textures (Forced ResourcePack) * Easy way to add localization using the built-in ItemBuilder
* Uncloseable inventories * Supports custom textures (Forced ResourcePack)
* GUI Builder * Uncloseable inventories
* GUI Builder
## Examples ## Examples
![1](https://i.imgur.com/uaqjHSS.gif)
![1](https://i.imgur.com/uaqjHSS.gif)
![2](https://i.imgur.com/rvE7VK5.gif) ![2](https://i.imgur.com/rvE7VK5.gif)

@ -28,6 +28,15 @@
</repository> </repository>
</repositories> </repositories>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<modules> <modules>
<module>InventoryAccess/IA-R1</module> <module>InventoryAccess/IA-R1</module>
<module>InventoryAccess/IA-R2</module> <module>InventoryAccess/IA-R2</module>