Skip to content

Commit

Permalink
Revamp Font system
Browse files Browse the repository at this point in the history
  • Loading branch information
iiAhmedYT committed Aug 14, 2024
1 parent b75a6cf commit 3cddba7
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 100 deletions.
97 changes: 5 additions & 92 deletions src/main/java/to/itsme/itsmyconfig/font/Font.java
Original file line number Diff line number Diff line change
@@ -1,100 +1,13 @@
package to.itsme.itsmyconfig.font;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.minimessage.tag.TagPattern;
import to.itsme.itsmyconfig.util.Strings;
import org.jetbrains.annotations.NotNull;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public interface Font {

public enum Font {
SMALL_CAPS(
"smallcaps",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzÑÓÚñóú",
"ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘǫʀsᴛᴜᴠᴡxʏᴢɴᴏᴜɴᴏᴜ"
),
UPSIDE_DOWN(
"upsidedown",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz"
);

private final Map<Character, Character> characterMap;
private final TextReplacementConfig config;
private final @TagPattern String name;

Font(
@TagPattern final String name,
final String original,
final String replacements
) {
this.name = name;
this.characterMap = createMapping(original, replacements);
this.config = createConfig();
}

public @TagPattern String getName() {
return name;
}

private TextReplacementConfig createConfig() {
final TextReplacementConfig.Builder config = TextReplacementConfig.builder();
config.match(Strings.LETTERS_PATTERN).replacement((matchResult, builder) -> {
final String text = this.apply(matchResult.group());
return Component.text().content(text);
});
return config.build();
}

public String apply(final String text) {
final byte[] bytes = this.englishify(text).getBytes(StandardCharsets.UTF_8);
final StringBuilder builder = new StringBuilder();
for (byte messageByte : bytes) {
final char originalChar = (char) messageByte;
final char styledChar = characterMap.getOrDefault(originalChar, originalChar);
builder.append(styledChar);
}
return builder.toString();
}

public String englishify(final String text) {
return text
.replace("À", "A")
.replace("Â", "A")
.replace("à", "a")
.replace("â", "a")
.replace("É", "E")
.replace("È", "E")
.replace("Ê", "E")
.replace("é", "e")
.replace("è", "e")
.replace("ê", "e")
.replace("Î", "I")
.replace("î", "i")
.replace("Ô", "O")
.replace("ô", "o")
.replace("Û", "U")
.replace("û", "u")
.replace("Ç", "C")
.replace("ç", "c");
}

public Component apply(final Component component) {
return component.replaceText(config);
}

private static Map<Character, Character> createMapping(final String original, final String replacements) {
if (original.length() != replacements.length()) {
throw new IllegalArgumentException("Original and replacement texts must be of the same length.");
}

final Map<Character, Character> mapping = new HashMap<>();
for (int i = 0; i < original.length(); i++) {
mapping.put(original.charAt(i), replacements.charAt(i));
}
return mapping;
}
@TagPattern String getName();
@NotNull String apply(final @NotNull String text);
@NotNull Component apply(final @NotNull Component component);

}
46 changes: 46 additions & 0 deletions src/main/java/to/itsme/itsmyconfig/font/FontImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package to.itsme.itsmyconfig.font;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextReplacementConfig;
import net.kyori.adventure.text.minimessage.tag.TagPattern;
import org.jetbrains.annotations.NotNull;
import to.itsme.itsmyconfig.util.Strings;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public abstract class FontImpl implements Font {

private static final Map<String, Font> FONTS = new HashMap<>();

private final @TagPattern String name;
private final TextReplacementConfig config = this.createConfig();

public FontImpl(final @TagPattern String name) {
this.name = name;
}

public @TagPattern String getName() {
return name;
}

@Override
public @NotNull Component apply(final @NotNull Component component) {
return component.replaceText(config);
}

private TextReplacementConfig createConfig() {
final TextReplacementConfig.Builder config = TextReplacementConfig.builder();
config.match(Strings.LETTERS_PATTERN).replacement((matchResult, builder) -> {
final String text = this.apply(matchResult.group());
return Component.text().content(text);
});
return config.build();
}

public static Collection<Font> values() {
return FONTS.values();
}

}
60 changes: 60 additions & 0 deletions src/main/java/to/itsme/itsmyconfig/font/MappedFont.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package to.itsme.itsmyconfig.font;

import net.kyori.adventure.text.minimessage.tag.TagPattern;
import org.jetbrains.annotations.NotNull;
import to.itsme.itsmyconfig.util.Strings;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class MappedFont extends FontImpl {

public static final MappedFont SMALL_CAPS = new MappedFont(
"smallcaps",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘꞯʀsᴛᴜᴠᴡxʏᴢᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘꞯʀsᴛᴜᴠᴡxʏᴢ"
);

public static final MappedFont UPSIDE_DOWN = new MappedFont(
"upsidedown",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
"∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz"
);

private final Map<Character, Character> characterMap;

MappedFont(
@TagPattern final String name,
final String original,
final String replacements
) {
super(name);
this.characterMap = createMapping(original, replacements);
}

@Override
public @NotNull String apply(final @NotNull String text) {
final byte[] bytes = Strings.englishify(text).getBytes(StandardCharsets.UTF_8);
final StringBuilder builder = new StringBuilder();
for (final byte messageByte : bytes) {
final char originalChar = (char) messageByte;
final char styledChar = characterMap.getOrDefault(originalChar, originalChar);
builder.append(styledChar);
}
return builder.toString();
}

private static Map<Character, Character> createMapping(final String original, final String replacements) {
if (original.length() != replacements.length()) {
throw new IllegalArgumentException("Original and replacement texts must be of the same length.");
}

final Map<Character, Character> mapping = new HashMap<>();
for (int i = 0; i < original.length(); i++) {
mapping.put(original.charAt(i), replacements.charAt(i));
}
return mapping;
}

}
4 changes: 2 additions & 2 deletions src/main/java/to/itsme/itsmyconfig/hook/PAPIHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import to.itsme.itsmyconfig.ItsMyConfig;
import to.itsme.itsmyconfig.font.MappedFont;
import to.itsme.itsmyconfig.placeholder.Placeholder;
import to.itsme.itsmyconfig.placeholder.PlaceholderType;
import to.itsme.itsmyconfig.font.Font;
import to.itsme.itsmyconfig.util.Strings;

/**
Expand Down Expand Up @@ -129,7 +129,7 @@ private String handleFont(final String[] splitParams) {
}
} else if ("smallcaps".equals(fontType)) {
String message = splitParams[2].toLowerCase();
return Font.SMALL_CAPS.apply(message);
return MappedFont.SMALL_CAPS.apply(message);
}
return "ERROR";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

public final class PacketChatListener extends PacketListener {

private static final String DEBUG_HYPHEN = "###############################################";

private final boolean internalAdventure;
private final Method fromComponent;
private final BungeeComponentSerializer bungee = BungeeComponentSerializer.get();
Expand Down Expand Up @@ -54,22 +56,22 @@ public void onPacketSending(final PacketEvent event) {
Utilities.debug(() -> "################# CHAT PACKET #################\nProccessing packet " + container.getType().name());
final PacketResponse response = this.processPacket(container);
if (response == null || response.message.isEmpty()) {
Utilities.debug(() -> "Packet is null or empty\n###############################################");
Utilities.debug(() -> "Packet is null or empty\n" + DEBUG_HYPHEN);
return;
}

final String message = response.message;
Utilities.debug(() -> "Checking: " + message);
if (!this.startsWithSymbol(message)) {
Utilities.debug(() -> "Message doesn't start w/ the symbol-prefix: " + message + "\n###############################################");
Utilities.debug(() -> "Message doesn't start w/ the symbol-prefix: " + message + "\n" + DEBUG_HYPHEN);
return;
}

final Player player = event.getPlayer();
final Component parsed = Utilities.translate(this.processMessage(message), player);
if (parsed.equals(Component.empty())) {
event.setCancelled(true);
Utilities.debug(() -> "Component is empty, cancelling...\n###############################################");
Utilities.debug(() -> "Component is empty, cancelling...\n" + DEBUG_HYPHEN);
return;
}

Expand All @@ -95,7 +97,7 @@ public void onPacketSending(final PacketEvent event) {
break;
}

Utilities.debug(() -> "###############################################");
Utilities.debug(() -> DEBUG_HYPHEN);
}

private PacketResponse processPacket(final PacketContainer container) {
Expand Down
22 changes: 21 additions & 1 deletion src/main/java/to/itsme/itsmyconfig/util/Strings.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
import org.jetbrains.annotations.NotNull;

import java.text.Normalizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -17,7 +18,8 @@ public final class Strings {
public static final Pattern TAG_PATTERN = Pattern.compile("<(\\w+)(?::\"([^\"]*)\"|:([^<]*))*>");

private static final Pattern COLOR_FILTER = Pattern.compile("[§&][a-zA-Z0-9]");
public static final Pattern ARGUMENT_PATTERN = Pattern.compile("\\{([0-9]+)}");
private static final Pattern ARGUMENT_PATTERN = Pattern.compile("\\{([0-9]+)}");
private static final Pattern DIACRITICAL_MARKS_PATTERN = Pattern.compile("\\p{M}");
private static final Pattern QUOTE_PATTERN = Pattern.compile("<quote(?::([^>]*))?>(.*)</quote>");

/**
Expand Down Expand Up @@ -226,4 +228,22 @@ public static String toString(final @NotNull List<String> list) {
return String.join(System.lineSeparator(), list.stream().map(Object::toString).toArray(String[]::new));
}

/**
* Converts a string containing accented characters into a string with plain
* English characters by removing diacritical marks (accents).
*
* <p>This method normalizes the input text by decomposing accented characters
* into their base characters followed by diacritical marks. It then removes
* the diacritical marks, resulting in a string composed of basic Latin letters.</p>
*
* <p>For example, the input string "À la carte" would be converted to "A la carte".</p>
*
* @param text the input string potentially containing accented characters
* @return a new string with the accented characters converted to plain English characters
*/
public static String englishify(final String text) {
final String normalized = Normalizer.normalize(text, Normalizer.Form.NFD);
return DIACRITICAL_MARKS_PATTERN.matcher(normalized).replaceAll("");
}

}
3 changes: 2 additions & 1 deletion src/main/java/to/itsme/itsmyconfig/util/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.jetbrains.annotations.Nullable;
import to.itsme.itsmyconfig.ItsMyConfig;
import to.itsme.itsmyconfig.font.Font;
import to.itsme.itsmyconfig.font.FontImpl;
import to.itsme.itsmyconfig.font.FontTag;
import to.itsme.itsmyconfig.placeholder.Placeholder;
import to.itsme.itsmyconfig.placeholder.type.ColorPlaceholder;
Expand All @@ -41,7 +42,7 @@ public final class Utilities {

static {
final TagResolver.Builder builder = TagResolver.builder();
for (final @Subst("") Font font : Font.values()) {
for (final @Subst("") Font font : FontImpl.values()) {
builder.tag(font.getName(), new FontTag(font));
}
FONT_RESOLVER = builder.build();
Expand Down

0 comments on commit 3cddba7

Please sign in to comment.