Skip to content

Commit 6cb9ca2

Browse files
committed
Intelligently style chat messages
1 parent 70d9dfa commit 6cb9ca2

File tree

4 files changed

+84
-85
lines changed

4 files changed

+84
-85
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ yarn_mappings=1.21.3+build.2
99
loader_version=0.16.7
1010

1111
# Mod Properties
12-
mod_version=1.0.0
12+
mod_version=1.1.0a15
1313
maven_group=com.scnamelink
1414
archives_base_name=sc-name-link
1515

src/client/java/com/scnamelink/SpooncraftNameLinkClient.java

Lines changed: 80 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer;
66
import net.fabricmc.api.ClientModInitializer;
77
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
8+
import net.minecraft.text.HoverEvent;
89
import net.minecraft.text.MutableText;
910
import net.minecraft.text.Style;
1011
import net.minecraft.text.Text;
@@ -30,12 +31,56 @@ public class SpooncraftNameLinkClient implements ClientModInitializer {
3031
// List of mappings for replacement and optional color changes
3132
private static List<DisplayMapping> mappings = new ArrayList<>();
3233

34+
/**
35+
* Applies the mapping to a given message. It optionally replaces the Minecraft name with
36+
* the Discord nickname and applies the colour styling.
37+
*
38+
* @param message The original in-game message or name
39+
* @param mapping The {@code DisplayMapping} object containing the name and color mapping
40+
* details
41+
* @param replaceName Whether to replace the name with the name defined in the mapping
42+
* @param replaceColour Whether to replace the colour with the colour defined in the mapping
43+
* @return A new MutableText object with the mapping applied (replacements and color changes)
44+
*/
45+
static MutableText applyMapping(Text message, DisplayMapping mapping,
46+
boolean replaceName, boolean replaceColour) {
47+
if (message == null || message.getString().isEmpty() || mapping == null) {
48+
return Text.empty();
49+
}
50+
51+
MutableText outputMessage = Text.empty();
52+
message.visit((style, text) -> {
53+
String replacedText = text;
54+
Style replacedStyle = style;
55+
56+
// Apply the mapping
57+
if (replacedText.contains(mapping.mc_name)) {
58+
// Replace the string
59+
if (mapping.discord_nick != null && replaceName) {
60+
replacedText = replacedText.replace(mapping.mc_name, mapping.discord_nick);
61+
}
62+
// Apply color if specified
63+
if (mapping.colour != null && replaceColour) {
64+
replacedStyle = replacedStyle.withColor(Integer.parseInt(mapping.colour, 16));
65+
}
66+
}
67+
68+
// Create new MutableText with the display string and style
69+
MutableText newText = (MutableText) Text.of(replacedText);
70+
newText.setStyle(replacedStyle);
71+
outputMessage.append(newText);
72+
73+
return Optional.empty(); // Continue visiting
74+
}, Style.EMPTY);
75+
76+
return outputMessage;
77+
}
3378

3479
/**
3580
* Retrieves and applies the correct name mapping (if any) for a given Minecraft username or
3681
* UUID.
37-
* This method checks the mappings list to see if the provided displayName or uuid has a
38-
* corresponding mapping, and if found, applies it by optionally altering the name and color.
82+
* Checks the mappings list to see if the provided displayName or uuid has a corresponding
83+
* mapping, and if found, applies it by optionally altering the name and color.
3984
*
4085
* @param displayName The original in-game name to be displayed
4186
* @param uuid The UUID of the Minecraft player
@@ -46,28 +91,18 @@ public class SpooncraftNameLinkClient implements ClientModInitializer {
4691
*/
4792
public static Text getStyledName(Text displayName, UUID uuid, String name, boolean replaceName,
4893
boolean replaceColour) {
49-
DisplayMapping correctMapping = null;
50-
5194
// Iterate over the mappings to find the correct match based on UUID or Minecraft name
5295
for (DisplayMapping mapping : mappings) {
53-
// If the UUID matches or the name matches, select the mapping and break
96+
// If the UUID matches or the name matches, apply the mapping and return it
5497
if (Objects.equals(mapping.mc_uuid, uuid) || Objects.equals(mapping.mc_name, name)) {
55-
correctMapping = mapping;
56-
break;
98+
return applyMapping(displayName, mapping, replaceName, replaceColour);
5799
}
58100
}
59-
60-
// If a matching mapping is found, apply it; otherwise, return the original displayName
61-
if (correctMapping != null) { // If a mapping could be found.
62-
return applyMapping(displayName, correctMapping, replaceName, replaceColour);
63-
}
64-
// If the mapping couldn't be found, simply return what we got.
65101
return displayName;
66102
}
67103

68104
/**
69-
* Retrieves and applies the correct name mapping (if any) for a given Minecraft username or
70-
* UUID.
105+
* Retrieves and applies the correct name mapping (if any) for a given Minecraft username.
71106
*
72107
* @param displayName The original in-game name to be displayed
73108
* @param name The in-game name as a Text object
@@ -78,78 +113,43 @@ public static Text getStyledName(Text displayName, UUID uuid, String name, boole
78113
*/
79114
public static Text getStyledName(Text displayName, String name, boolean replaceName,
80115
boolean replaceColour) {
81-
return getStyledName(displayName, new UUID(0, 0), name, replaceName, replaceColour);
116+
return getStyledName(displayName, UUID.fromString("00000000-0000-0000-0000-000000000000"), name, replaceName, replaceColour);
82117
}
83118

84119
/**
85-
* Applies the mapping to a given message. It optionally replaces the Minecraft name with
86-
* the Discord nickname and applies the colour styling.
120+
* Styles the chat message by replacing the name and colour if specified.
121+
* Only styles the name if the text has a {@code HoverEvent} component.
87122
*
88123
* @param message The original in-game message or name
89-
* @param mapping The {@code DisplayMapping} object containing the name and color mapping
90-
* details
91124
* @param replaceName Whether to replace the name with the name defined in the mapping
92125
* @param replaceColour Whether to replace the colour with the colour defined in the mapping
93126
* @return A new MutableText object with the mapping applied (replacements and color changes)
94127
*/
95-
public static MutableText applyMapping(Text message, DisplayMapping mapping,
96-
boolean replaceName, boolean replaceColour) {
97-
MutableText outputMessage = Text.empty();
98-
99-
if (message == null || message.getString().isEmpty() || mapping == null) {
100-
return outputMessage;
128+
public static Text getStyledChat(Text message, boolean replaceName, boolean replaceColour) {
129+
if (message == null || message.getString().isEmpty()) {
130+
return Text.empty();
101131
}
102132

133+
MutableText outputMessage = Text.empty();
103134
message.visit((style, text) -> {
104-
Style replacedStyle = style;
105-
String replacedText = text;
106-
107-
// Apply the mapping
108-
if (replacedText.contains(mapping.mc_name)) {
109-
// Replace the string
110-
if (mapping.discord_nick != null && replaceName) {
111-
replacedText = replacedText.replace(mapping.mc_name, mapping.discord_nick);
112-
}
113-
// Apply color if specified
114-
if (mapping.colour != null && replaceColour) {
115-
replacedStyle = replacedStyle.withColor(Integer.parseInt(mapping.colour, 16));
135+
MutableText newText = Text.literal(text).setStyle(style);
136+
137+
HoverEvent event = style.getHoverEvent();
138+
if (event != null) {
139+
HoverEvent.EntityContent value = event.getValue(HoverEvent.Action.SHOW_ENTITY);
140+
if (value != null && value.name.isPresent()) {
141+
newText = (MutableText) getStyledName(newText, value.uuid, String.valueOf(value.name), replaceName, replaceColour)
142+
.setStyle(newText.getStyle().withHoverEvent(event));
116143
}
117144
}
118145

119-
// Create new MutableText with the display string and style
120-
MutableText newText = (MutableText) Text.of(replacedText);
121-
newText.setStyle(replacedStyle);
122146
outputMessage.append(newText);
123-
124-
return Optional.empty(); // Continue visiting
147+
return Optional.empty();
125148
}, Style.EMPTY);
126149

127150
return outputMessage;
128151
}
129152

130-
/**
131-
* Naively applies styling and replacements to a given message.
132-
* This method applies every name mapping in the mappings list to the message, regardless of
133-
* context.
134-
*
135-
* @param message The original message to which mappings will be applied
136-
* @param replaceName Whether to replace the name with the name defined in the mapping
137-
* @param replaceColour Whether to replace the colour with the colour defined in the mapping
138-
* @return A new Text object with all applicable mappings and styles applied
139-
*/
140-
public static Text naivelyStyleText(Text message, boolean replaceName, boolean replaceColour) {
141-
MutableText outputMessage = (MutableText) message;
142-
143-
// Apply each mapping sequentially to the message
144-
for (DisplayMapping mapping : mappings) {
145-
outputMessage = applyMapping(outputMessage, mapping, replaceName, replaceColour);
146-
}
147-
148-
// Return the final styled message
149-
return outputMessage;
150-
}
151-
152-
153153
/**
154154
* Retrieves the mappings from the specified source URL or the default URL if none is provided.
155155
* If the mod is disabled in the configuration, it disables the mod and logs a warning.
@@ -159,26 +159,23 @@ public static Text naivelyStyleText(Text message, boolean replaceName, boolean r
159159
* @return The number of mappings retrieved.
160160
*/
161161
public static int getMappings(String source) {
162-
String s = source;
163-
if (s == null || s.isEmpty())
164-
s = "https://gwaff.uqcloud.net/api/spooncraft";
165-
162+
String s = (source == null || source.isEmpty()) ? "https://gwaff.uqcloud.net/api/spooncraft" : source;
166163
mappings = NameLinkAPI.getMappings(s);
167-
168164
return mappings.size();
169165
}
170166

167+
/**
168+
* Retrieves a Text object detailing the status of the mod.
169+
*
170+
* @return A Text object containing the status of the mod
171+
*/
171172
public static Text getStatusString() {
172173
String status = NameLinkAPI.getStatus();
173174
return switch (status) {
174-
case "Success" ->
175-
Text.translatable("text.scnamelink.status.success").formatted(Formatting.WHITE);
176-
case "Working" ->
177-
Text.translatable("text.scnamelink.status.working").formatted(Formatting.YELLOW);
178-
case "Fallback" ->
179-
Text.translatable("text.scnamelink.status.fallback").formatted(Formatting.RED);
180-
case "Failure" ->
181-
Text.translatable("text.scnamelink.status.failure").formatted(Formatting.RED, Formatting.BOLD);
175+
case "Success" -> Text.translatable("text.scnamelink.status.success").formatted(Formatting.WHITE);
176+
case "Working" -> Text.translatable("text.scnamelink.status.working").formatted(Formatting.YELLOW);
177+
case "Fallback" -> Text.translatable("text.scnamelink.status.fallback").formatted(Formatting.RED);
178+
case "Failure" -> Text.translatable("text.scnamelink.status.failure").formatted(Formatting.RED, Formatting.BOLD);
182179
default -> Text.of(NameLinkAPI.getStatus());
183180
};
184181
}
@@ -189,9 +186,11 @@ public void onInitializeClient() {
189186
config = AutoConfig.getConfigHolder(SCNameLinkConfig.class).getConfig();
190187

191188
final int count = getMappings(config.apiLink);
192-
if (count > 0)
189+
if (count > 0) {
193190
LOGGER.info("{} initialised with {} mappings", MOD_ID, mappings.size());
194-
else LOGGER.warn("{} initialised with NO mappings found", MOD_ID);
191+
} else {
192+
LOGGER.warn("{} initialised with NO mappings found", MOD_ID);
193+
}
195194

196195
if (!config.enableMod) {
197196
NameLinkAPI.disableMod();

src/client/java/com/scnamelink/config/SCNameLinkConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ public class SCNameLinkConfig implements ConfigData {
2626
// Whether to replace names in the chat using discord nicknames.
2727
public boolean replacechat = true;
2828
// Whether to colour names in the chat using the colour from discord.
29-
public boolean colourchat = false;
29+
public boolean colourchat = true;
3030
}

src/client/java/com/scnamelink/mixin/client/ChatHudMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void onReceivingMessages(Args args) {
2525

2626
Text message = args.get(1);
2727

28-
args.set(1, SpooncraftNameLinkClient.naivelyStyleText(message,CONFIG.replacechat,
29-
CONFIG.colourchat));
28+
args.set(1, SpooncraftNameLinkClient.getStyledChat(message, CONFIG.replacechat,
29+
CONFIG.colourchat));
3030
}
3131
}

0 commit comments

Comments
 (0)