Skip to content

Commit 67137c6

Browse files
committed
Enhance BedrockNameResolver for improved player name matching
- Updated documentation for clarity on matching logic. - Implemented deterministic preference for Java players over Bedrock. - Added handling for prefixed and prefix-stripped player name comparisons.
1 parent bbbcf7e commit 67137c6

File tree

1 file changed

+68
-11
lines changed

1 file changed

+68
-11
lines changed

AdvancedCore/src/main/java/com/bencodez/advancedcore/api/bedrock/BedrockNameResolver.java

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,30 +353,87 @@ private String stripPrefixIfPresent(String n) {
353353
}
354354

355355
/**
356-
* Find an online player matching the provided name in either: - exact form
357-
* (case-insensitive), OR - prefixed variant, OR - prefix-stripped comparison
358-
* (online ".name" matches input "name")
356+
* Find an online player matching the provided name in either:
357+
* <ul>
358+
* <li>Exact form (case-insensitive)</li>
359+
* <li>Prefixed variant (case-insensitive)</li>
360+
* <li>Prefix-stripped comparison (e.g. ".DarkAshley" matches "darkashley")</li>
361+
* </ul>
362+
*
363+
* <p>
364+
* IMPORTANT: If both a Java and Bedrock player effectively match the same
365+
* unprefixed input (e.g. "Name" and ".Name" are both online), this method will
366+
* deterministically prefer the Java player to avoid incorrectly forcing Bedrock
367+
* resolution due to non-deterministic iteration order.
368+
* </p>
369+
*
370+
* @param name incoming player name
371+
* @return matching online {@link Player} or null
359372
*/
360373
private Player findOnlineByNameOrStripped(String name) {
361-
if (name == null || name.isEmpty())
374+
if (name == null || name.isEmpty()) {
362375
return null;
376+
}
363377

364378
final String lower = name.toLowerCase(Locale.ROOT);
365379
final String prefixed = buildPrefixedVariant(name);
366380

381+
// 1) Exact match first (deterministic preference)
367382
for (Player p : Bukkit.getOnlinePlayers()) {
368383
final String pn = p.getName();
369-
if (pn.equalsIgnoreCase(name))
384+
if (pn != null && pn.equalsIgnoreCase(name)) {
370385
return p;
386+
}
387+
}
371388

372-
if (prefixed != null && pn.equalsIgnoreCase(prefixed))
373-
return p;
389+
// 2) Prefixed variant match next (if incoming was unprefixed)
390+
if (prefixed != null) {
391+
for (Player p : Bukkit.getOnlinePlayers()) {
392+
final String pn = p.getName();
393+
if (pn != null && pn.equalsIgnoreCase(prefixed)) {
394+
return p;
395+
}
396+
}
397+
}
374398

375-
// ".DarkAshley" should match "darkashley"
376-
if (stripPrefixIfPresent(pn).toLowerCase(Locale.ROOT).equals(lower))
377-
return p;
399+
// 3) Prefix-stripped match last
400+
// If multiple players match after stripping, prefer Java over Bedrock.
401+
Player bedrockCandidate = null;
402+
Player javaCandidate = null;
403+
404+
for (Player p : Bukkit.getOnlinePlayers()) {
405+
final String pn = p.getName();
406+
if (pn == null) {
407+
continue;
408+
}
409+
410+
final String strippedLower = stripPrefixIfPresent(pn).toLowerCase(Locale.ROOT);
411+
if (!strippedLower.equals(lower)) {
412+
continue;
413+
}
414+
415+
// Decide preference using UUID-based bedrock detection (authoritative online)
416+
boolean isBedrock = false;
417+
try {
418+
isBedrock = bedrockDetect.isBedrock(p.getUniqueId());
419+
} catch (Throwable ignored) {
420+
// If detection fails, treat as unknown; prefer as java to avoid
421+
// incorrectly forcing bedrock.
422+
isBedrock = false;
423+
}
424+
425+
if (isBedrock) {
426+
if (bedrockCandidate == null) {
427+
bedrockCandidate = p;
428+
}
429+
} else {
430+
// Java (or unknown) wins immediately
431+
javaCandidate = p;
432+
break;
433+
}
378434
}
379-
return null;
435+
436+
return (javaCandidate != null) ? javaCandidate : bedrockCandidate;
380437
}
381438

382439
public static final class Result {

0 commit comments

Comments
 (0)