diff --git a/.gitignore b/.gitignore
index aacdf3e..7013a14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -144,3 +144,7 @@ buildNumber.properties
.mvn/wrapper/maven-wrapper.jar
# End of https://www.gitignore.io/api/git,java,maven,intellij+all
+
+cache
+local-repo
+generated
diff --git a/pom.xml b/pom.xml
index e4691aa..7a762bd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,8 +21,8 @@
io.papermc.paper
paper-api
- 1.21.6-R0.1-SNAPSHOT
- provided
+ 1.21.11-pre1-R0.1-SNAPSHOT
+ compile
org.junit.jupiter
@@ -30,11 +30,25 @@
5.6.2
test
+
+ com.google.code.gson
+ gson
+ 2.10.1
+
org.ow2.asm
asm
- 9.5
- provided
+ 9.6
+
+
+ org.ow2.asm
+ asm-commons
+ 9.6
+
+
+ org.ow2.asm
+ asm-tree
+ 9.6
@@ -177,5 +191,9 @@
paper-repo
https://repo.papermc.io/repository/maven-public/
+
+ paper-pr
+ https://maven-prs.papermc.io/Paper/pr13194/
+
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/Main.java b/src/main/java/io/github/essentialsx/itemdbgenerator/Main.java
index 2e77774..71219dc 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/Main.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/Main.java
@@ -75,6 +75,7 @@ public class Main extends JavaPlugin {
public static Set EXPERIMENTAL_MATERIALS = null;
public static Set EXPERIMENTAL_POTIONS = null;
+ public static Set VALID_ITEMS = null;
@Override
public void onEnable() {
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/StandaloneMain.java b/src/main/java/io/github/essentialsx/itemdbgenerator/StandaloneMain.java
new file mode 100644
index 0000000..fb6d628
--- /dev/null
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/StandaloneMain.java
@@ -0,0 +1,211 @@
+package io.github.essentialsx.itemdbgenerator;
+
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import org.bukkit.Material;
+import org.bukkit.potion.PotionType;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Stream;
+
+public class StandaloneMain {
+
+ private static final String MANIFEST_URL = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json";
+ private static final Gson GSON = new Gson();
+
+ public static void main(String[] args) {
+ String targetVersion = args.length > 0 ? args[0] : null;
+
+ try {
+ if (targetVersion == null) {
+ JsonObject manifest = fetchJson(MANIFEST_URL).getAsJsonObject();
+ targetVersion = manifest.getAsJsonObject("latest").get("snapshot").getAsString();
+ System.out.println("Targeting latest release: " + targetVersion);
+ }
+
+ File cacheDir = new File("cache");
+ if (!cacheDir.exists()) cacheDir.mkdirs();
+
+ // Clean up libraries to avoid version conflicts
+ File libDir = new File(cacheDir, "libraries");
+ if (libDir.exists()) {
+ System.out.println("Cleaning up old libraries...");
+ deleteDirectory(libDir);
+ }
+
+ System.out.println("Downloading server jar for version " + targetVersion + "...");
+ File serverJar = new File(cacheDir, "server-" + targetVersion + ".jar");
+ if (!serverJar.exists()) {
+ downloadServerJar(targetVersion, serverJar);
+ }
+ System.out.println("Using server jar: " + serverJar.getAbsolutePath());
+
+ System.out.println("Running server jar to unpack libraries...");
+ new ProcessBuilder("java", "-jar", serverJar.getName(), "--help")
+ .directory(cacheDir)
+ .start()
+ .waitFor();
+
+ File versionsDir = new File(cacheDir, "versions");
+ File extractedServerJar = findServerJar(versionsDir);
+ if (extractedServerJar == null) {
+ throw new RuntimeException("Could not find unpacked server jar in " + versionsDir);
+ }
+ System.out.println("Found unpacked server jar: " + extractedServerJar);
+
+ String classpath = buildClasspath(cacheDir, extractedServerJar);
+
+ System.out.println("Running data generator...");
+ new ProcessBuilder("java", "-cp", classpath, "net.minecraft.data.Main", "--reports")
+ .directory(cacheDir)
+ .inheritIO()
+ .start()
+ .waitFor();
+
+ File reportFile = new File(cacheDir, "generated/reports/items.json");
+ if (!reportFile.exists()) {
+ throw new RuntimeException("Data generator failed to produce " + reportFile);
+ }
+
+ System.out.println("Parsing generated report...");
+ Set items = parseItemsReport(reportFile);
+ System.out.println("Found " + items.size() + " valid items.");
+ Main.VALID_ITEMS = items;
+
+ System.out.println("Generating experimental JSONs...");
+ AnnotationGenerator.main(new String[0]);
+
+ System.out.println("Loading experimental data...");
+ Reader reader = new InputStreamReader(Objects.requireNonNull(Main.class.getResourceAsStream("/experimental_materials.json")));
+ Main.EXPERIMENTAL_MATERIALS = GSON.fromJson(reader, new TypeToken>(){}.getType());
+ reader.close();
+ reader = new InputStreamReader(Objects.requireNonNull(Main.class.getResourceAsStream("/experimental_potions.json")));
+ Main.EXPERIMENTAL_POTIONS = GSON.fromJson(reader, new TypeToken>(){}.getType());
+ reader.close();
+
+ System.out.println("Generating items.json...");
+ JsonObject itemMap = Main.generateItemMap();
+ Main.save(itemMap);
+
+ System.out.println("Generation complete!");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void deleteDirectory(File file) {
+ File[] contents = file.listFiles();
+ if (contents != null) {
+ for (File f : contents) {
+ deleteDirectory(f);
+ }
+ }
+ file.delete();
+ }
+
+ private static void downloadServerJar(String version, File outputFile) throws IOException {
+ JsonObject manifest = fetchJson(MANIFEST_URL).getAsJsonObject();
+ com.google.gson.JsonArray versions = manifest.getAsJsonArray("versions");
+
+ String versionUrl = null;
+ for (com.google.gson.JsonElement v : versions) {
+ JsonObject vObj = v.getAsJsonObject();
+ if (vObj.get("id").getAsString().equals(version)) {
+ versionUrl = vObj.get("url").getAsString();
+ break;
+ }
+ }
+
+ if (versionUrl == null) {
+ throw new IllegalArgumentException("Version " + version + " not found in manifest.");
+ }
+
+ JsonObject versionMeta = fetchJson(versionUrl).getAsJsonObject();
+ JsonObject downloads = versionMeta.getAsJsonObject("downloads");
+ if (!downloads.has("server")) {
+ throw new IllegalArgumentException("No server download found for version " + version);
+ }
+
+ String serverUrl = downloads.getAsJsonObject("server").get("url").getAsString();
+ downloadFile(serverUrl, outputFile);
+ }
+
+ private static File findServerJar(File dir) throws IOException {
+ if (!dir.exists()) return null;
+ try (Stream stream = Files.walk(dir.toPath())) {
+ return stream
+ .map(Path::toFile)
+ .filter(f -> f.getName().endsWith(".jar") && !f.getName().contains("bundler"))
+ .findFirst()
+ .orElse(null);
+ }
+ }
+
+ private static String buildClasspath(File workingDir, File extractedServerJar) throws IOException {
+ StringBuilder cp = new StringBuilder();
+ cp.append(extractedServerJar.getAbsolutePath());
+
+ Path libPath = new File(workingDir, "libraries").toPath();
+ if (Files.exists(libPath)) {
+ Files.walk(libPath)
+ .filter(p -> p.toString().endsWith(".jar"))
+ .forEach(p -> {
+ cp.append(File.pathSeparator);
+ cp.append(p.toAbsolutePath().toString());
+ });
+ }
+ return cp.toString();
+ }
+
+ private static Set parseItemsReport(File reportFile) throws IOException {
+ try (Reader reader = new java.io.FileReader(reportFile)) {
+ JsonObject json = GSON.fromJson(reader, JsonObject.class);
+ Set items = new HashSet<>();
+ for (String key : json.keySet()) {
+ if (key.startsWith("minecraft:")) {
+ items.add(key.substring(10));
+ } else {
+ items.add(key);
+ }
+ }
+ return items;
+ }
+ }
+
+ private static com.google.gson.JsonElement fetchJson(String urlString) throws IOException {
+ URL url = new URL(urlString);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("GET");
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
+ return GSON.fromJson(reader, com.google.gson.JsonElement.class);
+ }
+ }
+
+ private static void downloadFile(String urlString, File outputFile) throws IOException {
+ URL url = new URL(urlString);
+ try (InputStream in = url.openStream();
+ FileOutputStream out = new FileOutputStream(outputFile)) {
+ byte[] buffer = new byte[8192];
+ int bytesRead;
+ while ((bytesRead = in.read(buffer)) != -1) {
+ out.write(buffer, 0, bytesRead);
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/CopperBuildingBlockAliasProvider.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/CopperBuildingBlockAliasProvider.java
index e36eef9..ecb6864 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/CopperBuildingBlockAliasProvider.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/CopperBuildingBlockAliasProvider.java
@@ -106,7 +106,13 @@ private enum CopperBuildingBlock implements CompoundType {
TRAPDOOR(null, "%strapdoor", "%sdoortrap", "%shatch", "%stdoor", "%sdoort", "%strapd", "%sdtrap"),
BULB(null, "%sbulb"),
GRATE(null, "%sgrate"),
- BLOCK("^[A-Z]+_(SLAB|STAIRS)", true, "%scopperblock", "%scopblock", "%scoblock"),
+ GOLEM_STATUE(null, "%sgolemstatue", "%sstatue", "%sgolem"),
+ LANTERN(null, "%slantern", "%slantern", "%slight"),
+ LIGHTNING_ROD(null, "%srod", "%slrod", "%slightrod"),
+ BARS(null, "%sbars", "%sbar", "%sbarsb", "%sbarsblock", "%sfence"),
+ CHAIN(null, "%schain", "%slink", "%schains", "%slinks"),
+ CHEST(null, "%schest", "%scontainer", "%sdrawer"),
+ BLOCK("^[A-Z_]+_(SLAB|STAIRS)", true, "%scopperblock", "%scopblock", "%scoblock"),
;
private final Pattern regex;
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/FixedAliasProvider.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/FixedAliasProvider.java
index c72edda..0162f01 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/FixedAliasProvider.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/FixedAliasProvider.java
@@ -69,6 +69,7 @@ private static void add(EntityType entity, String... aliases) {
add(Material.BOOKSHELF, "bshelf", "bookcase", "casebook", "shelfbook", "bookblock", "blockbook");
add(Material.CHISELED_BOOKSHELF, "cbshelf", "cbookcase", "cshelfbook", "cbookblock", "cblockbook", "chiseledshelf", "chiseledb");
add(Material.TORCH, "burningstick", "burnstick");
+ add(Material.COPPER_TORCH, "copperburningstick", "copperburnstick");
add(Material.GLOWSTONE, "glowingstoneblock", "lightstoneblock", "glowstoneblock", "blockglowingstone", "blocklightstone", "blockglowstone", "glowingstone", "lightstone", "glowingblock", "lightblock", "glowblock", "lstone");
add(Material.LILY_PAD, "waterlily", "lily", "swamppad", "lpad", "wlily");
add(Material.ANCIENT_DEBRIS, "debris");
@@ -214,6 +215,8 @@ private static void add(EntityType entity, String... aliases) {
add(Material.TURTLE_SCUTE, "scute", "minecraft:scute");
add(EntityType.MOOSHROOM, "mushroom_cow_spawner");
add(EntityType.SNOW_GOLEM, "snowman_spawner");
+ // == 1.21.9 Enum Renaming Manual Fixes
+ add(Material.IRON_CHAIN, "chain", "minecraft:chain");
}
@Override
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MeatFishAliasProvider.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MeatFishAliasProvider.java
index b679d6a..72a764e 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MeatFishAliasProvider.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MeatFishAliasProvider.java
@@ -72,7 +72,7 @@ private enum FoodType implements CompoundType {
COOKED("COOKED_[A-Z_]+", "%scooked", "%scook", "%sc", "%sgrilled", "%sgrill", "%sg", "%sroasted", "%sroast", "%sro", "%sbbq", "%stoasted", "cooked%s", "cook%s", "c%s", "grilled%s", "grill%s", "g%s", "roasted%s", "roast%s", "ro%s", "bbq%s", "toasted%s"),
HIDE("[A-Z_]+_HIDE", "%shide", "%sskin", "%scoat", "%sfur"),
STEW("[A-Z_]+_STEW", "%sstew", "%ssoup"),
- RAW("^(?!COOKED_)[A-Z_]+(?!_STEW)$", "raw%s", "ra%s", "uncooked%s", "plain%s", "%s"),
+ RAW("^(?!COOKED_|MUSIC_DISC_)[A-Z_]+(?!_STEW)$", "raw%s", "ra%s", "uncooked%s", "plain%s", "%s"),
;
private final Pattern regex;
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MineableAliasProvider.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MineableAliasProvider.java
index a7bb561..c09d220 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MineableAliasProvider.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/MineableAliasProvider.java
@@ -91,6 +91,8 @@ public String[] getNames() {
*/
@SuppressWarnings("unused")
private enum MineableItemType implements CompoundType {
+ // The Copper Age
+ NUGGET(null, "%snugget", "%snug"),
// Caves and Cliffs
RAW_ORE_BLOCK("RAW_[A-Z]+_BLOCK", "raw%soreblock", "%sorechunkblock", "r%soreblock", "raw%sorebl", "%sorechunkbl", "r%sorebl"),
RAW_ORE("RAW_[A-Z]+_ORE", "raw%sore", "%sorechunk", "r%sore"),
@@ -104,6 +106,7 @@ private enum MineableItemType implements CompoundType {
SCRAP(null, "%sscrap"),
// Tools
SWORD(null, "%ssword"),
+ SPEAR(null, "%sspear"),
SHOVEL(null, "%sshovel", "%sspade"),
PICKAXE(null, "%spickaxe", "%spick"),
AXE("[A-Z_]+_(? get(ItemProvider.Item item) {
private enum DiscType implements CompoundType {
// this is scuffed beyond belief
DISC_FRAGMENT("^DISC_FRAGMENT_5", "discfrag", "fragment"),
- MUSIC_DISC("^MUSIC_DISC_[A-Z0-9]+", generateFormatsFromNames(MUSIC_DISC_NAMES))
+ MUSIC_DISC("^MUSIC_DISC_[A-Z0-9_]+", generateFormatsFromNames(MUSIC_DISC_NAMES))
;
private final Pattern regex;
@@ -82,6 +82,7 @@ private enum Track implements CompoundModifier {
CREATOR_MUSIC_BOX("MUSIC_DISC_CREATOR_MUSIC_BOX", "creatormusicbox", "creatormusicb", "creatormbox", "creatormb"),
PRECIPICE("MUSIC_DISC_PRECIPICE", "precipice"),
TEARS("MUSIC_DISC_TEARS", "tears", "ghast"),
+ LAVA_CHICKEN("MUSIC_DISC_LAVA_CHICKEN", "lavachicken", "lava", "chicken", "lchicken", "lchick")
;
private final Pattern regex;
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/WoodAliasProvider.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/WoodAliasProvider.java
index 28a5d6f..df14e6c 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/WoodAliasProvider.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/alias/WoodAliasProvider.java
@@ -89,6 +89,7 @@ private enum WoodItemType implements CompoundType {
PROPAGULE(null, "propagule%s", "%sprop", "%ssapling", "%streesapling", "%slogsapling", "%strunksapling", "%swoodsapling"),
MUDDY_ROOTS("^MUDDY_[A-Z_]+_ROOTS", "mud%sroots", "mud%sroot"),
ROOTS("^(?!MUDDY_)[A-Z_]+_ROOTS", "%sroots", "%sroot"),
+ SHELF(null, "%sshelf", "%srack", "%sledge", "%smantel")
;
private final Pattern regex;
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialEnumProvider.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialEnumProvider.java
index 300eb16..6decf37 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialEnumProvider.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialEnumProvider.java
@@ -15,7 +15,13 @@ public Stream- get() {
return Arrays.stream(Material.values())
.filter(mat -> !mat.name().contains("LEGACY"))
.filter(mat -> !Main.EXPERIMENTAL_MATERIALS.contains(mat))
- .filter(Material::isItem)
+ .filter(mat -> {
+ if (Main.VALID_ITEMS != null) {
+ String id = mat.name().toLowerCase();
+ return Main.VALID_ITEMS.contains(id) || Main.VALID_ITEMS.contains("minecraft:" + id);
+ }
+ return mat.isItem();
+ })
.map(MaterialEnumItem::new);
}
diff --git a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialFallbacks.java b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialFallbacks.java
index 4347754..dde1459 100644
--- a/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialFallbacks.java
+++ b/src/main/java/io/github/essentialsx/itemdbgenerator/providers/item/MaterialFallbacks.java
@@ -33,6 +33,8 @@ public class MaterialFallbacks {
add(Material.DIRT_PATH, "GRASS_PATH");
/* 1.20.3: Grass was renamed to short grass */
add(Material.SHORT_GRASS, "GRASS");
+ /* 1.21.9: Chain was renamed to iron chain */
+ add(Material.IRON_CHAIN, "CHAIN");
}
private MaterialFallbacks() {