2424import org .bukkit .Bukkit ;
2525import org .bukkit .OfflinePlayer ;
2626import org .bukkit .Server ;
27+ import org .bukkit .entity .Player ;
2728import org .jetbrains .annotations .Nullable ;
29+ import org .maxgamer .quickshop .QuickShop ;
2830
2931import java .util .Arrays ;
3032import java .util .Locale ;
33+ import java .util .Map ;
34+ import java .util .Set ;
3135import java .util .UUID ;
3236import java .util .concurrent .TimeUnit ;
37+ import java .util .logging .Level ;
3338
3439/**
3540 * A player finder for finding player by name
3944 */
4045public final class PlayerFinder {
4146
47+ //Hold store for large server
48+ private static final Map <String , UUID > string2UUIDStash = new java .util .concurrent .ConcurrentHashMap <>();
4249 private static final Cache <String , UUID > string2UUIDCache = CacheBuilder .newBuilder ().expireAfterAccess (60 , TimeUnit .MINUTES ).build ();
4350
51+ private static volatile boolean isStashNeeded ;
52+
4453 private PlayerFinder () {
4554 }
4655
@@ -49,37 +58,54 @@ public static UUID findUUIDByName(String name) {
4958 }
5059
5160 @ Nullable
52- private static OfflinePlayer findPlayerByName (String name , java .util .Collection <? extends org .bukkit .OfflinePlayer > players ) {
53- //Cache all players when offline player is too many
54- boolean cacheAllPlayers = players .size () > 5000 ;
55- OfflinePlayer result = null ;
61+ private static OfflinePlayer findPlayerByName (String name , java .util .Collection <? extends org .bukkit .OfflinePlayer > players , boolean isOfflinePlayer ) {
5662 for (OfflinePlayer player : players ) {
5763 String playerName = player .getName ();
5864 if (playerName != null ) {
5965 if (playerName .equalsIgnoreCase (name )) {
60- result = player ;
61- if (!cacheAllPlayers ) {
62- return result ;
63- }
64- }
65- if (cacheAllPlayers ) {
66- string2UUIDCache .put (playerName .toLowerCase (Locale .ROOT ), player .getUniqueId ());
66+ return player ;
6767 }
6868 }
6969 }
70- return result ;
70+ return null ;
71+ }
72+
73+ public static Set <String > getCachedOfflinePlayerNames () {
74+ return string2UUIDStash .keySet ();
75+ }
76+
77+ public static void updateStashIfNeeded (Player player ) {
78+ if (isStashNeeded ) {
79+ string2UUIDStash .put (player .getName ().toLowerCase (Locale .ROOT ), player .getUniqueId ());
80+ }
81+ }
82+
83+ public static void doLargeOfflineCachingWork (QuickShop quickShop , OfflinePlayer [] offlinePlayers ) {
84+ quickShop .getLogger ().log (Level .INFO , "Large server detected (offline player > 2000), start offline player caching..." );
85+ isStashNeeded = true ;
86+ for (OfflinePlayer offlinePlayer : quickShop .getServer ().getOfflinePlayers ()) {
87+ string2UUIDStash .put (offlinePlayer .getName (), offlinePlayer .getUniqueId ());
88+ }
89+ quickShop .getLogger ().log (Level .INFO , "Done! cached " + offlinePlayers .length + " players." );
7190 }
7291
7392 public static OfflinePlayer findOfflinePlayerByName (String name ) {
7493 OfflinePlayer result ;
75- UUID uuid = string2UUIDCache .getIfPresent (name .toLowerCase (Locale .ROOT ));
94+ UUID uuid ;
95+
96+ uuid = string2UUIDCache .getIfPresent (name .toLowerCase (Locale .ROOT ));
97+
98+ if (uuid == null && !string2UUIDStash .isEmpty ()) {
99+ uuid = string2UUIDStash .get (name .toLowerCase (Locale .ROOT ));
100+ }
101+
76102 if (uuid != null ) {
77103 return Bukkit .getOfflinePlayer (uuid );
78104 } else {
79105 Server server = Bukkit .getServer ();
80- result = findPlayerByName (name , server .getOnlinePlayers ());
106+ result = findPlayerByName (name , server .getOnlinePlayers (), false );
81107 if (result == null ) {
82- result = findPlayerByName (name , Arrays .asList (server .getOfflinePlayers ()));
108+ result = findPlayerByName (name , Arrays .asList (server .getOfflinePlayers ()), true );
83109 }
84110 if (result == null ) {
85111 result = Bukkit .getServer ().getOfflinePlayer (name );
0 commit comments