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() {