Support for 1.17.1

This commit is contained in:
NichtStudioCode 2021-07-10 20:12:40 +02:00
parent 0a4883f347
commit 11912e31e8
8 changed files with 424 additions and 7 deletions

@ -78,6 +78,11 @@
<artifactId>1_17_R1</artifactId> <artifactId>1_17_R1</artifactId>
<version>0.1-SNAPSHOT</version> <version>0.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>de.studiocode.invui</groupId>
<artifactId>1_17_R2</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

@ -15,13 +15,14 @@
<properties> <properties>
<maven.compiler.source>16</maven.compiler.source> <maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target> <maven.compiler.target>16</maven.compiler.target>
<spigotVersion>1.17-R0.1-SNAPSHOT</spigotVersion>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId> <artifactId>spigot</artifactId>
<version>1.17-R0.1-SNAPSHOT</version> <version>${spigotVersion}</version>
<classifier>remapped-mojang</classifier> <classifier>remapped-mojang</classifier>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -46,9 +47,9 @@
</goals> </goals>
<id>remap-obf</id> <id>remap-obf</id>
<configuration> <configuration>
<srgIn>org.spigotmc:minecraft-server:1.17-R0.1-SNAPSHOT:txt:maps-mojang</srgIn> <srgIn>org.spigotmc:minecraft-server:${spigotVersion}:txt:maps-mojang</srgIn>
<reverse>true</reverse> <reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:1.17-R0.1-SNAPSHOT: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,8 +62,8 @@
<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:1.17-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn> <srgIn>org.spigotmc:minecraft-server:${spigotVersion}:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:1.17-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies> <remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-obf</remappedDependencies>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<project 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">
<parent>
<groupId>de.studiocode.invui</groupId>
<artifactId>InvUI-Parent</artifactId>
<version>0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>1_17_R2</artifactId>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<spigotVersion>1.17.1-R0.1-SNAPSHOT</spigotVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>${spigotVersion}</version>
<classifier>remapped-mojang</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>de.studiocode.invui</groupId>
<artifactId>api</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.md-5</groupId>
<artifactId>specialsource-maven-plugin</artifactId>
<version>1.2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-obf</id>
<configuration>
<srgIn>org.spigotmc:minecraft-server:${spigotVersion}:txt:maps-mojang</srgIn>
<reverse>true</reverse>
<remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-mojang</remappedDependencies>
<remappedArtifactAttached>true</remappedArtifactAttached>
<remappedClassifierName>remapped-obf</remappedClassifierName>
</configuration>
</execution>
<execution>
<phase>package</phase>
<goals>
<goal>remap</goal>
</goals>
<id>remap-spigot</id>
<configuration>
<inputFile>${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
<srgIn>org.spigotmc:minecraft-server:${spigotVersion}:csrg:maps-spigot</srgIn>
<remappedDependencies>org.spigotmc:spigot:${spigotVersion}:jar:remapped-obf</remappedDependencies>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,188 @@
package de.studiocode.inventoryaccess.v1_17_R2.inventory;
import de.studiocode.inventoryaccess.api.abstraction.inventory.AnvilInventory;
import de.studiocode.inventoryaccess.v1_17_R2.util.InventoryUtilsImpl;
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.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_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryAnvil;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.Inventory;
import java.util.function.Consumer;
public class AnvilInventoryImpl extends AnvilMenu implements AnvilInventory {
private final Component title;
private final Consumer<String> renameHandler;
private final CraftInventoryView view;
private final ServerPlayer player;
private String text;
private boolean open;
public AnvilInventoryImpl(org.bukkit.entity.Player player, BaseComponent[] title, Consumer<String> renameHandler) {
this(((CraftPlayer) player).getHandle(), InventoryUtilsImpl.createNMSComponent(title), renameHandler);
}
public AnvilInventoryImpl(ServerPlayer player, Component title, Consumer<String> renameHandler) {
super(player.nextContainerCounter(), player.getInventory(),
ContainerLevelAccess.create(player.level, new BlockPos(Integer.MAX_VALUE, 0, 0)));
this.title = title;
this.renameHandler = renameHandler;
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, title));
// send initial items
NonNullList<ItemStack> 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), slot, incrementStateId(), 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 Inventory getBukkitInventory() {
return view.getTopInventory();
}
@Override
public String getRenameText() {
return text;
}
@Override
public boolean isOpen() {
return open;
}
// --- ContainerAnvil ---
@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 void setItemName(String s) {
// save rename text
text = s;
// call the rename handler
if (renameHandler != null) renameHandler.accept(s);
// the client expects the item to change to it's new name and removes it from the inventory, so it needs to be sent again
sendItem(2);
}
/**
* 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
}
}

@ -0,0 +1,66 @@
package de.studiocode.inventoryaccess.v1_17_R2.util;
import de.studiocode.inventoryaccess.api.abstraction.util.InventoryUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
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_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftContainer;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventory;
import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
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) {
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(Player player, BaseComponent[] title) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
AbstractContainerMenu menu = serverPlayer.containerMenu;
serverPlayer.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), createNMSComponent(title)));
}
public static Component createNMSComponent(BaseComponent[] components) {
String json = ComponentSerializer.toString(components);
return CraftChatMessage.fromJSON(json);
}
}

@ -0,0 +1,75 @@
package de.studiocode.inventoryaccess.v1_17_R2.util;
import de.studiocode.inventoryaccess.api.abstraction.util.ItemUtils;
import de.studiocode.inventoryaccess.api.version.ReflectionUtils;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import java.io.*;
import java.lang.reflect.Field;
public class ItemUtilsImpl implements ItemUtils {
private static final Field CRAFT_ITEM_STACK_HANDLE_FIELD = ReflectionUtils.getField(CraftItemStack.class, true, "handle");
@Override
public byte[] serializeItemStack(org.bukkit.inventory.ItemStack itemStack, boolean compressed) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializeItemStack(itemStack, out, compressed);
return out.toByteArray();
}
@Override
public void serializeItemStack(org.bukkit.inventory.ItemStack itemStack, OutputStream outputStream, boolean compressed) {
try {
ItemStack nmsStack;
if (itemStack instanceof CraftItemStack)
nmsStack = (ItemStack) CRAFT_ITEM_STACK_HANDLE_FIELD.get(itemStack);
else 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 (IllegalAccessException | 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(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;
}
}

@ -13,9 +13,16 @@ public class ReflectionUtils {
private static final String VERSION = getVersion(); private static final String VERSION = getVersion();
private static String getVersion() { private static String getVersion() {
String version = Bukkit.getVersion();
version = version.substring(version.indexOf("MC: "), version.length() - 1).substring(4);
if (version.equals("1.17.1")) {
return "v1_17_R2"; // TODO: find a better solution
} else {
String path = Bukkit.getServer().getClass().getPackage().getName(); String path = Bukkit.getServer().getClass().getPackage().getName();
return path.substring(path.lastIndexOf(".") + 1); return path.substring(path.lastIndexOf(".") + 1);
} }
}
public static <T> Class<T> getImplClass(String path) { public static <T> Class<T> getImplClass(String path) {
try { try {

@ -31,6 +31,7 @@
<module>InventoryAccess/1_16_R2</module> <module>InventoryAccess/1_16_R2</module>
<module>InventoryAccess/1_16_R3</module> <module>InventoryAccess/1_16_R3</module>
<module>InventoryAccess/1_17_R1</module> <module>InventoryAccess/1_17_R1</module>
<module>InventoryAccess/1_17_R2</module>
<module>InventoryAccess/api</module> <module>InventoryAccess/api</module>
<module>InvUI</module> <module>InvUI</module>
</modules> </modules>