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 int pluginRelease = 1;
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[] pluginContributors = new String[]{};
public static final String pluginLicense = "GNU AGPL v3 (or later)";

View file

@ -18,6 +18,7 @@
*/
package de.pickshadow.plugin.base;
import de.pickshadow.plugin.classes.CommandBase;
import de.pickshadow.plugin.classes.logger.LoggerInstanceImpl;
import de.pickshadow.plugin.commands.*;
import de.pickshadow.plugin.loaders.ConfigLoader;
@ -32,6 +33,9 @@ public class PluginInitializer {
// Objects
private final LoggerInstanceImpl logger;
// Lists
CommandBase[] commands = new CommandBase[0];
public PluginInitializer() {
logger = ObjHolder.logger.getInstance(getClass());
}
@ -61,16 +65,14 @@ public class PluginInitializer {
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
logger.verb("Registering commands");
try {
new BroadcastCommand().registerCommand();
new DiscordCommand().registerCommand();
new HomeCommand().registerCommand();
new PluginCommand().registerCommand();
new SystemInformationCommand().registerCommand();
new TrollCommand().registerCommand();
new MsgCommand().registerCommand();
for (CommandBase command : commands) command.registerCommand();
} catch (NullPointerException e) {
logger.crash("Could not register plugin commands", e.getStackTrace());
}
@ -92,10 +94,23 @@ public class PluginInitializer {
public void uninitialize() {
logger.info("Uninitializing PSSP");
// Close active hunspell instance
logger.verb("Closing Hunspell instance");
ObjHolder.spellingHelper.setActiveLanguage(null);
// Save player data
logger.verb("Saving player data");
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");
}
}

View file

@ -20,6 +20,7 @@ package de.pickshadow.plugin.base;
import de.pickshadow.plugin.BuildConfiguration;
import de.pickshadow.plugin.classes.Configuration;
import de.pickshadow.plugin.classes.Types;
import de.pickshadow.plugin.classes.logger.LoggerInstanceImpl;
import de.pickshadow.plugin.utils.Miscellaneous;
import org.bukkit.Bukkit;
@ -29,48 +30,46 @@ import java.util.UUID;
public class Scheduler {
LoggerInstanceImpl logger;
// Keeps track on how many times the scheduler has been run
// Normally this isn't required, this however prevents duplicate
// scheduler calls in case /pssp scheduler <timeframe> is used.
public int execsMinutely = 0;
public int execsHourly = 0;
// Keeps track of running bukkit scheduler tasks
private int taskIdMinutely = 0;
private int taskIdHourly = 0;
public void initializeScheduler() {
logger = ObjHolder.logger.getInstance(getClass());
logger.verb("Initializing scheduler");
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runMinuteTasks(execsMinutely), 1200L);
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runHourTasks(execsHourly), 72000L);
taskIdMinutely = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runMinuteTasks, 1200L).getTaskId();
taskIdHourly = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runHourTasks, 72000L).getTaskId();
}
public void runMinuteTasks(int execs) {
// If execution count does not match return
if (execs != execsMinutely) return;
public void executeScheduler(Types.SchedulerType type) {
switch (type) {
case MINUTELY:
Bukkit.getScheduler().cancelTask(taskIdMinutely);
runMinuteTasks();
break;
case HOURLY:
Bukkit.getScheduler().cancelTask(taskIdHourly);
runHourTasks();
}
}
public void runMinuteTasks() {
// Print announcement
printTaskAnnouncement("minutely");
// Increase execution count to prevent additional calls
execsMinutely++;
// Save player data
for (UUID uuid : ObjHolder.playerDataLoader.getLoadedUUIDs()) ObjHolder.playerDataLoader.savePlayerData(uuid);
// Schedule
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runMinuteTasks(execsMinutely), 1200L);
taskIdMinutely = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runMinuteTasks, 1200L).getTaskId();
}
public void runHourTasks(int execs) {
// If execution count does not match return
if (execs != execsHourly) return;
public void runHourTasks() {
// Print announcement
printTaskAnnouncement("hourly");
// Increase execution count to prevent additional calls
execsHourly++;
// Reload configuration file
Configuration newConfig = ObjHolder.configLoader.loadConfig();
if (newConfig == null) {
@ -85,7 +84,7 @@ public class Scheduler {
// Schedule
Bukkit.getScheduler().runTaskLater(ObjHolder.main, () -> runHourTasks(execsHourly), 72000L);
taskIdHourly = Bukkit.getScheduler().runTaskLater(ObjHolder.main, this::runHourTasks, 72000L).getTaskId();
}
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_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%";
// 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 String inviteLink = "";
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 LoggerLevel { ERROR, WARN, INFO, VERB, DIAG }
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
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (sender instanceof ConsoleCommandSender) {
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
return true;
}
if (Miscellaneous.isCommandSentByConsole(sender, true)) return true;
Player player = (Player) sender;
Location coords = player.getRespawnLocation();
if (coords == null) {

View file

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

View file

@ -27,7 +27,6 @@ import de.pickshadow.plugin.utils.Miscellaneous;
import de.pickshadow.plugin.utils.TabCompletionHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@ -77,10 +76,7 @@ public class PluginCommand extends CommandBase {
gcThread.start();
break;
case "playerinfo":
if (sender instanceof ConsoleCommandSender) {
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
break;
}
if (Miscellaneous.isCommandSentByConsole(sender, true)) break;
Player player = (Player) sender;
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 "minute":
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")));
break;
case "hourly":
case "hour":
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")));
break;
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
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (sender instanceof ConsoleCommandSender) {
sender.sendMessage(Miscellaneous.format(Translation.GLOBAL_NOT_A_PLAYER, Types.FormatType.ERROR));
return true;
}
if (Miscellaneous.isCommandSentByConsole(sender, true)) return true;
Player player = (Player) sender;
if (args.length < 2) {
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.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference;
@ -66,6 +68,18 @@ public class Miscellaneous {
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
/// Bytes <-> Mebibytes
public static double byteToMib(int bytes, boolean flatten) {

View file

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

View file

@ -62,6 +62,15 @@ commands:
usage: /reply <Nachricht>
aliases: [ "r" ]
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:
pickshadow.*:
@ -81,6 +90,8 @@ permissions:
- pickshadow.commands.broadcast
- pickshadow.commands.msg
- pickshadow.commands.reply
- pickshadow.commands.clearchat
- pickshadow.commands.toggledownfall
pickshadow.commands.discord:
default: not op
pickshadow.commands.home:
@ -97,3 +108,7 @@ permissions:
default: not op
pickshadow.commands.reply:
default: not op
pickshadow.commands.clearchat:
default: op
pickshadow.commands.toggledownfall:
default: not op