mirror of
https://github.com/GeyserMC/Rainbow.git
synced 2025-12-19 14:59:16 +00:00
More final tweaks
This commit is contained in:
@@ -8,14 +8,11 @@ import net.minecraft.Util;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.core.HolderLookup;
|
import net.minecraft.core.HolderLookup;
|
||||||
import net.minecraft.resources.RegistryOps;
|
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.CodecUtil;
|
||||||
|
import org.geysermc.rainbow.RainbowIO;
|
||||||
import org.geysermc.rainbow.mapping.PackSerializer;
|
import org.geysermc.rainbow.mapping.PackSerializer;
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -31,26 +28,17 @@ public class MinecraftPackSerializer implements PackSerializer {
|
|||||||
@Override
|
@Override
|
||||||
public <T> CompletableFuture<?> saveJson(Codec<T> codec, T object, Path path) {
|
public <T> CompletableFuture<?> saveJson(Codec<T> codec, T object, Path path) {
|
||||||
DynamicOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registries);
|
DynamicOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registries);
|
||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> RainbowIO.safeIO(() -> CodecUtil.trySaveJson(codec, object, path.resolveSibling(path.getFileName() + ".json"), ops)),
|
||||||
try {
|
Util.backgroundExecutor().forName("PackSerializer-saveJson"));
|
||||||
CodecUtil.trySaveJson(codec, object, path.resolveSibling(path.getFileName() + ".json"), ops);
|
|
||||||
} catch (IOException exception) {
|
|
||||||
// TODO log
|
|
||||||
}
|
|
||||||
}, Util.backgroundExecutor().forName("PackSerializer-saveJson"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<?> saveTexture(byte[] texture, Path path) {
|
public CompletableFuture<?> saveTexture(byte[] texture, Path path) {
|
||||||
return CompletableFuture.runAsync(() -> {
|
return CompletableFuture.runAsync(() -> RainbowIO.safeIO(() -> {
|
||||||
try {
|
CodecUtil.ensureDirectoryExists(path.getParent());
|
||||||
CodecUtil.ensureDirectoryExists(path.getParent());
|
try (OutputStream outputTexture = new FileOutputStream(path.toFile())) {
|
||||||
try (OutputStream outputTexture = new FileOutputStream(path.toFile())) {
|
outputTexture.write(texture);
|
||||||
outputTexture.write(texture);
|
|
||||||
}
|
|
||||||
} catch (IOException exception) {
|
|
||||||
// TODO log
|
|
||||||
}
|
}
|
||||||
}, Util.backgroundExecutor().forName("PackSerializer-saveTexture"));
|
}), Util.backgroundExecutor().forName("PackSerializer-saveTexture"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import net.minecraft.util.RandomSource;
|
|||||||
import net.minecraft.util.StringUtil;
|
import net.minecraft.util.StringUtil;
|
||||||
import org.geysermc.rainbow.CodecUtil;
|
import org.geysermc.rainbow.CodecUtil;
|
||||||
import org.geysermc.rainbow.Rainbow;
|
import org.geysermc.rainbow.Rainbow;
|
||||||
|
import org.geysermc.rainbow.RainbowIO;
|
||||||
import org.geysermc.rainbow.client.mixin.SplashRendererAccessor;
|
import org.geysermc.rainbow.client.mixin.SplashRendererAccessor;
|
||||||
import org.geysermc.rainbow.client.render.MinecraftGeometryRenderer;
|
import org.geysermc.rainbow.client.render.MinecraftGeometryRenderer;
|
||||||
import org.geysermc.rainbow.pack.BedrockItem;
|
import org.geysermc.rainbow.pack.BedrockItem;
|
||||||
@@ -24,7 +25,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public final class PackManager {
|
public final class PackManager {
|
||||||
private static final List<String> PACK_SUMMARY_COMMENTS = List.of("Use the custom item API v2 build!", "bugrock moment", "RORY",
|
private static final List<String> PACK_SUMMARY_COMMENTS = List.of("Use the custom item API v2 build!", "bugrock moment", "RORY",
|
||||||
"use !!plshelp", "rm -rf --no-preserve-root /*", "welcome to the internet!", "beep beep. boop boop?", "FROG", "it is frog day", "it is cat day!",
|
"use !!plshelp", "*message was deleted*", "welcome to the internet!", "beep beep. boop boop?", "FROG", "it is frog day", "it is cat day!",
|
||||||
"eclipse will hear about this.", "you must now say the word 'frog' in the #general channel", "You Just Lost The Game", "you are now breathing manually",
|
"eclipse will hear about this.", "you must now say the word 'frog' in the #general channel", "You Just Lost The Game", "you are now breathing manually",
|
||||||
"you are now blinking manually", "you're eligible for a free hug token! <3", "don't mind me!", "hissss", "Gayser and Floodgayte, my favourite plugins.",
|
"you are now blinking manually", "you're eligible for a free hug token! <3", "don't mind me!", "hissss", "Gayser and Floodgayte, my favourite plugins.",
|
||||||
"meow", "we'll be done here soon™", "got anything else to say?", "we're done now!", "this will be fixed by v6053", "expect it to be done within 180 business days!",
|
"meow", "we'll be done here soon™", "got anything else to say?", "we're done now!", "this will be fixed by v6053", "expect it to be done within 180 business days!",
|
||||||
@@ -69,11 +70,7 @@ public final class PackManager {
|
|||||||
|
|
||||||
public boolean finish() {
|
public boolean finish() {
|
||||||
currentPack.map(pack -> {
|
currentPack.map(pack -> {
|
||||||
try {
|
RainbowIO.safeIO(() -> Files.writeString(getExportPath().orElseThrow().resolve(REPORT_FILE), createPackSummary(pack)));
|
||||||
Files.writeString(getExportPath().orElseThrow().resolve(REPORT_FILE), createPackSummary(pack));
|
|
||||||
} catch (IOException exception) {
|
|
||||||
// TODO log
|
|
||||||
}
|
|
||||||
return pack.save();
|
return pack.save();
|
||||||
}).ifPresent(CompletableFuture::join);
|
}).ifPresent(CompletableFuture::join);
|
||||||
boolean wasPresent = currentPack.isPresent();
|
boolean wasPresent = currentPack.isPresent();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import net.minecraft.util.ProblemReporter;
|
|||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.equipment.EquipmentAsset;
|
import net.minecraft.world.item.equipment.EquipmentAsset;
|
||||||
import org.geysermc.rainbow.Rainbow;
|
import org.geysermc.rainbow.Rainbow;
|
||||||
|
import org.geysermc.rainbow.RainbowIO;
|
||||||
import org.geysermc.rainbow.mapping.AssetResolver;
|
import org.geysermc.rainbow.mapping.AssetResolver;
|
||||||
import org.geysermc.rainbow.mapping.PackSerializer;
|
import org.geysermc.rainbow.mapping.PackSerializer;
|
||||||
import org.geysermc.rainbow.pack.BedrockPack;
|
import org.geysermc.rainbow.pack.BedrockPack;
|
||||||
@@ -125,7 +126,7 @@ public abstract class RainbowModelProvider extends FabricModelProvider {
|
|||||||
try {
|
try {
|
||||||
output.writeIfNeeded(path, texture, HashCode.fromBytes(texture));
|
output.writeIfNeeded(path, texture, HashCode.fromBytes(texture));
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
LOGGER.error("Failed to save file to {}", path, exception);
|
LOGGER.error("Failed to save texture to {}", path, exception);
|
||||||
}
|
}
|
||||||
}, Util.backgroundExecutor().forName("PackSerializer-saveTexture"));
|
}, Util.backgroundExecutor().forName("PackSerializer-saveTexture"));
|
||||||
}
|
}
|
||||||
@@ -153,12 +154,11 @@ public abstract class RainbowModelProvider extends FabricModelProvider {
|
|||||||
public Optional<ResolvedModel> getResolvedModel(ResourceLocation location) {
|
public Optional<ResolvedModel> getResolvedModel(ResourceLocation location) {
|
||||||
return resolvedModelCache.computeIfAbsent(location, key -> Optional.ofNullable(models.get(location))
|
return resolvedModelCache.computeIfAbsent(location, key -> Optional.ofNullable(models.get(location))
|
||||||
.map(instance -> BlockModel.fromStream(new StringReader(instance.get().toString())))
|
.map(instance -> BlockModel.fromStream(new StringReader(instance.get().toString())))
|
||||||
.or(() -> {
|
.or(() -> RainbowIO.safeIO(() -> {
|
||||||
try (BufferedReader reader = resourceManager.openAsReader(location.withPrefix("models/").withSuffix(".json"))) {
|
try (BufferedReader reader = resourceManager.openAsReader(location.withPrefix("models/").withSuffix(".json"))) {
|
||||||
return Optional.of(BlockModel.fromStream(reader));
|
return BlockModel.fromStream(reader);
|
||||||
} catch (IOException ignored) {}
|
}
|
||||||
return Optional.empty();
|
}))
|
||||||
})
|
|
||||||
.map(model -> new ResolvedModel() {
|
.map(model -> new ResolvedModel() {
|
||||||
@Override
|
@Override
|
||||||
public @NotNull UnbakedModel wrapped() {
|
public @NotNull UnbakedModel wrapped() {
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ public class Rainbow {
|
|||||||
return ResourceLocation.fromNamespaceAndPath(MOD_ID, path);
|
return ResourceLocation.fromNamespaceAndPath(MOD_ID, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rename remove file
|
public static String safeResourceLocation(ResourceLocation location) {
|
||||||
public static String fileSafeResourceLocation(ResourceLocation location) {
|
|
||||||
return location.toString().replace(':', '.').replace('/', '_');
|
return location.toString().replace(':', '.').replace('/', '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
51
rainbow/src/main/java/org/geysermc/rainbow/RainbowIO.java
Normal file
51
rainbow/src/main/java/org/geysermc/rainbow/RainbowIO.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package org.geysermc.rainbow;
|
||||||
|
|
||||||
|
import com.mojang.logging.LogUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public final class RainbowIO {
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
|
private RainbowIO() {}
|
||||||
|
|
||||||
|
public static <T> T safeIO(IOSupplier<T> supplier, T defaultValue) {
|
||||||
|
try {
|
||||||
|
return supplier.get();
|
||||||
|
} catch (IOException exception) {
|
||||||
|
LOGGER.error("Failed to perform IO operation!", exception);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Optional<T> safeIO(IOSupplier<T> supplier) {
|
||||||
|
try {
|
||||||
|
return Optional.ofNullable(supplier.get());
|
||||||
|
} catch (IOException exception) {
|
||||||
|
LOGGER.error("Failed to perform IO operation!", exception);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void safeIO(IORunnable runnable) {
|
||||||
|
try {
|
||||||
|
runnable.run();
|
||||||
|
} catch (IOException exception) {
|
||||||
|
LOGGER.error("Failed to perform IO operation!", exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IOSupplier<T> {
|
||||||
|
|
||||||
|
T get() throws IOException;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IORunnable {
|
||||||
|
|
||||||
|
void run() throws IOException;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -61,7 +61,7 @@ public record GeyserBaseDefinition(ResourceLocation bedrockIdentifier, Optional<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String textureName() {
|
public String textureName() {
|
||||||
return bedrockOptions.icon.orElse(Rainbow.fileSafeResourceLocation(bedrockIdentifier));
|
return bedrockOptions.icon.orElse(Rainbow.safeResourceLocation(bedrockIdentifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
public record BedrockOptions(Optional<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue, List<ResourceLocation> tags) {
|
public record BedrockOptions(Optional<String> icon, boolean allowOffhand, boolean displayHandheld, int protectionValue, List<ResourceLocation> tags) {
|
||||||
|
|||||||
@@ -71,9 +71,9 @@ public class BedrockItemMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void tryMapStack(ItemStack stack, int customModelData, ProblemReporter reporter, PackContext context) {
|
public static void tryMapStack(ItemStack stack, int customModelData, ProblemReporter reporter, PackContext context) {
|
||||||
// TODO Improve this, use resouce log in problemreporter
|
ResourceLocation itemModel = stack.get(DataComponents.ITEM_MODEL);
|
||||||
ItemModel.Unbaked vanillaModel = context.assetResolver().getClientItem(stack.get(DataComponents.ITEM_MODEL)).map(ClientItem::model).orElseThrow();
|
ItemModel.Unbaked vanillaModel = context.assetResolver().getClientItem(itemModel).map(ClientItem::model).orElseThrow();
|
||||||
ProblemReporter childReporter = reporter.forChild(() -> "item model " + vanillaModel + " with custom model data " + customModelData + " ");
|
ProblemReporter childReporter = reporter.forChild(() -> "item model " + itemModel + " with custom model data " + customModelData + " ");
|
||||||
if (vanillaModel instanceof RangeSelectItemModel.Unbaked(RangeSelectItemModelProperty property, float scale, List<RangeSelectItemModel.Entry> entries, Optional<ItemModel.Unbaked> fallback)) {
|
if (vanillaModel instanceof RangeSelectItemModel.Unbaked(RangeSelectItemModelProperty property, float scale, List<RangeSelectItemModel.Entry> entries, Optional<ItemModel.Unbaked> fallback)) {
|
||||||
// WHY, Mojang?
|
// WHY, Mojang?
|
||||||
if (property instanceof net.minecraft.client.renderer.item.properties.numeric.CustomModelDataProperty(int index)) {
|
if (property instanceof net.minecraft.client.renderer.item.properties.numeric.CustomModelDataProperty(int index)) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public record BedrockGeometryContext(Optional<Supplier<StitchedGeometry>> geomet
|
|||||||
// This check should probably be done differently (actually check if the model is 2D or 3D)
|
// This check should probably be done differently (actually check if the model is 2D or 3D)
|
||||||
|
|
||||||
ResourceLocation modelLocation = ResourceLocation.parse(model.debugName());
|
ResourceLocation modelLocation = ResourceLocation.parse(model.debugName());
|
||||||
String safeIdentifier = Rainbow.fileSafeResourceLocation(bedrockIdentifier);
|
String safeIdentifier = Rainbow.safeResourceLocation(bedrockIdentifier);
|
||||||
|
|
||||||
geometry = Optional.of(Suppliers.memoize(() -> {
|
geometry = Optional.of(Suppliers.memoize(() -> {
|
||||||
StitchedTextures stitchedTextures = StitchedTextures.stitchModelTextures(textures, context);
|
StitchedTextures stitchedTextures = StitchedTextures.stitchModelTextures(textures, context);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.geysermc.rainbow.mapping.geometry;
|
|||||||
|
|
||||||
import com.mojang.blaze3d.platform.NativeImage;
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.block.model.TextureSlots;
|
import net.minecraft.client.renderer.block.model.TextureSlots;
|
||||||
import net.minecraft.client.renderer.texture.SpriteContents;
|
import net.minecraft.client.renderer.texture.SpriteContents;
|
||||||
import net.minecraft.client.renderer.texture.SpriteLoader;
|
import net.minecraft.client.renderer.texture.SpriteLoader;
|
||||||
@@ -12,12 +11,12 @@ import net.minecraft.client.resources.model.Material;
|
|||||||
import net.minecraft.data.AtlasIds;
|
import net.minecraft.data.AtlasIds;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import org.geysermc.rainbow.Rainbow;
|
import org.geysermc.rainbow.Rainbow;
|
||||||
|
import org.geysermc.rainbow.RainbowIO;
|
||||||
import org.geysermc.rainbow.mapping.PackContext;
|
import org.geysermc.rainbow.mapping.PackContext;
|
||||||
import org.geysermc.rainbow.mixin.SpriteContentsAccessor;
|
import org.geysermc.rainbow.mixin.SpriteContentsAccessor;
|
||||||
import org.geysermc.rainbow.mixin.SpriteLoaderAccessor;
|
import org.geysermc.rainbow.mixin.SpriteLoaderAccessor;
|
||||||
import org.geysermc.rainbow.mixin.TextureSlotsAccessor;
|
import org.geysermc.rainbow.mixin.TextureSlotsAccessor;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -50,20 +49,20 @@ public record StitchedTextures(Map<String, TextureAtlasSprite> sprites, Supplier
|
|||||||
// Atlas ID doesn't matter much here, but BLOCKS is the most appropriate
|
// Atlas ID doesn't matter much here, but BLOCKS is the most appropriate
|
||||||
// Not sure if 1024 should be the max supported texture size, but it seems to work
|
// Not sure if 1024 should be the max supported texture size, but it seems to work
|
||||||
SpriteLoader spriteLoader = new SpriteLoader(AtlasIds.BLOCKS, 1024, 16, 16);
|
SpriteLoader spriteLoader = new SpriteLoader(AtlasIds.BLOCKS, 1024, 16, 16);
|
||||||
List<SpriteContents> sprites = textures.distinct().map(texture -> readSpriteContents(texture, context)).toList();
|
List<SpriteContents> sprites = textures.distinct()
|
||||||
|
.map(texture -> readSpriteContents(texture, context))
|
||||||
|
.<SpriteContents>mapMulti(Optional::ifPresent)
|
||||||
|
.toList();
|
||||||
return ((SpriteLoaderAccessor) spriteLoader).invokeStitch(sprites, 0, Util.backgroundExecutor());
|
return ((SpriteLoaderAccessor) spriteLoader).invokeStitch(sprites, 0, Util.backgroundExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SpriteContents readSpriteContents(ResourceLocation location, PackContext context) {
|
private static Optional<SpriteContents> readSpriteContents(ResourceLocation location, PackContext context) {
|
||||||
// TODO decorate path util
|
return RainbowIO.safeIO(() -> {
|
||||||
// TODO don't use ResourceManager
|
try (InputStream textureStream = context.assetResolver().openAsset(Rainbow.decorateTextureLocation(location))) {
|
||||||
// TODO IO is on main thread here?
|
NativeImage texture = NativeImage.read(textureStream);
|
||||||
try (InputStream textureStream = context.assetResolver().openAsset(Rainbow.decorateTextureLocation(location))) {
|
return new SpriteContents(location, new FrameSize(texture.getWidth(), texture.getHeight()), texture);
|
||||||
NativeImage texture = NativeImage.read(textureStream);
|
}
|
||||||
return new SpriteContents(location, new FrameSize(texture.getWidth(), texture.getHeight()), texture);
|
});
|
||||||
} catch (IOException exception) {
|
|
||||||
throw new RuntimeException(exception);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NativeImage stitchTextureAtlas(SpriteLoader.Preparations preparations) {
|
private static NativeImage stitchTextureAtlas(SpriteLoader.Preparations preparations) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public record BedrockItem(ResourceLocation identifier, String textureName, Bedro
|
|||||||
CompletableFuture.allOf(attachableTextures.stream().map(textureSaver).toArray(CompletableFuture[]::new)),
|
CompletableFuture.allOf(attachableTextures.stream().map(textureSaver).toArray(CompletableFuture[]::new)),
|
||||||
stitchedGeometry.map(StitchedGeometry::geometry).map(geometry -> geometry.save(serializer, geometryDirectory)).orElse(noop()),
|
stitchedGeometry.map(StitchedGeometry::geometry).map(geometry -> geometry.save(serializer, geometryDirectory)).orElse(noop()),
|
||||||
stitchedGeometry.map(StitchedGeometry::stitchedTextures).map(textureSaver).orElse(noop()),
|
stitchedGeometry.map(StitchedGeometry::stitchedTextures).map(textureSaver).orElse(noop()),
|
||||||
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.fileSafeResourceLocation(identifier))).orElse(noop())
|
geometryContext.animation().map(context -> context.animation().save(serializer, animationDirectory, Rainbow.safeResourceLocation(identifier))).orElse(noop())
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import net.minecraft.world.item.component.CustomModelData;
|
|||||||
import org.geysermc.rainbow.CodecUtil;
|
import org.geysermc.rainbow.CodecUtil;
|
||||||
import org.geysermc.rainbow.PackConstants;
|
import org.geysermc.rainbow.PackConstants;
|
||||||
import org.geysermc.rainbow.Rainbow;
|
import org.geysermc.rainbow.Rainbow;
|
||||||
|
import org.geysermc.rainbow.RainbowIO;
|
||||||
import org.geysermc.rainbow.image.NativeImageUtil;
|
import org.geysermc.rainbow.image.NativeImageUtil;
|
||||||
import org.geysermc.rainbow.mapping.AssetResolver;
|
import org.geysermc.rainbow.mapping.AssetResolver;
|
||||||
import org.geysermc.rainbow.mapping.BedrockItemMapper;
|
import org.geysermc.rainbow.mapping.BedrockItemMapper;
|
||||||
@@ -131,22 +132,12 @@ public class BedrockPack {
|
|||||||
Function<TextureHolder, CompletableFuture<?>> textureSaver = texture -> {
|
Function<TextureHolder, CompletableFuture<?>> textureSaver = texture -> {
|
||||||
ResourceLocation textureLocation = Rainbow.decorateTextureLocation(texture.location());
|
ResourceLocation textureLocation = Rainbow.decorateTextureLocation(texture.location());
|
||||||
return texture.supplier()
|
return texture.supplier()
|
||||||
.flatMap(image -> {
|
.flatMap(image -> RainbowIO.safeIO(() -> NativeImageUtil.writeToByteArray(image.get())))
|
||||||
try {
|
.or(() -> RainbowIO.safeIO(() -> {
|
||||||
return Optional.of(NativeImageUtil.writeToByteArray(image.get()));
|
|
||||||
} catch (IOException exception) {
|
|
||||||
// TODO log
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.or(() -> {
|
|
||||||
try (InputStream textureStream = context.assetResolver().openAsset(textureLocation)) {
|
try (InputStream textureStream = context.assetResolver().openAsset(textureLocation)) {
|
||||||
return Optional.of(textureStream.readAllBytes());
|
return textureStream.readAllBytes();
|
||||||
} catch (IOException exception) {
|
|
||||||
// TODO log
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
.map(bytes -> serializer.saveTexture(bytes, paths.packRoot().resolve(textureLocation.getPath())))
|
.map(bytes -> serializer.saveTexture(bytes, paths.packRoot().resolve(textureLocation.getPath())))
|
||||||
.orElse(CompletableFuture.completedFuture(null));
|
.orElse(CompletableFuture.completedFuture(null));
|
||||||
};
|
};
|
||||||
@@ -156,11 +147,7 @@ public class BedrockPack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (paths.zipOutput().isPresent()) {
|
if (paths.zipOutput().isPresent()) {
|
||||||
try {
|
RainbowIO.safeIO(() -> CodecUtil.tryZipDirectory(paths.packRoot(), paths.zipOutput().get()));
|
||||||
CodecUtil.tryZipDirectory(paths.packRoot(), paths.zipOutput().get());
|
|
||||||
} catch (IOException exception) {
|
|
||||||
// TODO log
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reporter instanceof AutoCloseable closeable) {
|
if (reporter instanceof AutoCloseable closeable) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public record BedrockAttachable(BedrockVersion formatVersion, AttachableInfo inf
|
|||||||
|
|
||||||
public CompletableFuture<?> save(PackSerializer serializer, Path attachablesDirectory) {
|
public CompletableFuture<?> save(PackSerializer serializer, Path attachablesDirectory) {
|
||||||
// Get a safe attachable path by using Geyser's way of getting icons
|
// Get a safe attachable path by using Geyser's way of getting icons
|
||||||
return serializer.saveJson(CODEC, this, attachablesDirectory.resolve(Rainbow.fileSafeResourceLocation(info.identifier) + ".json"));
|
return serializer.saveJson(CODEC, this, attachablesDirectory.resolve(Rainbow.safeResourceLocation(info.identifier) + ".json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder(ResourceLocation identifier) {
|
public static Builder builder(ResourceLocation identifier) {
|
||||||
|
|||||||
Reference in New Issue
Block a user