1
0
mirror of https://github.com/GeyserMC/Rainbow.git synced 2025-12-19 14:59:16 +00:00

Make pack saving abstract

This commit is contained in:
Eclipse
2025-10-14 10:59:57 +00:00
parent a38cbdf413
commit 6a1fe997ba
11 changed files with 137 additions and 104 deletions

View File

@@ -6,31 +6,22 @@ import net.minecraft.client.resources.model.EquipmentAssetManager;
import net.minecraft.client.resources.model.EquipmentClientInfo;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.client.resources.model.ResolvedModel;
import net.minecraft.core.HolderLookup;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.world.item.equipment.EquipmentAsset;
import org.geysermc.rainbow.client.accessor.ResolvedModelAccessor;
import org.geysermc.rainbow.client.mixin.EntityRenderDispatcherAccessor;
import org.geysermc.rainbow.mapping.AssetResolver;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;
public class MinecraftAssetResolver implements AssetResolver {
private final ModelManager modelManager;
private final EquipmentAssetManager equipmentAssetManager;
private final ResourceManager resourceManager;
private final HolderLookup.Provider registries;
public MinecraftAssetResolver(Minecraft minecraft) {
modelManager = minecraft.getModelManager();
equipmentAssetManager = ((EntityRenderDispatcherAccessor) minecraft.getEntityRenderDispatcher()).getEquipmentAssets();
resourceManager = minecraft.getResourceManager();
registries = Objects.requireNonNull(minecraft.level).registryAccess();
}
@Override
@@ -47,14 +38,4 @@ public class MinecraftAssetResolver implements AssetResolver {
public Optional<EquipmentClientInfo> getEquipmentInfo(ResourceKey<EquipmentAsset> key) {
return Optional.of(equipmentAssetManager.get(key));
}
@Override
public InputStream getTexture(ResourceLocation location) throws IOException {
return resourceManager.open(location);
}
@Override
public HolderLookup.Provider registries() {
return registries;
}
}

View File

@@ -0,0 +1,60 @@
package org.geysermc.rainbow.client;
import com.google.gson.JsonElement;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.JsonOps;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.core.HolderLookup;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import org.apache.commons.io.IOUtils;
import org.geysermc.rainbow.CodecUtil;
import org.geysermc.rainbow.mapping.PackSerializer;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
public class MinecraftPackSerializer implements PackSerializer {
private final HolderLookup.Provider registries;
private final ResourceManager resourceManager;
public MinecraftPackSerializer(Minecraft minecraft) {
registries = Objects.requireNonNull(minecraft.level).registryAccess();
resourceManager = minecraft.getResourceManager();
}
@Override
public <T> CompletableFuture<?> saveJson(Codec<T> codec, T object, Path path) {
DynamicOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registries);
return CompletableFuture.runAsync(() -> {
try {
CodecUtil.trySaveJson(codec, object, path.resolveSibling(path.getFileName() + ".json"), ops);
} catch (IOException exception) {
// TODO log
}
}, Util.backgroundExecutor().forName("PackSerializer-saveJson"));
}
@Override
public CompletableFuture<?> saveTexture(ResourceLocation texture, Path path) {
return CompletableFuture.runAsync(() -> {
ResourceLocation texturePath = texture.withPath(p -> "textures/" + p + ".png");
try (InputStream inputTexture = resourceManager.open(texturePath)) {
CodecUtil.ensureDirectoryExists(path.getParent());
try (OutputStream outputTexture = new FileOutputStream(path.toFile())) {
IOUtils.copy(inputTexture, outputTexture);
}
} catch (IOException exception) {
// TODO log
}
}, Util.backgroundExecutor().forName("PackSerializer-saveTexture"));
}
}

View File

@@ -18,6 +18,7 @@ import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
public final class PackManager {
@@ -32,7 +33,7 @@ public final class PackManager {
private static final Path EXPORT_DIRECTORY = FabricLoader.getInstance().getGameDir().resolve(Rainbow.MOD_ID);
private static final Path PACK_DIRECTORY = Path.of("pack");
private static final Path MAPPINGS_FILE = Path.of("geyser_mappings.json");
private static final Path MAPPINGS_FILE = Path.of("geyser_mappings");
private static final Path PACK_ZIP_FILE = Path.of("pack.zip");
private static final Path REPORT_FILE = Path.of("report.txt");
@@ -44,7 +45,8 @@ public final class PackManager {
}
Path packDirectory = createPackDirectory(name);
BedrockPack pack = BedrockPack.builder(name, packDirectory.resolve(MAPPINGS_FILE), packDirectory.resolve(PACK_DIRECTORY), new MinecraftAssetResolver(Minecraft.getInstance()))
BedrockPack pack = BedrockPack.builder(name, packDirectory.resolve(MAPPINGS_FILE), packDirectory.resolve(PACK_DIRECTORY),
new MinecraftPackSerializer(Minecraft.getInstance()), new MinecraftAssetResolver(Minecraft.getInstance()))
.withPackZipFile(packDirectory.resolve(PACK_ZIP_FILE))
.withGeometryRenderer(MinecraftGeometryRenderer.INSTANCE)
.reportSuccesses()
@@ -64,17 +66,18 @@ public final class PackManager {
return currentPack.map(pack -> EXPORT_DIRECTORY.resolve(pack.name()));
}
public Optional<Boolean> finish() {
Optional<Boolean> success = currentPack.map(pack -> {
public boolean finish() {
currentPack.map(pack -> {
try {
Files.writeString(getExportPath().orElseThrow().resolve(REPORT_FILE), createPackSummary(pack));
} catch (IOException exception) {
// TODO log
}
return pack.save();
});
}).ifPresent(CompletableFuture::join);
boolean wasPresent = currentPack.isPresent();
currentPack = Optional.empty();
return success;
return wasPresent;
}
private static String createPackSummary(BedrockPack pack) {

View File

@@ -113,14 +113,13 @@ public class PackGeneratorCommand {
.then(ClientCommandManager.literal("finish")
.executes(context -> {
Optional<Path> exportPath = packManager.getExportPath();
packManager.finish().ifPresentOrElse(success -> {
if (!success) {
context.getSource().sendError(Component.translatable("commands.rainbow.pack_finished_error"));
} else {
context.getSource().sendFeedback(Component.translatable("commands.rainbow.pack_finished_successfully")
.withStyle(style -> style.withUnderlined(true).withClickEvent(new ClickEvent.OpenFile(exportPath.orElseThrow()))));
}
}, () -> context.getSource().sendError(NO_PACK_CREATED));
if (packManager.finish()) {
// TODO error when exporting fails
context.getSource().sendFeedback(Component.translatable("commands.rainbow.pack_finished_successfully")
.withStyle(style -> style.withUnderlined(true).withClickEvent(new ClickEvent.OpenFile(exportPath.orElseThrow()))));
} else {
context.getSource().sendError(NO_PACK_CREATED);
}
return 0;
})
)