mirror of
https://github.com/GeyserMC/Rainbow.git
synced 2025-12-20 15:29:27 +00:00
Work on problem reporting
This commit is contained in:
@@ -27,6 +27,7 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
|
|
||||||
private final List<String> pendingPackCommands = new ArrayList<>();
|
private final List<String> pendingPackCommands = new ArrayList<>();
|
||||||
private boolean waitingOnItem = false;
|
private boolean waitingOnItem = false;
|
||||||
|
private boolean waitingOnClear = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
@@ -50,7 +51,7 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
.then(ClientCommandManager.literal("map")
|
.then(ClientCommandManager.literal("map")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
ItemStack heldItem = context.getSource().getPlayer().getMainHandItem();
|
ItemStack heldItem = context.getSource().getPlayer().getMainHandItem();
|
||||||
PackManager.getInstance().map(heldItem, true);
|
PackManager.getInstance().map(heldItem);
|
||||||
context.getSource().sendFeedback(Component.literal("Added held item to Geyser mappings"));
|
context.getSource().sendFeedback(Component.literal("Added held item to Geyser mappings"));
|
||||||
return 0;
|
return 0;
|
||||||
})
|
})
|
||||||
@@ -59,7 +60,7 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
int mapped = 0;
|
int mapped = 0;
|
||||||
for (ItemStack stack : context.getSource().getPlayer().getInventory()) {
|
for (ItemStack stack : context.getSource().getPlayer().getInventory()) {
|
||||||
if (PackManager.getInstance().map(stack, false)) {
|
if (PackManager.getInstance().map(stack)) {
|
||||||
mapped++;
|
mapped++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,10 +70,8 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
)
|
)
|
||||||
.then(ClientCommandManager.literal("finish")
|
.then(ClientCommandManager.literal("finish")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
try {
|
if (!PackManager.getInstance().finish()) {
|
||||||
PackManager.getInstance().finish();
|
throw new SimpleCommandExceptionType(Component.literal("Errors occurred whilst trying to write the pack to disk!")).create();
|
||||||
} catch (IOException exception) {
|
|
||||||
throw new SimpleCommandExceptionType(Component.literal(exception.getMessage())).create();
|
|
||||||
}
|
}
|
||||||
context.getSource().sendFeedback(Component.literal("Wrote pack to disk"));
|
context.getSource().sendFeedback(Component.literal("Wrote pack to disk"));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -80,8 +79,10 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
)
|
)
|
||||||
.then(ClientCommandManager.literal("auto")
|
.then(ClientCommandManager.literal("auto")
|
||||||
.then(ClientCommandManager.argument("namespace", StringArgumentType.word())
|
.then(ClientCommandManager.argument("namespace", StringArgumentType.word())
|
||||||
|
.then(ClientCommandManager.argument("path", StringArgumentType.string())
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
String namespace = StringArgumentType.getString(context, "namespace");
|
String namespace = StringArgumentType.getString(context, "namespace");
|
||||||
|
String path = StringArgumentType.getString(context, "path");
|
||||||
|
|
||||||
// Duplicated code, this is just to try this out
|
// Duplicated code, this is just to try this out
|
||||||
try {
|
try {
|
||||||
@@ -93,7 +94,7 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
|
|
||||||
// hack
|
// hack
|
||||||
CommandContext<?> suggestionsContext = new CommandContext<>(null,
|
CommandContext<?> suggestionsContext = new CommandContext<>(null,
|
||||||
"loot give @s loot " + namespace + ":",
|
"loot give @s loot " + namespace + ":" + path,
|
||||||
null, null, null, null, null, null, null, false);
|
null, null, null, null, null, null, null, false);
|
||||||
context.getSource().getClient().getConnection().getSuggestionsProvider()
|
context.getSource().getClient().getConnection().getSuggestionsProvider()
|
||||||
.customSuggestion(suggestionsContext)
|
.customSuggestion(suggestionsContext)
|
||||||
@@ -102,12 +103,15 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
ClientTickEvents.START_CLIENT_TICK.register(client -> {
|
ClientTickEvents.START_CLIENT_TICK.register(client -> {
|
||||||
if (!pendingPackCommands.isEmpty() || waitingOnItem) {
|
if (!pendingPackCommands.isEmpty() || waitingOnItem || waitingOnClear) {
|
||||||
if (!waitingOnItem) {
|
if (waitingOnClear && client.player.getInventory().isEmpty()) {
|
||||||
|
waitingOnClear = false;
|
||||||
|
} else if (!waitingOnItem) {
|
||||||
String command = pendingPackCommands.removeFirst();
|
String command = pendingPackCommands.removeFirst();
|
||||||
client.getConnection().send(new ServerboundChatCommandPacket("loot give @s loot " + command));
|
client.getConnection().send(new ServerboundChatCommandPacket("loot give @s loot " + command));
|
||||||
waitingOnItem = true;
|
waitingOnItem = true;
|
||||||
@@ -116,7 +120,7 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
int mapped = 0;
|
int mapped = 0;
|
||||||
for (ItemStack stack : client.player.getInventory()) {
|
for (ItemStack stack : client.player.getInventory()) {
|
||||||
try {
|
try {
|
||||||
if (PackManager.getInstance().map(stack, false)) {
|
if (PackManager.getInstance().map(stack)) {
|
||||||
mapped++;
|
mapped++;
|
||||||
}
|
}
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
@@ -130,11 +134,16 @@ public class GeyserMappingsGenerator implements ClientModInitializer {
|
|||||||
waitingOnItem = false;
|
waitingOnItem = false;
|
||||||
if (pendingPackCommands.isEmpty()) {
|
if (pendingPackCommands.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
PackManager.getInstance().finish();
|
if (!PackManager.getInstance().finish()) {
|
||||||
} catch (IOException | CommandSyntaxException exception) {
|
client.player.displayClientMessage(Component.literal("Errors occurred whilst trying to write the pack to disk!"), false);
|
||||||
throw new RuntimeException(exception);
|
return;
|
||||||
|
}
|
||||||
|
} catch (CommandSyntaxException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
client.player.displayClientMessage(Component.literal("Wrote pack to disk"), false);
|
client.player.displayClientMessage(Component.literal("Wrote pack to disk"), false);
|
||||||
|
} else {
|
||||||
|
waitingOnClear = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,25 +24,17 @@ public final class PackManager {
|
|||||||
currentPack = new BedrockPack(name);
|
currentPack = new BedrockPack(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean map(ItemStack stack, boolean throwOnModelMissing) throws CommandSyntaxException {
|
public boolean map(ItemStack stack) throws CommandSyntaxException {
|
||||||
ensurePackIsCreated();
|
ensurePackIsCreated();
|
||||||
|
|
||||||
try {
|
return currentPack.map(stack);
|
||||||
currentPack.map(stack);
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
if (throwOnModelMissing) {
|
|
||||||
throw new SimpleCommandExceptionType(Component.literal("Item stack does not have a custom model")).create();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finish() throws CommandSyntaxException, IOException {
|
public boolean finish() throws CommandSyntaxException {
|
||||||
ensurePackIsCreated();
|
ensurePackIsCreated();
|
||||||
currentPack.save();
|
boolean success = currentPack.save();
|
||||||
currentPack = null;
|
currentPack = null;
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensurePackIsCreated() throws CommandSyntaxException {
|
private void ensurePackIsCreated() throws CommandSyntaxException {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import net.minecraft.client.renderer.item.properties.select.TrimMaterialProperty
|
|||||||
import net.minecraft.core.component.DataComponentPatch;
|
import net.minecraft.core.component.DataComponentPatch;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.ProblemReporter;
|
||||||
import net.minecraft.world.item.CrossbowItem;
|
import net.minecraft.world.item.CrossbowItem;
|
||||||
import net.minecraft.world.item.equipment.trim.TrimMaterial;
|
import net.minecraft.world.item.equipment.trim.TrimMaterial;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@@ -37,9 +38,10 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class GeyserItemMapper {
|
public class GeyserItemMapper {
|
||||||
|
|
||||||
public static Stream<GeyserMapping> mapItem(ResourceLocation modelLocation, String displayName, int protectionValue, DataComponentPatch componentPatch) {
|
public static Stream<GeyserMapping> mapItem(ResourceLocation modelLocation, String displayName, int protectionValue, DataComponentPatch componentPatch,
|
||||||
MappingContext context = new MappingContext(List.of(), modelLocation, displayName, protectionValue, componentPatch);
|
ProblemReporter reporter) {
|
||||||
ItemModel model = Minecraft.getInstance().getModelManager().getItemModel(modelLocation);
|
ItemModel model = Minecraft.getInstance().getModelManager().getItemModel(modelLocation);
|
||||||
|
MappingContext context = new MappingContext(List.of(), modelLocation, displayName, protectionValue, componentPatch, reporter.forChild(() -> "model " + modelLocation + " "));
|
||||||
return mapItem(model, context);
|
return mapItem(model, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,14 +55,15 @@ public class GeyserItemMapper {
|
|||||||
return Stream.of(context.create(itemModel));
|
return Stream.of(context.create(itemModel));
|
||||||
}
|
}
|
||||||
case ConditionalItemModel conditional -> {
|
case ConditionalItemModel conditional -> {
|
||||||
return mapConditionalModel(conditional, context);
|
return mapConditionalModel(conditional, context.child("condition " + conditional + " "));
|
||||||
}
|
}
|
||||||
case SelectItemModel<?> select -> {
|
case SelectItemModel<?> select -> {
|
||||||
return mapSelectModel(select, context);
|
return mapSelectModel(select, context.child("select " + select + " "));
|
||||||
}
|
}
|
||||||
default -> {}
|
default -> {}
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException("Unable to map item model " + model.getClass());
|
context.reporter.report(() -> "unable to map item model " + model.getClass());
|
||||||
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<GeyserMapping> mapConditionalModel(ConditionalItemModel model, MappingContext context) {
|
private static Stream<GeyserMapping> mapConditionalModel(ConditionalItemModel model, MappingContext context) {
|
||||||
@@ -71,15 +74,19 @@ public class GeyserItemMapper {
|
|||||||
case CustomModelDataProperty customModelData -> new GeyserConditionPredicate.CustomModelData(customModelData.index());
|
case CustomModelDataProperty customModelData -> new GeyserConditionPredicate.CustomModelData(customModelData.index());
|
||||||
case HasComponent hasComponent -> new GeyserConditionPredicate.HasComponent(hasComponent.componentType()); // ignoreDefault property not a thing, we should look into that in Geyser! TODO
|
case HasComponent hasComponent -> new GeyserConditionPredicate.HasComponent(hasComponent.componentType()); // ignoreDefault property not a thing, we should look into that in Geyser! TODO
|
||||||
case FishingRodCast ignored -> GeyserConditionPredicate.FISHING_ROD_CAST;
|
case FishingRodCast ignored -> GeyserConditionPredicate.FISHING_ROD_CAST;
|
||||||
default -> throw new UnsupportedOperationException("Unsupported conditional model property " + property.getClass());
|
default -> null;
|
||||||
};
|
};
|
||||||
|
if (predicateProperty == null) {
|
||||||
|
context.reporter.report(() -> "unsupported conditional model property " + property);
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
ItemModel onTrue = ((ConditionalItemModelAccessor) model).getOnTrue();
|
ItemModel onTrue = ((ConditionalItemModelAccessor) model).getOnTrue();
|
||||||
ItemModel onFalse = ((ConditionalItemModelAccessor) model).getOnFalse();
|
ItemModel onFalse = ((ConditionalItemModelAccessor) model).getOnFalse();
|
||||||
|
|
||||||
return Stream.concat(
|
return Stream.concat(
|
||||||
mapItem(onTrue, context.with(new GeyserConditionPredicate(predicateProperty, true))),
|
mapItem(onTrue, context.with(new GeyserConditionPredicate(predicateProperty, true), "condition on true ")),
|
||||||
mapItem(onFalse, context.with(new GeyserConditionPredicate(predicateProperty, false)))
|
mapItem(onFalse, context.with(new GeyserConditionPredicate(predicateProperty, false), "condition on false "))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,22 +99,32 @@ public class GeyserItemMapper {
|
|||||||
case ContextDimension ignored -> dimension -> new GeyserMatchPredicate.ContextDimension((ResourceKey<Level>) dimension);
|
case ContextDimension ignored -> dimension -> new GeyserMatchPredicate.ContextDimension((ResourceKey<Level>) dimension);
|
||||||
// Why, Mojang?
|
// Why, Mojang?
|
||||||
case net.minecraft.client.renderer.item.properties.select.CustomModelDataProperty customModelData -> string -> new GeyserMatchPredicate.CustomModelData((String) string, customModelData.index());
|
case net.minecraft.client.renderer.item.properties.select.CustomModelDataProperty customModelData -> string -> new GeyserMatchPredicate.CustomModelData((String) string, customModelData.index());
|
||||||
default -> throw new UnsupportedOperationException("Unsupported select model property " + property.getClass());
|
default -> null;
|
||||||
};
|
};
|
||||||
|
if (dataConstructor == null) {
|
||||||
|
context.reporter.report(() -> "unsupported select model property " + property);
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
Object2ObjectMap<T, ItemModel> cases = ((SelectItemModelCasesAccessor<T>) model).geyser_mappings_generator$getCases();
|
Object2ObjectMap<T, ItemModel> cases = ((SelectItemModelCasesAccessor<T>) model).geyser_mappings_generator$getCases();
|
||||||
return Stream.concat(
|
return Stream.concat(
|
||||||
cases.entrySet().stream()
|
cases.entrySet().stream()
|
||||||
.flatMap(caze -> mapItem(caze.getValue(), context.with(new GeyserMatchPredicate(dataConstructor.apply(caze.getKey()))))),
|
.flatMap(caze -> mapItem(caze.getValue(), context.with(new GeyserMatchPredicate(dataConstructor.apply(caze.getKey())), "select case " + caze.getKey() + " "))),
|
||||||
mapItem(cases.defaultReturnValue(), context)
|
mapItem(cases.defaultReturnValue(), context.child("default case "))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private record MappingContext(List<GeyserPredicate> predicateStack, ResourceLocation model, String displayName, int protectionValue, DataComponentPatch componentPatch) {
|
private record MappingContext(List<GeyserPredicate> predicateStack, ResourceLocation model, String displayName, int protectionValue, DataComponentPatch componentPatch,
|
||||||
|
ProblemReporter reporter) {
|
||||||
|
|
||||||
public MappingContext with(GeyserPredicate predicate) {
|
public MappingContext with(GeyserPredicate predicate, String childName) {
|
||||||
return new MappingContext(Stream.concat(predicateStack.stream(), Stream.of(predicate)).toList(), model, displayName, protectionValue, componentPatch);
|
return new MappingContext(Stream.concat(predicateStack.stream(), Stream.of(predicate)).toList(), model, displayName, protectionValue, componentPatch,
|
||||||
|
reporter.forChild(() -> childName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappingContext child(String childName) {
|
||||||
|
return new MappingContext(predicateStack, model, displayName, protectionValue, componentPatch, reporter.forChild(() -> childName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeyserMapping create(ResourceLocation bedrockIdentifier) {
|
public GeyserMapping create(ResourceLocation bedrockIdentifier) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.component.DataComponents;
|
import net.minecraft.core.component.DataComponents;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.ProblemReporter;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import org.geysermc.packgenerator.CodecUtil;
|
import org.geysermc.packgenerator.CodecUtil;
|
||||||
@@ -48,20 +49,25 @@ public class GeyserMappings {
|
|||||||
mappings.put(item, mapping);
|
mappings.put(item, mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void map(ItemStack stack, Consumer<GeyserMapping> mappingConsumer) {
|
public void map(ItemStack stack, ProblemReporter reporter, Consumer<GeyserMapping> mappingConsumer) {
|
||||||
Optional<? extends ResourceLocation> patchedModel = stack.getComponentsPatch().get(DataComponents.ITEM_MODEL);
|
Optional<? extends ResourceLocation> patchedModel = stack.getComponentsPatch().get(DataComponents.ITEM_MODEL);
|
||||||
//noinspection OptionalAssignedToNull - annoying Mojang
|
//noinspection OptionalAssignedToNull - annoying Mojang
|
||||||
if (patchedModel == null || patchedModel.isEmpty()) {
|
if (patchedModel == null || patchedModel.isEmpty()) {
|
||||||
throw new IllegalArgumentException("Item stack does not have a custom model");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLocation model = patchedModel.get();
|
ResourceLocation model = patchedModel.get();
|
||||||
String displayName = stack.getHoverName().getString();
|
String displayName = stack.getHoverName().getString();
|
||||||
int protectionValue = 0; // TODO check the attributes
|
int protectionValue = 0; // TODO check the attributes
|
||||||
|
|
||||||
GeyserItemMapper.mapItem(model, displayName, protectionValue, stack.getComponentsPatch())
|
GeyserItemMapper.mapItem(model, displayName, protectionValue, stack.getComponentsPatch(), reporter)
|
||||||
.forEach(mapping -> {
|
.forEach(mapping -> {
|
||||||
|
try {
|
||||||
map(stack.getItemHolder(), mapping);
|
map(stack.getItemHolder(), mapping);
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
reporter.forChild(() -> "mapping with bedrock identifier " + mapping.bedrockIdentifier() + " ").report(() -> "failed to add mapping to mappings file: " + exception.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
mappingConsumer.accept(mapping);
|
mappingConsumer.accept(mapping);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.geysermc.packgenerator.pack;
|
|||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.ProblemReporter;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.geysermc.packgenerator.CodecUtil;
|
import org.geysermc.packgenerator.CodecUtil;
|
||||||
@@ -10,16 +11,19 @@ import org.geysermc.packgenerator.PackConstants;
|
|||||||
import org.geysermc.packgenerator.mapping.attachable.AttachableMapper;
|
import org.geysermc.packgenerator.mapping.attachable.AttachableMapper;
|
||||||
import org.geysermc.packgenerator.mapping.geyser.GeyserMappings;
|
import org.geysermc.packgenerator.mapping.geyser.GeyserMappings;
|
||||||
import org.geysermc.packgenerator.pack.attachable.BedrockAttachable;
|
import org.geysermc.packgenerator.pack.attachable.BedrockAttachable;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class BedrockPack {
|
public class BedrockPack {
|
||||||
private static final Path EXPORT_DIRECTORY = FabricLoader.getInstance().getGameDir().resolve("geyser");
|
private static final Path EXPORT_DIRECTORY = FabricLoader.getInstance().getGameDir().resolve("geyser");
|
||||||
@@ -30,6 +34,8 @@ public class BedrockPack {
|
|||||||
private static final Path MANIFEST_FILE = Path.of("manifest.json");
|
private static final Path MANIFEST_FILE = Path.of("manifest.json");
|
||||||
private static final Path ITEM_ATLAS_FILE = Path.of("textures/item_texture.json");
|
private static final Path ITEM_ATLAS_FILE = Path.of("textures/item_texture.json");
|
||||||
|
|
||||||
|
private static final Path REPORT_FILE = Path.of("report.txt");
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Path exportPath;
|
private final Path exportPath;
|
||||||
private final Path packPath;
|
private final Path packPath;
|
||||||
@@ -39,22 +45,45 @@ public class BedrockPack {
|
|||||||
private final List<BedrockAttachable> attachables = new ArrayList<>();
|
private final List<BedrockAttachable> attachables = new ArrayList<>();
|
||||||
private final List<ResourceLocation> texturesToExport = new ArrayList<>();
|
private final List<ResourceLocation> texturesToExport = new ArrayList<>();
|
||||||
|
|
||||||
|
private final ProblemReporter.Collector reporter;
|
||||||
|
|
||||||
public BedrockPack(String name) throws IOException {
|
public BedrockPack(String name) throws IOException {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
exportPath = createPackDirectory(name);
|
exportPath = createPackDirectory(name);
|
||||||
packPath = exportPath.resolve(PACK_DIRECTORY);
|
packPath = exportPath.resolve(PACK_DIRECTORY);
|
||||||
mappings = CodecUtil.readOrCompute(GeyserMappings.CODEC, exportPath.resolve(MAPPINGS_FILE), GeyserMappings::new);
|
mappings = CodecUtil.readOrCompute(GeyserMappings.CODEC, exportPath.resolve(MAPPINGS_FILE), GeyserMappings::new);
|
||||||
manifest = CodecUtil.readOrCompute(PackManifest.CODEC, packPath.resolve(MANIFEST_FILE), () -> defaultManifest(name)).increment();
|
manifest = CodecUtil.readOrCompute(PackManifest.CODEC, packPath.resolve(MANIFEST_FILE), () -> defaultManifest(name)).increment();
|
||||||
itemTextures = CodecUtil.readOrCompute(BedrockTextureAtlas.ITEM_ATLAS_CODEC, packPath.resolve(ITEM_ATLAS_FILE),
|
itemTextures = CodecUtil.readOrCompute(BedrockTextureAtlas.ITEM_ATLAS_CODEC, packPath.resolve(ITEM_ATLAS_FILE),
|
||||||
() -> BedrockTextureAtlas.itemAtlas(name, BedrockTextures.builder())).textures().toBuilder();
|
() -> BedrockTextureAtlas.itemAtlas(name, BedrockTextures.builder())).textures().toBuilder();
|
||||||
|
|
||||||
|
reporter = new ProblemReporter.Collector(() -> "Bedrock pack " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String name() {
|
public String name() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void map(ItemStack stack) {
|
public boolean map(ItemStack stack) {
|
||||||
mappings.map(stack, mapping -> {
|
if (stack.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AtomicBoolean problems = new AtomicBoolean();
|
||||||
|
ProblemReporter mapReporter = new ProblemReporter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ProblemReporter forChild(PathElement child) {
|
||||||
|
return reporter.forChild(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void report(Problem problem) {
|
||||||
|
problems.set(true);
|
||||||
|
reporter.report(problem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mappings.map(stack, mapReporter, mapping -> {
|
||||||
// TODO a proper way to get texture from item model
|
// TODO a proper way to get texture from item model
|
||||||
itemTextures.withItemTexture(mapping, mapping.bedrockIdentifier().getPath());
|
itemTextures.withItemTexture(mapping, mapping.bedrockIdentifier().getPath());
|
||||||
ResourceLocation texture = mapping.bedrockIdentifier();
|
ResourceLocation texture = mapping.bedrockIdentifier();
|
||||||
@@ -64,14 +93,27 @@ public class BedrockPack {
|
|||||||
texturesToExport.add(texture);
|
texturesToExport.add(texture);
|
||||||
AttachableMapper.mapItem(stack, mapping.bedrockIdentifier(), texturesToExport::add).ifPresent(attachables::add);
|
AttachableMapper.mapItem(stack, mapping.bedrockIdentifier(), texturesToExport::add).ifPresent(attachables::add);
|
||||||
});
|
});
|
||||||
|
return problems.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() throws IOException {
|
public boolean save() {
|
||||||
|
boolean success = true;
|
||||||
|
|
||||||
|
try {
|
||||||
CodecUtil.trySaveJson(GeyserMappings.CODEC, mappings, exportPath.resolve(MAPPINGS_FILE));
|
CodecUtil.trySaveJson(GeyserMappings.CODEC, mappings, exportPath.resolve(MAPPINGS_FILE));
|
||||||
CodecUtil.trySaveJson(PackManifest.CODEC, manifest, packPath.resolve(MANIFEST_FILE));
|
CodecUtil.trySaveJson(PackManifest.CODEC, manifest, packPath.resolve(MANIFEST_FILE));
|
||||||
CodecUtil.trySaveJson(BedrockTextureAtlas.CODEC, BedrockTextureAtlas.itemAtlas(name, itemTextures), packPath.resolve(ITEM_ATLAS_FILE));
|
CodecUtil.trySaveJson(BedrockTextureAtlas.CODEC, BedrockTextureAtlas.itemAtlas(name, itemTextures), packPath.resolve(ITEM_ATLAS_FILE));
|
||||||
|
} catch (IOException exception) {
|
||||||
|
reporter.forChild(() -> "saving Geyser mappings, pack manifest, and texture atlas ").report(() -> "failed to save to pack: " + exception);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
for (BedrockAttachable attachable : attachables) {
|
for (BedrockAttachable attachable : attachables) {
|
||||||
|
try {
|
||||||
attachable.save(packPath.resolve(ATTACHABLES_DIRECTORY));
|
attachable.save(packPath.resolve(ATTACHABLES_DIRECTORY));
|
||||||
|
} catch (IOException exception) {
|
||||||
|
reporter.forChild(() -> "attachable for bedrock item " + attachable.info().identifier() + " ").report(() -> "failed to save to pack: " + exception);
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ResourceLocation texture : texturesToExport) {
|
for (ResourceLocation texture : texturesToExport) {
|
||||||
@@ -82,10 +124,19 @@ public class BedrockPack {
|
|||||||
try (OutputStream outputTexture = new FileOutputStream(texturePath.toFile())) {
|
try (OutputStream outputTexture = new FileOutputStream(texturePath.toFile())) {
|
||||||
IOUtils.copy(inputTexture, outputTexture);
|
IOUtils.copy(inputTexture, outputTexture);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException exception) {
|
} catch (IOException exception) {
|
||||||
// TODO
|
ResourceLocation finalTexture = texture;
|
||||||
|
reporter.forChild(() -> "texture " + finalTexture + " ").report(() -> "failed to save to pack: " + exception);
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Files.writeString(exportPath.resolve(REPORT_FILE), reporter.getTreeReport());
|
||||||
|
} catch (IOException exception) {
|
||||||
|
// TODO log
|
||||||
|
}
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Path createPackDirectory(String name) throws IOException {
|
private static Path createPackDirectory(String name) throws IOException {
|
||||||
|
|||||||
Reference in New Issue
Block a user