mirror of
https://github.com/GeyserMC/PackConverter.git
synced 2025-12-21 07:49:17 +00:00
Split conversion process into 3 parts, make converters more standalone (#42)
* Work on splitting converters * Properly split converting of sound registries and sounds * Testing stuff * Implement splitting of texture conversion, still some things to do * Add bedrock pack back to TransformContext * Transition * AssetCollector -> AssetCombiner * Remove unnecessary interfaces * Re-implement action listeners * Final things * Cleanup * Some Javadocs, fixup copyright * Relocate pipeline classes and rename converter package -> type, create KeyUtil to lessen code warnings
This commit is contained in:
@@ -28,7 +28,7 @@ package org.geysermc.pack.converter.bootstrap;
|
|||||||
|
|
||||||
import com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme;
|
import com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme;
|
||||||
import org.geysermc.pack.converter.PackConverter;
|
import org.geysermc.pack.converter.PackConverter;
|
||||||
import org.geysermc.pack.converter.converter.Converters;
|
import org.geysermc.pack.converter.pipeline.AssetConverters;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -77,7 +77,7 @@ public class Main {
|
|||||||
.input(Path.of(inputPath))
|
.input(Path.of(inputPath))
|
||||||
.output(Path.of(outputPath))
|
.output(Path.of(outputPath))
|
||||||
.packName(packName)
|
.packName(packName)
|
||||||
.converters(Converters.defaultConverters(debug))
|
.converters(AssetConverters.converters(debug))
|
||||||
.convert()
|
.convert()
|
||||||
.pack();
|
.pack();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ package org.geysermc.pack.converter.bootstrap;
|
|||||||
|
|
||||||
import com.twelvemonkeys.image.BufferedImageIcon;
|
import com.twelvemonkeys.image.BufferedImageIcon;
|
||||||
import org.geysermc.pack.converter.PackConverter;
|
import org.geysermc.pack.converter.PackConverter;
|
||||||
import org.geysermc.pack.converter.converter.Converters;
|
import org.geysermc.pack.converter.pipeline.AssetConverters;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
import org.geysermc.pack.converter.util.ZipUtils;
|
import org.geysermc.pack.converter.util.ZipUtils;
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ public class ThunderGUI extends JFrame {
|
|||||||
.output(outputPath)
|
.output(outputPath)
|
||||||
.packName(packName.getText().isBlank() ? inputPath.getFileName().toString() : packName.getText())
|
.packName(packName.getText().isBlank() ? inputPath.getFileName().toString() : packName.getText())
|
||||||
.vanillaPackPath(vanillaPackPath)
|
.vanillaPackPath(vanillaPackPath)
|
||||||
.converters(Converters.defaultConverters(this.debugMode.get()))
|
.converters(AssetConverters.converters(this.debugMode.get()))
|
||||||
.logListener(logListener)
|
.logListener(logListener)
|
||||||
.convert()
|
.convert()
|
||||||
.pack();
|
.pack();
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter;
|
|
||||||
|
|
||||||
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
|
||||||
import org.geysermc.pack.converter.data.ConversionData;
|
|
||||||
import org.geysermc.pack.converter.util.LogListener;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public record PackConversionContext<T extends ConversionData>(
|
|
||||||
@NotNull T data,
|
|
||||||
@NotNull PackConverter packConverter,
|
|
||||||
@NotNull ResourcePack javaResourcePack,
|
|
||||||
@NotNull BedrockResourcePack bedrockResourcePack,
|
|
||||||
@NotNull LogListener logListener) {
|
|
||||||
|
|
||||||
public Path inputDirectory() {
|
|
||||||
return this.data.inputDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Path outputDirectory() {
|
|
||||||
return this.data.outputDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void debug(@NotNull String message) {
|
|
||||||
this.logListener.debug(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void info(@NotNull String message) {
|
|
||||||
this.logListener.info(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void warn(@NotNull String message) {
|
|
||||||
this.logListener.warn(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void error(@NotNull String message) {
|
|
||||||
this.logListener.error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void error(@NotNull String message, @NotNull Throwable exception) {
|
|
||||||
this.logListener.error(message, exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,10 +28,12 @@ package org.geysermc.pack.converter;
|
|||||||
|
|
||||||
import org.apache.commons.io.file.PathUtils;
|
import org.apache.commons.io.file.PathUtils;
|
||||||
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
import org.geysermc.pack.converter.converter.ActionListener;
|
import org.geysermc.pack.converter.pipeline.ConverterPipeline;
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
import org.geysermc.pack.converter.util.DefaultLogListener;
|
||||||
import org.geysermc.pack.converter.data.ConversionData;
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
import org.geysermc.pack.converter.util.*;
|
import org.geysermc.pack.converter.util.NioDirectoryFileTreeReader;
|
||||||
|
import org.geysermc.pack.converter.util.VanillaPackProvider;
|
||||||
|
import org.geysermc.pack.converter.util.ZipUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import team.unnamed.creative.ResourcePack;
|
import team.unnamed.creative.ResourcePack;
|
||||||
@@ -43,9 +45,8 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Optional;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,11 +64,9 @@ public final class PackConverter {
|
|||||||
private boolean compressed;
|
private boolean compressed;
|
||||||
private boolean enforcePackCheck = false;
|
private boolean enforcePackCheck = false;
|
||||||
|
|
||||||
private final Map<Class<?>, List<ActionListener<?>>> actionListeners = new IdentityHashMap<>();
|
|
||||||
|
|
||||||
private BiConsumer<ResourcePack, BedrockResourcePack> postProcessor;
|
private BiConsumer<ResourcePack, BedrockResourcePack> postProcessor;
|
||||||
|
|
||||||
private final List<Converter<?>> converters = new ArrayList<>();
|
private final List<ConverterPipeline<?, ?>> converters = new ArrayList<>();
|
||||||
|
|
||||||
private Path tmpDir;
|
private Path tmpDir;
|
||||||
|
|
||||||
@@ -187,7 +186,7 @@ public final class PackConverter {
|
|||||||
* @param converter the converter to add
|
* @param converter the converter to add
|
||||||
* @return this instance
|
* @return this instance
|
||||||
*/
|
*/
|
||||||
public PackConverter converter(@NotNull Converter<?> converter) {
|
public PackConverter converter(@NotNull ConverterPipeline<?, ?> converter) {
|
||||||
this.converters.add(converter);
|
this.converters.add(converter);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -198,7 +197,7 @@ public final class PackConverter {
|
|||||||
* @param converters the converters to add
|
* @param converters the converters to add
|
||||||
* @return this instance
|
* @return this instance
|
||||||
*/
|
*/
|
||||||
public PackConverter converters(@NotNull List<? extends Converter<?>> converters) {
|
public PackConverter converters(@NotNull List<? extends ConverterPipeline<?, ?>> converters) {
|
||||||
this.converters.addAll(converters);
|
this.converters.addAll(converters);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -227,42 +226,6 @@ public final class PackConverter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a list of action listeners for a specific conversion data class.
|
|
||||||
* <p>
|
|
||||||
* This is particularly useful for external programs that may rely on
|
|
||||||
* various bits of information from the pack converter at different
|
|
||||||
* stages.
|
|
||||||
*
|
|
||||||
* @param clazz the conversion data class
|
|
||||||
* @param actionListeners the action listeners
|
|
||||||
* @return this instance
|
|
||||||
* @param <T> the conversion data type
|
|
||||||
*/
|
|
||||||
public <T extends ConversionData> PackConverter actionListeners(@NotNull Class<T> clazz, @NotNull ActionListener<T>... actionListeners) {
|
|
||||||
this.actionListeners.put(clazz, List.of(actionListeners));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the action listeners.
|
|
||||||
* <p>
|
|
||||||
* This is particularly useful for external programs that may rely on
|
|
||||||
* various bits of information from the pack converter at different
|
|
||||||
* stages.
|
|
||||||
*
|
|
||||||
* @param actionListeners the action listeners
|
|
||||||
* @return this instance
|
|
||||||
* @param <T> the conversion data type
|
|
||||||
*/
|
|
||||||
public <T extends ConversionData> PackConverter actionListeners(@NotNull Map<Class<T>, List<ActionListener<T>>> actionListeners) {
|
|
||||||
for (Map.Entry<Class<T>, List<ActionListener<T>>> entry : actionListeners.entrySet()) {
|
|
||||||
this.actionListeners.put(entry.getKey(), (List) entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the post processor for the converted resource pack.
|
* Sets the post processor for the converted resource pack.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -320,25 +283,10 @@ public final class PackConverter {
|
|||||||
ResourcePack vanillaResourcePack = MinecraftResourcePackReader.minecraft().readFromZipFile(vanillaPackPath);
|
ResourcePack vanillaResourcePack = MinecraftResourcePackReader.minecraft().readFromZipFile(vanillaPackPath);
|
||||||
BedrockResourcePack bedrockResourcePack = new BedrockResourcePack(this.tmpDir);
|
BedrockResourcePack bedrockResourcePack = new BedrockResourcePack(this.tmpDir);
|
||||||
|
|
||||||
final Converter.ConversionDataCreationContext conversionDataCreationContext = new Converter.ConversionDataCreationContext(
|
int errors = converters.stream()
|
||||||
this, logListener, input, this.tmpDir, javaResourcePack, vanillaResourcePack
|
.mapToInt(converter -> converter.convert(javaResourcePack, Optional.of(vanillaResourcePack),
|
||||||
);
|
bedrockResourcePack, packName(), textureSubdirectory, logListener))
|
||||||
|
.sum();
|
||||||
int errors = 0;
|
|
||||||
for (Converter converter : this.converters) {
|
|
||||||
ConversionData data = converter.createConversionData(conversionDataCreationContext);
|
|
||||||
PackConversionContext<?> context = new PackConversionContext<>(data, this, javaResourcePack, bedrockResourcePack, this.logListener);
|
|
||||||
|
|
||||||
List<ActionListener<?>> actionListeners = this.actionListeners.getOrDefault(data.getClass(), List.of());
|
|
||||||
try {
|
|
||||||
actionListeners.forEach(actionListener -> actionListener.preConvert((PackConversionContext) context));
|
|
||||||
converter.convert(context);
|
|
||||||
actionListeners.forEach(actionListener -> actionListener.postConvert((PackConversionContext) context));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
this.logListener.error("Error converting pack!", t);
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.postProcessor != null) {
|
if (this.postProcessor != null) {
|
||||||
this.postProcessor.accept(javaResourcePack, bedrockResourcePack);
|
this.postProcessor.accept(javaResourcePack, bedrockResourcePack);
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.lang;
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
|
||||||
import org.geysermc.pack.converter.converter.BaseConverter;
|
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
|
||||||
import org.geysermc.pack.converter.data.BaseConversionData;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.lang.Language;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
|
||||||
public class LangConverter extends BaseConverter {
|
|
||||||
private static final String BEDROCK_TEXTS_LOCATION = "texts";
|
|
||||||
|
|
||||||
private final Pattern positionalStringReplacement = Pattern.compile("%([0-9]+)\\$s");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void convert(@NotNull PackConversionContext<BaseConversionData> context) throws Exception {
|
|
||||||
Collection<Language> languages = context.javaResourcePack().languages();
|
|
||||||
for (Language language : languages) {
|
|
||||||
Map<String, String> strings = language.translations();
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : strings.entrySet()) {
|
|
||||||
String value = entry.getValue();
|
|
||||||
|
|
||||||
// Replace %d with %s
|
|
||||||
value = value.replace("%d", "%s");
|
|
||||||
|
|
||||||
// Replace `%x$s` with `%x`
|
|
||||||
value = positionalStringReplacement.matcher(value).replaceAll("%$1");
|
|
||||||
|
|
||||||
entry.setValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
String languageKey = language.key().value();
|
|
||||||
|
|
||||||
// Convert the language key to the Bedrock equivalent
|
|
||||||
if (languageKey.equals("no_no")) {
|
|
||||||
languageKey = "nb_no";
|
|
||||||
}
|
|
||||||
|
|
||||||
context.bedrockResourcePack().addLanguage(languageKey, strings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,261 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.model;
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import net.kyori.adventure.key.Key;
|
|
||||||
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.ModelEntity;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.Geometry;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.Bones;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.Description;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.Cubes;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.Uv;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.Down;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.East;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.North;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.South;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.Up;
|
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.West;
|
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
|
||||||
import org.geysermc.pack.converter.data.ModelConversionData;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
|
||||||
import team.unnamed.creative.base.CubeFace;
|
|
||||||
import team.unnamed.creative.model.Element;
|
|
||||||
import team.unnamed.creative.model.ElementFace;
|
|
||||||
import team.unnamed.creative.model.ElementRotation;
|
|
||||||
import team.unnamed.creative.model.Model;
|
|
||||||
import team.unnamed.creative.texture.TextureUV;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
|
||||||
public class ModelConverter implements Converter<ModelConversionData> {
|
|
||||||
private static final String FORMAT_VERSION = "1.16.0";
|
|
||||||
private static final String GEOMETRY_FORMAT = "geometry.%s";
|
|
||||||
|
|
||||||
private static final float[] ELEMENT_OFFSET = new float[] { 8, 0, 8 };
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void convert(@NotNull PackConversionContext<ModelConversionData> context) throws Exception {
|
|
||||||
ResourcePack javaPack = context.javaResourcePack();
|
|
||||||
BedrockResourcePack bedrockPack = context.bedrockResourcePack();
|
|
||||||
Collection<Model> models = javaPack.models();
|
|
||||||
if (models.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelStitcher.Provider provider = context.data().getModelProvider();
|
|
||||||
for (Model model : models) {
|
|
||||||
model = new ModelStitcher(provider, model, context.logListener()).stitch();
|
|
||||||
|
|
||||||
List<Element> elements = model.elements();
|
|
||||||
if (elements.isEmpty()) {
|
|
||||||
context.debug("Model " + model.key().key() + " has no elements");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String value = model.key().value();
|
|
||||||
context.debug("Converting model " + model.key().key() + ":" + value);
|
|
||||||
|
|
||||||
// TODO: Convert item models but save differently?
|
|
||||||
if (value.startsWith("item/")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelEntity modelEntity = new ModelEntity();
|
|
||||||
modelEntity.formatVersion(FORMAT_VERSION);
|
|
||||||
|
|
||||||
Geometry geometry = new Geometry();
|
|
||||||
|
|
||||||
String namespace = model.key().namespace();
|
|
||||||
String fileName = value.substring(value.lastIndexOf('/') + 1);
|
|
||||||
|
|
||||||
String geoName = (namespace.equals(Key.MINECRAFT_NAMESPACE) ? "" : namespace + ".") + fileName;
|
|
||||||
|
|
||||||
// TODO: Don't hardcode all this
|
|
||||||
Description description = new Description();
|
|
||||||
description.identifier(String.format(GEOMETRY_FORMAT, geoName));
|
|
||||||
description.textureWidth(16);
|
|
||||||
description.textureHeight(16);
|
|
||||||
description.visibleBoundsWidth(2);
|
|
||||||
description.visibleBoundsHeight(2);
|
|
||||||
description.visibleBoundsOffset(new float[] { 0.0f, 0.25f, 0.0f });
|
|
||||||
geometry.description(description);
|
|
||||||
|
|
||||||
List<Bones> bones = new ArrayList<>();
|
|
||||||
|
|
||||||
// TODO: Should each element be its own bone rather
|
|
||||||
// than its own cube in the same bone?
|
|
||||||
int i = 0;
|
|
||||||
for (Element element : elements) {
|
|
||||||
float[] from = element.from().toArray();
|
|
||||||
float[] to = element.to().toArray();
|
|
||||||
|
|
||||||
Bones bone = new Bones();
|
|
||||||
bone.name("bone_" + i++);
|
|
||||||
bone.pivot(new float[] { ELEMENT_OFFSET[0], ELEMENT_OFFSET[1], -ELEMENT_OFFSET[2] });
|
|
||||||
|
|
||||||
Cubes cube = new Cubes();
|
|
||||||
cube.origin(new float[] { ELEMENT_OFFSET[0] - to[0], from[1], from[2] - ELEMENT_OFFSET[2] });
|
|
||||||
cube.size(new float[] { to[0] - from[0], to[1] - from[1], to[2] - from[2] });
|
|
||||||
|
|
||||||
ElementRotation elementRotation = element.rotation();
|
|
||||||
if (elementRotation != null) {
|
|
||||||
float[] origin = elementRotation.origin().toArray();
|
|
||||||
cube.pivot(new float[] { ELEMENT_OFFSET[0] - origin[0], ELEMENT_OFFSET[1] - origin[1], origin[2] - ELEMENT_OFFSET[2] });
|
|
||||||
|
|
||||||
float angle = elementRotation.angle();
|
|
||||||
float[] rotation = new float[3];
|
|
||||||
switch (elementRotation.axis()) {
|
|
||||||
case X -> rotation[0] = -angle;
|
|
||||||
case Y -> rotation[1] = -angle;
|
|
||||||
case Z -> rotation[2] = -angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
cube.rotation(rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uv uv = new Uv();
|
|
||||||
for (Map.Entry<CubeFace, ElementFace> entry : element.faces().entrySet()) {
|
|
||||||
CubeFace face = entry.getKey();
|
|
||||||
ElementFace elementFace = entry.getValue();
|
|
||||||
if (elementFace.uv0() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Java pack lib we use does this weird thing where it
|
|
||||||
// divides the UV by 16, so we need to multiply it by 16
|
|
||||||
|
|
||||||
String texture = elementFace.texture().replace("#", "");
|
|
||||||
applyUv(uv, face, texture, multiplyUv(elementFace.uv0(), 16f));
|
|
||||||
}
|
|
||||||
|
|
||||||
cube.uv(uv);
|
|
||||||
bone.cubes(List.of(cube));
|
|
||||||
|
|
||||||
bones.add(bone);
|
|
||||||
}
|
|
||||||
|
|
||||||
geometry.bones(bones);
|
|
||||||
|
|
||||||
modelEntity.geometry(List.of(geometry));
|
|
||||||
|
|
||||||
if (model.key().namespace().contains("entity")) {
|
|
||||||
bedrockPack.addEntityModel(modelEntity, fileName + ".json");
|
|
||||||
} else {
|
|
||||||
// Bedrock only has a concept of entity or block models
|
|
||||||
bedrockPack.addBlockModel(modelEntity, fileName + ".json");
|
|
||||||
}
|
|
||||||
|
|
||||||
context.data().addStitchedModel(model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ModelConversionData createConversionData(@NotNull ConversionDataCreationContext context) {
|
|
||||||
return new ModelConversionData(
|
|
||||||
context.inputDirectory(), context.outputDirectory(),
|
|
||||||
ModelStitcher.vanillaProvider(context.javaResourcePack(), context.logListener(), context.vanillaResourcePack()),
|
|
||||||
context.vanillaResourcePack()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextureUV multiplyUv(TextureUV textureUV, float mult) {
|
|
||||||
return TextureUV.uv(textureUV.from().multiply(mult), textureUV.to().multiply(mult));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void applyUv(Uv uv, CubeFace face, String texture, TextureUV faceUv) {
|
|
||||||
float[] uvs;
|
|
||||||
float[] uvSize;
|
|
||||||
|
|
||||||
// These values are flipped for some reason
|
|
||||||
if (face == CubeFace.DOWN || face == CubeFace.UP) {
|
|
||||||
uvs = new float[] { faceUv.to().x(), faceUv.to().y() };
|
|
||||||
uvSize = new float[] { faceUv.from().x() - faceUv.to().x(), faceUv.from().y() - faceUv.to().y() };
|
|
||||||
} else {
|
|
||||||
uvs = new float[] { faceUv.from().x(), faceUv.from().y() };
|
|
||||||
uvSize = new float[] { faceUv.to().x() - faceUv.from().x(), faceUv.to().y() - faceUv.from().y() };
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (face) {
|
|
||||||
case NORTH -> {
|
|
||||||
North north = new North();
|
|
||||||
north.uv(uvs);
|
|
||||||
north.uvSize(uvSize);
|
|
||||||
north.materialInstance(texture);
|
|
||||||
|
|
||||||
uv.north(north);
|
|
||||||
}
|
|
||||||
case SOUTH -> {
|
|
||||||
South south = new South();
|
|
||||||
south.uv(uvs);
|
|
||||||
south.uvSize(uvSize);
|
|
||||||
south.materialInstance(texture);
|
|
||||||
|
|
||||||
uv.south(south);
|
|
||||||
}
|
|
||||||
case EAST -> {
|
|
||||||
East east = new East();
|
|
||||||
east.uv(uvs);
|
|
||||||
east.uvSize(uvSize);
|
|
||||||
east.materialInstance(texture);
|
|
||||||
|
|
||||||
uv.east(east);
|
|
||||||
}
|
|
||||||
case WEST -> {
|
|
||||||
West west = new West();
|
|
||||||
west.uv(uvs);
|
|
||||||
west.uvSize(uvSize);
|
|
||||||
west.materialInstance(texture);
|
|
||||||
|
|
||||||
uv.west(west);
|
|
||||||
}
|
|
||||||
case UP -> {
|
|
||||||
Up up = new Up();
|
|
||||||
up.uv(uvs);
|
|
||||||
up.uvSize(uvSize);
|
|
||||||
up.materialInstance(texture);
|
|
||||||
|
|
||||||
uv.up(up);
|
|
||||||
}
|
|
||||||
case DOWN -> {
|
|
||||||
Down down = new Down();
|
|
||||||
down.uv(uvs);
|
|
||||||
down.uvSize(uvSize);
|
|
||||||
down.materialInstance(texture);
|
|
||||||
|
|
||||||
uv.down(down);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.sound;
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import org.apache.commons.io.file.PathUtils;
|
|
||||||
import org.geysermc.pack.bedrock.resource.sounds.sounddefinitions.SoundDefinitions;
|
|
||||||
import org.geysermc.pack.bedrock.resource.sounds.sounddefinitions.Sounds;
|
|
||||||
import org.geysermc.pack.converter.Constants;
|
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
|
||||||
import org.geysermc.pack.converter.converter.BaseConverter;
|
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
|
||||||
import org.geysermc.pack.converter.data.BaseConversionData;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
|
||||||
import team.unnamed.creative.sound.SoundEntry;
|
|
||||||
import team.unnamed.creative.sound.SoundEvent;
|
|
||||||
import team.unnamed.creative.sound.SoundRegistry;
|
|
||||||
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
|
||||||
public class SoundConverter extends BaseConverter {
|
|
||||||
private static final String JAVA_SOUNDS_LOCATION = Constants.JAVA_PACK_LOCATION + "/sounds";
|
|
||||||
private static final String BEDROCK_SOUNDS_LOCATION = "sounds";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void convert(@NotNull PackConversionContext<BaseConversionData> context) throws Exception {
|
|
||||||
Collection<SoundRegistry> registry = context.javaResourcePack().soundRegistries();
|
|
||||||
for (SoundRegistry soundRegistry : registry) {
|
|
||||||
@Unmodifiable @NotNull Collection<SoundEvent> sounds = soundRegistry.sounds();
|
|
||||||
|
|
||||||
for (SoundEvent value : sounds) {
|
|
||||||
String key = value.key().asString();
|
|
||||||
|
|
||||||
SoundDefinitions definition = new SoundDefinitions();
|
|
||||||
definition.useLegacyMaxDistance(true); // TODO: Needed?
|
|
||||||
definition.maxDistance(64); // ???
|
|
||||||
for (SoundEntry sound : value.sounds()) {
|
|
||||||
Sounds bedrockSound = new Sounds();
|
|
||||||
bedrockSound.name(BEDROCK_SOUNDS_LOCATION + "/" + sound.key().value());
|
|
||||||
bedrockSound.stream(sound.stream());
|
|
||||||
bedrockSound.loadOnLowMemory(true);
|
|
||||||
bedrockSound.volume(sound.volume());
|
|
||||||
bedrockSound.pitch(sound.pitch());
|
|
||||||
bedrockSound.weight(sound.weight());
|
|
||||||
|
|
||||||
definition.sounds().add(bedrockSound);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.bedrockResourcePack().addSoundDefinition(key, definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Relocate sound files
|
|
||||||
Path input = context.inputDirectory().resolve(String.format(JAVA_SOUNDS_LOCATION, soundRegistry.namespace()));
|
|
||||||
Path output = context.outputDirectory().resolve(BEDROCK_SOUNDS_LOCATION);
|
|
||||||
|
|
||||||
if (Files.notExists(output)) {
|
|
||||||
Files.createDirectories(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
PathUtils.copyDirectory(input, output, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture;
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformedTexture;
|
|
||||||
import org.geysermc.pack.converter.data.TextureConversionData;
|
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.texture.Texture;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.AlphaComposite;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ServiceLoader;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
|
||||||
public class TextureConverter implements Converter<TextureConversionData> {
|
|
||||||
public static final String BEDROCK_TEXTURES_LOCATION = "textures";
|
|
||||||
|
|
||||||
private final List<TextureTransformer> transformers = StreamSupport.stream(ServiceLoader.load(TextureTransformer.class).spliterator(), false)
|
|
||||||
.sorted(Comparator.comparingInt(TextureTransformer::order))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
public static final Map<String, String> DIRECTORY_LOCATIONS = Map.of(
|
|
||||||
"block", "blocks",
|
|
||||||
"item", "items",
|
|
||||||
"gui", "ui"
|
|
||||||
);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void convert(@NotNull PackConversionContext<TextureConversionData> context) throws Exception {
|
|
||||||
TextureMappings mappings = TextureMappings.textureMappings();
|
|
||||||
|
|
||||||
List<Texture> textures = new ArrayList<>(context.javaResourcePack().textures());
|
|
||||||
|
|
||||||
context.info("Transforming textures...");
|
|
||||||
TransformContext transformContext = new TransformContext(
|
|
||||||
context,
|
|
||||||
mappings,
|
|
||||||
textures,
|
|
||||||
context.bedrockResourcePack(),
|
|
||||||
context.javaResourcePack()
|
|
||||||
);
|
|
||||||
for (TextureTransformer transformer : this.transformers) {
|
|
||||||
transformer.transform(transformContext);
|
|
||||||
}
|
|
||||||
context.info("Transformed textures!");
|
|
||||||
|
|
||||||
context.info("Writing textures...");
|
|
||||||
|
|
||||||
for (Texture texture : textures) {
|
|
||||||
String input = texture.key().value();
|
|
||||||
Path texturePath = context.outputDirectory().resolve(BEDROCK_TEXTURES_LOCATION);
|
|
||||||
Path potentialOutput = texturePath.resolve(input);
|
|
||||||
String relativePath = texturePath.relativize(potentialOutput).toString().replace(File.separatorChar, '/');
|
|
||||||
|
|
||||||
if (relativePath.endsWith(".png")) relativePath = relativePath.substring(0, relativePath.length() - 4);
|
|
||||||
|
|
||||||
String rootPath = relativePath.substring(0, relativePath.indexOf('/'));
|
|
||||||
String bedrockRoot = DIRECTORY_LOCATIONS.getOrDefault(rootPath, rootPath);
|
|
||||||
|
|
||||||
List<Path> outputs = new ArrayList<>();
|
|
||||||
List<String> outputPaths = new ArrayList<>();
|
|
||||||
|
|
||||||
Object mappingObject = mappings.textures(relativePath);
|
|
||||||
|
|
||||||
if (mappingObject == null) {
|
|
||||||
mappingObject = mappings.textures(rootPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
String fallbackPath = bedrockRoot + "/" + relativePath.substring(relativePath.indexOf('/') + 1) + ".png";
|
|
||||||
if (mappingObject instanceof Map<?,?> keyMappings) { // Handles common subdirectories
|
|
||||||
String sanitizedName = input.substring(input.indexOf('/') + 1);
|
|
||||||
if (sanitizedName.endsWith(".png")) sanitizedName = sanitizedName.substring(0, sanitizedName.length() - 4);
|
|
||||||
|
|
||||||
Object bedrockOutput = keyMappings.get(sanitizedName);
|
|
||||||
if (bedrockOutput instanceof String bedrockPath) {
|
|
||||||
outputPaths.add(bedrockRoot + "/" + bedrockPath + ".png");
|
|
||||||
} else if (bedrockOutput instanceof List<?> paths) {
|
|
||||||
for (String bedrockPath : (List<String>) paths) {
|
|
||||||
outputPaths.add(bedrockRoot + "/" + bedrockPath + ".png");
|
|
||||||
}
|
|
||||||
} else { // Fallback
|
|
||||||
outputPaths.add(fallbackPath);
|
|
||||||
}
|
|
||||||
} else if (mappingObject instanceof String str) { // Direct mappings
|
|
||||||
outputPaths.add(str + ".png");
|
|
||||||
} else if (mappingObject instanceof List<?> paths) { // Mappings where duplicate code paths exist
|
|
||||||
for (String path : (List<String>) paths) {
|
|
||||||
outputPaths.add(path + ".png");
|
|
||||||
}
|
|
||||||
} else { // Fallback
|
|
||||||
outputPaths.add(fallbackPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
String bedrockDirectory = "%s/%s";
|
|
||||||
if (context.data().textureSubdirectory() != null) {
|
|
||||||
bedrockDirectory = "%s/" + context.data().textureSubdirectory() + "/%s";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String outputPath : outputPaths) {
|
|
||||||
context.debug(String.format("Converted %s to %s, writing texture.", input, outputPath));
|
|
||||||
|
|
||||||
String root = outputPath.substring(0, outputPath.indexOf('/'));
|
|
||||||
String value = outputPath.substring(outputPath.indexOf('/') + 1);
|
|
||||||
|
|
||||||
outputs.add(texturePath.resolve((
|
|
||||||
bedrockDirectory.formatted(root, value)
|
|
||||||
).replace('/', File.separatorChar)));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] bytes = texture.data().toByteArray();
|
|
||||||
|
|
||||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
|
|
||||||
|
|
||||||
for (Path output : outputs) {
|
|
||||||
TransformedTexture transformedTexture = new TransformedTexture(texture, output);
|
|
||||||
|
|
||||||
if (output.getParent() != null && Files.notExists(output.getParent())) {
|
|
||||||
Files.createDirectories(output.getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedImage bedrockImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
|
||||||
|
|
||||||
Graphics2D g = bedrockImage.createGraphics();
|
|
||||||
g.setComposite(AlphaComposite.Src);
|
|
||||||
g.drawImage(image, 0, 0, null);
|
|
||||||
g.dispose();
|
|
||||||
|
|
||||||
String pngKey = context.outputDirectory().relativize(output).toString().replace(File.separatorChar, '/');
|
|
||||||
PngToTgaMappings.TgaMapping mapping = PngToTgaMappings.mapping(pngKey);
|
|
||||||
if (mapping != null) {
|
|
||||||
Path tgaPath = context.outputDirectory().resolve(mapping.value());
|
|
||||||
if (Files.notExists(tgaPath.getParent())) {
|
|
||||||
Files.createDirectories(tgaPath.getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageUtil.writeTGA(tgaPath, bedrockImage);
|
|
||||||
if (!mapping.keep()) {
|
|
||||||
Files.deleteIfExists(output);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try (OutputStream stream = Files.newOutputStream(output)) {
|
|
||||||
ImageIO.write(bedrockImage, "png", stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.data().addTransformedTexture(transformedTexture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context.info("Written textures!");
|
|
||||||
|
|
||||||
context.info("Texture conversion complete!");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TextureConversionData createConversionData(@NotNull ConversionDataCreationContext context) {
|
|
||||||
return new TextureConversionData(
|
|
||||||
context.inputDirectory(),
|
|
||||||
context.outputDirectory(),
|
|
||||||
context.converter().textureSubdirectory(),
|
|
||||||
context.vanillaResourcePack()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.data;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
public class BaseConversionData implements ConversionData {
|
|
||||||
private final Path inputDirectory;
|
|
||||||
private final Path outputDirectory;
|
|
||||||
private final ResourcePack vanillaPack;
|
|
||||||
|
|
||||||
public BaseConversionData(@NotNull Path inputDirectory, @NotNull Path outputDirectory, @NotNull ResourcePack vanillaPack) {
|
|
||||||
this.inputDirectory = inputDirectory;
|
|
||||||
this.outputDirectory = outputDirectory;
|
|
||||||
this.vanillaPack = vanillaPack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Path inputDirectory() {
|
|
||||||
return this.inputDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Path outputDirectory() {
|
|
||||||
return this.outputDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public ResourcePack vanillaPack() {
|
|
||||||
return this.vanillaPack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.data;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.kyori.adventure.key.Key;
|
|
||||||
import org.geysermc.pack.converter.converter.model.ModelStitcher;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
|
||||||
import team.unnamed.creative.model.Model;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ModelConversionData extends BaseConversionData {
|
|
||||||
private final Map<Key, Model> stitchedModels = new HashMap<>();
|
|
||||||
@Getter
|
|
||||||
private final ModelStitcher.Provider modelProvider;
|
|
||||||
|
|
||||||
public ModelConversionData(@NotNull Path inputDirectory, @NotNull Path outputDirectory, ModelStitcher.Provider modelProvider, @NotNull ResourcePack vanillaPack) {
|
|
||||||
super(inputDirectory, outputDirectory, vanillaPack);
|
|
||||||
this.modelProvider = modelProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addStitchedModel(@NotNull Model model) {
|
|
||||||
this.stitchedModels.put(model.key(), model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Model model(@NotNull Key key) {
|
|
||||||
return this.stitchedModels.get(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/PackConverter
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.pack.converter.data;
|
|
||||||
|
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformedTexture;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TextureConversionData extends BaseConversionData {
|
|
||||||
private final List<TransformedTexture> transformedTextures = new ArrayList<>();
|
|
||||||
private final String textureSubdirectory;
|
|
||||||
|
|
||||||
public TextureConversionData(@NotNull Path inputDirectory, @NotNull Path outputDirectory, @Nullable String textureSubdirectory, @NotNull ResourcePack vanillaPack) {
|
|
||||||
super(inputDirectory, outputDirectory, vanillaPack);
|
|
||||||
|
|
||||||
this.textureSubdirectory = textureSubdirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTransformedTexture(@NotNull TransformedTexture transformedTexture) {
|
|
||||||
this.transformedTextures.add(transformedTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public List<TransformedTexture> transformedTextures() {
|
|
||||||
return this.transformedTextures;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public String textureSubdirectory() {
|
|
||||||
return this.textureSubdirectory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listeners for actions that occur during execution of a {@link ConverterPipeline}. All implemented listeners should be as pure as possible:
|
||||||
|
* no side effects should occur, and no modifications should be made to received arguments, unless specifically stated this is allowed.
|
||||||
|
*/
|
||||||
|
public interface ActionListener<JavaAsset, BedrockAsset> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed after a {@link ConverterPipeline} has extracted all applicable {@link JavaAsset}s for conversion of a {@link ResourcePack}. This method
|
||||||
|
* can be used to add extra {@link JavaAsset}s for conversion by adding them to the {@code extracted} collection, which is mutable.
|
||||||
|
*
|
||||||
|
* @param pack the resource pack that is used for extraction of {@link JavaAsset}s
|
||||||
|
* @param extracted the {@link JavaAsset}s the {@link ConverterPipeline} has extracted from the resource pack
|
||||||
|
* @param context the {@link ExtractionContext}
|
||||||
|
*/
|
||||||
|
default void postExtract(ResourcePack pack, Collection<JavaAsset> extracted, ExtractionContext context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed after a {@link ConverterPipeline} has converted a {@link JavaAsset} to a {@link BedrockAsset}. This method
|
||||||
|
* can be used to modify the {@link BedrockAsset} after conversion.
|
||||||
|
*
|
||||||
|
* <p><em>Please note that the {@link BedrockAsset} should be considered immutable, and no modifications should be made to it. Instead,
|
||||||
|
* return a modified copy.</em></p>
|
||||||
|
*
|
||||||
|
* @param asset the {@link JavaAsset} that was converted
|
||||||
|
* @param bedrockAsset the resulting {@link BedrockAsset}
|
||||||
|
* @param context the {@link ConversionContext}
|
||||||
|
* @return the modified {@link BedrockAsset}, or return the original if no modifications were made
|
||||||
|
*/
|
||||||
|
default BedrockAsset postConvert(JavaAsset asset, BedrockAsset bedrockAsset, ConversionContext context) {
|
||||||
|
return bedrockAsset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed after a {@link ConverterPipeline} has added all converted {@link BedrockAsset}s to the {@link BedrockResourcePack}. This method
|
||||||
|
* can be used to add additional assets to the output {@code pack}.
|
||||||
|
*
|
||||||
|
* @param pack the bedrock resource pack
|
||||||
|
* @param assets the assets added to the bedrock resource pack (immutable)
|
||||||
|
* @param context the {@link CombineContext}
|
||||||
|
*/
|
||||||
|
default void postInclude(BedrockResourcePack pack, List<BedrockAsset> assets, CombineContext context) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface AssetCombiner<BedrockAsset> {
|
||||||
|
|
||||||
|
void include(BedrockResourcePack pack, List<BedrockAsset> assets, CombineContext context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface AssetConverter<JavaAsset, BedrockAsset> {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
BedrockAsset convert(JavaAsset asset, ConversionContext context) throws Exception;
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import net.kyori.adventure.key.Keyed;
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.bedrock.resource.Manifest;
|
||||||
|
import org.geysermc.pack.bedrock.resource.sounds.sounddefinitions.SoundDefinitions;
|
||||||
|
import org.geysermc.pack.converter.type.base.PackIconConverter;
|
||||||
|
import org.geysermc.pack.converter.type.base.PackManifestConverter;
|
||||||
|
import org.geysermc.pack.converter.type.lang.BedrockLanguage;
|
||||||
|
import org.geysermc.pack.converter.type.lang.LangConverter;
|
||||||
|
import org.geysermc.pack.converter.type.misc.SplashTextConverter;
|
||||||
|
import org.geysermc.pack.converter.type.model.BedrockModel;
|
||||||
|
import org.geysermc.pack.converter.type.model.ModelConverter;
|
||||||
|
import org.geysermc.pack.converter.type.sound.SoundConverter;
|
||||||
|
import org.geysermc.pack.converter.type.sound.SoundRegistryConverter;
|
||||||
|
import org.geysermc.pack.converter.type.texture.TextureConverter;
|
||||||
|
import org.geysermc.pack.converter.type.texture.transformer.TransformedTexture;
|
||||||
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
import team.unnamed.creative.base.Writable;
|
||||||
|
import team.unnamed.creative.lang.Language;
|
||||||
|
import team.unnamed.creative.metadata.pack.PackMeta;
|
||||||
|
import team.unnamed.creative.model.Model;
|
||||||
|
import team.unnamed.creative.part.ResourcePackPart;
|
||||||
|
import team.unnamed.creative.serialize.minecraft.ResourceCategory;
|
||||||
|
import team.unnamed.creative.serialize.minecraft.language.LanguageSerializer;
|
||||||
|
import team.unnamed.creative.serialize.minecraft.sound.SoundSerializer;
|
||||||
|
import team.unnamed.creative.sound.Sound;
|
||||||
|
import team.unnamed.creative.sound.SoundRegistry;
|
||||||
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
@SuppressWarnings({"UnstableApiUsage", "unused"})
|
||||||
|
public final class AssetConverters {
|
||||||
|
private static final List<ConverterPipeline<?, ?>> CONVERTERS = new ArrayList<>();
|
||||||
|
private static boolean bootstrapped = false;
|
||||||
|
|
||||||
|
public static final ConverterPipeline<PackMeta, Manifest> MANIFEST = createSingle(
|
||||||
|
(pack, context) -> pack.packMeta(),
|
||||||
|
PackManifestConverter.INSTANCE,
|
||||||
|
BedrockResourcePack::manifest);
|
||||||
|
public static final ConverterPipeline<Writable, byte[]> ICON = createSingle(PackIconConverter::extractIcon, PackIconConverter.INSTANCE, BedrockResourcePack::icon);
|
||||||
|
public static final ConverterPipeline<Writable, JsonElement> SPLASH_TEXT = createSingle(
|
||||||
|
(pack, context) -> pack.unknownFile("assets/minecraft/texts/splashes.txt"),
|
||||||
|
SplashTextConverter.INSTANCE,
|
||||||
|
(pack, splashes) -> pack.addExtraFile(splashes, "splashes.json"));
|
||||||
|
public static final ConverterPipeline<Language, BedrockLanguage> LANGUAGE = create(extractor(LanguageSerializer.CATEGORY), LangConverter.INSTANCE);
|
||||||
|
public static final ConverterPipeline<Model, BedrockModel> MODEL = create(ModelConverter.INSTANCE);
|
||||||
|
public static final ConverterPipeline<SoundRegistry, Map<String, SoundDefinitions>> SOUND_REGISTRY = create(
|
||||||
|
(pack, context) -> pack.soundRegistries(), SoundRegistryConverter.INSTANCE);
|
||||||
|
public static final ConverterPipeline<Sound, Sound> SOUND = create(extractor(SoundSerializer.CATEGORY), SoundConverter.INSTANCE);
|
||||||
|
public static final ConverterPipeline<Texture, TransformedTexture> TEXTURE = create(TextureConverter.INSTANCE);
|
||||||
|
|
||||||
|
private static <JavaAsset, BedrockAsset> ConverterPipeline<JavaAsset, BedrockAsset> createSingle(BiFunction<ResourcePack, ExtractionContext, JavaAsset> extractor,
|
||||||
|
AssetConverter<JavaAsset, BedrockAsset> converter,
|
||||||
|
BiConsumer<BedrockResourcePack, BedrockAsset> collector) {
|
||||||
|
return create(
|
||||||
|
(pack, context) -> Optional.ofNullable(extractor.apply(pack, context))
|
||||||
|
.map(List::of)
|
||||||
|
.orElse(List.of()),
|
||||||
|
converter,
|
||||||
|
(pack, assets, context) -> collector.accept(pack, assets.get(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <JavaAsset, BedrockAsset,
|
||||||
|
ConverterCombiner extends AssetConverter<JavaAsset, BedrockAsset>
|
||||||
|
& AssetCombiner<BedrockAsset>> ConverterPipeline<JavaAsset, BedrockAsset> create(AssetExtractor<JavaAsset> extractor,
|
||||||
|
ConverterCombiner converterCombiner) {
|
||||||
|
return create(extractor, converterCombiner, converterCombiner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <JavaAsset, BedrockAsset,
|
||||||
|
Pipeline extends AssetExtractor<JavaAsset> & AssetConverter<JavaAsset, BedrockAsset>
|
||||||
|
& AssetCombiner<BedrockAsset>> ConverterPipeline<JavaAsset, BedrockAsset> create(Pipeline pipeline) {
|
||||||
|
return create(pipeline, pipeline, pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <JavaAsset, BedrockAsset> ConverterPipeline<JavaAsset, BedrockAsset> create(AssetExtractor<JavaAsset> extractor,
|
||||||
|
AssetConverter<JavaAsset, BedrockAsset> converter,
|
||||||
|
AssetCombiner<BedrockAsset> combiner) {
|
||||||
|
ConverterPipeline<JavaAsset, BedrockAsset> pipeline = new ConverterPipeline<>(extractor, converter, combiner, false, Optional.empty());
|
||||||
|
if (!bootstrapped) {
|
||||||
|
CONVERTERS.add(pipeline);
|
||||||
|
}
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ConverterPipeline<?, ?>> converters(boolean experimental) {
|
||||||
|
return List.copyOf(CONVERTERS).stream()
|
||||||
|
.filter(converter -> experimental || !converter.experimental())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
// This will cause 3rd-party converters made using the utility methods here to not be added to the CONVERTERS array
|
||||||
|
bootstrapped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <JavaAsset extends Keyed & ResourcePackPart> AssetExtractor<JavaAsset> extractor(ResourceCategory<JavaAsset> category) {
|
||||||
|
return (pack, context) -> category.lister().apply(pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,21 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.data;
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface ConversionData {
|
@FunctionalInterface
|
||||||
|
public interface AssetExtractor<JavaAsset> {
|
||||||
|
|
||||||
@NotNull
|
Collection<JavaAsset> extract(ResourcePack pack, ExtractionContext context);
|
||||||
Path inputDirectory();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
Path outputDirectory();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
ResourcePack vanillaPack();
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
|
import org.geysermc.pack.converter.util.LogListenerHelper;
|
||||||
|
|
||||||
|
public record CombineContext(String textureSubDirectory, LogListener logListener) implements LogListenerHelper {
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
|
import org.geysermc.pack.converter.util.LogListenerHelper;
|
||||||
|
|
||||||
|
public record ConversionContext(String packName, LogListener logListener) implements LogListenerHelper {
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@SuppressWarnings("ClassCanBeRecord") // We don't want to expose the fields here
|
||||||
|
public final class ConverterPipeline<JavaAsset, BedrockAsset>
|
||||||
|
implements AssetExtractor<JavaAsset>, AssetConverter<JavaAsset, BedrockAsset>, AssetCombiner<BedrockAsset> {
|
||||||
|
private final AssetExtractor<JavaAsset> extractor;
|
||||||
|
private final AssetConverter<JavaAsset, BedrockAsset> converter;
|
||||||
|
private final AssetCombiner<BedrockAsset> combiner;
|
||||||
|
private final boolean experimental;
|
||||||
|
private final Optional<ActionListener<JavaAsset, BedrockAsset>> listener;
|
||||||
|
|
||||||
|
public ConverterPipeline(AssetExtractor<JavaAsset> extractor,
|
||||||
|
AssetConverter<JavaAsset, BedrockAsset> converter,
|
||||||
|
AssetCombiner<BedrockAsset> combiner,
|
||||||
|
boolean experimental,
|
||||||
|
Optional<ActionListener<JavaAsset, BedrockAsset>> listener) {
|
||||||
|
this.extractor = extractor;
|
||||||
|
this.converter = converter;
|
||||||
|
this.combiner = combiner;
|
||||||
|
this.experimental = experimental;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<JavaAsset> extract(ResourcePack pack, ExtractionContext context) {
|
||||||
|
Collection<JavaAsset> extracted = extractor.extract(pack, context);
|
||||||
|
listener.ifPresent(actionListener -> actionListener.postExtract(pack, extracted, context));
|
||||||
|
return extracted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BedrockAsset convert(JavaAsset asset, ConversionContext context) throws Exception {
|
||||||
|
BedrockAsset converted = converter.convert(asset, context);
|
||||||
|
return listener.map(actionListener -> actionListener.postConvert(asset, converted, context))
|
||||||
|
.orElse(converted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void include(BedrockResourcePack pack, List<BedrockAsset> assets, CombineContext context) {
|
||||||
|
combiner.include(pack, assets, context);
|
||||||
|
listener.ifPresent(actionListener -> actionListener.postInclude(pack, assets, context));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int convert(ResourcePack pack, Optional<ResourcePack> vanillaPack, BedrockResourcePack bedrockPack, String packName, String textureSubDirectory, LogListener logListener) {
|
||||||
|
ExtractionContext extractionContext = new ExtractionContext(bedrockPack, vanillaPack, logListener);
|
||||||
|
ConversionContext conversionContext = new ConversionContext(packName, logListener);
|
||||||
|
CombineContext combineContext = new CombineContext(textureSubDirectory, logListener);
|
||||||
|
|
||||||
|
AtomicInteger errors = new AtomicInteger(0);
|
||||||
|
List<BedrockAsset> converted = extract(pack, extractionContext).stream()
|
||||||
|
.map(asset -> {
|
||||||
|
try {
|
||||||
|
return convert(asset, conversionContext);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
errors.incrementAndGet();
|
||||||
|
logListener.error("Failed to convert asset", exception);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
|
if (!converted.isEmpty()) {
|
||||||
|
include(bedrockPack, converted, combineContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean experimental() {
|
||||||
|
return experimental;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConverterPipeline<JavaAsset, BedrockAsset> withActionListener(ActionListener<JavaAsset, BedrockAsset> listener) {
|
||||||
|
return new ConverterPipeline<>(extractor, converter, combiner, experimental, Optional.of(listener));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,34 +24,19 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter;
|
package org.geysermc.pack.converter.pipeline;
|
||||||
|
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
import org.geysermc.pack.converter.PackConverter;
|
|
||||||
import org.geysermc.pack.converter.data.ConversionData;
|
|
||||||
import org.geysermc.pack.converter.util.LogListener;
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.geysermc.pack.converter.util.LogListenerHelper;
|
||||||
import team.unnamed.creative.ResourcePack;
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface Converter<T extends ConversionData> {
|
/**
|
||||||
|
* @param bedrockResourcePack should never be used. The bedrock resource pack should not be written to during extraction, rather only during combination of converted assets.
|
||||||
void convert(@NotNull PackConversionContext<T> context) throws Exception;
|
* The bedrock resource pack is only included here for legacy converters still making use of it, which will be rewritten soon.
|
||||||
|
*/
|
||||||
T createConversionData(@NotNull ConversionDataCreationContext context);
|
public record ExtractionContext(@Deprecated(forRemoval = true) BedrockResourcePack bedrockResourcePack,
|
||||||
|
Optional<ResourcePack> vanillaPack, LogListener logListener) implements LogListenerHelper {
|
||||||
default boolean isExperimental() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
record ConversionDataCreationContext(
|
|
||||||
@NotNull PackConverter converter,
|
|
||||||
@NotNull LogListener logListener,
|
|
||||||
@NotNull Path inputDirectory,
|
|
||||||
@NotNull Path outputDirectory,
|
|
||||||
@NotNull ResourcePack javaResourcePack,
|
|
||||||
@NotNull ResourcePack vanillaResourcePack
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,33 +24,41 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.base;
|
package org.geysermc.pack.converter.type.base;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
import org.geysermc.pack.converter.converter.BaseConverter;
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
import org.geysermc.pack.converter.pipeline.ExtractionContext;
|
||||||
import org.geysermc.pack.converter.data.BaseConversionData;
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import team.unnamed.creative.ResourcePack;
|
||||||
import team.unnamed.creative.base.Writable;
|
import team.unnamed.creative.base.Writable;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
import java.util.Optional;
|
||||||
public class PackIconConverter extends BaseConverter {
|
|
||||||
private static final Key UNKNOWN_PACK = Key.key(Key.MINECRAFT_NAMESPACE, "misc/unknown_pack.png");
|
|
||||||
|
|
||||||
@Override
|
public class PackIconConverter implements AssetConverter<Writable, byte[]> {
|
||||||
public void convert(@NotNull PackConversionContext<BaseConversionData> context) throws Exception {
|
public static final PackIconConverter INSTANCE = new PackIconConverter();
|
||||||
Writable packIcon = context.javaResourcePack().icon();
|
private static final Key UNKNOWN_PACK = KeyUtil.key(Key.MINECRAFT_NAMESPACE, "misc/unknown_pack.png");
|
||||||
|
|
||||||
|
public static Writable extractIcon(ResourcePack pack, ExtractionContext context) {
|
||||||
|
Writable packIcon = pack.icon();
|
||||||
if (packIcon == null) {
|
if (packIcon == null) {
|
||||||
if (context.javaResourcePack().texture(UNKNOWN_PACK) != null) {
|
Texture unknownPackOverride = pack.texture(UNKNOWN_PACK);
|
||||||
packIcon = context.javaResourcePack().texture(UNKNOWN_PACK).data();
|
if (unknownPackOverride != null) {
|
||||||
|
packIcon = unknownPackOverride.data();
|
||||||
} else {
|
} else {
|
||||||
packIcon = context.data().vanillaPack().texture(UNKNOWN_PACK).data();
|
packIcon = context.vanillaPack()
|
||||||
|
.flatMap(vanilla -> Optional.ofNullable(vanilla.texture(UNKNOWN_PACK)))
|
||||||
|
.map(Texture::data)
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return packIcon;
|
||||||
|
}
|
||||||
|
|
||||||
context.bedrockResourcePack().icon(packIcon.toByteArray());
|
@Override
|
||||||
|
public byte[] convert(Writable writable, ConversionContext context) throws Exception {
|
||||||
|
return writable.toByteArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,36 +24,30 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.base;
|
package org.geysermc.pack.converter.type.base;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
|
||||||
import org.geysermc.pack.bedrock.resource.Manifest;
|
import org.geysermc.pack.bedrock.resource.Manifest;
|
||||||
import org.geysermc.pack.bedrock.resource.manifest.Header;
|
import org.geysermc.pack.bedrock.resource.manifest.Header;
|
||||||
import org.geysermc.pack.bedrock.resource.manifest.Modules;
|
import org.geysermc.pack.bedrock.resource.manifest.Modules;
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
import org.geysermc.pack.converter.converter.BaseConverter;
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
import team.unnamed.creative.metadata.pack.PackMeta;
|
||||||
import org.geysermc.pack.converter.data.BaseConversionData;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.ResourcePack;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
public class PackManifestConverter implements AssetConverter<PackMeta, Manifest> {
|
||||||
public class PackManifestConverter extends BaseConverter {
|
public static final PackManifestConverter INSTANCE = new PackManifestConverter();
|
||||||
private static final int FORMAT_VERSION = 2;
|
private static final int FORMAT_VERSION = 2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convert(@NotNull PackConversionContext<BaseConversionData> context) throws Exception {
|
public Manifest convert(PackMeta packMeta, ConversionContext context) throws Exception {
|
||||||
ResourcePack javaPack = context.javaResourcePack();
|
|
||||||
|
|
||||||
Manifest manifest = new Manifest();
|
Manifest manifest = new Manifest();
|
||||||
manifest.formatVersion(FORMAT_VERSION);
|
manifest.formatVersion(FORMAT_VERSION);
|
||||||
|
|
||||||
Header header = new Header();
|
Header header = new Header();
|
||||||
header.description(javaPack.description());
|
header.description(packMeta.description());
|
||||||
header.name(context.packConverter().packName());
|
header.name(context.packName());
|
||||||
header.version(new float[] { 1, 0, 0 });
|
header.version(new float[] { 1, 0, 0 });
|
||||||
header.minEngineVersion(new float[] { 1, 16, 0 });
|
header.minEngineVersion(new float[] { 1, 16, 0 });
|
||||||
header.uuid(UUID.randomUUID().toString());
|
header.uuid(UUID.randomUUID().toString());
|
||||||
@@ -61,12 +55,13 @@ public class PackManifestConverter extends BaseConverter {
|
|||||||
manifest.header(header);
|
manifest.header(header);
|
||||||
|
|
||||||
Modules module = new Modules();
|
Modules module = new Modules();
|
||||||
module.description(javaPack.description());
|
module.description(packMeta.description());
|
||||||
module.type("resources");
|
module.type("resources");
|
||||||
module.uuid(UUID.randomUUID().toString());
|
module.uuid(UUID.randomUUID().toString());
|
||||||
module.version(new float[] { 1, 0, 0 });
|
module.version(new float[] { 1, 0, 0 });
|
||||||
|
|
||||||
manifest.modules(List.of(module));
|
manifest.modules(List.of(module));
|
||||||
context.bedrockResourcePack().manifest(manifest);
|
|
||||||
|
return manifest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,8 +24,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter;
|
package org.geysermc.pack.converter.type.lang;
|
||||||
|
|
||||||
public class Constants {
|
import java.util.Map;
|
||||||
public static final String JAVA_PACK_LOCATION = "assets/%s";
|
|
||||||
|
public record BedrockLanguage(String language, Map<String, String> strings) {
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.type.lang;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetCombiner;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
|
import org.geysermc.pack.converter.pipeline.CombineContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
|
import team.unnamed.creative.lang.Language;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class LangConverter implements AssetConverter<Language, BedrockLanguage>, AssetCombiner<BedrockLanguage> {
|
||||||
|
public static final LangConverter INSTANCE = new LangConverter();
|
||||||
|
|
||||||
|
private static final Pattern POSITIONAL_STRING_REPLACEMENT = Pattern.compile("%([0-9]+)\\$s");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BedrockLanguage convert(Language language, ConversionContext context) throws Exception {
|
||||||
|
Map<String, String> strings = language.translations();
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : strings.entrySet()) {
|
||||||
|
String value = entry.getValue();
|
||||||
|
|
||||||
|
// Replace %d with %s
|
||||||
|
value = value.replace("%d", "%s");
|
||||||
|
|
||||||
|
// Replace `%x$s` with `%x`
|
||||||
|
value = POSITIONAL_STRING_REPLACEMENT.matcher(value).replaceAll("%$1");
|
||||||
|
|
||||||
|
entry.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
String languageKey = language.key().value();
|
||||||
|
|
||||||
|
// Convert the language key to the Bedrock equivalent
|
||||||
|
if (languageKey.equals("no_no")) {
|
||||||
|
languageKey = "nb_no";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BedrockLanguage(languageKey, strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void include(BedrockResourcePack pack, List<BedrockLanguage> languages, CombineContext context) {
|
||||||
|
Map<String, Map<String, String>> merged = new HashMap<>();
|
||||||
|
|
||||||
|
for (BedrockLanguage language : languages) {
|
||||||
|
Map<String, String> mergedLanguage = merged.computeIfAbsent(language.language(), name -> new HashMap<>());
|
||||||
|
for (Map.Entry<String, String> entry : language.strings().entrySet()) {
|
||||||
|
if (mergedLanguage.containsKey(entry.getKey())) {
|
||||||
|
context.warn("Conflicting language string " + entry.getKey() + "!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mergedLanguage.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
merged.forEach(pack::addLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2025 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,38 +24,27 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.misc;
|
package org.geysermc.pack.converter.type.misc;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.*;
|
import com.google.gson.JsonElement;
|
||||||
import net.kyori.adventure.key.Key;
|
import com.google.gson.JsonObject;
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
import org.geysermc.pack.converter.converter.BaseConverter;
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
import org.geysermc.pack.converter.converter.Converter;
|
|
||||||
import org.geysermc.pack.converter.data.BaseConversionData;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import team.unnamed.creative.base.Writable;
|
import team.unnamed.creative.base.Writable;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@AutoService(Converter.class)
|
public class SplashTextConverter implements AssetConverter<Writable, JsonElement> {
|
||||||
public class SplashTextConverter extends BaseConverter {
|
public static final SplashTextConverter INSTANCE = new SplashTextConverter();
|
||||||
private static final Gson GSON = new GsonBuilder()
|
|
||||||
.setPrettyPrinting()
|
|
||||||
.create();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void convert(@NotNull PackConversionContext<BaseConversionData> context) throws Exception {
|
public JsonElement convert(Writable writable, ConversionContext context) throws Exception {
|
||||||
Writable javaSplashText = context.javaResourcePack().unknownFile("assets/minecraft/texts/splashes.txt");
|
String[] splashes = writable.toUTF8String().split("\n");
|
||||||
if (javaSplashText == null) return;
|
|
||||||
|
|
||||||
String[] splashes = javaSplashText.toUTF8String().split("\n");
|
|
||||||
JsonArray splashesArray = new JsonArray();
|
JsonArray splashesArray = new JsonArray();
|
||||||
Arrays.stream(splashes).toList().forEach(splashesArray::add);
|
Arrays.stream(splashes).toList().forEach(splashesArray::add);
|
||||||
JsonObject object = new JsonObject();
|
JsonObject object = new JsonObject();
|
||||||
object.add("splashes", splashesArray);
|
object.add("splashes", splashesArray);
|
||||||
|
return object;
|
||||||
context.bedrockResourcePack().addExtraFile(GSON.toJson(object).getBytes(StandardCharsets.UTF_8), "splashes.json");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,19 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter;
|
package org.geysermc.pack.converter.type.model;
|
||||||
|
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
import org.geysermc.pack.bedrock.resource.models.entity.ModelEntity;
|
||||||
import org.geysermc.pack.converter.data.ConversionData;
|
|
||||||
|
|
||||||
/**
|
public record BedrockModel(ModelType type, String fileName, ModelEntity model) {
|
||||||
* A listener for actions that occur during pack conversion.
|
|
||||||
*/
|
|
||||||
public interface ActionListener<T extends ConversionData> {
|
|
||||||
|
|
||||||
default void preConvert(PackConversionContext<T> context) {
|
public enum ModelType {
|
||||||
}
|
BLOCK,
|
||||||
|
ENTITY
|
||||||
default void postConvert(PackConversionContext<T> context) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.type.model;
|
||||||
|
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.ModelEntity;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.Geometry;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.Bones;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.Description;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.Cubes;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.Uv;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.Down;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.East;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.North;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.South;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.Up;
|
||||||
|
import org.geysermc.pack.bedrock.resource.models.entity.modelentity.geometry.bones.cubes.uv.West;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetCombiner;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetExtractor;
|
||||||
|
import org.geysermc.pack.converter.pipeline.CombineContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ExtractionContext;
|
||||||
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
import team.unnamed.creative.base.CubeFace;
|
||||||
|
import team.unnamed.creative.model.Element;
|
||||||
|
import team.unnamed.creative.model.ElementFace;
|
||||||
|
import team.unnamed.creative.model.ElementRotation;
|
||||||
|
import team.unnamed.creative.model.Model;
|
||||||
|
import team.unnamed.creative.texture.TextureUV;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ModelConverter implements AssetExtractor<Model>, AssetConverter<Model, BedrockModel>, AssetCombiner<BedrockModel> {
|
||||||
|
public static final ModelConverter INSTANCE = new ModelConverter();
|
||||||
|
|
||||||
|
private static final String FORMAT_VERSION = "1.16.0";
|
||||||
|
private static final String GEOMETRY_FORMAT = "geometry.%s";
|
||||||
|
|
||||||
|
private static final float[] ELEMENT_OFFSET = new float[] { 8, 0, 8 };
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Model> extract(ResourcePack pack, ExtractionContext context) {
|
||||||
|
ModelStitcher.Provider modelProvider = context.vanillaPack()
|
||||||
|
.map(vanilla -> ModelStitcher.vanillaProvider(pack, vanilla))
|
||||||
|
.orElseGet(() -> ModelStitcher.baseProvider(pack));
|
||||||
|
// TODO maybe parallel, if model stitching takes a lot of time
|
||||||
|
return pack.models().stream()
|
||||||
|
.map(model -> new ModelStitcher(modelProvider, model, context.logListener()).stitch())
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BedrockModel convert(Model model, ConversionContext context) throws Exception {
|
||||||
|
List<Element> elements = model.elements();
|
||||||
|
if (elements.isEmpty()) {
|
||||||
|
context.debug("Model " + model.key().key() + " has no elements");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = model.key().value();
|
||||||
|
context.debug("Converting model " + model.key().key() + ":" + value);
|
||||||
|
|
||||||
|
// TODO: Convert item models but save differently?
|
||||||
|
if (value.startsWith("item/")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelEntity modelEntity = new ModelEntity();
|
||||||
|
modelEntity.formatVersion(FORMAT_VERSION);
|
||||||
|
|
||||||
|
Geometry geometry = new Geometry();
|
||||||
|
|
||||||
|
String namespace = model.key().namespace();
|
||||||
|
String fileName = value.substring(value.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
|
String geoName = (namespace.equals(Key.MINECRAFT_NAMESPACE) ? "" : namespace + ".") + fileName;
|
||||||
|
|
||||||
|
// TODO: Don't hardcode all this
|
||||||
|
Description description = new Description();
|
||||||
|
description.identifier(String.format(GEOMETRY_FORMAT, geoName));
|
||||||
|
description.textureWidth(16);
|
||||||
|
description.textureHeight(16);
|
||||||
|
description.visibleBoundsWidth(2);
|
||||||
|
description.visibleBoundsHeight(2);
|
||||||
|
description.visibleBoundsOffset(new float[] { 0.0f, 0.25f, 0.0f });
|
||||||
|
geometry.description(description);
|
||||||
|
|
||||||
|
List<Bones> bones = new ArrayList<>();
|
||||||
|
|
||||||
|
// TODO: Should each element be its own bone rather
|
||||||
|
// than its own cube in the same bone?
|
||||||
|
int i = 0;
|
||||||
|
for (Element element : elements) {
|
||||||
|
float[] from = element.from().toArray();
|
||||||
|
float[] to = element.to().toArray();
|
||||||
|
|
||||||
|
Bones bone = new Bones();
|
||||||
|
bone.name("bone_" + i++);
|
||||||
|
bone.pivot(new float[] { ELEMENT_OFFSET[0], ELEMENT_OFFSET[1], -ELEMENT_OFFSET[2] });
|
||||||
|
|
||||||
|
Cubes cube = new Cubes();
|
||||||
|
cube.origin(new float[] { ELEMENT_OFFSET[0] - to[0], from[1], from[2] - ELEMENT_OFFSET[2] });
|
||||||
|
cube.size(new float[] { to[0] - from[0], to[1] - from[1], to[2] - from[2] });
|
||||||
|
|
||||||
|
ElementRotation elementRotation = element.rotation();
|
||||||
|
if (elementRotation != null) {
|
||||||
|
float[] origin = elementRotation.origin().toArray();
|
||||||
|
cube.pivot(new float[] { ELEMENT_OFFSET[0] - origin[0], ELEMENT_OFFSET[1] - origin[1], origin[2] - ELEMENT_OFFSET[2] });
|
||||||
|
|
||||||
|
float angle = elementRotation.angle();
|
||||||
|
float[] rotation = new float[3];
|
||||||
|
switch (elementRotation.axis()) {
|
||||||
|
case X -> rotation[0] = -angle;
|
||||||
|
case Y -> rotation[1] = -angle;
|
||||||
|
case Z -> rotation[2] = -angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
cube.rotation(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uv uv = new Uv();
|
||||||
|
for (Map.Entry<CubeFace, ElementFace> entry : element.faces().entrySet()) {
|
||||||
|
CubeFace face = entry.getKey();
|
||||||
|
ElementFace elementFace = entry.getValue();
|
||||||
|
if (elementFace.uv0() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Java pack lib we use does this weird thing where it
|
||||||
|
// divides the UV by 16, so we need to multiply it by 16
|
||||||
|
|
||||||
|
String texture = elementFace.texture().replace("#", "");
|
||||||
|
applyUv(uv, face, texture, multiplyUv(elementFace.uv0(), 16f));
|
||||||
|
}
|
||||||
|
|
||||||
|
cube.uv(uv);
|
||||||
|
bone.cubes(List.of(cube));
|
||||||
|
|
||||||
|
bones.add(bone);
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry.bones(bones);
|
||||||
|
|
||||||
|
modelEntity.geometry(List.of(geometry));
|
||||||
|
|
||||||
|
if (model.key().namespace().contains("entity")) {
|
||||||
|
return new BedrockModel(BedrockModel.ModelType.ENTITY, fileName + ".json", modelEntity);
|
||||||
|
} else {
|
||||||
|
// Bedrock only has a concept of entity or block models
|
||||||
|
return new BedrockModel(BedrockModel.ModelType.BLOCK, fileName + ".json", modelEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void include(BedrockResourcePack pack, List<BedrockModel> bedrockModels, CombineContext context) {
|
||||||
|
List<String> entityModels = new ArrayList<>();
|
||||||
|
List<String> blockModels = new ArrayList<>();
|
||||||
|
|
||||||
|
for (BedrockModel model : bedrockModels) {
|
||||||
|
switch (model.type()) {
|
||||||
|
case ENTITY -> {
|
||||||
|
if (entityModels.contains(model.fileName())) {
|
||||||
|
context.warn("Conflicting entity model " + model.fileName() + "!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
entityModels.add(model.fileName());
|
||||||
|
pack.addEntityModel(model.model(), model.fileName());
|
||||||
|
}
|
||||||
|
case BLOCK -> {
|
||||||
|
if (blockModels.contains(model.fileName())) {
|
||||||
|
context.warn("Conflicting entity model " + model.fileName() + "!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
blockModels.add(model.fileName());
|
||||||
|
pack.addBlockModel(model.model(), model.fileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextureUV multiplyUv(TextureUV textureUV, float mult) {
|
||||||
|
return TextureUV.uv(textureUV.from().multiply(mult), textureUV.to().multiply(mult));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyUv(Uv uv, CubeFace face, String texture, TextureUV faceUv) {
|
||||||
|
float[] uvs;
|
||||||
|
float[] uvSize;
|
||||||
|
|
||||||
|
// These values are flipped for some reason
|
||||||
|
if (face == CubeFace.DOWN || face == CubeFace.UP) {
|
||||||
|
uvs = new float[] { faceUv.to().x(), faceUv.to().y() };
|
||||||
|
uvSize = new float[] { faceUv.from().x() - faceUv.to().x(), faceUv.from().y() - faceUv.to().y() };
|
||||||
|
} else {
|
||||||
|
uvs = new float[] { faceUv.from().x(), faceUv.from().y() };
|
||||||
|
uvSize = new float[] { faceUv.to().x() - faceUv.from().x(), faceUv.to().y() - faceUv.from().y() };
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (face) {
|
||||||
|
case NORTH -> {
|
||||||
|
North north = new North();
|
||||||
|
north.uv(uvs);
|
||||||
|
north.uvSize(uvSize);
|
||||||
|
north.materialInstance(texture);
|
||||||
|
|
||||||
|
uv.north(north);
|
||||||
|
}
|
||||||
|
case SOUTH -> {
|
||||||
|
South south = new South();
|
||||||
|
south.uv(uvs);
|
||||||
|
south.uvSize(uvSize);
|
||||||
|
south.materialInstance(texture);
|
||||||
|
|
||||||
|
uv.south(south);
|
||||||
|
}
|
||||||
|
case EAST -> {
|
||||||
|
East east = new East();
|
||||||
|
east.uv(uvs);
|
||||||
|
east.uvSize(uvSize);
|
||||||
|
east.materialInstance(texture);
|
||||||
|
|
||||||
|
uv.east(east);
|
||||||
|
}
|
||||||
|
case WEST -> {
|
||||||
|
West west = new West();
|
||||||
|
west.uv(uvs);
|
||||||
|
west.uvSize(uvSize);
|
||||||
|
west.materialInstance(texture);
|
||||||
|
|
||||||
|
uv.west(west);
|
||||||
|
}
|
||||||
|
case UP -> {
|
||||||
|
Up up = new Up();
|
||||||
|
up.uv(uvs);
|
||||||
|
up.uvSize(uvSize);
|
||||||
|
up.materialInstance(texture);
|
||||||
|
|
||||||
|
uv.up(up);
|
||||||
|
}
|
||||||
|
case DOWN -> {
|
||||||
|
Down down = new Down();
|
||||||
|
down.uv(uvs);
|
||||||
|
down.uvSize(uvSize);
|
||||||
|
down.materialInstance(texture);
|
||||||
|
|
||||||
|
uv.down(down);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,12 +24,11 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.model;
|
package org.geysermc.pack.converter.type.model;
|
||||||
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.util.DefaultLogListener;
|
import org.geysermc.pack.converter.util.DefaultLogListener;
|
||||||
import org.geysermc.pack.converter.util.LogListener;
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
import org.geysermc.pack.converter.util.VanillaPackProvider;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import team.unnamed.creative.ResourcePack;
|
import team.unnamed.creative.ResourcePack;
|
||||||
@@ -39,10 +38,7 @@ import team.unnamed.creative.model.ItemTransform;
|
|||||||
import team.unnamed.creative.model.Model;
|
import team.unnamed.creative.model.Model;
|
||||||
import team.unnamed.creative.model.ModelTexture;
|
import team.unnamed.creative.model.ModelTexture;
|
||||||
import team.unnamed.creative.model.ModelTextures;
|
import team.unnamed.creative.model.ModelTextures;
|
||||||
import team.unnamed.creative.serialize.minecraft.MinecraftResourcePackReader;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -195,7 +191,7 @@ public class ModelStitcher {
|
|||||||
return pack::model;
|
return pack::model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Provider vanillaProvider(@NotNull ResourcePack pack, @NotNull LogListener log, @NotNull ResourcePack vanillaPack) {
|
public static Provider vanillaProvider(@NotNull ResourcePack pack, @NotNull ResourcePack vanillaPack) {
|
||||||
return key -> {
|
return key -> {
|
||||||
Model model = pack.model(key);
|
Model model = pack.model(key);
|
||||||
if (model == null) {
|
if (model == null) {
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.type.sound;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetCombiner;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
|
import org.geysermc.pack.converter.pipeline.CombineContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import team.unnamed.creative.sound.Sound;
|
||||||
|
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SoundConverter implements AssetConverter<Sound, Sound>, AssetCombiner<Sound> {
|
||||||
|
public static final SoundConverter INSTANCE = new SoundConverter();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Sound convert(Sound sound, ConversionContext context) throws Exception {
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void include(BedrockResourcePack pack, List<Sound> sounds, CombineContext context) {
|
||||||
|
List<String> exported = new ArrayList<>();
|
||||||
|
Path output = pack.directory().resolve(SoundRegistryConverter.BEDROCK_SOUNDS_LOCATION);
|
||||||
|
|
||||||
|
for (Sound sound : sounds) {
|
||||||
|
String path = sound.key().value();
|
||||||
|
if (exported.contains(path)) {
|
||||||
|
context.warn("Conflicting sound file " + sound.key() + "!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Path file = output.resolve(path + ".ogg");
|
||||||
|
Path directory = file.getParent();
|
||||||
|
try {
|
||||||
|
Files.createDirectories(directory);
|
||||||
|
try (OutputStream outputStream = new FileOutputStream(file.toFile())) {
|
||||||
|
sound.data().write(outputStream);
|
||||||
|
}
|
||||||
|
} catch (IOException exception) {
|
||||||
|
context.error("Failed to write sound file " + sound.key() + "!", exception);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
exported.add(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.type.sound;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.bedrock.resource.sounds.sounddefinitions.SoundDefinitions;
|
||||||
|
import org.geysermc.pack.bedrock.resource.sounds.sounddefinitions.Sounds;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetCombiner;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
|
import org.geysermc.pack.converter.pipeline.CombineContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import team.unnamed.creative.sound.SoundEntry;
|
||||||
|
import team.unnamed.creative.sound.SoundEvent;
|
||||||
|
import team.unnamed.creative.sound.SoundRegistry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SoundRegistryConverter implements AssetConverter<SoundRegistry, Map<String, SoundDefinitions>>, AssetCombiner<Map<String, SoundDefinitions>> {
|
||||||
|
public static final SoundRegistryConverter INSTANCE = new SoundRegistryConverter();
|
||||||
|
static final String BEDROCK_SOUNDS_LOCATION = "sounds";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Map<String, SoundDefinitions> convert(SoundRegistry soundRegistry, ConversionContext context) throws Exception {
|
||||||
|
Map<String, SoundDefinitions> definitions = new HashMap<>();
|
||||||
|
|
||||||
|
for (SoundEvent value : soundRegistry.sounds()) {
|
||||||
|
String key = value.key().asString();
|
||||||
|
|
||||||
|
SoundDefinitions definition = new SoundDefinitions();
|
||||||
|
definition.useLegacyMaxDistance(true); // TODO: Needed?
|
||||||
|
definition.maxDistance(64); // ???
|
||||||
|
for (SoundEntry sound : value.sounds()) {
|
||||||
|
Sounds bedrockSound = new Sounds();
|
||||||
|
bedrockSound.name(BEDROCK_SOUNDS_LOCATION + "/" + sound.key().value());
|
||||||
|
bedrockSound.stream(sound.stream());
|
||||||
|
bedrockSound.loadOnLowMemory(true);
|
||||||
|
bedrockSound.volume(sound.volume());
|
||||||
|
bedrockSound.pitch(sound.pitch());
|
||||||
|
bedrockSound.weight(sound.weight());
|
||||||
|
|
||||||
|
definition.sounds().add(bedrockSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
definitions.put(key, definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return definitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void include(BedrockResourcePack pack, List<Map<String, SoundDefinitions>> maps, CombineContext context) {
|
||||||
|
List<String> soundEvents = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map<String, SoundDefinitions> definitions : maps) {
|
||||||
|
for (Map.Entry<String, SoundDefinitions> entry : definitions.entrySet()) {
|
||||||
|
if (soundEvents.contains(entry.getKey())) {
|
||||||
|
context.warn("Conflicting sound event " + entry.getKey() + "!");
|
||||||
|
}
|
||||||
|
pack.addSoundDefinition(entry.getKey(), entry.getValue());
|
||||||
|
soundEvents.add(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture;
|
package org.geysermc.pack.converter.type.texture;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -189,10 +189,10 @@ public final class PngToTgaMappings {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static TgaMapping mapping(@NotNull String key) {
|
static TgaMapping mapping(@NotNull String key) {
|
||||||
return MAPPINGS.get(key);
|
return MAPPINGS.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
record TgaMapping(String value, boolean keep) {
|
record TgaMapping(String value, boolean keep) {
|
||||||
|
|
||||||
public TgaMapping(String value) {
|
public TgaMapping(String value) {
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2025 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/PackConverter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.pack.converter.type.texture;
|
||||||
|
|
||||||
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetCombiner;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetConverter;
|
||||||
|
import org.geysermc.pack.converter.pipeline.AssetExtractor;
|
||||||
|
import org.geysermc.pack.converter.pipeline.CombineContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ConversionContext;
|
||||||
|
import org.geysermc.pack.converter.pipeline.ExtractionContext;
|
||||||
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
|
import org.geysermc.pack.converter.type.texture.transformer.TransformedTexture;
|
||||||
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import team.unnamed.creative.ResourcePack;
|
||||||
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.AlphaComposite;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
public class TextureConverter implements AssetExtractor<Texture>, AssetConverter<Texture, TransformedTexture>, AssetCombiner<TransformedTexture> {
|
||||||
|
public static final TextureConverter INSTANCE = new TextureConverter();
|
||||||
|
public static final String BEDROCK_TEXTURES_LOCATION = "textures";
|
||||||
|
|
||||||
|
private final List<TextureTransformer> transformers = StreamSupport.stream(ServiceLoader.load(TextureTransformer.class).spliterator(), false)
|
||||||
|
.sorted(Comparator.comparingInt(TextureTransformer::order))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
public static final Map<String, String> DIRECTORY_LOCATIONS = Map.of(
|
||||||
|
"block", "blocks",
|
||||||
|
"item", "items",
|
||||||
|
"gui", "ui"
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Texture> extract(ResourcePack pack, ExtractionContext context) {
|
||||||
|
// TODO ideally textures should be transformed individually in the convert process, and not together in the extraction process, but this is hard to achieve,
|
||||||
|
// TODO and will need another big refactor to the texture transformation code
|
||||||
|
// TODO for now this will work, but for library users it might be nice to be able to properly convert singular textures with transformations
|
||||||
|
TextureMappings mappings = TextureMappings.textureMappings();
|
||||||
|
List<Texture> textures = new ArrayList<>(pack.textures());
|
||||||
|
|
||||||
|
context.info("Transforming textures...");
|
||||||
|
TransformContext transformContext = new TransformContext(
|
||||||
|
mappings,
|
||||||
|
textures,
|
||||||
|
context.bedrockResourcePack(),
|
||||||
|
pack,
|
||||||
|
context.vanillaPack(),
|
||||||
|
context.logListener()
|
||||||
|
);
|
||||||
|
for (TextureTransformer transformer : this.transformers) {
|
||||||
|
try {
|
||||||
|
transformer.transform(transformContext);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.info("Transformed textures!");
|
||||||
|
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable TransformedTexture convert(Texture texture, ConversionContext context) throws Exception {
|
||||||
|
TextureMappings mappings = TextureMappings.textureMappings();
|
||||||
|
TransformedTexture transformed = new TransformedTexture(texture);
|
||||||
|
|
||||||
|
String input = texture.key().value();
|
||||||
|
String relativePath = input.replaceAll("\\.png$", "");
|
||||||
|
|
||||||
|
String rootPath = relativePath.substring(0, relativePath.indexOf('/'));
|
||||||
|
String bedrockRoot = DIRECTORY_LOCATIONS.getOrDefault(rootPath, rootPath);
|
||||||
|
|
||||||
|
Object mappingObject = mappings.textures(relativePath);
|
||||||
|
|
||||||
|
if (mappingObject == null) {
|
||||||
|
mappingObject = mappings.textures(rootPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
String fallbackPath = bedrockRoot + "/" + relativePath.substring(relativePath.indexOf('/') + 1) + ".png";
|
||||||
|
if (mappingObject instanceof Map<?,?> keyMappings) { // Handles common subdirectories
|
||||||
|
String sanitizedName = input.substring(input.indexOf('/') + 1);
|
||||||
|
if (sanitizedName.endsWith(".png")) sanitizedName = sanitizedName.substring(0, sanitizedName.length() - 4);
|
||||||
|
|
||||||
|
Object bedrockOutput = keyMappings.get(sanitizedName);
|
||||||
|
if (bedrockOutput instanceof String bedrockPath) {
|
||||||
|
transformed.output(bedrockRoot + "/" + bedrockPath + ".png");
|
||||||
|
} else if (bedrockOutput instanceof List<?> paths) {
|
||||||
|
for (String bedrockPath : (List<String>) paths) {
|
||||||
|
transformed.output(bedrockRoot + "/" + bedrockPath + ".png");
|
||||||
|
}
|
||||||
|
} else { // Fallback
|
||||||
|
transformed.output(fallbackPath);
|
||||||
|
}
|
||||||
|
} else if (mappingObject instanceof String str) { // Direct mappings
|
||||||
|
transformed.output(str + ".png");
|
||||||
|
} else if (mappingObject instanceof List<?> paths) { // Mappings where duplicate code paths exist
|
||||||
|
for (String path : (List<String>) paths) {
|
||||||
|
transformed.output(path + ".png");
|
||||||
|
}
|
||||||
|
} else { // Fallback
|
||||||
|
transformed.output(fallbackPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void include(BedrockResourcePack pack, List<TransformedTexture> transformedTextures, CombineContext context) {
|
||||||
|
Path texturePath = pack.directory().resolve(BEDROCK_TEXTURES_LOCATION);
|
||||||
|
List<String> exportedPaths = new ArrayList<>();
|
||||||
|
|
||||||
|
for (TransformedTexture textureToExport : transformedTextures) {
|
||||||
|
String bedrockDirectory = "%s/%s";
|
||||||
|
if (context.textureSubDirectory() != null) {
|
||||||
|
bedrockDirectory = "%s/" + context.textureSubDirectory() + "/%s";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Path> outputs = new ArrayList<>();
|
||||||
|
for (String outputPath : textureToExport.output()) {
|
||||||
|
if (exportedPaths.contains(outputPath)) {
|
||||||
|
context.warn("Conflicting texture " + outputPath + "!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
exportedPaths.add(outputPath);
|
||||||
|
|
||||||
|
String root = outputPath.substring(0, outputPath.indexOf('/'));
|
||||||
|
String value = outputPath.substring(outputPath.indexOf('/') + 1);
|
||||||
|
|
||||||
|
outputs.add(texturePath.resolve((
|
||||||
|
bedrockDirectory.formatted(root, value)
|
||||||
|
).replace('/', File.separatorChar)));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] bytes = textureToExport.texture().data().toByteArray();
|
||||||
|
|
||||||
|
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
|
||||||
|
|
||||||
|
for (Path output : outputs) {
|
||||||
|
if (output.getParent() != null && Files.notExists(output.getParent())) {
|
||||||
|
Files.createDirectories(output.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedImage bedrockImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
Graphics2D g = bedrockImage.createGraphics();
|
||||||
|
g.setComposite(AlphaComposite.Src);
|
||||||
|
g.drawImage(image, 0, 0, null);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
String pngKey = pack.directory().relativize(output).toString().replace(File.separatorChar, '/');
|
||||||
|
PngToTgaMappings.TgaMapping mapping = PngToTgaMappings.mapping(pngKey);
|
||||||
|
if (mapping != null) {
|
||||||
|
Path tgaPath = pack.directory().resolve(mapping.value());
|
||||||
|
if (Files.notExists(tgaPath.getParent())) {
|
||||||
|
Files.createDirectories(tgaPath.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageUtil.writeTGA(tgaPath, bedrockImage);
|
||||||
|
if (!mapping.keep()) {
|
||||||
|
Files.deleteIfExists(output);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (OutputStream stream = Files.newOutputStream(output)) {
|
||||||
|
ImageIO.write(bedrockImage, "png", stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException exception) {
|
||||||
|
context.error("Failed to write texture " + textureToExport.texture().key() + "!", exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture;
|
package org.geysermc.pack.converter.type.texture;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
@@ -34,7 +34,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@ToString
|
@ToString
|
||||||
public class TextureMappings extends LinkedHashMap<String, Object> {
|
public class TextureMappings extends LinkedHashMap<String, Object> {
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer;
|
package org.geysermc.pack.converter.type.texture.transformer;
|
||||||
|
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -24,14 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer;
|
package org.geysermc.pack.converter.type.texture.transformer;
|
||||||
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
import org.geysermc.pack.bedrock.resource.BedrockResourcePack;
|
||||||
import org.geysermc.pack.converter.PackConversionContext;
|
import org.geysermc.pack.converter.type.texture.TextureMappings;
|
||||||
import org.geysermc.pack.converter.converter.texture.TextureMappings;
|
|
||||||
import org.geysermc.pack.converter.data.TextureConversionData;
|
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.LogListener;
|
||||||
|
import org.geysermc.pack.converter.util.LogListenerHelper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import team.unnamed.creative.ResourcePack;
|
import team.unnamed.creative.ResourcePack;
|
||||||
@@ -43,27 +43,33 @@ import java.io.IOException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class TransformContext {
|
public class TransformContext implements LogListenerHelper {
|
||||||
private final PackConversionContext<TextureConversionData> conversionContext;
|
|
||||||
private final TextureMappings mappings;
|
private final TextureMappings mappings;
|
||||||
private final Collection<Texture> textures;
|
private final Collection<Texture> textures;
|
||||||
|
// TODO figure out how to handle this, this is executed in the extraction phase and ideally bedrock pack wouldn't be accessed then
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
private final BedrockResourcePack bedrockPack;
|
private final BedrockResourcePack bedrockPack;
|
||||||
private final ResourcePack javaPack;
|
private final ResourcePack javaPack;
|
||||||
|
private final Optional<ResourcePack> vanillaPack;
|
||||||
|
private final LogListener logListener;
|
||||||
private final Map<Key, Texture> byKey = new HashMap<>();
|
private final Map<Key, Texture> byKey = new HashMap<>();
|
||||||
|
|
||||||
public TransformContext(
|
public TransformContext(
|
||||||
PackConversionContext<TextureConversionData> conversionContext,
|
|
||||||
TextureMappings mappings,
|
TextureMappings mappings,
|
||||||
Collection<Texture> textures,
|
Collection<Texture> textures,
|
||||||
BedrockResourcePack bedrockPack,
|
BedrockResourcePack bedrockPack,
|
||||||
ResourcePack javaPack
|
ResourcePack javaPack,
|
||||||
|
Optional<ResourcePack> vanillaPack,
|
||||||
|
LogListener logListener
|
||||||
) {
|
) {
|
||||||
this.conversionContext = conversionContext;
|
|
||||||
this.mappings = mappings;
|
this.mappings = mappings;
|
||||||
this.textures = textures;
|
this.textures = textures;
|
||||||
this.bedrockPack = bedrockPack;
|
this.bedrockPack = bedrockPack;
|
||||||
this.javaPack = javaPack;
|
this.javaPack = javaPack;
|
||||||
|
this.vanillaPack = vanillaPack;
|
||||||
|
this.logListener = logListener;
|
||||||
|
|
||||||
for (Texture texture : textures) {
|
for (Texture texture : textures) {
|
||||||
this.byKey.put(texture.key(), texture);
|
this.byKey.put(texture.key(), texture);
|
||||||
@@ -74,16 +80,17 @@ public class TransformContext {
|
|||||||
return this.mappings;
|
return this.mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
public BedrockResourcePack bedrockResourcePack() {
|
public BedrockResourcePack bedrockResourcePack() {
|
||||||
return this.bedrockPack;
|
return bedrockPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourcePack javaResourcePack() {
|
public ResourcePack javaResourcePack() {
|
||||||
return this.javaPack;
|
return this.javaPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourcePack vanillaPack() {
|
public Optional<ResourcePack> vanillaPack() {
|
||||||
return this.conversionContext.data().vanillaPack();
|
return vanillaPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,8 +133,7 @@ public class TransformContext {
|
|||||||
public Texture pollOrPeekVanilla(@NotNull Key key) {
|
public Texture pollOrPeekVanilla(@NotNull Key key) {
|
||||||
Texture remove = this.byKey.remove(key);
|
Texture remove = this.byKey.remove(key);
|
||||||
if (remove == null) {
|
if (remove == null) {
|
||||||
// This *shouldn't* be null, but if a bad key is inputted, it is possible this value is null
|
return vanillaPack.map(pack -> pack.texture(key)).orElse(null);
|
||||||
return this.conversionContext.data().vanillaPack().texture(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.textures.remove(remove);
|
this.textures.remove(remove);
|
||||||
@@ -146,8 +152,7 @@ public class TransformContext {
|
|||||||
public Texture peekOrVanilla(@NotNull Key key) {
|
public Texture peekOrVanilla(@NotNull Key key) {
|
||||||
Texture texture = this.byKey.get(key);
|
Texture texture = this.byKey.get(key);
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
// This *shouldn't* be null, but if a bad key is inputted, it is possible this value is null
|
return vanillaPack.map(pack -> pack.texture(key)).orElse(null);
|
||||||
return this.conversionContext.data().vanillaPack().texture(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
@@ -186,23 +191,7 @@ public class TransformContext {
|
|||||||
this.byKey.put(texture.key(), texture);
|
this.byKey.put(texture.key(), texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void debug(@NotNull String message) {
|
public LogListener logListener() {
|
||||||
this.conversionContext.debug(message);
|
return logListener;
|
||||||
}
|
|
||||||
|
|
||||||
public void info(@NotNull String message) {
|
|
||||||
this.conversionContext.info(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void warn(@NotNull String message) {
|
|
||||||
this.conversionContext.warn(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void error(@NotNull String message) {
|
|
||||||
this.conversionContext.error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void error(@NotNull String message, @NotNull Throwable throwable) {
|
|
||||||
this.conversionContext.error(message, throwable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,20 +24,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer;
|
package org.geysermc.pack.converter.type.texture.transformer;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class TransformedTexture {
|
public class TransformedTexture {
|
||||||
private final Texture texture;
|
private final Texture texture;
|
||||||
private Path output;
|
private final List<String> outputs = new ArrayList<>();
|
||||||
|
|
||||||
public TransformedTexture(@NotNull Texture texture, @NotNull Path output) {
|
public TransformedTexture(@NotNull Texture texture) {
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
this.output = output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -46,11 +46,11 @@ public class TransformedTexture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Path output() {
|
public List<String> output() {
|
||||||
return output;
|
return outputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void output(@NotNull Path output) {
|
public void output(@NotNull String output) {
|
||||||
this.output = output;
|
outputs.add(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,12 +24,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type;
|
package org.geysermc.pack.converter.type.texture.transformer.type;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ public class AtlasTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
BufferedImage atlasImage = null;
|
BufferedImage atlasImage = null;
|
||||||
for (int i = 0; i <= atlasCount; i++) {
|
for (int i = 0; i <= atlasCount; i++) {
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, String.format(javaName, String.format("%1$2s", i).replace(" ", "0"))));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, String.format(javaName, String.format("%1$2s", i).replace(" ", "0"))));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -69,7 +70,7 @@ public class AtlasTransformer implements TextureTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (atlasImage != null) {
|
if (atlasImage != null) {
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, bedrockName), atlasImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, bedrockName), atlasImage, "png");
|
||||||
context.debug(String.format("Created atlas %s", bedrockName));
|
context.debug(String.format("Created atlas %s", bedrockName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type;
|
package org.geysermc.pack.converter.type.texture.transformer.type;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.geysermc.pack.converter.util.UnsafeKey;
|
import org.geysermc.pack.converter.util.UnsafeKey;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
@@ -272,7 +273,7 @@ public class ColorizeTransformer implements TextureTransformer {
|
|||||||
Color color = overlay.color();
|
Color color = overlay.color();
|
||||||
boolean deleteOverlay = overlay.deleteOverlay();
|
boolean deleteOverlay = overlay.deleteOverlay();
|
||||||
|
|
||||||
Key key = Key.key(Key.MINECRAFT_NAMESPACE, overlayPath);
|
Key key = KeyUtil.key(Key.MINECRAFT_NAMESPACE, overlayPath);
|
||||||
Texture texture = deleteOverlay ? context.poll(key) : context.peek(key);
|
Texture texture = deleteOverlay ? context.poll(key) : context.peek(key);
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
context.debug("Missing overlay texture: " + overlayPath);
|
context.debug("Missing overlay texture: " + overlayPath);
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type;
|
package org.geysermc.pack.converter.type.texture.transformer.type;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -102,8 +103,8 @@ public class OverlayTransformer implements TextureTransformer {
|
|||||||
boolean noReplace = overlay.noReplace();
|
boolean noReplace = overlay.noReplace();
|
||||||
boolean keep = overlay.keep();
|
boolean keep = overlay.keep();
|
||||||
|
|
||||||
Key javaKey = Key.key(Key.MINECRAFT_NAMESPACE, javaName);
|
Key javaKey = KeyUtil.key(Key.MINECRAFT_NAMESPACE, javaName);
|
||||||
Key overlayKey = Key.key(Key.MINECRAFT_NAMESPACE, overlayName);
|
Key overlayKey = KeyUtil.key(Key.MINECRAFT_NAMESPACE, overlayName);
|
||||||
|
|
||||||
// We don't have either textures, skip this
|
// We don't have either textures, skip this
|
||||||
if (!context.isTexturePresent(javaKey) && !context.isTexturePresent(overlayKey)) continue;
|
if (!context.isTexturePresent(javaKey) && !context.isTexturePresent(overlayKey)) continue;
|
||||||
@@ -149,7 +150,7 @@ public class OverlayTransformer implements TextureTransformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, bedrockName), image, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, bedrockName), image, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type;
|
package org.geysermc.pack.converter.type.texture.transformer.type;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -46,8 +47,8 @@ public class WeatherTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture snowTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, SNOW_INPUT));
|
Texture snowTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, SNOW_INPUT));
|
||||||
Texture rainTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, RAIN_INPUT));
|
Texture rainTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, RAIN_INPUT));
|
||||||
if (snowTexture == null || rainTexture == null) {
|
if (snowTexture == null || rainTexture == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -69,6 +70,6 @@ public class WeatherTransformer implements TextureTransformer {
|
|||||||
// Rain
|
// Rain
|
||||||
graphics.drawImage(ImageUtil.cover(ImageUtil.crop(rainImage, rainImage.getWidth(), (int) (5 * factor)), weatherImage.getWidth(), (int) (5 * factor)), 0, (int) (5 * factor), null);
|
graphics.drawImage(ImageUtil.cover(ImageUtil.crop(rainImage, rainImage.getWidth(), (int) (5 * factor)), weatherImage.getWidth(), (int) (5 * factor)), 0, (int) (5 * factor), null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, WEATHER_OUTPUT), weatherImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, WEATHER_OUTPUT), weatherImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ public class BedTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (String bedColor : BED_COLORS) {
|
for (String bedColor : BED_COLORS) {
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, BED_PATH + "/" + bedColor + ".png"));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BED_PATH + "/" + bedColor + ".png"));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -110,7 +111,7 @@ public class BedTransformer implements TextureTransformer {
|
|||||||
graphics.drawImage(ImageUtil.rotate(ImageUtil.crop(bedImage, ((fromX + 9) * factor), ((fromY + 3) * factor), (3 * factor), (3 * factor)), 180), ((toX + 3) * factor), (toY * factor), null);
|
graphics.drawImage(ImageUtil.rotate(ImageUtil.crop(bedImage, ((fromX + 9) * factor), ((fromY + 3) * factor), (3 * factor), (3 * factor)), 180), ((toX + 3) * factor), (toY * factor), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BED_PATH + "/" + bedColor + ".png"), newBedImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BED_PATH + "/" + bedColor + ".png"), newBedImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -50,8 +51,8 @@ public class ChestDoubleTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (ChestData chest : CHEST_DATA) {
|
for (ChestData chest : CHEST_DATA) {
|
||||||
Texture leftTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, chest.javaNameLeft()));
|
Texture leftTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.javaNameLeft()));
|
||||||
Texture rightTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, chest.javaNameRight()));
|
Texture rightTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.javaNameRight()));
|
||||||
if (leftTexture == null || rightTexture == null) {
|
if (leftTexture == null || rightTexture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -101,7 +102,7 @@ public class ChestDoubleTransformer implements TextureTransformer {
|
|||||||
graphics.drawImage(ImageUtil.crop(leftImage, 0, 0, (6 * factor), (6 * factor)), 0, 0, null);
|
graphics.drawImage(ImageUtil.crop(leftImage, 0, 0, (6 * factor), (6 * factor)), 0, 0, null);
|
||||||
graphics.drawImage(ImageUtil.crop(rightImage, 0, 0, (6 * factor), (6 * factor)), 0, 0, null);
|
graphics.drawImage(ImageUtil.crop(rightImage, 0, 0, (6 * factor), (6 * factor)), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, chest.bedrockName()), newImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.bedrockName()), newImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ public class ChestFrontTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (ChestData chest : CHESTS) {
|
for (ChestData chest : CHESTS) {
|
||||||
Texture texture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, chest.javaName()));
|
Texture texture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.javaName()));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -68,7 +69,7 @@ public class ChestFrontTransformer implements TextureTransformer {
|
|||||||
graphics.drawImage(ImageUtil.crop(fromImage, (14 * factor), (34 * factor), (14 * factor), (9 * factor)), 0, (5 * factor), null);
|
graphics.drawImage(ImageUtil.crop(fromImage, (14 * factor), (34 * factor), (14 * factor), (9 * factor)), 0, (5 * factor), null);
|
||||||
graphics.drawImage(ImageUtil.crop(fromImage , factor, factor, (2 * factor), (4 * factor)), (6 * factor), (3 * factor), null);
|
graphics.drawImage(ImageUtil.crop(fromImage , factor, factor, (2 * factor), (4 * factor)), (6 * factor), (3 * factor), null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, chest.bedrockName()), newImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.bedrockName()), newImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ public class ChestNormalTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (String variant : VARIANTS) {
|
for (String variant : VARIANTS) {
|
||||||
Texture texture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, CHEST_PATH + "/" + variant + ".png"));
|
Texture texture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, CHEST_PATH + "/" + variant + ".png"));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -86,7 +87,7 @@ public class ChestNormalTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
graphics.drawImage(ImageUtil.crop(chestImage, 0, 0, (6 * factor), (6 * factor)), 0, 0, null);
|
graphics.drawImage(ImageUtil.crop(chestImage, 0, 0, (6 * factor), (6 * factor)), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, CHEST_PATH + "/" + variant + ".png"), newChestImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, CHEST_PATH + "/" + variant + ".png"), newChestImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ public class ChestSideTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (ChestData chest : CHESTS) {
|
for (ChestData chest : CHESTS) {
|
||||||
Texture texture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, chest.javaName()));
|
Texture texture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.javaName()));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -66,7 +67,7 @@ public class ChestSideTransformer implements TextureTransformer {
|
|||||||
graphics.drawImage(ImageUtil.crop(fromImage, (28 * factor), (14 * factor), (14 * factor), (5 * factor)), 0, 0, null);
|
graphics.drawImage(ImageUtil.crop(fromImage, (28 * factor), (14 * factor), (14 * factor), (5 * factor)), 0, 0, null);
|
||||||
graphics.drawImage(ImageUtil.crop(fromImage, (28 * factor), (34 * factor), (14 * factor), (9 * factor)), 0, (5 * factor), null);
|
graphics.drawImage(ImageUtil.crop(fromImage, (28 * factor), (34 * factor), (14 * factor), (9 * factor)), 0, (5 * factor), null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, chest.bedrockName()), newImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, chest.bedrockName()), newImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ import java.io.IOException;
|
|||||||
public class ConduitTransformer implements TextureTransformer {
|
public class ConduitTransformer implements TextureTransformer {
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture baseTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, "entity/conduit/base.png"));
|
Texture baseTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/conduit/base.png"));
|
||||||
if (baseTexture != null) {
|
if (baseTexture != null) {
|
||||||
BufferedImage baseImage = this.readImage(baseTexture);
|
BufferedImage baseImage = this.readImage(baseTexture);
|
||||||
|
|
||||||
@@ -53,10 +54,10 @@ public class ConduitTransformer implements TextureTransformer {
|
|||||||
Graphics g = bedrockBaseImage.getGraphics();
|
Graphics g = bedrockBaseImage.getGraphics();
|
||||||
g.drawImage(ImageUtil.crop(baseImage, 0, 0, (int) (24 * scale), (int) (12 * scale)), 0, 0, null);
|
g.drawImage(ImageUtil.crop(baseImage, 0, 0, (int) (24 * scale), (int) (12 * scale)), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "blocks/conduit_base.png"), bedrockBaseImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "blocks/conduit_base.png"), bedrockBaseImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture eyeTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, "entity/conduit/closed_eye.png"));
|
Texture eyeTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/conduit/closed_eye.png"));
|
||||||
if (eyeTexture != null) {
|
if (eyeTexture != null) {
|
||||||
BufferedImage image = this.readImage(eyeTexture);
|
BufferedImage image = this.readImage(eyeTexture);
|
||||||
|
|
||||||
@@ -67,10 +68,10 @@ public class ConduitTransformer implements TextureTransformer {
|
|||||||
Graphics g = bedrockImage.getGraphics();
|
Graphics g = bedrockImage.getGraphics();
|
||||||
g.drawImage(ImageUtil.crop(image, 0, 0, (int) (8 * scale), (int) (8 * scale)), 0, 0, null);
|
g.drawImage(ImageUtil.crop(image, 0, 0, (int) (8 * scale), (int) (8 * scale)), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "blocks/conduit_closed.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "blocks/conduit_closed.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture eyeOpenTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, "entity/conduit/open_eye.png"));
|
Texture eyeOpenTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "entity/conduit/open_eye.png"));
|
||||||
if (eyeOpenTexture != null) {
|
if (eyeOpenTexture != null) {
|
||||||
BufferedImage image = this.readImage(eyeOpenTexture);
|
BufferedImage image = this.readImage(eyeOpenTexture);
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ public class ConduitTransformer implements TextureTransformer {
|
|||||||
Graphics g = bedrockImage.getGraphics();
|
Graphics g = bedrockImage.getGraphics();
|
||||||
g.drawImage(ImageUtil.crop(image, 0, 0, (int) (8 * scale), (int) (8 * scale)), 0, 0, null);
|
g.drawImage(ImageUtil.crop(image, 0, 0, (int) (8 * scale), (int) (8 * scale)), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "blocks/conduit_open.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "blocks/conduit_open.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ public class LiquidTransformer implements TextureTransformer {
|
|||||||
int minWidth = liquid.minWidth();
|
int minWidth = liquid.minWidth();
|
||||||
boolean grayscale = liquid.grayscale();
|
boolean grayscale = liquid.grayscale();
|
||||||
|
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, javaName));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, javaName));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -70,7 +71,7 @@ public class LiquidTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
liquidImage = ImageUtil.ensureMinWidth(liquidImage, minWidth);
|
liquidImage = ImageUtil.ensureMinWidth(liquidImage, minWidth);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, bedrockName), liquidImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, bedrockName), liquidImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.block;
|
package org.geysermc.pack.converter.type.texture.transformer.type.block;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -47,22 +48,22 @@ public class TallSeagrassTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture javaTop = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_TOP));
|
Texture javaTop = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_TOP));
|
||||||
|
|
||||||
if (javaTop != null) {
|
if (javaTop != null) {
|
||||||
BufferedImage javaImage = this.readImage(javaTop);
|
BufferedImage javaImage = this.readImage(javaTop);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BEDROCK_TOP.formatted("a")), javaImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BEDROCK_TOP.formatted("a")), javaImage, "png");
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BEDROCK_TOP.formatted("b")), ImageUtil.flip(javaImage, true, false), "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BEDROCK_TOP.formatted("b")), ImageUtil.flip(javaImage, true, false), "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture javaBottom = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_BOTTOM));
|
Texture javaBottom = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_BOTTOM));
|
||||||
|
|
||||||
if (javaBottom != null) {
|
if (javaBottom != null) {
|
||||||
BufferedImage javaImage = this.readImage(javaBottom);
|
BufferedImage javaImage = this.readImage(javaBottom);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BEDROCK_BOTTOM.formatted("a")), javaImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BEDROCK_BOTTOM.formatted("a")), javaImage, "png");
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BEDROCK_BOTTOM.formatted("b")), ImageUtil.flip(javaImage, true, false), "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BEDROCK_BOTTOM.formatted("b")), ImageUtil.flip(javaImage, true, false), "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ public class ArrowTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, INPUT));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, INPUT));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -76,6 +77,6 @@ public class ArrowTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
graphics.drawImage(fromImage, 0, 10 * factor, null);
|
graphics.drawImage(fromImage, 0, 10 * factor, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, OUTPUT), newArrowImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, OUTPUT), newArrowImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ public class DolphinTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture javaTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, LOCATION));
|
Texture javaTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, LOCATION));
|
||||||
if (javaTexture == null) return;
|
if (javaTexture == null) return;
|
||||||
|
|
||||||
BufferedImage javaImage = this.readImage(javaTexture);
|
BufferedImage javaImage = this.readImage(javaTexture);
|
||||||
@@ -590,6 +591,6 @@ public class DolphinTransformer implements TextureTransformer {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, LOCATION), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, LOCATION), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -47,8 +48,8 @@ public class DrownedTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture drownedTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, String.format(TEXTURE_PATH, DROWNED_TEXTURE)));
|
Texture drownedTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, String.format(TEXTURE_PATH, DROWNED_TEXTURE)));
|
||||||
Texture outerLayerTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, String.format(TEXTURE_PATH, DROWNED_OUTER_LAYER_TEXTURE)));
|
Texture outerLayerTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, String.format(TEXTURE_PATH, DROWNED_OUTER_LAYER_TEXTURE)));
|
||||||
|
|
||||||
if (drownedTexture == null || outerLayerTexture == null) {
|
if (drownedTexture == null || outerLayerTexture == null) {
|
||||||
return;
|
return;
|
||||||
@@ -71,6 +72,6 @@ public class DrownedTransformer implements TextureTransformer {
|
|||||||
graphics.drawImage(ImageUtil.crop(overlayImage, (int) (16 * factor), (int) (48 * factor), (int) (16 * factor), (int) (16 * factor)), 0, (int) (48 * factor), null);
|
graphics.drawImage(ImageUtil.crop(overlayImage, (int) (16 * factor), (int) (48 * factor), (int) (16 * factor), (int) (16 * factor)), 0, (int) (48 * factor), null);
|
||||||
graphics.drawImage(ImageUtil.crop(overlayImage, (int) (32 * factor), (int) (48 * factor), (int) (16 * factor), (int) (16 * factor)), (int) (48 * factor), (int) (48 * factor), null);
|
graphics.drawImage(ImageUtil.crop(overlayImage, (int) (32 * factor), (int) (48 * factor), (int) (16 * factor), (int) (16 * factor)), (int) (48 * factor), (int) (48 * factor), null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, String.format(TEXTURE_PATH, DROWNED_TEXTURE)), newImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, String.format(TEXTURE_PATH, DROWNED_TEXTURE)), newImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,22 +24,21 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
@@ -52,11 +51,11 @@ public class PaintingTransformer implements TextureTransformer {
|
|||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
// Let's check if we actually need to convert anything.
|
// Let's check if we actually need to convert anything.
|
||||||
boolean isAnyPresent = PAINTING_DATA.keySet().stream().anyMatch(key -> {
|
boolean isAnyPresent = PAINTING_DATA.keySet().stream().anyMatch(key -> {
|
||||||
return context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted(key)));
|
return context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted(key)));
|
||||||
});
|
});
|
||||||
|
|
||||||
// We don't map this like the others because bedrock is difficult, so it isn't in PAINTING_DATA.
|
// We don't map this like the others because bedrock is difficult, so it isn't in PAINTING_DATA.
|
||||||
isAnyPresent = isAnyPresent || context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted("back")));
|
isAnyPresent = isAnyPresent || context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted("back")));
|
||||||
|
|
||||||
if (!isAnyPresent) return; // we have nothing to convert, skip this
|
if (!isAnyPresent) return; // we have nothing to convert, skip this
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ public class PaintingTransformer implements TextureTransformer {
|
|||||||
Map<String, Float> scales = new HashMap<>();
|
Map<String, Float> scales = new HashMap<>();
|
||||||
|
|
||||||
PAINTING_DATA.forEach((key, value) -> {
|
PAINTING_DATA.forEach((key, value) -> {
|
||||||
Texture javaTexture = context.pollOrPeekVanilla(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted(key)));
|
Texture javaTexture = context.pollOrPeekVanilla(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted(key)));
|
||||||
if (javaTexture == null) {
|
if (javaTexture == null) {
|
||||||
scales.put(key, 1f);
|
scales.put(key, 1f);
|
||||||
return;
|
return;
|
||||||
@@ -83,7 +82,7 @@ public class PaintingTransformer implements TextureTransformer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Again, bedrock being difficult with back.
|
// Again, bedrock being difficult with back.
|
||||||
Texture backTexture = context.pollOrPeekVanilla(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted("back")));
|
Texture backTexture = context.pollOrPeekVanilla(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted("back")));
|
||||||
if (backTexture != null) {
|
if (backTexture != null) {
|
||||||
BufferedImage image = this.readImage(backTexture);
|
BufferedImage image = this.readImage(backTexture);
|
||||||
|
|
||||||
@@ -128,7 +127,7 @@ public class PaintingTransformer implements TextureTransformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "painting/kz.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "painting/kz.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
// BedrockX and BedrockY determine where the image is in kz.png (Bedrock painting atlas)
|
// BedrockX and BedrockY determine where the image is in kz.png (Bedrock painting atlas)
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -47,9 +48,9 @@ public class SheepTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Key sheepKey = Key.key(Key.MINECRAFT_NAMESPACE, SHEEP);
|
Key sheepKey = KeyUtil.key(Key.MINECRAFT_NAMESPACE, SHEEP);
|
||||||
Key woolKey = Key.key(Key.MINECRAFT_NAMESPACE, SHEEP_WOOL);
|
Key woolKey = KeyUtil.key(Key.MINECRAFT_NAMESPACE, SHEEP_WOOL);
|
||||||
Key undercoatKey = Key.key(Key.MINECRAFT_NAMESPACE, SHEEP_UNDERCOAT);
|
Key undercoatKey = KeyUtil.key(Key.MINECRAFT_NAMESPACE, SHEEP_UNDERCOAT);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!context.isTexturePresent(sheepKey) &&
|
!context.isTexturePresent(sheepKey) &&
|
||||||
@@ -93,6 +94,6 @@ public class SheepTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(sheepWoolImage, 0, sheepImage.getHeight(), null);
|
g.drawImage(sheepWoolImage, 0, sheepImage.getHeight(), null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, SHEEP), newImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, SHEEP), newImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,12 +24,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ public class VillagerTransformer implements TextureTransformer {
|
|||||||
for (String entity : ENTITIES) {
|
for (String entity : ENTITIES) {
|
||||||
for (String profession : VILLAGER_PROFESSIONS) {
|
for (String profession : VILLAGER_PROFESSIONS) {
|
||||||
String texturePath = String.format(TEXTURE_PATH, entity, profession);
|
String texturePath = String.format(TEXTURE_PATH, entity, profession);
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, texturePath));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, texturePath));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -91,7 +92,7 @@ public class VillagerTransformer implements TextureTransformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, texturePath), newImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, texturePath), newImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.entity;
|
package org.geysermc.pack.converter.type.texture.transformer.type.entity;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -53,7 +54,7 @@ public class ZombieTransformer implements TextureTransformer {
|
|||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (ZombieData zombieData : ZOMBIES) {
|
for (ZombieData zombieData : ZOMBIES) {
|
||||||
String zombie = zombieData.name();
|
String zombie = zombieData.name();
|
||||||
Key path = Key.key(Key.MINECRAFT_NAMESPACE, TEXTURE_PATH.formatted(zombie));
|
Key path = KeyUtil.key(Key.MINECRAFT_NAMESPACE, TEXTURE_PATH.formatted(zombie));
|
||||||
Texture texture = context.poll(path);
|
Texture texture = context.poll(path);
|
||||||
if (texture == null) continue;
|
if (texture == null) continue;
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ public class ZombieTransformer implements TextureTransformer {
|
|||||||
context.offer(path, bedrockImage, "png");
|
context.offer(path, bedrockImage, "png");
|
||||||
|
|
||||||
if (zombieData.mobHead()) {
|
if (zombieData.mobHead()) {
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, MOB_HEAD_PATH.formatted(zombie)), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, MOB_HEAD_PATH.formatted(zombie)), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,16 +24,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.item;
|
package org.geysermc.pack.converter.type.texture.transformer.type.item;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -67,8 +68,8 @@ public class BundleTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (String color : COLORS) {
|
for (String color : COLORS) {
|
||||||
Texture backTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, FRONT.formatted(color)));
|
Texture backTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, FRONT.formatted(color)));
|
||||||
Texture frontTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, BACK.formatted(color)));
|
Texture frontTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BACK.formatted(color)));
|
||||||
if (backTexture == null || frontTexture == null) continue; // TODO: If one is missing, pull from vanilla pack
|
if (backTexture == null || frontTexture == null) continue; // TODO: If one is missing, pull from vanilla pack
|
||||||
|
|
||||||
BufferedImage backImage = this.readImage(backTexture);
|
BufferedImage backImage = this.readImage(backTexture);
|
||||||
@@ -81,7 +82,7 @@ public class BundleTransformer implements TextureTransformer {
|
|||||||
g.drawImage(backImage, 0, 0, null);
|
g.drawImage(backImage, 0, 0, null);
|
||||||
g.drawImage(frontImage, 0, 0, null);
|
g.drawImage(frontImage, 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BEDROCK_OUTPUT.formatted(color)), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BEDROCK_OUTPUT.formatted(color)), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,13 +24,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.geysermc.pack.converter.util.Spritesheet;
|
import org.geysermc.pack.converter.util.Spritesheet;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
@@ -75,10 +76,10 @@ public class BaseParticleTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
// Create a grayscale bubble image
|
// Create a grayscale bubble image
|
||||||
Texture bubbleTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, PATH + "/bubble.png"));
|
Texture bubbleTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, PATH + "/bubble.png"));
|
||||||
if (bubbleTexture != null) {
|
if (bubbleTexture != null) {
|
||||||
BufferedImage bubble = this.readImage(bubbleTexture);
|
BufferedImage bubble = this.readImage(bubbleTexture);
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, PATH + "/bubble_gray.png"), ImageUtil.grayscale(bubble), "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, PATH + "/bubble_gray.png"), ImageUtil.grayscale(bubble), "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createSpritesheet(context);
|
this.createSpritesheet(context);
|
||||||
@@ -169,7 +170,7 @@ public class BaseParticleTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
context.debug(String.format("Creating particle spritesheet %s", OUTPUT));
|
context.debug(String.format("Creating particle spritesheet %s", OUTPUT));
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, PATH + "/" + OUTPUT), vanillaSprite, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, PATH + "/" + OUTPUT), vanillaSprite, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TextureData {
|
interface TextureData {
|
||||||
@@ -181,7 +182,7 @@ public class BaseParticleTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Key textureKey(int atlas) {
|
public Key textureKey(int atlas) {
|
||||||
return Key.key(Key.MINECRAFT_NAMESPACE, PATH + "/" + javaName + "_" + atlas + ".png");
|
return KeyUtil.key(Key.MINECRAFT_NAMESPACE, PATH + "/" + javaName + "_" + atlas + ".png");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -207,7 +208,7 @@ public class BaseParticleTransformer implements TextureTransformer {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, textureName + ".png"));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, textureName + ".png"));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class CampfireParticleTransformer extends SpritesheetParticleTransformer {
|
public class CampfireParticleTransformer extends SpritesheetParticleTransformer {
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class SculkChargeParticleTransformer extends SpritesheetParticleTransformer {
|
public class SculkChargeParticleTransformer extends SpritesheetParticleTransformer {
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class SculkChargePopParticleTransformer extends SpritesheetParticleTransformer {
|
public class SculkChargePopParticleTransformer extends SpritesheetParticleTransformer {
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class SculkSoulParticleTransformer extends SpritesheetParticleTransformer {
|
public class SculkSoulParticleTransformer extends SpritesheetParticleTransformer {
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class SonicExplosionParticleTransformer extends SpritesheetParticleTransformer {
|
public class SonicExplosionParticleTransformer extends SpritesheetParticleTransformer {
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class SoulParticleTransformer extends SpritesheetParticleTransformer {
|
public class SoulParticleTransformer extends SpritesheetParticleTransformer {
|
||||||
@@ -24,12 +24,13 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.particle;
|
package org.geysermc.pack.converter.type.texture.transformer.type.particle;
|
||||||
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.geysermc.pack.converter.util.Spritesheet;
|
import org.geysermc.pack.converter.util.Spritesheet;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
@@ -59,7 +60,7 @@ public class SpritesheetParticleTransformer implements TextureTransformer {
|
|||||||
BitSet occupiedSectors = new BitSet(this.atlasCount);
|
BitSet occupiedSectors = new BitSet(this.atlasCount);
|
||||||
Spritesheet spritesheet = new Spritesheet();
|
Spritesheet spritesheet = new Spritesheet();
|
||||||
for (int i = 0; i < this.atlasCount; i++) {
|
for (int i = 0; i < this.atlasCount; i++) {
|
||||||
Texture texture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, String.format(this.javaPath, i)));
|
Texture texture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, String.format(this.javaPath, i)));
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -95,6 +96,6 @@ public class SpritesheetParticleTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
context.debug(String.format("Creating particle spritesheet %s", this.bedrockPath));
|
context.debug(String.format("Creating particle spritesheet %s", this.bedrockPath));
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, this.bedrockPath), vanillaSprite, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, this.bedrockPath), vanillaSprite, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,26 +24,35 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.ui;
|
package org.geysermc.pack.converter.type.texture.transformer.type.ui;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.font.*;
|
import team.unnamed.creative.font.BitMapFontProvider;
|
||||||
import team.unnamed.creative.font.Font;
|
import team.unnamed.creative.font.Font;
|
||||||
|
import team.unnamed.creative.font.FontProvider;
|
||||||
|
import team.unnamed.creative.font.ReferenceFontProvider;
|
||||||
|
import team.unnamed.creative.font.SpaceFontProvider;
|
||||||
|
import team.unnamed.creative.font.UnihexFontProvider;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HexFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class FontTransformer implements TextureTransformer {
|
public class FontTransformer implements TextureTransformer {
|
||||||
@@ -69,7 +78,7 @@ public class FontTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
// Currently, only the default font is converted, custom fonts are not supported on bedrock
|
// Currently, only the default font is converted, custom fonts are not supported on bedrock
|
||||||
for (Font font : context.javaResourcePack().fonts()) {
|
for (Font font : context.javaResourcePack().fonts()) {
|
||||||
if (!font.key().equals(Key.key(Key.MINECRAFT_NAMESPACE, "default"))) continue;
|
if (!font.key().equals(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "default"))) continue;
|
||||||
|
|
||||||
for (FontProvider fontProvider : font.providers()) {
|
for (FontProvider fontProvider : font.providers()) {
|
||||||
unicodeFontData.addAll(handleFont(context, fontProvider));
|
unicodeFontData.addAll(handleFont(context, fontProvider));
|
||||||
@@ -77,15 +86,15 @@ public class FontTransformer implements TextureTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we have no data, don't stop yet, we may still want to generate some stuff from vanilla
|
// if we have no data, don't stop yet, we may still want to generate some stuff from vanilla
|
||||||
if (unicodeFontData.isEmpty()) {
|
if (unicodeFontData.isEmpty() && context.vanillaPack().isPresent()) {
|
||||||
if (
|
if (
|
||||||
!context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, "font/ascii.png")) &&
|
!context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/ascii.png")) &&
|
||||||
!context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, "font/accented.png")) &&
|
!context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/accented.png")) &&
|
||||||
!context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, "font/nonlatin_european.png"))
|
!context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/nonlatin_european.png"))
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
for (Font font : context.vanillaPack().fonts()) {
|
for (Font font : context.vanillaPack().get().fonts()) {
|
||||||
if (!font.key().equals(Key.key(Key.MINECRAFT_NAMESPACE, "default"))) continue;
|
if (!font.key().equals(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "default"))) continue;
|
||||||
|
|
||||||
for (FontProvider fontProvider : font.providers()) {
|
for (FontProvider fontProvider : font.providers()) {
|
||||||
unicodeFontData.addAll(handleFont(context, fontProvider));
|
unicodeFontData.addAll(handleFont(context, fontProvider));
|
||||||
@@ -225,8 +234,8 @@ public class FontTransformer implements TextureTransformer {
|
|||||||
} else if (fontProvider instanceof ReferenceFontProvider referenceFontProvider) {
|
} else if (fontProvider instanceof ReferenceFontProvider referenceFontProvider) {
|
||||||
// Refers to other fonts, so we need to read those
|
// Refers to other fonts, so we need to read those
|
||||||
Font font = context.javaResourcePack().font(referenceFontProvider.id());
|
Font font = context.javaResourcePack().font(referenceFontProvider.id());
|
||||||
if (font == null) { // Just maybe, the vanilla files are used
|
if (font == null && context.vanillaPack().isPresent()) { // Just maybe, the vanilla files are used
|
||||||
font = context.vanillaPack().font(referenceFontProvider.id());
|
font = context.vanillaPack().get().font(referenceFontProvider.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font == null) {
|
if (font == null) {
|
||||||
@@ -247,30 +256,30 @@ public class FontTransformer implements TextureTransformer {
|
|||||||
private void transformDefault8(@NotNull TransformContext context) throws IOException {
|
private void transformDefault8(@NotNull TransformContext context) throws IOException {
|
||||||
// Don't attempt to write default8 if we have no data to pull from, otherwise it's vanilla to vanilla
|
// Don't attempt to write default8 if we have no data to pull from, otherwise it's vanilla to vanilla
|
||||||
if (
|
if (
|
||||||
!context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, "font/ascii.png")) &&
|
!context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/ascii.png")) &&
|
||||||
!context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, "font/accented.png")) &&
|
!context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/accented.png")) &&
|
||||||
!context.isTexturePresent(Key.key(Key.MINECRAFT_NAMESPACE, "font/nonlatin_european.png"))
|
!context.isTexturePresent(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/nonlatin_european.png"))
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
// Store the java images to prevent constant image reading
|
// Store the java images to prevent constant image reading
|
||||||
Map<String, BufferedImage> imgs = new HashMap<>();
|
Map<String, BufferedImage> imgs = new HashMap<>();
|
||||||
Map<String, Integer> scales = new HashMap<>();
|
Map<String, Integer> scales = new HashMap<>();
|
||||||
|
|
||||||
Texture ascii = context.peekOrVanilla(Key.key(Key.MINECRAFT_NAMESPACE, "font/ascii.png"));
|
Texture ascii = context.peekOrVanilla(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/ascii.png"));
|
||||||
if (ascii != null) {
|
if (ascii != null) {
|
||||||
BufferedImage image = this.readImage(ascii);
|
BufferedImage image = this.readImage(ascii);
|
||||||
imgs.put("ascii", image);
|
imgs.put("ascii", image);
|
||||||
scales.put("ascii", image.getWidth() / 128);
|
scales.put("ascii", image.getWidth() / 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture accented = context.peekOrVanilla(Key.key(Key.MINECRAFT_NAMESPACE, "font/accented.png"));
|
Texture accented = context.peekOrVanilla(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/accented.png"));
|
||||||
if (accented != null) {
|
if (accented != null) {
|
||||||
BufferedImage image = this.readImage(accented);
|
BufferedImage image = this.readImage(accented);
|
||||||
imgs.put("accented", image);
|
imgs.put("accented", image);
|
||||||
scales.put("accented", image.getWidth() / 144);
|
scales.put("accented", image.getWidth() / 144);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture nonlatin_european = context.peekOrVanilla(Key.key(Key.MINECRAFT_NAMESPACE, "font/nonlatin_european.png"));
|
Texture nonlatin_european = context.peekOrVanilla(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "font/nonlatin_european.png"));
|
||||||
if (nonlatin_european != null) {
|
if (nonlatin_european != null) {
|
||||||
BufferedImage image = this.readImage(nonlatin_european);
|
BufferedImage image = this.readImage(nonlatin_european);
|
||||||
imgs.put("nonlatin_european", image);
|
imgs.put("nonlatin_european", image);
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.ui;
|
package org.geysermc.pack.converter.type.texture.transformer.type.ui;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ public class HotbarTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture javaHotbarTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, HOTBAR));
|
Texture javaHotbarTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, HOTBAR));
|
||||||
if (javaHotbarTexture == null) return;
|
if (javaHotbarTexture == null) return;
|
||||||
|
|
||||||
BufferedImage javaHotbarImage = readImage(javaHotbarTexture);
|
BufferedImage javaHotbarImage = readImage(javaHotbarTexture);
|
||||||
@@ -61,7 +62,7 @@ public class HotbarTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.crop(javaHotbarImage, 0, 0, scale, height), 0, 0, null);
|
g.drawImage(ImageUtil.crop(javaHotbarImage, 0, 0, scale, height), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/hotbar_start_cap.png"), bedrockStartHotbar, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/hotbar_start_cap.png"), bedrockStartHotbar, "png");
|
||||||
|
|
||||||
for (int i = 0; i <= 8; i++) {
|
for (int i = 0; i <= 8; i++) {
|
||||||
BufferedImage bedrockHotbarPart = new BufferedImage(scale * 20, height, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage bedrockHotbarPart = new BufferedImage(scale * 20, height, BufferedImage.TYPE_INT_ARGB);
|
||||||
@@ -70,7 +71,7 @@ public class HotbarTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
graphics.drawImage(ImageUtil.crop(javaHotbarImage, (i * 20 * scale) + scale, 0, scale * 20, height), 0, 0, null);
|
graphics.drawImage(ImageUtil.crop(javaHotbarImage, (i * 20 * scale) + scale, 0, scale * 20, height), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/hotbar_" + i + ".png"), bedrockHotbarPart, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/hotbar_" + i + ".png"), bedrockHotbarPart, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The texture is 1 wide, so 1 * scale = scale
|
// The texture is 1 wide, so 1 * scale = scale
|
||||||
@@ -80,9 +81,9 @@ public class HotbarTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.crop(javaHotbarImage, javaHotbarImage.getWidth() - scale, 0, scale, height), 0, 0, null);
|
g.drawImage(ImageUtil.crop(javaHotbarImage, javaHotbarImage.getWidth() - scale, 0, scale, height), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/hotbar_end_cap.png"), bedrockEndHotbar, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/hotbar_end_cap.png"), bedrockEndHotbar, "png");
|
||||||
|
|
||||||
Texture javaHotbarSelectionTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, HOTBAR_SELECTION));
|
Texture javaHotbarSelectionTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, HOTBAR_SELECTION));
|
||||||
if (javaHotbarSelectionTexture == null) return;
|
if (javaHotbarSelectionTexture == null) return;
|
||||||
|
|
||||||
BufferedImage javaHotbarSelectionImage = readImage(javaHotbarSelectionTexture);
|
BufferedImage javaHotbarSelectionImage = readImage(javaHotbarSelectionTexture);
|
||||||
@@ -99,6 +100,6 @@ public class HotbarTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.flip(ImageUtil.crop(javaHotbarSelectionImage, 0, 0, size, selectionScale), false, true), 0, size - selectionScale, null);
|
g.drawImage(ImageUtil.flip(ImageUtil.crop(javaHotbarSelectionImage, 0, 0, size, selectionScale), false, true), 0, size - selectionScale, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/selected_hotbar_slot.png"), bedrockHotbarSelection, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/selected_hotbar_slot.png"), bedrockHotbarSelection, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,20 +24,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.ui;
|
package org.geysermc.pack.converter.type.texture.transformer.type.ui;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
@@ -52,7 +52,7 @@ public class LocatorTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (Map.Entry<String, String> mapping : DOT_MAPPING.entrySet()) {
|
for (Map.Entry<String, String> mapping : DOT_MAPPING.entrySet()) {
|
||||||
Texture dotTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, mapping.getKey()));
|
Texture dotTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, mapping.getKey()));
|
||||||
if (dotTexture == null) continue;
|
if (dotTexture == null) continue;
|
||||||
|
|
||||||
BufferedImage dotImage = this.readImage(dotTexture);
|
BufferedImage dotImage = this.readImage(dotTexture);
|
||||||
@@ -71,10 +71,10 @@ public class LocatorTransformer implements TextureTransformer {
|
|||||||
// Also accounts for the scale a resource pack may offer
|
// Also accounts for the scale a resource pack may offer
|
||||||
g.drawImage(ImageUtil.crop(dotImage, scale, scale, bedrockSize, bedrockSize), 0, 0, null);
|
g.drawImage(ImageUtil.crop(dotImage, scale, scale, bedrockSize, bedrockSize), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, mapping.getValue()), bedrockDotImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, mapping.getValue()), bedrockDotImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture upArrowTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_arrow_up.png"));
|
Texture upArrowTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_arrow_up.png"));
|
||||||
if (upArrowTexture != null) {
|
if (upArrowTexture != null) {
|
||||||
BufferedImage javaImage = this.readImage(upArrowTexture);
|
BufferedImage javaImage = this.readImage(upArrowTexture);
|
||||||
|
|
||||||
@@ -86,10 +86,10 @@ public class LocatorTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.crop(javaImage, 0, 1, javaImage.getWidth(), scale * 4), 0, 0, null);
|
g.drawImage(ImageUtil.crop(javaImage, 0, 1, javaImage.getWidth(), scale * 4), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/locator_arrow_up.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/locator_arrow_up.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture downArrowTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_arrow_down.png"));
|
Texture downArrowTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_arrow_down.png"));
|
||||||
if (downArrowTexture != null) {
|
if (downArrowTexture != null) {
|
||||||
BufferedImage javaImage = this.readImage(downArrowTexture);
|
BufferedImage javaImage = this.readImage(downArrowTexture);
|
||||||
|
|
||||||
@@ -101,10 +101,10 @@ public class LocatorTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.crop(javaImage, 0, 0, javaImage.getWidth(), scale * 4), 0, 0, null);
|
g.drawImage(ImageUtil.crop(javaImage, 0, 0, javaImage.getWidth(), scale * 4), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/locator_arrow_down.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/locator_arrow_down.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture bgTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_background.png"));
|
Texture bgTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_background.png"));
|
||||||
if (bgTexture != null) {
|
if (bgTexture != null) {
|
||||||
BufferedImage javaImage = this.readImage(bgTexture);
|
BufferedImage javaImage = this.readImage(bgTexture);
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ public class LocatorTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.crop(javaImage, javaImage.getWidth() - (scale * 5), 0, scale * 5, javaImage.getHeight()), (scale * 182) - scale * 5, 0, null);
|
g.drawImage(ImageUtil.crop(javaImage, javaImage.getWidth() - (scale * 5), 0, scale * 5, javaImage.getHeight()), (scale * 182) - scale * 5, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/locator_bg.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/locator_bg.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.ui;
|
package org.geysermc.pack.converter.type.texture.transformer.type.ui;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -62,7 +63,7 @@ public class SignTransformer implements TextureTransformer {
|
|||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
for (SignData signData : SIGNS) {
|
for (SignData signData : SIGNS) {
|
||||||
Texture javaTexture = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted(signData.name)));
|
Texture javaTexture = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, JAVA_LOCATION.formatted(signData.name)));
|
||||||
if (javaTexture == null) continue;
|
if (javaTexture == null) continue;
|
||||||
|
|
||||||
BufferedImage javaImage = this.readImage(javaTexture);
|
BufferedImage javaImage = this.readImage(javaTexture);
|
||||||
@@ -75,7 +76,7 @@ public class SignTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.crop(javaImage, (int) (2 * scale), (int) (2 * scale), (int) (scale * 24), (int) (scale * 12)), 0, 0, null);
|
g.drawImage(ImageUtil.crop(javaImage, (int) (2 * scale), (int) (2 * scale), (int) (scale * 24), (int) (scale * 12)), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, BEDROCK_LOCATION.formatted(signData.bedrockName)), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, BEDROCK_LOCATION.formatted(signData.bedrockName)), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,17 +24,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.ui;
|
package org.geysermc.pack.converter.type.texture.transformer.type.ui;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
import org.geysermc.pack.converter.util.ImageUtil;
|
import org.geysermc.pack.converter.util.ImageUtil;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Graphics;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ import java.io.IOException;
|
|||||||
public class TitleTransformer implements TextureTransformer {
|
public class TitleTransformer implements TextureTransformer {
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture javaTexture = context.poll(Key.key(Key.MINECRAFT_NAMESPACE, "gui/title/minecraft.png"));
|
Texture javaTexture = context.poll(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/title/minecraft.png"));
|
||||||
if (javaTexture == null) return;
|
if (javaTexture == null) return;
|
||||||
|
|
||||||
BufferedImage javaImage = this.readImage(javaTexture);
|
BufferedImage javaImage = this.readImage(javaTexture);
|
||||||
@@ -56,6 +57,6 @@ public class TitleTransformer implements TextureTransformer {
|
|||||||
|
|
||||||
g.drawImage(ImageUtil.resize(ImageUtil.crop(javaImage, 0, 0, javaImage.getWidth(), javaImage.getHeight() - ((int) (scale * 79))), 1937, 333), 0, 0, null);
|
g.drawImage(ImageUtil.resize(ImageUtil.crop(javaImage, 0, 0, javaImage.getWidth(), javaImage.getHeight() - ((int) (scale * 79))), 1937, 333), 0, 0, null);
|
||||||
|
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/title.png"), bedrockImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/title.png"), bedrockImage, "png");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,22 +24,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter.texture.transformer.type.ui;
|
package org.geysermc.pack.converter.type.texture.transformer.type.ui;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.TextureTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.TransformContext;
|
import org.geysermc.pack.converter.type.texture.transformer.TransformContext;
|
||||||
|
import org.geysermc.pack.converter.util.KeyUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import team.unnamed.creative.texture.Texture;
|
import team.unnamed.creative.texture.Texture;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
// This isn't really a "transformer", we just include some files if an certain UI elements are present
|
// This isn't really a "transformer", we just include some files if an certain UI elements are present
|
||||||
// in order to get it to appear correctly, the mappings here are still done in textures.json or elsewhere
|
// in order to get it to appear correctly, the mappings here are still done in textures.json or elsewhere
|
||||||
@@ -47,29 +45,26 @@ import java.nio.charset.StandardCharsets;
|
|||||||
// Credit to Bedrock Tweaks, wouldn't know how to do this without their packs
|
// Credit to Bedrock Tweaks, wouldn't know how to do this without their packs
|
||||||
@AutoService(TextureTransformer.class)
|
@AutoService(TextureTransformer.class)
|
||||||
public class UISizeTransformer implements TextureTransformer {
|
public class UISizeTransformer implements TextureTransformer {
|
||||||
private static final Gson GSON = new GsonBuilder()
|
|
||||||
.setPrettyPrinting()
|
|
||||||
.create();
|
|
||||||
|
|
||||||
private static final JsonArray FULLBARSLICE = new JsonArray();
|
private static final JsonArray FULLBARSLICE = new JsonArray();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transform(@NotNull TransformContext context) throws IOException {
|
public void transform(@NotNull TransformContext context) throws IOException {
|
||||||
Texture emptyXp = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/experience_bar_background.png"));
|
Texture emptyXp = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/experience_bar_background.png"));
|
||||||
if (emptyXp != null) {
|
if (emptyXp != null) {
|
||||||
writeUiJson(context, this.readImage(emptyXp), "experiencebarempty", FULLBARSLICE);
|
writeUiJson(context, this.readImage(emptyXp), "experiencebarempty", FULLBARSLICE);
|
||||||
|
|
||||||
// Since we have the full image, we *don't* want this
|
// Since we have the full image, we *don't* want this
|
||||||
BufferedImage nubImage = new BufferedImage(11, 5, BufferedImage.TYPE_INT_ARGB);
|
BufferedImage nubImage = new BufferedImage(11, 5, BufferedImage.TYPE_INT_ARGB);
|
||||||
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, "ui/experiencenub.png"), nubImage, "png");
|
context.offer(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "ui/experiencenub.png"), nubImage, "png");
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture fullXp = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/experience_bar_progress.png"));
|
Texture fullXp = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/experience_bar_progress.png"));
|
||||||
if (fullXp != null) {
|
if (fullXp != null) {
|
||||||
writeUiJson(context, this.readImage(fullXp), "experiencebarfull", FULLBARSLICE);
|
writeUiJson(context, this.readImage(fullXp), "experiencebarfull", FULLBARSLICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture locatorBg = context.peek(Key.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_background.png"));
|
Texture locatorBg = context.peek(KeyUtil.key(Key.MINECRAFT_NAMESPACE, "gui/sprites/hud/locator_bar_background.png"));
|
||||||
if (locatorBg != null) {
|
if (locatorBg != null) {
|
||||||
BufferedImage image = this.readImage(locatorBg);
|
BufferedImage image = this.readImage(locatorBg);
|
||||||
|
|
||||||
@@ -97,7 +92,7 @@ public class UISizeTransformer implements TextureTransformer {
|
|||||||
baseSize.add(customHeight);
|
baseSize.add(customHeight);
|
||||||
rootObject.add("base_size", baseSize);
|
rootObject.add("base_size", baseSize);
|
||||||
|
|
||||||
context.bedrockResourcePack().addExtraFile(GSON.toJson(rootObject).getBytes(StandardCharsets.UTF_8), "textures/ui/%s.json".formatted(jsonName));
|
context.bedrockResourcePack().addExtraFile(rootObject, "textures/ui/%s.json".formatted(jsonName));
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,15 +24,22 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter;
|
package org.geysermc.pack.converter.util;
|
||||||
|
|
||||||
import org.geysermc.pack.converter.data.BaseConversionData;
|
import net.kyori.adventure.key.Key;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class BaseConverter implements Converter<BaseConversionData> {
|
@SuppressWarnings("PatternValidation")
|
||||||
|
public final class KeyUtil {
|
||||||
|
|
||||||
@Override
|
private KeyUtil() {
|
||||||
public BaseConversionData createConversionData(@NotNull ConversionDataCreationContext context) {
|
}
|
||||||
return new BaseConversionData(context.inputDirectory(), context.outputDirectory(), context.vanillaResourcePack());
|
|
||||||
|
public static @NotNull Key key(final @NotNull String string) {
|
||||||
|
return Key.key(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull Key key(final @NotNull String namespace, final @NotNull String value) {
|
||||||
|
return Key.key(namespace, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
* Copyright (c) 2025-2025 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -24,22 +24,31 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.pack.converter.converter;
|
package org.geysermc.pack.converter.util;
|
||||||
|
|
||||||
import java.util.List;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import java.util.ServiceLoader;
|
|
||||||
|
|
||||||
public class Converters {
|
public interface LogListenerHelper {
|
||||||
|
|
||||||
public static List<? extends Converter<?>> defaultConverters() {
|
LogListener logListener();
|
||||||
return defaultConverters(false);
|
|
||||||
|
default void debug(@NotNull String message) {
|
||||||
|
logListener().debug(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<? extends Converter<?>> defaultConverters(boolean experimental) {
|
default void info(@NotNull String message) {
|
||||||
return ServiceLoader.load(Converter.class).stream()
|
logListener().info(message);
|
||||||
.map(ServiceLoader.Provider::get)
|
}
|
||||||
.map(c -> (Converter<?>)c)
|
|
||||||
.filter(converter -> experimental || !converter.isExperimental())
|
default void warn(@NotNull String message) {
|
||||||
.toList();
|
logListener().warn(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void error(@NotNull String message) {
|
||||||
|
logListener().error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
default void error(@NotNull String message, @NotNull Throwable exception) {
|
||||||
|
logListener().error(message, exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,12 +26,16 @@
|
|||||||
|
|
||||||
package org.geysermc.pack.converter.util;
|
package org.geysermc.pack.converter.util;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.io.file.PathUtils;
|
import org.apache.commons.io.file.PathUtils;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.type.OverlayTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.type.OverlayTransformer;
|
||||||
import org.geysermc.pack.converter.converter.texture.transformer.type.entity.SheepTransformer;
|
import org.geysermc.pack.converter.type.texture.transformer.type.entity.SheepTransformer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@@ -40,7 +44,10 @@ import java.io.InputStream;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public final class VanillaPackProvider {
|
public final class VanillaPackProvider {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ package org.geysermc.pack.bedrock.resource;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import org.geysermc.pack.bedrock.resource.attachables.Attachables;
|
import org.geysermc.pack.bedrock.resource.attachables.Attachables;
|
||||||
import org.geysermc.pack.bedrock.resource.models.entity.ModelEntity;
|
import org.geysermc.pack.bedrock.resource.models.entity.ModelEntity;
|
||||||
import org.geysermc.pack.bedrock.resource.render_controllers.RenderControllers;
|
import org.geysermc.pack.bedrock.resource.render_controllers.RenderControllers;
|
||||||
@@ -44,9 +45,9 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -91,6 +92,16 @@ public class BedrockResourcePack {
|
|||||||
this.terrainTexture = terrainTexture;
|
this.terrainTexture = terrainTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the directory of the resource pack.
|
||||||
|
*
|
||||||
|
* @return the directory of the resource pack
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Path directory() {
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the manifest of the resource pack.
|
* Get the manifest of the resource pack.
|
||||||
*
|
*
|
||||||
@@ -500,6 +511,16 @@ public class BedrockResourcePack {
|
|||||||
this.extraFiles.put(location, bytes);
|
this.extraFiles.put(location, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an extra JSON file to the resource pack.
|
||||||
|
*
|
||||||
|
* @param element the contents of the file
|
||||||
|
* @param location the location of the file
|
||||||
|
*/
|
||||||
|
public void addExtraFile(@NotNull JsonElement element, @NotNull String location) {
|
||||||
|
addExtraFile(GSON.toJson(element).getBytes(StandardCharsets.UTF_8), location);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports the resource pack to the specified directory.
|
* Exports the resource pack to the specified directory.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user