Skip to content

Commit

Permalink
Add super simple ResourceManager implementation
Browse files Browse the repository at this point in the history
Add back `assetIndex`/`assetsDir` to `clientData` run config args
Add back `DataGeneratorTest` sound/particle tests making use of new resource manager
  • Loading branch information
ApexModder committed Dec 25, 2024
1 parent 9bc22d4 commit 099263e
Show file tree
Hide file tree
Showing 7 changed files with 328 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void writeUserDevConfig() throws IOException {
"--version", getNeoForgeVersion().get());
}

if (runType == RunType.CLIENT || runType == RunType.JUNIT) {
if (runType == RunType.CLIENT || runType == RunType.CLIENT_DATA || runType == RunType.JUNIT) {
Collections.addAll(args,
"--assetIndex", "{asset_index}",
"--assetsDir", "{assets_root}");
Expand Down
6 changes: 4 additions & 2 deletions patches/net/minecraft/client/data/Main.java.patch
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
--- a/net/minecraft/client/data/Main.java
+++ b/net/minecraft/client/data/Main.java
@@ -30,16 +_,27 @@
@@ -30,16 +_,29 @@
OptionSpec<Void> optionspec1 = optionparser.accepts("client", "Include client generators");
OptionSpec<Void> optionspec2 = optionparser.accepts("all", "Include all generators");
OptionSpec<String> optionspec3 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated");
+ optionparser.accepts("gameDir").withRequiredArg().ofType(java.io.File.class).defaultsTo(new java.io.File(".")).required(); //Need by modlauncher, so lets just eat it
+ OptionSpec<String> mod = optionparser.accepts("mod", "A modid to dump").withRequiredArg().withValuesSeparatedBy(",");
+ OptionSpec<Void> flat = optionparser.accepts("flat", "Do not append modid prefix to output directory when generating for multiple mods");
+ OptionSpec<String> assetIndex = optionparser.accepts("assetIndex").withRequiredArg();
+ OptionSpec<java.io.File> assetsDir = optionparser.accepts("assetsDir").withRequiredArg().ofType(java.io.File.class);
+ OptionSpec<Void> validateSpec = optionparser.accepts("validate", "Validate inputs");
OptionSet optionset = optionparser.parse(p_388033_);
if (!optionset.has(optionspec) && optionset.hasOptions()) {
Expand All @@ -24,7 +26,7 @@
addClientProviders(datagenerator, flag1);
- datagenerator.run();
+ }
+ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, java.util.List.of(), false, false, validate, isFlat, () -> {
+ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, java.util.List.of(), false, false, validate, isFlat, optionset.valueOf(assetIndex), optionset.valueOf(assetsDir), () -> {
+ ClientBootstrap.bootstrap();
+ net.neoforged.neoforge.client.ClientHooks.registerSpriteSourceTypes();
+ net.neoforged.neoforge.client.entity.animation.json.AnimationTypeManager.init();
Expand Down
2 changes: 1 addition & 1 deletion patches/net/minecraft/data/Main.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
addServerProviders(datagenerator, collection, flag1, flag2, flag3);
- datagenerator.run();
+ }
+ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, collection, flag2, flag3, validate, isFlat, () -> {},
+ net.neoforged.neoforge.data.loading.DatagenModLoader.begin(mods, path, collection, flag2, flag3, validate, isFlat, null, null, () -> {},
+ net.neoforged.neoforge.data.event.GatherDataEvent.Server::new, datagenerator);
} else {
optionparser.printHelpOn(System.out);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.common.data;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import net.minecraft.client.resources.ClientPackSource;
import net.minecraft.client.resources.IndexedAssetSource;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.PackLocationInfo;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.repository.PackSource;
import net.minecraft.server.packs.repository.ServerPacksSource;
import net.minecraft.server.packs.resources.FallbackResourceManager;
import net.minecraft.server.packs.resources.Resource;
import net.minecraft.server.packs.resources.ResourceManager;
import net.neoforged.fml.ModList;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.resource.ResourcePackLoader;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

/**
* Simple {@link ResourceManager} implementation for looking up resources at runtime during data generation.
* <p>
* This resource manager can be used to lookup any asset/data file at runtime, assuming that the respective mod is loaded.
* <p>
* Do take note that under server data-gen runs, most of Minecraft's assets will be missing due to {@link ClientPackSource} being client only.
*
* @see ResourceManager
*/
public final class DataResourceManager {
private final FallbackResourceManager client = new FallbackResourceManager(PackType.CLIENT_RESOURCES, "minecraft");
private final FallbackResourceManager server = new FallbackResourceManager(PackType.SERVER_DATA, "minecraft");

@ApiStatus.Internal
public DataResourceManager(@Nullable String assetIndex, @Nullable File assetsDir) {
if (FMLEnvironment.dist.isClient() && assetIndex != null && assetsDir != null)
client.push(ClientPackSource.createVanillaPackSource(IndexedAssetSource.createIndexFs(assetsDir.toPath(), assetIndex)));

server.push(ServerPacksSource.createVanillaPackSource());

ModList.get().forEachModInOrder(mod -> {
var packInfo = new PackLocationInfo("mod/" + mod.getModId(), Component.empty(), PackSource.BUILT_IN, Optional.empty());
var modPack = ResourcePackLoader.createPackForMod(mod.getModInfo().getOwningFile()).openPrimary(packInfo);

client.push(modPack);
server.push(modPack);
});
}

private ResourceManager manager(PackType packType) {
return switch (packType) {
case CLIENT_RESOURCES -> client;
case SERVER_DATA -> server;
};
}

public Optional<Resource> getResource(PackType packType, ResourceLocation path) {
return manager(packType).getResource(path);
}

public boolean exists(PackType packType, ResourceLocation path) {
return getResource(packType, path).isPresent();
}

public Resource getResourceOrThrow(PackType packType, ResourceLocation path) throws FileNotFoundException {
return getResource(packType, path).orElseThrow(() -> new FileNotFoundException("Missing " + name(packType) + " resource " + path));
}

public InputStream open(PackType packType, ResourceLocation path) throws IOException {
return getResourceOrThrow(packType, path).open();
}

public BufferedReader openAsReader(PackType packType, ResourceLocation path) throws IOException {
return getResourceOrThrow(packType, path).openAsReader();
}

public List<Resource> getResourceStack(PackType packType, ResourceLocation path) {
return manager(packType).getResourceStack(path);
}

public Map<ResourceLocation, Resource> listResources(PackType packType, String path, Predicate<ResourceLocation> filter) {
return manager(packType).listResources(path, filter);
}

public Map<ResourceLocation, List<Resource>> listResourceStacks(PackType packType, String path, Predicate<ResourceLocation> filter) {
return manager(packType).listResourceStacks(path, filter);
}

private static String name(PackType packType) {
return switch (packType) {
case CLIENT_RESOURCES -> "client";
case SERVER_DATA -> "server";
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.neoforged.bus.api.Event;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.event.IModBusEvent;
import net.neoforged.neoforge.common.data.DataResourceManager;

public abstract class GatherDataEvent extends Event implements IModBusEvent {
private final DataGenerator dataGenerator;
Expand All @@ -44,6 +45,10 @@ public ModContainer getModContainer() {
return this.modContainer;
}

public DataResourceManager getResourceManager() {
return config.resourceManager;
}

public Collection<Path> getInputs() {
return this.config.getInputs();
}
Expand Down Expand Up @@ -90,9 +95,10 @@ public static class DataGeneratorConfig {
private final boolean validate;
private final boolean flat;
private final List<DataGenerator> generators = new ArrayList<>();
private final DataResourceManager resourceManager;

public DataGeneratorConfig(final Set<String> mods, final Path path, final Collection<Path> inputs, final CompletableFuture<HolderLookup.Provider> lookupProvider,
final boolean dev, final boolean reports, final boolean validate, final boolean flat, final DataGenerator vanillaGenerator) {
final boolean dev, final boolean reports, final boolean validate, final boolean flat, final DataGenerator vanillaGenerator, final DataResourceManager resourceManager) {
this.mods = mods;
this.path = path;
this.inputs = inputs;
Expand All @@ -101,6 +107,7 @@ public DataGeneratorConfig(final Set<String> mods, final Path path, final Collec
this.reports = reports;
this.validate = validate;
this.flat = flat;
this.resourceManager = resourceManager;
if (mods.contains("minecraft") || mods.isEmpty()) {
this.generators.add(vanillaGenerator);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package net.neoforged.neoforge.data.loading;

import java.io.File;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Set;
Expand All @@ -15,12 +16,14 @@
import net.minecraft.data.registries.VanillaRegistries;
import net.minecraft.server.Bootstrap;
import net.neoforged.fml.ModLoader;
import net.neoforged.neoforge.common.data.DataResourceManager;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import net.neoforged.neoforge.internal.CommonModLoader;
import net.neoforged.neoforge.internal.RegistrationEvents;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

public class DatagenModLoader extends CommonModLoader {
private static final Logger LOGGER = LogManager.getLogger();
Expand All @@ -34,7 +37,7 @@ public static boolean isRunningDataGen() {
@ApiStatus.Internal
public static void begin(final Set<String> mods, final Path path, final Collection<Path> inputs,
final boolean devToolGenerators, final boolean reportsGenerator,
final boolean structureValidator, final boolean flat, Runnable setup, GatherDataEvent.GatherDataEventGenerator eventGenerator,
final boolean structureValidator, final boolean flat, @Nullable final String assetIndex, @Nullable final File assetsDir, Runnable setup, GatherDataEvent.GatherDataEventGenerator eventGenerator,
DataGenerator vanillaGenerator) {
if (mods.contains("minecraft") && mods.size() == 1)
return;
Expand All @@ -45,7 +48,7 @@ public static void begin(final Set<String> mods, final Path path, final Collecti
// Modify components as the (modified) defaults may be required in datagen, i.e. stack size
RegistrationEvents.modifyComponents();
CompletableFuture<HolderLookup.Provider> lookupProvider = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor());
dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, lookupProvider, devToolGenerators, reportsGenerator, structureValidator, flat, vanillaGenerator);
dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, lookupProvider, devToolGenerators, reportsGenerator, structureValidator, flat, vanillaGenerator, new DataResourceManager(assetIndex, assetsDir));
setup.run();
ModLoader.runEventGenerator(mc -> eventGenerator.create(mc, dataGeneratorConfig.makeGenerator(p -> dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()),
dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig));
Expand Down
Loading

0 comments on commit 099263e

Please sign in to comment.