26 Commits
Author SHA1 Message Date
auto 41d0c94eed Add April Fools event listener for themed interactions
Introduced a new event listener, `AprilFoolsEvent`, to handle April Fools Day interactions with players. This includes good and bad actions that trigger messages, potion effects, and other behaviors based on player activities. Registered the new event listener in `PlayerUtils`.
2025-03-31 22:03:42 +02:00
auto 785a64b7e6 Refactor Glow command to optimize logic order.
Reorganized the "off" condition block to execute after clearing existing glow teams.
2025-03-24 21:26:56 +01:00
auto 7cfdc39f75 Refactor interact event handling and add trial spawner logic.
Renamed the event handler for clarity and added logic to handle trial spawner interactions with cooldown feedback for players. Introduced functional interfaces for cleaner and reusable code when processing armor stand counts and trial spawner timers.
2025-03-22 20:57:59 +01:00
auto 7c04361ea5 Add armor stand placement limits per chunk
Implemented functionality to restrict the number of armor stands a player can place in a chunk based on permissions. Added configuration support for customizable limits and proper error handling for edge cases. Registered the LimitArmorStands event listener in the plugin manager.
2025-03-22 20:33:31 +01:00
auto 10449f4a80 Refactor message-sending to use sendRichMessage API.
Replaced all instances of sendMiniMessage with sendRichMessage for improved readability and consistency across the codebase. This change ensures better handling of message formatting and placeholders.
2025-03-22 19:12:28 +01:00
auto ff05856494 Fixed key storage access in KeyStorage.java
Fix the retrieval and saving of keys by updating the path format used in config.getInt and config.set methods.
2024-10-04 21:35:43 +02:00
auto 08370abf77 Save key storage on plugin disable
Ensure that all keys in KeyStorage are saved when the plugin is disabled. This prevents potential data loss by explicitly saving storage during the onDisable lifecycle event.
2024-10-04 21:27:06 +02:00
auto 5a7b9859cd Fix NPE in key configuration, fixed tab completion
Added missing key mapping to prevent NullPointerException when no UUIDs are present in KeyStorage. Also adjusted tab completion logic in Key.java to handle cases with more than one argument.
2024-10-04 21:24:49 +02:00
auto d43f269c22 Fix NPE in key configuration, fixed tab completion
Added missing key mapping to prevent NullPointerException when no UUIDs are present in KeyStorage. Also adjusted tab completion logic in Key.java to handle cases with more than one argument.
2024-10-04 21:19:53 +02:00
auto ad9a3491eb Rename config file in KeyStorage constructor
Changed the configuration file from "messages.yml" to "key_storage.yml". This update fixes a bug where it was writing to the wrong file.
2024-10-04 21:15:02 +02:00
auto 3c34707944 Add system to track keys given and related command for players
Introduces `KeyStorage` for handling keys and their persistence. Added `Key` subcommand to allow players to receive their keys. Updated configuration files and messages to support the new feature.
2024-10-04 20:53:54 +02:00
auto 524a657abd Fix goat horn handling in GoatHornEvent
Replaced usage of Tag.SNAPS_GOAT_HORN with Material.GOAT_HORN for type checking and setting cooldowns.
2024-08-17 00:52:00 +02:00
auto 2fa3e3a6f0 Add logging to GoatHornEvent and register it
Introduced a logger to GoatHornEvent to record when a player uses a goat horn, both in and out of spawn. This helps with tracking player actions and debugging potential issues related to goat horn usage.
2024-08-11 23:53:53 +02:00
auto c0c8cbbfa4 Add GoatHornEvent listener (stops spamming goat horns in spawn)
Implement GoatHornEvent to handle player interactions with goat horns. This feature sets a cooldown for goat horn items, if the player is near spawn or already has an active cooldown.
2024-08-11 23:49:02 +02:00
auto 0c305e79e5 Add GoatHornEvent listener (stops spamming goat horns in spawn)
Implement GoatHornEvent to handle player interactions with goat horns. This feature sets a cooldown for goat horn items, if the player is near spawn or already has an active cooldown.
2024-08-11 23:48:35 +02:00
auto 4ed83b6376 Remove Git version logging and related plugin
Removed the `printVersion` method from `PlayerUtils.java` and eliminated the `gradle-git-properties` plugin from `build.gradle.kts`. These changes simplify the project setup by removing unnecessary Git version logging dependencies.
2024-08-04 22:37:26 +02:00
auto 9e9ada4e2b Update Java version and Galaxy-API dependency
Upgraded the project to use Java 21 instead of Java 17 in the toolchain configuration. Also updated the Galaxy-API dependency to version 1.21-R0.1-SNAPSHOT.
2024-08-04 22:36:36 +02:00
stijn 50f66b93c3 Merge pull request 'fix_rotate' (#1) from fix_rotate into master
Reviewed-on: #1
2024-08-04 20:29:46 +00:00
auto 91ba53208b Merge branch 'refs/heads/master' into fix_rotate 2024-08-04 22:27:32 +02:00
auto 7783101887 Add Jenkinsfile for CI pipeline
Introduce a Jenkinsfile to automate the build process using Gradle. The pipeline consists of three stages: building with Gradle, archiving artifacts, and sending build notifications to Discord. This integration enhances the CI/CD workflow by ensuring consistent builds and timely notifications.
2024-08-04 22:26:57 +02:00
auto f616ed5af0 Switch config paths to use /mnt directory
Updated file paths for configuration and message files to use the /mnt directory instead of the user's home directory.
2024-08-04 22:26:46 +02:00
auto 2bdf8b6b48 Remove temporary debug logging in RotateBlockEvent & fixed drip leaf & iron trap door rotation
The update primarily eradicates numerous debug logging lines in the RotateBlockEvent class. This cleanup improves the readability of the code and enhances performance by reducing unnecessary logging operations. The "toggleDripLeaf" and "toggleTrapDoor" methods have also been updated to verify block data.
2024-07-07 15:17:32 +02:00
auto f3f6d11547 Add logging to RotateBlockEvent
Debug logs were added to the RotateBlockEvent class. These logs will help track the flow of various states and actions, such as the current material and action type, whether the block is a trap door or a drip leaf, among others. This enhancement will assist debugging by providing more visibility into the state of the application at runtime.
2024-07-01 20:39:07 +02:00
auto a5f59c2399 Fixed ordinal check being made before incrementing
In the RotateBlockEvent class, a bug was fixed where the ordinal check was previously being done before the ordinal was incremented.
2024-06-30 20:37:24 +02:00
auto 6209b71db4 Add block interaction enhancements and git properties
Updated block interaction behavior for IRON_TRAPDOOR and BIG_DRIPLEAF_PLACEABLE to allow their state to be toggled. Added the use of git properties to build.gradle.kts, allowing insightful git information such as commit id and time to be retrieved and printed.
2024-06-30 20:28:18 +02:00
auto df875406e1 Add distance check to TeleportEvent
In addition to checking if a player is on a vehicle, the update now also checks if the distance between the player's current location and the teleport destination is more than 5 blocks. If that's the case, the teleportation is cancelled.
2024-06-28 23:23:50 +02:00
20 changed files with 751 additions and 58 deletions
Vendored
+20
View File
@@ -0,0 +1,20 @@
pipeline {
agent any
stages {
stage('Gradle') {
steps {
sh 'bash gradlew build'
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'build/libs/', followSymlinks: false
}
}
stage('discord') {
steps {
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
}
}
}
}
+2 -2
View File
@@ -11,7 +11,7 @@ apply<JavaLibraryPlugin>()
java { java {
toolchain { toolchain {
languageVersion.set(JavaLanguageVersion.of(17)) languageVersion.set(JavaLanguageVersion.of(21))
} }
} }
@@ -38,7 +38,7 @@ tasks {
} }
dependencies { dependencies {
compileOnly("com.alttd:Galaxy-API:1.20.4-R0.1-SNAPSHOT") { compileOnly("com.alttd:Galaxy-API:1.21-R0.1-SNAPSHOT") {
isChanging = true isChanging = true
} }
} }
@@ -3,14 +3,16 @@ package com.alttd.playerutils;
import com.alttd.playerutils.commands.PlayerUtilsCommand; import com.alttd.playerutils.commands.PlayerUtilsCommand;
import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock; import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
import com.alttd.playerutils.config.Config; import com.alttd.playerutils.config.Config;
import com.alttd.playerutils.config.KeyStorage;
import com.alttd.playerutils.config.Messages; import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.event_listeners.RotateBlockEvent; import com.alttd.playerutils.event_listeners.*;
import com.alttd.playerutils.event_listeners.TeleportEvent;
import com.alttd.playerutils.event_listeners.XpBottleEvent;
import com.alttd.playerutils.util.Logger; import com.alttd.playerutils.util.Logger;
import org.bukkit.Bukkit;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.util.concurrent.TimeUnit;
public final class PlayerUtils extends JavaPlugin { public final class PlayerUtils extends JavaPlugin {
private Logger logger; private Logger logger;
@@ -22,10 +24,12 @@ public final class PlayerUtils extends JavaPlugin {
registerCommands(); registerCommands();
registerEvents(); registerEvents();
reloadConfigs(); reloadConfigs();
registerSchedulers();
} }
@Override @Override
public void onDisable() { public void onDisable() {
KeyStorage.STORAGE.save();
} }
private void registerCommands() { private void registerCommands() {
@@ -36,8 +40,11 @@ public final class PlayerUtils extends JavaPlugin {
PluginManager pluginManager = getServer().getPluginManager(); PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new XpBottleEvent(this, logger), this); pluginManager.registerEvents(new XpBottleEvent(this, logger), this);
pluginManager.registerEvents(new TeleportEvent(), this); pluginManager.registerEvents(new TeleportEvent(), this);
pluginManager.registerEvents(new GoatHornEvent(logger), this);
pluginManager.registerEvents(new LimitArmorStands(this, logger), this);
pluginManager.registerEvents(new AprilFoolsEvent(), this);
RotateBlockEvent rotateBlockEvent = new RotateBlockEvent(); RotateBlockEvent rotateBlockEvent = new RotateBlockEvent(logger);
pluginManager.registerEvents(rotateBlockEvent, this); pluginManager.registerEvents(rotateBlockEvent, this);
playerUtilsCommand.addSubCommand(new RotateBlock(rotateBlockEvent)); playerUtilsCommand.addSubCommand(new RotateBlock(rotateBlockEvent));
} }
@@ -45,5 +52,11 @@ public final class PlayerUtils extends JavaPlugin {
public void reloadConfigs() { public void reloadConfigs() {
Config.reload(logger); Config.reload(logger);
Messages.reload(logger); Messages.reload(logger);
KeyStorage.reload(logger);
}
private void registerSchedulers() {
Bukkit.getScheduler().runTaskTimerAsynchronously(this, KeyStorage.STORAGE::save,
TimeUnit.MINUTES.toSeconds(5) * 20, TimeUnit.MINUTES.toSeconds(5) * 20);
} }
} }
@@ -22,7 +22,7 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
PluginCommand command = playerUtils.getCommand("playerutils"); PluginCommand command = playerUtils.getCommand("playerutils");
if (command == null) { if (command == null) {
subCommands = null; subCommands = null;
logger.severe("Unable to find transfer command."); logger.severe("Unable to find playerutils command.");
return; return;
} }
command.setExecutor(this); command.setExecutor(this);
@@ -33,17 +33,18 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
new Glow(logger), new Glow(logger),
new XPCheque(playerUtils), new XPCheque(playerUtils),
new XPCalc(), new XPCalc(),
new Reload(playerUtils)) new Reload(playerUtils),
new Key(logger))
); );
} }
@Override @Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String cmd, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String cmd, @NotNull String[] args) {
if (args.length == 0) { if (args.length == 0) {
commandSender.sendMiniMessage(Messages.HELP.HELP_MESSAGE_WRAPPER.replaceAll("<commands>", subCommands.stream() commandSender.sendRichMessage(Messages.HELP.HELP_MESSAGE_WRAPPER.replaceAll("<commands>", subCommands.stream()
.filter(subCommand -> commandSender.hasPermission(subCommand.getPermission())) .filter(subCommand -> commandSender.hasPermission(subCommand.getPermission()))
.map(SubCommand::getHelpMessage) .map(SubCommand::getHelpMessage)
.collect(Collectors.joining("\n"))), null); .collect(Collectors.joining("\n"))));
return true; return true;
} }
@@ -52,13 +53,13 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
return false; return false;
if (!commandSender.hasPermission(subCommand.getPermission())) { if (!commandSender.hasPermission(subCommand.getPermission())) {
commandSender.sendMiniMessage(Messages.GENERIC.NO_PERMISSION, Placeholder.parsed("permission", subCommand.getPermission())); commandSender.sendRichMessage(Messages.GENERIC.NO_PERMISSION, Placeholder.parsed("permission", subCommand.getPermission()));
return true; return true;
} }
boolean executedCorrectly = subCommand.onCommand(commandSender, args); boolean executedCorrectly = subCommand.onCommand(commandSender, args);
if (!executedCorrectly) { if (!executedCorrectly) {
commandSender.sendMiniMessage(subCommand.getHelpMessage(), null); commandSender.sendRichMessage(subCommand.getHelpMessage());
} }
return true; return true;
} }
@@ -41,20 +41,20 @@ public class Glow extends SubCommand {
Player player = playerFromArg.get(); Player player = playerFromArg.get();
if (args[1].equalsIgnoreCase("off")) {
turnOffGlow(commandSender, player, otherPlayer);
return true;
}
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
board.getTeams().stream() board.getTeams().stream()
.filter(team -> team.getName().startsWith("Glow")) .filter(team -> team.getName().startsWith("Glow"))
.filter(team -> team.hasPlayer(player)) .filter(team -> team.hasPlayer(player))
.forEach(team -> team.removePlayer(player)); .forEach(team -> team.removePlayer(player));
if (args[1].equalsIgnoreCase("off")) {
turnOffGlow(commandSender, player, otherPlayer);
return true;
}
Optional<DyeColor> any = Arrays.stream(DyeColor.values()).filter(chatColor -> chatColor.name().equalsIgnoreCase(args[1])).findAny(); Optional<DyeColor> any = Arrays.stream(DyeColor.values()).filter(chatColor -> chatColor.name().equalsIgnoreCase(args[1])).findAny();
if (any.isEmpty()) { if (any.isEmpty()) {
commandSender.sendMiniMessage(getHelpMessage(), null); commandSender.sendRichMessage(getHelpMessage());
return true; return true;
} }
@@ -75,36 +75,37 @@ public class Glow extends SubCommand {
private Optional<Player> getTargetPlayer(CommandSender commandSender, String[] args) { private Optional<Player> getTargetPlayer(CommandSender commandSender, String[] args) {
if (args.length == 2) { if (args.length == 2) {
if (!(commandSender instanceof Player commandPlayer)) { if (!(commandSender instanceof Player commandPlayer)) {
commandSender.sendMiniMessage(Messages.GENERIC.PLAYER_ONLY, null); commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
return Optional.empty(); return Optional.empty();
} }
return Optional.of(commandPlayer); return Optional.of(commandPlayer);
} }
if (!commandSender.hasPermission(getPermission() + ".other")) { if (!commandSender.hasPermission(getPermission() + ".other")) {
commandSender.sendMiniMessage(Messages.GENERIC.NO_PERMISSION, Placeholder.parsed("permission", getPermission() + ".other")); commandSender.sendRichMessage(Messages.GENERIC.NO_PERMISSION, Placeholder.parsed("permission", getPermission() + ".other"));
return Optional.empty(); return Optional.empty();
} }
Optional<? extends Player> any = Bukkit.getOnlinePlayers().stream().filter(offlinePlayer -> offlinePlayer.getName().equalsIgnoreCase(args[2])).findAny(); Optional<? extends Player> any = Bukkit.getOnlinePlayers().stream().filter(offlinePlayer -> offlinePlayer.getName().equalsIgnoreCase(args[2])).findAny();
if (any.isPresent()) { if (any.isPresent()) {
return Optional.of(any.get()); return Optional.of(any.get());
} else { } else {
commandSender.sendMiniMessage(Messages.GENERIC.PLAYER_NOT_FOUND, Placeholder.parsed("player", args[2])); commandSender.sendRichMessage(Messages.GENERIC.PLAYER_NOT_FOUND, Placeholder.parsed("player", args[2]));
return Optional.empty(); return Optional.empty();
} }
} }
private void turnOffGlow(CommandSender commandSender, Player player, boolean otherPlayer) { private void turnOffGlow(CommandSender commandSender, Player player, boolean otherPlayer) {
player.sendMiniMessage(Messages.GLOW.GLOW_OFF, null); player.sendRichMessage(Messages.GLOW.GLOW_OFF);
player.setGlowing(false); player.setGlowing(false);
if (otherPlayer) { if (otherPlayer) {
commandSender.sendMiniMessage(Messages.GLOW.GLOW_OFF_FOR_PLAYER, Placeholder.component("player", player.name())); commandSender.sendRichMessage(Messages.GLOW.GLOW_OFF_FOR_PLAYER, Placeholder.component("player", player.name()));
} }
} }
private void turnOnGlow(CommandSender commandSender, Player player, Team team, DyeColor dyeColor, boolean otherPlayer) { private void turnOnGlow(CommandSender commandSender, Player player, Team team, DyeColor dyeColor, boolean otherPlayer) {
if (team.getScoreboard() == null) { if (team.getScoreboard() == null) {
commandSender.sendMiniMessage(Messages.GLOW.UNABLE_TO_GET_SCOREBOARD, null); commandSender.sendRichMessage(Messages.GLOW.UNABLE_TO_GET_SCOREBOARD);
logger.warning("Unable to get scoreboard for team"); logger.warning("Unable to get scoreboard for team");
return; return;
} }
@@ -114,9 +115,9 @@ public class Glow extends SubCommand {
player.setScoreboard(team.getScoreboard()); player.setScoreboard(team.getScoreboard());
player.setGlowing(true); player.setGlowing(true);
player.sendMiniMessage(Messages.GLOW.GLOW_ON, Placeholder.parsed("color", dyeColor.name())); player.sendRichMessage(Messages.GLOW.GLOW_ON, Placeholder.parsed("color", dyeColor.name()));
if (otherPlayer) { if (otherPlayer) {
commandSender.sendMiniMessage(Messages.GLOW.GLOW_ON_FOR_PLAYER, TagResolver.resolver( commandSender.sendRichMessage(Messages.GLOW.GLOW_ON_FOR_PLAYER, TagResolver.resolver(
Placeholder.parsed("color", dyeColor.name()), Placeholder.parsed("color", dyeColor.name()),
Placeholder.component("player", player.name()) Placeholder.component("player", player.name())
)); ));
@@ -0,0 +1,87 @@
package com.alttd.playerutils.commands.playerutils_subcommands;
import com.alttd.playerutils.commands.SubCommand;
import com.alttd.playerutils.config.Config;
import com.alttd.playerutils.config.KeyStorage;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.util.Logger;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
public class Key extends SubCommand {
private final Logger logger;
public Key(Logger logger) {
this.logger = logger;
}
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
if (!(commandSender instanceof Player player)) {
commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
return true;
}
if (args.length != 2) {
return false;
}
String crate = args[1].toLowerCase();
if (!Config.KEY.CRATES.containsKey(crate)) {
commandSender.sendRichMessage(Messages.KEY.CRATE_NOT_EXIST, Placeholder.parsed("crate", crate));
return true;
}
UUID uuid = player.getUniqueId();
Object2IntOpenHashMap<UUID> crateMap = KeyStorage.STORAGE.KEYS.get(crate);
int totalKeys = Config.KEY.CRATES.getOrDefault(crate, 0);
int keys = crateMap.getOrDefault(uuid, 0);
if (keys >= totalKeys) {
commandSender.sendRichMessage(Messages.KEY.RETRIEVED_ALL_KEYS, TagResolver.resolver(
Placeholder.parsed("crate", crate),
Placeholder.parsed("keys", String.valueOf(keys))));
return true;
}
crateMap.addTo(uuid, 1);
logger.info(String.format("Gave %s one key for %s", player.getName(), crate));
commandSender.getServer().dispatchCommand(Bukkit.getConsoleSender(), String.format("crate give v %s 1 %s", crate, player.getName()));
if (keys + 1 == totalKeys) {
commandSender.sendRichMessage(Messages.KEY.GAVE_FINAL_KEY, TagResolver.resolver(
Placeholder.parsed("crate", crate),
Placeholder.parsed("keys", String.valueOf(keys + 1))));
} else {
commandSender.sendRichMessage(Messages.KEY.GAVE_KEY, TagResolver.resolver(
Placeholder.parsed("crate", crate),
Placeholder.parsed("keys", String.valueOf(keys + 1)),
Placeholder.parsed("total_keys", String.valueOf(totalKeys))));
}
return true;
}
@Override
public String getName() {
return "key";
}
@Override
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
if (args.length > 2) {
return List.of();
}
return Config.KEY.CRATES.keySet().stream().toList();
}
@Override
public String getHelpMessage() {
return Messages.HELP.KEY;
}
}
@@ -18,7 +18,7 @@ public class Reload extends SubCommand {
@Override @Override
public boolean onCommand(CommandSender commandSender, String[] args) { public boolean onCommand(CommandSender commandSender, String[] args) {
playerUtils.reloadConfigs(); playerUtils.reloadConfigs();
commandSender.sendMiniMessage(Messages.RELOAD.RELOADED, null); commandSender.sendRichMessage(Messages.RELOAD.RELOADED);
return true; return true;
} }
@@ -19,15 +19,15 @@ public class RotateBlock extends SubCommand {
@Override @Override
public boolean onCommand(CommandSender commandSender, String[] args) { public boolean onCommand(CommandSender commandSender, String[] args) {
if (!(commandSender instanceof Player player)) { if (!(commandSender instanceof Player player)) {
commandSender.sendMiniMessage(Messages.GENERIC.PLAYER_ONLY, null); commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
return true; return true;
} }
boolean enabled = rotateBlockEvent.toggleRotate(player.getUniqueId()); boolean enabled = rotateBlockEvent.toggleRotate(player.getUniqueId());
if (enabled) if (enabled)
commandSender.sendMiniMessage(Messages.ROTATE_BLOCK.ENABLED, null); commandSender.sendRichMessage(Messages.ROTATE_BLOCK.ENABLED);
else else
commandSender.sendMiniMessage(Messages.ROTATE_BLOCK.DISABLED, null); commandSender.sendRichMessage(Messages.ROTATE_BLOCK.DISABLED);
return true; return true;
} }
@@ -34,7 +34,7 @@ public class XPCalc extends SubCommand {
startingLevel++; startingLevel++;
} }
commandSender.sendMiniMessage(Messages.XP_CALC.XP_NEEDED, Placeholder.parsed("xp_needed", String.valueOf(totalXpNeeded))); commandSender.sendRichMessage(Messages.XP_CALC.XP_NEEDED, Placeholder.parsed("xp_needed", String.valueOf(totalXpNeeded)));
return true; return true;
} }
@@ -31,7 +31,7 @@ public class XPCheque extends SubCommand {
@Override @Override
public boolean onCommand(CommandSender commandSender, String[] args) { public boolean onCommand(CommandSender commandSender, String[] args) {
if (!(commandSender instanceof Player player)) { if (!(commandSender instanceof Player player)) {
commandSender.sendMiniMessage(Messages.GENERIC.PLAYER_ONLY, null); commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
return true; return true;
} }
@@ -48,7 +48,7 @@ public class XPCheque extends SubCommand {
} }
if (amount > 64 || amount < 1) { if (amount > 64 || amount < 1) {
commandSender.sendMiniMessage(Messages.XP_CHEQUE.INVALID_AMOUNT, null); commandSender.sendRichMessage(Messages.XP_CHEQUE.INVALID_AMOUNT);
return true; return true;
} }
@@ -60,24 +60,24 @@ public class XPCheque extends SubCommand {
} }
if ((xpValue <= 0)) { if ((xpValue <= 0)) {
commandSender.sendMiniMessage(Messages.XP_CHEQUE.NEGATIVE, null); commandSender.sendRichMessage(Messages.XP_CHEQUE.NEGATIVE);
return true; return true;
} }
int totalExperience = player.getTotalExperience(); int totalExperience = player.getTotalExperience();
if (totalExperience < (xpValue * amount)) { if (totalExperience < (xpValue * amount)) {
commandSender.sendMiniMessage(Messages.XP_CHEQUE.NOT_ENOUGH_XP, Placeholder.parsed("xp", String.valueOf(totalExperience))); commandSender.sendRichMessage(Messages.XP_CHEQUE.NOT_ENOUGH_XP, Placeholder.parsed("xp", String.valueOf(totalExperience)));
return true; return true;
} }
ItemStack heldItem = player.getInventory().getItemInMainHand(); ItemStack heldItem = player.getInventory().getItemInMainHand();
if (!heldItem.getType().equals(Material.GLASS_BOTTLE)) { if (!heldItem.getType().equals(Material.GLASS_BOTTLE)) {
commandSender.sendMiniMessage(Messages.XP_CHEQUE.NOT_HOLDING_BOTTLE, null); commandSender.sendRichMessage(Messages.XP_CHEQUE.NOT_HOLDING_BOTTLE);
return true; return true;
} }
if (heldItem.getAmount() < amount) { if (heldItem.getAmount() < amount) {
commandSender.sendMiniMessage(Messages.XP_CHEQUE.NOT_ENOUGH_BOTTLE, Placeholder.parsed("amount", String.valueOf(amount))); commandSender.sendRichMessage(Messages.XP_CHEQUE.NOT_ENOUGH_BOTTLE, Placeholder.parsed("amount", String.valueOf(amount)));
return true; return true;
} }
@@ -122,7 +122,7 @@ public class XPCheque extends SubCommand {
NamespacedKey customXp = NamespacedKey.fromString("custom_xp", playerUtils); NamespacedKey customXp = NamespacedKey.fromString("custom_xp", playerUtils);
if (customXp == null) { if (customXp == null) {
player.sendMiniMessage(Messages.XP_CHEQUE.FAILED_STORAGE, null); player.sendRichMessage(Messages.XP_CHEQUE.FAILED_STORAGE);
return Optional.empty(); return Optional.empty();
} }
persistentDataContainer.set(customXp, PersistentDataType.INTEGER, xpValue); persistentDataContainer.set(customXp, PersistentDataType.INTEGER, xpValue);
@@ -1,8 +1,12 @@
package com.alttd.playerutils.config; package com.alttd.playerutils.config;
import com.alttd.playerutils.util.Logger; import com.alttd.playerutils.util.Logger;
import org.bukkit.configuration.ConfigurationSection;
import java.io.File; import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class Config extends AbstractConfig{ public class Config extends AbstractConfig{
@@ -11,8 +15,8 @@ public class Config extends AbstractConfig{
Config(Logger logger) { Config(Logger logger) {
super( super(
new File(System.getProperty("user.home") + File.separator new File(File.separator
+ "share" + File.separator + "mnt" + File.separator
+ "configs" + File.separator + "configs" + File.separator
+ "PlayerUtils"), + "PlayerUtils"),
"config.yml", logger); "config.yml", logger);
@@ -36,4 +40,46 @@ public class Config extends AbstractConfig{
WARNINGS = config.getBoolean(prefix, "warnings", WARNINGS); WARNINGS = config.getBoolean(prefix, "warnings", WARNINGS);
} }
} }
public static class KEY {
private static final String prefix = "key.";
public static HashMap<String, Integer> CRATES = new HashMap<>();
@SuppressWarnings("unused")
private static void load() {
CRATES.clear();
ConfigurationSection configurationSection = config.getConfigurationSection(prefix.substring(0, prefix.length() - 1));
if (configurationSection == null) {
config.logger.warning("No keys configured, adding default");
config.set(prefix, "dailyvotecrate", 0);
config.set(prefix, "weeklyvotecrate", 0);
config.set(prefix, "questcrate", 0);
return;
}
Set<String> keys = configurationSection.getKeys(false);
for (String key : keys) {
CRATES.put(key, config.getInt(prefix, key, 0));
}
}
}
public static class ARMOR_STAND_LIMIT {
private static final String prefix = "armor_stand_limit.";
public static HashMap<String, Integer> LIMIT = new HashMap<>();
@SuppressWarnings("unused")
private static void load() {
LIMIT.clear();
ConfigurationSection configurationSection = config.getConfigurationSection(prefix.substring(0, prefix.length() - 1));
if (configurationSection == null) {
config.logger.warning("No limits configured, adding default");
config.set(prefix, "default", 10);
}
Set<String> limits = configurationSection.getKeys(false);
for (String key : limits) {
LIMIT.put(key, config.getInt(prefix, key, 10));
}
}
}
} }
@@ -0,0 +1,71 @@
package com.alttd.playerutils.config;
import com.alttd.playerutils.util.Logger;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.bukkit.configuration.ConfigurationSection;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public class KeyStorage extends AbstractConfig {
static KeyStorage config;
private final Logger logger;
public KeyStorage(Logger logger) {
super(
new File(File.separator
+ "mnt" + File.separator
+ "configs" + File.separator
+ "PlayerUtils"),
"key_storage.yml", logger);
this.logger = logger;
}
public static void reload(Logger logger) {
logger.info("Reloading key storage");
config = new KeyStorage(logger);
config.readConfig(KeyStorage.class, null);
}
public static class STORAGE {
private static final String prefix = "storage.";
public static HashMap<String, Object2IntOpenHashMap<UUID>> KEYS = new HashMap<>();
@SuppressWarnings("unused")
private static void load() {
save();
KEYS.clear();
for (String crate : Config.KEY.CRATES.keySet()) {
Object2IntOpenHashMap<UUID> count = new Object2IntOpenHashMap<>();
ConfigurationSection configurationSection = config.getConfigurationSection(prefix + crate);
if (configurationSection == null) {
config.logger.info(String.format("No section yet for crate %s", crate));
KEYS.put(crate, count);
continue;
}
List<UUID> uuids = configurationSection.getKeys(false).stream().map(UUID::fromString).toList();
if (uuids.isEmpty()) {
config.logger.info(String.format("No keys yet for crate %s", crate));
KEYS.put(crate, count);
continue;
}
for (UUID uuid : uuids) {
int keys = config.getInt(prefix + crate + ".", uuid.toString(), 0);
count.put(uuid, keys);
}
KEYS.put(crate, count);
}
}
public synchronized static void save() {
config.logger.info("Saving KeyStorage");
KEYS.keySet()
.forEach(crate -> KEYS.get(crate)
.forEach((uuid, keys) -> config.set(prefix + crate + ".", uuid.toString(), keys)));
}
}
}
@@ -1,6 +1,7 @@
package com.alttd.playerutils.config; package com.alttd.playerutils.config;
import com.alttd.playerutils.util.Logger; import com.alttd.playerutils.util.Logger;
import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@@ -11,8 +12,8 @@ public class Messages extends AbstractConfig {
Messages(Logger logger) { Messages(Logger logger) {
super( super(
new File(System.getProperty("user.home") + File.separator new File(File.separator
+ "share" + File.separator + "mnt" + File.separator
+ "configs" + File.separator + "configs" + File.separator
+ "PlayerUtils"), + "PlayerUtils"),
"messages.yml", logger); "messages.yml", logger);
@@ -34,6 +35,7 @@ public class Messages extends AbstractConfig {
public static String XP_CALC = "<green>Calculate the amount of XP between levels: <gold>/pu xpcalc <from> <to></gold></green>"; public static String XP_CALC = "<green>Calculate the amount of XP between levels: <gold>/pu xpcalc <from> <to></gold></green>";
public static String RELOAD = "<green>Reload the configs for PlayerUtils: <gold>/pu reload</gold></green>"; public static String RELOAD = "<green>Reload the configs for PlayerUtils: <gold>/pu reload</gold></green>";
public static String ROTATE_BLOCK = "<green>Enable rotating blocks with a blaze rod: <gold>/pu rotateblock</gold></green>"; public static String ROTATE_BLOCK = "<green>Enable rotating blocks with a blaze rod: <gold>/pu rotateblock</gold></green>";
public static String KEY = "<green>Receive a key that you are owed: <gold>/pu key</gold></green>";
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static void load() { private static void load() {
@@ -138,4 +140,21 @@ public class Messages extends AbstractConfig {
DISABLED = config.getString(prefix, "disabled", DISABLED); DISABLED = config.getString(prefix, "disabled", DISABLED);
} }
} }
public static class KEY {
private static final String prefix = "pu-command.key.";
public static String CRATE_NOT_EXIST = "<red>There is no crate called <crate></green>";
public static String RETRIEVED_ALL_KEYS = "<red>You already retrieved all <keys> keys for the <crate>.</red>";
public static String GAVE_KEY = "<green>You received a <crate> key. You have received <keys> out of <total_keys> keys. Make sure to use your key before requesting another</green>";
public static String GAVE_FINAL_KEY = "<green>You received your final <crate> key. You have received a total of <keys> keys for this crate.</green>";
@SuppressWarnings("unused")
private static void load() {
CRATE_NOT_EXIST = config.getString(prefix, "crate-not-exist", CRATE_NOT_EXIST);
RETRIEVED_ALL_KEYS = config.getString(prefix, "retrieved-all-keys", RETRIEVED_ALL_KEYS);
GAVE_KEY = config.getString(prefix, "gave-key", GAVE_KEY);
GAVE_FINAL_KEY = config.getString(prefix, "gave-final-key", GAVE_FINAL_KEY);
}
}
} }
@@ -0,0 +1,226 @@
package com.alttd.playerutils.event_listeners;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityBreedEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerBucketEntityEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public class AprilFoolsEvent implements Listener {
MiniMessage miniMessage = MiniMessage.miniMessage();
List<Component> happyMessages = List.of(
miniMessage.deserialize("<green>You have a sudden urge of calmness and peace</green>"),
miniMessage.deserialize("<green>Mother nature is pleased and graces us with her beauty!</green>"),
miniMessage.deserialize("<green>The gentle breeze feels like a soothing hug from nature.</green>")
);
List<Component> angryMessages = List.of(
miniMessage.deserialize("<red>Something seems off...</red>"),
miniMessage.deserialize("<red>Mother nature is angry and furious with you!</red>"),
miniMessage.deserialize("<red>The wind picks up, carrying the anger of the earth.</red>")
);
private final List<PotionEffectType> badEffects = List.of(PotionEffectType.BLINDNESS, PotionEffectType.NAUSEA,
PotionEffectType.LEVITATION, PotionEffectType.DARKNESS, PotionEffectType.MINING_FATIGUE, PotionEffectType.SLOWNESS);
private final List<PotionEffectType> goodEffects = List.of(PotionEffectType.ABSORPTION, PotionEffectType.GLOWING,
PotionEffectType.HEALTH_BOOST, PotionEffectType.HERO_OF_THE_VILLAGE, PotionEffectType.LUCK, PotionEffectType.REGENERATION,
PotionEffectType.REGENERATION, PotionEffectType.RESISTANCE, PotionEffectType.SATURATION, PotionEffectType.STRENGTH);
private final List<Material> badBlocks = List.of(Material.SHORT_GRASS, Material.TALL_GRASS, Material.SEAGRASS,
Material.TALL_SEAGRASS, Material.LILY_PAD, Material.KELP, Material.KELP_PLANT, Material.BEEHIVE,
Material.BAMBOO, Material.MOSS_BLOCK, Material.CACTUS, Material.SMALL_DRIPLEAF, Material.BIG_DRIPLEAF);
private final List<Material> goodBlocks = List.of(Material.CACTUS, Material.AZALEA, Material.FLOWERING_AZALEA);
private final HashMap<UUID, Integer> goodActions = new HashMap<>();
private final HashMap<UUID, Integer> badActions = new HashMap<>();
private boolean isFlower(Material material) {
return Tag.FLOWERS.isTagged(material);
}
private boolean isLog(Material material) {
return Tag.LOGS.isTagged(material);
}
private boolean isLeaves(Material material) {
return Tag.LEAVES.isTagged(material);
}
private boolean isBadBlock(Material material) {
return badBlocks.contains(material) || isFlower(material) || isLog(material) || isLeaves(material);
}
private boolean isGoodBlock(@NotNull Material material) {
return goodBlocks.contains(material) || isFlower(material);
}
private boolean isNotAprilFools() {
LocalDate currentDate = LocalDate.now(ZoneOffset.UTC);
return currentDate.getMonthValue() != 4 || currentDate.getDayOfMonth() != 1;
}
/**
* Determines whether the provided count exceeds a randomly generated limit.
* The limit is generated as a random integer between 100 and 300, inclusive.
*
* @param count the value to be compared against the generated random limit
* @return true if the count is greater than the random limit; false otherwise
*/
private boolean underLimit(int count) {
int randomValue = 100 + (int) (Math.random() * 201);
return count <= randomValue;
}
private Component getRandomMessage(@NotNull List<Component> messages) {
return messages.get((int) (Math.random() * messages.size()));
}
private PotionEffectType getRandomEffect(@NotNull List<PotionEffectType> potionEffectTypes) {
return potionEffectTypes.get((int) (Math.random() * potionEffectTypes.size()));
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (isNotAprilFools()) {
return;
}
if (!isGoodBlock(event.getBlock().getType())) {
return;
}
runGoodAction(event.getPlayer());
}
@EventHandler
public void onGrassBlockBoneMealed(PlayerInteractEvent event) {
if (isNotAprilFools()) {
return;
}
if (!event.getAction().isRightClick()) {
return;
}
ItemStack itemInHand = event.getPlayer().getInventory().getItemInMainHand();
if (itemInHand.getType() != Material.BONE_MEAL) {
return;
}
Block clickedBlock = event.getClickedBlock();
if (clickedBlock == null || clickedBlock.getType() != Material.GRASS_BLOCK) {
return;
}
if (event.getHand() != EquipmentSlot.HAND) {
return;
}
runGoodAction(event.getPlayer());
}
@EventHandler
public void onAnimalBred(EntityBreedEvent event) {
if (isNotAprilFools()) {
return;
}
if (!(event.getBreeder() instanceof Player player)) {
return;
}
runGoodAction(player);
}
private void runGoodAction(@NotNull Player player) {
goodActions.merge(player.getUniqueId(), 1, Integer::sum);
if (underLimit(goodActions.get(player.getUniqueId()))) {
return;
}
player.sendMessage(getRandomMessage(happyMessages));
player.addPotionEffect(getRandomEffect(goodEffects).createEffect(60 * 20, 1));
goodActions.put(player.getUniqueId(), 0);
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
if (isNotAprilFools()) {
return;
}
if (!isBadBlock(event.getBlock().getType())) {
return;
}
Player player = event.getPlayer();
runBadAction(player);
}
@EventHandler
public void onAnimalKilled(EntityDeathEvent event) {
if (isNotAprilFools()) {
return;
}
LivingEntity entity = event.getEntity();
if (entity.getKiller() == null) {
return;
}
if (entity instanceof Monster) {
return;
}
Player player = entity.getKiller();
runBadAction(player);
}
@EventHandler
public void onFishCollected(PlayerBucketEntityEvent event) {
if (isNotAprilFools()) {
return;
}
Player player = event.getPlayer();
runBadAction(player);
}
@EventHandler
public void onPlayerFish(PlayerFishEvent event) {
if (isNotAprilFools()) {
return;
}
Player player = event.getPlayer();
runBadAction(player);
}
private void runBadAction(@NotNull Player player) {
badActions.merge(player.getUniqueId(), 1, Integer::sum);
if (underLimit(badActions.get(player.getUniqueId()))) {
return;
}
player.sendMessage(getRandomMessage(angryMessages));
player.addPotionEffect(getRandomEffect(badEffects).createEffect(10 * 20, 1));
badActions.put(player.getUniqueId(), 0);
}
}
@@ -0,0 +1,53 @@
package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.util.Logger;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import java.util.concurrent.TimeUnit;
public class GoatHornEvent implements Listener {
private final Logger logger;
public GoatHornEvent(Logger logger) {
this.logger = logger;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
ItemStack item = event.getItem();
if (item == null) {
return;
}
if (!event.getItem().getType().equals(Material.GOAT_HORN)) {
return;
}
Player player = event.getPlayer();
if (player.getCooldown(item.getType()) > 0) {
event.setCancelled(true);
return;
}
Location spawn = player.getLocation().clone();
spawn.set(0, player.getY(), 0);
if (player.getLocation().distance(spawn) > 250) {
logger.info(String.format("Player %s with uuid %s used a goat horn", player.getName(), player.getUniqueId()));
return;
}
logger.info(String.format("Player %s with uuid %s used a goat horn in spawn", player.getName(), player.getUniqueId()));
player.setCooldown(Material.GOAT_HORN, (int) TimeUnit.MINUTES.toSeconds(5) * 20);
}
}
@@ -0,0 +1,148 @@
package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.PlayerUtils;
import com.alttd.playerutils.config.Config;
import com.alttd.playerutils.util.Logger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.title.Title;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.block.TrialSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class LimitArmorStands implements Listener {
private final PlayerUtils playerUtils;
private final Logger logger;
public LimitArmorStands(PlayerUtils playerUtils, Logger logger) {
this.playerUtils = playerUtils;
this.logger = logger;
}
@FunctionalInterface
private interface ArmorStandCountConsumer {
void apply(int armorStandCount, @NotNull Player player, @NotNull NamespacedKey namespacedKey,
@NotNull PersistentDataContainer persistentDataContainer);
}
@FunctionalInterface
private interface TrialSpawnerTimerConsumer {
void apply(int ticks, @NotNull Player player);
}
@EventHandler
public void onPlayerInteractEvent(PlayerInteractEvent event) {
handleArmorStandPlacing(event, (armorStandCount, player, namespacedKey, persistentDataContainer) -> {
int max = 0;
for (String permission : Config.ARMOR_STAND_LIMIT.LIMIT.keySet()) {
if (player.hasPermission("pu.limit." + permission)) {
max = Math.max(max, Config.ARMOR_STAND_LIMIT.LIMIT.get(permission));
}
}
if (armorStandCount >= max) {
event.setCancelled(true);
player.sendRichMessage("<red>You can not place more than <max> armor stands in a chunk</red>",
Placeholder.parsed("max", String.valueOf(max)));
return;
}
persistentDataContainer.set(namespacedKey, PersistentDataType.INTEGER, ++armorStandCount);
});
if (event.getPlayer().hasPermission("pu.trial_spawner.cooldown")) {
handleRightClickTrialSpawner(event, (ticks, player) -> {
MiniMessage miniMessage = MiniMessage.miniMessage();
Title title = Title.title(Component.empty(),
miniMessage.deserialize("<green>Cooldown <red><seconds></red></green>",
Placeholder.parsed("seconds", String.valueOf(ticks / 20))));
player.showTitle(title);
});
}
}
private void handleArmorStandPlacing(PlayerInteractEvent event, ArmorStandCountConsumer consumer) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
if (!event.getMaterial().equals(Material.ARMOR_STAND)) {
return;
}
if (event.getClickedBlock() == null) {
return;
}
Player player = event.getPlayer();;
Chunk chunk = event.getClickedBlock().getChunk();
NamespacedKey namespacedKey = NamespacedKey.fromString("armor_stand_count", playerUtils);
if (namespacedKey == null) {
event.setCancelled(true);
logger.warning("Unable to retrieve name spaced key for armor stand count.");
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
return;
}
PersistentDataContainer persistentDataContainer = chunk.getPersistentDataContainer();
if (!persistentDataContainer.has(namespacedKey, PersistentDataType.INTEGER)) {
persistentDataContainer.set(namespacedKey, PersistentDataType.INTEGER, countArmorStands(chunk));
}
Integer armorStandCount = persistentDataContainer.get(namespacedKey, PersistentDataType.INTEGER);
if (armorStandCount == null) {
event.setCancelled(true);
logger.warning("Unable to retrieve armor stand count.");
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
return;
}
consumer.apply(armorStandCount, event.getPlayer(), namespacedKey, persistentDataContainer);
}
private void handleRightClickTrialSpawner(PlayerInteractEvent event, TrialSpawnerTimerConsumer consumer) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
if (!event.getMaterial().equals(Material.AIR)) {
return;
}
if (event.getClickedBlock() == null) {
return;
}
Block block = event.getClickedBlock();
if (!block.getType().equals(Material.TRIAL_SPAWNER)) {
return;
}
if (!(block instanceof TrialSpawner trialSpawner)) {
return;
}
if (!(trialSpawner.getBlockData() instanceof org.bukkit.block.data.type.TrialSpawner trialSpawnerData)) {
return;
}
Player player = event.getPlayer();
if (!trialSpawnerData.getTrialSpawnerState().equals(org.bukkit.block.data.type.TrialSpawner.State.INACTIVE)) {
consumer.apply(0, player);
return;
}
consumer.apply(trialSpawner.getCooldownLength(), player);
}
private int countArmorStands(Chunk chunk) {
return (int) Arrays.stream(chunk.getEntities())
.filter(entity -> entity.getType().equals(EntityType.ARMOR_STAND))
.count();
}
}
@@ -1,5 +1,6 @@
package com.alttd.playerutils.event_listeners; package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.util.Logger;
import org.bukkit.Axis; import org.bukkit.Axis;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
@@ -23,8 +24,13 @@ import java.util.stream.Collectors;
public class RotateBlockEvent implements Listener { public class RotateBlockEvent implements Listener {
private final HashSet<UUID> rotateEnabled = new HashSet<>(); private final HashSet<UUID> rotateEnabled = new HashSet<>();
private final Logger logger;
private static final List<BlockFace> VALID_FOUR_STATES = List.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST); private static final List<BlockFace> VALID_FOUR_STATES = List.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST);
public RotateBlockEvent(Logger logger) {
this.logger = logger;
}
public synchronized boolean toggleRotate(UUID uuid) { public synchronized boolean toggleRotate(UUID uuid) {
if (rotateEnabled.contains(uuid)) { if (rotateEnabled.contains(uuid)) {
@@ -55,7 +61,14 @@ public class RotateBlockEvent implements Listener {
return; return;
Material type = block.getType(); Material type = block.getType();
if (Tag.STAIRS.isTagged(type)) { logger.debug(String.format("Material %s with action %s", type, event.getAction().isLeftClick() ? "left click" : "right click"));
if (type.equals(Material.IRON_TRAPDOOR) && event.getAction().isLeftClick()) {
event.setCancelled(true);
toggleTrapDoor(block, player);
} else if (type.equals(Material.BIG_DRIPLEAF) && event.getAction().isLeftClick()) {
event.setCancelled(true);
toggleDripLeaf(block, player);
} else if (Tag.STAIRS.isTagged(type)) {
event.setCancelled(true); event.setCancelled(true);
rotateStairs(block, player); rotateStairs(block, player);
} else if (Tag.WALLS.isTagged(type)) { } else if (Tag.WALLS.isTagged(type)) {
@@ -67,12 +80,6 @@ public class RotateBlockEvent implements Listener {
} else if(Tag.RAILS.isTagged(type)) { } else if(Tag.RAILS.isTagged(type)) {
event.setCancelled(true); event.setCancelled(true);
toggleRails(block, player); toggleRails(block, player);
} else if (type.equals(Material.IRON_TRAPDOOR) && event.getAction().isLeftClick()) {
event.setCancelled(true);
toggleTrapDoor(block, player);
} else if (Tag.BIG_DRIPLEAF_PLACEABLE.isTagged(type) && event.getAction().isLeftClick()) {
event.setCancelled(true);
toggleDripLeaf(block, player);
} else if (block.getBlockData() instanceof Directional directional) { } else if (block.getBlockData() instanceof Directional directional) {
event.setCancelled(true); event.setCancelled(true);
rotateDirectionalBlock(block, directional, player); rotateDirectionalBlock(block, directional, player);
@@ -83,7 +90,7 @@ public class RotateBlockEvent implements Listener {
} }
private void toggleDripLeaf(Block block, Player player) { private void toggleDripLeaf(Block block, Player player) {
if (!(block instanceof BigDripleaf bigDripleaf)) { if (!(block.getBlockData() instanceof BigDripleaf bigDripleaf)) {
return; return;
} }
@@ -94,10 +101,8 @@ public class RotateBlockEvent implements Listener {
BigDripleaf.Tilt[] values = BigDripleaf.Tilt.values(); BigDripleaf.Tilt[] values = BigDripleaf.Tilt.values();
int ordinal = bigDripleaf.getTilt().ordinal(); int ordinal = bigDripleaf.getTilt().ordinal();
if (ordinal == values.length) { if (++ordinal == values.length) {
ordinal = 0; ordinal = 0;
} else {
ordinal++;
} }
bigDripleaf.setTilt(values[ordinal]); bigDripleaf.setTilt(values[ordinal]);
@@ -105,7 +110,7 @@ public class RotateBlockEvent implements Listener {
} }
private void toggleTrapDoor(Block block, Player player) { private void toggleTrapDoor(Block block, Player player) {
if (!(block instanceof TrapDoor trapDoor)) { if (!(block.getBlockData() instanceof TrapDoor trapDoor)) {
return; return;
} }
@@ -114,6 +119,7 @@ public class RotateBlockEvent implements Listener {
} }
trapDoor.setOpen(!trapDoor.isOpen()); trapDoor.setOpen(!trapDoor.isOpen());
block.setBlockAndForget(trapDoor);
} }
private void toggleRails(Block block, Player player) { private void toggleRails(Block block, Player player) {
@@ -18,6 +18,8 @@ public class TeleportEvent implements Listener {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (player.getVehicle() == null) if (player.getVehicle() == null)
return; return;
if (event.getTo().distance(event.getFrom()) < 5)
return;
event.setCancelled(true); event.setCancelled(true);
player.sendRichMessage("<red>Teleporting was cancelled. You can not be sitting, or mounted while teleporting."); player.sendRichMessage("<red>Teleporting was cancelled. You can not be sitting, or mounted while teleporting.");
} }
@@ -103,7 +103,7 @@ public class XpBottleEvent implements Listener {
NamespacedKey customXp = NamespacedKey.fromString("custom_xp", playerUtils); NamespacedKey customXp = NamespacedKey.fromString("custom_xp", playerUtils);
if (customXp == null) { if (customXp == null) {
player.sendMiniMessage(Messages.XP_CHEQUE.FAILED_STORAGE, null); player.sendRichMessage(Messages.XP_CHEQUE.FAILED_STORAGE);
return Optional.empty(); return Optional.empty();
} }
persistentDataContainer.set(customXp, PersistentDataType.INTEGER, xpValue); persistentDataContainer.set(customXp, PersistentDataType.INTEGER, xpValue);