@@ -29,7 +29,7 @@ public static UuidLookup getInstance() {
2929 private final ConcurrentHashMap <String , String > nameToUuid = new ConcurrentHashMap <>();
3030
3131 private UuidLookup () {
32- // No plugin uuidNameCache anymore. Cache is owned here.
32+ // Cache is owned here.
3333 }
3434
3535 /*
@@ -40,9 +40,9 @@ private UuidLookup() {
4040 * Resolve UUID string from a player name.
4141 *
4242 * Lookup order: 1) If input is already a UUID -> canonical UUID 2) Offline
43- * mode: deterministic UUID from name 3) Online player (Bukkit) 4) Local cache
44- * (name->uuid) 5) Storage (mysql/sqlite) or flatfile scan fallback 6) Bukkit
45- * OfflinePlayer fallback (best-effort)
43+ * mode: deterministic UUID from NORMALIZED name 3) Online player (Bukkit) 4)
44+ * Local cache (name->uuid) 5) Storage (mysql/sqlite) or flatfile scan fallback
45+ * 6) Bukkit OfflinePlayer fallback (best-effort)
4646 *
4747 * @param playerName player name or UUID string
4848 * @return UUID string, or "" if not found / invalid input
@@ -62,13 +62,21 @@ public String getUUID(String playerName) {
6262 return parsed .toString ();
6363 }
6464
65- // Offline mode: deterministic UUID
65+ // Offline mode: deterministic UUID from NORMALIZED name
6666 if (!plugin .getOptions ().isOnlineMode ()) {
67- String uuid = UUID .nameUUIDFromBytes (("OfflinePlayer:" + playerName ).getBytes (StandardCharsets .UTF_8 ))
67+ String normalized = normalizeOfflineName (playerName );
68+ if (normalized .isEmpty ()) {
69+ return "" ;
70+ }
71+ String uuid = UUID .nameUUIDFromBytes (("OfflinePlayer:" + normalized ).getBytes (StandardCharsets .UTF_8 ))
6872 .toString ();
69- // Cache mapping so later lookups are instant + casing preserved for this
70- // session
73+
74+ // Cache mapping so later lookups are instant
75+ // Keep display name as the original provided (casing preserved),
76+ // but ensure name->uuid cache key uses normalized key.
7177 cacheMapping (uuid , playerName );
78+ nameToUuid .put (normNameKey (normalized ), uuid );
79+
7280 return uuid ;
7381 }
7482
@@ -191,6 +199,14 @@ public void cacheMapping(String uuid, String name) {
191199
192200 uuidToName .put (uuid , name );
193201 nameToUuid .put (normNameKey (name ), uuid );
202+
203+ // Also cache normalized offline key when in offline mode
204+ if (!plugin .getOptions ().isOnlineMode ()) {
205+ String normalized = normalizeOfflineName (name );
206+ if (!normalized .isEmpty ()) {
207+ nameToUuid .put (normNameKey (normalized ), uuid );
208+ }
209+ }
194210 }
195211
196212 /**
@@ -211,6 +227,12 @@ public void invalidate(String uuidOrName) {
211227 String name = uuidToName .remove (uuid );
212228 if (name != null ) {
213229 nameToUuid .remove (normNameKey (name ));
230+ if (!plugin .getOptions ().isOnlineMode ()) {
231+ String normalized = normalizeOfflineName (name );
232+ if (!normalized .isEmpty ()) {
233+ nameToUuid .remove (normNameKey (normalized ));
234+ }
235+ }
214236 }
215237 return ;
216238 }
@@ -220,6 +242,16 @@ public void invalidate(String uuidOrName) {
220242 if (uuid != null ) {
221243 uuidToName .remove (uuid );
222244 }
245+
246+ if (!plugin .getOptions ().isOnlineMode ()) {
247+ String normalized = normalizeOfflineName (s );
248+ if (!normalized .isEmpty ()) {
249+ String uuid2 = nameToUuid .remove (normNameKey (normalized ));
250+ if (uuid2 != null ) {
251+ uuidToName .remove (uuid2 );
252+ }
253+ }
254+ }
223255 }
224256
225257 /**
@@ -230,7 +262,19 @@ public String getCachedUUID(String playerName) {
230262 return "" ;
231263 }
232264 String u = nameToUuid .get (normNameKey (playerName ));
233- return isUuidString (u ) ? u : "" ;
265+ if (isUuidString (u )) {
266+ return u ;
267+ }
268+
269+ if (!plugin .getOptions ().isOnlineMode ()) {
270+ String normalized = normalizeOfflineName (playerName );
271+ if (!normalized .isEmpty ()) {
272+ String u2 = nameToUuid .get (normNameKey (normalized ));
273+ return isUuidString (u2 ) ? u2 : "" ;
274+ }
275+ }
276+
277+ return "" ;
234278 }
235279
236280 /**
@@ -278,6 +322,13 @@ private String lookupUuidFromStorageOrFlatfile(String playerName) {
278322 return "" ;
279323 }
280324
325+ private String normalizeOfflineName (String name ) {
326+ if (name == null ) {
327+ return "" ;
328+ }
329+ return name .trim ().toLowerCase (Locale .ROOT );
330+ }
331+
281332 private boolean isGoodName (String n ) {
282333 return n != null && !n .trim ().isEmpty () && !n .equalsIgnoreCase ("Error getting name" );
283334 }
0 commit comments