Skip to content

Commit

Permalink
Improve default handling
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Dec 18, 2024
1 parent fa6f9c3 commit f04321f
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 134 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public static String parseTextToLegacy(final String text) {

private static Component parseTextToComponent(final String text) {
String parsedText = convertMiniMessageString(text);

for (PlaceholderParser parser : preParsePlaceholders) {
parsedText = parser.parseString(parsedText);
}
Expand All @@ -69,7 +68,6 @@ private static Component parseTextToComponent(final String text) {
ampersandRGB = parser.parseString(ampersandRGB);
}

// Also parse ampersands that were not parsed by MiniMessage
return PistonSerializersRelocated.ampersandRGB.deserialize(ampersandRGB);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,169 +9,172 @@
import java.util.concurrent.atomic.AtomicReference;

@RequiredArgsConstructor
public class CenterPlaceholder implements PlaceholderParser {
public class CenterPlaceholder {
private static final ThreadLocal<boolean[]> CENTERED_LINES = ThreadLocal.withInitial(() -> new boolean[2]);

private static final int LINE_LENGTH = 45;
private static final String PLACEHOLDER = "<center>";
private static final String SPACE = " ";
private static final char AMPERSAND = '&';
private static final char BOLD = 'l';
private static final char RESET = 'r';
private static final char HEX_CODE = '#';
private static final String BOLD_SYNTAX = AMPERSAND + String.valueOf(BOLD);
private static final String RESET_SYNTAX = AMPERSAND + String.valueOf(RESET);
private static final char[] LEGACY_CODES = {HEX_CODE, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'k', BOLD, 'm', 'n', 'o', RESET};
private static final char[] COLOR_CODES = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

@Override
public String parseString(String text) {
boolean[] centeredLines = CENTERED_LINES.get();
AtomicReference<String> colorCode = new AtomicReference<>();
Set<Character> formatModifiers = new HashSet<>();
String[] lines = text.split("\n", 2);
for (int i = 0; i < lines.length; i++) {
// We need to keep track of colors even if the line is not centered
String parsed = centerText(lines[i], colorCode, formatModifiers);
if (centeredLines[i]) {
lines[i] = parsed;

public static class PreProcessor implements PlaceholderParser {
@Override
public String parseString(String text) {
boolean[] centeredLines = CENTERED_LINES.get();

String[] lines = text.split("<newline>", 2);
for (int i = 0; i < lines.length; i++) {
if (lines[i].startsWith(PLACEHOLDER)) {
centeredLines[i] = true;
lines[i] = lines[i].substring(PLACEHOLDER.length());
}
}
}

CENTERED_LINES.remove();
return String.join("\n", lines);
return String.join("<newline>", lines);
}
}

private String centerText(String text, AtomicReference<String> colorCode, Set<Character> formatModifiers) {
float textWidthCounter = 0;
int textChars = text.length();

for (int i = 0; i < textChars; i++) {
char c = text.charAt(i);
if (c == AMPERSAND && i + 1 < textChars) {
char next = text.charAt(i + 1);
if (isValidLegacyChar(next)) {
if (next == RESET) {
colorCode.set(null);
formatModifiers.clear();
} else if (next == HEX_CODE) {
colorCode.set(text.substring(i + 1, i + 8));
i += 6;
} else if (isValidColorChar(next)) {
colorCode.set(String.valueOf(next));
} else {
formatModifiers.add(next);
}
public static class PostProcessor implements PlaceholderParser {
private static final int LINE_LENGTH = 45;
private static final String SPACE = " ";
private static final char AMPERSAND = '&';
private static final char BOLD = 'l';
private static final char RESET = 'r';
private static final char HEX_CODE = '#';
private static final String BOLD_SYNTAX = AMPERSAND + String.valueOf(BOLD);
private static final String RESET_SYNTAX = AMPERSAND + String.valueOf(RESET);
private static final char[] LEGACY_CODES = {HEX_CODE, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'k', BOLD, 'm', 'n', 'o', RESET};
private static final char[] COLOR_CODES = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static final int HEX_CODE_LENGTH = 6;

i++;
continue;
@Override
public String parseString(String text) {
boolean[] centeredLines = CENTERED_LINES.get();
AtomicReference<String> colorCode = new AtomicReference<>();
Set<Character> formatModifiers = new HashSet<>();
String[] lines = text.split("\n", 2);
for (int i = 0; i < lines.length; i++) {
// We need to keep track of colors even if the line is not centered
String parsed = centerText(lines[i], colorCode, formatModifiers);
if (centeredLines[i]) {
lines[i] = parsed;
}
}

textWidthCounter += TextWidthUtils.getCharWidth(c, 1, formatModifiers.contains(BOLD));
CENTERED_LINES.remove();
return String.join("\n", lines);
}

float spaceWidth = TextWidthUtils.getCharWidth(' ', 1, false);
float spaceBoldWidth = TextWidthUtils.getCharWidth(' ', 1, true);
float bigAWidth = TextWidthUtils.getCharWidth('A', 1, false);
int[] leftPaddingSpaces = getLeftPadding(textWidthCounter, spaceWidth, spaceBoldWidth, LINE_LENGTH * bigAWidth);
private String centerText(String text, AtomicReference<String> colorCode, Set<Character> formatModifiers) {
float textWidthCounter = 0;
int textChars = text.length();

for (int i = 0; i < textChars; i++) {
char c = text.charAt(i);
if (c == AMPERSAND && i + 1 < textChars) {
char next = text.charAt(i + 1);
if (isValidLegacyChar(next)) {
if (next == RESET) {
colorCode.set(null);
formatModifiers.clear();
} else if (next == HEX_CODE) {
colorCode.set(text.substring(i + 1, i + 2 + HEX_CODE_LENGTH));
i += 6;
} else if (isValidColorChar(next)) {
colorCode.set(String.valueOf(next));
} else {
formatModifiers.add(next);
}

i++;
continue;
}
}

StringBuilder builder = new StringBuilder();
builder.append(RESET_SYNTAX);
builder.append(SPACE.repeat(Math.max(0, leftPaddingSpaces[0])));
textWidthCounter += TextWidthUtils.getCharWidth(c, 1, formatModifiers.contains(BOLD));
}

builder.append(BOLD_SYNTAX);
builder.append(SPACE.repeat(Math.max(0, leftPaddingSpaces[1])));
builder.append(RESET_SYNTAX);
if (colorCode.get() != null) {
builder.append(AMPERSAND).append(colorCode.get());
}
float spaceWidth = TextWidthUtils.getCharWidth(' ', 1, false);
float spaceBoldWidth = TextWidthUtils.getCharWidth(' ', 1, true);
float bigAWidth = TextWidthUtils.getCharWidth('A', 1, false);
int[] leftPaddingSpaces = getLeftPadding(textWidthCounter, spaceWidth, spaceBoldWidth, LINE_LENGTH * bigAWidth);

for (char formatModifier : formatModifiers) {
builder.append(AMPERSAND).append(formatModifier);
}
StringBuilder builder = new StringBuilder();
builder.append(RESET_SYNTAX);
builder.append(SPACE.repeat(Math.max(0, leftPaddingSpaces[0])));

return builder.append(text).toString();
}
builder.append(BOLD_SYNTAX);
builder.append(SPACE.repeat(Math.max(0, leftPaddingSpaces[1])));
builder.append(RESET_SYNTAX);
if (colorCode.get() != null) {
builder.append(AMPERSAND).append(colorCode.get());
}

private boolean isValidLegacyChar(char c) {
for (char colorCode : LEGACY_CODES) {
if (c == colorCode) {
return true;
for (char formatModifier : formatModifiers) {
builder.append(AMPERSAND).append(formatModifier);
}
}

return false;
}
return builder.append(text).toString();
}

private boolean isValidColorChar(char c) {
for (char colorCode : COLOR_CODES) {
if (c == colorCode) {
return true;
private boolean isValidLegacyChar(char c) {
for (char colorCode : LEGACY_CODES) {
if (c == colorCode) {
return true;
}
}
}

return false;
}
return false;
}

@SuppressWarnings("SuspiciousNameCombination")
public static int[] getLeftPadding(float textWidth, float spaceWidth, float spaceBoldWidth, float lineLength) {
// Calculate the total padding needed on both sides
float totalPaddingWidth = lineLength - textWidth;
private boolean isValidColorChar(char c) {
for (char colorCode : COLOR_CODES) {
if (c == colorCode) {
return true;
}
}

// If the text is too wide to fit within the line length, return zero spaces
if (totalPaddingWidth <= 0) {
return new int[]{0, 0};
return false;
}

// Calculate the padding needed on one side to center the text
float leftPaddingWidth = totalPaddingWidth / 2.0f;
int maxPossibleSpaces = (int) (leftPaddingWidth / spaceWidth);
@SuppressWarnings("SuspiciousNameCombination")
public static int[] getLeftPadding(float textWidth, float spaceWidth, float spaceBoldWidth, float lineLength) {
// Calculate the total padding needed on both sides
float totalPaddingWidth = lineLength - textWidth;

return findClosestExponents(spaceWidth, spaceBoldWidth, leftPaddingWidth, maxPossibleSpaces);
}

private static int[] findClosestExponents(float x, float y, float z, int range) {
// Initialize the exponents n and m, and the minimum difference
int bestN = 0;
int bestM = 0;
float minDifference = Float.MAX_VALUE;

// Iterate through possible values of n and m to find the best combination
for (int n = 0; n <= range; n++) {
for (int m = 0; m <= range; m++) {
// Calculate x * n + y * m
float value = x * n + y * m;

// Calculate the difference from z
float difference = Math.abs(value - z);

// Update the best values if the current difference is smaller
if (difference < minDifference) {
minDifference = difference;
bestN = n;
bestM = m;
}
// If the text is too wide to fit within the line length, return zero spaces
if (totalPaddingWidth <= 0) {
return new int[]{0, 0};
}
}

return new int[]{bestN, bestM};
}
// Calculate the padding needed on one side to center the text
float leftPaddingWidth = totalPaddingWidth / 2.0f;
int maxPossibleSpaces = (int) (leftPaddingWidth / spaceWidth);

public static class PreProcessorCenterPlaceholder implements PlaceholderParser {
@Override
public String parseString(String text) {
boolean[] centeredLines = CENTERED_LINES.get();
return findClosestExponents(spaceWidth, spaceBoldWidth, leftPaddingWidth, maxPossibleSpaces);
}

String[] lines = text.split("\\n|<newline>", 2);
for (int i = 0; i < lines.length; i++) {
if (lines[i].startsWith(PLACEHOLDER)) {
centeredLines[i] = true;
lines[i] = lines[i].substring(PLACEHOLDER.length());
private static int[] findClosestExponents(float x, float y, float z, int range) {
// Initialize the exponents n and m, and the minimum difference
int bestN = 0;
int bestM = 0;
float minDifference = Float.MAX_VALUE;

// Iterate through possible values of n and m to find the best combination
for (int n = 0; n <= range; n++) {
for (int m = 0; m <= range; m++) {
// Calculate x * n + y * m
float value = x * n + y * m;

// Calculate the difference from z
float difference = Math.abs(value - z);

// Update the best values if the current difference is smaller
if (difference < minDifference) {
minDifference = difference;
bestN = n;
bestM = m;
}
}
}

return String.join("\n", lines);
return new int[]{bestN, bestM};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ public class CommonPlaceholder implements PlaceholderParser {
public String parseString(String text) {
text = text.replace("%online%", String.valueOf(plugin.getPlayerCount()));
text = text.replace("%max%", String.valueOf(plugin.getMaxPlayers()));
text = text.replace("%newline%", "\n");
text = text.replace("%newline%", "<newline>");
text = text.replace("\n", "<newline>");
text = text.replace("<online>", String.valueOf(plugin.getPlayerCount()));
text = text.replace("<max>", String.valueOf(plugin.getMaxPlayers()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ public void loadConfig() {
public void registerCommonPlaceholder() {
platform.startup("Registering placeholders");
PlaceholderUtil.registerParser(new CommonPlaceholder(platform));
PlaceholderUtil.registerParser(new CenterPlaceholder.PreProcessorCenterPlaceholder());
PlaceholderUtil.registerPostParser(new CenterPlaceholder());
PlaceholderUtil.registerParser(new CenterPlaceholder.PreProcessor());
PlaceholderUtil.registerPostParser(new CenterPlaceholder.PostProcessor());
}

public void loadFavicons() {
Expand Down

0 comments on commit f04321f

Please sign in to comment.