Add auto PR generation (#48)

* Remap 1.21.6 to Mojang mappings

* start working on automation

* update newVersion script to use manifest

* update scripts

* update doc

* add dispatchable bump workflow

* update workflow env

* update workflows
This commit is contained in:
extremeheat
2025-08-17 23:37:24 +02:00
committed by GitHub
parent f9b358bb07
commit 5a98d2aabd
30 changed files with 553 additions and 353 deletions
+38
View File
@@ -0,0 +1,38 @@
const cp = require('child_process')
const gh = require('gh-helpers')()
const bump = require('../../tools/newVersion')
const exec = (a, o) => {
console.log('$', a)
cp.execSync(a, { stdio: 'inherit', ...o })
}
module.exports = async ([newVersion], helpers) => {
try {
bump(newVersion)
// Delete any existing branch named 'bump'
exec('git branch -D bump')
exec('git checkout -b bump')
exec('git add mc/' + newVersion)
exec('git commit -m "Add version ' + newVersion + '"')
exec('git push origin bump --force')
const pr = await gh.createPullRequest(
'Add version ' + newVersion,
'This automated PR adds version ' + newVersion,
'bump',
'main'
)
console.log('Pull request created:', pr.html_url)
} catch (error) {
console.log('Error bumping version:', error)
return helpers.reply('Error bumping version: ' + error.message)
}
}
if (require.main === module) {
const args = process.argv.slice(2)
if (args.length !== 1) {
console.error('Usage: node bump.js <newVersion>')
process.exit(1)
}
module.exports(args, { reply: console.log })
}
+2
View File
@@ -31,6 +31,8 @@ jobs:
versions="${versions%,*}]"
echo "versions=$versions" >> "$GITHUB_OUTPUT"
- name: Ensure that versions.json includes all versions
run: node -e 'const fs = require("fs"); const versions = JSON.parse(fs.readFileSync("versions.json", "utf8")); const expectedVersions = fs.readdirSync("mc"); if (expectedVersions.length !== versions.length || !expectedVersions.every(v => versions.includes(v))) { throw new Error("versions.json does not match the expected versions in mc/ folder"); }'
build:
needs: define-versions
+19
View File
@@ -0,0 +1,19 @@
name: Repo Commands
on:
issue_comment: # Handle comment commands
types: [created]
pull_request_target: # Handle renamed PRs
types: [edited]
jobs:
comment-trigger:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Run command handlers
uses: PrismarineJS/prismarine-repo-actions@master
with:
# NOTE: You must specify a Personal Access Token (PAT) with repo access here. While you can use the default GITHUB_TOKEN, actions taken with it will not trigger other actions, so if you have a CI workflow, commits created by this action will not trigger it.
token: ${{ secrets.PAT_PASSWORD }}
@@ -0,0 +1,15 @@
name: handle-mcdata-update
on:
repository_dispatch:
types: [mc-update]
jobs:
update-mcdata:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- run: npm install # install gh-helpers
- run: node .github/commands/bump.js ${{ github.event.client_payload.tag }}
env:
GITHUB_TOKEN: ${{ secrets.PAT_PASSWORD }}
+3
View File
@@ -118,3 +118,6 @@ gradle-app.setting
!gradle-wrapper.jar
bin/
node_modules
package-lock.json
+23 -7
View File
@@ -25,14 +25,30 @@ You can then find the minecraft-data in the `mc/<version>/run/minecraft-data` di
## 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` 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 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.
For that, use an IDE like IntelliJ IDEA to fix the issues.
Generally, our automated PR system will automatically create a new PR for a new version, so you just have to clone the auto opened PR and continue work on it.
### Manual setup
To add a new version manually, run
```
npm run bump <version>
```
For example, `npm run bump 1.21.6` will:
* Create mc/1.21.6 as a copy of 1.21.5
* Update mc/1.21.6/build.gradle for 1.21.6
* Add the version to `versions.json`
### Updating
Then, you need to fix all code issues that are caused by the new version as `mc/1.21.6` for example may need changes for the latest version of Minecraft.
Refer to Minecraft source code diffs for reference, as the code uses standard Mojmaps.
You can use an IDE like IntelliJ IDEA to manuall fix the issues or an LLM agent that has access to the source code diff.
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
+3 -4
View File
@@ -8,10 +8,9 @@ unimined.minecraft {
version "1.21.6"
mappings {
intermediary()
yarn(1)
devFallbackNamespace "intermediary"
mojmap()
devFallbackNamespace "mojmap"
}
customPatcher(new CustomOfficialFabricMinecraftTransformer(project, delegate as MinecraftProvider)) {
@@ -4,9 +4,9 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.entity.attribute.ClampedEntityAttribute;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.RangedAttribute;
import java.util.Objects;
@@ -19,17 +19,17 @@ public class AttributesDataGenerator implements IDataGenerator {
@Override
public JsonElement generateDataJson() {
JsonArray arr = new JsonArray();
var registry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ATTRIBUTE);
for (EntityAttribute attribute : registry) {
var registry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ATTRIBUTE);
for (Attribute attribute : registry) {
JsonObject obj = new JsonObject();
String name = Objects.requireNonNull(registry.getId(attribute)).getPath();
String name = Objects.requireNonNull(registry.getKey(attribute)).getPath();
while(name.contains("_")) {
name = name.replaceFirst("_[a-z]", String.valueOf(Character.toUpperCase(name.charAt(name.indexOf("_") + 1))));
}
obj.addProperty("name", name);
obj.addProperty("resource", Objects.requireNonNull(registry.getId(attribute)).toString());
obj.addProperty("min", ((ClampedEntityAttribute) attribute).getMinValue());
obj.addProperty("max", ((ClampedEntityAttribute) attribute).getMaxValue());
obj.addProperty("resource", Objects.requireNonNull(registry.getKey(attribute)).toString());
obj.addProperty("min", ((RangedAttribute) attribute).getMinValue());
obj.addProperty("max", ((RangedAttribute) attribute).getMaxValue());
obj.addProperty("default", attribute.getDefaultValue());
arr.add(obj);
}
@@ -3,19 +3,19 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.BiomeTags;
import net.minecraft.util.Identifier;
import net.minecraft.world.biome.Biome;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BiomeTags;
import net.minecraft.world.level.biome.Biome;
public class BiomesDataGenerator implements IDataGenerator {
private static String guessBiomeDimensionFromCategory(Biome biome) {
var biomeRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.BIOME);
if (biomeRegistry.getEntry(biome).isIn(BiomeTags.IS_NETHER)) {
var biomeRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.BIOME);
if (biomeRegistry.wrapAsHolder(biome).is(BiomeTags.IS_NETHER)) {
return "nether";
} else if (biomeRegistry.getEntry(biome).isIn(BiomeTags.IS_END)) {
} else if (biomeRegistry.wrapAsHolder(biome).is(BiomeTags.IS_END)) {
return "end";
} else {
return "overworld";
@@ -77,14 +77,14 @@ public class BiomesDataGenerator implements IDataGenerator {
public static JsonObject generateBiomeInfo(Registry<Biome> registry, Biome biome) {
JsonObject biomeDesc = new JsonObject();
Identifier registryKey = registry.getKey(biome).orElseThrow().getValue();
ResourceLocation registryKey = registry.getKey(biome);
String localizationKey = String.format("biome.%s.%s", registryKey.getNamespace(), registryKey.getPath());
String name = registryKey.getPath();
biomeDesc.addProperty("id", registry.getRawId(biome));
biomeDesc.addProperty("id", registry.getId(biome));
biomeDesc.addProperty("name", name);
String dimension = guessBiomeDimensionFromCategory(biome);
biomeDesc.addProperty("category", guessCategoryBasedOnName(name, dimension));
biomeDesc.addProperty("temperature", biome.getTemperature());
biomeDesc.addProperty("temperature", biome.getBaseTemperature());
//biomeDesc.addProperty("precipitation", biome.getPrecipitation().getName());// - removed in 1.19.4
biomeDesc.addProperty("has_precipitation", biome.hasPrecipitation());
//biomeDesc.addProperty("depth", biome.getDepth()); - Doesn't exist anymore in minecraft source
@@ -104,8 +104,8 @@ public class BiomesDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray biomesArray = new JsonArray();
DynamicRegistryManager registryManager = DGU.getWorld().getRegistryManager();
Registry<Biome> biomeRegistry = registryManager.getOrThrow(RegistryKeys.BIOME);
RegistryAccess registryManager = DGU.getWorld().registryAccess();
Registry<Biome> biomeRegistry = registryManager.lookupOrThrow(Registries.BIOME);
biomeRegistry.stream()
.map(biome -> generateBiomeInfo(biomeRegistry, biome))
@@ -5,14 +5,14 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.EmptyBlockView;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.util.*;
@@ -25,7 +25,7 @@ public class BlockCollisionShapesDataGenerator implements IDataGenerator {
@Override
public JsonObject generateDataJson() {
Registry<Block> blockRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.BLOCK);
Registry<Block> blockRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.BLOCK);
BlockShapesCache blockShapesCache = new BlockShapesCache();
blockRegistry.forEach(blockShapesCache::processBlock);
@@ -44,11 +44,11 @@ public class BlockCollisionShapesDataGenerator implements IDataGenerator {
private int lastCollisionShapeId = 0;
public void processBlock(Block block) {
List<BlockState> blockStates = block.getStateManager().getStates();
List<BlockState> blockStates = block.getStateDefinition().getPossibleStates();
List<Integer> blockCollisionShapes = new ArrayList<>();
for (BlockState blockState : blockStates) {
VoxelShape blockShape = blockState.getCollisionShape(EmptyBlockView.INSTANCE, BlockPos.ORIGIN);
VoxelShape blockShape = blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
Integer blockShapeIndex = uniqueBlockShapes.get(blockShape);
if (blockShapeIndex == null) {
@@ -77,7 +77,7 @@ public class BlockCollisionShapesDataGenerator implements IDataGenerator {
}
}
Identifier registryKey = blockRegistry.getKey(entry.getKey()).orElseThrow().getValue();
ResourceLocation registryKey = blockRegistry.getKey(entry.getKey());
resultObject.add(registryKey.getPath(), blockCollision);
}
@@ -89,7 +89,7 @@ public class BlockCollisionShapesDataGenerator implements IDataGenerator {
for (var entry : uniqueBlockShapes.entrySet()) {
JsonArray boxesArray = new JsonArray();
entry.getKey().forEachBox((x1, y1, z1, x2, y2, z2) -> {
entry.getKey().forAllBoxes((x1, y1, z1, x2, y2, z2) -> {
JsonArray oneBoxJsonArray = new JsonArray();
oneBoxJsonArray.add(x1);
@@ -4,27 +4,27 @@ import com.google.common.base.CaseFormat;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.block.AirBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.loot.context.LootContextParameters;
import net.minecraft.loot.context.LootWorldContext;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.IntProperty;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.EmptyBlockView;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.AirBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,8 +38,8 @@ public class BlocksDataGenerator implements IDataGenerator {
private static final Logger logger = LoggerFactory.getLogger(BlocksDataGenerator.class);
private static List<Item> getItemsEffectiveForBlock(BlockState blockState) {
return DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM).stream()
.filter(item -> item.getDefaultStack().isSuitableFor(blockState))
return DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM).stream()
.filter(item -> item.getDefaultInstance().isCorrectToolForDrops(blockState))
.collect(Collectors.toList());
}
@@ -47,17 +47,17 @@ public class BlocksDataGenerator implements IDataGenerator {
MinecraftServer minecraftServer = DGU.getCurrentlyRunningServer();
if (minecraftServer != null) {
//If we have local world context, we can actually evaluate loot tables and determine actual data
ServerWorld serverWorld = minecraftServer.getOverworld();
LootWorldContext.Builder lootContextParameterSet = new LootWorldContext.Builder(serverWorld)
.add(LootContextParameters.BLOCK_STATE, blockState)
.add(LootContextParameters.ORIGIN, Vec3d.ZERO)
.add(LootContextParameters.TOOL, firstToolItem.getDefaultStack());
outDrops.addAll(blockState.getDroppedStacks(lootContextParameterSet));
ServerLevel serverWorld = minecraftServer.overworld();
LootParams.Builder lootContextParameterSet = new LootParams.Builder(serverWorld)
.withParameter(LootContextParams.BLOCK_STATE, blockState)
.withParameter(LootContextParams.ORIGIN, Vec3.ZERO)
.withParameter(LootContextParams.TOOL, firstToolItem.getDefaultInstance());
outDrops.addAll(blockState.getDrops(lootContextParameterSet));
} else {
//If we're lacking world context to correctly determine drops, assume that default drop is ItemBlock stack in quantity of 1
Item itemBlock = blockState.getBlock().asItem();
if (itemBlock != Items.AIR) {
outDrops.add(itemBlock.getDefaultStack());
outDrops.add(itemBlock.getDefaultInstance());
}
}
}
@@ -67,7 +67,7 @@ public class BlocksDataGenerator implements IDataGenerator {
if (property instanceof BooleanProperty) {
return "bool";
}
if (property instanceof IntProperty) {
if (property instanceof IntegerProperty) {
return "int";
}
if (property instanceof EnumProperty) {
@@ -82,7 +82,7 @@ public class BlocksDataGenerator implements IDataGenerator {
private static <T extends Comparable<T>> JsonObject generateStateProperty(Property<T> property) {
JsonObject propertyObject = new JsonObject();
Collection<T> propertyValues = property.getValues();
Collection<T> propertyValues = property.getPossibleValues();
propertyObject.addProperty("name", property.getName());
propertyObject.addProperty("type", getPropertyTypeName(property));
@@ -92,7 +92,7 @@ public class BlocksDataGenerator implements IDataGenerator {
if (!(property instanceof BooleanProperty)) {
JsonArray propertyValuesArray = new JsonArray();
for (T propertyValue : propertyValues) {
propertyValuesArray.add(property.name(propertyValue));
propertyValuesArray.add(property.getName(propertyValue));
}
propertyObject.add("values", propertyValuesArray);
}
@@ -120,21 +120,22 @@ public class BlocksDataGenerator implements IDataGenerator {
public static JsonObject generateBlock(List<MaterialsDataGenerator.MaterialInfo> materials, Block block) {
JsonObject blockDesc = new JsonObject();
Registry<Block> blockRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.BLOCK);
List<BlockState> blockStates = block.getStateManager().getStates();
BlockState defaultState = block.getDefaultState();
Identifier registryKey = Registries.BLOCK.getKey(block).orElseThrow().getValue();
String localizationKey = block.getTranslationKey();
List<BlockState> blockStates = block.getStateDefinition().getPossibleStates();
BlockState defaultState = block.defaultBlockState();
ResourceLocation registryKey = blockRegistry.getKey(block);
String localizationKey = block.getDescriptionId();
List<Item> effectiveTools = getItemsEffectiveForBlock(defaultState);
blockDesc.addProperty("id", Registries.BLOCK.getRawId(block));
blockDesc.addProperty("id", blockRegistry.getId(block));
blockDesc.addProperty("name", registryKey.getPath());
blockDesc.addProperty("displayName", DGU.translateText(localizationKey));
blockDesc.addProperty("hardness", block.getHardness());
blockDesc.addProperty("resistance", block.getBlastResistance());
blockDesc.addProperty("stackSize", block.asItem().getMaxCount());
blockDesc.addProperty("diggable", block.getHardness() != -1.0f && !(block instanceof AirBlock));
blockDesc.addProperty("hardness", block.defaultDestroyTime());
blockDesc.addProperty("resistance", block.getExplosionResistance());
blockDesc.addProperty("stackSize", block.asItem().getDefaultMaxStackSize());
blockDesc.addProperty("diggable", block.defaultDestroyTime() != -1.0f && !(block instanceof AirBlock));
// JsonObject effTools = new JsonObject();
// effectiveTools.forEach(item -> effTools.addProperty(
// String.valueOf(Registry.ITEM.getRawId(item)), // key
@@ -143,25 +144,26 @@ public class BlocksDataGenerator implements IDataGenerator {
// blockDesc.add("effectiveTools", effTools);
blockDesc.addProperty("material", findMatchingBlockMaterial(defaultState, materials));
blockDesc.addProperty("transparent", !defaultState.isOpaque());
blockDesc.addProperty("emitLight", defaultState.getLuminance());
blockDesc.addProperty("filterLight", defaultState.getOpacity());
blockDesc.addProperty("transparent", !defaultState.canOcclude());
blockDesc.addProperty("emitLight", defaultState.getLightEmission());
blockDesc.addProperty("filterLight", defaultState.getLightBlock());
blockDesc.addProperty("defaultState", Block.getRawIdFromState(defaultState));
blockDesc.addProperty("minStateId", Block.getRawIdFromState(blockStates.getFirst()));
blockDesc.addProperty("maxStateId", Block.getRawIdFromState(blockStates.getLast()));
blockDesc.addProperty("defaultState", Block.getId(defaultState));
blockDesc.addProperty("minStateId", Block.getId(blockStates.getFirst()));
blockDesc.addProperty("maxStateId", Block.getId(blockStates.getLast()));
JsonArray stateProperties = new JsonArray();
for (Property<?> property : block.getStateManager().getProperties()) {
for (Property<?> property : block.getStateDefinition().getProperties()) {
stateProperties.add(generateStateProperty(property));
}
blockDesc.add("states", stateProperties);
//Only add harvest tools if tool is required for harvesting this block
if (defaultState.isToolRequired()) {
if (defaultState.requiresCorrectToolForDrops()) {
Registry<Item> itemRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM);
JsonObject effectiveToolsObject = new JsonObject();
for (Item effectiveItem : effectiveTools) {
effectiveToolsObject.addProperty(Integer.toString(Item.getRawId(effectiveItem)), true);
effectiveToolsObject.addProperty(Integer.toString(itemRegistry.getId(effectiveItem)), true);
}
blockDesc.add("harvestTools", effectiveToolsObject);
}
@@ -170,12 +172,13 @@ public class BlocksDataGenerator implements IDataGenerator {
populateDropsIfPossible(defaultState, effectiveTools.isEmpty() ? Items.AIR : effectiveTools.getFirst(), actualBlockDrops);
JsonArray dropsArray = new JsonArray();
Registry<Item> itemRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM);
for (ItemStack dropStack : actualBlockDrops) {
dropsArray.add(Item.getRawId(dropStack.getItem()));
dropsArray.add(itemRegistry.getId(dropStack.getItem()));
}
blockDesc.add("drops", dropsArray);
VoxelShape blockCollisionShape = defaultState.getCollisionShape(EmptyBlockView.INSTANCE, BlockPos.ORIGIN);
VoxelShape blockCollisionShape = defaultState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
blockDesc.addProperty("boundingBox", blockCollisionShape.isEmpty() ? "empty" : "block");
return blockDesc;
@@ -190,8 +193,9 @@ public class BlocksDataGenerator implements IDataGenerator {
public JsonArray generateDataJson() {
JsonArray resultBlocksArray = new JsonArray();
List<MaterialsDataGenerator.MaterialInfo> availableMaterials = MaterialsDataGenerator.getGlobalMaterialInfo();
Registry<Block> blockRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.BLOCK);
Registries.BLOCK.forEach(block -> resultBlocksArray.add(generateBlock(availableMaterials, block)));
blockRegistry.forEach(block -> resultBlocksArray.add(generateBlock(availableMaterials, block)));
return resultBlocksArray;
}
}
@@ -3,31 +3,31 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffects;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.stream.Collectors;
public class EffectsDataGenerator implements IDataGenerator {
public static JsonObject generateEffect(Registry<StatusEffect> registry, StatusEffect statusEffect) {
public static JsonObject generateEffect(Registry<MobEffect> registry, MobEffect mobEffect) {
JsonObject effectDesc = new JsonObject();
Identifier registryKey = registry.getKey(statusEffect).orElseThrow().getValue();
ResourceLocation registryKey = registry.getKey(mobEffect);
effectDesc.addProperty("id", registry.getRawId(statusEffect));
if (statusEffect == StatusEffects.UNLUCK) {
effectDesc.addProperty("id", registry.getId(mobEffect));
if (mobEffect == MobEffects.UNLUCK.value()) {
effectDesc.addProperty("name", "BadLuck");
effectDesc.addProperty("displayName", "Bad Luck");
} else {
effectDesc.addProperty("name", Arrays.stream(registryKey.getPath().split("_")).map(StringUtils::capitalize).collect(Collectors.joining()));
effectDesc.addProperty("displayName", DGU.translateText(statusEffect.getTranslationKey()));
effectDesc.addProperty("displayName", DGU.translateText(mobEffect.getDescriptionId()));
}
effectDesc.addProperty("type", statusEffect.isBeneficial() ? "good" : "bad");
effectDesc.addProperty("type", mobEffect.isBeneficial() ? "good" : "bad");
return effectDesc;
}
@@ -39,8 +39,8 @@ public class EffectsDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray resultsArray = new JsonArray();
Registry<StatusEffect> statusEffectRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.STATUS_EFFECT);
statusEffectRegistry.forEach(effect -> resultsArray.add(generateEffect(statusEffectRegistry, effect)));
Registry<MobEffect> mobEffectRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.MOB_EFFECT);
mobEffectRegistry.forEach(effect -> resultsArray.add(generateEffect(mobEffectRegistry, effect)));
return resultsArray;
}
}
@@ -3,36 +3,36 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.item.Item;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.entry.RegistryEntryList;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.enchantment.Enchantment;
import java.util.List;
public class EnchantmentsDataGenerator implements IDataGenerator {
public static String getEnchantmentTargetName(RegistryEntryList<Item> target) {
TagKey<Item> tagKey = target.getTagKey().orElseThrow();
return tagKey.id().getPath().split("/")[1];
public static String getEnchantmentTargetName(HolderSet<Item> target) {
TagKey<Item> tagKey = target.unwrapKey().orElseThrow();
return tagKey.location().getPath().split("/")[1];
}
private static boolean isEnchantmentInTag(Enchantment enchantment, String tag) {
return DGU.getWorld()
.getRegistryManager()
.getOrThrow(RegistryKeys.ENCHANTMENT)
.getOrThrow(TagKey.of(RegistryKeys.ENCHANTMENT, Identifier.of(tag)))
.registryAccess()
.lookupOrThrow(Registries.ENCHANTMENT)
.getOrThrow(TagKey.create(Registries.ENCHANTMENT, ResourceLocation.parse(tag)))
.stream()
.anyMatch(enchantmentRegistryEntry -> enchantmentRegistryEntry.value() == enchantment);
}
//Equation enchantment costs follow is a * level + b, so we can easily retrieve a and b by passing zero level
private static JsonObject generateEnchantmentMinPowerCoefficients(Enchantment enchantment) {
int b = enchantment.getMinPower(0);
int a = enchantment.getMinPower(1) - b;
int b = enchantment.getMinLevel();
int a = enchantment.getMaxLevel() - b;
JsonObject resultObject = new JsonObject();
resultObject.addProperty("a", a);
@@ -41,8 +41,8 @@ public class EnchantmentsDataGenerator implements IDataGenerator {
}
private static JsonObject generateEnchantmentMaxPowerCoefficients(Enchantment enchantment) {
int b = enchantment.getMaxPower(0);
int a = enchantment.getMaxPower(1) - b;
int b = enchantment.getMinLevel();
int a = enchantment.getMaxLevel() - b;
JsonObject resultObject = new JsonObject();
resultObject.addProperty("a", a);
@@ -52,9 +52,9 @@ public class EnchantmentsDataGenerator implements IDataGenerator {
public static JsonObject generateEnchantment(Registry<Enchantment> registry, Enchantment enchantment) {
JsonObject enchantmentDesc = new JsonObject();
Identifier registryKey = registry.getKey(enchantment).orElseThrow().getValue();
ResourceLocation registryKey = registry.getKey(enchantment);
enchantmentDesc.addProperty("id", registry.getRawId(enchantment));
enchantmentDesc.addProperty("id", registry.getId(enchantment));
enchantmentDesc.addProperty("name", registryKey.getPath());
enchantmentDesc.addProperty("displayName", enchantment.description().getString());
@@ -68,21 +68,21 @@ public class EnchantmentsDataGenerator implements IDataGenerator {
List<Enchantment> incompatibleEnchantments = registry.stream()
.filter(other -> {
RegistryEntry<Enchantment> enchantmentEntry = registry.getEntry(enchantment);
RegistryEntry<Enchantment> otherEntry = registry.getEntry(other);
return !Enchantment.canBeCombined(enchantmentEntry, otherEntry);
Holder<Enchantment> enchantmentEntry = registry.wrapAsHolder(enchantment);
Holder<Enchantment> otherEntry = registry.wrapAsHolder(other);
return !Enchantment.areCompatible(enchantmentEntry, otherEntry);
})
.filter(other -> other != enchantment)
.toList();
JsonArray excludes = new JsonArray();
for (Enchantment excludedEnchantment : incompatibleEnchantments) {
Identifier otherKey = registry.getKey(excludedEnchantment).orElseThrow().getValue();
ResourceLocation otherKey = registry.getKey(excludedEnchantment);
excludes.add(otherKey.getPath());
}
enchantmentDesc.add("exclude", excludes);
enchantmentDesc.addProperty("category", getEnchantmentTargetName(enchantment.getApplicableItems()));
enchantmentDesc.addProperty("weight", enchantment.getWeight());
enchantmentDesc.addProperty("category", getEnchantmentTargetName(enchantment.definition().supportedItems()));
enchantmentDesc.addProperty("weight", enchantment.definition().weight());
enchantmentDesc.addProperty("tradeable", isEnchantmentInTag(enchantment, "tradeable"));
enchantmentDesc.addProperty("discoverable", isEnchantmentInTag(enchantment, "on_random_loot"));
@@ -97,7 +97,7 @@ public class EnchantmentsDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray resultsArray = new JsonArray();
Registry<Enchantment> enchantmentRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ENCHANTMENT);
Registry<Enchantment> enchantmentRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ENCHANTMENT);
enchantmentRegistry.stream()
.forEach(enchantment -> resultsArray.add(generateEnchantment(enchantmentRegistry, enchantment)));
return resultsArray;
@@ -3,33 +3,33 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.mob.AmbientEntity;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.WaterCreatureEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.passive.PassiveEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Identifier;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ambient.AmbientCreature;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.animal.WaterAnimal;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.projectile.Projectile;
public class EntitiesDataGenerator implements IDataGenerator {
public static JsonObject generateEntity(Registry<EntityType<?>> entityRegistry, EntityType<?> entityType) {
JsonObject entityDesc = new JsonObject();
Identifier registryKey = entityRegistry.getKey(entityType).orElseThrow().getValue();
int entityRawId = entityRegistry.getRawId(entityType);
ResourceLocation registryKey = entityRegistry.getKey(entityType);
int entityRawId = entityRegistry.getId(entityType);
entityDesc.addProperty("id", entityRawId);
entityDesc.addProperty("internalId", entityRawId);
entityDesc.addProperty("name", registryKey.getPath());
entityDesc.addProperty("displayName", DGU.translateText(entityType.getTranslationKey()));
entityDesc.addProperty("displayName", DGU.translateText(entityType.getDescriptionId()));
entityDesc.addProperty("width", entityType.getDimensions().width());
entityDesc.addProperty("height", entityType.getDimensions().height());
@@ -37,7 +37,7 @@ public class EntitiesDataGenerator implements IDataGenerator {
MinecraftServer minecraftServer = DGU.getCurrentlyRunningServer();
if (minecraftServer != null) {
Entity entityObject = entityType.create(minecraftServer.getOverworld(), SpawnReason.NATURAL);
Entity entityObject = entityType.create(minecraftServer.overworld(), EntitySpawnReason.NATURAL);
entityTypeString = entityObject != null ? getEntityTypeForClass(entityObject.getClass()) : "unknown";
}
if (entityType == EntityType.PLAYER) {
@@ -52,20 +52,36 @@ public class EntitiesDataGenerator implements IDataGenerator {
private static String getCategoryFrom(EntityType<?> entityType) {
if (entityType == EntityType.PLAYER) return "UNKNOWN";
Entity entity = entityType.create(DGU.getWorld(), SpawnReason.NATURAL);
Entity entity = entityType.create(DGU.getWorld(), EntitySpawnReason.NATURAL);
if (entity == null)
throw new Error("Entity was null after trying to create a: " + DGU.translateText(entityType.getTranslationKey()));
throw new Error("Entity was null after trying to create a: " + DGU.translateText(entityType.getDescriptionId()));
entity.discard();
return switch (entity.getClass().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 Error("Unexpected entity type: " + entity.getClass().getPackageName());
};
String packageName = entity.getClass().getPackageName();
// Use a more flexible approach to handle sub-packages
if (packageName.equals("net.minecraft.world.entity.decoration") ||
packageName.startsWith("net.minecraft.world.entity.decoration.")) {
return "Immobile";
} else if (packageName.equals("net.minecraft.world.entity.boss") ||
packageName.equals("net.minecraft.world.entity.monster") ||
packageName.startsWith("net.minecraft.world.entity.boss.") ||
packageName.startsWith("net.minecraft.world.entity.monster.")) {
return "Hostile mobs";
} else if (packageName.equals("net.minecraft.world.entity.projectile") ||
packageName.startsWith("net.minecraft.world.entity.projectile.")) {
return "Projectiles";
} else if (packageName.equals("net.minecraft.world.entity.animal") ||
packageName.startsWith("net.minecraft.world.entity.animal.")) {
return "Passive mobs";
} else if (packageName.equals("net.minecraft.world.entity.vehicle") ||
packageName.startsWith("net.minecraft.world.entity.vehicle.")) {
return "Vehicles";
} else if (packageName.equals("net.minecraft.world.entity")) {
return "UNKNOWN";
} else {
// Instead of throwing an error, return UNKNOWN for unexpected packages
return "UNKNOWN";
}
}
//Honestly, both "type" and "category" fields in the schema and examples do not contain any useful information
@@ -73,25 +89,25 @@ public class EntitiesDataGenerator implements IDataGenerator {
//by the Entity class hierarchy (which has some weirdness too by the way)
private static String getEntityTypeForClass(Class<? extends Entity> entityClass) {
//Top-level classifications
if (WaterCreatureEntity.class.isAssignableFrom(entityClass)) {
if (WaterAnimal.class.isAssignableFrom(entityClass)) {
return "water_creature";
}
if (AnimalEntity.class.isAssignableFrom(entityClass)) {
if (Animal.class.isAssignableFrom(entityClass)) {
return "animal";
}
if (HostileEntity.class.isAssignableFrom(entityClass)) {
if (Monster.class.isAssignableFrom(entityClass)) {
return "hostile";
}
if (AmbientEntity.class.isAssignableFrom(entityClass)) {
if (AmbientCreature.class.isAssignableFrom(entityClass)) {
return "ambient";
}
//Second level classifications. PathAwareEntity is not included because it
//doesn't really make much sense to categorize by it
if (PassiveEntity.class.isAssignableFrom(entityClass)) {
if (AgeableMob.class.isAssignableFrom(entityClass)) {
return "passive";
}
if (MobEntity.class.isAssignableFrom(entityClass)) {
if (Mob.class.isAssignableFrom(entityClass)) {
return "mob";
}
@@ -99,7 +115,7 @@ public class EntitiesDataGenerator implements IDataGenerator {
if (LivingEntity.class.isAssignableFrom(entityClass)) {
return "living";
}
if (ProjectileEntity.class.isAssignableFrom(entityClass)) {
if (Projectile.class.isAssignableFrom(entityClass)) {
return "projectile";
}
return "other";
@@ -113,7 +129,7 @@ public class EntitiesDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray resultArray = new JsonArray();
Registry<EntityType<?>> entityTypeRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ENTITY_TYPE);
Registry<EntityType<?>> entityTypeRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ENTITY_TYPE);
entityTypeRegistry.forEach(entity -> resultArray.add(generateEntity(entityTypeRegistry, entity)));
return resultArray;
}
@@ -3,27 +3,27 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.FoodComponent;
import net.minecraft.item.Item;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.food.FoodProperties;
import net.minecraft.world.item.Item;
import java.util.Objects;
public class FoodsDataGenerator implements IDataGenerator {
public static JsonObject generateFoodDescriptor(Registry<Item> registry, Item foodItem) {
JsonObject foodDesc = new JsonObject();
Identifier registryKey = registry.getKey(foodItem).orElseThrow().getValue();
ResourceLocation registryKey = registry.getKey(foodItem);
foodDesc.addProperty("id", registry.getRawId(foodItem));
foodDesc.addProperty("id", registry.getId(foodItem));
foodDesc.addProperty("name", registryKey.getPath());
foodDesc.addProperty("stackSize", foodItem.getMaxCount());
foodDesc.addProperty("displayName", DGU.translateText(foodItem.getTranslationKey()));
foodDesc.addProperty("stackSize", foodItem.getDefaultMaxStackSize());
foodDesc.addProperty("displayName", DGU.translateText(foodItem.getDescriptionId()));
FoodComponent foodComponent = Objects.requireNonNull(foodItem.getComponents().get(DataComponentTypes.FOOD));
FoodProperties foodComponent = Objects.requireNonNull(foodItem.components().get(DataComponents.FOOD));
float foodPoints = foodComponent.nutrition();
float saturationRatio = foodComponent.saturation() * 2.0F;
float saturation = foodPoints * saturationRatio;
@@ -43,9 +43,9 @@ public class FoodsDataGenerator implements IDataGenerator {
public JsonArray generateDataJson() {
JsonArray resultsArray = new JsonArray();
Registry<Item> itemRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM);
Registry<Item> itemRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM);
itemRegistry.stream()
.filter(i -> i.getComponents().contains(DataComponentTypes.FOOD))
.filter(i -> i.components().has(DataComponents.FOOD))
.forEach(food -> resultsArray.add(generateFoodDescriptor(itemRegistry, food)));
return resultsArray;
}
@@ -3,7 +3,7 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.block.enums.NoteBlockInstrument;
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
public class InstrumentsDataGenerator implements IDataGenerator {
@Override
@@ -17,7 +17,7 @@ public class InstrumentsDataGenerator implements IDataGenerator {
for (NoteBlockInstrument instrument : NoteBlockInstrument.values()) {
JsonObject object = new JsonObject();
object.addProperty("id", instrument.ordinal());
object.addProperty("name", instrument.asString());
object.addProperty("name", instrument.getSerializedName());
array.add(object);
}
return array;
@@ -4,14 +4,14 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
import java.util.List;
import java.util.Objects;
@@ -20,26 +20,26 @@ import java.util.stream.Collectors;
public class ItemsDataGenerator implements IDataGenerator {
private static List<Item> calculateItemsToRepairWith(Registry<Item> itemRegistry, Item sourceItem) {
ItemStack sourceItemStack = sourceItem.getDefaultStack();
ItemStack sourceItemStack = new ItemStack(sourceItem);
return itemRegistry.stream()
.filter(otherItem -> sourceItemStack.canRepairWith(otherItem.getDefaultStack()))
.filter(otherItem -> sourceItemStack.isValidRepairItem(new ItemStack(otherItem)))
.collect(Collectors.toList());
}
public static JsonObject generateItem(Registry<Item> itemRegistry, Item item) {
JsonObject itemDesc = new JsonObject();
Identifier registryKey = itemRegistry.getKey(item).orElseThrow().getValue();
ResourceLocation registryKey = itemRegistry.getKey(item);
itemDesc.addProperty("id", itemRegistry.getRawId(item));
itemDesc.addProperty("id", itemRegistry.getId(item));
itemDesc.addProperty("name", registryKey.getPath());
itemDesc.addProperty("displayName", DGU.translateText(item.getTranslationKey()));
itemDesc.addProperty("stackSize", item.getMaxCount());
itemDesc.addProperty("displayName", DGU.translateText(item.getDescriptionId()));
itemDesc.addProperty("stackSize", item.getDefaultMaxStackSize());
JsonArray enchantCategoriesArray = new JsonArray();
DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ENCHANTMENT).stream()
.map(Enchantment::getApplicableItems)
.filter(applicableItems -> applicableItems.contains(itemRegistry.getEntry(item)))
DGU.getWorld().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).stream()
.map(Enchantment::getSupportedItems)
.filter(applicableItems -> applicableItems.contains(itemRegistry.wrapAsHolder(item)))
.map(EnchantmentsDataGenerator::getEnchantmentTargetName)
.distinct()
.forEach(enchantCategoriesArray::add);
@@ -48,19 +48,19 @@ public class ItemsDataGenerator implements IDataGenerator {
itemDesc.add("enchantCategories", enchantCategoriesArray);
}
if (item.getComponents().contains(DataComponentTypes.DAMAGE)) {
if (item.components().has(DataComponents.MAX_DAMAGE)) {
List<Item> repairWithItems = calculateItemsToRepairWith(itemRegistry, item);
JsonArray fixedWithArray = new JsonArray();
for (Item repairWithItem : repairWithItems) {
Identifier repairWithName = itemRegistry.getKey(repairWithItem).orElseThrow().getValue();
ResourceLocation repairWithName = itemRegistry.getKey(repairWithItem);
fixedWithArray.add(repairWithName.getPath());
}
if (fixedWithArray.size() > 0) {
itemDesc.add("repairWith", fixedWithArray);
}
int maxDurability = Objects.requireNonNull(item.getComponents().get(DataComponentTypes.MAX_DAMAGE));
int maxDurability = Objects.requireNonNull(item.components().get(DataComponents.MAX_DAMAGE));
itemDesc.addProperty("maxDurability", maxDurability);
}
return itemDesc;
@@ -74,7 +74,7 @@ public class ItemsDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray resultArray = new JsonArray();
Registry<Item> itemRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM);
Registry<Item> itemRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM);
itemRegistry.stream().forEach(item -> resultArray.add(generateItem(itemRegistry, item)));
return resultArray;
}
@@ -5,16 +5,16 @@ import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.core.Registry;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.Registries;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import java.util.*;
import java.util.function.Predicate;
@@ -26,11 +26,11 @@ import java.util.stream.Collectors;
public class MaterialsDataGenerator implements IDataGenerator {
private static final List<ImmutableList<String>> COMPOSITE_MATERIALS = ImmutableList.<ImmutableList<String>>builder()
.add(ImmutableList.of("plant", makeMaterialNameForTag(BlockTags.AXE_MINEABLE)))
.add(ImmutableList.of("gourd", makeMaterialNameForTag(BlockTags.AXE_MINEABLE)))
.add(ImmutableList.of(makeMaterialNameForTag(BlockTags.LEAVES), makeMaterialNameForTag(BlockTags.HOE_MINEABLE)))
.add(ImmutableList.of(makeMaterialNameForTag(BlockTags.LEAVES), makeMaterialNameForTag(BlockTags.AXE_MINEABLE), makeMaterialNameForTag(BlockTags.HOE_MINEABLE)))
.add(ImmutableList.of("vine_or_glow_lichen", "plant", makeMaterialNameForTag(BlockTags.AXE_MINEABLE)
.add(ImmutableList.of("plant", makeMaterialNameForTag(BlockTags.MINEABLE_WITH_AXE)))
.add(ImmutableList.of("gourd", makeMaterialNameForTag(BlockTags.MINEABLE_WITH_AXE)))
.add(ImmutableList.of(makeMaterialNameForTag(BlockTags.LEAVES), makeMaterialNameForTag(BlockTags.MINEABLE_WITH_HOE)))
.add(ImmutableList.of(makeMaterialNameForTag(BlockTags.LEAVES), makeMaterialNameForTag(BlockTags.MINEABLE_WITH_AXE), makeMaterialNameForTag(BlockTags.MINEABLE_WITH_HOE)))
.add(ImmutableList.of("vine_or_glow_lichen", "plant", makeMaterialNameForTag(BlockTags.MINEABLE_WITH_AXE)
)).build();
private static final Map<String, Float> TOOL_SPEEDS = new HashMap<>() {{
@@ -58,7 +58,7 @@ public class MaterialsDataGenerator implements IDataGenerator {
}
private static String makeMaterialNameForTag(TagKey<Block> tag) {
return tag.id().getPath();
return tag.location().getPath();
}
private static void createCompositeMaterialInfo(List<MaterialInfo> allMaterials, List<String> combinedMaterials) {
@@ -90,32 +90,32 @@ public class MaterialsDataGenerator implements IDataGenerator {
public static List<MaterialInfo> getGlobalMaterialInfo() {
ArrayList<MaterialInfo> resultList = new ArrayList<>();
resultList.add(new MaterialInfo("vine_or_glow_lichen", blockState -> blockState.isOf(Blocks.VINE) || blockState.isOf(Blocks.GLOW_LICHEN)));
resultList.add(new MaterialInfo("coweb", blockState -> blockState.isOf(Blocks.COBWEB)));
resultList.add(new MaterialInfo("vine_or_glow_lichen", blockState -> blockState.is(Blocks.VINE) || blockState.is(Blocks.GLOW_LICHEN)));
resultList.add(new MaterialInfo("coweb", blockState -> blockState.is(Blocks.COBWEB)));
resultList.add(new MaterialInfo("leaves", blockState -> blockState.isIn(BlockTags.LEAVES)));
resultList.add(new MaterialInfo("wool", blockState -> blockState.isIn(BlockTags.WOOL)));
resultList.add(new MaterialInfo("leaves", blockState -> blockState.is(BlockTags.LEAVES)));
resultList.add(new MaterialInfo("wool", blockState -> blockState.is(BlockTags.WOOL)));
// Block Materials were removed in 1.20 in favor of block tags
resultList.add(new MaterialInfo("gourd", blockState -> blockState.isOf(Blocks.MELON) || blockState.isOf(Blocks.PUMPKIN) || blockState.isOf(Blocks.JACK_O_LANTERN)));
resultList.add(new MaterialInfo("gourd", blockState -> blockState.is(Blocks.MELON) || blockState.is(Blocks.PUMPKIN) || blockState.is(Blocks.JACK_O_LANTERN)));
// 'sword_efficient' tag is for all plants, and includes everything from the old PLANT and REPLACEABLE_PLANT materials (see https://minecraft.fandom.com/wiki/Tag#Blocks)
resultList.add(new MaterialInfo("plant", blockState -> blockState.isIn(BlockTags.SWORD_EFFICIENT)));
resultList.add(new MaterialInfo("plant", blockState -> blockState.is(BlockTags.SWORD_EFFICIENT)));
HashSet<String> uniqueMaterialNames = new HashSet<>();
Registry<Item> itemRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM);
Registry<Item> itemRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM);
itemRegistry.forEach(item -> {
if (item.getComponents().get(DataComponentTypes.TOOL) != null) {
item.getComponents().get(DataComponentTypes.TOOL).rules()
if (item.components().get(DataComponents.TOOL) != null) {
item.components().get(DataComponents.TOOL).rules()
.stream().map(rule -> rule.blocks())
.forEach(blocks -> {
Optional<TagKey<Block>> tagKey = blocks.getTagKey();
Optional<TagKey<Block>> tagKey = blocks.unwrapKey();
if (tagKey.isPresent()) {
String materialName = makeMaterialNameForTag((tagKey.get()));
if (!uniqueMaterialNames.contains(materialName)) {
uniqueMaterialNames.add(materialName);
resultList.add(new MaterialInfo(materialName, blockState -> blockState.isIn(blocks)));
resultList.add(new MaterialInfo(materialName, blockState -> blockState.is(blocks)));
}
}
});
@@ -133,7 +133,7 @@ public class MaterialsDataGenerator implements IDataGenerator {
@Override
public JsonElement generateDataJson() {
Registry<Item> itemRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM);
Registry<Item> itemRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM);
Map<String, Map<Item, Float>> materialMiningSpeeds = new LinkedHashMap<>();
materialMiningSpeeds.put("default", new LinkedHashMap<>());
@@ -152,22 +152,22 @@ public class MaterialsDataGenerator implements IDataGenerator {
//Shears need special handling because they do not follow normal rules like tools
leavesMaterialSpeeds.put(Items.SHEARS, 15.0f);
cowebMaterialSpeeds.put(Items.SHEARS, 15.0f);
Map<Item, Float> vineOrGlowLichenSpeeds = new LinkedHashMap<>();
vineOrGlowLichenSpeeds.put(Items.SHEARS, 2.0f);
materialMiningSpeeds.put("vine_or_glow_lichen", vineOrGlowLichenSpeeds);
Map<Item, Float> woolSpeeds = new LinkedHashMap<>();
woolSpeeds.put(Items.SHEARS, 5.0f);
materialMiningSpeeds.put("wool", woolSpeeds);
itemRegistry.forEach(item -> {
//Tools are handled rather easily and do not require anything else
if (item.getComponents().get(DataComponentTypes.TOOL) != null) {
item.getComponents().get(DataComponentTypes.TOOL).rules()
if (item.components().get(DataComponents.TOOL) != null) {
item.components().get(DataComponents.TOOL).rules()
.stream().map(rule -> rule.blocks())
.forEach(blocks -> {
Optional<TagKey<Block>> tagKey = blocks.getTagKey();
Optional<TagKey<Block>> tagKey = blocks.unwrapKey();
if (tagKey.isPresent()) {
String materialName = makeMaterialNameForTag(tagKey.get());
@@ -179,7 +179,7 @@ public class MaterialsDataGenerator implements IDataGenerator {
);
//Swords require special treatment
if (itemRegistry.getId(item).getPath().contains("sword")) {
if (itemRegistry.getKey(item).getPath().contains("sword")) {
cowebMaterialSpeeds.put(item, 15.0f);
plantMaterialSpeeds.put(item, 1.5f);
leavesMaterialSpeeds.put(item, 1.5f);
@@ -195,7 +195,7 @@ public class MaterialsDataGenerator implements IDataGenerator {
JsonObject toolSpeedsObject = new JsonObject();
for (var toolEntry : entry.getValue().entrySet()) {
int rawItemId = itemRegistry.getRawId(toolEntry.getKey());
int rawItemId = itemRegistry.getId(toolEntry.getKey());
toolSpeedsObject.addProperty(Integer.toString(rawItemId), toolEntry.getValue());
}
resultObject.add(entry.getKey(), toolSpeedsObject);
@@ -3,17 +3,17 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.particle.ParticleType;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.core.Registry;
import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
public class ParticlesDataGenerator implements IDataGenerator {
public static JsonObject generateParticleType(Registry<ParticleType<?>> registry, ParticleType<?> particleType) {
JsonObject effectDesc = new JsonObject();
Identifier registryKey = registry.getKey(particleType).orElseThrow().getValue();
ResourceLocation registryKey = registry.getKey(particleType);
effectDesc.addProperty("id", registry.getRawId(particleType));
effectDesc.addProperty("id", registry.getId(particleType));
effectDesc.addProperty("name", registryKey.getPath());
return effectDesc;
}
@@ -26,7 +26,7 @@ public class ParticlesDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray resultsArray = new JsonArray();
Registry<ParticleType<?>> particleTypeRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.PARTICLE_TYPE);
Registry<ParticleType<?>> particleTypeRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.PARTICLE_TYPE);
particleTypeRegistry.forEach(particleType -> resultsArray.add(generateParticleType(particleTypeRegistry, particleType)));
return resultsArray;
}
@@ -6,14 +6,13 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.item.Item;
import net.minecraft.recipe.*;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.recipe.input.CraftingRecipeInput;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.*;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.RecipeType;
import java.util.ArrayList;
import java.util.List;
@@ -22,7 +21,7 @@ import java.util.Objects;
public class RecipeDataGenerator implements IDataGenerator {
private static int getRawIdFor(Item item) {
return DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ITEM).getRawId(item);
return DGU.getWorld().registryAccess().lookupOrThrow(Registries.ITEM).getId(item);
}
@Override
@@ -32,26 +31,28 @@ public class RecipeDataGenerator implements IDataGenerator {
@Override
public JsonElement generateDataJson() {
DynamicRegistryManager registryManager = DGU.getWorld().getRegistryManager();
RegistryAccess registryManager = DGU.getWorld().registryAccess();
JsonObject finalObj = new JsonObject();
Multimap<Integer, JsonObject> recipes = ArrayListMultimap.create();
for (RecipeEntry<?> recipeE : Objects.requireNonNull(DGU.getWorld()).getServer().getRecipeManager().values()) {
for (RecipeHolder<?> recipeE : Objects.requireNonNull(DGU.getWorld()).getServer().getRecipeManager().getRecipes()) {
Recipe<?> recipe = recipeE.value();
if (recipe instanceof ShapedRecipe sr) {
generateShapedRecipe(registryManager, finalObj, sr, 0);
} else if (recipe instanceof ShapelessRecipe sl) {
var ingredients = new JsonArray();
for (Ingredient ingredient : sl.getIngredientPlacement().getIngredients()) {
if (ingredient.getMatchingItems().findAny().isEmpty()) continue;
ingredients.add(getRawIdFor(ingredient.getMatchingItems().findFirst().get().value()));
for (Object ingredientDisplay : sl.display()) {
if (ingredientDisplay instanceof Ingredient ingredient) {
if (ingredient.items().toList().isEmpty()) continue;
ingredients.add(getRawIdFor(ingredient.items().toList().get(0).value()));
}
}
var rootRecipeObject = new JsonObject();
rootRecipeObject.add("ingredients", ingredients);
var resultObject = new JsonObject();
resultObject.addProperty("id", getRawIdFor(sl.craft(CraftingRecipeInput.EMPTY, registryManager).getItem()));
resultObject.addProperty("count", sl.craft(CraftingRecipeInput.EMPTY, registryManager).getCount());
resultObject.addProperty("id", getRawIdFor(sl.assemble(CraftingInput.EMPTY, registryManager).getItem()));
resultObject.addProperty("count", sl.assemble(CraftingInput.EMPTY, registryManager).getCount());
rootRecipeObject.add("result", resultObject);
recipes.put(getRawIdFor(sl.craft(CraftingRecipeInput.EMPTY, registryManager).getItem()), rootRecipeObject);
recipes.put(getRawIdFor(sl.assemble(CraftingInput.EMPTY, registryManager).getItem()), rootRecipeObject);
}
}
recipes.forEach((a, b) -> {
@@ -63,7 +64,7 @@ public class RecipeDataGenerator implements IDataGenerator {
return finalObj;
}
private void generateShapedRecipe(DynamicRegistryManager registryManager, JsonObject finalObj, ShapedRecipe sr, int n) {
private void generateShapedRecipe(RegistryAccess registryManager, JsonObject finalObj, ShapedRecipe sr, int n) {
boolean hasIncremented = false;
var ingredients = sr.getIngredients();
List<Integer> ingr = new ArrayList<>();
@@ -77,7 +78,7 @@ public class RecipeDataGenerator implements IDataGenerator {
ingr.add(null);
continue;
}
var matchingList = stacks.get().getMatchingItems().toList();
var matchingList = stacks.get().items().toList();
if (matchingList.isEmpty()) {
ingr.add(null);
continue;
@@ -110,11 +111,11 @@ public class RecipeDataGenerator implements IDataGenerator {
finalRecipe.add("inShape", inShape);
var resultObject = new JsonObject();
resultObject.addProperty("id", getRawIdFor(sr.craft(CraftingRecipeInput.EMPTY, registryManager).getItem()));
resultObject.addProperty("count", sr.craft(CraftingRecipeInput.EMPTY, registryManager).getCount());
resultObject.addProperty("id", getRawIdFor(sr.assemble(CraftingInput.EMPTY, registryManager).getItem()));
resultObject.addProperty("count", sr.assemble(CraftingInput.EMPTY, registryManager).getCount());
finalRecipe.add("result", resultObject);
String id = ((Integer) getRawIdFor(sr.craft(CraftingRecipeInput.EMPTY, registryManager).getItem())).toString();
String id = ((Integer) getRawIdFor(sr.assemble(CraftingInput.EMPTY, registryManager).getItem())).toString();
if (!finalObj.has(id)) {
finalObj.add(id, new JsonArray());
@@ -2,15 +2,18 @@ package dev.u9g.minecraftdatagenerator.generators;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.minecraft.registry.Registries;
import net.minecraft.sound.SoundEvent;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.sounds.SoundEvent;
public class SoundsDataGenerator implements IDataGenerator {
public static JsonObject generateSound(SoundEvent soundEvent) {
JsonObject soundDesc = new JsonObject();
soundDesc.addProperty("id", Registries.SOUND_EVENT.getRawId(soundEvent) + 1); // the plus 1 is required for 1.19.2+ due to Mojang using 0 in the packet to say that you should read a string id instead.
soundDesc.addProperty("name", soundEvent.id().getPath());
soundDesc.addProperty("id", BuiltInRegistries.SOUND_EVENT.getId(soundEvent) + 1); // the plus 1 is required for 1.19.2+ due to Mojang using 0 in the packet to say that you should read a string id instead.
soundDesc.addProperty("name", soundEvent.location().getPath());
return soundDesc;
}
@@ -23,7 +26,8 @@ public class SoundsDataGenerator implements IDataGenerator {
@Override
public JsonArray generateDataJson() {
JsonArray resultsArray = new JsonArray();
Registries.SOUND_EVENT.forEach(sound -> resultsArray.add(generateSound(sound)));
Registry<SoundEvent> soundEventRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.SOUND_EVENT);
soundEventRegistry.forEach(sound -> resultsArray.add(generateSound(sound)));
return resultsArray;
}
}
@@ -4,18 +4,17 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import dev.u9g.minecraftdatagenerator.util.DGU;
import dev.u9g.minecraftdatagenerator.util.EmptyRenderBlockView;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.RedstoneWireBlock;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.FoliageColors;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.FoliageColor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.RedStoneWireBlock;
import java.util.*;
@@ -24,7 +23,7 @@ public class TintsDataGenerator implements IDataGenerator {
BiomeTintColors colors = new BiomeTintColors();
biomeRegistry.forEach(biome -> {
int biomeGrassColor = biome.getGrassColorAt(0.0, 0.0);
int biomeGrassColor = biome.getGrassColor(0.0, 0.0);
int biomeFoliageColor = biome.getFoliageColor();
int biomeWaterColor = biome.getWaterColor();
@@ -38,9 +37,9 @@ public class TintsDataGenerator implements IDataGenerator {
public static Map<Integer, Integer> generateRedstoneTintColors() {
Map<Integer, Integer> resultColors = new LinkedHashMap<>();
for (int redstoneLevel : RedstoneWireBlock.POWER.getValues()) {
for (int redstoneLevel : RedStoneWireBlock.POWER.getPossibleValues()) {
// Remove the unintended alpha channel from the redstone tint color
int color = removeAlphaChannel(RedstoneWireBlock.getWireColor(redstoneLevel));
int color = removeAlphaChannel(RedStoneWireBlock.getColorForPower(redstoneLevel));
resultColors.put(redstoneLevel, color);
}
return resultColors;
@@ -50,18 +49,18 @@ public class TintsDataGenerator implements IDataGenerator {
float r = (float) (color >> 16 & 0xFF) / 255;
float g = (float) (color >> 8 & 0xFF) / 255;
float b = (float) (color & 0xFF) / 255;
return ColorHelper.fromFloats(0, r, g, b);
return ((int)(r * 255) << 16) | ((int)(g * 255) << 8) | (int)(b * 255);
}
private static int getBlockColor(Block block) {
return BlockColors.create().getColor(block.getDefaultState(), EmptyRenderBlockView.INSTANCE, BlockPos.ORIGIN, 0xFFFFFF);
return BlockColors.createDefault().getColor(block.defaultBlockState(), EmptyRenderBlockView.INSTANCE, BlockPos.ZERO, 0xFFFFFF);
}
public static Map<Block, Integer> generateConstantTintColors() {
Map<Block, Integer> resultColors = new LinkedHashMap<>();
resultColors.put(Blocks.BIRCH_LEAVES, FoliageColors.BIRCH);
resultColors.put(Blocks.SPRUCE_LEAVES, FoliageColors.SPRUCE);
resultColors.put(Blocks.BIRCH_LEAVES, FoliageColor.FOLIAGE_BIRCH);
resultColors.put(Blocks.SPRUCE_LEAVES, FoliageColor.FOLIAGE_EVERGREEN);
resultColors.put(Blocks.LILY_PAD, getBlockColor(Blocks.LILY_PAD));
resultColors.put(Blocks.ATTACHED_MELON_STEM, getBlockColor(Blocks.ATTACHED_MELON_STEM));
@@ -81,7 +80,7 @@ public class TintsDataGenerator implements IDataGenerator {
JsonArray keysArray = new JsonArray();
for (Biome biome : entry.getValue()) {
Identifier registryKey = biomeRegistry.getKey(biome).orElseThrow().getValue();
ResourceLocation registryKey = biomeRegistry.getKey(biome);
keysArray.add(registryKey.getPath());
}
@@ -119,7 +118,7 @@ public class TintsDataGenerator implements IDataGenerator {
JsonObject entryObject = new JsonObject();
JsonArray keysArray = new JsonArray();
Identifier registryKey = blockRegistry.getKey(entry.getKey()).orElseThrow().getValue();
ResourceLocation registryKey = blockRegistry.getKey(entry.getKey());
keysArray.add(registryKey.getPath());
entryObject.add("keys", keysArray);
@@ -139,9 +138,9 @@ public class TintsDataGenerator implements IDataGenerator {
@Override
public JsonObject generateDataJson() {
DynamicRegistryManager registryManager = DGU.getWorld().getRegistryManager();
Registry<Biome> biomeRegistry = registryManager.getOrThrow(RegistryKeys.BIOME);
Registry<Block> blockRegistry = registryManager.getOrThrow(RegistryKeys.BLOCK);
RegistryAccess registryManager = DGU.getWorld().registryAccess();
Registry<Biome> biomeRegistry = registryManager.lookupOrThrow(Registries.BIOME);
Registry<Block> blockRegistry = registryManager.lookupOrThrow(Registries.BLOCK);
BiomeTintColors biomeTintColors = generateBiomeTintColors(biomeRegistry);
Map<Integer, Integer> redstoneColors = generateRedstoneTintColors();
@@ -17,9 +17,9 @@
*/
package dev.u9g.minecraftdatagenerator.mixin;
import net.minecraft.resource.DataPackSettings;
import net.minecraft.resource.featuretoggle.FeatureFlags;
import net.minecraft.util.Identifier;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.world.flag.FeatureFlags;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -27,10 +27,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DataPackSettings.class)
@Mixin(PackRepository.class)
public class DataPackSettingsMixin {
@Inject(method = "getEnabled", at = @At("HEAD"), cancellable = true)
@Inject(method = "getSelectedIds", at = @At("HEAD"), cancellable = true)
public void getEnabled(CallbackInfoReturnable<List<String>> cir) {
cir.setReturnValue(FeatureFlags.FEATURE_MANAGER.toId(FeatureFlags.FEATURE_MANAGER.getFeatureSet()).stream().map(Identifier::getPath).toList());
cir.setReturnValue(FeatureFlags.REGISTRY.toNames(FeatureFlags.REGISTRY.allFlags()).stream().map(ResourceLocation::getPath).toList());
}
}
@@ -1,14 +1,14 @@
package dev.u9g.minecraftdatagenerator.mixin;
import net.minecraft.server.dedicated.EulaReader;
import net.minecraft.server.Eula;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(EulaReader.class)
@Mixin(Eula.class)
public class EULAMixin {
@Inject(method = "isEulaAgreedTo()Z", at = @At("TAIL"), cancellable = true)
@Inject(method = "hasAgreedToEULA()Z", at = @At("TAIL"), cancellable = true)
public void init(CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(true);
}
@@ -2,21 +2,21 @@ package dev.u9g.minecraftdatagenerator.mixin;
import dev.u9g.minecraftdatagenerator.MinecraftDataGenerator;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.MinecraftVersion;
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
import net.minecraft.SharedConstants;
import net.minecraft.server.dedicated.DedicatedServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(MinecraftDedicatedServer.class)
@Mixin(DedicatedServer.class)
public class ReadyMixin {
@Inject(method = "setupServer()Z", at = @At("TAIL"))
@Inject(method = "initServer()Z", at = @At("TAIL"))
private void init(CallbackInfoReturnable<Boolean> cir) {
MinecraftDataGenerator.start(
"1.21.6",
DGU.getCurrentlyRunningServer().getRunDirectory()
SharedConstants.VERSION_STRING,
DGU.getCurrentlyRunningServer().getServerDirectory()
);
}
}
@@ -1,9 +1,9 @@
package dev.u9g.minecraftdatagenerator.util;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.locale.Language;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Language;
import net.minecraft.world.World;
import net.minecraft.world.level.Level;
public class DGU {
@SuppressWarnings("deprecation")
@@ -12,10 +12,10 @@ public class DGU {
}
public static String translateText(String translationKey) {
return Language.getInstance().get(translationKey);
return Language.getInstance().getOrDefault(translationKey);
}
public static World getWorld() {
return getCurrentlyRunningServer().getOverworld();
public static Level getWorld() {
return getCurrentlyRunningServer().overworld();
}
}
@@ -1,23 +1,24 @@
package dev.u9g.minecraftdatagenerator.util;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.fluid.Fluids;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockRenderView;
import net.minecraft.world.LightType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeKeys;
import net.minecraft.world.biome.ColorResolver;
import net.minecraft.world.chunk.light.LightingProvider;
import dev.u9g.minecraftdatagenerator.util.DGU;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSpecialEffects.GrassColorModifier;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import org.jetbrains.annotations.Nullable;
public enum EmptyRenderBlockView implements BlockRenderView {
public enum EmptyRenderBlockView implements BlockAndTintGetter {
INSTANCE;
@Nullable
@@ -26,46 +27,51 @@ public enum EmptyRenderBlockView implements BlockRenderView {
}
public BlockState getBlockState(BlockPos pos) {
return Blocks.AIR.getDefaultState();
return Blocks.AIR.defaultBlockState();
}
public FluidState getFluidState(BlockPos pos) {
return Fluids.EMPTY.getDefaultState();
return Fluids.EMPTY.defaultFluidState();
}
public int getBottomY() {
return 0;
}
@Override
public int getHeight() {
return 0;
return 384;
}
@Override
public float getBrightness(Direction direction, boolean shaded) {
public float getShade(Direction direction, boolean shaded) {
return 0.0f;
}
@Override
public LightingProvider getLightingProvider() {
public LevelLightEngine getLightEngine() {
return null;
}
@Override
public int getColor(BlockPos pos, ColorResolver colorResolver) {
Registry<Biome> biomeRegistry = DGU.getWorld().getRegistryManager().getOrThrow(RegistryKeys.BIOME);
Biome plainsBiome = biomeRegistry.get(BiomeKeys.PLAINS);
public int getBlockTint(BlockPos pos, net.minecraft.world.level.ColorResolver colorResolver) {
Registry<Biome> biomeRegistry = DGU.getWorld().registryAccess().lookupOrThrow(Registries.BIOME);
Biome plainsBiome = biomeRegistry.get(Biomes.PLAINS).orElse(null).value();
return colorResolver.getColor(plainsBiome, pos.getX(), pos.getY());
}
@Override
public int getLightLevel(LightType type, BlockPos pos) {
return type == LightType.SKY ? 15 : 0;
public int getBrightness(LightLayer type, BlockPos pos) {
return type == LightLayer.SKY ? 15 : 0;
}
@Override
public int getBaseLightLevel(BlockPos pos, int ambientDarkness) {
return ambientDarkness;
}
@Override
public int getMinY() {
return -64;
}
}
+16
View File
@@ -0,0 +1,16 @@
{
"name": "minecraft-data-generator",
"version": "1.0.0",
"description": "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.",
"main": "index.js",
"scripts": {
"fix": "standard --fix",
"bump": "node tools/newVersion.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"gh-helpers": "^0.3.5",
"standard": "^17.1.2"
}
}
+38
View File
@@ -0,0 +1,38 @@
const fs = require('fs')
const { join } = require('path')
const manifest = require('../versions.json')
const oldVersion = manifest.at(-1)
const oldDir = join(__dirname, '../mc', oldVersion)
function bump (newVersion) {
const newDir = join(__dirname, '../mc', newVersion)
if (fs.existsSync(newDir)) {
console.warn(`New version directory already exists: ${newDir}`)
process.exit(0)
}
fs.cpSync(oldDir, newDir, { recursive: true })
// update the build.gradle file in the new mc version directory to replace the old version with the new version
const buildGradlePath = join(__dirname, '../mc', newVersion, 'build.gradle')
let buildGradleContent = fs.readFileSync(buildGradlePath, 'utf8')
buildGradleContent = buildGradleContent.replace(new RegExp(oldVersion, 'g'), newVersion)
fs.writeFileSync(buildGradlePath, buildGradleContent)
// Now update the versions.json file
manifest.push(newVersion)
fs.writeFileSync(join(__dirname, '../versions.json'), JSON.stringify(manifest, null, 2))
}
module.exports = bump
if (require.main === module) {
const [newVersion] = process.argv.slice(2)
if (!newVersion) {
console.error('Usage: node newVersion.js <newVersion>')
process.exit(1)
}
bump(newVersion)
}
+24
View File
@@ -0,0 +1,24 @@
[
"1.7",
"1.8.9",
"1.9.4",
"1.10.2",
"1.11.2",
"1.12.2",
"1.13",
"1.14",
"1.15",
"1.16",
"1.17",
"1.18",
"22w19a",
"1.19",
"1.19.2",
"1.20",
"1.20.4",
"1.20.5",
"1.21",
"1.21.3",
"1.21.5",
"1.21.6"
]