Compare commits

..

7 commits

Author SHA1 Message Date
9a6ff804f1
Bump version to v1-a2 2024-04-30 22:48:35 +02:00
d365fbb89c
Add /toggledownfall command (rip) 2024-04-30 22:48:26 +02:00
8dbb4671dc
Fix /clearchat command 2024-04-30 22:46:36 +02:00
78925ccb9a
Add isCommandSentByConsole method 2024-04-30 22:46:21 +02:00
027b86d5f2
Add /clearchat command 2024-04-30 22:30:55 +02:00
d776de46c7
Replace buggy execution times system
I replaced that buggy execution time checking thingy for simply keeping track of the bukkit scheduler task id and cancelling the task if necessary. Much easier and simpler, with less bugs.
2024-04-30 22:30:44 +02:00
0fb317038a
Add commandbase array 2024-04-30 22:29:00 +02:00
15 changed files with 170 additions and 50 deletions

View file

@ -26,7 +26,7 @@ public final class BuildConfiguration {
public static final String pluginName = "PickShadow Server Plugin"; public static final String pluginName = "PickShadow Server Plugin";
public static final int pluginRelease = 1; public static final int pluginRelease = 1;
public static final Types.VersionType pluginVersionType = Types.VersionType.ALPHA; public static final Types.VersionType pluginVersionType = Types.VersionType.ALPHA;
public static final int pluginTyperelease = 1; public static final int pluginTyperelease = 2;
public static final String[] pluginAuthors = new String[]{ "JeremyStarTM" }; public static final String[] pluginAuthors = new String[]{ "JeremyStarTM" };
public static final String[] pluginContributors = new String[]{}; public static final String[] pluginContributors = new String[]{};
public static final String pluginLicense = "GNU AGPL v3 (or later)"; public static final String pluginLicense = "GNU AGPL v3 (or later)";

View file

@ -18,6 +18,7 @@
*/ */
package de.pickshadow.plugin.base; package de.pickshadow.plugin.base;
import de.pickshadow.plugin.classes.CommandBase;
import de.pickshadow.plugin.classes.logger.LoggerInstanceImpl; import de.pickshadow.plugin.classes.logger.LoggerInstanceImpl;
import de.pickshadow.plugin.commands.*; import de.pickshadow.plugin.commands.*;
import de.pickshadow.plugin.loaders.ConfigLoader; import de.pickshadow.plugin.loaders.ConfigLoader;
@ -32,6 +33,9 @@ public class PluginInitializer {
// Objects // Objects
private final LoggerInstanceImpl logger; private final LoggerInstanceImpl logger;
// Lists
CommandBase[] commands = new CommandBase[0];
public PluginInitializer() { public PluginInitializer() {
logger = ObjHolder.logger.getInstance(getClass()); logger = ObjHolder.logger.getInstance(getClass());
} }
@ -61,16 +65,14 @@ public class PluginInitializer {
return "Could not update active spelling language"; return "Could not update active spelling language";
} }
// Initialize commands
logger.verb("Initializing commands");
commands = new CommandBase[]{new BroadcastCommand(), new DiscordCommand(), new HomeCommand(), new PluginCommand(), new SystemInformationCommand(), new TrollCommand(), new MsgCommand(), new ClearChatCommand(), new ToggleDownfallCommand()};
// Register commands // Register commands
logger.verb("Registering commands"); logger.verb("Registering commands");
try { try {
new BroadcastCommand().registerCommand(); for (CommandBase command : commands) command.registerCommand();
new DiscordCommand().registerCommand();
new HomeCommand().registerCommand();
new PluginCommand().registerCommand();
new SystemInformationCommand().registerCommand();
new TrollCommand().registerCommand();
new MsgCommand().registerCommand();
} catch (NullPointerException e) { } catch (NullPointerException e) {
logger.crash("Could not register plugin commands", e.getStackTrace()); logger.crash("Could not register plugin commands", e.getStackTrace());
} }
@ -92,10 +94,23 @@ public class PluginInitializer {
public void uninitialize() { public void uninitialize() {
logger.info("Uninitializing PSSP"); logger.info("Uninitializing PSSP");
// Close active hunspell instance
logger.verb("Closing Hunspell instance"); logger.verb("Closing Hunspell instance");
ObjHolder.spellingHelper.setActiveLanguage(null); ObjHolder.spellingHelper.setActiveLanguage(null);
// Save player data
logger.verb("Saving player data"); logger.verb("Saving player data");
for (UUID uuid : ObjHolder.playerDataLoader.getLoadedUUIDs()) ObjHolder.playerDataLoader.savePlayerData(uuid); for (UUID uuid : ObjHolder.playerDataLoader.getLoadedUUIDs()) ObjHolder.playerDataLoader.savePlayerData(uuid);
// Unregister commands
logger.verb("Unregistering commands");
try {
for (CommandBase command : commands) command.unregisterCommand();
} catch (NullPointerException e) {
logger.crash("Could not unregister plugin commands", e.getStackTrace(), true);
}
logger.info("Uninitialized PSSP"); logger.info("Uninitialized PSSP");
} }
} }

View file

@ -20,6 +20,7 @@ package de.pickshadow.plugin.base;
import de.pickshadow.plugin.BuildConfiguration; import de.pickshadow.plugin.BuildConfiguration;
import de.pickshadow.plugin.classes.Configuration; import de.pickshadow.plugin.classes.Configuration;
import de.pickshadow.plugin.classes.Types;
import de.pickshadow.plugin.classes.logger.LoggerInstanceImpl; import de.pickshadow.plugin.classes.logger.LoggerInstanceImpl;
import de.pickshadow.plugin.utils.Miscellaneous; import de.pickshadow.plugin.utils.Miscellaneous;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -29,48 +30,46 @@ import java.util.UUID;
public class Scheduler { public class Scheduler {
LoggerInstanceImpl logger; LoggerInstanceImpl logger;
// Keeps track on how many times the scheduler has been run // Keeps track of running bukkit scheduler tasks
// Normally this isn't required, this however prevents duplicate private int taskIdMinutely = 0;
// scheduler calls in case /pssp scheduler <timeframe> is used. private int taskIdHourly = 0;
public int execsMinutely = 0;
public int execsHourly = 0;
public void initializeScheduler() { public void initializeScheduler() {
logger = ObjHolder.logger.getInstance(getClass()); logger = ObjHolder.logger.getInstance(getClass());
logger.verb("Initializing scheduler"); logger.verb("Initializing scheduler");
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runMinuteTasks(execsMinutely), 1200L); taskIdMinutely = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runMinuteTasks, 1200L).getTaskId();
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runHourTasks(execsHourly), 72000L); taskIdHourly = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runHourTasks, 72000L).getTaskId();
} }
public void runMinuteTasks(int execs) { public void executeScheduler(Types.SchedulerType type) {
// If execution count does not match return switch (type) {
if (execs != execsMinutely) return; case MINUTELY:
Bukkit.getScheduler().cancelTask(taskIdMinutely);
runMinuteTasks();
break;
case HOURLY:
Bukkit.getScheduler().cancelTask(taskIdHourly);
runHourTasks();
}
}
public void runMinuteTasks() {
// Print announcement // Print announcement
printTaskAnnouncement("minutely"); printTaskAnnouncement("minutely");
// Increase execution count to prevent additional calls
execsMinutely++;
// Save player data // Save player data
for (UUID uuid : ObjHolder.playerDataLoader.getLoadedUUIDs()) ObjHolder.playerDataLoader.savePlayerData(uuid); for (UUID uuid : ObjHolder.playerDataLoader.getLoadedUUIDs()) ObjHolder.playerDataLoader.savePlayerData(uuid);
// Schedule // Schedule
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runMinuteTasks(execsMinutely), 1200L); taskIdMinutely = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runMinuteTasks, 1200L).getTaskId();
} }
public void runHourTasks(int execs) { public void runHourTasks() {
// If execution count does not match return
if (execs != execsHourly) return;
// Print announcement // Print announcement
printTaskAnnouncement("hourly"); printTaskAnnouncement("hourly");
// Increase execution count to prevent additional calls
execsHourly++;
// Reload configuration file // Reload configuration file
Configuration newConfig = ObjHolder.configLoader.loadConfig(); Configuration newConfig = ObjHolder.configLoader.loadConfig();
if (newConfig == null) { if (newConfig == null) {
@ -85,7 +84,7 @@ public class Scheduler {
// Schedule // Schedule
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runHourTasks(execsHourly), 72000L); taskIdHourly = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runHourTasks, 72000L).getTaskId();
} }
private void printTaskAnnouncement(String timeframe) { private void printTaskAnnouncement(String timeframe) {

View file

@ -109,4 +109,10 @@ public class Translation {
public static String MSG_NO_LAST_MESSAGED_PLAYER = "Du scheinst keinen Spieler in der letzten Zeit angeschrieben zu haben."; public static String MSG_NO_LAST_MESSAGED_PLAYER = "Du scheinst keinen Spieler in der letzten Zeit angeschrieben zu haben.";
public static String MSG_TO = "<gold><bold>%reciever% <reset><gold>« <bold>%sender% <reset><gold>» <reset>%message%"; public static String MSG_TO = "<gold><bold>%reciever% <reset><gold>« <bold>%sender% <reset><gold>» <reset>%message%";
public static String MSG_FROM = "<gold><bold>%reciever% <reset><gold>» <bold>%sender% <reset><gold>» <reset>%message%"; public static String MSG_FROM = "<gold><bold>%reciever% <reset><gold>» <bold>%sender% <reset><gold>» <reset>%message%";
// Command: /clearchat
public static String CLEARCHAT = "Der Chat wurde von %sender% geleert.";
// Command: /toggledownfall
public static String TOGGLEDOWNFALL = "Der Niederschlag wurde umgestellt.";
} }

View file

@ -23,4 +23,5 @@ public class Configuration {
public boolean enablePrefix = false; public boolean enablePrefix = false;
public String inviteLink = ""; public String inviteLink = "";
public String defaultSpellingLanguage = "de_DE"; public String defaultSpellingLanguage = "de_DE";
public boolean useOldMcTranslationForToggleDownfall = true;
} }

View file

@ -22,4 +22,5 @@ public class Types {
public enum VersionType { RELEASE, RELEASECANDIDATE, BETA, ALPHA } public enum VersionType { RELEASE, RELEASECANDIDATE, BETA, ALPHA }
public enum LoggerLevel { ERROR, WARN, INFO, VERB, DIAG } public enum LoggerLevel { ERROR, WARN, INFO, VERB, DIAG }
public enum FormatType { NONE, ERROR, NORMAL } public enum FormatType { NONE, ERROR, NORMAL }
public enum SchedulerType { MINUTELY, HOURLY }
} }

View file

@ -0,0 +1,30 @@
package de.pickshadow.plugin.commands;
import de.pickshadow.plugin.base.Translation;
import de.pickshadow.plugin.classes.CommandBase;
import de.pickshadow.plugin.utils.Miscellaneous;
import de.pickshadow.plugin.utils.TabCompletionHelper;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class ClearChatCommand extends CommandBase {
public ClearChatCommand() {
commandNames = new String[]{ "clearchat" };
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
for (Player player : Bukkit.getOnlinePlayers()) player.sendMessage(MiniMessage.miniMessage().deserialize("\n".repeat(10000)).append(Miscellaneous.format(Translation.CLEARCHAT.replace("%sender%", sender.getName()))));
return true;
}
@Override
public TabCompleter getCompletion() {
return TabCompletionHelper.createEmptyCompletion();
}
}

View file

@ -35,10 +35,7 @@ public class HomeCommand extends CommandBase {
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (sender instanceof ConsoleCommandSender) { if (Miscellaneous.isCommandSentByConsole(sender, true)) return true;
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
return true;
}
Player player = (Player) sender; Player player = (Player) sender;
Location coords = player.getRespawnLocation(); Location coords = player.getRespawnLocation();
if (coords == null) { if (coords == null) {

View file

@ -29,7 +29,6 @@ import de.pickshadow.plugin.utils.TabCompletionHelper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -44,10 +43,7 @@ public class MsgCommand extends CommandBase {
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (sender instanceof ConsoleCommandSender) { if (Miscellaneous.isCommandSentByConsole(sender, true)) return true;
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
return true;
}
// Define shared variables // Define shared variables
Player player = (Player) sender; Player player = (Player) sender;

View file

@ -27,7 +27,6 @@ import de.pickshadow.plugin.utils.Miscellaneous;
import de.pickshadow.plugin.utils.TabCompletionHelper; import de.pickshadow.plugin.utils.TabCompletionHelper;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.TabCompleter; import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -77,10 +76,7 @@ public class PluginCommand extends CommandBase {
gcThread.start(); gcThread.start();
break; break;
case "playerinfo": case "playerinfo":
if (sender instanceof ConsoleCommandSender) { if (Miscellaneous.isCommandSentByConsole(sender, true)) break;
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
break;
}
Player player = (Player) sender; Player player = (Player) sender;
sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_PLAYERINFO.replace("%playerdata%", ObjHolder.playerDataLoader.getPlayerData(player.getUniqueId()).convertToString()))); sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_PLAYERINFO.replace("%playerdata%", ObjHolder.playerDataLoader.getPlayerData(player.getUniqueId()).convertToString())));
@ -95,13 +91,13 @@ public class PluginCommand extends CommandBase {
case "minutely": case "minutely":
case "minute": case "minute":
sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER.replace("%timeframe%", "minutely"))); sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER.replace("%timeframe%", "minutely")));
ObjHolder.scheduler.runMinuteTasks(ObjHolder.scheduler.execsMinutely); ObjHolder.scheduler.executeScheduler(Types.SchedulerType.MINUTELY);
sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER_DONE.replace("%timeframe%", "minutely"))); sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER_DONE.replace("%timeframe%", "minutely")));
break; break;
case "hourly": case "hourly":
case "hour": case "hour":
sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER.replace("%timeframe%", "hourly"))); sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER.replace("%timeframe%", "hourly")));
ObjHolder.scheduler.runHourTasks(ObjHolder.scheduler.execsHourly); ObjHolder.scheduler.executeScheduler(Types.SchedulerType.HOURLY);
sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER_DONE.replace("%timeframe%", "hourly"))); sender.sendMessage(Miscellaneous.format(Translation.PLUGINCOMMAND_SCHEDULER_DONE.replace("%timeframe%", "hourly")));
break; break;
default: sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_INVALID_ARGUMENT.replace("%usage%", command.getUsage()), Types.FormatType.ERROR)); default: sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_INVALID_ARGUMENT.replace("%usage%", command.getUsage()), Types.FormatType.ERROR));

View file

@ -0,0 +1,52 @@
package de.pickshadow.plugin.commands;
import de.pickshadow.plugin.base.ObjHolder;
import de.pickshadow.plugin.base.Translation;
import de.pickshadow.plugin.classes.CommandBase;
import de.pickshadow.plugin.utils.Miscellaneous;
import de.pickshadow.plugin.utils.TabCompletionHelper;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
import java.util.Random;
public class ToggleDownfallCommand extends CommandBase {
public ToggleDownfallCommand() {
commandNames = new String[]{ "toggledownfall" };
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (Miscellaneous.isCommandSentByConsole(sender, true)) return true;
Player player = (Player) sender;
World world = player.getWorld();
if (world.isClearWeather()) world.setClearWeatherDuration(new Random().nextInt(6000));
else if (world.isThundering()) {
world.setThundering(true);
world.setThunderDuration(new Random().nextInt(6000));
} else {
logger.error("Invalid weather state. isClearWeather() and isThundering() are false.");
player.sendMessage(Miscellaneous.format(Translation.GLOBAL_EXCEPTION));
return true;
}
if (ObjHolder.config.useOldMcTranslationForToggleDownfall) {
if (player.locale() == Locale.GERMANY) player.sendMessage("Der Niederschlag wurde umgestellt.");
else player.sendMessage("Toggled downfall.");
}
else player.sendMessage(Miscellaneous.format(Translation.TOGGLEDOWNFALL));
return true;
}
@Override
public TabCompleter getCompletion() {
return TabCompletionHelper.createEmptyCompletion();
}
}

View file

@ -45,10 +45,7 @@ public class TrollCommand extends CommandBase {
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (sender instanceof ConsoleCommandSender) { if (Miscellaneous.isCommandSentByConsole(sender, true)) return true;
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
return true;
}
Player player = (Player) sender; Player player = (Player) sender;
if (args.length < 2) { if (args.length < 2) {
player.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_ENOUGH_ARGUMENTS.replace("%usage%", command.getUsage()), Types.FormatType.ERROR)); player.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_ENOUGH_ARGUMENTS.replace("%usage%", command.getUsage()), Types.FormatType.ERROR));

View file

@ -24,6 +24,8 @@ import de.pickshadow.plugin.classes.Types;
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 org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -66,6 +68,18 @@ public class Miscellaneous {
ObjHolder.logger.warn(Miscellaneous.class, "Garbage collector finished"); ObjHolder.logger.warn(Miscellaneous.class, "Garbage collector finished");
} }
// Check if command was sent by console
public static boolean isCommandSentByConsole(CommandSender sender) {
return isCommandSentByConsole(sender, false);
}
public static boolean isCommandSentByConsole(CommandSender sender, boolean issueError) {
if (sender instanceof ConsoleCommandSender) {
if (issueError) sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
return true;
}
return false;
}
// Data type conversion // Data type conversion
/// Bytes <-> Mebibytes /// Bytes <-> Mebibytes
public static double byteToMib(int bytes, boolean flatten) { public static double byteToMib(int bytes, boolean flatten) {

View file

@ -10,3 +10,4 @@ version: 0
enablePrefix: true enablePrefix: true
inviteLink: "" inviteLink: ""
defaultSpellingLanguage: "de_DE" defaultSpellingLanguage: "de_DE"
useOldMcTranslationForToggleDownfall: true

View file

@ -62,6 +62,15 @@ commands:
usage: /reply <Nachricht> usage: /reply <Nachricht>
aliases: [ "r" ] aliases: [ "r" ]
permission: pickshadow.commands.reply permission: pickshadow.commands.reply
clearchat:
description: Löscht den Chatverlauf für den gesamten Server.
usage: /clearchat
aliases: [ "cc", "chatclear" ]
permission: pickshadow.commands.clearchat
toggledownfall:
description: Stellt den Niederschlag um. Erinnering an alte Zeiten.
usage: /toggledownfall
permission: pickshadow.commands.toggledownfall
permissions: permissions:
pickshadow.*: pickshadow.*:
@ -81,6 +90,8 @@ permissions:
- pickshadow.commands.broadcast - pickshadow.commands.broadcast
- pickshadow.commands.msg - pickshadow.commands.msg
- pickshadow.commands.reply - pickshadow.commands.reply
- pickshadow.commands.clearchat
- pickshadow.commands.toggledownfall
pickshadow.commands.discord: pickshadow.commands.discord:
default: not op default: not op
pickshadow.commands.home: pickshadow.commands.home:
@ -97,3 +108,7 @@ permissions:
default: not op default: not op
pickshadow.commands.reply: pickshadow.commands.reply:
default: not op default: not op
pickshadow.commands.clearchat:
default: op
pickshadow.commands.toggledownfall:
default: not op