diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b560995..275d28f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,7 @@ on: jobs: build: strategy: + fail-fast: false matrix: version: [ "1.7", diff --git a/1.14/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java b/1.14/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java index 5671b48..c7c5582 100644 --- a/1.14/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java +++ b/1.14/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java @@ -2,6 +2,7 @@ package dev.u9g.minecraftdatagenerator.generators; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import dev.u9g.minecraftdatagenerator.FieldHelper; import dev.u9g.minecraftdatagenerator.util.DGU; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -17,6 +18,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.NotNull; +import java.lang.reflect.ParameterizedType; import java.util.Objects; public class EntitiesDataGenerator implements IDataGenerator { @@ -42,20 +44,17 @@ public class EntitiesDataGenerator implements IDataGenerator { } private static String getCategoryFrom(@NotNull EntityType entityType) { - if (entityType == EntityType.PLAYER) return "other"; // fail early for player entities - Entity entity = entityType.create(DGU.getWorld()); - if (entity == null) - throw new IllegalStateException("Entity was null after trying to create a: " + DGU.translateText(entityType.getTranslationKey())); - entity.remove(); - return switch (entity.getClass().getPackageName()) { + ParameterizedType entityTypeClass = (ParameterizedType) FieldHelper.findStaticFieldWithValue(EntityType.class, entityType).getGenericType(); + Class entityClass = (Class) entityTypeClass.getActualTypeArguments()[0]; + return switch (entityClass.getPackageName()) { case "net.minecraft.entity.decoration", "net.minecraft.entity.decoration.painting" -> "Immobile"; case "net.minecraft.entity.boss", "net.minecraft.entity.mob", "net.minecraft.entity.boss.dragon" -> "Hostile mobs"; case "net.minecraft.entity.projectile", "net.minecraft.entity.thrown" -> "Projectiles"; case "net.minecraft.entity.passive" -> "Passive mobs"; case "net.minecraft.entity.vehicle" -> "Vehicles"; - case "net.minecraft.entity" -> "other"; - default -> throw new IllegalStateException("Unexpected entity type: " + entity.getClass().getPackageName()); + case "net.minecraft.entity.player", "net.minecraft.entity" -> "other"; + default -> throw new IllegalStateException("Unexpected entity type: " + entityClass.getPackageName()); }; } diff --git a/1.15/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java b/1.15/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java index b0a0f7f..1e4c130 100644 --- a/1.15/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java +++ b/1.15/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java @@ -2,6 +2,7 @@ package dev.u9g.minecraftdatagenerator.generators; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import dev.u9g.minecraftdatagenerator.FieldHelper; import dev.u9g.minecraftdatagenerator.util.DGU; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -17,6 +18,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.NotNull; +import java.lang.reflect.ParameterizedType; import java.util.Objects; public class EntitiesDataGenerator implements IDataGenerator { @@ -42,21 +44,17 @@ public class EntitiesDataGenerator implements IDataGenerator { } private static String getCategoryFrom(@NotNull EntityType entityType) { - if (entityType == EntityType.PLAYER) return "other"; // fail early for player entities - Entity entity = entityType.create(DGU.getWorld()); - if (entity == null) - throw new IllegalStateException("Entity was null after trying to create a: " + DGU.translateText(entityType.getTranslationKey())); - entity.remove(); - return switch (entity.getClass().getPackageName()) { + ParameterizedType entityTypeClass = (ParameterizedType) FieldHelper.findStaticFieldWithValue(EntityType.class, entityType).getGenericType(); + Class entityClass = (Class) entityTypeClass.getActualTypeArguments()[0]; + return switch (entityClass.getPackageName()) { case "net.minecraft.entity.decoration", "net.minecraft.entity.decoration.painting" -> "Immobile"; case "net.minecraft.entity.boss", "net.minecraft.entity.mob", "net.minecraft.entity.boss.dragon" -> "Hostile mobs"; - case "net.minecraft.entity.projectile", "net.minecraft.entity.projectile.thrown", - "net.minecraft.entity.thrown" -> "Projectiles"; + case "net.minecraft.entity.projectile", "net.minecraft.entity.thrown" -> "Projectiles"; case "net.minecraft.entity.passive" -> "Passive mobs"; case "net.minecraft.entity.vehicle" -> "Vehicles"; - case "net.minecraft.entity" -> "other"; - default -> throw new IllegalStateException("Unexpected entity type: " + entity.getClass().getPackageName()); + case "net.minecraft.entity.player", "net.minecraft.entity" -> "other"; + default -> throw new IllegalStateException("Unexpected entity type: " + entityClass.getPackageName()); }; } diff --git a/1.16/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java b/1.16/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java index cb0ace0..2f3dddc 100644 --- a/1.16/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java +++ b/1.16/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java @@ -2,6 +2,7 @@ package dev.u9g.minecraftdatagenerator.generators; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import dev.u9g.minecraftdatagenerator.FieldHelper; import dev.u9g.minecraftdatagenerator.util.DGU; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -18,6 +19,8 @@ import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.NotNull; +import java.lang.reflect.ParameterizedType; + public class EntitiesDataGenerator implements IDataGenerator { public static JsonObject generateEntity(Registry> entityRegistry, EntityType entityType) { JsonObject entityDesc = new JsonObject(); @@ -42,20 +45,17 @@ public class EntitiesDataGenerator implements IDataGenerator { } private static String getCategoryFrom(@NotNull EntityType entityType) { - if (entityType == EntityType.PLAYER) return "other"; // fail early for player entities - Entity entity = entityType.create(DGU.getWorld()); - if (entity == null) - throw new IllegalStateException("Entity was null after trying to create a: " + DGU.translateText(entityType.getTranslationKey())); - entity.remove(); - return switch (entity.getClass().getPackageName()) { + ParameterizedType entityTypeClass = (ParameterizedType) FieldHelper.findStaticFieldWithValue(EntityType.class, entityType).getGenericType(); + Class entityClass = (Class) entityTypeClass.getActualTypeArguments()[0]; + return switch (entityClass.getPackageName()) { case "net.minecraft.entity.decoration", "net.minecraft.entity.decoration.painting" -> "Immobile"; case "net.minecraft.entity.boss", "net.minecraft.entity.mob", "net.minecraft.entity.boss.dragon" -> "Hostile mobs"; case "net.minecraft.entity.projectile", "net.minecraft.entity.projectile.thrown" -> "Projectiles"; case "net.minecraft.entity.passive" -> "Passive mobs"; case "net.minecraft.entity.vehicle" -> "Vehicles"; - case "net.minecraft.entity" -> "other"; - default -> throw new IllegalStateException("Unexpected entity type: " + entity.getClass().getPackageName()); + case "net.minecraft.entity.player", "net.minecraft.entity" -> "other"; + default -> throw new IllegalStateException("Unexpected entity type: " + entityClass.getPackageName()); }; } diff --git a/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java b/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java index 753d79b..4fdb5cb 100644 --- a/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java +++ b/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java @@ -2,6 +2,7 @@ package dev.u9g.minecraftdatagenerator.generators; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import dev.u9g.minecraftdatagenerator.FieldHelper; import dev.u9g.minecraftdatagenerator.util.DGU; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -17,6 +18,8 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; +import java.lang.reflect.ParameterizedType; + public class EntitiesDataGenerator implements IDataGenerator { public static JsonObject generateEntity(Registry> entityRegistry, EntityType entityType) { JsonObject entityDesc = new JsonObject(); @@ -45,20 +48,17 @@ public class EntitiesDataGenerator implements IDataGenerator { } private static String getCategoryFrom(EntityType entityType) { - if (entityType == EntityType.PLAYER) return "UNKNOWN"; // fail early for player entities - Entity entity = EntityType.createInstanceFromId(Registry.ENTITY_TYPE.getRawId(entityType), DGU.getWorld()); - if (entity == null) - throw new IllegalStateException("Entity was null after trying to create a: " + DGU.translateText(entityType.getTranslationKey())); - entity.discard(); - return switch (entity.getClass().getPackageName()) { + ParameterizedType entityTypeClass = (ParameterizedType) FieldHelper.findStaticFieldWithValue(EntityType.class, entityType).getGenericType(); + Class entityClass = (Class) entityTypeClass.getActualTypeArguments()[0]; + return switch (entityClass.getPackageName()) { case "net.minecraft.entity.decoration", "net.minecraft.entity.decoration.painting" -> "Immobile"; case "net.minecraft.entity.boss", "net.minecraft.entity.mob", "net.minecraft.entity.boss.dragon" -> "Hostile mobs"; case "net.minecraft.entity.projectile", "net.minecraft.entity.projectile.thrown" -> "Projectiles"; case "net.minecraft.entity.passive" -> "Passive mobs"; case "net.minecraft.entity.vehicle" -> "Vehicles"; - case "net.minecraft.entity" -> "UNKNOWN"; - default -> throw new IllegalStateException("Unexpected entity type: " + entity.getClass().getPackageName()); + case "net.minecraft.entity.player", "net.minecraft.entity" -> "other"; + default -> throw new IllegalStateException("Unexpected entity type: " + entityClass.getPackageName()); }; } diff --git a/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/RecipeDataGenerator.java b/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/RecipeDataGenerator.java index 3ec1d82..396f721 100644 --- a/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/RecipeDataGenerator.java +++ b/1.17/src/main/java/dev/u9g/minecraftdatagenerator/generators/RecipeDataGenerator.java @@ -1,23 +1,10 @@ package dev.u9g.minecraftdatagenerator.generators; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Multimap; -import com.google.gson.JsonArray; import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import dev.u9g.minecraftdatagenerator.util.DGU; +import com.google.gson.JsonNull; import net.minecraft.item.Item; -import net.minecraft.recipe.Ingredient; -import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.ShapedRecipe; -import net.minecraft.recipe.ShapelessRecipe; import net.minecraft.util.registry.Registry; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - public class RecipeDataGenerator implements IDataGenerator { private static int getRawIdFor(Item item) { @@ -31,102 +18,108 @@ public class RecipeDataGenerator implements IDataGenerator { @Override public JsonElement generateDataJson() { - JsonObject finalObj = new JsonObject(); - Multimap recipes = ArrayListMultimap.create(); - for (Recipe recipe : Objects.requireNonNull(DGU.getWorld()).getRecipeManager().values()) { - if (recipe instanceof ShapedRecipe sr) { - var ingredients = sr.getIngredients(); - List ingr = new ArrayList<>(); - for (int i = 0; i < 9; i++) { - if (i >= ingredients.size()) { - ingr.add(-1); - continue; - } - var stacks = ingredients.get(i); -// var matching = stacks.getMatchingStacks(); -// if (matching.length == 0) { +// JsonObject finalObj = new JsonObject(); +// Multimap recipes = ArrayListMultimap.create(); +// for (Recipe recipe : Objects.requireNonNull(DGU.getWorld()).getRecipeManager().values()) { +// if (recipe instanceof ShapedRecipe sr) { +// var ingredients = sr.getIngredients(); +// List ingr = new ArrayList<>(); +// for (int i = 0; i < 9; i++) { +// if (i >= ingredients.size()) { // ingr.add(-1); -// } else { -// ingr.add(getRawIdFor(matching[0].getItem())); +// continue; // } - } - Lists.reverse(ingr); - - JsonArray inShape = new JsonArray(); - - var iter = ingr.iterator(); - for (int y = 0; y < 3; y++) { - var jsonRow = new JsonArray(); - int one = iter.next(); - int two = iter.next(); - int three = iter.next(); - if (y > 0 && one == -1 && two == -1 && three == -1) continue; - jsonRow.add(one); - jsonRow.add(two); - jsonRow.add(three); - inShape.add(jsonRow); - } - - JsonObject finalRecipe = new JsonObject(); - finalRecipe.add("inShape", inShape); - - var resultObject = new JsonObject(); - resultObject.addProperty("id", getRawIdFor(sr.getOutput().getItem())); - resultObject.addProperty("count", sr.getOutput().getCount()); - finalRecipe.add("result", resultObject); - - String id = ((Integer) getRawIdFor(sr.getOutput().getItem())).toString(); - - if (!finalObj.has(id)) { - finalObj.add(id, new JsonArray()); - } - finalObj.get(id).getAsJsonArray().add(finalRecipe); -// var input = new JsonArray(); -// var ingredients = sr.getIngredients().stream().toList(); -// for (int y = 0; y < sr.getHeight(); y++) { -// var arr = new JsonArray(); -// for (int x = 0; x < sr.getWidth(); x++) { -// if ((y*3)+x >= ingredients.size()) { -// arr.add(JsonNull.INSTANCE); -// continue; -// } -// var ingredient = ingredients.get((y*3)+x).getMatchingStacks(); // FIXME: fix when there are more than one matching stack -// if (ingredient.length == 0) { -// arr.add(JsonNull.INSTANCE); -// } else { -// arr.add(getRawIdFor(ingredient[0].getItem())); -// } -// } -// input.add(arr); +// var stacks = ingredients.get(i); +//// var matching = stacks.getMatchingStacks(); +//// if (matching.length == 0) { +//// ingr.add(-1); +//// } else { +//// ingr.add(getRawIdFor(matching[0].getItem())); +//// } // } -// var rootRecipeObject = new JsonObject(); -// rootRecipeObject.add("inShape", input); +// Lists.reverse(ingr); +// +// JsonArray inShape = new JsonArray(); +// +// var iter = ingr.iterator(); +// for (int y = 0; y < 3; y++) { +// var jsonRow = new JsonArray(); +// int one = iter.next(); +// int two = iter.next(); +// int three = iter.next(); +// if (y > 0 && one == -1 && two == -1 && three == -1) continue; +// jsonRow.add(one); +// jsonRow.add(two); +// jsonRow.add(three); +// inShape.add(jsonRow); +// } +// +// JsonObject finalRecipe = new JsonObject(); +// finalRecipe.add("inShape", inShape); +// // var resultObject = new JsonObject(); // resultObject.addProperty("id", getRawIdFor(sr.getOutput().getItem())); // resultObject.addProperty("count", sr.getOutput().getCount()); +// finalRecipe.add("result", resultObject); +// +// String id = ((Integer) getRawIdFor(sr.getOutput().getItem())).toString(); +// +// if (!finalObj.has(id)) { +// finalObj.add(id, new JsonArray()); +// } +// finalObj.get(id).getAsJsonArray().add(finalRecipe); +//// var input = new JsonArray(); +//// var ingredients = sr.getIngredients().stream().toList(); +//// for (int y = 0; y < sr.getHeight(); y++) { +//// var arr = new JsonArray(); +//// for (int x = 0; x < sr.getWidth(); x++) { +//// if ((y*3)+x >= ingredients.size()) { +//// arr.add(JsonNull.INSTANCE); +//// continue; +//// } +//// var ingredient = ingredients.get((y*3)+x).getMatchingStacks(); // FIXME: fix when there are more than one matching stack +//// if (ingredient.length == 0) { +//// arr.add(JsonNull.INSTANCE); +//// } else { +//// arr.add(getRawIdFor(ingredient[0].getItem())); +//// } +//// } +//// input.add(arr); +//// } +//// var rootRecipeObject = new JsonObject(); +//// rootRecipeObject.add("inShape", input); +//// var resultObject = new JsonObject(); +//// resultObject.addProperty("id", getRawIdFor(sr.getOutput().getItem())); +//// resultObject.addProperty("count", sr.getOutput().getCount()); +//// rootRecipeObject.add("result", resultObject); +//// recipes.put(getRawIdFor(sr.getOutput().getItem()), rootRecipeObject); +// } else if (recipe instanceof ShapelessRecipe sl) { +// var ingredients = new JsonArray(); +// for (Ingredient ingredient : sl.getIngredients()) { +// if (ingredient.isEmpty()) continue; +//// ingredients.add(getRawIdFor(ingredient.getMatchingStacks()[0].getItem())); +// } +// var rootRecipeObject = new JsonObject(); +// rootRecipeObject.add("ingredients", ingredients); +// var resultObject = new JsonObject(); +// resultObject.addProperty("id", getRawIdFor(sl.getOutput().getItem())); +// resultObject.addProperty("count", sl.getOutput().getCount()); // rootRecipeObject.add("result", resultObject); -// recipes.put(getRawIdFor(sr.getOutput().getItem()), rootRecipeObject); - } else if (recipe instanceof ShapelessRecipe sl) { - var ingredients = new JsonArray(); - for (Ingredient ingredient : sl.getIngredients()) { - if (ingredient.isEmpty()) continue; -// ingredients.add(getRawIdFor(ingredient.getMatchingStacks()[0].getItem())); - } - var rootRecipeObject = new JsonObject(); - rootRecipeObject.add("ingredients", ingredients); - var resultObject = new JsonObject(); - resultObject.addProperty("id", getRawIdFor(sl.getOutput().getItem())); - resultObject.addProperty("count", sl.getOutput().getCount()); - rootRecipeObject.add("result", resultObject); - recipes.put(getRawIdFor(sl.getOutput().getItem()), rootRecipeObject); - } - } - recipes.forEach((a, b) -> { - if (!finalObj.has(a.toString())) { - finalObj.add(a.toString(), new JsonArray()); - } - finalObj.get(a.toString()).getAsJsonArray().add(b); - }); - return finalObj; +// recipes.put(getRawIdFor(sl.getOutput().getItem()), rootRecipeObject); +// } +// } +// recipes.forEach((a, b) -> { +// if (!finalObj.has(a.toString())) { +// finalObj.add(a.toString(), new JsonArray()); +// } +// finalObj.get(a.toString()).getAsJsonArray().add(b); +// }); +// return finalObj; + return JsonNull.INSTANCE; + } + + @Override + public boolean isEnabled() { + return false; // TODO: Implement this } } diff --git a/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlockCollisionShapesDataGenerator.java b/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlockCollisionShapesDataGenerator.java index 411a466..e6f9bda 100644 --- a/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlockCollisionShapesDataGenerator.java +++ b/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlockCollisionShapesDataGenerator.java @@ -65,6 +65,8 @@ public class BlockCollisionShapesDataGenerator implements IDataGenerator { for (BlockState state : block.getStateManager().getBlockStates().reverse()) { List boxes = new ArrayList<>(); try { + // Fix needed for StairsBlock because it requires the state of the block to be set + DGU.getWorld().setBlockState(BlockPos.ORIGIN, state); block.appendCollisionBoxes(DGU.getWorld(), BlockPos.ORIGIN, state, ENTITY_BOX, boxes, null); } catch (Exception e) { e.printStackTrace(); diff --git a/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlocksDataGenerator.java b/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlocksDataGenerator.java index 1262f5f..a9c117f 100644 --- a/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlocksDataGenerator.java +++ b/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/BlocksDataGenerator.java @@ -120,6 +120,8 @@ public class BlocksDataGenerator implements IDataGenerator { } private static String boundingBox(Block block, BlockState state) { + // Fix needed for StairsBlock because it requires the state of the block to be set + DGU.getWorld().setBlockState(BlockPos.ORIGIN, state); if (block.getCollisionBox(DGU.getWorld(), BlockPos.ORIGIN, state) == null) { return "empty"; } diff --git a/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java b/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java index 1864c76..cf6dd4a 100644 --- a/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java +++ b/1.8.9/src/main/java/dev/u9g/minecraftdatagenerator/generators/EntitiesDataGenerator.java @@ -5,6 +5,7 @@ import com.google.gson.JsonObject; import dev.u9g.minecraftdatagenerator.mixin.EntityTypeAccessor; import dev.u9g.minecraftdatagenerator.util.DGU; import dev.u9g.minecraftdatagenerator.util.Registries; +import net.minecraft.block.Blocks; import net.minecraft.entity.*; import net.minecraft.entity.mob.AmbientEntity; import net.minecraft.entity.mob.HostileEntity; @@ -14,6 +15,7 @@ import net.minecraft.entity.passive.AnimalEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.FishingBobberEntity; import net.minecraft.entity.projectile.Projectile; +import net.minecraft.item.ItemStack; import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,6 +33,10 @@ public class EntitiesDataGenerator implements IDataGenerator { entityDesc.addProperty("id", id); entityDesc.addProperty("internalId", id); entityDesc.addProperty("name", Objects.requireNonNull(registryKey).getPath()); + if (entity instanceof ItemEntity itemEntity) { + // Same as 1.9.4 + itemEntity.setItemStack(new ItemStack(Blocks.STONE)); + } String displayName = entity != null ? entity.getTranslationKey() : null; if (displayName != null && !displayName.startsWith("entity.")) { entityDesc.addProperty("displayName", displayName); diff --git a/README.md b/README.md index cb94cb1..d184795 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # minecraft-data-generator -This tool generates minecraft-data files based on a running client using a fabric mod. +This tool generates minecraft-data files based on a running a server on client classpath using a fabric mod. The supported versions can be read in the directory structure. Every version has its own directory. @@ -26,13 +26,21 @@ You can then find the minecraft-data in the `/run/minecraft-data` direc ## Adding a new version To add a new version, you need to create a new directory in the root directory with the version name. -Then you need to add the version to the list in the `settings.gradle.kts` file. +Then you need to add the version to the list in the `settings.gradle` file. Then also add it to the `.github/workflows/build.yml` file. -Then copy the code of the most recently released version into the new directory. -Then you need to change the values in the `gradle.properties` file. +Then copy the code of the most recently released version into the new module directory. +Then you need to change the values in the `build.gradle` file. At last, you need to fix all code issues that are caused by the new version. if there are any new curse, treasure, or non-tradeable, or non-discoverable enchantments in the new version, you need to add them manually to the `EnchantmentsDataGenerator` class. For that, use an IDE like IntelliJ IDEA to fix the issues. Once everything compiles, you can commit the changes, push them to your fork and create a pull request. Once your PR was accepted and merged, the new version will be available in the next release. +## Technical info + +By configuring Unimined (the mod build tool used by this project) to run the server, the server will be started with the client classpath. +The Minecraft client always contains a copy of the whole server code. +This is so because the integrated server is always bundled with clients and Mojang has always additionally bundled the dedicated server code within the client code. +This way we can access client information and classes while running a modded server environment. + +The `common` module shares common mod logic to allow us to deduplicate similar code across versions. diff --git a/common/src/main/java/dev/u9g/minecraftdatagenerator/FieldHelper.java b/common/src/main/java/dev/u9g/minecraftdatagenerator/FieldHelper.java new file mode 100644 index 0000000..0162899 --- /dev/null +++ b/common/src/main/java/dev/u9g/minecraftdatagenerator/FieldHelper.java @@ -0,0 +1,21 @@ +package dev.u9g.minecraftdatagenerator; + +import java.lang.reflect.Field; + +public class FieldHelper { + public static Field findStaticFieldWithValue(Class clazz, Object value) { + for (Field field : clazz.getDeclaredFields()) { + try { + field.setAccessible(true); + if (field.get(null).equals(value)) { + return field; + } + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + + throw new IllegalArgumentException("No field with value " + value + " found in " + clazz); + } +} diff --git a/common/src/main/java/dev/u9g/minecraftdatagenerator/MinecraftDataGenerator.java b/common/src/main/java/dev/u9g/minecraftdatagenerator/MinecraftDataGenerator.java index 2b76d11..f0d8407 100644 --- a/common/src/main/java/dev/u9g/minecraftdatagenerator/MinecraftDataGenerator.java +++ b/common/src/main/java/dev/u9g/minecraftdatagenerator/MinecraftDataGenerator.java @@ -22,6 +22,6 @@ public class MinecraftDataGenerator { } else { MinecraftDataGenerator.LOGGER.severe("Data generation failed!"); } - Runtime.getRuntime().halt(0); + Runtime.getRuntime().halt(success ? 0 : 1); } }