Skip to content

Commit 5657d6d

Browse files
authored
feat: support minecraft version 1.21.4 (#36)
* feat: support minecraft version 1.21.4 * fix: missing mapping name
1 parent d30f34f commit 5657d6d

6 files changed

Lines changed: 232 additions & 1 deletion

File tree

.github/workflows/buildtools.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ checkVersion "1.20.2" "17"
3333
checkVersion "1.20.4" "17"
3434
checkVersion "1.20.6" "21"
3535
checkVersion "1.21" "21"
36-
checkVersion "1.21.3" "21"
36+
checkVersion "1.21.3" "21"
37+
checkVersion "1.21.4" "21"

zip-common/src/main/java/net/imprex/zip/common/MinecraftVersion.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ private static final class NmsMapping {
1919
private static final List<NmsMapping> MAPPINGS = new ArrayList<>();
2020

2121
static {
22+
MAPPINGS.add(new NmsMapping("1.21.4", "v1_21_R3"));
2223
MAPPINGS.add(new NmsMapping("1.21.3", "v1_21_R2"));
2324
MAPPINGS.add(new NmsMapping("1.21", "v1_21_R1"));
2425
MAPPINGS.add(new NmsMapping("1.20.5", "v1_20_R4"));

zip-nms/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@
2121
<module>zip-nms-v1_20_R4</module>
2222
<module>zip-nms-v1_21_R1</module>
2323
<module>zip-nms-v1_21_R2</module>
24+
<module>zip-nms-v1_21_R3</module>
2425
</modules>
2526
</project>

zip-nms/zip-nms-v1_21_R3/pom.xml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>net.imprex</groupId>
8+
<artifactId>zip-nms</artifactId>
9+
<version>${revision}</version>
10+
</parent>
11+
12+
<artifactId>zip-nms-v1_21_R3</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>net.imprex</groupId>
17+
<artifactId>zip-nms-api</artifactId>
18+
<version>${revision}</version>
19+
<scope>provided</scope>
20+
</dependency>
21+
<dependency>
22+
<groupId>org.spigotmc</groupId>
23+
<artifactId>spigot</artifactId>
24+
<version>1.21.4-R0.1-SNAPSHOT</version>
25+
<classifier>remapped-mojang</classifier>
26+
<scope>provided</scope>
27+
</dependency>
28+
</dependencies>
29+
30+
<build>
31+
<plugins>
32+
<plugin>
33+
<groupId>net.md-5</groupId>
34+
<artifactId>specialsource-maven-plugin</artifactId>
35+
<version>${plugin.specialsource.version}</version>
36+
<executions>
37+
<execution>
38+
<phase>package</phase>
39+
<goals>
40+
<goal>remap</goal>
41+
</goals>
42+
<id>remap-obf</id>
43+
<configuration>
44+
<srgIn>
45+
org.spigotmc:minecraft-server:1.21.4-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
46+
<reverse>true</reverse>
47+
<remappedDependencies>
48+
org.spigotmc:spigot:1.21.4-R0.1-SNAPSHOT:jar:remapped-mojang</remappedDependencies>
49+
<remappedArtifactAttached>true</remappedArtifactAttached>
50+
<remappedClassifierName>remapped-obf</remappedClassifierName>
51+
</configuration>
52+
</execution>
53+
<execution>
54+
<phase>package</phase>
55+
<goals>
56+
<goal>remap</goal>
57+
</goals>
58+
<id>remap-spigot</id>
59+
<configuration>
60+
<inputFile>
61+
${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar</inputFile>
62+
<srgIn>
63+
org.spigotmc:minecraft-server:1.21.4-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
64+
<remappedDependencies>
65+
org.spigotmc:spigot:1.21.4-R0.1-SNAPSHOT:jar:remapped-obf</remappedDependencies>
66+
</configuration>
67+
</execution>
68+
</executions>
69+
</plugin>
70+
</plugins>
71+
</build>
72+
</project>
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package net.imprex.zip.nms.v1_21_R3;
2+
3+
import java.io.ByteArrayInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
import java.lang.reflect.InvocationTargetException;
6+
import java.lang.reflect.Method;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Optional;
10+
import java.util.UUID;
11+
import java.util.function.BiConsumer;
12+
13+
import org.bukkit.Material;
14+
import org.bukkit.craftbukkit.v1_21_R3.CraftRegistry;
15+
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftItemStack;
16+
import org.bukkit.inventory.ItemStack;
17+
import org.bukkit.inventory.meta.SkullMeta;
18+
19+
import com.mojang.authlib.GameProfile;
20+
import com.mojang.authlib.properties.Property;
21+
22+
import net.imprex.zip.common.ReflectionUtil;
23+
import net.imprex.zip.nms.api.NmsManager;
24+
import net.minecraft.core.RegistryAccess;
25+
import net.minecraft.nbt.CompoundTag;
26+
import net.minecraft.nbt.ListTag;
27+
import net.minecraft.nbt.NbtAccounter;
28+
import net.minecraft.nbt.NbtIo;
29+
import net.minecraft.nbt.Tag;
30+
import net.minecraft.world.item.component.ResolvableProfile;
31+
32+
public class ZipNmsManager implements NmsManager {
33+
34+
private static final BiConsumer<SkullMeta, GameProfile> SET_PROFILE;
35+
36+
private static final RegistryAccess DEFAULT_REGISTRY = CraftRegistry.getMinecraftRegistry();
37+
38+
private static final CompoundTag NBT_EMPTY_ITEMSTACK = new CompoundTag();
39+
40+
static {
41+
NBT_EMPTY_ITEMSTACK.putString("id", "minecraft:air");
42+
43+
BiConsumer<SkullMeta, GameProfile> setProfile = (meta, profile) -> {
44+
throw new NullPointerException("Unable to find 'setProfile' method!");
45+
};
46+
47+
Class<?> craftMetaSkullClass = new ItemStack(Material.PLAYER_HEAD)
48+
.getItemMeta()
49+
.getClass();
50+
51+
Method setResolvableProfileMethod = ReflectionUtil.searchMethod(craftMetaSkullClass, void.class, ResolvableProfile.class);
52+
if (setResolvableProfileMethod != null) {
53+
setProfile = (meta, profile) -> {
54+
try {
55+
setResolvableProfileMethod.invoke(meta, new ResolvableProfile(profile));
56+
} catch (IllegalAccessException | InvocationTargetException e) {
57+
e.printStackTrace();
58+
}
59+
};
60+
} else {
61+
Method setProfileMethod = ReflectionUtil.searchMethod(craftMetaSkullClass, void.class, GameProfile.class);
62+
if (setProfileMethod != null) {
63+
setProfile = (meta, profile) -> {
64+
try {
65+
setProfileMethod.invoke(meta, profile);
66+
} catch (IllegalAccessException | InvocationTargetException e) {
67+
e.printStackTrace();
68+
}
69+
};
70+
}
71+
}
72+
73+
SET_PROFILE = setProfile;
74+
}
75+
76+
public byte[] nbtToBinary(CompoundTag compound) {
77+
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
78+
NbtIo.writeCompressed(compound, outputStream);
79+
return outputStream.toByteArray();
80+
} catch (Exception e) {
81+
e.printStackTrace();
82+
}
83+
return null;
84+
}
85+
86+
public CompoundTag binaryToNBT(byte[] binary) {
87+
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(binary)) {
88+
return NbtIo.readCompressed(inputStream, NbtAccounter.unlimitedHeap());
89+
} catch (Exception e) {
90+
e.printStackTrace();
91+
}
92+
return new CompoundTag();
93+
}
94+
95+
@Override
96+
public byte[] itemstackToBinary(ItemStack[] items) {
97+
CompoundTag inventory = new CompoundTag();
98+
ListTag list = new ListTag();
99+
for (ItemStack itemStack : items) {
100+
if (itemStack == null || itemStack.getType() == Material.AIR) {
101+
list.add(NBT_EMPTY_ITEMSTACK);
102+
} else {
103+
net.minecraft.world.item.ItemStack craftItem = CraftItemStack.asNMSCopy(itemStack);
104+
Tag tag = craftItem.save(DEFAULT_REGISTRY);
105+
list.add(tag);
106+
}
107+
}
108+
inventory.put("i", list);
109+
return nbtToBinary(inventory);
110+
}
111+
112+
@Override
113+
public List<ItemStack> binaryToItemStack(byte[] binary) {
114+
CompoundTag nbt = binaryToNBT(binary);
115+
List<ItemStack> items = new ArrayList<>();
116+
if (nbt.contains("i", 9)) {
117+
ListTag list = nbt.getList("i", 10);
118+
for (Tag base : list) {
119+
if (base instanceof CompoundTag itemTag) {
120+
if (itemTag.getString("id").equals("minecraft:air")) {
121+
items.add(new ItemStack(Material.AIR));
122+
} else {
123+
Optional<net.minecraft.world.item.ItemStack> optional = net.minecraft.world.item.ItemStack.parse(DEFAULT_REGISTRY, itemTag);
124+
if (optional.isPresent()) {
125+
items.add(CraftItemStack.asBukkitCopy(optional.get()));
126+
}
127+
}
128+
}
129+
}
130+
}
131+
return items;
132+
}
133+
134+
@Override
135+
public void setSkullProfile(SkullMeta meta, String texture) {
136+
try {
137+
GameProfile gameProfile = new GameProfile(UUID.randomUUID(), "");
138+
gameProfile.getProperties().put("textures", new Property("textures", texture));
139+
140+
SET_PROFILE.accept(meta, gameProfile);
141+
} catch (Exception e) {
142+
e.printStackTrace();
143+
}
144+
}
145+
146+
@Override
147+
public boolean isAir(Material material) {
148+
return material == null || material == Material.AIR;
149+
}
150+
}

zip-plugin/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,11 @@
101101
<version>${revision}</version>
102102
<scope>compile</scope>
103103
</dependency>
104+
<dependency>
105+
<groupId>net.imprex</groupId>
106+
<artifactId>zip-nms-v1_21_R3</artifactId>
107+
<version>${revision}</version>
108+
<scope>compile</scope>
109+
</dependency>
104110
</dependencies>
105111
</project>

0 commit comments

Comments
 (0)