feat: integrated Glyphs library
This commit is contained in:
parent
fadc170c62
commit
e8c588b2b6
@ -10,6 +10,8 @@ import java.net.InetSocketAddress;
|
||||
@Log4j2
|
||||
public class ServerBootstrap {
|
||||
|
||||
public static final ClassLoader CLASS_LOADER = ServerBootstrap.class.getClassLoader();
|
||||
|
||||
private static final String[] LOGO = {
|
||||
"==============================================",
|
||||
"Minestom Server Base v3 - by ScarletRedMan",
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package ru.dragonestia.msb3.api.glyph;
|
||||
|
||||
public final class GlyphConstants {
|
||||
|
||||
public static final int CHEST_GUI_WIDTH = 176;
|
||||
public static final int DEFAULT_CHAT_WIDTH = 320;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package ru.dragonestia.msb3.api.glyph.compile;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface ArbitraryCharacterFactory {
|
||||
|
||||
@NotNull Character nextCharacter() throws IllegalStateException;
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package ru.dragonestia.msb3.api.glyph.compile;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class DefaultArbitraryCharacterFactory implements ArbitraryCharacterFactory {
|
||||
|
||||
private final static Set<Character> reservedCharacters = new HashSet<>();
|
||||
|
||||
static {
|
||||
for (char c = 'a'; c <= 'z'; c++) reservedCharacters.add(c);
|
||||
for (char c = 'A'; c <= 'Z'; c++) reservedCharacters.add(c);
|
||||
for (char c = 'а'; c <= 'я'; c++) reservedCharacters.add(c);
|
||||
for (char c = 'А'; c <= 'Я'; c++) reservedCharacters.add(c);
|
||||
for (char c = '0'; c <= '9'; c++) reservedCharacters.add(c);
|
||||
|
||||
reservedCharacters.addAll(Arrays.asList(
|
||||
'!', '?', ':', '$',
|
||||
';', '#', '@', '%',
|
||||
'^', '&', '*', '(',
|
||||
')', '_', '-', '+',
|
||||
'/', '\\', '№', '"',
|
||||
'\'', '{', '}', '[',
|
||||
']', '~', '`', '<', '>',
|
||||
',', '.', '|', '\n', '\r',
|
||||
'\b', '\f', '\t', ' ',
|
||||
'ё', 'Ё', '=')
|
||||
);
|
||||
}
|
||||
|
||||
private char currentChar = '\uA201';
|
||||
|
||||
@Override
|
||||
public @NotNull Character nextCharacter() throws IllegalStateException {
|
||||
if (currentChar == Character.MAX_VALUE) {
|
||||
throw new IllegalStateException("Characters range exceeded");
|
||||
}
|
||||
|
||||
do {
|
||||
currentChar++;
|
||||
} while (!isCharacterAllowed(currentChar));
|
||||
return currentChar;
|
||||
}
|
||||
|
||||
private boolean isCharacterAllowed(char c) {
|
||||
return !reservedCharacters.contains(c);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package ru.dragonestia.msb3.api.glyph.compile;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import team.unnamed.creative.font.Font;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
import team.unnamed.creative.part.ResourcePackPart;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DefaultGlyphCompiler implements GlyphCompiler {
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull ResourcePackPart> compile(@NotNull Collection<@NotNull ResourceProducer> producers) {
|
||||
Set<ResourcePackPart> fileResources = new HashSet<>();
|
||||
|
||||
Set<Key> fontKeys = producers
|
||||
.stream()
|
||||
.map(ResourceProducer::fontKey)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
for (Key key : fontKeys) {
|
||||
List<FontProvider> fontProviders = new ArrayList<>();
|
||||
ArbitraryCharacterFactory characterFactory = new DefaultArbitraryCharacterFactory();
|
||||
for (ResourceProducer producer : producers) {
|
||||
if (producer.fontKey().equals(key)) {
|
||||
producer.produceResources(characterFactory);
|
||||
// Add font providers for current font key
|
||||
fontProviders.addAll(producer.fontProviders());
|
||||
// Add textures to common set with resources
|
||||
fileResources.addAll(producer.textures());
|
||||
}
|
||||
}
|
||||
fileResources.add(Font.font(key, fontProviders));
|
||||
}
|
||||
|
||||
return fileResources;
|
||||
}
|
||||
|
||||
<T> Iterable<T> toIterable(final Stream<T> stream) {
|
||||
return stream::iterator;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package ru.dragonestia.msb3.api.glyph.compile;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import team.unnamed.creative.part.ResourcePackPart;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public interface GlyphCompiler {
|
||||
|
||||
static GlyphCompiler instance() {
|
||||
return new DefaultGlyphCompiler();
|
||||
}
|
||||
|
||||
@NotNull Collection<@NotNull ResourcePackPart> compile(@NotNull Collection<@NotNull ResourceProducer> resourceProducerCollection);
|
||||
|
||||
default @NotNull Collection<@NotNull ResourcePackPart> compile(@NotNull ResourceProducer... resourceProducer) {
|
||||
return compile(Arrays.asList(resourceProducer));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package ru.dragonestia.msb3.api.glyph.compile;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceAlreadyProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public interface ResourceProducer {
|
||||
|
||||
@NotNull Key fontKey();
|
||||
|
||||
boolean produced();
|
||||
|
||||
void produceResources(ArbitraryCharacterFactory characterFactory) throws ResourceAlreadyProducedException;
|
||||
|
||||
@NotNull Collection<@NotNull FontProvider> fontProviders() throws ResourceNotProducedException;
|
||||
|
||||
default @NotNull Collection<@NotNull Texture> textures() throws ResourceNotProducedException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package ru.dragonestia.msb3.api.glyph.font;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.GlyphCompiler;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter.LanguageGlyphCollection;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyphResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.mojang.MojangSpacesGlyph;
|
||||
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.part.ResourcePackPart;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class GlyphFont {
|
||||
|
||||
public static final SpacesGlyphResourceProducer SPACES = MojangSpacesGlyph.create();
|
||||
private static final Key MINECRAFT_FONT_KEY = Key.key(Glyph.DEFAULT_NAMESPACE, "minecraft_font");
|
||||
private static final Writable MINECRAFT_FONT_IMAGE_WRITABLE = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/defaults/minecraft_font.png");
|
||||
public static final LanguageGlyphCollection LANGUAGE_GLYPH = minecraftFontGlyphCollection(
|
||||
MINECRAFT_FONT_KEY,
|
||||
Key.key(MINECRAFT_FONT_KEY.asString().concat(".png")),
|
||||
List.of(new TextureProperties(12,-6),
|
||||
new TextureProperties(8,-24),
|
||||
new TextureProperties(8,-36)));
|
||||
|
||||
private GlyphFont() {}
|
||||
|
||||
public static Collection<ResourcePackPart> compile() {
|
||||
return GlyphCompiler.instance().compile(SPACES, LANGUAGE_GLYPH);
|
||||
}
|
||||
|
||||
private static @NotNull LanguageGlyphCollection minecraftFontGlyphCollection(@NotNull Key fontKey, @NotNull Key textureKey, @NotNull List<@NotNull TextureProperties> propertiesList) {
|
||||
return LanguageGlyphCollection.of(fontKey,
|
||||
Texture.texture(textureKey, MINECRAFT_FONT_IMAGE_WRITABLE),
|
||||
propertiesList,
|
||||
List.of(" АБВГДЕЖЗИК",
|
||||
"ЛМНОПРСТУФХЦЧШЩЪ",
|
||||
"ЫЬЭЮЯабвгдежзикл",
|
||||
"мнопрстуфхцчшщъы",
|
||||
"ьэюяйЙёЁ ",
|
||||
"₽!\"#$%&'()*+,-./",
|
||||
"0123456789: <=>?",
|
||||
"@ABCDEFGHIJKLMNO",
|
||||
"PQRSTUVWXYZ[\\]^_",
|
||||
"`abcdefghijklmno",
|
||||
"pqrstuvwxyz{|} ")
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph;
|
||||
|
||||
public interface AppendableGlyph extends Glyph {}
|
||||
@ -0,0 +1,24 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class EmptyGlyph implements AppendableGlyph {
|
||||
|
||||
public static final EmptyGlyph INSTANCE = new EmptyGlyph();
|
||||
|
||||
@Override
|
||||
public @NotNull Component toAdventure() throws ResourceNotProducedException {
|
||||
return Component.text("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
|
||||
public interface Glyph {
|
||||
|
||||
String DEFAULT_NAMESPACE = "glyphs";
|
||||
|
||||
Key DEFAULT_FONT_KEY = Key.key(DEFAULT_NAMESPACE, "default");
|
||||
|
||||
Key DEFAULT_SPACES_FONT_KEY = Key.key(DEFAULT_NAMESPACE, "spaces");
|
||||
|
||||
int SEPARATOR_WIDTH = 1;
|
||||
|
||||
@NotNull Component toAdventure() throws ResourceNotProducedException;
|
||||
|
||||
int width();
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyphResourceProducer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface GlyphComponentBuilder {
|
||||
|
||||
static @NotNull GlyphComponentBuilder universal(SpacesGlyphResourceProducer spacesProducer) {
|
||||
return new GlyphComponentBuilderImpl(spacesProducer, 0, Component.text(""));
|
||||
}
|
||||
|
||||
static @NotNull GlyphComponentBuilder gui(SpacesGlyphResourceProducer spacesProducer) {
|
||||
return new GlyphComponentBuilderImpl(spacesProducer, -8, Component.text("", NamedTextColor.WHITE));
|
||||
}
|
||||
|
||||
@NotNull GlyphComponentBuilder append(PositionType positionType, int position, @NotNull AppendableGlyph glyph);
|
||||
|
||||
default @NotNull GlyphComponentBuilder append(PositionType positionType, @NotNull AppendableGlyph glyph) {
|
||||
return append(positionType, 0, glyph);
|
||||
}
|
||||
|
||||
@NotNull GlyphComponentBuilder append(PositionType positionType, int position, @NotNull List<? extends @NotNull AppendableGlyph> glyphList);
|
||||
|
||||
default @NotNull GlyphComponentBuilder append(PositionType positionType, @NotNull List<? extends @NotNull AppendableGlyph> glyphList) {
|
||||
return append(positionType, 0, glyphList);
|
||||
}
|
||||
|
||||
// Append with default position type
|
||||
|
||||
default @NotNull GlyphComponentBuilder append(int position, @NotNull AppendableGlyph glyph) {
|
||||
return append(PositionType.ABSOLUTE, position, glyph);
|
||||
}
|
||||
|
||||
default @NotNull GlyphComponentBuilder append(@NotNull AppendableGlyph glyph) {
|
||||
return append(PositionType.ABSOLUTE, glyph);
|
||||
}
|
||||
|
||||
default @NotNull GlyphComponentBuilder append(int position, @NotNull List<? extends @NotNull AppendableGlyph> glyphList) {
|
||||
return append(PositionType.ABSOLUTE, position, glyphList);
|
||||
}
|
||||
|
||||
default @NotNull GlyphComponentBuilder append(@NotNull List<? extends @NotNull AppendableGlyph> glyphList) {
|
||||
return append(PositionType.ABSOLUTE, glyphList);
|
||||
}
|
||||
|
||||
@NotNull Component build(boolean keepInitialPosition);
|
||||
|
||||
default @NotNull Component build() {
|
||||
return build(true);
|
||||
}
|
||||
|
||||
enum PositionType {
|
||||
ABSOLUTE,
|
||||
RELATIVE
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyphResourceProducer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class GlyphComponentBuilderImpl implements GlyphComponentBuilder {
|
||||
|
||||
private final SpacesGlyphResourceProducer spacesProducer;
|
||||
private final int initialPosition;
|
||||
private final Component baseComponent;
|
||||
|
||||
private final List<Glyph> glyphs = new ArrayList<>();
|
||||
|
||||
private int previousElementsWidth;
|
||||
|
||||
@Override
|
||||
public @NotNull GlyphComponentBuilder append(PositionType positionType, int position, @NotNull AppendableGlyph glyph) {
|
||||
if (positionType == PositionType.ABSOLUTE && previousElementsWidth != 0) {
|
||||
glyphs.add(spacesProducer.translate((-1) * previousElementsWidth));
|
||||
previousElementsWidth = 0;
|
||||
}
|
||||
|
||||
if (position != 0) {
|
||||
glyphs.add(spacesProducer.translate(position));
|
||||
}
|
||||
|
||||
glyphs.add(glyph);
|
||||
this.previousElementsWidth += position + glyph.width();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull GlyphComponentBuilder append(PositionType positionType, int position, @NotNull List<? extends @NotNull AppendableGlyph> glyphList) {
|
||||
if (positionType == PositionType.ABSOLUTE && previousElementsWidth != 0) {
|
||||
glyphs.add(spacesProducer.translate((-1) * previousElementsWidth));
|
||||
previousElementsWidth = 0;
|
||||
}
|
||||
|
||||
if (position != 0) {
|
||||
glyphs.add(spacesProducer.translate(position));
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
for (AppendableGlyph glyph : glyphList) {
|
||||
glyphs.add(glyph);
|
||||
width += glyph.width();
|
||||
}
|
||||
|
||||
this.previousElementsWidth += position + width;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component build(boolean keepInitialPosition) {
|
||||
if (keepInitialPosition) {
|
||||
previousElementsWidth += initialPosition;
|
||||
|
||||
// Component should have zero width finally
|
||||
if (previousElementsWidth != 0) {
|
||||
glyphs.add(spacesProducer.translate((-1) * previousElementsWidth));
|
||||
}
|
||||
}
|
||||
|
||||
var component = baseComponent;
|
||||
|
||||
if (initialPosition != 0) {
|
||||
component = component.append(spacesProducer.translate(initialPosition).toAdventure());
|
||||
}
|
||||
|
||||
for (Glyph glyph : glyphs) {
|
||||
component = component.append(glyph.toAdventure());
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.exception;
|
||||
|
||||
public class ResourceAlreadyProducedException extends RuntimeException {}
|
||||
@ -0,0 +1,3 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.exception;
|
||||
|
||||
public class ResourceNotProducedException extends RuntimeException {}
|
||||
@ -0,0 +1,33 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.AppendableGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
public interface ImageGlyph extends AppendableGlyph, ResourceProducer {
|
||||
|
||||
static @NotNull ImageGlyph of(@NotNull Key key,
|
||||
@NotNull Texture texture,
|
||||
@NotNull TextureProperties properties) {
|
||||
return new ImageGlyphImpl(key, texture, properties);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
static @NotNull ImageGlyph of(@NotNull Texture texture,
|
||||
@NotNull TextureProperties properties) {
|
||||
return of(Glyph.DEFAULT_FONT_KEY, texture, properties);
|
||||
}
|
||||
|
||||
@NotNull Character character() throws ResourceNotProducedException;
|
||||
|
||||
@NotNull Texture texture();
|
||||
|
||||
default @NotNull Component toAdventure() throws ResourceNotProducedException {
|
||||
return Component.text(character()).font(fontKey());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ArbitraryCharacterFactory;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceAlreadyProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.util.ImageUtil;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class ImageGlyphImpl implements ImageGlyph {
|
||||
|
||||
private final Key fontKey;
|
||||
private final Texture texture;
|
||||
private final TextureProperties properties;
|
||||
|
||||
private Character character;
|
||||
private Set<FontProvider> fontProviders;
|
||||
|
||||
private int width = -1;
|
||||
|
||||
@Override
|
||||
public @NotNull Key fontKey() {
|
||||
return fontKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean produced() {
|
||||
return fontProviders != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produceResources(ArbitraryCharacterFactory characterFactory) throws ResourceAlreadyProducedException {
|
||||
if (fontProviders != null) {
|
||||
throw new ResourceAlreadyProducedException();
|
||||
}
|
||||
|
||||
var fontProviderBuilder = FontProvider.bitMap();
|
||||
|
||||
this.character = characterFactory.nextCharacter();
|
||||
|
||||
fontProviderBuilder.characters(String.valueOf(character));
|
||||
fontProviderBuilder.file(texture.key());
|
||||
fontProviderBuilder.ascent(properties.ascent());
|
||||
fontProviderBuilder.height(properties.height());
|
||||
|
||||
this.fontProviders = Collections.singleton(fontProviderBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull FontProvider> fontProviders() throws ResourceNotProducedException {
|
||||
if (fontProviders == null) {
|
||||
throw new ResourceNotProducedException();
|
||||
}
|
||||
return fontProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull Texture> textures() throws ResourceNotProducedException {
|
||||
return Collections.singleton(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
if (width == -1) {
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(new ByteArrayInputStream(texture.data().toByteArray()));
|
||||
int fileHeight = image.getHeight();
|
||||
width = (int) Math.ceil(
|
||||
((double) properties.height() / (double) fileHeight)
|
||||
* ImageUtil.calculateWidth(image)) + Glyph.SEPARATOR_WIDTH;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Character character() throws ResourceNotProducedException {
|
||||
if (fontProviders == null) {
|
||||
throw new ResourceNotProducedException();
|
||||
}
|
||||
return character;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Texture texture() {
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image;
|
||||
|
||||
public record TextureProperties(int height, int ascent) {}
|
||||
@ -0,0 +1,11 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter;
|
||||
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ColorableGlyph {
|
||||
|
||||
@Nullable TextColor color();
|
||||
|
||||
void updateColor(@Nullable TextColor color);
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.AppendableGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LanguageGlyphCollection extends ResourceProducer {
|
||||
|
||||
static @NotNull LanguageGlyphCollection of(@NotNull Key fontKey,
|
||||
@NotNull Texture texture,
|
||||
@NotNull List<@NotNull TextureProperties> propertiesList,
|
||||
@NotNull List<@NotNull String> charactersMapping) {
|
||||
return new LanguageGlyphCollectionImpl(fontKey, texture, propertiesList, charactersMapping);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
static @NotNull LanguageGlyphCollection of(@NotNull Texture texture,
|
||||
@NotNull List<@NotNull TextureProperties> propertiesList,
|
||||
@NotNull List<@NotNull String> charactersMapping) {
|
||||
return of(Glyph.DEFAULT_FONT_KEY, texture, propertiesList, charactersMapping);
|
||||
}
|
||||
|
||||
@NotNull AppendableGlyph translate(int height, int ascent, @NotNull Character character, @Nullable TextColor color) throws IllegalArgumentException;
|
||||
|
||||
@NotNull List<@NotNull AppendableGlyph> translate(int height, int ascent, @NotNull String text, @Nullable TextColor color) throws IllegalArgumentException;
|
||||
|
||||
default @NotNull AppendableGlyph translate(int height, int ascent, @NotNull Character character) throws IllegalArgumentException {
|
||||
return translate(height, ascent, character, null);
|
||||
}
|
||||
|
||||
default @NotNull List<@NotNull AppendableGlyph> translate(int height, int ascent, @NotNull String text) throws IllegalArgumentException {
|
||||
return translate(height, ascent, text, null);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ArbitraryCharacterFactory;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.AppendableGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceAlreadyProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LanguageGlyphCollectionImpl implements LanguageGlyphCollection {
|
||||
|
||||
private final Key fontKey;
|
||||
private final Texture texture;
|
||||
|
||||
private final Map<TextureProperties, MulticharacterImageGlyphCollection> propertiesToMulticharacterMap = new HashMap<>();
|
||||
|
||||
private Set<FontProvider> fontProviders;
|
||||
|
||||
LanguageGlyphCollectionImpl(
|
||||
Key fontKey,
|
||||
Texture texture,
|
||||
List<TextureProperties> propertiesList,
|
||||
List<String> charactersMapping
|
||||
) {
|
||||
this.fontKey = fontKey;
|
||||
this.texture = texture;
|
||||
|
||||
for (TextureProperties properties : propertiesList) {
|
||||
propertiesToMulticharacterMap.put(properties, MulticharacterImageGlyphCollection.of(fontKey, texture, properties, charactersMapping));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull Key fontKey() {
|
||||
return fontKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean produced() {
|
||||
return fontProviders != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produceResources(ArbitraryCharacterFactory characterFactory) throws ResourceAlreadyProducedException {
|
||||
if (fontProviders != null) {
|
||||
throw new ResourceAlreadyProducedException();
|
||||
}
|
||||
|
||||
fontProviders = new HashSet<>();
|
||||
|
||||
for (var entry : propertiesToMulticharacterMap.entrySet()) {
|
||||
entry.getValue().produceResources(characterFactory);
|
||||
fontProviders.addAll(entry.getValue().fontProviders());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull FontProvider> fontProviders() throws ResourceNotProducedException {
|
||||
return fontProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull Texture> textures() throws ResourceNotProducedException {
|
||||
return Collections.singleton(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull AppendableGlyph translate(int height, int ascent, @NotNull Character character, @Nullable TextColor color) throws IllegalArgumentException {
|
||||
TextureProperties properties = new TextureProperties(height, ascent);
|
||||
if (!propertiesToMulticharacterMap.containsKey(properties)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return propertiesToMulticharacterMap.get(properties).translate(character, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<@NotNull AppendableGlyph> translate(int height, int ascent, @NotNull String text, @Nullable TextColor color) throws IllegalArgumentException {
|
||||
TextureProperties properties = new TextureProperties(height, ascent);
|
||||
if (!propertiesToMulticharacterMap.containsKey(properties)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return propertiesToMulticharacterMap.get(properties).translate(text, color);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.AppendableGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyph;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public interface MulticharacterImageGlyphCollection extends ResourceProducer {
|
||||
|
||||
static @NotNull MulticharacterImageGlyphCollection of(@NotNull Key fontKey,
|
||||
@NotNull Texture texture,
|
||||
@NotNull TextureProperties properties,
|
||||
@NotNull List<@NotNull String> charactersMapping) {
|
||||
return new MulticharacterImageGlyphCollectionImpl(fontKey, texture, properties, charactersMapping);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
static @NotNull MulticharacterImageGlyphCollection of(@NotNull Texture texture,
|
||||
@NotNull TextureProperties properties,
|
||||
@NotNull List<@NotNull String> charactersMapping) {
|
||||
return of(Glyph.DEFAULT_FONT_KEY, texture, properties, charactersMapping);
|
||||
}
|
||||
|
||||
@NotNull AppendableGlyph translate(@NotNull Character character, @Nullable TextColor color) throws IllegalArgumentException;
|
||||
|
||||
default @NotNull List<@NotNull AppendableGlyph> translate(@NotNull String text, @Nullable TextColor color) throws IllegalArgumentException {
|
||||
List<AppendableGlyph> glyphs = new ArrayList<>();
|
||||
for (char character : text.toCharArray()) {
|
||||
if (character == ' ') {
|
||||
glyphs.add(SpacesGlyph.DEFAULT_SPACE_GLYPH);
|
||||
} else {
|
||||
glyphs.add(translate(character, color));
|
||||
}
|
||||
}
|
||||
return glyphs;
|
||||
}
|
||||
|
||||
default @NotNull AppendableGlyph translate(@NotNull Character character) throws IllegalArgumentException {
|
||||
return translate(character, null);
|
||||
}
|
||||
|
||||
default @NotNull List<@NotNull AppendableGlyph> translate(@NotNull String text) throws IllegalArgumentException {
|
||||
return translate(text, null);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ArbitraryCharacterFactory;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceAlreadyProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.glyph.util.ImageUtil;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class MulticharacterImageGlyphCollectionImpl implements MulticharacterImageGlyphCollection {
|
||||
|
||||
private final Key fontKey;
|
||||
private final Texture texture;
|
||||
private final TextureProperties properties;
|
||||
private final List<String> charactersMapping;
|
||||
|
||||
private final Map<Character, Character> originToArbitraryCharacterMap = new HashMap<>();
|
||||
|
||||
private Set<FontProvider> fontProviders;
|
||||
|
||||
private BufferedImage image;
|
||||
|
||||
@Override
|
||||
public @NotNull Key fontKey() {
|
||||
return fontKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean produced() {
|
||||
return fontProviders != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produceResources(ArbitraryCharacterFactory characterFactory) throws ResourceAlreadyProducedException {
|
||||
if (fontProviders != null) {
|
||||
throw new ResourceAlreadyProducedException();
|
||||
}
|
||||
|
||||
var fontProviderBuilder = FontProvider.bitMap();
|
||||
fontProviderBuilder.file(texture.key());
|
||||
fontProviderBuilder.ascent(properties.ascent());
|
||||
fontProviderBuilder.height(properties.height());
|
||||
|
||||
List<String> mappingLines = new ArrayList<>();
|
||||
|
||||
for (String mappingLine : charactersMapping) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (char character : mappingLine.toCharArray()) {
|
||||
char arbitraryCharacter = characterFactory.nextCharacter();
|
||||
originToArbitraryCharacterMap.put(character, arbitraryCharacter);
|
||||
builder.append(arbitraryCharacter);
|
||||
}
|
||||
mappingLines.add(builder.toString());
|
||||
}
|
||||
|
||||
fontProviderBuilder.characters(mappingLines);
|
||||
|
||||
this.fontProviders = Collections.singleton(fontProviderBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull FontProvider> fontProviders() throws ResourceNotProducedException {
|
||||
return fontProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull Texture> textures() throws ResourceNotProducedException {
|
||||
return Collections.singleton(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PreparedImageGlyph translate(@NotNull Character character, @Nullable TextColor color) throws IllegalArgumentException {
|
||||
if (!originToArbitraryCharacterMap.containsKey(character)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
for (int lineIndex = 0; lineIndex < charactersMapping.size(); lineIndex++) {
|
||||
String line = charactersMapping.get(lineIndex);
|
||||
for (int characterIndex = 0; characterIndex < line.toCharArray().length; characterIndex++) {
|
||||
if (line.charAt(characterIndex) == character) {
|
||||
if (image == null) {
|
||||
cacheImage();
|
||||
}
|
||||
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
int filePartWidth = image.getWidth() / charactersMapping.get(0).length();
|
||||
int filePartHeight = image.getHeight() / charactersMapping.size();
|
||||
|
||||
width = (int) Math.ceil(
|
||||
((double) properties.height() / (double) filePartHeight)
|
||||
* ImageUtil.calculateWidth(
|
||||
image, filePartWidth * characterIndex, filePartHeight * lineIndex,
|
||||
filePartWidth * (characterIndex + 1), filePartHeight * (lineIndex + 1)
|
||||
)) + Glyph.SEPARATOR_WIDTH;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new PreparedImageGlyph(fontKey, originToArbitraryCharacterMap.get(character), width, color);
|
||||
}
|
||||
|
||||
private void cacheImage() {
|
||||
try {
|
||||
image = ImageIO.read(new ByteArrayInputStream(texture.data().toByteArray()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.AppendableGlyph;
|
||||
|
||||
@AllArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class PreparedImageGlyph implements AppendableGlyph, ColorableGlyph {
|
||||
|
||||
private final Key key;
|
||||
private final Character character;
|
||||
private final int width;
|
||||
private @Nullable TextColor color;
|
||||
|
||||
@Override
|
||||
public @NotNull Component toAdventure() {
|
||||
return Component.text(character)
|
||||
.font(key)
|
||||
.color(color == null ? NamedTextColor.BLACK : color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable TextColor color() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateColor(@Nullable TextColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.EmptyGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.util.ArrayUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class AbstractSpacesGlyphResourceProducer implements SpacesGlyphResourceProducer {
|
||||
|
||||
private final Key fontKey;
|
||||
|
||||
protected Map<Integer, Character> mapping;
|
||||
|
||||
@Override
|
||||
public @NotNull Key fontKey() {
|
||||
return fontKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean produced() {
|
||||
return mapping != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Glyph translate(int length) throws ResourceNotProducedException {
|
||||
if (mapping == null) {
|
||||
throw new ResourceNotProducedException();
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
return EmptyGlyph.INSTANCE;
|
||||
}
|
||||
|
||||
int sign = length > 0 ? 1 : -1;
|
||||
String binaryString = Integer.toBinaryString(Math.abs(length));
|
||||
|
||||
List<Character> characters = new ArrayList<>();
|
||||
|
||||
int currentRankLength = 1;
|
||||
for (int index = 0; index < binaryString.length(); index++) {
|
||||
char digit = binaryString.charAt(binaryString.length() - index - 1);
|
||||
if (digit == '1') {
|
||||
int partLength = currentRankLength * sign;
|
||||
if (!mapping.containsKey(partLength)) {
|
||||
throw new IllegalArgumentException("Too much length");
|
||||
}
|
||||
characters.add(mapping.get(partLength));
|
||||
}
|
||||
currentRankLength *= 2;
|
||||
}
|
||||
|
||||
return new SpacesGlyph(fontKey(), ArrayUtil.toCharArray(characters), length);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.AppendableGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import team.unnamed.creative.font.Font;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class DefaultSpaceGlyph implements AppendableGlyph {
|
||||
|
||||
@Override
|
||||
public @NotNull Component toAdventure() throws ResourceNotProducedException {
|
||||
return Component.text(" ").font(Font.MINECRAFT_DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ArbitraryCharacterFactory;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceAlreadyProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.font.BitMapFontProvider;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DefaultSpacesGlyphResourceProducer extends AbstractSpacesGlyphResourceProducer {
|
||||
|
||||
private final Key textureKey;
|
||||
private final Writable writable;
|
||||
|
||||
private Set<Texture> textures;
|
||||
private Set<FontProvider> fontProviders;
|
||||
|
||||
public DefaultSpacesGlyphResourceProducer(Key fontKey, Key textureKey, Writable writable) {
|
||||
super(fontKey);
|
||||
this.textureKey = textureKey;
|
||||
this.writable = writable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean produced() {
|
||||
return textures != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produceResources(ArbitraryCharacterFactory characterFactory) {
|
||||
if (textures != null) {
|
||||
throw new ResourceAlreadyProducedException();
|
||||
}
|
||||
|
||||
this.mapping = new HashMap<>();
|
||||
|
||||
Set<FontProvider> fontProviders = new HashSet<>();
|
||||
|
||||
for (int length = 1; length <= 2048; length *= 2) {
|
||||
fontProviders.add(prepareBuilder(characterFactory, length).build());
|
||||
fontProviders.add(prepareBuilder(characterFactory, length * (-1)).build());
|
||||
}
|
||||
|
||||
this.textures = Collections.singleton(Texture.texture(textureKey, writable));
|
||||
this.fontProviders = fontProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull FontProvider> fontProviders() throws ResourceNotProducedException {
|
||||
if (fontProviders == null) {
|
||||
throw new ResourceNotProducedException();
|
||||
}
|
||||
return fontProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull Texture> textures() throws ResourceNotProducedException {
|
||||
if (textures == null) {
|
||||
throw new ResourceNotProducedException();
|
||||
}
|
||||
return textures;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private BitMapFontProvider.Builder prepareBuilder(ArbitraryCharacterFactory characterFactory, int length) {
|
||||
var fontProviderBuilder = FontProvider.bitMap();
|
||||
|
||||
char character = characterFactory.nextCharacter();
|
||||
|
||||
fontProviderBuilder.characters(String.valueOf(character));
|
||||
fontProviderBuilder.file(textureKey);
|
||||
|
||||
if (length > 0) {
|
||||
fontProviderBuilder.height(length - 1);
|
||||
fontProviderBuilder.ascent(0);
|
||||
} else {
|
||||
fontProviderBuilder.height(length - 2);
|
||||
fontProviderBuilder.ascent(-32768);
|
||||
}
|
||||
|
||||
mapping.put(length, character);
|
||||
|
||||
return fontProviderBuilder;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class SpacesGlyph implements Glyph {
|
||||
|
||||
private static final Key DEFAULT_SPACE_TEXTURE_KEY = Key.key(Glyph.DEFAULT_NAMESPACE, "space");
|
||||
public static final @NotNull DefaultSpaceGlyph DEFAULT_SPACE_GLYPH = new DefaultSpaceGlyph();
|
||||
private final Key key;
|
||||
private final char[] characters;
|
||||
private final int length;
|
||||
|
||||
public static @NotNull SpacesGlyphResourceProducer create(@NotNull Key fontKey,
|
||||
@NotNull Key textureKey,
|
||||
@NotNull Writable spacesWritable) {
|
||||
return new DefaultSpacesGlyphResourceProducer(fontKey, textureKey, spacesWritable);
|
||||
}
|
||||
|
||||
public static SpacesGlyphResourceProducer create(@NotNull Writable spacesWritable) {
|
||||
return create(Glyph.DEFAULT_SPACES_FONT_KEY, DEFAULT_SPACE_TEXTURE_KEY, spacesWritable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Component toAdventure() {
|
||||
return Component.text(new String(characters)).font(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return length;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space;
|
||||
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
|
||||
public interface SpacesGlyphResourceProducer extends ResourceProducer {
|
||||
|
||||
Glyph translate(int length) throws ResourceNotProducedException;
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space.mojang;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyphResourceProducer;
|
||||
|
||||
public interface MojangSpacesGlyph extends Glyph, ResourceProducer {
|
||||
|
||||
static @NotNull SpacesGlyphResourceProducer create(@NotNull Key key) {
|
||||
return new MojangSpacesGlyphResourceProducer(key);
|
||||
}
|
||||
|
||||
static SpacesGlyphResourceProducer create() {
|
||||
return create(Glyph.DEFAULT_SPACES_FONT_KEY);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
package ru.dragonestia.msb3.api.glyph.glyph.space.mojang;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ArbitraryCharacterFactory;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceAlreadyProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.exception.ResourceNotProducedException;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.AbstractSpacesGlyphResourceProducer;
|
||||
import team.unnamed.creative.font.FontProvider;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
public class MojangSpacesGlyphResourceProducer extends AbstractSpacesGlyphResourceProducer {
|
||||
|
||||
private Set<FontProvider> fontProviders;
|
||||
|
||||
public MojangSpacesGlyphResourceProducer(Key key) {
|
||||
super(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean produced() {
|
||||
return fontProviders != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void produceResources(ArbitraryCharacterFactory characterFactory) {
|
||||
if (fontProviders != null) {
|
||||
throw new ResourceAlreadyProducedException();
|
||||
}
|
||||
|
||||
mapping = new HashMap<>();
|
||||
|
||||
var fontProviderBuilder = FontProvider.space();
|
||||
|
||||
for (int length = 1; length <= 2048; length *= 2) {
|
||||
fontProviderBuilder.advance(retrieveCharacter(characterFactory, length), length);
|
||||
fontProviderBuilder.advance(retrieveCharacter(characterFactory, length * (-1)), length * (-1));
|
||||
}
|
||||
|
||||
this.fontProviders = Collections.singleton(fontProviderBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull FontProvider> fontProviders() throws ResourceNotProducedException {
|
||||
if (fontProviders == null) {
|
||||
throw new ResourceNotProducedException();
|
||||
}
|
||||
return fontProviders;
|
||||
}
|
||||
|
||||
private Character retrieveCharacter(ArbitraryCharacterFactory characterFactory, int length) {
|
||||
char character = characterFactory.nextCharacter();
|
||||
mapping.put(length, character);
|
||||
return character;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package ru.dragonestia.msb3.api.glyph.pack;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.GlyphCompiler;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import team.unnamed.creative.part.ResourcePackPart;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class DefaultGlyphResourcePack implements GlyphResourcePack {
|
||||
|
||||
private final Map<String, ResourceProducer> raw = new HashMap<>();
|
||||
private final Map<String, ResourceProducer> compiled = new HashMap<>();
|
||||
|
||||
private final Set<ResourcePackPart> resources = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<@NotNull ResourcePackPart> all() {
|
||||
if (!raw.isEmpty()) {
|
||||
compileAll();
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compileAll() {
|
||||
var resources = GlyphCompiler.instance().compile(raw.values());
|
||||
this.resources.addAll(resources);
|
||||
compiled.putAll(raw);
|
||||
raw.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull <T extends ResourceProducer> GlyphResourcePack with(@NotNull ResourceIdentifier<@NotNull T> id, @NotNull T producer) {
|
||||
if (raw.containsKey(id.key()) || compiled.containsKey(id.key())) {
|
||||
throw new IllegalArgumentException("Producer with this identifier already registered");
|
||||
}
|
||||
raw.put(id.key(), producer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull GlyphResourcePack with(@NotNull ResourcePackPart resource) {
|
||||
resources.add(resource);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ResourceProducer> @NotNull T get(@NotNull ResourceIdentifier<@NotNull T> id) throws IllegalArgumentException {
|
||||
if (!compiled.containsKey(id.key())) {
|
||||
throw new IllegalArgumentException("Producer with that identifier is not compiled");
|
||||
}
|
||||
ResourceProducer producer = compiled.get(id.key());
|
||||
if (!id.getType().isAssignableFrom(producer.getClass())) {
|
||||
throw new IllegalArgumentException("Wrong producer type");
|
||||
}
|
||||
return (T) producer;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package ru.dragonestia.msb3.api.glyph.pack;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyphResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.mojang.MojangSpacesGlyph;
|
||||
import team.unnamed.creative.ResourcePack;
|
||||
import team.unnamed.creative.part.ResourcePackPart;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface GlyphResourcePack {
|
||||
|
||||
@NotNull Collection<@NotNull ResourcePackPart> all();
|
||||
|
||||
void compileAll();
|
||||
|
||||
@Contract("_, _ -> this")
|
||||
<T extends ResourceProducer> @NotNull GlyphResourcePack with(@NotNull ResourceIdentifier<@NotNull T> id, @NotNull T producer);
|
||||
|
||||
@Contract("_ -> this")
|
||||
@NotNull GlyphResourcePack with(@NotNull ResourcePackPart resource);
|
||||
|
||||
@Contract("_ -> this")
|
||||
default @NotNull GlyphResourcePack with(@NotNull ResourcePackPart... resources) {
|
||||
for (ResourcePackPart resource : resources) {
|
||||
with(resource);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Contract("_ -> this")
|
||||
default @NotNull GlyphResourcePack with(@NotNull Collection<@NotNull ResourcePackPart> resources) {
|
||||
resources.forEach(this::with);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Contract("-> this")
|
||||
default @NotNull GlyphResourcePack withMojangSpaces() {
|
||||
with(ResourceIdentifier.SPACES, MojangSpacesGlyph.create());
|
||||
return this;
|
||||
}
|
||||
|
||||
<T extends ResourceProducer> @NotNull T get(@NotNull ResourceIdentifier<@NotNull T> id) throws IllegalArgumentException;
|
||||
|
||||
default @NotNull SpacesGlyphResourceProducer spaces() {
|
||||
return get(ResourceIdentifier.SPACES);
|
||||
}
|
||||
|
||||
default void writeAll(@NotNull ResourcePack resourcePack) {
|
||||
all().forEach(resourcePack::part);
|
||||
}
|
||||
|
||||
static @NotNull GlyphResourcePack create() {
|
||||
return new DefaultGlyphResourcePack();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package ru.dragonestia.msb3.api.glyph.pack;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.ImageGlyph;
|
||||
|
||||
public interface ImageResourceIdentifier extends ResourceIdentifier<@NotNull ImageGlyph> {
|
||||
|
||||
@Override
|
||||
default @NotNull Class<@NotNull ImageGlyph> getType() {
|
||||
return ImageGlyph.class;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package ru.dragonestia.msb3.api.glyph.pack;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.multicharacter.LanguageGlyphCollection;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.space.SpacesGlyphResourceProducer;
|
||||
|
||||
public interface ResourceIdentifier<T extends @NotNull ResourceProducer> {
|
||||
|
||||
@NotNull StringIdentifier<@NotNull SpacesGlyphResourceProducer> SPACES = StringIdentifier.of("spaces", SpacesGlyphResourceProducer.class);
|
||||
|
||||
@NotNull StringIdentifier<@NotNull LanguageGlyphCollection> MINECRAFT_FONT = StringIdentifier.of("minecraft_font", LanguageGlyphCollection.class);
|
||||
|
||||
String STRING_IDENTIFIER_NAMESPACE = "glyphs";
|
||||
|
||||
@NotNull String key();
|
||||
|
||||
@NotNull Class<T> getType();
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package ru.dragonestia.msb3.api.glyph.pack;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.ResourceProducer;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.ImageGlyph;
|
||||
|
||||
public class StringIdentifier<T extends @NotNull ResourceProducer> implements ResourceIdentifier<T> {
|
||||
|
||||
private final @NotNull String id;
|
||||
|
||||
private final @NotNull Class<T> type;
|
||||
|
||||
protected StringIdentifier(@NotNull String id, @NotNull Class<T> type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String key() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public static <T extends @NotNull ResourceProducer> @NotNull StringIdentifier<@NotNull T> of(
|
||||
@NotNull String id,
|
||||
@NotNull Class<T> type) {
|
||||
return new StringIdentifier<>(id, type);
|
||||
}
|
||||
|
||||
public static @NotNull StringIdentifier<@NotNull ImageGlyph> image(@NotNull String id) {
|
||||
return new StringIdentifier<>(id, ImageGlyph.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package ru.dragonestia.msb3.api.glyph.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class ArrayUtil {
|
||||
|
||||
public char[] toCharArray(@NotNull List<Character> list) {
|
||||
char[] arr = new char[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
arr[i] = list.get(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package ru.dragonestia.msb3.api.glyph.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
@UtilityClass
|
||||
public class ImageUtil {
|
||||
|
||||
public int calculateWidth(BufferedImage image, int xFrom, int yFrom, int xTo, int yTo) {
|
||||
int width;
|
||||
for (width = xTo - 1; width > xFrom; width--) {
|
||||
for (int height = yFrom; height < yTo; height++) {
|
||||
if (new Color(image.getRGB(width, height), true)
|
||||
.getAlpha() == 255) {
|
||||
return width - xFrom + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return width - xFrom + 1;
|
||||
}
|
||||
|
||||
public int calculateWidth(BufferedImage image) {
|
||||
return calculateWidth(image, 0, 0, image.getWidth(), image.getHeight());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package ru.dragonestia.msb3.api.item;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.model.*;
|
||||
import team.unnamed.creative.part.ResourcePackPart;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
public class BlankSlotItem {
|
||||
|
||||
private static final Writable BLANK_SLOT_IMAGE_WRITABLE = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/defaults/blank_slot.png");
|
||||
private static ItemStack stack;
|
||||
|
||||
private BlankSlotItem() {}
|
||||
|
||||
public synchronized static ItemStack getItem() {
|
||||
if (stack == null) {
|
||||
stack = ItemStack.builder(Material.PAPER)
|
||||
.customModelData(1)
|
||||
.build();
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static Collection<ResourcePackPart> compile() {
|
||||
var modelKey = Key.key(Glyph.DEFAULT_NAMESPACE, "blank_slot");
|
||||
var itemKey = Key.key("item/paper");
|
||||
|
||||
Model blankSlotModel = Model.model()
|
||||
.key(modelKey)
|
||||
.parent(Model.ITEM_GENERATED)
|
||||
.textures(ModelTextures.builder()
|
||||
.layers(ModelTexture.ofKey(modelKey))
|
||||
.build())
|
||||
.build();
|
||||
|
||||
Model paperItemModel = Model.model()
|
||||
.key(itemKey)
|
||||
.parent(Model.ITEM_GENERATED)
|
||||
.textures(ModelTextures.builder()
|
||||
.layers(ModelTexture.ofKey(itemKey))
|
||||
.build())
|
||||
.overrides(ItemOverride.of(modelKey, ItemPredicate.customModelData(1)))
|
||||
.build();
|
||||
|
||||
Texture texture = Texture.texture(Key.key("glyphs", "blank_slot.png"), BLANK_SLOT_IMAGE_WRITABLE);
|
||||
return Arrays.asList(blankSlotModel, paperItemModel, texture);
|
||||
}
|
||||
}
|
||||
@ -2,26 +2,79 @@ package ru.dragonestia.msb3.api.resource;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import ru.dragonestia.msb3.api.glyph.compile.GlyphCompiler;
|
||||
import ru.dragonestia.msb3.api.glyph.font.GlyphFont;
|
||||
import ru.dragonestia.msb3.api.glyph.pack.GlyphResourcePack;
|
||||
import ru.dragonestia.msb3.api.item.BlankSlotItem;
|
||||
import ru.dragonestia.msb3.api.title.BlackScreen;
|
||||
import team.unnamed.creative.ResourcePack;
|
||||
import team.unnamed.creative.atlas.Atlas;
|
||||
import team.unnamed.creative.atlas.AtlasSource;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.model.Model;
|
||||
import team.unnamed.creative.serialize.minecraft.MinecraftResourcePackWriter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Log4j2
|
||||
public class ResourcePackManager {
|
||||
|
||||
@Getter private final ResourcePack resourcePack;
|
||||
private final ResourcePack resourcePack;
|
||||
private final GlyphResourcePack glyphResourcePack;
|
||||
|
||||
public ResourcePackManager() {
|
||||
resourcePack = ResourcePack.resourcePack();
|
||||
resourcePack.packMeta(34, "Dragonestia MSB3 - Resource pack");
|
||||
resourcePack.icon(Writable.resource(getClass().getClassLoader(), "logo.png"));
|
||||
resourcePack.unknownFile("credits.txt", Writable.stringUtf8("dragonestia.ru"));
|
||||
|
||||
glyphResourcePack = GlyphResourcePack.create();
|
||||
initDefaultGlyphs();
|
||||
}
|
||||
|
||||
private void initDefaultGlyphs() {
|
||||
glyphResourcePack.with(BlankSlotItem.compile());
|
||||
glyphResourcePack.with(GlyphCompiler.instance().compile(BlackScreen.GLYPH));
|
||||
glyphResourcePack.with(GlyphFont.compile());
|
||||
}
|
||||
|
||||
public void compile() {
|
||||
glyphResourcePack.writeAll(resourcePack);
|
||||
generateAtlases();
|
||||
MinecraftResourcePackWriter.minecraft().writeToZipFile(new File("resource-pack.zip"), resourcePack);
|
||||
log.info("Compiled resource pack. File: ./resource-pack.zip");
|
||||
}
|
||||
|
||||
private void generateAtlases() {
|
||||
Atlas.Builder atlasBuilder = Atlas.atlas();
|
||||
atlasBuilder.key(Key.key("minecraft", "blocks"));
|
||||
Set<String> applicableTextureKeys = new HashSet<>();
|
||||
|
||||
for (Model model: resourcePack.models()) {
|
||||
for (var layer: model.textures().layers()) {
|
||||
var key = layer.key();
|
||||
if (key != null) {
|
||||
applicableTextureKeys.add(key.asString().concat(".png"));
|
||||
}
|
||||
}
|
||||
|
||||
for (var texture: model.textures().variables().values()) {
|
||||
var key = texture.key();
|
||||
if (key != null) {
|
||||
applicableTextureKeys.add(key.asString().concat(".png"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sources = resourcePack.textures()
|
||||
.stream()
|
||||
//.filter(texture -> !applicableTextureKeys.contains(texture.key().asString()))
|
||||
.map(texture -> (AtlasSource) AtlasSource.single(Key.key(texture.key().toString().replace(".png", "")))).toList();
|
||||
atlasBuilder.sources(sources);
|
||||
resourcePack.atlas(atlasBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
package ru.dragonestia.msb3.api.title;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.minestom.server.entity.Player;
|
||||
import ru.dragonestia.msb3.api.ServerBootstrap;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.Glyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.ImageGlyph;
|
||||
import ru.dragonestia.msb3.api.glyph.glyph.image.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.util.ResourceFromJar;
|
||||
import team.unnamed.creative.base.Writable;
|
||||
import team.unnamed.creative.texture.Texture;
|
||||
|
||||
public class BlackScreen {
|
||||
|
||||
private static final Writable BACKGROUND_WRITABLE = ResourceFromJar.of(ServerBootstrap.CLASS_LOADER, "glyphs/defaults/fullscreen_background.png");
|
||||
private static final Key FULLSCREEN_BACKGROUND_KEY = Key.key(Glyph.DEFAULT_NAMESPACE, "fullscreen_background.png");
|
||||
public static final ImageGlyph GLYPH = fullscreenBackgroundGlyph();
|
||||
|
||||
private BlackScreen() {}
|
||||
|
||||
public static void show(Player player) {
|
||||
player.showTitle(Title.title(
|
||||
GLYPH.toAdventure(),
|
||||
Component.empty()
|
||||
));
|
||||
}
|
||||
|
||||
private static ImageGlyph fullscreenBackgroundGlyph() {
|
||||
return ImageGlyph.of(FULLSCREEN_BACKGROUND_KEY,
|
||||
Texture.texture(FULLSCREEN_BACKGROUND_KEY, BACKGROUND_WRITABLE),
|
||||
new TextureProperties(2500, 256));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package ru.dragonestia.msb3.api.util;
|
||||
|
||||
import team.unnamed.creative.base.Writable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public interface ResourceFromJar {
|
||||
|
||||
static Writable of(ClassLoader classLoader, String fileName) {
|
||||
return Writable.inputStream(() -> {
|
||||
try {
|
||||
URL url = classLoader.getResource(fileName);
|
||||
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
URLConnection connection = url.openConnection();
|
||||
connection.setUseCaches(false);
|
||||
return connection.getInputStream();
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
BIN
api/src/main/resources/glyphs/defaults/blank_slot.png
Normal file
BIN
api/src/main/resources/glyphs/defaults/blank_slot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
api/src/main/resources/glyphs/defaults/fullscreen_background.png
Normal file
BIN
api/src/main/resources/glyphs/defaults/fullscreen_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 120 B |
BIN
api/src/main/resources/glyphs/defaults/minecraft_font.png
Normal file
BIN
api/src/main/resources/glyphs/defaults/minecraft_font.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
api/src/main/resources/glyphs/defaults/space.png
Normal file
BIN
api/src/main/resources/glyphs/defaults/space.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 120 B |
Loading…
x
Reference in New Issue
Block a user