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
13 changes: 13 additions & 0 deletions src/tel/eden/mod/chat/ChatText.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ private ChatText() {
* already a valid username, else null.
*/
static String resolveRealName(Component message, String displayed) {
if (displayed == null) {
return null;
}
if (message == null) {
String cleaned = displayed.replaceAll("[^a-zA-Z0-9_]", "");
return IGN.matcher(cleaned).matches() ? cleaned : null;
}
List<MetaChar> chars = flatten(message);
String text = text(chars);
int start = text.indexOf(displayed);
Expand Down Expand Up @@ -74,6 +81,9 @@ static String resolveRealName(Component message, String displayed) {
* no metadata is present (caller falls back to the displayed name).
*/
public static String resolveRealNameAnywhere(Component message, String displayed) {
if (message == null) {
return null;
}
Set<String> candidates = new LinkedHashSet<>();
message.visit((style, fragment) -> {
String hover = hoverRealName(style);
Expand Down Expand Up @@ -113,6 +123,9 @@ public static String resolveRealNameAnywhere(Component message, String displayed
}

private static List<MetaChar> flatten(Component message) {
if (message == null) {
return List.of();
}
List<MetaChar> out = new ArrayList<>();
message.visit((style, fragment) -> {
String hover = hoverRealName(style);
Expand Down
5 changes: 4 additions & 1 deletion src/tel/eden/mod/chat/PlayerNameResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ public static void reset() {

/** Resolve a rendered player name and retain any hover-provided nickname mapping. */
public static String resolve(Component message, String displayed) {
if (displayed == null) {
return null;
}
// A reward/bank line can contain several player names. Resolving from every
// hover in the whole component made the receiver inherit the giver's hover
// (e.g. a catboy/FadeDave hover turned every recipient into FadeDave). Only
// accept metadata attached to this displayed span; a previously learned alias
// is the safe fallback when the server omits that span's hover.
String resolved = ChatText.resolveRealName(message, displayed);
String resolved = message != null ? ChatText.resolveRealName(message, displayed) : null;
if (resolved == null) {
resolved = canonicalize(displayed);
}
Expand Down
12 changes: 12 additions & 0 deletions test/tel/eden/mod/chat/ChatTextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ void resolveRealNameAnywhereReturnsNullWithNoHoverOrInsertionMetadata() {
assertNull(ChatText.resolveRealNameAnywhere(message, "plain"));
}

@Test
void resolveRealNameHandlesNullMessageSafely() {
assertEquals("Asthae", ChatText.resolveRealName(null, "Asthae"));
assertNull(ChatText.resolveRealName(null, "some weird nickname"));
assertNull(ChatText.resolveRealName(null, null));
}

@Test
void resolveRealNameAnywhereHandlesNullMessageSafely() {
assertNull(ChatText.resolveRealNameAnywhere(null, "plain"));
}

@Test
void resolveClickTargetNamePeelsANickSlashRealSuffix() {
Component message = Component.literal("catboy/FadeDave");
Expand Down
6 changes: 6 additions & 0 deletions test/tel/eden/mod/chat/PlayerNameResolverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,10 @@ void learnFromTextIgnoresUnknownWordsAndLearnsKnownPlayer() {
PlayerNameResolver.learnFromText("KnownUser/NickBuddy joined!");
assertEquals(Optional.of("KnownUser"), PlayerNameResolver.resolveKnown("NickBuddy"));
}

@Test
void resolveHandlesNullMessageSafely() {
assertEquals("SomePlayer", PlayerNameResolver.resolve(null, "SomePlayer"));
assertEquals(null, PlayerNameResolver.resolve(null, null));
}
}
Loading