mirror of
https://github.com/GeyserMC/Rainbow.git
synced 2025-12-19 14:59:16 +00:00
Work on datagen module
This commit is contained in:
@@ -3,7 +3,7 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Implement namedElements so IntelliJ can use it correctly, but include the remapped build
|
||||
// Implement namedElements so IDEs can use it correctly, but include the remapped build
|
||||
implementation(project(path = ":rainbow", configuration = "namedElements"))
|
||||
include(project(":rainbow"))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"minVersion": "0.8",
|
||||
"package": "org.geysermc.rainbow.client.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [],
|
||||
"client": [
|
||||
"EntityRenderDispatcherAccessor",
|
||||
"GuiItemRenderStateMixin",
|
||||
|
||||
9
datagen/build.gradle.kts
Normal file
9
datagen/build.gradle.kts
Normal file
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id("rainbow.base-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Implement namedElements so IDEs can use it correctly, but include the remapped build
|
||||
implementation(project(path = ":rainbow", configuration = "namedElements"))
|
||||
include(project(":rainbow"))
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.geysermc.rainbow.datagen;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.minecraft.client.data.models.model.ModelInstance;
|
||||
import net.minecraft.client.renderer.item.ClientItem;
|
||||
import net.minecraft.client.resources.model.EquipmentClientInfo;
|
||||
import net.minecraft.client.resources.model.ResolvedModel;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.equipment.EquipmentAsset;
|
||||
import org.geysermc.rainbow.mapping.AssetResolver;
|
||||
import org.geysermc.rainbow.mapping.PackSerializer;
|
||||
import org.geysermc.rainbow.pack.BedrockPack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public abstract class RainbowModelProvider extends FabricModelProvider {
|
||||
private final HolderLookup.Provider registries;
|
||||
private final PackOutput.PathProvider bedrockPackPathProvider;
|
||||
private Map<Item, ClientItem> itemInfosMap;
|
||||
private Map<ResourceLocation, ModelInstance> models;
|
||||
|
||||
public RainbowModelProvider(FabricDataOutput output, HolderLookup.Provider registries) {
|
||||
super(output);
|
||||
this.registries = registries;
|
||||
bedrockPackPathProvider = output.createPathProvider(PackOutput.Target.RESOURCE_PACK, "bedrock");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<?> run(CachedOutput output) {
|
||||
CompletableFuture<?> vanillaModels = super.run(output);
|
||||
|
||||
BedrockPack pack = BedrockPack.builder("rainbow", Path.of("geyser_mappings"), Path.of("pack"),
|
||||
new Serializer(output, registries, bedrockPackPathProvider), new ModelResolver(itemInfosMap)).build();
|
||||
|
||||
for (Item item : itemInfosMap.keySet()) {
|
||||
pack.map(getVanillaItem(item).builtInRegistryHolder(), getVanillaDataComponentPatch(item));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(vanillaModels, pack.save());
|
||||
}
|
||||
|
||||
protected abstract Item getVanillaItem(Item modded);
|
||||
|
||||
protected DataComponentPatch getVanillaDataComponentPatch(Item modded) {
|
||||
DataComponentPatch.Builder builder = DataComponentPatch.builder();
|
||||
modded.components().forEach(builder::set);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public void setItemInfosMap(Map<Item, ClientItem> itemInfosMap) {
|
||||
this.itemInfosMap = itemInfosMap;
|
||||
}
|
||||
|
||||
public void setModels(Map<ResourceLocation, ModelInstance> models) {
|
||||
this.models = models;
|
||||
}
|
||||
|
||||
private record Serializer(CachedOutput output, HolderLookup.Provider registries, PackOutput.PathProvider provider) implements PackSerializer {
|
||||
|
||||
@Override
|
||||
public <T> CompletableFuture<?> saveJson(Codec<T> codec, T object, Path path) {
|
||||
ResourceLocation location = ResourceLocation.withDefaultNamespace(path.toString());
|
||||
return DataProvider.saveStable(output, registries, codec, object, provider.json(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> saveTexture(ResourceLocation texture, Path path) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ModelResolver implements AssetResolver {
|
||||
private final Map<ResourceLocation, ClientItem> itemInfosMap;
|
||||
private final Map<ResourceLocation, ModelInstance> models;
|
||||
|
||||
private ModelResolver(Map<Item, ClientItem> itemInfosMap, Map<ResourceLocation, ModelInstance> models) {
|
||||
this.itemInfosMap = new HashMap<>();
|
||||
for (Map.Entry<Item, ClientItem> entry : itemInfosMap.entrySet()) {
|
||||
this.itemInfosMap.put(entry.getKey().builtInRegistryHolder().key().location(), entry.getValue());
|
||||
}
|
||||
this.models = models;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ResolvedModel> getResolvedModel(ResourceLocation location) {
|
||||
return Optional.ofNullable(models.get(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ClientItem> getClientItem(ResourceLocation location) {
|
||||
return Optional.ofNullable(itemInfosMap.get(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EquipmentClientInfo> getEquipmentInfo(ResourceKey<EquipmentAsset> key) {
|
||||
return Optional.empty(); // TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.geysermc.rainbow.datagen.mixin;
|
||||
|
||||
import net.minecraft.client.renderer.item.ClientItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(targets = "net.minecraft.client.data.models.ModelProvider$ItemInfoCollector")
|
||||
public interface ItemInfoCollectorAccessor {
|
||||
|
||||
@Accessor
|
||||
Map<Item, ClientItem> getItemInfos();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.geysermc.rainbow.datagen.mixin;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.minecraft.client.data.models.ModelProvider;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import org.geysermc.rainbow.datagen.RainbowModelProvider;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(ModelProvider.class)
|
||||
public abstract class ModelProviderMixin implements DataProvider {
|
||||
|
||||
@WrapOperation(method = "run", at = @At(value = "NEW", target = "Lnet/minecraft/client/data/models/ModelProvider$ItemInfoCollector;"))
|
||||
public Object setItemInfosInRainbowModelProvider(Operation<?> original) {
|
||||
Object itemInfoCollector = original.call();
|
||||
if ((Object) this instanceof RainbowModelProvider rainbowModelProvider) {
|
||||
rainbowModelProvider.setItemInfosMap(((ItemInfoCollectorAccessor) itemInfoCollector).getItemInfos());
|
||||
}
|
||||
return itemInfoCollector;
|
||||
}
|
||||
|
||||
@WrapOperation(method = "run", at = @At(value = "NEW", target = "Lnet/minecraft/client/data/models/ModelProvider$SimpleModelCollector;"))
|
||||
public Object setModelsInRainbowModelProvider(Operation<?> original) {
|
||||
Object simpleModelCollector = original.call();
|
||||
if ((Object) this instanceof RainbowModelProvider rainbowModelProvider) {
|
||||
rainbowModelProvider.setModels(((SimpleModelCollectorAccessor) simpleModelCollector).getModels());
|
||||
}
|
||||
return simpleModelCollector;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.geysermc.rainbow.datagen.mixin;
|
||||
|
||||
import net.minecraft.client.data.models.model.ModelInstance;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(targets = "net.minecraft.client.data.models.ModelProvider$SimpleModelCollector")
|
||||
public interface SimpleModelCollectorAccessor {
|
||||
|
||||
@Accessor
|
||||
Map<ResourceLocation, ModelInstance> getModels();
|
||||
}
|
||||
30
datagen/src/main/resources/fabric.mod.json
Normal file
30
datagen/src/main/resources/fabric.mod.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "rainbow-datagen",
|
||||
"version": "${version}",
|
||||
"name": "Rainbow",
|
||||
"description": "Rainbow is a mod to generate Geyser item mappings and bedrock resourcepacks for use with Geyser's custom item API (v2)",
|
||||
"authors": [
|
||||
"GeyserMC contributors"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://github.com/GeyserMC/rainbow",
|
||||
"issues": "https://github.com/GeyserMC/rainbow/issues",
|
||||
"sources": "https://github.com/GeyserMC/rainbow"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "client",
|
||||
"mixins": [],
|
||||
"depends": {
|
||||
"fabricloader": ">=${loader_version}",
|
||||
"fabric-api": "*",
|
||||
"minecraft": "${supported_versions}"
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"links": {
|
||||
"modmenu.discord": "https://discord.gg/GeyserMC"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
datagen/src/main/resources/rainbow-datagen.mixins.json
Normal file
14
datagen/src/main/resources/rainbow-datagen.mixins.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "org.geysermc.rainbow.datagen.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"client": [
|
||||
"ItemInfoCollectorAccessor",
|
||||
"ModelProviderMixin",
|
||||
"SimpleModelCollectorAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
"sources": "https://github.com/GeyserMC/rainbow"
|
||||
},
|
||||
"license": "MIT",
|
||||
"icon": "assets/rainbow/icon.png",
|
||||
"environment": "client",
|
||||
"mixins": [
|
||||
"rainbow.mixins.json"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"minVersion": "0.8",
|
||||
"package": "org.geysermc.rainbow.mixin",
|
||||
"compatibilityLevel": "JAVA_21",
|
||||
"mixins": [],
|
||||
"client": [
|
||||
"LateBoundIdMapperAccessor",
|
||||
"RangeSelectItemModelAccessor",
|
||||
|
||||
@@ -11,5 +11,6 @@ pluginManagement {
|
||||
|
||||
include(":rainbow")
|
||||
include(":client")
|
||||
include(":datagen")
|
||||
|
||||
rootProject.name = "rainbow-parent"
|
||||
|
||||
Reference in New Issue
Block a user