diff --git a/build.gradle.kts b/build.gradle.kts index 52ed782..8cbcd56 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "com.bitaspire" -version = "1.2.1" +version = "1.2.3" repositories { mavenLocal() diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55..b1b8ef5 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118..b52fb7e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip networkTimeout=10000 +retries=0 +retryBackOffMs=500 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 23d15a9..b9bb139 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat index 5eed7ee..aa5f10b 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -23,8 +23,8 @@ @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -51,7 +51,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,30 +65,18 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/libraries/CyberCore-2.0.0.jar b/libraries/CyberCore-2.0.0.jar index 0f8fbca..2383b7b 100644 Binary files a/libraries/CyberCore-2.0.0.jar and b/libraries/CyberCore-2.0.0.jar differ diff --git a/src/main/java/com/bitaspire/cyberlevels/command/CLVTabComplete.java b/src/main/java/com/bitaspire/cyberlevels/command/CLVTabComplete.java index e54d6dc..28d6641 100644 --- a/src/main/java/com/bitaspire/cyberlevels/command/CLVTabComplete.java +++ b/src/main/java/com/bitaspire/cyberlevels/command/CLVTabComplete.java @@ -25,8 +25,18 @@ public class CLVTabComplete implements TabCompleter { private static final String PLAYER_PREFIX = "CyberLevels.player."; private static final String ADMIN_PREFIX = "CyberLevels.admin."; - - private static final Map COMMAND_PERMISSIONS = new HashMap<>(); + private static final long PLAYER_NAME_CACHE_MILLIS = 5000L; + + private static final List EXP_AMOUNT_SUGGESTIONS = Collections.unmodifiableList( + Arrays.asList("", "5", "100", "250", "1000") + ); + private static final List LEVEL_AMOUNT_SUGGESTIONS = Collections.unmodifiableList( + Arrays.asList("", "1", "2", "5") + ); + private static final Set MUTATION_COMMANDS = Collections.unmodifiableSet(new HashSet<>( + Arrays.asList("addexp", "setexp", "removeexp", "addlevel", "setlevel", "removelevel") + )); + private static final Map COMMAND_PERMISSIONS = new LinkedHashMap<>(); static { COMMAND_PERMISSIONS.put("about", PLAYER_PREFIX + "about"); @@ -48,6 +58,9 @@ public class CLVTabComplete implements TabCompleter { } private final CyberLevels main; + private long playerNamesCachedAt = 0L; + private boolean playerNamesCachedOfflineMode = false; + private List cachedPlayerNames = Collections.emptyList(); /** * Produces context-aware tab completions for the CyberLevels command set. @@ -84,16 +97,14 @@ public List onTabComplete(@NotNull CommandSender sender, @NotNull Comman break; case "addexp": case "setexp": case "removeexp": - return partialMatch(args[1], Arrays.asList("", "5", "100", "250", "1000")); + return partialMatch(args[1], EXP_AMOUNT_SUGGESTIONS); case "addlevel": case "setlevel": case "removelevel": - return partialMatch(args[1], Arrays.asList("", "1", "2", "5")); + return partialMatch(args[1], LEVEL_AMOUNT_SUGGESTIONS); } } - if (args.length == 3 && - Arrays.asList("addexp", "setexp", "removeexp", "addlevel", "setlevel", "removelevel") - .contains(args[0].toLowerCase())) + if (args.length == 3 && MUTATION_COMMANDS.contains(args[0].toLowerCase(Locale.ENGLISH))) { List suggestions = new ArrayList<>(); suggestions.add("[]"); @@ -105,9 +116,16 @@ public List onTabComplete(@NotNull CommandSender sender, @NotNull Comman } private List getPlayerNames() { - List players = new ArrayList<>(); + boolean offlineMode = main.cache().config().isTabCompleteLoadOfflineUsers(); + long now = System.currentTimeMillis(); + + if (offlineMode == playerNamesCachedOfflineMode && + now - playerNamesCachedAt <= PLAYER_NAME_CACHE_MILLIS) + return cachedPlayerNames; + + LinkedHashSet players = new LinkedHashSet<>(); - if (main.cache().config().isTabCompleteLoadOfflineUsers()) { + if (offlineMode) { for (OfflinePlayer p : Bukkit.getOfflinePlayers()) { String name = p.getName(); if (name != null) players.add(name); @@ -118,13 +136,18 @@ private List getPlayerNames() { } } - return players; + List snapshot = new ArrayList<>(players); + snapshot.sort(String.CASE_INSENSITIVE_ORDER); + cachedPlayerNames = snapshot; + playerNamesCachedOfflineMode = offlineMode; + playerNamesCachedAt = now; + return cachedPlayerNames; } private List partialMatch(String input, List options) { List matches = new ArrayList<>(); StringUtil.copyPartialMatches(input, options, matches); - Collections.sort(matches); + matches.sort(String.CASE_INSENSITIVE_ORDER); return matches; } } diff --git a/src/main/java/com/bitaspire/cyberlevels/hook/HookManager.java b/src/main/java/com/bitaspire/cyberlevels/hook/HookManager.java index 7226dd7..e2a046a 100644 --- a/src/main/java/com/bitaspire/cyberlevels/hook/HookManager.java +++ b/src/main/java/com/bitaspire/cyberlevels/hook/HookManager.java @@ -82,33 +82,33 @@ public HookManager(CyberLevels main) { "ms&7.", ""); } - private synchronized boolean loadAxHoesIfReady() { - if (axHoesLoaded) return false; - if (!main.isEnabled("AxHoes")) return false; + private synchronized void loadAxHoesIfReady() { + if (axHoesLoaded || !main.isEnabled("AxHoes")) return; - final long l = System.currentTimeMillis(); + long l = System.currentTimeMillis(); AxHoesHook hook = new AxHoesHook(main, this); hooks.add(hook); + // Only register here if the global register() pass has already run; otherwise it'll be // picked up by hooks.forEach(Hook::register) later. Registering twice would attach the // listener twice and double-count every PlayerXPGainEvent. if (globalRegistered) hook.register(); + axHoesLoaded = true; main.logger("&7Loaded &eAxHoes&7 plugin hook in &a" + (System.currentTimeMillis() - l) + "ms&7."); - return true; } - private synchronized boolean loadAxPickIfReady() { - if (axPickLoaded) return false; - if (!main.isEnabled("AxPickaxes")) return false; + private synchronized void loadAxPickIfReady() { + if (axPickLoaded || !main.isEnabled("AxPickaxes")) return; - final long l = System.currentTimeMillis(); + long l = System.currentTimeMillis(); AxPickHook hook = new AxPickHook(main, this); hooks.add(hook); + if (globalRegistered) hook.register(); + axPickLoaded = true; main.logger("&7Loaded &eAxPickaxes&7 plugin hook in &a" + (System.currentTimeMillis() - l) + "ms&7."); - return true; } void sendExp(Player player, ExpSource source, String item) { @@ -150,7 +150,8 @@ public double externalMultiplier(Player player) { if (player == null) return 1D; double multiplier = 1D; - if (axBoostersHook != null) multiplier *= axBoostersHook.getMultiplier(player); + if (axBoostersHook != null) + multiplier *= axBoostersHook.getMultiplier(player); return multiplier; }