From 05f02dae78506b3a832465ec18711aca384463b1 Mon Sep 17 00:00:00 2001 From: NichtStudioCode <51272202+NichtStudioCode@users.noreply.github.com> Date: Sun, 24 Sep 2023 18:06:23 +0200 Subject: [PATCH] 1.20.2 Support --- inventoryaccess/inventory-access-r15/pom.xml | 139 +++++++++++++ .../r15/AnvilInventoryImpl.java | 190 ++++++++++++++++++ .../r15/CartographyInventoryImpl.java | 137 +++++++++++++ .../r15/InventoryUtilsImpl.java | 73 +++++++ .../inventoryaccess/r15/ItemUtilsImpl.java | 91 +++++++++ .../inventoryaccess/r15/PlayerUtilsImpl.java | 98 +++++++++ .../version/InventoryAccessRevision.java | 1 + invui/pom.xml | 5 + pom.xml | 1 + 9 files changed, 735 insertions(+) create mode 100644 inventoryaccess/inventory-access-r15/pom.xml create mode 100644 inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/AnvilInventoryImpl.java create mode 100644 inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/CartographyInventoryImpl.java create mode 100644 inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/InventoryUtilsImpl.java create mode 100644 inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/ItemUtilsImpl.java create mode 100644 inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/PlayerUtilsImpl.java diff --git a/inventoryaccess/inventory-access-r15/pom.xml b/inventoryaccess/inventory-access-r15/pom.xml new file mode 100644 index 0000000..2beba21 --- /dev/null +++ b/inventoryaccess/inventory-access-r15/pom.xml @@ -0,0 +1,139 @@ + + + + xyz.xenondevs.invui + invui-parent + 1.16 + ../../pom.xml + + 4.0.0 + + inventory-access-r15 + + + 17 + 17 + 1.20.2-R0.1-SNAPSHOT + + + + + org.spigotmc + spigot + ${spigot.version} + remapped-mojang + provided + + + xyz.xenondevs.invui + inventory-access + ${project.parent.version} + + + + + + + xyz.xenondevs.string-remapper + string-remapper-maven-plugin + 1.2 + + + + remap-spigot + + remap + + + ${spigot.version} + spigot + ${project.build.directory}/classes + ${project.build.directory}/classes-spigot + + + + + remap-mojang + + remap + + + ${spigot.version} + mojang + ${project.build.directory}/classes + ${project.build.directory}/classes-mojang + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + default-jar + none + + + spigot + + jar + + + ${project.build.directory}/classes-spigot + + + + mojang + + jar + + + ${project.build.directory}/classes-mojang + remapped-mojang + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.2 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:${spigot.version}:txt:maps-mojang + true + org.spigotmc:spigot:${spigot.version}:jar:remapped-mojang + false + ${project.artifactId}-${project.version}-remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:${spigot.version}:csrg:maps-spigot + org.spigotmc:spigot:${spigot.version}:jar:remapped-obf + + + + + + + + \ No newline at end of file diff --git a/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/AnvilInventoryImpl.java b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/AnvilInventoryImpl.java new file mode 100644 index 0000000..2f9c025 --- /dev/null +++ b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/AnvilInventoryImpl.java @@ -0,0 +1,190 @@ +package xyz.xenondevs.inventoryaccess.r15; + +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.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.AnvilMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R2.event.CraftEventFactory; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventoryAnvil; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.inventoryaccess.abstraction.inventory.AnvilInventory; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; + +import java.util.List; +import java.util.function.Consumer; + +class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory { + + private final List> renameHandlers; + private final CraftInventoryView view; + private final ServerPlayer player; + + private String text; + private boolean open; + + public AnvilInventoryImpl(org.bukkit.entity.Player player, @NotNull ComponentWrapper title, List> renameHandlers) { + this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandlers); + } + + public AnvilInventoryImpl(ServerPlayer player, Component title, List> renameHandlers) { + super(player.nextContainerCounter(), player.getInventory(), + ContainerLevelAccess.create(player.level(), new BlockPos(0, 0, 0))); + + setTitle(title); + this.renameHandlers = renameHandlers; + this.player = player; + + CraftInventoryAnvil inventory = new CraftInventoryAnvil(access.getLocation(), + inputSlots, resultSlots, this); + this.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.ANVIL, getTitle())); + + // send initial items + NonNullList itemsList = NonNullList.of(ItemStack.EMPTY, getItem(0), getItem(1), getItem(2)); + player.connection.send(new ClientboundContainerSetContentPacket(getActiveWindowId(player), incrementStateId(), itemsList, ItemStack.EMPTY)); + + // init menu + player.initMenu(this); + } + + public void sendItem(int slot) { + player.connection.send(new ClientboundContainerSetSlotPacket(getActiveWindowId(player), incrementStateId(), slot, getItem(slot))); + } + + public void setItem(int slot, ItemStack item) { + if (slot < 2) inputSlots.setItem(slot, item); + else resultSlots.setItem(0, item); + + if (open) sendItem(slot); + } + + private ItemStack getItem(int slot) { + if (slot < 2) return inputSlots.getItem(slot); + else return resultSlots.getItem(0); + } + + private int getActiveWindowId(ServerPlayer player) { + AbstractContainerMenu container = player.containerMenu; + return container == null ? -1 : container.containerId; + } + + @Override + public void setItem(int slot, org.bukkit.inventory.ItemStack itemStack) { + setItem(slot, CraftItemStack.asNMSCopy(itemStack)); + } + + @Override + public @NotNull Inventory getBukkitInventory() { + return view.getTopInventory(); + } + + @Override + public String getRenameText() { + return text; + } + + @Override + public boolean isOpen() { + return open; + } + + // --- AnvilMenu --- + + @Override + public CraftInventoryView getBukkitView() { + return view; + } + + /** + * Called every tick to see if the {@link Player} can still use that container. + * (Used to for checking the distance between the {@link Player} and the container + * and closing the window when the distance gets too big.) + * + * @param player The {@link Player} + * @return If the {@link Player} can still use that container + */ + @Override + public boolean stillValid(Player player) { + return true; + } + + /** + * Called when the rename text gets changed. + * + * @param s The new rename text + */ + @Override + public boolean setItemName(String s) { + // save rename text + text = s; + + // call rename handlers + if (renameHandlers != null) + renameHandlers.forEach(handler -> handler.accept(s)); + + // the client expects the item to change to its new name and removes it from the inventory, so it needs to be sent again + sendItem(2); + + return false; + } + + /** + * Called when the container is closed to give the items back. + * + * @param player The {@link Player} that closed this container + */ + @Override + public void removed(Player player) { + open = false; + } + + + /** + * Called when the container gets closed to put items back into a players + * inventory or drop them in the world. + * + * @param player The {@link Player} that closed this container + * @param container The container + */ + @Override + protected void clearContainer(Player player, Container container) { + open = false; + } + + /** + * Called when both items in the {@link AnvilMenu#inputSlots} were set to create + * the resulting product, calculate the level cost and call the {@link PrepareAnvilEvent}. + */ + @Override + public void createResult() { + // empty + } + +} diff --git a/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/CartographyInventoryImpl.java b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/CartographyInventoryImpl.java new file mode 100644 index 0000000..ee60a45 --- /dev/null +++ b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/CartographyInventoryImpl.java @@ -0,0 +1,137 @@ +package xyz.xenondevs.inventoryaccess.r15; + +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_20_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R2.event.CraftEventFactory; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventoryCartography; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.inventoryaccess.abstraction.inventory.CartographyInventory; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; +import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; +import net.minecraft.world.entity.player.Player; + +import java.lang.reflect.Field; + +class CartographyInventoryImpl extends CartographyTableMenu implements CartographyInventory { + + private static final Field RESULT_CONTAINER_FIELD = ReflectionUtils.getField( + CartographyTableMenu.class, + true, + "SRF(net.minecraft.world.inventory.CartographyTableMenu resultContainer)" + ); + + 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(org.bukkit.entity.Player player, @NotNull ComponentWrapper 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(0, 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 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(Player player, int i) { + return ItemStack.EMPTY; + } + + @Override + public boolean canTakeItemForPickAll(ItemStack itemstack, Slot slot) { + return true; + } + + @Override + public boolean stillValid(Player player) { + return true; + } + + @Override + protected void clearContainer(Player player, Container container) { + // empty + } + +} diff --git a/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/InventoryUtilsImpl.java b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/InventoryUtilsImpl.java new file mode 100644 index 0000000..030751b --- /dev/null +++ b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/InventoryUtilsImpl.java @@ -0,0 +1,73 @@ +package xyz.xenondevs.inventoryaccess.r15; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.Container; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_20_R2.event.CraftEventFactory; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftContainer; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftInventory; +import org.bukkit.craftbukkit.v1_20_R2.util.CraftChatMessage; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.inventoryaccess.abstraction.util.InventoryUtils; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; + +class InventoryUtilsImpl implements InventoryUtils { + + public static Component createNMSComponent(ComponentWrapper component) { + if (component == null) return null; + return CraftChatMessage.fromJSON(component.serializeToJson()); + } + + public static int getActiveWindowId(ServerPlayer player) { + AbstractContainerMenu container = player.containerMenu; + return container == null ? -1 : container.containerId; + } + + @Override + public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory) { + openCustomInventory(player, inventory, null); + } + + @Override + public void openCustomInventory(@NotNull Player player, @NotNull Inventory inventory, @Nullable ComponentWrapper title) { + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + MenuType menuType = CraftContainer.getNotchInventoryType(inventory); + + if (serverPlayer.connection != null) { + AbstractContainerMenu menu = new CraftContainer(inventory, serverPlayer, serverPlayer.nextContainerCounter()); + menu = CraftEventFactory.callInventoryOpenEvent(serverPlayer, menu); + if (menu != null) { + Container container = ((CraftInventory) inventory).getInventory(); + Component titleComponent; + if (title == null) { + if (container instanceof MenuProvider) + titleComponent = ((MenuProvider) container).getDisplayName(); + else titleComponent = CraftChatMessage.fromString(menu.getBukkitView().getTitle())[0]; + } else titleComponent = createNMSComponent(title); + + menu.checkReachable = false; + serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menuType, titleComponent)); + serverPlayer.containerMenu = menu; + serverPlayer.initMenu(menu); + } + } + + } + + @Override + public void updateOpenInventoryTitle(@NotNull Player player, @NotNull ComponentWrapper title) { + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + AbstractContainerMenu menu = serverPlayer.containerMenu; + serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), createNMSComponent(title))); + serverPlayer.initMenu(menu); + } + +} diff --git a/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/ItemUtilsImpl.java b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/ItemUtilsImpl.java new file mode 100644 index 0000000..969903b --- /dev/null +++ b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/ItemUtilsImpl.java @@ -0,0 +1,91 @@ +package xyz.xenondevs.inventoryaccess.r15; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import xyz.xenondevs.inventoryaccess.abstraction.util.ItemUtils; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; +import xyz.xenondevs.inventoryaccess.util.ReflectionRegistry; +import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; + +import java.io.*; +import java.util.List; +import java.util.stream.Collectors; + +class ItemUtilsImpl implements ItemUtils { + + @Override + public byte[] serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, boolean compressed) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + serializeItemStack(itemStack, out, compressed); + return out.toByteArray(); + } + + @Override + public void serializeItemStack(org.bukkit.inventory.@NotNull ItemStack itemStack, @NotNull OutputStream outputStream, boolean compressed) { + try { + ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + CompoundTag nbt = nmsStack.save(new CompoundTag()); + + if (compressed) { + NbtIo.writeCompressed(nbt, outputStream); + } else { + DataOutputStream dataOut = new DataOutputStream(outputStream); + NbtIo.write(nbt, dataOut); + } + + outputStream.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public org.bukkit.inventory.ItemStack deserializeItemStack(byte[] data, boolean compressed) { + ByteArrayInputStream in = new ByteArrayInputStream(data); + return deserializeItemStack(in, compressed); + } + + @Override + public org.bukkit.inventory.ItemStack deserializeItemStack(@NotNull InputStream inputStream, boolean compressed) { + try { + CompoundTag nbt; + if (compressed) { + nbt = NbtIo.readCompressed(inputStream); + } else { + DataInputStream dataIn = new DataInputStream(inputStream); + nbt = NbtIo.read(dataIn); + } + + ItemStack itemStack = ItemStack.of(nbt); + + return CraftItemStack.asCraftMirror(itemStack); + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void setDisplayName(@NotNull ItemMeta itemMeta, @NotNull ComponentWrapper name) { + ReflectionUtils.setFieldValue( + ReflectionRegistry.CB_CRAFT_META_ITEM_DISPLAY_NAME_FIELD, + itemMeta, + name.serializeToJson() + ); + } + + @Override + public void setLore(@NotNull ItemMeta itemMeta, @NotNull List<@NotNull ComponentWrapper> lore) { + ReflectionUtils.setFieldValue( + ReflectionRegistry.CB_CRAFT_META_ITEM_LORE_FIELD, + itemMeta, + lore.stream().map(ComponentWrapper::serializeToJson).collect(Collectors.toList()) + ); + } + +} \ No newline at end of file diff --git a/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/PlayerUtilsImpl.java b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/PlayerUtilsImpl.java new file mode 100644 index 0000000..46f5c9c --- /dev/null +++ b/inventoryaccess/inventory-access-r15/src/main/java/xyz/xenondevs/inventoryaccess/r15/PlayerUtilsImpl.java @@ -0,0 +1,98 @@ +package xyz.xenondevs.inventoryaccess.r15; + +import net.minecraft.network.protocol.common.ClientboundResourcePackPacket; +import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; +import net.minecraft.server.PlayerAdvancements; +import net.minecraft.server.ServerAdvancementManager; +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.craftbukkit.v1_20_R2.CraftServer; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.xenondevs.inventoryaccess.abstraction.util.PlayerUtils; +import xyz.xenondevs.inventoryaccess.component.ComponentWrapper; +import xyz.xenondevs.inventoryaccess.map.MapIcon; +import xyz.xenondevs.inventoryaccess.map.MapPatch; +import xyz.xenondevs.inventoryaccess.util.DataUtils; +import xyz.xenondevs.inventoryaccess.util.ReflectionUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +class PlayerUtilsImpl implements PlayerUtils { + + private static final Method REGISTER_LISTENERS_METHOD = ReflectionUtils.getMethod( + PlayerAdvancements.class, + true, + "ASRM(net/minecraft/server/PlayerAdvancements.registerListeners(Lnet/minecraft/server/ServerAdvancementManager;)V)", + ServerAdvancementManager.class + ); + + @Override + public void stopAdvancementListening(@NotNull Player player) { + stopAdvancementListening(((CraftPlayer) player).getHandle()); + } + + @Override + public void stopAdvancementListening(@NotNull Object player) { + ((ServerPlayer) player).getAdvancements().stopListening(); + } + + @Override + public void startAdvancementListening(@NotNull Player player) { + startAdvancementListening(((CraftPlayer) player).getHandle()); + } + + @Override + public void startAdvancementListening(@NotNull Object player) { + PlayerAdvancements advancements = ((ServerPlayer) player).getAdvancements(); + ServerAdvancementManager manager = ((CraftServer) Bukkit.getServer()).getServer().getAdvancements(); + 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 icons) { + List 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.getComponent() != null ? InventoryUtilsImpl.createNMSComponent(icon.getComponent()) : 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() + ); + } + + @Override + public void sendResourcePack(@NotNull Player player, @NotNull String url, byte[] hash, @Nullable ComponentWrapper prompt, boolean force) { + var serverPlayer = ((CraftPlayer) player).getHandle(); + var packet = new ClientboundResourcePackPacket( + url, + DataUtils.toHexadecimalString(hash), + force, + InventoryUtilsImpl.createNMSComponent(prompt) + ); + serverPlayer.connection.send(packet); + } + +} diff --git a/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/version/InventoryAccessRevision.java b/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/version/InventoryAccessRevision.java index 47cd126..33df554 100644 --- a/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/version/InventoryAccessRevision.java +++ b/inventoryaccess/inventory-access/src/main/java/xyz/xenondevs/inventoryaccess/version/InventoryAccessRevision.java @@ -5,6 +5,7 @@ import xyz.xenondevs.inventoryaccess.util.VersionUtils; public enum InventoryAccessRevision { // this order is required + R15("r15", "1.20.2"), R14("r14", "1.20.0"), R13("r13", "1.19.4"), R12("r12", "1.19.3"), diff --git a/invui/pom.xml b/invui/pom.xml index 9bcd31c..f3e5fde 100644 --- a/invui/pom.xml +++ b/invui/pom.xml @@ -93,6 +93,11 @@ inventory-access-r14 ${project.version} + + xyz.xenondevs.invui + inventory-access-r15 + ${project.version} + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 32ff9e5..41fa218 100644 --- a/pom.xml +++ b/pom.xml @@ -71,6 +71,7 @@ inventoryaccess/inventory-access-r12 inventoryaccess/inventory-access-r13 inventoryaccess/inventory-access-r14 + inventoryaccess/inventory-access-r15 invui-core invui-resourcepack invui-kotlin