Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 48 additions & 23 deletions src/main/java/com/mcprotector/chat/FactionTextFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

import com.mcprotector.config.FactionConfig;
import com.mcprotector.data.Faction;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextColor;
import net.minecraft.server.level.ServerPlayer;

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

public final class FactionTextFormatter {
private FactionTextFormatter() {
}
Expand All @@ -19,33 +18,59 @@ public static Component formatChat(FactionChatMode mode, ServerPlayer sender, Fa
case ALLY -> FactionConfig.SERVER.allyChatFormat.get();
case PUBLIC -> FactionConfig.SERVER.publicChatFormat.get();
};
return Component.literal(applyFormat(format, sender, faction, message));
return applyFormat(format, sender, faction, message);
}

public static Component formatTabList(ServerPlayer player, Faction faction) {
String format = FactionConfig.SERVER.tabListFormat.get();
return Component.literal(applyFormat(format, player, faction, ""));
return applyFormat(format, player, faction, "");
}

private static String applyFormat(String format, ServerPlayer sender, Faction faction, String message) {
Map<String, String> replacements = new HashMap<>();
String factionColor = faction != null ? faction.getLegacyColorCode() : ChatFormatting.WHITE.toString();
private static Component applyFormat(String format, ServerPlayer sender, Faction faction, String message) {
String factionName = faction != null ? faction.getName() : "NoFaction";
replacements.put("{faction}", factionColor + factionName + ChatFormatting.RESET);
replacements.put("{player}", sender.getName().getString());
replacements.put("{message}", ChatFormatting.RESET + message);
replacements.put("{faction_color}", factionColor);
replacements.put("{reset}", ChatFormatting.RESET.toString());
String role = faction != null ? faction.getRole(sender.getUUID()) : null;
replacements.put("{role}", role != null ? faction.getRoleDisplayName(role) : "Wanderer");
String result = format;
if (faction != null) {
String coloredBracket = factionColor + "[" + factionName + "]" + ChatFormatting.RESET;
result = result.replace("[{faction}]", coloredBracket);
}
for (Map.Entry<String, String> entry : replacements.entrySet()) {
result = result.replace(entry.getKey(), entry.getValue());
String role = faction != null && faction.getRole(sender.getUUID()) != null
? faction.getRoleDisplayName(faction.getRole(sender.getUUID()))
: "Wanderer";
String playerName = sender.getName().getString();
int factionRgb = faction != null ? faction.getColorRgb() : 0xFFFFFF;
Style currentStyle = Style.EMPTY;
MutableComponent result = Component.empty();

int index = 0;
while (index < format.length()) {
int start = format.indexOf('{', index);
if (start < 0) {
appendLiteral(result, format.substring(index), currentStyle);
break;
}
if (start > index) {
appendLiteral(result, format.substring(index, start), currentStyle);
}
int end = format.indexOf('}', start);
if (end < 0) {
appendLiteral(result, format.substring(start), currentStyle);
break;
}
String token = format.substring(start, end + 1);
switch (token) {
case "{faction_color}" -> currentStyle = currentStyle.withColor(TextColor.fromRgb(factionRgb));
case "{reset}" -> currentStyle = Style.EMPTY;
case "{faction}" -> appendLiteral(result, factionName, currentStyle);
case "{player}" -> appendLiteral(result, playerName, currentStyle);
case "{message}" -> appendLiteral(result, message, currentStyle);
case "{role}" -> appendLiteral(result, role, currentStyle);
default -> appendLiteral(result, token, currentStyle);
}
index = end + 1;
}

return result;
}

private static void appendLiteral(MutableComponent target, String text, Style style) {
if (text == null || text.isEmpty()) {
return;
}
target.append(Component.literal(text).withStyle(style));
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/mcprotector/client/ClientColorHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.mcprotector.client;

public final class ClientColorHelper {
private ClientColorHelper() {
}

/**
* Converts a standard ARGB color value to the color ordering used by client GUI draw calls.
*/
public static int toGuiColor(int argb) {
int alpha = (argb >>> 24) & 0xFF;
int red = (argb >>> 16) & 0xFF;
int green = (argb >>> 8) & 0xFF;
int blue = argb & 0xFF;
return (alpha << 24) | (blue << 16) | (green << 8) | red;
}

public static float red(int argb) {
return (toGuiColor(argb) & 0xFF) / 255.0f;
}

public static float green(int argb) {
return ((toGuiColor(argb) >>> 8) & 0xFF) / 255.0f;
}

public static float blue(int argb) {
return ((toGuiColor(argb) >>> 16) & 0xFF) / 255.0f;
}

public static float alpha(int argb) {
return ((argb >>> 24) & 0xFF) / 255.0f;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public static void render(RenderLevelStageEvent event) {
continue;
}
int color = resolveClaimColor(entry.getValue());
float red = ((color >> 16) & 0xFF) / 255.0f;
float green = ((color >> 8) & 0xFF) / 255.0f;
float blue = (color & 0xFF) / 255.0f;
float alpha = (((color >> 24) & 0xFF) / 255.0f) * BORDER_ALPHA;
float red = ClientColorHelper.red(color);
float green = ClientColorHelper.green(color);
float blue = ClientColorHelper.blue(color);
float alpha = ClientColorHelper.alpha(color) * BORDER_ALPHA;
double minX = chunkPos.getMinBlockX();
double maxX = chunkPos.getMaxBlockX() + 1.0;
double minZ = chunkPos.getMinBlockZ();
Expand Down Expand Up @@ -104,10 +104,10 @@ public static void render(RenderLevelStageEvent event) {
continue;
}
int color = resolveClaimColor(entry.getValue());
float red = ((color >> 16) & 0xFF) / 255.0f;
float green = ((color >> 8) & 0xFF) / 255.0f;
float blue = (color & 0xFF) / 255.0f;
float alpha = (((color >> 24) & 0xFF) / 255.0f) * BORDER_ALPHA;
float red = ClientColorHelper.red(color);
float green = ClientColorHelper.green(color);
float blue = ClientColorHelper.blue(color);
float alpha = ClientColorHelper.alpha(color) * BORDER_ALPHA;
double minX = chunkPos.getMinBlockX();
double maxX = chunkPos.getMaxBlockX() + 1.0;
double minZ = chunkPos.getMinBlockZ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.mcprotector.network.FactionActionPacket;
import com.mcprotector.network.FactionClaimSelectionPacket;
import com.mcprotector.network.FactionStatePacket;
import com.mcprotector.client.ClientColorHelper;
import com.mcprotector.client.ClientNetworkSender;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
Expand Down Expand Up @@ -1101,7 +1102,7 @@ private void renderFactionList(GuiGraphics guiGraphics,
label += " - " + faction.relation();
}
int color = 0xFF000000 | faction.color();
guiGraphics.drawString(this.font, label, getPanelLeft(), y, color);
guiGraphics.drawString(this.font, label, getPanelLeft(), y, ClientColorHelper.toGuiColor(color));
y += lineHeight;
}
renderScrollIndicator(guiGraphics, factions.size(), visibleLines, factionListScrollOffset, listStart, listBottom);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mcprotector.client.gui;

import com.mcprotector.client.ClientColorHelper;
import com.mcprotector.client.FactionMapClientData;
import com.mcprotector.client.map.MapBackgroundProvider;
import com.mcprotector.client.map.MapBackgroundProviders;
Expand Down Expand Up @@ -77,11 +78,12 @@ public static void renderMapGrid(GuiGraphics guiGraphics, FactionMapClientData.M
if (mapSnapshot.backgroundState() != null && mapSnapshot.backgroundState().enabled()) {
color = withAlpha(color, 0xA0);
}
guiGraphics.fill(x, y, x + region.cellSize(), y + region.cellSize(), color);
int guiColor = ClientColorHelper.toGuiColor(color);
guiGraphics.fill(x, y, x + region.cellSize(), y + region.cellSize(), guiColor);
int halfCell = Math.max(1, region.cellSize() / 2);
guiGraphics.fill(x, y, x + halfCell, y + halfCell, 0x18FFFFFF);
guiGraphics.fill(x + halfCell, y + halfCell, x + region.cellSize(), y + region.cellSize(), 0x18000000);
int gridColor = shadeColor(color, 0.75f);
int gridColor = shadeColor(guiColor, 0.75f);
guiGraphics.renderOutline(x, y, region.cellSize(), region.cellSize(), gridColor);
}
}
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/com/mcprotector/command/FactionCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -1034,16 +1034,14 @@ private static int setColor(CommandSourceStack source, String colorName) throws
return 0;
}
String normalized = FactionConfig.normalizeColorInput(colorName);
ChatFormatting named = ChatFormatting.getByName(normalized);
boolean validNamed = named != null && named.isColor();
boolean validHex = FactionConfig.isHexColor(normalized);
if (!validNamed && !validHex) {
source.sendFailure(Component.literal("Unknown color. Use a vanilla color name or hex format (#RRGGBB)."));
if (!validHex) {
source.sendFailure(Component.literal("Unknown color. Use hex format only (#RRGGBB)."));
return 0;
}
faction.get().setColorName(normalized);
faction.get().setColorName("#" + (normalized.startsWith("#") ? normalized.substring(1) : normalized));
FactionData.get(source.getLevel()).setDirty();
source.sendSuccess(() -> Component.literal("Faction color updated to " + normalized), true);
source.sendSuccess(() -> Component.literal("Faction color updated to " + faction.get().getColorName()), true);
return 1;
}

Expand Down
26 changes: 20 additions & 6 deletions src/main/java/com/mcprotector/config/FactionConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,27 @@ public static int parseHexColor(String colorName) {
}

public static int resolveRgbColor(String colorName) {
String normalized = normalizeFactionHexColor(colorName);
if (!isHexColor(normalized)) {
return 0xFFFFFF;
}
return parseHexColor(normalized);
}

public static String normalizeFactionHexColor(String colorName) {
String normalized = normalizeColorInput(colorName);
if (normalized.isEmpty()) {
return "#ffffff";
}
if (isHexColor(normalized)) {
return parseHexColor(normalized);
String hex = normalized.startsWith("#") ? normalized.substring(1) : normalized;
return "#" + hex;
}
ChatFormatting formatting = ChatFormatting.getByName(normalized);
if (formatting != null && formatting.isColor() && formatting.getColor() != null) {
return String.format("#%06x", formatting.getColor());
}
ChatFormatting formatting = parseColor(normalized);
Integer rgb = formatting.getColor();
return rgb == null ? 0xFFFFFF : rgb;
return "#ffffff";
}

public static String toLegacyHexCode(String colorName) {
Expand Down Expand Up @@ -240,8 +254,8 @@ public static final class Server {
private Server(ModConfigSpec.Builder builder) {
builder.push("factions");
defaultFactionColor = builder
.comment("Default faction chat color name (e.g. red, gold, blue).")
.define("defaultFactionColor", "gold");
.comment("Default faction color in hex format (#RRGGBB).")
.define("defaultFactionColor", "#ffd700");
defaultMotd = builder
.comment("Default message of the day for new factions.")
.define("defaultMotd", "Welcome to the faction!");
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/mcprotector/data/Faction.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public String getLegacyColorCode() {
}

public void setColorName(String colorName) {
this.colorName = colorName;
this.colorName = FactionConfig.normalizeFactionHexColor(colorName);
}

public String getMotd() {
Expand Down Expand Up @@ -267,7 +267,7 @@ public boolean removeRule(String rule) {
}

private void applyDefaults() {
colorName = FactionConfig.getDefaultColorName();
colorName = FactionConfig.normalizeFactionHexColor(FactionConfig.getDefaultColorName());
motd = FactionConfig.getDefaultMotd();
description = FactionConfig.getDefaultDescription();
bannerColor = FactionConfig.getDefaultBannerColor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,12 @@ private static int resolveClaimColor(boolean safeZone, boolean personal, String
if (personal) {
return PERSONAL_CLAIM_COLOR;
}
return switch (relation) {
return resolveFactionColor(faction).orElseGet(() -> switch (relation) {
case "OWN" -> 0xFF4CAF50;
case "ALLY" -> 0xFF4FC3F7;
case "WAR" -> 0xFFEF5350;
default -> resolveFactionColor(faction).orElse(0xFF8D8D8D);
};
default -> 0xFF8D8D8D;
});
}

private static Optional<Integer> resolveFactionColor(Optional<Faction> faction) {
Expand Down
Loading