Compare commits

...
7 Commits
Author SHA1 Message Date
Len 6d9def24e1 Update Gradle 2026-08-01 05:08:27 -05:00
Len cdb75366d4 Correct package com.alttd.afkdectector 2026-07-29 16:37:06 -05:00
Len 68632b7a24 Remove java toolchain 2026-07-29 04:34:15 -05:00
Len bee1048fc2 Remove unused Logger.java 2026-07-25 12:40:40 -05:00
Len b9a7e6a7e4 Refactor commands to use Brigadier. 2026-07-25 12:20:22 -05:00
Len f82160d7d3 Refactor to PaperPlugin 2026-07-25 10:43:58 -05:00
Len ea0d678c83 Update to 26.2 2026-07-23 14:56:32 -05:00
15 changed files with 265 additions and 279 deletions
+66 -24
View File
@@ -1,20 +1,16 @@
import java.io.ByteArrayOutputStream import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
import net.minecrell.pluginyml.paper.PaperPluginDescription
plugins { plugins {
id("java") id("java")
id("de.eldoria.plugin-yml.paper") version "0.9.0"
} }
group = "com.alttd" group = "com.alttd.afkdectector"
version = System.getenv("BUILD_NUMBER") ?: gitCommit() version = System.getenv("BUILD_NUMBER") ?: gitCommit()
description = "Altitude AFK Detector plugin." description = "Altitude AFK Detector plugin."
apply<JavaLibraryPlugin>() apply<JavaLibraryPlugin>()
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(25))
}
}
tasks { tasks {
withType<JavaCompile> { withType<JavaCompile> {
options.encoding = Charsets.UTF_8.name() options.encoding = Charsets.UTF_8.name()
@@ -27,18 +23,10 @@ tasks {
jar { jar {
archiveFileName.set("${rootProject.name}.jar") archiveFileName.set("${rootProject.name}.jar")
} }
processResources {
filteringCharset = Charsets.UTF_8.name()
duplicatesStrategy = DuplicatesStrategy.INCLUDE
filesMatching("plugin.yml") {
expand(Pair("projectVersion", project.version))
}
}
} }
dependencies { dependencies {
compileOnly("com.alttd.cosmos:cosmos-api:26.1.2.build.11-release") { compileOnly("com.alttd.cosmos:cosmos-api:26.2.build.17-stable") {
isChanging = true isChanging = true
} }
compileOnly("de.keyle:mypet-api:4.0.0-SNAPSHOT") compileOnly("de.keyle:mypet-api:4.0.0-SNAPSHOT")
@@ -48,12 +36,66 @@ dependencies {
} }
fun gitCommit(): String { fun gitCommit(): String {
// val os = ByteArrayOutputStream()
// project.exec {
// isIgnoreExitValue = true
// commandLine = "git rev-parse --short HEAD".split(" ")
// standardOutput = os
// }
// return String(os.toByteArray()).trim()
return "FIXME" return "FIXME"
} }
paper {
name = rootProject.name
main = "$group.${rootProject.name}"
description = rootProject.description
bootstrapper = "$group.${rootProject.name}Bootstrap"
version = "${rootProject.version}"
apiVersion = "26.2"
authors = listOf("destro174")
serverDependencies {
register("MyPet") {
required = false
load = PaperPluginDescription.RelativeLoadOrder.BEFORE
}
}
permissions {
register("afkdetector.admin") {
description = "Admin permission for the ${rootProject.name} plugin."
default = BukkitPluginDescription.Permission.Default.FALSE
children = listOf(
"afkdetector.bypass",
"afkdetector.afklist",
"afkdetector.afkcheck",
"afkdetector.notify",
"afkdetector.reload"
)
}
register("afkdetector.bypass") {
description = "Bypass permission for the ${rootProject.name} plugin."
default = BukkitPluginDescription.Permission.Default.FALSE
children = listOf(
"afkdetector.kickexempt"
)
}
register("afkdetector.reload") {
description = "Allows reloading the ${rootProject.name} plugin."
default = BukkitPluginDescription.Permission.Default.FALSE
}
register("afkdetector.kickexempt") {
description = "Bypass permission for being afk kicked."
default = BukkitPluginDescription.Permission.Default.FALSE
}
register("afkdetector.afktime") {
description = "Master permission for custom afk time in the ${rootProject.name} plugin."
default = BukkitPluginDescription.Permission.Default.FALSE
}
register("afkdetector.afkcheck") {
description = "Allows usage of the /afkcheck command."
default = BukkitPluginDescription.Permission.Default.FALSE
}
register("afkdetector.afklist") {
description = "Allows usage of the /afklist command."
default = BukkitPluginDescription.Permission.Default.FALSE
}
register("afkdetector.notify") {
description = "Get notified when a player is afk."
default = BukkitPluginDescription.Permission.Default.FALSE
}
}
}
Binary file not shown.
+3 -1
View File
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
Vendored
+26 -18
View File
@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright © 2015-2021 the original authors. # Copyright © 2015 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +82,11 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@@ -133,22 +132,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@@ -165,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -193,16 +198,19 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available. # Stop when "xargs" is not available.
Vendored
+14 -12
View File
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@@ -26,6 +28,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@@ -42,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -56,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
+7
View File
@@ -14,6 +14,13 @@ dependencyResolutionManagement {
password = nexusPass password = nexusPass
} }
} }
maven {
url = uri("https://repo.alttd.com/repository/alttd/")
credentials {
username = nexusUser
password = nexusPass
}
}
maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.papermc.io/repository/maven-public/")
maven { maven {
name = "userderezzedRepoSnapshots" name = "userderezzedRepoSnapshots"
@@ -10,7 +10,10 @@ import com.alttd.afkdectector.config.Messages;
import com.alttd.afkdectector.config.MessagesConfig; import com.alttd.afkdectector.config.MessagesConfig;
import com.alttd.afkdectector.trackers.AutoJoinTracker; import com.alttd.afkdectector.trackers.AutoJoinTracker;
import com.alttd.afkdectector.trackers.SuspiciousKickTracker; import com.alttd.afkdectector.trackers.SuspiciousKickTracker;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
@@ -25,10 +28,12 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -53,11 +58,9 @@ public class AFKDetector extends JavaPlugin implements Listener {
miniMessage = MiniMessage.miniMessage(); miniMessage = MiniMessage.miniMessage();
loadConfig(null); loadConfig(null);
getServer().getPluginManager().registerEvents(this, this); getServer().getPluginManager().registerEvents(this, this);
//getCommand("afk").setExecutor(new AFKCommand(this));
getCommand("afklist").setExecutor(new AFKListCommand(this)); registerCommands();
getCommand("afkcheck").setExecutor(new AFKCheckCommand(this));
getCommand("relogcheck").setExecutor(new RelogCheckCommand(this));
getCommand("reloadafkdetector").setExecutor(new ReloadCommand(this));
new AFKCheckTimer(this).init(); new AFKCheckTimer(this).init();
myPetEnabled = getServer().getPluginManager().isPluginEnabled("MyPet"); myPetEnabled = getServer().getPluginManager().isPluginEnabled("MyPet");
} catch (Throwable t) { } catch (Throwable t) {
@@ -69,6 +72,17 @@ public class AFKDetector extends JavaPlugin implements Listener {
} }
} }
private void registerCommands() {
LifecycleEventManager<Plugin> manager = this.getLifecycleManager();
manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> {
final Commands commands = event.registrar();
new AFKListCommand().register(commands);
new AFKCheckCommand().register(commands);
new RelogCheckCommand().register(commands);
new ReloadCommand().register(commands);
});
}
@Override @Override
public void onDisable() { public void onDisable() {
this.getServer().getScheduler().cancelTasks(this); this.getServer().getScheduler().cancelTasks(this);
@@ -0,0 +1,13 @@
package com.alttd.afkdectector;
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
@SuppressWarnings("UnstableApiUsage")
public class AFKDetectorBootstrap implements PluginBootstrap {
@Override
public void bootstrap(BootstrapContext context) {}
}
@@ -3,6 +3,10 @@ package com.alttd.afkdectector.command;
import com.alttd.afkdectector.AFKDetector; import com.alttd.afkdectector.AFKDetector;
import com.alttd.afkdectector.afkplayer.AFKPlayer; import com.alttd.afkdectector.afkplayer.AFKPlayer;
import com.alttd.afkdectector.config.Messages; import com.alttd.afkdectector.config.Messages;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
@@ -21,45 +25,35 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class AFKCheckCommand implements CommandExecutor, TabCompleter { public class AFKCheckCommand {
private final AFKDetector plugin; public void register(Commands commands) {
commands.register(
Commands.literal("afkcheck")
.requires(commandSourceStack ->
commandSourceStack.getSender().hasPermission("afkdetector.afkcheck"))
.then(Commands.argument("player", ArgumentTypes.player())
.executes(commandContext -> {
CommandSourceStack sourceStack = commandContext.getSource();
Player target = commandContext.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
public AFKCheckCommand(AFKDetector plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (!(args.length > 0)) {
sender.sendMessage(Component.text(command.getUsage(), NamedTextColor.RED));
return true;
}
Player target = Bukkit.getPlayer(args[0]);
if (target == null) {
sender.sendMessage(Component.text(command.getUsage(), NamedTextColor.RED));
return true;
}
MiniMessage miniMessage = AFKDetector.miniMessage; MiniMessage miniMessage = AFKDetector.miniMessage;
target.showTitle(Title.title(miniMessage.deserialize(Messages.AFK_CHECK_TITLE.getMessage()), target.showTitle(Title.title(miniMessage.deserialize(Messages.AFK_CHECK_TITLE.getMessage()),
miniMessage.deserialize(Messages.AFK_CHECK_SUBTITLE.getMessage()))); miniMessage.deserialize(Messages.AFK_CHECK_SUBTITLE.getMessage())));
if (sender instanceof Player player) {
String cmd = "msg " + args[0] + " " + Messages.AFK_CHECK_MESSAGE.getMessage(); if (commandContext.getSource().getSender() instanceof Player player) {
String cmd = "msg " + target.getName() + " " + Messages.AFK_CHECK_MESSAGE.getMessage();
PlayerCommandPreprocessEvent commandEvent = new PlayerCommandPreprocessEvent(player, "/" + cmd); PlayerCommandPreprocessEvent commandEvent = new PlayerCommandPreprocessEvent(player, "/" + cmd);
Bukkit.getPluginManager().callEvent(commandEvent); Bukkit.getPluginManager().callEvent(commandEvent);
player.performCommand(cmd); player.performCommand(cmd);
} else { } else {
Bukkit.dispatchCommand(sender, "msg " + args[0] + " " + Messages.AFK_CHECK_MESSAGE.getMessage()); Bukkit.dispatchCommand(commandContext.getSource().getSender(), "msg " + target.getName() + " " + Messages.AFK_CHECK_MESSAGE.getMessage());
} }
return true; return com.mojang.brigadier.Command.SINGLE_SUCCESS;
} })
)
@Override .build()
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) { , "Perform an afk check on the target."
List<String> completions = new ArrayList<>(); );
if (strings.length == 1) {
StringUtil.copyPartialMatches(strings[0], plugin.players.values().stream().filter(AFKPlayer::isAFK).map(AFKPlayer::getPlayerName).collect(Collectors.toList()), completions);
}
return null;
} }
} }
@@ -4,33 +4,39 @@ import com.alttd.afkdectector.AFKDetector;
import com.alttd.afkdectector.afkplayer.AFKPlayer; import com.alttd.afkdectector.afkplayer.AFKPlayer;
import com.alttd.afkdectector.config.Config; import com.alttd.afkdectector.config.Config;
import com.alttd.afkdectector.config.Messages; import com.alttd.afkdectector.config.Messages;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class AFKListCommand implements CommandExecutor, TabCompleter { public class AFKListCommand {
private final AFKDetector plugin; public void register(Commands commands) {
commands.register(
public AFKListCommand(AFKDetector plugin) { Commands.literal("afklist")
this.plugin = plugin; .requires(commandSourceStack ->
} commandSourceStack.getSender().hasPermission("afkdetector.afkcheck"))
.executes(commandContext -> {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
int afkPlayers = 0; int afkPlayers = 0;
Component message = Component.empty(); Component message = Component.empty();
MiniMessage miniMessage = AFKDetector.miniMessage; MiniMessage miniMessage = AFKDetector.miniMessage;
for (AFKPlayer afkplayer : plugin.players.values()) { for (AFKPlayer afkplayer : AFKDetector.getInstance().players.values()) {
long standingTime = afkplayer.getStandingTime(); long standingTime = afkplayer.getStandingTime();
if (System.currentTimeMillis() - standingTime <= TimeUnit.MINUTES.toMillis(Config.TOGGLE_TIME)) { if (System.currentTimeMillis() - standingTime <= TimeUnit.MINUTES.toMillis(Config.TOGGLE_TIME)) {
continue; continue;
@@ -50,12 +56,12 @@ public class AFKListCommand implements CommandExecutor, TabCompleter {
Placeholder.parsed("afkplayers", Integer.toString(afkPlayers)) Placeholder.parsed("afkplayers", Integer.toString(afkPlayers))
); );
Component component = miniMessage.deserialize(Messages.AFK_LIST.getMessage(), templates); Component component = miniMessage.deserialize(Messages.AFK_LIST.getMessage(), templates);
sender.sendMessage(component.append(message)); commandContext.getSource().getSender().sendMessage(component.append(message));
return true;
}
@Override return com.mojang.brigadier.Command.SINGLE_SUCCESS;
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) { })
return null; .build()
, "List all players that are afk"
);
} }
} }
@@ -1,6 +1,7 @@
package com.alttd.afkdectector.command; package com.alttd.afkdectector.command;
import com.alttd.afkdectector.AFKDetector; import com.alttd.afkdectector.AFKDetector;
import io.papermc.paper.command.brigadier.Commands;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@@ -9,22 +10,19 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
public class ReloadCommand implements CommandExecutor, TabCompleter { public class ReloadCommand {
private final AFKDetector plugin; public void register(Commands commands) {
commands.register(
public ReloadCommand(AFKDetector plugin) { Commands.literal("reloadafkdetector")
this.plugin = plugin; .requires(commandSourceStack ->
} commandSourceStack.getSender().hasPermission("afkdetector.reload"))
.executes(commandContext -> {
@Override AFKDetector.getInstance().loadConfig(commandContext.getSource().getSender());
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { return com.mojang.brigadier.Command.SINGLE_SUCCESS;
AFKDetector.getInstance().loadConfig(sender); })
return true; .build()
} , "Reload the plugin configuration."
);
@Override
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) {
return null;
} }
} }
@@ -3,6 +3,10 @@ package com.alttd.afkdectector.command;
import com.alttd.afkdectector.AFKDetector; import com.alttd.afkdectector.AFKDetector;
import com.alttd.afkdectector.afkplayer.AFKPlayer; import com.alttd.afkdectector.afkplayer.AFKPlayer;
import com.alttd.afkdectector.config.Messages; import com.alttd.afkdectector.config.Messages;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
@@ -21,45 +25,35 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class RelogCheckCommand implements CommandExecutor, TabCompleter { public class RelogCheckCommand {
private final AFKDetector plugin; public void register(Commands commands) {
commands.register(
Commands.literal("relogcheck")
.requires(commandSourceStack ->
commandSourceStack.getSender().hasPermission("afkdetector.relogcheck"))
.then(Commands.argument("player", ArgumentTypes.player())
.executes(commandContext -> {
CommandSourceStack sourceStack = commandContext.getSource();
Player target = commandContext.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
public RelogCheckCommand(AFKDetector plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (!(args.length > 0)) {
sender.sendMessage(Component.text(command.getUsage(), NamedTextColor.RED));
return true;
}
Player target = Bukkit.getPlayer(args[0]);
if (target == null) {
sender.sendMessage(Component.text(command.getUsage(), NamedTextColor.RED));
return true;
}
MiniMessage miniMessage = AFKDetector.miniMessage; MiniMessage miniMessage = AFKDetector.miniMessage;
target.showTitle(Title.title(miniMessage.deserialize(Messages.RELOG_CHECK_TITLE.getMessage()), target.showTitle(Title.title(miniMessage.deserialize(Messages.RELOG_CHECK_TITLE.getMessage()),
miniMessage.deserialize(Messages.RELOG_CHECK_SUBTITLE.getMessage()))); miniMessage.deserialize(Messages.RELOG_CHECK_SUBTITLE.getMessage())));
if (sender instanceof Player player) {
String cmd = "msg " + args[0] + " " + Messages.RELOG_CHECK_MESSAGE.getMessage(); if (commandContext.getSource().getSender() instanceof Player player) {
String cmd = "msg " + target.getName() + " " + Messages.RELOG_CHECK_MESSAGE.getMessage();
PlayerCommandPreprocessEvent commandEvent = new PlayerCommandPreprocessEvent(player, "/" + cmd); PlayerCommandPreprocessEvent commandEvent = new PlayerCommandPreprocessEvent(player, "/" + cmd);
Bukkit.getPluginManager().callEvent(commandEvent); Bukkit.getPluginManager().callEvent(commandEvent);
player.performCommand(cmd); player.performCommand(cmd);
} else { } else {
Bukkit.dispatchCommand(sender, "msg " + args[0] + " " + Messages.RELOG_CHECK_MESSAGE.getMessage()); Bukkit.dispatchCommand(commandContext.getSource().getSender(), "msg " + target.getName() + " " + Messages.RELOG_CHECK_MESSAGE.getMessage());
} }
return true; return com.mojang.brigadier.Command.SINGLE_SUCCESS;
} })
)
@Override .build()
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, String[] strings) { , "Perform a relog check on the target."
List<String> completions = new ArrayList<>(); );
if (strings.length == 1) {
StringUtil.copyPartialMatches(strings[0], plugin.players.values().stream().filter(AFKPlayer::isAFK).map(AFKPlayer::getPlayerName).collect(Collectors.toList()), completions);
}
return null;
} }
} }
@@ -1,28 +0,0 @@
package com.alttd.afkdectector.util;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import java.util.logging.Level;
public class Logger {
public static void info(String str) {
log(Level.INFO, "&e" + str);
}
public static void warn(String str) {
log(Level.SEVERE, "&6" + str);
}
public static void severe(String str) {
log(Level.SEVERE, "&c" + str);
}
public static void log(Level level, String str) {
Bukkit.getLogger().log(level,
ChatColor.translateAlternateColorCodes('&',
"&r " + str));
}
}
View File
-66
View File
@@ -1,66 +0,0 @@
main: com.alttd.afkdectector.AFKDetector
name: AFKDetector
version: ${projectVersion}
api-version: 1.21
author: Destro174
softdepend:
- MyPet
description: Checks if a player is afk.
commands:
afklist:
description: Gives a list of all afk players
permission: afkdetector.afklist
permission-message: You do not have permission!
usage: /afklist
afkcheck:
description: Sends and afkcheck message to the target
permission: afkdetector.afkcheck
permission-message: You do not have permission!
usage: /afkcheck <target>
relogcheck:
description: Sends and relogcheck message to the target
permission: afkdetector.relogcheck
permission-message: You do not have permission!
usage: /relogcheck <target>
reloadafkdetector:
description: Reloads the plugin config
permission: afkdetector.reload
permission-message: You do not have permission!
usage: /afkdetectorreload
permissions:
afkdetector.admin:
default: op
description: Implies all permissions.
children:
afkdetector.bypass: true
afkdetector.afklist: true
afkdetector.afkcheck: true
afkdetector.notify: true
afkdetector.reload: true
afkdetector.bypass:
description: Bypass the AFKplugin.
default: op
children:
afkdetector.kickexempt: true
afkdetector.reload:
description: Allows reloading the afkdetector plugin config.
default: op
afkdetector.kickexempt:
description: Doesn't kick you automatically for AFK.
default: op
afkdetector.afktime:
description: Master permission for custom times.
default: false
afkdetector.afkcheck:
description: Allows the usage of /afkcheck command.
default: false
afkdetector.afklist:
description: Allows the usage of /afklist command.
default: false
afkdetector.notify:
description: Get output when a player goes afk.
default: false