Compare commits

..

1 Commits

Author SHA1 Message Date
Teriuihi 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
26 changed files with 401 additions and 530 deletions

View File

@ -1,7 +1,6 @@
plugins {
id("java")
id("maven-publish")
id("com.github.ben-manes.versions") version "0.52.0"
}
group = "com.alttd"
@ -39,12 +38,7 @@ tasks {
}
dependencies {
compileOnly("com.alttd.cosmos:cosmos-api:1.21.10-R0.1-SNAPSHOT") {
compileOnly("com.alttd:Galaxy-API:1.21-R0.1-SNAPSHOT") {
isChanging = true
}
implementation("org.slf4j:slf4j-api:2.0.17")
compileOnly("org.projectlombok:lombok:1.18.38")
annotationProcessor("org.projectlombok:lombok:1.18.38")
}

View File

@ -1,21 +1,11 @@
rootProject.name = "StaffUtils"
val nexusUser = providers.gradleProperty("alttdSnapshotUsername").orNull ?: System.getenv("NEXUS_USERNAME")
val nexusPass = providers.gradleProperty("alttdSnapshotPassword").orNull ?: System.getenv("NEXUS_PASSWORD")
rootProject.name = "PlayerUtils"
dependencyResolutionManagement {
repositories {
mavenLocal()
mavenCentral()
maven {
url = uri("https://repo.alttd.com/repository/alttd-snapshot/")
credentials {
username = nexusUser
password = nexusPass
}
}
maven("https://repo.destro.xyz/snapshots")
maven("https://jitpack.io")
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
maven("'https://jitpack.io'") // Vault
}
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
}

View File

@ -1,12 +1,12 @@
package com.alttd.playerutils;
import com.alttd.playerutils.commands.PlayerUtilsCommand;
import com.alttd.playerutils.commands.playerutils_subcommands.GhastSpeed;
import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
import com.alttd.playerutils.config.Config;
import com.alttd.playerutils.config.KeyStorage;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.event_listeners.*;
import com.alttd.playerutils.util.Logger;
import org.bukkit.Bukkit;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
@ -15,10 +15,12 @@ import java.util.concurrent.TimeUnit;
public final class PlayerUtils extends JavaPlugin {
private Logger logger;
private PlayerUtilsCommand playerUtilsCommand;
@Override
public void onEnable() {
this.logger = new Logger(getLogger());
registerCommands();
registerEvents();
reloadConfigs();
@ -31,31 +33,26 @@ public final class PlayerUtils extends JavaPlugin {
}
private void registerCommands() {
playerUtilsCommand = new PlayerUtilsCommand(this);
playerUtilsCommand = new PlayerUtilsCommand(this, logger);
}
private void registerEvents() {
PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new XpBottleEvent(this), this);
pluginManager.registerEvents(new XpBottleEvent(this, logger), this);
pluginManager.registerEvents(new TeleportEvent(), this);
pluginManager.registerEvents(new GoatHornEvent(), this);
pluginManager.registerEvents(new LimitArmorStands(this), this);
pluginManager.registerEvents(new BlockBlockUseEvent(), this);
pluginManager.registerEvents(new PlayerJoin(this), 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);
playerUtilsCommand.addSubCommand(new RotateBlock(rotateBlockEvent));
GhastSpeedEvent ghastSpeedEvent = new GhastSpeedEvent();
pluginManager.registerEvents(ghastSpeedEvent, this);
playerUtilsCommand.addSubCommand(new GhastSpeed(ghastSpeedEvent));
}
public void reloadConfigs() {
Config.reload();
Messages.reload();
KeyStorage.reload();
Config.reload(logger);
Messages.reload(logger);
KeyStorage.reload(logger);
}
private void registerSchedulers() {

View File

@ -3,26 +3,26 @@ package com.alttd.playerutils.commands;
import com.alttd.playerutils.PlayerUtils;
import com.alttd.playerutils.commands.playerutils_subcommands.*;
import com.alttd.playerutils.config.Messages;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import com.alttd.playerutils.event_listeners.RotateBlockEvent;
import com.alttd.playerutils.util.Logger;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j @Getter
public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
private final List<SubCommand> subCommands;
public PlayerUtilsCommand(PlayerUtils playerUtils) {
public PlayerUtilsCommand(PlayerUtils playerUtils, Logger logger) {
PluginCommand command = playerUtils.getCommand("playerutils");
if (command == null) {
subCommands = null;
log.error("Unable to find playerutils command.");
logger.severe("Unable to find playerutils command.");
return;
}
command.setExecutor(this);
@ -30,11 +30,11 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
command.setAliases(List.of("pu"));
subCommands = new ArrayList<>(List.of(
new Glow(),
new Glow(logger),
new XPCheque(playerUtils),
new XPCalc(),
new Reload(playerUtils),
new Key())
new Key(logger))
);
}
@ -85,6 +85,10 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
return res;
}
public List<SubCommand> getSubCommands() {
return subCommands;
}
private SubCommand getSubCommand(String cmdName) {
return subCommands.stream()
.filter(subCommand -> subCommand.getName().equals(cmdName))

View File

@ -1,11 +0,0 @@
package com.alttd.playerutils.commands.argument_parser;
import org.bukkit.command.CommandSender;
import java.util.Optional;
public interface ArgumentParser<T> {
Optional<T> parse(CommandSender commandSender, String argument);
}

View File

@ -1,23 +0,0 @@
package com.alttd.playerutils.commands.argument_parser;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.data_objects.GHAST_SPEED;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Optional;
public class GhastSpeedParser implements ArgumentParser<GHAST_SPEED> {
@Override
public Optional<GHAST_SPEED> parse(CommandSender commandSender, String speed) {
GHAST_SPEED ghastSpeed;
try {
ghastSpeed = GHAST_SPEED.valueOf(speed.toUpperCase());
} catch (IllegalArgumentException e) {
return Optional.empty();
}
return Optional.of(ghastSpeed);
}
}

View File

@ -1,21 +0,0 @@
package com.alttd.playerutils.commands.argument_parser;
import com.alttd.playerutils.config.Messages;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Optional;
public class OnlinePlayerParser implements ArgumentParser<Player> {
@Override
public Optional<Player> parse(CommandSender commandSender, String playerName) {
Player player = commandSender.getServer().getPlayer(playerName);
if (player == null || !player.isOnline()) {
commandSender.sendRichMessage(Messages.GENERIC.PLAYER_NOT_FOUND, Placeholder.parsed("player", playerName));
return Optional.empty();
}
return Optional.of(player);
}
}

View File

@ -1,90 +0,0 @@
package com.alttd.playerutils.commands.playerutils_subcommands;
import com.alttd.playerutils.commands.SubCommand;
import com.alttd.playerutils.commands.argument_parser.GhastSpeedParser;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.data_objects.GHAST_SPEED;
import com.alttd.playerutils.event_listeners.GhastSpeedEvent;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.HappyGhast;
import org.bukkit.entity.Player;
import java.util.*;
public class GhastSpeed extends SubCommand {
private final static GhastSpeedParser GHAST_SPEED_PARSER = new GhastSpeedParser();
private final static int GHAST_SPEED_ARG = 1;
private final GhastSpeedEvent ghastSpeedEvent;
public GhastSpeed(GhastSpeedEvent ghastSpeedEvent) {
this.ghastSpeedEvent = ghastSpeedEvent;
}
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
if (args.length != 2) {
return false;
}
if (!(commandSender instanceof Player player)) {
commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
return true;
}
Optional<GHAST_SPEED> parsedGhastSpeed = GHAST_SPEED_PARSER.parse(commandSender, args[GHAST_SPEED_ARG]);
if (parsedGhastSpeed.isEmpty()) {
return false;
}
GHAST_SPEED ghastSpeed = parsedGhastSpeed.get();
if (!(player.getVehicle() instanceof HappyGhast happyGhast)) {
commandSender.sendRichMessage(Messages.GHAST_SPEED.NOT_RIDING_A_GHAST);
return true;
}
AttributeInstance attribute = happyGhast.getAttribute(Attribute.FLYING_SPEED);
if (attribute == null) {
commandSender.sendRichMessage(Messages.GHAST_SPEED.FAILED_TO_SET_SPEED);
return true;
}
if (!commandSender.hasPermission(getPermission() + "." + ghastSpeed.name().toLowerCase())) {
commandSender.sendRichMessage(Messages.GENERIC.NO_PERMISSION,
Placeholder.parsed("permission", getPermission() + "." +
ghastSpeed.name().toLowerCase()));
return true;
}
double newSpeed = GHAST_SPEED.getSpeed(ghastSpeed);
ghastSpeedEvent.setNewSpeed(player.getUniqueId(), ghastSpeed);
attribute.setBaseValue(newSpeed);
commandSender.sendRichMessage(Messages.GHAST_SPEED.NEW_SPEED_SET_TO,
Placeholder.parsed("speed", ghastSpeed.name().toLowerCase().replace("_", " ")));
return true;
}
@Override
public String getName() {
return "ghastspeed";
}
@Override
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
if (args.length == 2) {
return Arrays.stream(GHAST_SPEED.values())
.map(GHAST_SPEED::name)
.filter(name -> commandSender.hasPermission(
getPermission() + "." + name.toLowerCase())).toList();
}
return List.of();
}
@Override
public String getHelpMessage() {
return Messages.HELP.GHAST_SPEED;
}
}

View File

@ -2,7 +2,7 @@ package com.alttd.playerutils.commands.playerutils_subcommands;
import com.alttd.playerutils.commands.SubCommand;
import com.alttd.playerutils.config.Messages;
import lombok.extern.slf4j.Slf4j;
import com.alttd.playerutils.util.Logger;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
@ -19,7 +19,13 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j public class Glow extends SubCommand {
public class Glow extends SubCommand {
private final Logger logger;
public Glow(Logger logger) {
this.logger = logger;
}
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
@ -100,7 +106,7 @@ import java.util.stream.Collectors;
private void turnOnGlow(CommandSender commandSender, Player player, Team team, DyeColor dyeColor, boolean otherPlayer) {
if (team.getScoreboard() == null) {
commandSender.sendRichMessage(Messages.GLOW.UNABLE_TO_GET_SCOREBOARD);
log.warn("Unable to get scoreboard for team");
logger.warning("Unable to get scoreboard for team");
return;
}

View File

@ -4,8 +4,8 @@ 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 lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
@ -15,7 +15,13 @@ import org.bukkit.entity.Player;
import java.util.List;
import java.util.UUID;
@Slf4j public class Key extends SubCommand {
public class Key extends SubCommand {
private final Logger logger;
public Key(Logger logger) {
this.logger = logger;
}
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
@ -46,7 +52,7 @@ import java.util.UUID;
}
crateMap.addTo(uuid, 1);
log.info("Gave {} one key for {}", player.getName(), crate);
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(

View File

@ -64,7 +64,7 @@ public class XPCheque extends SubCommand {
return true;
}
int totalExperience = player.calculateTotalExperiencePoints();
int totalExperience = player.getTotalExperience();
if (totalExperience < (xpValue * amount)) {
commandSender.sendRichMessage(Messages.XP_CHEQUE.NOT_ENOUGH_XP, Placeholder.parsed("xp", String.valueOf(totalExperience)));
return true;
@ -139,7 +139,7 @@ public class XPCheque extends SubCommand {
}
public void decreaseExperience(Player player, int xpToRemove) {
int totalExp = player.calculateTotalExperiencePoints();
int totalExp = player.getTotalExperience();
int newTotalExp = Math.max(totalExp - xpToRemove, 0);
int level = 0;
@ -153,7 +153,7 @@ public class XPCheque extends SubCommand {
float progress = (float) newTotalExp / getExpToNext(level);
player.setExperienceLevelAndProgress(totalExp - xpToRemove);
player.setTotalExperience(totalExp - xpToRemove);
player.setLevel(level);
player.setExp(progress);
}

View File

@ -1,8 +1,8 @@
package com.alttd.playerutils.config;
import com.alttd.playerutils.PlayerUtils;
import com.alttd.playerutils.util.Logger;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
@ -19,16 +19,19 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j @SuppressWarnings({"unused", "SameParameterValue"})
@SuppressWarnings({"unused", "SameParameterValue"})
abstract class AbstractConfig {
File file;
YamlConfiguration yaml;
private static Logger logger = null;
AbstractConfig(PlayerUtils playerUtils, String filename) {
AbstractConfig(PlayerUtils playerUtils, String filename, Logger logger) {
AbstractConfig.logger = logger;
init(new File(playerUtils.getDataFolder(), filename), filename);
}
AbstractConfig(File file, String filename) {
AbstractConfig(File file, String filename, Logger logger) {
AbstractConfig.logger = logger;
init(new File(file.getPath() + File.separator + filename), filename);
}
@ -38,9 +41,10 @@ abstract class AbstractConfig {
try {
yaml.load(file);
} catch (IOException ignore) {
} catch (InvalidConfigurationException e) {
log.error("Could not load {}, please correct your syntax errors", filename, e);
throw new RuntimeException(e);
} catch (InvalidConfigurationException ex) {
if (logger != null)
logger.severe(String.format("Could not load %s, please correct your syntax errors", filename));
throw new RuntimeException(ex);
}
yaml.options().copyDefaults(true);
}
@ -55,8 +59,10 @@ abstract class AbstractConfig {
method.invoke(instance);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception e) {
log.error("Error invoking {}.", method, e);
} catch (Exception ex) {
if (logger != null)
logger.severe("Error invoking %.", method.toString());
ex.printStackTrace();
}
}
}
@ -69,8 +75,10 @@ abstract class AbstractConfig {
private void save() {
try {
yaml.save(file);
} catch (IOException e) {
log.error("Could not save {}.", file.toString(), e);
} catch (IOException ex) {
if (logger != null)
logger.severe("Could not save %.", file.toString());
ex.printStackTrace();
}
}
@ -142,4 +150,4 @@ abstract class AbstractConfig {
ConfigurationSection getConfigurationSection(String path) {
return yaml.getConfigurationSection(path);
}
}
}

View File

@ -1,28 +1,31 @@
package com.alttd.playerutils.config;
import lombok.extern.slf4j.Slf4j;
import com.alttd.playerutils.util.Logger;
import org.bukkit.configuration.ConfigurationSection;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
@Slf4j public class Config extends AbstractConfig{
public class Config extends AbstractConfig{
static Config config;
private Logger logger;
Config() {
Config(Logger logger) {
super(
new File(File.separator
+ "mnt" + File.separator
+ "configs" + File.separator
+ "PlayerUtils"),
"config.yml");
"config.yml", logger);
this.logger = logger;
}
public static void reload() {
log.info("Reloading config");
config = new Config();
public static void reload(Logger logger) {
logger.info("Reloading config");
config = new Config(logger);
config.readConfig(Config.class, null);
}
@ -47,7 +50,7 @@ import java.util.Set;
CRATES.clear();
ConfigurationSection configurationSection = config.getConfigurationSection(prefix.substring(0, prefix.length() - 1));
if (configurationSection == null) {
log.warn("No keys configured, adding default");
config.logger.warning("No keys configured, adding default");
config.set(prefix, "dailyvotecrate", 0);
config.set(prefix, "weeklyvotecrate", 0);
config.set(prefix, "questcrate", 0);
@ -70,7 +73,7 @@ import java.util.Set;
LIMIT.clear();
ConfigurationSection configurationSection = config.getConfigurationSection(prefix.substring(0, prefix.length() - 1));
if (configurationSection == null) {
log.warn("No limits configured, adding default");
config.logger.warning("No limits configured, adding default");
config.set(prefix, "default", 10);
}
Set<String> limits = configurationSection.getKeys(false);
@ -79,17 +82,4 @@ import java.util.Set;
}
}
}
public static class LOCATOR_BAR {
private static final String prefix = "locator_bar.";
public static double WAYPOINT_RECEIVE_RANGE = 200;
public static double WAYPOINT_TRANSMIT_RANGE = 200;
@SuppressWarnings("unused")
private static void load() {
WAYPOINT_RECEIVE_RANGE = config.getDouble(prefix, "waypoint_receive_range", WAYPOINT_RECEIVE_RANGE);
WAYPOINT_TRANSMIT_RANGE = config.getDouble(prefix, "waypoint_transmit_range", WAYPOINT_TRANSMIT_RANGE);
}
}
}

View File

@ -1,7 +1,7 @@
package com.alttd.playerutils.config;
import com.alttd.playerutils.util.Logger;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.configuration.ConfigurationSection;
import java.io.File;
@ -9,23 +9,24 @@ import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@Slf4j
public class KeyStorage extends AbstractConfig {
static KeyStorage config;
private final Logger logger;
public KeyStorage() {
public KeyStorage(Logger logger) {
super(
new File(File.separator
+ "mnt" + File.separator
+ "configs" + File.separator
+ "PlayerUtils"),
"key_storage.yml");
"key_storage.yml", logger);
this.logger = logger;
}
public static void reload() {
log.info("Reloading key storage");
config = new KeyStorage();
public static void reload(Logger logger) {
logger.info("Reloading key storage");
config = new KeyStorage(logger);
config.readConfig(KeyStorage.class, null);
}
@ -42,13 +43,13 @@ public class KeyStorage extends AbstractConfig {
Object2IntOpenHashMap<UUID> count = new Object2IntOpenHashMap<>();
ConfigurationSection configurationSection = config.getConfigurationSection(prefix + crate);
if (configurationSection == null) {
log.info("No section yet for crate {}", crate);
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()) {
log.info("No keys yet for crate {}", crate);
config.logger.info(String.format("No keys yet for crate %s", crate));
KEYS.put(crate, count);
continue;
}
@ -61,7 +62,7 @@ public class KeyStorage extends AbstractConfig {
}
public synchronized static void save() {
log.info("Saving KeyStorage");
config.logger.info("Saving KeyStorage");
KEYS.keySet()
.forEach(crate -> KEYS.get(crate)
.forEach((uuid, keys) -> config.set(prefix + crate + ".", uuid.toString(), keys)));

View File

@ -1,22 +1,27 @@
package com.alttd.playerutils.config;
import com.alttd.playerutils.util.Logger;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
public class Messages extends AbstractConfig {
static Messages config;
private final Logger logger;
Messages() {
Messages(Logger logger) {
super(
new File(File.separator
+ "mnt" + File.separator
+ "configs" + File.separator
+ "PlayerUtils"),
"messages.yml");
"messages.yml", logger);
this.logger = logger;
}
public static void reload() {
config = new Messages();
public static void reload(Logger logger) {
config = new Messages(logger);
config.readConfig(Messages.class, null);
}
@ -31,7 +36,6 @@ public class Messages extends AbstractConfig {
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 KEY = "<green>Receive a key that you are owed: <gold>/pu key</gold></green>";
public static String GHAST_SPEED = "<green>Set the speed of a ghast: <gold>/pu ghastspeed <speed></gold></green>";
@SuppressWarnings("unused")
private static void load() {
@ -42,7 +46,6 @@ public class Messages extends AbstractConfig {
XP_CALC = config.getString(prefix, "xp-calc", XP_CALC);
RELOAD = config.getString(prefix, "reload", RELOAD);
ROTATE_BLOCK = config.getString(prefix, "rotate-block", ROTATE_BLOCK);
GHAST_SPEED = config.getString(prefix, "ghast-speed", GHAST_SPEED);
}
}
@ -154,30 +157,4 @@ public class Messages extends AbstractConfig {
GAVE_FINAL_KEY = config.getString(prefix, "gave-final-key", GAVE_FINAL_KEY);
}
}
public static class GHAST_SPEED {
private static final String prefix = "pu-command.ghast-speed.";
public static String NOT_RIDING_A_GHAST = "<red>You are not riding a ghast</red>";
public static String FAILED_TO_SET_SPEED = "<red>Failed to set ghast speed</red>";
public static String NEW_SPEED_SET_TO = "<green>New speed set to <speed></green>";
@SuppressWarnings("unused")
private static void load() {
NOT_RIDING_A_GHAST = config.getString(prefix, "not-riding-a-ghast", NOT_RIDING_A_GHAST);
FAILED_TO_SET_SPEED = config.getString(prefix, "failed-to-set-speed", FAILED_TO_SET_SPEED);
NEW_SPEED_SET_TO = config.getString(prefix, "new-speed-set-to", NEW_SPEED_SET_TO);
}
}
public static class BLOCK_BLOCK_USE {
private static final String prefix = "block-block-use.";
public static String BLOCKED = "<red>You are not powerful enough!</red>";
@SuppressWarnings("unused")
private static void load() {
BLOCKED = config.getString(prefix, "blocked", BLOCKED);
}
}
}

View File

@ -1,19 +0,0 @@
package com.alttd.playerutils.data_objects;
public enum GHAST_SPEED {
SLOW,
NORMAL,
FAST,
VERY_FAST,
EXTREMELY_FAST;
public static double getSpeed(GHAST_SPEED ghastSpeed) {
return switch (ghastSpeed) {
case SLOW -> 0.025;
case NORMAL -> 0.05;
case FAST -> 0.075;
case VERY_FAST -> 0.1;
case EXTREMELY_FAST -> 0.125;
};
}
}

View File

@ -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);
}
}

View File

@ -1,65 +0,0 @@
package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.config.Messages;
import com.destroystokyo.paper.MaterialTags;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockCanBuildEvent;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
public class BlockBlockUseEvent implements Listener {
@EventHandler
public void onBlockPlace(BlockCanBuildEvent event) {
Player player = event.getPlayer();
if (player != null && player.hasPermission("playerutils.block-block-use.bypass")) {
return;
}
if (isNotBlocked(event.getMaterial())) {
return;
}
event.setBuildable(false);
if (player != null) {
player.sendRichMessage(Messages.BLOCK_BLOCK_USE.BLOCKED);
}
}
@EventHandler
public void onItemUse(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (player.hasPermission("playerutils.block-block-use.bypass")) {
return;
}
if (!event.getAction().isRightClick()) {
return;
}
ItemStack item = event.getItem();
if (item == null || isNotBlocked(item.getType())) {
return;
}
player.sendRichMessage(Messages.BLOCK_BLOCK_USE.BLOCKED);
event.setCancelled(true);
}
@EventHandler
public void onDispenserUse(BlockDispenseEvent event) {
if (isNotBlocked(event.getItem().getType())) {
return;
}
event.setCancelled(true);
}
public boolean isNotBlocked(Material type) {
return !type.equals(Material.BEDROCK)
&& !type.equals(Material.SPAWNER)
&& !type.equals(Material.BARRIER)
&& !type.equals(Material.END_PORTAL_FRAME)
&& !MaterialTags.SPAWN_EGGS.isTagged(type);
}
}

View File

@ -1,72 +0,0 @@
package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.data_objects.GHAST_SPEED;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HappyGhast;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDismountEvent;
import org.bukkit.event.entity.EntityMountEvent;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.UUID;
public class GhastSpeedEvent implements Listener {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(GhastSpeedEvent.class);
private final HashMap<UUID, GHAST_SPEED> lastSetSpeed = new HashMap<>();
public GhastSpeedEvent() {
}
@EventHandler
public void onEntityMount(EntityMountEvent event) {
if (!(event.getEntity() instanceof Player player)) {
return;
}
Entity mount = event.getMount();
if (!(mount instanceof HappyGhast happyGhast)) {
return;
}
GHAST_SPEED ghastSpeed = lastSetSpeed.get(player.getUniqueId());
if (ghastSpeed == null) {
return;
}
AttributeInstance attribute = happyGhast.getAttribute(Attribute.FLYING_SPEED);
if (attribute == null) {
return;
}
attribute.setBaseValue(GHAST_SPEED.getSpeed(ghastSpeed));
}
@EventHandler
public void onEntityDismount(EntityDismountEvent event) {
if (!(event.getDismounted() instanceof HappyGhast happyGhast)) {
return;
}
if (happyGhast.getPassengers().size() >= 2) {
return;
}
AttributeInstance attribute = happyGhast.getAttribute(Attribute.FLYING_SPEED);
if (attribute == null) {
return;
}
attribute.setBaseValue(GHAST_SPEED.getSpeed(GHAST_SPEED.NORMAL));
}
public void setNewSpeed(UUID uuid, GHAST_SPEED speed) {
lastSetSpeed.put(uuid, speed);
}
}

View File

@ -1,6 +1,6 @@
package com.alttd.playerutils.event_listeners;
import lombok.extern.slf4j.Slf4j;
import com.alttd.playerutils.util.Logger;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@ -11,7 +11,13 @@ import org.bukkit.inventory.ItemStack;
import java.util.concurrent.TimeUnit;
@Slf4j public class GoatHornEvent implements Listener {
public class GoatHornEvent implements Listener {
private final Logger logger;
public GoatHornEvent(Logger logger) {
this.logger = logger;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
@ -35,10 +41,11 @@ import java.util.concurrent.TimeUnit;
if (player.getLocation().distance(spawn) > 250) {
log.info("Player {} with uuid {} used a goat horn", player.getName(), player.getUniqueId());
logger.info(String.format("Player %s with uuid %s used a goat horn", player.getName(), player.getUniqueId()));
return;
}
log.info("Player {} with uuid {} used a goat horn in spawn", player.getName(), player.getUniqueId());
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);
}

View File

@ -2,7 +2,7 @@ package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.PlayerUtils;
import com.alttd.playerutils.config.Config;
import lombok.extern.slf4j.Slf4j;
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;
@ -24,12 +24,14 @@ import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
@Slf4j public class LimitArmorStands implements Listener {
public class LimitArmorStands implements Listener {
private final PlayerUtils playerUtils;
private final Logger logger;
public LimitArmorStands(PlayerUtils playerUtils) {
public LimitArmorStands(PlayerUtils playerUtils, Logger logger) {
this.playerUtils = playerUtils;
this.logger = logger;
}
@FunctionalInterface
@ -87,7 +89,7 @@ import java.util.Arrays;
NamespacedKey namespacedKey = NamespacedKey.fromString("armor_stand_count", playerUtils);
if (namespacedKey == null) {
event.setCancelled(true);
log.warn("Unable to retrieve name spaced key for armor stand count.");
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;
@ -99,7 +101,7 @@ import java.util.Arrays;
Integer armorStandCount = persistentDataContainer.get(namespacedKey, PersistentDataType.INTEGER);
if (armorStandCount == null) {
event.setCancelled(true);
log.warn("Unable to retrieve armor stand count.");
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;

View File

@ -1,66 +0,0 @@
package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.config.Config;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.NamespacedKey;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
@Slf4j
public class PlayerJoin implements Listener {
private final NamespacedKey WAYPOINT_RECEIVE_KEY;
private final NamespacedKey WAYPOINT_TRANSMIT_KEY;
public PlayerJoin(JavaPlugin plugin) {
this.WAYPOINT_RECEIVE_KEY = new NamespacedKey(plugin, "waypoint_receive_modifier");
this.WAYPOINT_TRANSMIT_KEY = new NamespacedKey(plugin, "waypoint_transmit_modifier");
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
setModifiedAttribute(player, Attribute.WAYPOINT_RECEIVE_RANGE, Config.LOCATOR_BAR.WAYPOINT_RECEIVE_RANGE, WAYPOINT_RECEIVE_KEY);
setModifiedAttribute(player, Attribute.WAYPOINT_TRANSMIT_RANGE, Config.LOCATOR_BAR.WAYPOINT_TRANSMIT_RANGE, WAYPOINT_TRANSMIT_KEY);
}
private void setModifiedAttribute(Player player, Attribute attribute, double configValue, NamespacedKey key) {
AttributeInstance attributeInstance = player.getAttribute(attribute);
if (attributeInstance == null) {
log.error("Unable to retrieve attribute instance for player {}.", player.getName());
return;
}
for (AttributeModifier modifier : attributeInstance.getModifiers()) {
attributeInstance.removeModifier(modifier);
}
double attributeDelta = configValue - attributeInstance.getBaseValue();
if (attributeDelta != 0) {
AttributeModifier attributeModifier = new AttributeModifier(
key,
attributeDelta,
AttributeModifier.Operation.ADD_NUMBER
);
attributeInstance.addModifier(attributeModifier);
}
double actualValue = attributeInstance.getValue();
if (Math.abs(actualValue - configValue) > 0.01) {
log.warn("Failed to set attribute {} to {} for {}, actual value is {}.",
attribute, configValue, player.getName(), actualValue);
} else {
log.info("Set attribute {} for {} to {}.", attribute, player.getName(), configValue);
}
}
}

View File

@ -1,6 +1,6 @@
package com.alttd.playerutils.event_listeners;
import lombok.extern.slf4j.Slf4j;
import com.alttd.playerutils.util.Logger;
import org.bukkit.Axis;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@ -21,12 +21,17 @@ import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class RotateBlockEvent implements Listener {
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);
public RotateBlockEvent(Logger logger) {
this.logger = logger;
}
public synchronized boolean toggleRotate(UUID uuid) {
if (rotateEnabled.contains(uuid)) {
rotateEnabled.remove(uuid);
@ -56,8 +61,7 @@ public class RotateBlockEvent implements Listener {
return;
Material type = block.getType();
log.debug("Material {} with action {}", type, event.getAction().isLeftClick() ? "left " +
"click" : "right click");
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);

View File

@ -1,18 +0,0 @@
package com.alttd.playerutils.event_listeners;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityTameEvent;
import java.util.UUID;
public class VanillaPetTameEvent implements Listener {
@EventHandler
public void onEntityTame(EntityTameEvent event) {
UUID uniqueId = event.getOwner().getUniqueId();
}
}

View File

@ -2,7 +2,7 @@ package com.alttd.playerutils.event_listeners;
import com.alttd.playerutils.PlayerUtils;
import com.alttd.playerutils.config.Messages;
import lombok.extern.slf4j.Slf4j;
import com.alttd.playerutils.util.Logger;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
@ -25,13 +25,15 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@Slf4j public class XpBottleEvent implements Listener {
public class XpBottleEvent implements Listener {
private final PlayerUtils playerUtils;
private final Logger logger;
private final MiniMessage miniMessage = MiniMessage.miniMessage();
public XpBottleEvent(PlayerUtils playerUtils) {
public XpBottleEvent(PlayerUtils playerUtils, Logger logger) {
this.playerUtils = playerUtils;
this.logger = logger;
}
@EventHandler
@ -40,7 +42,7 @@ import java.util.stream.Collectors;
PersistentDataContainer persistentDataContainer = item.getItemMeta().getPersistentDataContainer();
NamespacedKey customXp = NamespacedKey.fromString("custom_xp", playerUtils);
if (customXp == null) {
log.warn("Unable to retrieve name spaced key.");
logger.warning("Unable to retrieve name spaced key.");
return;
}
Integer integer = persistentDataContainer.get(customXp, PersistentDataType.INTEGER);
@ -81,7 +83,7 @@ import java.util.stream.Collectors;
}
for (Map.Entry<CookingRecipe<?>, Integer> entry : recipesUsed.entrySet()) {
exp += (int) (entry.getKey().getExperience() * entry.getValue());
exp += entry.getKey().getExperience() * entry.getValue();
}
Optional<ItemStack> optionalItemStack = getExpBottleItem(player, exp);

View File

@ -0,0 +1,42 @@
package com.alttd.playerutils.util;
import com.alttd.playerutils.config.Config;
public class Logger {
private final java.util.logging.Logger logger;
static private final String RESET = "\u001B[0m";
static private final String GREEN = "\u001B[32m";
static private final String TEAL = "\u001B[36m";
public Logger(java.util.logging.Logger logger) {
this.logger = logger;
}
public void debug(String debug, String... variables) {
if (!Config.SETTINGS.DEBUG)
return;
logger.info(TEAL + replace(debug, variables) + RESET);
}
public void info(String info, String... variables) {
logger.info(GREEN + replace(info, variables) + RESET);
}
public void warning(String warning, String... variables) {
if (!Config.SETTINGS.WARNINGS)
return;
logger.warning(replace(warning, variables));
}
public void severe(String severe, String... variables) {
logger.severe(replace(severe, variables));
}
private String replace(String text, String... variables) {
for (String variable : variables) {
text = text.replaceFirst("%", variable);
}
return text;
}
}