1
0
mirror of https://github.com/GeyserMC/PackConverter.git synced 2026-01-04 15:31:36 +00:00

Add support for bulk converters

This commit is contained in:
RednedEpic
2023-05-28 19:49:29 -05:00
parent 257ca045cb
commit d853c91e7d
11 changed files with 206 additions and 55 deletions

View File

@@ -30,6 +30,10 @@ import com.google.auto.service.AutoService;
import org.geysermc.pack.converter.PackConversionContext;
import org.geysermc.pack.converter.PackConverter;
import org.geysermc.pack.converter.converter.Converter;
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.TransformedTexture;
import org.geysermc.pack.converter.converter.texture.transformer.bulk.BulkTextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.bulk.BulkTransformContext;
import org.geysermc.pack.converter.data.TextureConversionData;
import org.jetbrains.annotations.NotNull;
import team.unnamed.creative.texture.Texture;
@@ -37,7 +41,7 @@ import team.unnamed.creative.texture.Texture;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.stream.StreamSupport;
@@ -46,11 +50,17 @@ import java.util.stream.StreamSupport;
public class TextureConverter implements Converter<TextureConversionData> {
public static final String BEDROCK_TEXTURES_LOCATION = "textures";
private final List<BulkTextureTransformer> bulkTransformers = StreamSupport.stream(ServiceLoader.load(BulkTextureTransformer.class).spliterator(), false).toList();
private final List<TextureTransformer> transformers = StreamSupport.stream(ServiceLoader.load(TextureTransformer.class).spliterator(), false).toList();
@Override
public void convert(@NotNull PackConversionContext<TextureConversionData> context) throws Exception {
Collection<Texture> textures = context.javaResourcePack().textures();
List<Texture> textures = new ArrayList<>(context.javaResourcePack().textures());
BulkTransformContext bulkContext = new BulkTransformContext(context, textures);
for (BulkTextureTransformer bulkTransformer : this.bulkTransformers) {
bulkTransformer.transform(bulkContext);
}
for (Texture texture : textures) {
String output = texture.key().value();
@@ -63,7 +73,6 @@ public class TextureConverter implements Converter<TextureConversionData> {
}
transformedTexture = transformer.transform(context, transformedTexture);
if (transformedTexture == null) {
break;
}

View File

@@ -24,7 +24,7 @@
*
*/
package org.geysermc.pack.converter.converter.texture;
package org.geysermc.pack.converter.converter.texture.transformer;
import org.geysermc.pack.converter.PackConversionContext;
import org.geysermc.pack.converter.data.TextureConversionData;

View File

@@ -24,7 +24,7 @@
*
*/
package org.geysermc.pack.converter.converter.texture;
package org.geysermc.pack.converter.converter.texture.transformer;
import org.jetbrains.annotations.NotNull;
import team.unnamed.creative.texture.Texture;

View File

@@ -0,0 +1,36 @@
/*
* 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.transformer.bulk;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
public interface BulkTextureTransformer {
void transform(@NotNull BulkTransformContext context) throws IOException;
}

View File

@@ -0,0 +1,90 @@
/*
* 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.transformer.bulk;
import net.kyori.adventure.key.Key;
import org.geysermc.pack.converter.PackConversionContext;
import org.geysermc.pack.converter.data.TextureConversionData;
import org.geysermc.pack.converter.util.ImageUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import team.unnamed.creative.base.Writable;
import team.unnamed.creative.texture.Texture;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class BulkTransformContext {
private final PackConversionContext<TextureConversionData> conversionContext;
private final Collection<Texture> textures;
private final Map<Key, Texture> byKey = new HashMap<>();
public BulkTransformContext(PackConversionContext<TextureConversionData> conversionContext, Collection<Texture> textures) {
this.conversionContext = conversionContext;
this.textures = textures;
for (Texture texture : textures) {
this.byKey.put(texture.key(), texture);
}
}
public void info(@NotNull String message) {
this.conversionContext.info(message);
}
@Nullable
public Texture poll(@NotNull Key key) {
Texture remove = this.byKey.remove(key);
if (remove == null) {
return null;
}
this.textures.remove(remove);
return remove;
}
@Nullable
public Texture peek(@NotNull Key key) {
return this.byKey.get(key);
}
public void offer(@NotNull Key key, @NotNull BufferedImage image, @NotNull String format) throws IOException {
this.offer(Texture.of(key, Writable.bytes(ImageUtil.toByteArray(image, format))));
}
public void offer(@NotNull Texture texture) {
this.textures.add(texture);
this.byKey.put(texture.key(), texture);
}
public boolean containsKey(@NotNull Key key) {
return this.byKey.containsKey(key);
}
}

View File

@@ -24,71 +24,58 @@
*
*/
package org.geysermc.packconverter.converters;
package org.geysermc.pack.converter.converter.texture.transformer.bulk.type;
import com.google.auto.service.AutoService;
import lombok.Getter;
import org.geysermc.packconverter.PackConversionContext;
import org.geysermc.packconverter.PackConverter;
import org.geysermc.packconverter.utils.ImageUtils;
import net.kyori.adventure.key.Key;
import org.geysermc.pack.converter.converter.texture.transformer.bulk.BulkTextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.bulk.BulkTransformContext;
import org.jetbrains.annotations.NotNull;
import team.unnamed.creative.texture.Texture;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@AutoService(Converter.class)
public class AtlasConverter extends AbstractConverter {
@Getter
public static final List<Object[]> defaultData = new ArrayList<>();
static {
defaultData.add(new Object[] {"textures/items/clock_", 63, "textures/items/watch_atlas.png"});
defaultData.add(new Object[] {"textures/items/compass_", 31, "textures/items/compass_atlas.png"});
}
@AutoService(BulkTextureTransformer.class)
public class AtlasTransformer implements BulkTextureTransformer {
private static final List<AtlasData> ATLASES = List.of(
new AtlasData("item/clock_%s.png", "items/watch_atlas.png", 63),
new AtlasData("item/compass_%s.png", "items/compass_atlas.png", 31)
);
@Override
public void convert(@NotNull PackConversionContext context) {
List<AbstractConverter> delete = new ArrayList<>();
public void transform(@NotNull BulkTransformContext context) throws IOException {
for (AtlasData atlas : ATLASES) {
String javaName = atlas.javaName();
String bedrockName = atlas.bedrockName();
int atlasCount = atlas.altasCount();
try {
String base = (String) context.data()[0];
int count = (int) context.data()[1];
String to = (String) context.data()[2];
BufferedImage atlasImage = null;
for (int i = 0; i <= count; i++) {
String step = base + String.format("%1$2s", i).replace(" ", "0") + ".png";
File stepFile = context.storage().resolve(step).toFile();
if (!stepFile.exists()) {
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"))));
if (texture == null) {
continue;
}
BufferedImage stepImage = ImageIO.read(stepFile);
BufferedImage stepImage = ImageIO.read(new ByteArrayInputStream(texture.data().toByteArray()));
if (atlasImage == null) {
context.log(String.format("Create atlas %s", to));
atlasImage = new BufferedImage(stepImage.getWidth(), stepImage.getHeight() * (count + 1), BufferedImage.TYPE_INT_ARGB);
context.info(String.format("Creating atlas %s", bedrockName));
atlasImage = new BufferedImage(stepImage.getWidth(), stepImage.getHeight() * (atlasCount + 1), BufferedImage.TYPE_INT_ARGB);
}
atlasImage.getGraphics().drawImage(stepImage, 0, (stepImage.getHeight() * i), null);
delete.add(new DeleteConverter(packConverter, storage, new Object[] {step}));
}
if (atlasImage != null) {
ImageUtils.write(atlasImage, "png", storage.resolve(to).toFile());
context.offer(Key.key(Key.MINECRAFT_NAMESPACE, bedrockName), atlasImage, "png");
context.info(String.format("Created atlas %s", bedrockName));
}
} catch (IOException e) { }
}
}
return delete;
record AtlasData(String javaName, String bedrockName, int altasCount) {
}
}

View File

@@ -24,10 +24,10 @@
*
*/
package org.geysermc.pack.converter.converter.texture.transformer.path;
package org.geysermc.pack.converter.converter.texture.transformer.type.path;
import com.google.auto.service.AutoService;
import org.geysermc.pack.converter.converter.texture.TextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
@AutoService(TextureTransformer.class)
public class BlockTextureTransformer extends PathTransformer {

View File

@@ -24,10 +24,10 @@
*
*/
package org.geysermc.pack.converter.converter.texture.transformer.path;
package org.geysermc.pack.converter.converter.texture.transformer.type.path;
import com.google.auto.service.AutoService;
import org.geysermc.pack.converter.converter.texture.TextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
@AutoService(TextureTransformer.class)
public class ItemTextureTransformer extends PathTransformer {

View File

@@ -24,12 +24,12 @@
*
*/
package org.geysermc.pack.converter.converter.texture.transformer.path;
package org.geysermc.pack.converter.converter.texture.transformer.type.path;
import org.geysermc.pack.converter.PackConversionContext;
import org.geysermc.pack.converter.converter.texture.TextureConverter;
import org.geysermc.pack.converter.converter.texture.TextureTransformer;
import org.geysermc.pack.converter.converter.texture.TransformedTexture;
import org.geysermc.pack.converter.converter.texture.transformer.TextureTransformer;
import org.geysermc.pack.converter.converter.texture.transformer.TransformedTexture;
import org.geysermc.pack.converter.data.TextureConversionData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -48,7 +48,7 @@ public class PathTransformer implements TextureTransformer {
@Override
public boolean filter(@NotNull Texture texture) {
return texture.key().value().startsWith(this.input);
return texture.key().value().startsWith(this.input + "/");
}
@Override

View File

@@ -26,7 +26,7 @@
package org.geysermc.pack.converter.data;
import org.geysermc.pack.converter.converter.texture.TransformedTexture;
import org.geysermc.pack.converter.converter.texture.transformer.TransformedTexture;
import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;

View File

@@ -30,8 +30,11 @@ import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public class ImageUtil {
@@ -183,6 +186,32 @@ public class ImageUtil {
ImageIO.write(img, format, output);
}
/**
* Convert a {@link BufferedImage} to an {@link InputStream}
*
* @param img Image to use
* @param format Format to use
* @return InputStream of the image
* @throws IOException
*/
public static InputStream toInputStream(BufferedImage img, String format) throws IOException {
return new ByteArrayInputStream(toByteArray(img, format));
}
/**
* Convert a {@link BufferedImage} to a byte array
*
* @param img Image to use
* @param format Format to use
* @return Byte array of the image
* @throws IOException
*/
public static byte[] toByteArray(BufferedImage img, String format) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, format, os);
return os.toByteArray();
}
/**
* Convert a {@link BufferedImage} to grayscale
*