From 0402d95f561bcddd3943ff297b4bbbef547fa288 Mon Sep 17 00:00:00 2001 From: wolf Date: Sat, 28 Jun 2025 23:36:11 -0400 Subject: [PATCH] Added auto-updater, started to transfer Skript over, did the feather and freeze. --- Uploader/build.gradle.kts | 18 +++ .../java/me/trouper/uploader/Uploader.java | 89 ++++++++++++ build.gradle | 12 +- settings.gradle | 2 + .../trouper/clonedupecore/CloneDupeCore.java | 7 +- .../me/trouper/clonedupecore/data/Data.java | 3 + .../clonedupecore/data/SerialLocation.java | 35 +++++ .../trouper/clonedupecore/data/io/Config.java | 10 ++ .../clonedupecore/data/io/NBTConfig.java | 2 +- .../trouper/clonedupecore/server/Manager.java | 2 +- .../server/commands/AdminCommand.java | 46 +++++- .../server/commands/FreezeCommand.java | 123 ++++++++++++++++ .../server/commands/OffendCommand.java | 63 +++++---- .../server/commands/StatisticsCommand.java | 94 +++++++++++++ ...rimEffectCommand.java => TrimCommand.java} | 29 ++-- .../server/commands/WandCommand.java | 63 +++++++++ .../server/events/FreezeEvents.java | 75 ++++++++++ .../server/events/GamemodeEvent.java | 3 + .../server/events/StatisticEvent.java | 23 +++ .../server/gui/TrimEffectGui.java | 86 ++++++++++++ .../server/punishment/Freeze.java | 132 +++++++----------- .../punishment/animations/AnvilAnimation.java | 4 +- .../punishment/animations/GwenAnimation.java | 4 +- .../punishment/animations/LaserAnimation.java | 4 +- .../animations/LightningAnimation.java | 4 +- .../animations/MatrixAnimation.java | 4 +- .../server/scripts/DashWand.java | 19 +++ .../server/scripts/JailHeadWand.java | 48 +++++++ .../server/scripts/MobDisablers.java | 23 +++ .../server/trims/MaterialAnimation.java | 3 +- .../server/trims/TrimManager.java | 31 ++-- .../trims/animations/AmethystAnimation.java | 7 +- .../trims/animations/CopperAnimation.java | 7 +- .../trims/animations/DiamondAnimation.java | 7 +- .../trims/animations/EmeraldAnimation.java | 7 +- .../trims/animations/GoldAnimation.java | 7 +- .../trims/animations/IronAnimation.java | 7 +- .../trims/animations/LapisAnimation.java | 7 +- .../trims/animations/NetheriteAnimation.java | 7 +- .../trims/animations/QuartzAnimation.java | 2 +- .../trims/animations/RedstoneAnimation.java | 7 +- .../server/trolls/LiarTroll.java | 5 +- .../server/trolls/OrbitalTrollWand.java | 90 ++++++++---- src/main/resources/plugin.yml | 34 +++++ 44 files changed, 1024 insertions(+), 231 deletions(-) create mode 100644 Uploader/build.gradle.kts create mode 100644 Uploader/src/main/java/me/trouper/uploader/Uploader.java create mode 100644 src/main/java/me/trouper/clonedupecore/data/SerialLocation.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/commands/FreezeCommand.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/commands/StatisticsCommand.java rename src/main/java/me/trouper/clonedupecore/server/commands/{TrimEffectCommand.java => TrimCommand.java} (62%) create mode 100644 src/main/java/me/trouper/clonedupecore/server/commands/WandCommand.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/events/FreezeEvents.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/events/StatisticEvent.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/gui/TrimEffectGui.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/scripts/DashWand.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/scripts/JailHeadWand.java create mode 100644 src/main/java/me/trouper/clonedupecore/server/scripts/MobDisablers.java diff --git a/Uploader/build.gradle.kts b/Uploader/build.gradle.kts new file mode 100644 index 0000000..b469dcf --- /dev/null +++ b/Uploader/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("java") +} + +group = "me.trouper" +version = "1.0.0" + +repositories { + mavenCentral() +} + +dependencies { + implementation("com.github.mwiede:jsch:2.27.0") +} + +tasks.test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/Uploader/src/main/java/me/trouper/uploader/Uploader.java b/Uploader/src/main/java/me/trouper/uploader/Uploader.java new file mode 100644 index 0000000..df8bca2 --- /dev/null +++ b/Uploader/src/main/java/me/trouper/uploader/Uploader.java @@ -0,0 +1,89 @@ +package me.trouper.uploader; + +import com.jcraft.jsch.*; + +import java.io.File; +import java.io.FileInputStream; + +public class Uploader { + public static void main(String[] args) { + String sftpHost = "api.trouper.me"; + int sftpPort = 689; + String sftpUser = "root"; + String privateKeyPath = "/home/wolf/.ssh/deepfield_id_ed25519"; + String localFile = "/run/media/wolf/1TB drive/IJ/IdeaProjects/CloneDupeCore/build/libs/CloneDupeCore-1.0.0-all.jar"; + String remoteDir = "/home/cdn/files/plugins/CloneDupe/"; + + Session session = null; + ChannelSftp channelSftp = null; + + try { + JSch jsch = new JSch(); + jsch.addIdentity(privateKeyPath); + + session = jsch.getSession(sftpUser, sftpHost, sftpPort); + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(); + + Channel channel = session.openChannel("sftp"); + channel.connect(); + channelSftp = (ChannelSftp) channel; + + File file = new File(localFile); + channelSftp.cd(remoteDir); + + System.out.println("Uploading: " + file.getName()); + channelSftp.put( + new FileInputStream(file), + file.getName(), + new ProgressMonitor(file.length()), + ChannelSftp.OVERWRITE + ); + + System.out.println("\nUpload successful!"); + + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + if (channelSftp != null) channelSftp.exit(); + if (session != null) session.disconnect(); + } + } + + private static class ProgressMonitor implements SftpProgressMonitor { + private final long totalSize; + private long uploaded = 0; + private int lastPercent = -1; + + public ProgressMonitor(long totalSize) { + this.totalSize = totalSize; + } + + @Override + public void init(int op, String src, String dest, long max) { + System.out.println("Starting upload..."); + } + + @Override + public boolean count(long count) { + uploaded += count; + int percent = (int)((uploaded * 100) / totalSize); + if (percent != lastPercent) { + StringBuilder bar = new StringBuilder("\r["); + int progress = percent / 2; + for (int i = 0; i < 50; i++) { + bar.append(i < progress ? "=" : " "); + } + bar.append("] ").append(percent).append("%"); + System.out.print(bar); + lastPercent = percent; + } + return true; + } + + @Override + public void end() { + System.out.println("\nUpload complete."); + } + } +} diff --git a/build.gradle b/build.gradle index 1590204..c802a9d 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'me.trouper' -version = '1.0-SNAPSHOT' +version = '1.0.0' repositories { mavenCentral() @@ -75,4 +75,14 @@ processResources { shadowJar { minimize() +} + +task uploadPlugin(type: JavaExec) { + dependsOn(shadowJar) + + mainClass = 'me.trouper.uploader.Uploader' + classpath = project(':Uploader').sourceSets.main.runtimeClasspath + + def shadowJar = tasks.named("shadowJar").get().archiveFile.get().asFile + args = [shadowJar.absolutePath] } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 4ed8eb5..1285b65 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,3 @@ rootProject.name = 'CloneDupeCore' + +include 'Uploader' \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/CloneDupeCore.java b/src/main/java/me/trouper/clonedupecore/CloneDupeCore.java index bbc9deb..b456cd3 100644 --- a/src/main/java/me/trouper/clonedupecore/CloneDupeCore.java +++ b/src/main/java/me/trouper/clonedupecore/CloneDupeCore.java @@ -2,6 +2,7 @@ package me.trouper.clonedupecore; import com.github.retrooper.packetevents.PacketEvents; import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; +import me.trouper.alias.Alias; import me.trouper.clonedupecore.server.Manager; import org.bukkit.NamespacedKey; import org.bukkit.plugin.java.JavaPlugin; @@ -39,10 +40,14 @@ public final class CloneDupeCore extends JavaPlugin { public void onDisable() { getLogger().info("Cleaning up..."); manager.cleanup(); - getLogger().info("Saved all IO files."); + getLogger().info("Saving all IO files."); manager.io.saveAll(); + getLogger().info("Terminating PacketEventsAPI."); PacketEvents.getAPI().terminate(); + + getLogger().info("Stopping Alias."); + Alias.stop(getInstance(),getManager().common); } public static CloneDupeCore getInstance() { diff --git a/src/main/java/me/trouper/clonedupecore/data/Data.java b/src/main/java/me/trouper/clonedupecore/data/Data.java index f2dcc45..950d564 100644 --- a/src/main/java/me/trouper/clonedupecore/data/Data.java +++ b/src/main/java/me/trouper/clonedupecore/data/Data.java @@ -6,6 +6,9 @@ import me.trouper.clonedupecore.data.io.NBTConfig; import me.trouper.clonedupecore.data.io.Storage; public interface Data { + + Data data = new Data() {}; + default Config getConfig() { return CloneDupeCore.getInstance().getManager().io.config; } diff --git a/src/main/java/me/trouper/clonedupecore/data/SerialLocation.java b/src/main/java/me/trouper/clonedupecore/data/SerialLocation.java new file mode 100644 index 0000000..41d0ba8 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/data/SerialLocation.java @@ -0,0 +1,35 @@ +package me.trouper.clonedupecore.data; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +public record SerialLocation(String world, double x, double y, double z, float yaw, float pitch) { + public static Location translate(SerialLocation loc) { + World w = Bukkit.getWorld(loc.world()); + return new Location(w,loc.x(),loc.y(),loc.z(), loc.yaw(), loc.pitch()); + } + + public static SerialLocation translate(Location loc) { + return new SerialLocation(loc.getWorld().getName(),loc.x(),loc.y(),loc.z(), loc.getYaw(), loc.getPitch()); + } + + public Location translate() { + return translate(this); + } + + public boolean isSameLocation(Location loc) { + Location thisLoc = this.translate(); + return thisLoc.getWorld().equals(loc.getWorld()) && + thisLoc.getBlockX() == loc.getBlockX() && + thisLoc.getBlockY() == loc.getBlockY() && + thisLoc.getBlockZ() == loc.getBlockZ(); + } + + public boolean isSameLocation(SerialLocation loc) { + return this.world.equals(loc.world) && + (int) this.x == (int) loc.x && + (int) this.y == (int) loc.y && + (int) this.z == (int) loc.z; + } +} diff --git a/src/main/java/me/trouper/clonedupecore/data/io/Config.java b/src/main/java/me/trouper/clonedupecore/data/io/Config.java index d8951d3..70d91df 100755 --- a/src/main/java/me/trouper/clonedupecore/data/io/Config.java +++ b/src/main/java/me/trouper/clonedupecore/data/io/Config.java @@ -1,8 +1,10 @@ package me.trouper.clonedupecore.data.io; +import com.google.common.base.Predicates; import me.trouper.alias.data.JsonSerializable; import me.trouper.alias.server.systems.Verbose; import me.trouper.clonedupecore.CloneDupeCore; +import me.trouper.clonedupecore.data.SerialLocation; import java.io.File; import java.util.ArrayList; @@ -50,7 +52,15 @@ public class Config implements JsonSerializable { "screen" )); + public List allowedFreezeCommands = new ArrayList<>(List.of("discord","unfreeze","unscreenshare")); + + public List freezeCommandsOnQuit = new ArrayList<>(List.of("punish {0} screen")); + + public List noStats = new ArrayList<>(List.of("CrystalEvent","Event")); + public List getBanTemplateNames() { return new ArrayList<>(banTemplates); } + + public SerialLocation freezeLocation = new SerialLocation("unset",0,64,0,0,0); } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/data/io/NBTConfig.java b/src/main/java/me/trouper/clonedupecore/data/io/NBTConfig.java index d52d7a8..929ae1c 100644 --- a/src/main/java/me/trouper/clonedupecore/data/io/NBTConfig.java +++ b/src/main/java/me/trouper/clonedupecore/data/io/NBTConfig.java @@ -14,7 +14,7 @@ public class NBTConfig implements JsonSerializable { @Override public void save() { - CloneDupeCore.getInstance().getLogger().info("Saving Storage..."); + CloneDupeCore.getInstance().getLogger().info("Saving NBT Config..."); JsonSerializable.super.save(); } public RateLimit rateLimit = new RateLimit(); diff --git a/src/main/java/me/trouper/clonedupecore/server/Manager.java b/src/main/java/me/trouper/clonedupecore/server/Manager.java index 6389e46..431fccb 100644 --- a/src/main/java/me/trouper/clonedupecore/server/Manager.java +++ b/src/main/java/me/trouper/clonedupecore/server/Manager.java @@ -17,7 +17,7 @@ public class Manager { public Manager(JavaPlugin instance) { io = new IO(instance.getDataFolder()); - common = new Common(instance.getClass().getPackageName(),0xFF00AA,0xFFDDDD,"CloneDupeCore","CloneDupe> ",false); + common = new Common(instance.getClass().getPackageName(),0xFF00AA,0xFFDDDD,"CloneDupeCore","CloneDupe> ",false,"http://api.trouper.me:9090/download/plugins/CloneDupe/CloneDupeCore-1.0.0-all.jar"); trimManager = new TrimManager(); } diff --git a/src/main/java/me/trouper/clonedupecore/server/commands/AdminCommand.java b/src/main/java/me/trouper/clonedupecore/server/commands/AdminCommand.java index 6149463..4f9505e 100644 --- a/src/main/java/me/trouper/clonedupecore/server/commands/AdminCommand.java +++ b/src/main/java/me/trouper/clonedupecore/server/commands/AdminCommand.java @@ -6,7 +6,9 @@ import me.trouper.alias.server.commands.Permission; import me.trouper.alias.server.commands.QuickCommand; import me.trouper.alias.server.commands.completions.CompletionBuilder; import me.trouper.alias.server.systems.Text; +import me.trouper.alias.server.systems.tracing.BlockDisplayRaytracer; import me.trouper.alias.server.systems.visual.DisplayUtils; +import me.trouper.alias.update.AutoUpdater; import me.trouper.alias.utils.FormatUtils; import me.trouper.alias.utils.SoundPlayer; import me.trouper.clonedupecore.CloneDupeCore; @@ -14,12 +16,11 @@ import me.trouper.clonedupecore.data.Data; import me.trouper.clonedupecore.server.trims.ValidArmorType; import me.trouper.clonedupecore.server.trims.ValidMaterial; import net.kyori.adventure.text.format.TextDecoration; -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Sound; +import org.bukkit.*; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -42,6 +43,8 @@ public class AdminCommand implements QuickCommand, Data { case "debug" -> handleDebug(commandSender,args); case "trim" -> handleTrim(commandSender,args); case "reload" -> handleReload(commandSender,args); + case "cleanup" -> handleCleanup(commandSender,args); + case "update" -> handleUpdate(commandSender,args); } } @@ -70,9 +73,46 @@ public class AdminCommand implements QuickCommand, Data { b.argEnum(ValidArmorType.class) ) ) + ).then( + b.arg("update") + ).then( + b.arg("reload") + ).then( + b.arg("cleanup") ); } + private void handleUpdate(CommandSender sender, Args args) { + infoAny(sender,"Checking for an updated..."); + Bukkit.getScheduler().runTask(main.getPlugin(),()->{ + if (AutoUpdater.checkUpdate(main.getPlugin(),main.getCommon())) { + successAny(sender,"Updated plugin has been downloaded to {0}.","plugins/update"); + } else { + successAny(sender,"Plugin is up-to-date!"); + } + }); + + } + + private void handleCleanup(CommandSender sender, Args args) { + infoAny(sender,"Cleaning up temporary entities on all loaded worlds."); + Bukkit.getScheduler().runTask(main.getPlugin(),()->{ + int count = 0; + for (World world : Bukkit.getWorlds()) { + for (Chunk chunk : world.getLoadedChunks()) { + for (Entity entity : chunk.getEntities()) { + if (entity.getScoreboardTags().contains(main.getCommon().getTempTag())) { + entity.remove(); + count++; + } + } + } + } + if (count > 0) successAny(sender,"Successfully removed {0} temporary entities."); + else errorAny(sender,"Could not find any temporary entities."); + }); + } + private void handleReload(CommandSender sender, Args args) { successAny(sender,"Reloading IO and common..."); getIO().loadAll(); diff --git a/src/main/java/me/trouper/clonedupecore/server/commands/FreezeCommand.java b/src/main/java/me/trouper/clonedupecore/server/commands/FreezeCommand.java new file mode 100644 index 0000000..cc0b3ba --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/commands/FreezeCommand.java @@ -0,0 +1,123 @@ +package me.trouper.clonedupecore.server.commands; + +import me.trouper.alias.server.commands.Args; +import me.trouper.alias.server.commands.CommandRegistry; +import me.trouper.alias.server.commands.Permission; +import me.trouper.alias.server.commands.QuickCommand; +import me.trouper.alias.server.commands.completions.CompletionBuilder; +import me.trouper.alias.server.systems.Text; +import me.trouper.alias.utils.SoundPlayer; +import me.trouper.clonedupecore.data.Data; +import me.trouper.clonedupecore.data.SerialLocation; +import me.trouper.clonedupecore.server.punishment.Freeze; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.title.Title; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +@CommandRegistry( + value = "freeze", + permission = @Permission("clonedupe.freeze"), + printStackTrace = true, + usage = "/freeze " +) +public class FreezeCommand implements QuickCommand, Data { + + @Override + public void handleCommand(CommandSender sender, Command command, String label, Args args) { + if (label.equals("setfreeze") || label.equals("setscreenshare")) { + handleLocationUpdate(sender); + return; + } + + Player target = Bukkit.getPlayerExact(args.get(0).toString()); + if (target == null) { + errorAny(sender,"{0} is not a valid online player!",args.get(0).toString()); + return; + } + + boolean frozen = Freeze.getFrozen().containsKey(target.getUniqueId()) || "unfreeze".equals(label) || "unscreenshare".equals(label); + if (frozen) { + Freeze.thawPlayer(target.getUniqueId()); + infoAny(sender,"Completed ScreenShare/Freeze on {0}.",target.name()); + infoAny(target,"You have been released!"); + target.showTitle(Title.title( + Text.format(Text.Pallet.SUCCESS,"Screenshare Complete!").decorate(TextDecoration.BOLD), + Text.format(Text.Pallet.INFO,"Thank you for your cooperation."), + Title.Times.times(Duration.ZERO,Duration.of(3, ChronoUnit.SECONDS),Duration.ZERO) + )); + return; + } + + handleFreeze(sender,target); + } + + @Override + public void handleCompletion(CommandSender sender, Command command, String label, Args args, CompletionBuilder b) { + if (label.contains("set")) return; + b.then( + b.argOnlinePlayers() + ); + } + + private void handleFreeze(CommandSender sender, Player target) { + infoAny(sender,"Starting Screeenshare/Freeze on {0}.",target.name()); + + Location freezeLoc = target.getLocation(); + if (!"unset".equals(getConfig().freezeLocation.world())) { + freezeLoc = getConfig().freezeLocation.translate(); + } + + Title attemptTitle = Title.title( + Text.format(Text.Pallet.ERROR,"You are being Screenshared!").decorate(TextDecoration.BOLD), + Text.format(Text.Pallet.INFO,"Join the {0} VC using {1}!","'ScreenShare'", "/discord"), + Title.Times.times(Duration.ZERO,Duration.of(10, ChronoUnit.SECONDS),Duration.ZERO) + ); + + Component attemptMessage = Text.color(""" + &cLeaving before or during a ScreenShare results in: + &f➤ 1st Offense: 7d ban + &f➤ 2nd Offense: 14d ban + &f➤ 3rd Offense: 21d ban + + &cYou Have &l5 Minutes&r&c To Join '&4ScreenShare&c' VC. + """); + + Freeze.FrozenPlayer fp = new Freeze.FrozenPlayer(target.getUniqueId(), target.getLocation().clone(), (player)->{ + Freeze.thawPlayer(target.getUniqueId()); + getConfig().freezeCommandsOnQuit.forEach(cmd -> Bukkit.dispatchCommand(sender,cmd.replace("{0}",player.getName()))); + infoAny(sender,"{0} left while being Screenshared/Frozen, and has been punished as a result.",target.name()); + }, (player)->{ + player.showTitle(attemptTitle); + player.sendMessage(attemptMessage); + SoundPlayer.play(player, Sound.BLOCK_NOTE_BLOCK_BASS); + }); + + target.teleport(freezeLoc); + + Freeze.freezePlayer(fp); + } + + private void handleLocationUpdate(CommandSender sender) { + if (!(sender instanceof Player p)) { + errorAny(sender,"This command is for players only!"); + return; + } + if (!sender.hasPermission("clonedupe.setfreeze")) { + errorAny(sender,"You do not have permission to set the freeze location."); + return; + } + + getConfig().freezeLocation = new SerialLocation(p.getWorld().getName(),p.getX(),p.getY(),p.getZ(),p.getYaw(),p.getPitch()); + getConfig().save(); + successAny(p,"Successfully updated the freeze location."); + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/commands/OffendCommand.java b/src/main/java/me/trouper/clonedupecore/server/commands/OffendCommand.java index 24e6c67..8cddfb4 100644 --- a/src/main/java/me/trouper/clonedupecore/server/commands/OffendCommand.java +++ b/src/main/java/me/trouper/clonedupecore/server/commands/OffendCommand.java @@ -4,13 +4,12 @@ import club.minnced.discord.webhook.WebhookClient; import club.minnced.discord.webhook.WebhookClientBuilder; import club.minnced.discord.webhook.send.WebhookEmbed; import club.minnced.discord.webhook.send.WebhookEmbedBuilder; -import me.trouper.alias.server.commands.Args; -import me.trouper.alias.server.commands.CommandRegistry; -import me.trouper.alias.server.commands.Permission; -import me.trouper.alias.server.commands.QuickCommand; +import me.trouper.alias.server.commands.*; import me.trouper.alias.server.commands.completions.CompletionBuilder; +import me.trouper.alias.server.events.QuickListener; import me.trouper.alias.server.systems.Text; import me.trouper.alias.server.systems.Verbose; +import me.trouper.alias.utils.misc.ArrayUtils; import me.trouper.alias.utils.misc.TimeUtils; import me.trouper.clonedupecore.data.Data; import me.trouper.clonedupecore.server.punishment.LiteBansManager; @@ -21,20 +20,26 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; +import java.awt.desktop.QuitEvent; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @CommandRegistry( value = "offend", - usage = "/offend [template]", + usage = "/offend [template]", permission = @Permission("clonedupe.offend"), printStackTrace = true ) -public class OffendCommand implements QuickCommand, Data { +public class OffendCommand implements QuickCommandListener, Data { private final LiteBansManager liteBansManager = new LiteBansManager(); + private final List recentlyDisconnected = new ArrayList<>(); @Override public void handleCommand(CommandSender sender, Command command, String label, Args args) { @@ -50,42 +55,42 @@ public class OffendCommand implements QuickCommand, Data { return; } - String sub = args.get(1).toString(); String template = args.getSize() >= 3 ? args.get(2).toString() : null; - if ("query".equals(sub)) { - Bukkit.getScheduler().runTaskAsynchronously(main.getPlugin(), ()->{ - handleQuery(sender, target, template); - }); - } else if ("punish".equals(sub)) { - if (template == null) { - errorAny(sender, "You must specify a ban template!"); - return; - } - if (!getConfig().banTemplates.contains(template)) { - errorAny(sender, "That template is invalid! Available templates: " + - String.join(", ", getConfig().banTemplates)); - return; - } - Bukkit.getScheduler().runTaskAsynchronously(main.getPlugin(), ()->{ - handlePunish(sender, target, template); - }); + if (template == null) { + errorAny(sender, "You must specify a ban template!"); + return; } + if (!getConfig().banTemplates.contains(template)) { + errorAny(sender, "That template is invalid! Available templates: " + + String.join(", ", getConfig().banTemplates)); + return; + } + Bukkit.getScheduler().runTaskAsynchronously(main.getPlugin(), ()->{ + handlePunish(sender, target, template); + }); } @Override public void handleCompletion(CommandSender commandSender, Command command, String label, Args args, CompletionBuilder b) { + List players = ArrayUtils.map(Bukkit.getOnlinePlayers(),Player::getName); + players.addAll(recentlyDisconnected); b.then( - b.argOnlinePlayers() + b.arg(players) .then( - b.arg("query", "punish") - .then( - b.arg(getConfig().getBanTemplateNames()) - ) + b.arg(getConfig().getBanTemplateNames()) ) ); } + @EventHandler + public void onDisconnect(PlayerQuitEvent e) { + recentlyDisconnected.add(e.getPlayer().getName()); + Bukkit.getScheduler().runTaskLater(main.getPlugin(),()->{ + recentlyDisconnected.remove(e.getPlayer().getName()); + },20*120); + } + private void handleQuery(CommandSender sender, OfflinePlayer target, String template) { if (template == null) { List allBans = liteBansManager.getPlayerBans(target); diff --git a/src/main/java/me/trouper/clonedupecore/server/commands/StatisticsCommand.java b/src/main/java/me/trouper/clonedupecore/server/commands/StatisticsCommand.java new file mode 100644 index 0000000..d41cab1 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/commands/StatisticsCommand.java @@ -0,0 +1,94 @@ +package me.trouper.clonedupecore.server.commands; + +import me.trouper.alias.server.commands.Args; +import me.trouper.alias.server.commands.CommandRegistry; +import me.trouper.alias.server.commands.Permission; +import me.trouper.alias.server.commands.QuickCommand; +import me.trouper.alias.server.commands.completions.CompletionBuilder; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Statistic; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Arrays; + +@CommandRegistry( + value = "statedit", + permission = @Permission("clonedupe.statedit"), + usage = "/statedit [value]", + printStackTrace = true +) +public class StatisticsCommand implements QuickCommand { + @Override + public void handleCommand(CommandSender sender, Command command, String label, Args args) { + if (args.getSize() < 3) { + error(sender, Component.text("Usage: /statedit ")); + return; + } + + Player target = Bukkit.getPlayerExact(args.get(0).toString()); + if (target == null) { + error(sender, Component.text("Player not found.")); + return; + } + + Statistic stat; + try { + stat = Statistic.valueOf(args.get(1).toString().toUpperCase()); + } catch (IllegalArgumentException e) { + error(sender, Component.text("Invalid statistic type. Use tab for suggestions.")); + return; + } + + String sub = args.get(2).toString(); + + if (args.getSize() > 3) { + int value; + try { + value = args.get(3).toInt(); + } catch (NumberFormatException e) { + error(sender, Component.text("Value must be a number.")); + return; + } + switch (sub) { + case "set" -> { + target.setStatistic(stat, value); + success(sender, Component.text("Set {0} of {1} to {2}."),Component.text(stat.name()), target.name(),Component.text(value)); + } + case "add" -> { + target.incrementStatistic(stat, value); + success(sender, Component.text("Added {0} {1} to {2}. They now have {3} {0}"),Component.text(stat.name()), Component.text(value),target.name(),Component.text(target.getStatistic(stat))); + } + case "subtract" -> { + target.decrementStatistic(stat, value); + success(sender, Component.text("Subtracted {0} {1} from {2}. They now have {3} {0}"),Component.text(stat.name()),Component.text(value),target.name(),Component.text(target.getStatistic(stat))); + } + default -> { + value = target.getStatistic(stat); + success(sender, Component.text("The {0} of {1} is {2}.{"),Component.text(stat.name()),target.name(),Component.text(value)); + } + } + } else { + int value = target.getStatistic(stat); + success(sender, Component.text("The {0} of {1} is {2}"),Component.text(stat.name()),target.name(),Component.text(value)); + } + } + + @Override + public void handleCompletion(CommandSender sender, Command command, String label, Args args, CompletionBuilder b) { + b.then( + b.argOnlinePlayers() + .then( + b.argEnum(Statistic.class) + .then( + b.arg("add","remove","set") + .then(b.argInt("value")) + ).then( + b.arg("get") + ) + ) + ); + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/commands/TrimEffectCommand.java b/src/main/java/me/trouper/clonedupecore/server/commands/TrimCommand.java similarity index 62% rename from src/main/java/me/trouper/clonedupecore/server/commands/TrimEffectCommand.java rename to src/main/java/me/trouper/clonedupecore/server/commands/TrimCommand.java index a379eab..0b1d53d 100644 --- a/src/main/java/me/trouper/clonedupecore/server/commands/TrimEffectCommand.java +++ b/src/main/java/me/trouper/clonedupecore/server/commands/TrimCommand.java @@ -4,7 +4,9 @@ import me.trouper.alias.server.commands.Args; import me.trouper.alias.server.commands.CommandRegistry; import me.trouper.alias.server.commands.QuickCommand; import me.trouper.alias.server.commands.completions.CompletionBuilder; +import me.trouper.alias.server.systems.Verbose; import me.trouper.clonedupecore.data.Data; +import me.trouper.clonedupecore.server.gui.TrimEffectGui; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -12,31 +14,40 @@ import org.bukkit.entity.Player; @CommandRegistry( value = "trimeffect", usage = "/trimeffect ", consoleAllowed = false, - blocksAllowed = false + blocksAllowed = false, + printStackTrace = true ) -public class TrimEffectCommand implements QuickCommand, Data { +public class TrimCommand implements QuickCommand, Data { @Override public void handleCommand(CommandSender commandSender, Command command, String s, Args args) { Player p = (Player) commandSender; if (args.getSize() != 1) { - errorAny(commandSender,"Correct Usage: ", getRegistry().usage()); + new TrimEffectGui().open(p); return; } - if ("global".equals(args.get(0).toString())) { + + String mode = args.get(0).toString(); + if ("global".equalsIgnoreCase(mode)) { if (getStorage().disabledGlobalParticles.add(p.getUniqueId().toString())) { - successAny(commandSender,"Disabled global Trim effects."); + getStorage().save(); + successAny(p, "Disabled global Trim effects."); } else { getStorage().disabledGlobalParticles.remove(p.getUniqueId().toString()); - successAny(commandSender,"Enabled global Trim effects."); + getStorage().save(); + successAny(p, "Enabled global Trim effects."); } - } else { + } else if ("self".equalsIgnoreCase(mode)) { if (getStorage().disabledOwnParticles.add(p.getUniqueId().toString())) { - successAny(commandSender,"Disabled your own Trim effects."); + getStorage().save(); + successAny(p, "Disabled your own Trim effects."); } else { getStorage().disabledOwnParticles.remove(p.getUniqueId().toString()); - successAny(commandSender,"Enabled your own Trim effects."); + getStorage().save(); + successAny(p, "Enabled your own Trim effects."); } + } else { + new TrimEffectGui().open(p); } } diff --git a/src/main/java/me/trouper/clonedupecore/server/commands/WandCommand.java b/src/main/java/me/trouper/clonedupecore/server/commands/WandCommand.java new file mode 100644 index 0000000..190ad6e --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/commands/WandCommand.java @@ -0,0 +1,63 @@ +package me.trouper.clonedupecore.server.commands; + +import me.trouper.alias.Alias; +import me.trouper.alias.server.commands.Args; +import me.trouper.alias.server.commands.CommandRegistry; +import me.trouper.alias.server.commands.Permission; +import me.trouper.alias.server.commands.QuickCommand; +import me.trouper.alias.server.commands.completions.CompletionBuilder; +import me.trouper.alias.server.systems.AbstractWand; +import net.kyori.adventure.text.Component; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.stream.Collectors; + +import static me.trouper.alias.Alias.getAutoRegistrar; + +@CommandRegistry( + value = "wand", + usage = "/wand ", + permission = @Permission("clonedupe.getwand"), + consoleAllowed = false, + blocksAllowed = false +) +public class WandCommand implements QuickCommand { + + @Override + public void handleCommand(CommandSender sender, Command command, String label, Args args) { + if (!(sender instanceof Player player)) return; + + if (args.isEmpty()) { + error(sender, Component.text("You must specify a wand name.")); + return; + } + + String wandName = args.get(0).toString().toLowerCase(); + + List matches = getAutoRegistrar().getWands().stream() + .filter(w -> w.getClass().getSimpleName().toLowerCase().contains(wandName)) + .toList(); + + if (matches.isEmpty()) { + error(sender, Component.text("No wand found with name: " + wandName)); + return; + } + + AbstractWand wand = matches.get(0); + player.getInventory().addItem(wand.getWandItem()); + + success(sender, Component.text("Gave you the wand: " + wand.getClass().getSimpleName())); + } + + @Override + public void handleCompletion(CommandSender sender, Command command, String label, Args args, CompletionBuilder b) { + b.then( + b.arg(getAutoRegistrar().getWands().stream() + .map(w -> w.getClass().getSimpleName()) + .collect(Collectors.toList())) + ); + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/events/FreezeEvents.java b/src/main/java/me/trouper/clonedupecore/server/events/FreezeEvents.java new file mode 100644 index 0000000..c642eb3 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/events/FreezeEvents.java @@ -0,0 +1,75 @@ +package me.trouper.clonedupecore.server.events; + +import me.trouper.alias.server.events.QuickListener; +import me.trouper.clonedupecore.data.Data; +import me.trouper.clonedupecore.server.punishment.Freeze; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByBlockEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class FreezeEvents implements QuickListener { + @EventHandler + public void onMove(PlayerMoveEvent e) { + Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(e.getPlayer().getUniqueId()); + if (frozen == null) return; + + if (!e.getFrom().toVector().equals(e.getTo().toVector())) { + e.setTo(e.getFrom()); + } + if (frozen.getOnMove() != null) frozen.getOnMove().accept(e.getPlayer()); + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(e.getPlayer().getUniqueId()); + if (frozen == null) return; + + e.setCancelled(true); + if (frozen.getOnMove() != null) frozen.getOnMove().accept(e.getPlayer()); + } + + @EventHandler + public void onCommand(PlayerCommandPreprocessEvent e) { + Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(e.getPlayer().getUniqueId()); + if (frozen == null) return; + + String baseCmd = e.getMessage().replace("/", "").split(" ")[0].toLowerCase(); + if (!Data.data.getConfig().allowedFreezeCommands.contains(baseCmd)) { + e.setCancelled(true); + if (frozen.getOnMove() != null) frozen.getOnMove().accept(e.getPlayer()); + } + } + + @EventHandler + public void onDamageByEntity(EntityDamageByEntityEvent e) { + if (!(e.getEntity() instanceof Player p)) return; + Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(p.getUniqueId()); + if (frozen == null) return; + + e.setCancelled(true); + if (frozen.getOnMove() != null) frozen.getOnMove().accept(p); + } + + @EventHandler + public void onDamageByBlock(EntityDamageByBlockEvent e) { + if (!(e.getEntity() instanceof Player p)) return; + Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(p.getUniqueId()); + if (frozen == null) return; + + e.setCancelled(true); + if (frozen.getOnMove() != null) frozen.getOnMove().accept(p); + } + + @EventHandler + public void onQuit(PlayerQuitEvent e) { + Freeze.FrozenPlayer frozen = Freeze.getFrozen().get(e.getPlayer().getUniqueId()); + if (frozen == null) return; + + if (frozen.getOnQuit() != null) frozen.getOnQuit().accept(e.getPlayer()); + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/events/GamemodeEvent.java b/src/main/java/me/trouper/clonedupecore/server/events/GamemodeEvent.java index 305c733..381e10b 100644 --- a/src/main/java/me/trouper/clonedupecore/server/events/GamemodeEvent.java +++ b/src/main/java/me/trouper/clonedupecore/server/events/GamemodeEvent.java @@ -14,5 +14,8 @@ public class GamemodeEvent implements QuickListener { if (p.isOp()) return; p.setGameMode(GameMode.SURVIVAL); + p.setFlying(false); + p.setAllowFlight(false); + infoAny(p,"Flight has been disable when joining."); } } diff --git a/src/main/java/me/trouper/clonedupecore/server/events/StatisticEvent.java b/src/main/java/me/trouper/clonedupecore/server/events/StatisticEvent.java new file mode 100644 index 0000000..fc6cedd --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/events/StatisticEvent.java @@ -0,0 +1,23 @@ +package me.trouper.clonedupecore.server.events; + +import me.trouper.alias.server.events.QuickListener; +import me.trouper.clonedupecore.data.Data; +import org.bukkit.Statistic; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class StatisticEvent implements QuickListener, Data { + @EventHandler + public void onDeath(PlayerDeathEvent e) { + Player p = e.getPlayer(); + if (inExemptWorld(p)) { + if (p.getKiller() != null) p.getKiller().decrementStatistic(Statistic.PLAYER_KILLS); + e.getPlayer().decrementStatistic(Statistic.DEATHS); + } + } + + private boolean inExemptWorld(Player player) { + return getConfig().noStats.contains(player.getWorld().getName()); + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/gui/TrimEffectGui.java b/src/main/java/me/trouper/clonedupecore/server/gui/TrimEffectGui.java new file mode 100644 index 0000000..e2e0fd2 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/gui/TrimEffectGui.java @@ -0,0 +1,86 @@ +package me.trouper.clonedupecore.server.gui; + +import me.trouper.alias.server.systems.gui.QuickGui; +import me.trouper.alias.server.systems.gui.QuickGui.GuiAction; +import me.trouper.alias.utils.ItemBuilder; +import me.trouper.alias.utils.SoundPlayer; +import me.trouper.clonedupecore.data.Data; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Display; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.UUID; + +public class TrimEffectGui implements Data { + + + public void open(Player player) { + create(player.getUniqueId()).buildAndRegister("trim_effects").open(player); + } + + public ItemStack ENABLED = ItemBuilder.of(Material.LIME_STAINED_GLASS_PANE) + .displayName("Enabled") + .build(); + + public ItemStack DISABLED = ItemBuilder.of(Material.RED_STAINED_GLASS_PANE) + .displayName("Disabled") + .build(); + + public ItemStack EMPTY = ItemBuilder.of(Material.LIGHT_GRAY_STAINED_GLASS_PANE) + .displayName("") + .build(); + + private QuickGui.GuiBuilder create(UUID id) { + boolean globalDisabled = getStorage().disabledGlobalParticles.contains(id.toString()); + boolean selfDisabled = getStorage().disabledOwnParticles.contains(id.toString()); + + QuickGui.GuiBuilder builder = QuickGui.create(); + builder.title(Component.text("Trim Effect Settings")); + builder.rows(3); + + builder.fillSlots(globalDisabled ? DISABLED : ENABLED,null,1,2,3,10,12,19,20,21); + builder.fillSlots(selfDisabled ? DISABLED : ENABLED,null,5,6,7,14,16,23,24,25); + builder.itemMini(11, Material.GLASS_BOTTLE, "Toggle Global", onToggleGlobal()); + builder.itemMini(15, Material.ENDER_CHEST, "Toggle Self",onToggleSelf()); + + builder.fillEmpty(EMPTY); + + + return builder; + } + + private GuiAction onToggleGlobal() { + return (gui, event) -> { + Player p = (Player) event.getWhoClicked(); + String uuid = p.getUniqueId().toString(); + if (getStorage().disabledGlobalParticles.add(uuid)) { + SoundPlayer.play(p, Sound.UI_BUTTON_CLICK,1,0.5F); + } else { + getStorage().disabledGlobalParticles.remove(uuid); + SoundPlayer.play(p, Sound.UI_BUTTON_CLICK,1,1F); + } + getStorage().save(); + p.closeInventory(); + open(p); + }; + } + + private GuiAction onToggleSelf() { + return (gui, event) -> { + Player p = (Player) event.getWhoClicked(); + String uuid = p.getUniqueId().toString(); + if (getStorage().disabledOwnParticles.add(uuid)) { + SoundPlayer.play(p, Sound.UI_BUTTON_CLICK,1,0.5F); + } else { + getStorage().disabledOwnParticles.remove(uuid); + SoundPlayer.play(p, Sound.UI_BUTTON_CLICK,1,1F); + } + getStorage().save(); + p.closeInventory(); + open(p.getPlayer()); + }; + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/punishment/Freeze.java b/src/main/java/me/trouper/clonedupecore/server/punishment/Freeze.java index 9b6f1c6..15a6857 100644 --- a/src/main/java/me/trouper/clonedupecore/server/punishment/Freeze.java +++ b/src/main/java/me/trouper/clonedupecore/server/punishment/Freeze.java @@ -1,113 +1,77 @@ package me.trouper.clonedupecore.server.punishment; -import me.trouper.alias.server.Main; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByBlockEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.plugin.java.JavaPlugin; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; +import java.util.function.Consumer; + +public class Freeze { -public class Freeze implements Main { private static final Map FROZEN_PLAYERS = new HashMap<>(); - public static void freezePlayer(OfflinePlayer player) { + public static void quickFreeze(Player player) { UUID uuid = player.getUniqueId(); if (!FROZEN_PLAYERS.containsKey(uuid)) { - FrozenPlayer frozen = new FrozenPlayer(main.getPlugin(), uuid); + FrozenPlayer frozen = new FrozenPlayer(uuid, player.getLocation(), null, null); FROZEN_PLAYERS.put(uuid, frozen); } } - public static void thawPlayer(OfflinePlayer player) { - UUID uuid = player.getUniqueId(); - FrozenPlayer frozen = FROZEN_PLAYERS.remove(uuid); - if (frozen != null) { - frozen.thaw(); + public static void freezePlayer(FrozenPlayer player) { + UUID uuid = player.getUuid(); + if (!FROZEN_PLAYERS.containsKey(uuid)) { + FROZEN_PLAYERS.put(uuid, player); } } + public static void thawPlayer(UUID uuid) { + FROZEN_PLAYERS.remove(uuid).teleportBack(); + } + + public static Map getFrozen() { + return Collections.unmodifiableMap(FROZEN_PLAYERS); + } + + public static boolean isFrozen(UUID uuid) { + return FROZEN_PLAYERS.containsKey(uuid); + } + + public static FrozenPlayer get(UUID uuid) { + return FROZEN_PLAYERS.get(uuid); + } + public static class FrozenPlayer { - private final UUID uuid; - private final Listener listener; - private boolean frozen; + private final Location backLocation; + private final Consumer onQuit; + private final Consumer onMove; - public FrozenPlayer(JavaPlugin plugin, UUID uuid) { + public FrozenPlayer(UUID uuid, Location backLocation, Consumer onQuit, Consumer onMove) { this.uuid = uuid; - this.frozen = true; - - this.listener = new Listener() { - - @EventHandler - public void onPlayerMove(PlayerMoveEvent event) { - if (!event.getPlayer().getUniqueId().equals(uuid)) return; - if (!frozen) return; - - if (!event.getFrom().toVector().equals(event.getTo().toVector())) { - event.setTo(event.getFrom()); - } - } - - @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { - if (!event.getPlayer().getUniqueId().equals(uuid)) return; - if (!frozen) return; - - event.setCancelled(true); - } - - @EventHandler - public void onPlayerInteract(PlayerCommandPreprocessEvent event) { - if (!event.getPlayer().getUniqueId().equals(uuid)) return; - if (!frozen) return; - - event.setCancelled(true); - } - - @EventHandler - public void onPlayerDamage(EntityDamageByEntityEvent event) { - if (!event.getEntity().getUniqueId().equals(uuid)) return; - if (!frozen) return; - - event.setCancelled(true); - } - - @EventHandler - public void onPlayerDamage(EntityDamageByBlockEvent event) { - if (!event.getEntity().getUniqueId().equals(uuid)) return; - if (!frozen) return; - - event.setCancelled(true); - } - }; - - Bukkit.getPluginManager().registerEvents(listener, plugin); - } - - public void thaw() { - this.frozen = false; - HandlerList.unregisterAll(listener); - } - - public boolean isFrozen() { - return frozen; + this.backLocation = backLocation; + this.onQuit = onQuit; + this.onMove = onMove; } public UUID getUuid() { return uuid; } + + public Consumer getOnMove() { + return onMove; + } + + public Consumer getOnQuit() { + return onQuit; + } + + public void teleportBack() { + Player player = Bukkit.getPlayer(uuid); + if (player == null) return; + player.teleport(backLocation); + } } } diff --git a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/AnvilAnimation.java b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/AnvilAnimation.java index 7eb2980..51db657 100644 --- a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/AnvilAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/AnvilAnimation.java @@ -28,7 +28,7 @@ public class AnvilAnimation extends PunishmentAnimation { @Override protected void tick(int ticksElapsed) { - Freeze.freezePlayer(player); + Freeze.quickFreeze(player); if (!spawned) { spawnAnvilRing(); DisplayUtils.ring(player.getLocation().add(0,10,0),5,1,(point)->{ @@ -91,7 +91,7 @@ public class AnvilAnimation extends PunishmentAnimation { @Override protected void cleanup() { - Freeze.thawPlayer(player); + Freeze.thawPlayer(player.getUniqueId()); for (FallingBlock block : spawnedAnvils) { if (!block.isDead()) { block.remove(); diff --git a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/GwenAnimation.java b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/GwenAnimation.java index 8286905..d5dfc4e 100644 --- a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/GwenAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/GwenAnimation.java @@ -27,7 +27,7 @@ public class GwenAnimation extends PunishmentAnimation { @Override protected void tick(int ticksElapsed) { - Freeze.freezePlayer(player); + Freeze.quickFreeze(player); Location head = player.getEyeLocation(); Location center = head.clone().add(0, 3, 0); @@ -86,7 +86,7 @@ public class GwenAnimation extends PunishmentAnimation { @Override protected void cleanup() { - Freeze.thawPlayer(player); + Freeze.thawPlayer(player.getUniqueId()); for (Entity entity : guardians) { if (entity == null) continue; diff --git a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LaserAnimation.java b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LaserAnimation.java index 4c4e866..23e2620 100644 --- a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LaserAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LaserAnimation.java @@ -19,7 +19,7 @@ public class LaserAnimation extends PunishmentAnimation { @Override protected void tick(int ticksElapsed) { - Freeze.freezePlayer(player); + Freeze.quickFreeze(player); Location target = player.getEyeLocation(); Location center = player.getLocation(); @@ -59,6 +59,6 @@ public class LaserAnimation extends PunishmentAnimation { @Override protected void cleanup() { - Freeze.thawPlayer(player); + Freeze.thawPlayer(player.getUniqueId()); } } diff --git a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LightningAnimation.java b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LightningAnimation.java index e01ec9a..ea3a44f 100644 --- a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LightningAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/LightningAnimation.java @@ -21,7 +21,7 @@ public class LightningAnimation extends PunishmentAnimation { @Override protected void tick(int ticksElapsed) { - Freeze.freezePlayer(player); + Freeze.quickFreeze(player); Location cloudCenter = player.getLocation().clone().add(0,10,0); ParticleUtils.builder() .type(Particle.CLOUD) @@ -56,6 +56,6 @@ public class LightningAnimation extends PunishmentAnimation { @Override protected void cleanup() { - Freeze.thawPlayer(player); + Freeze.thawPlayer(player.getUniqueId()); } } diff --git a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/MatrixAnimation.java b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/MatrixAnimation.java index 753c66b..36ab121 100644 --- a/src/main/java/me/trouper/clonedupecore/server/punishment/animations/MatrixAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/punishment/animations/MatrixAnimation.java @@ -50,7 +50,7 @@ public class MatrixAnimation extends PunishmentAnimation{ ), Material.LIME_CONCRETE,Material.LIME_STAINED_GLASS); if (ticksElapsed != 1) return; - Freeze.freezePlayer(player); + Freeze.quickFreeze(player); DisplayUtils.sphereWave(center,5,0.5,2,(point)->{ TextDisplay display = point.getWorld().spawn(point,TextDisplay.class,(td)->{ @@ -88,7 +88,7 @@ public class MatrixAnimation extends PunishmentAnimation{ @Override protected void cleanup() { - Freeze.thawPlayer(player); + Freeze.thawPlayer(player.getUniqueId()); for (Map.Entry entry : cleanupList.entrySet()) { entry.getValue().cancel(); entry.getKey().remove(); diff --git a/src/main/java/me/trouper/clonedupecore/server/scripts/DashWand.java b/src/main/java/me/trouper/clonedupecore/server/scripts/DashWand.java new file mode 100644 index 0000000..272f352 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/scripts/DashWand.java @@ -0,0 +1,19 @@ +package me.trouper.clonedupecore.server.scripts; + +import me.trouper.alias.server.systems.AbstractWand; +import me.trouper.alias.utils.ItemBuilder; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class DashWand extends AbstractWand { + public DashWand() { + super("clonedupe.dash", ItemBuilder.of(Material.FEATHER) + .build()); + } + + @Override + protected void onRightClick(Player player) { + player.setVelocity(player.getVelocity().add(player.getEyeLocation().getDirection().normalize().multiply(2))); + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/scripts/JailHeadWand.java b/src/main/java/me/trouper/clonedupecore/server/scripts/JailHeadWand.java new file mode 100644 index 0000000..5d6bd52 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/scripts/JailHeadWand.java @@ -0,0 +1,48 @@ +package me.trouper.clonedupecore.server.scripts; + +import me.trouper.alias.server.events.QuickListener; +import me.trouper.alias.server.systems.AbstractWand; +import me.trouper.alias.server.systems.world.Snapshot; +import me.trouper.alias.utils.ItemBuilder; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.util.BoundingBox; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class JailHeadWand extends AbstractWand implements QuickListener { + public JailHeadWand() { + super("clonedupe.jailwand", ItemBuilder.of(Material.PLAYER_HEAD) + .build()); + } + + @Override + protected void onRightClick(Player player) { + + } + + private class Jail { + private final UUID prisoner; + private final List changedBlocks = new ArrayList<>(); + public Jail(Player prisoner) { + this.prisoner = prisoner.getUniqueId(); + Location loc = prisoner.getLocation(); + final int x = loc.getBlockX(); + final int y = loc.getBlockY(); + final int z = loc.getBlockZ(); + for (int dx = x - 1; dx < x + 1; dx++) { + for (int dy = y - 1; dy < y + 2; dy++) { + for (int dz = z - 1; dz < z + 1; dz++) { + Location pointer = loc.clone(); + pointer.setX(dx); + pointer.setY(dy); + pointer.setZ(dz); + } + } + } + } + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/scripts/MobDisablers.java b/src/main/java/me/trouper/clonedupecore/server/scripts/MobDisablers.java new file mode 100644 index 0000000..752d3f2 --- /dev/null +++ b/src/main/java/me/trouper/clonedupecore/server/scripts/MobDisablers.java @@ -0,0 +1,23 @@ +package me.trouper.clonedupecore.server.scripts; + +import me.trouper.alias.server.events.QuickListener; +import me.trouper.alias.server.events.custom.PlayerSpawnEntityEvent; +import org.bukkit.entity.Endermite; +import org.bukkit.entity.Wither; +import org.bukkit.event.EventHandler; + +public class MobDisablers implements QuickListener { + + @EventHandler + public void onSpawn(PlayerSpawnEntityEvent e) { + if (e.getSpawnedEntity() instanceof Wither w) { + w.remove(); + e.setCancelled(true); + infoAny(e.getPlayer(),"Nice try, withers are disabled."); + } + if (e.getSpawnedEntity() instanceof Endermite m) { + m.remove(); + e.setCancelled(true); + } + } +} diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/MaterialAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/MaterialAnimation.java index 2d10162..7e48e3d 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/MaterialAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/MaterialAnimation.java @@ -1,6 +1,7 @@ package me.trouper.clonedupecore.server.trims; import me.trouper.alias.server.Main; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import java.util.Set; @@ -24,5 +25,5 @@ public abstract class MaterialAnimation implements Main { public abstract void tickMoving(Player player, Set viewers, long loopTime); public abstract void tickStationary(Player player, Set viewers, long loopTime); - public abstract void onRemove(Player player); + public abstract void onRemove(OfflinePlayer player); } diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/TrimManager.java b/src/main/java/me/trouper/clonedupecore/server/trims/TrimManager.java index 40a1464..ff42576 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/TrimManager.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/TrimManager.java @@ -1,11 +1,15 @@ package me.trouper.clonedupecore.server.trims; import me.trouper.alias.server.Main; +import me.trouper.alias.server.events.QuickListener; import me.trouper.clonedupecore.data.Data; import me.trouper.clonedupecore.utils.ArmorUtils; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ArmorMeta; import org.bukkit.inventory.meta.ItemMeta; @@ -14,7 +18,7 @@ import org.bukkit.inventory.meta.trim.ArmorTrim; import java.util.*; import java.util.stream.Collectors; -public class TrimManager implements Main, Data { +public class TrimManager implements QuickListener, Data { private final Map animations = new EnumMap<>(ValidMaterial.class); private final Map activePlayers = new HashMap<>(); @@ -26,10 +30,7 @@ public class TrimManager implements Main, Data { public void tickPlayer(Player player) { UUID uuid = player.getUniqueId(); if (shouldHide(player)) { - if (activePlayers.containsKey(uuid)) { - animations.get(activePlayers.get(uuid).material).onRemove(player); - activePlayers.remove(uuid); - } + safeRemove(player); return; } @@ -38,10 +39,7 @@ public class TrimManager implements Main, Data { Location currentLocation = player.getLocation(); if (currentMaterial == null) { - if (activePlayers.containsKey(uuid)) { - animations.get(activePlayers.get(uuid).material).onRemove(player); - activePlayers.remove(uuid); - } + safeRemove(player); return; } @@ -55,9 +53,7 @@ public class TrimManager implements Main, Data { active.lastCheckedLocation = currentLocation; } else { active = new ActiveTrim(currentMaterial, currentLocation); - if (activePlayers.containsKey(uuid)) { - animations.get(activePlayers.get(uuid).material).onRemove(player); - } + safeRemove(player); activePlayers.put(uuid, active); } @@ -75,6 +71,12 @@ public class TrimManager implements Main, Data { } } + public void safeRemove(OfflinePlayer player) { + UUID id = player.getUniqueId(); + if (activePlayers.containsKey(id)) animations.get(activePlayers.get(id).material).onRemove(player); + activePlayers.remove(id); + } + public void startTicking() { Bukkit.getScheduler().runTaskTimer(main.getPlugin(), () -> Bukkit.getOnlinePlayers().forEach(this::tickPlayer),0,1); } @@ -128,4 +130,9 @@ public class TrimManager implements Main, Data { this.lastCheckedLocation = initialLocation; } } + + @EventHandler + public void onLeave(PlayerQuitEvent e) { + safeRemove(e.getPlayer()); + } } diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/AmethystAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/AmethystAnimation.java index 236bc23..1d27832 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/AmethystAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/AmethystAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.Player; import java.util.Set; @@ -73,5 +70,5 @@ public class AmethystAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) {} + public void onRemove(OfflinePlayer player) {} } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/CopperAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/CopperAnimation.java index de239f8..000b493 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/CopperAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/CopperAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.BlockDisplay; import org.bukkit.entity.Player; import org.bukkit.util.Transformation; @@ -111,7 +108,7 @@ public class CopperAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) { + public void onRemove(OfflinePlayer player) { List displays = activeDisplays.remove(player.getUniqueId()); if (displays != null) { for (BlockDisplay display : displays) { diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/DiamondAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/DiamondAnimation.java index c0e91a8..28b81e3 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/DiamondAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/DiamondAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.BlockDisplay; import org.bukkit.entity.Player; import org.bukkit.util.Transformation; @@ -113,7 +110,7 @@ public class DiamondAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) { + public void onRemove(OfflinePlayer player) { List displays = activeDisplays.remove(player.getUniqueId()); if (displays != null) { for (BlockDisplay display : displays) { diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/EmeraldAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/EmeraldAnimation.java index 440522f..a4383c5 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/EmeraldAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/EmeraldAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.util.Vector; @@ -81,5 +78,5 @@ public class EmeraldAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) {} + public void onRemove(OfflinePlayer player) {} } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/GoldAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/GoldAnimation.java index d3b3ce4..4a21bb3 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/GoldAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/GoldAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.Player; import java.util.Set; @@ -101,5 +98,5 @@ public class GoldAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) {} + public void onRemove(OfflinePlayer player) {} } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/IronAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/IronAnimation.java index 4078fd1..565652b 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/IronAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/IronAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.ItemDisplay; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -137,7 +134,7 @@ public class IronAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) { + public void onRemove(OfflinePlayer player) { List displays = activeDisplays.remove(player.getUniqueId()); if (displays != null) { for (ItemDisplay display : displays) { diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/LapisAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/LapisAnimation.java index 075c951..09781a7 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/LapisAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/LapisAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.Player; import java.util.Set; @@ -135,5 +132,5 @@ public class LapisAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) {} + public void onRemove(OfflinePlayer player) {} } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/NetheriteAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/NetheriteAnimation.java index b3bab20..1b99b81 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/NetheriteAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/NetheriteAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.BlockDisplay; import org.bukkit.entity.Player; import org.bukkit.util.Transformation; @@ -134,7 +131,7 @@ public class NetheriteAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) { + public void onRemove(OfflinePlayer player) { List displays = activeDisplays.remove(player.getUniqueId()); if (displays != null) { for (BlockDisplay display : displays) { diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/QuartzAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/QuartzAnimation.java index 25e8f36..89d7171 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/QuartzAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/QuartzAnimation.java @@ -83,5 +83,5 @@ public class QuartzAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) {} + public void onRemove(OfflinePlayer player) {} } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/server/trims/animations/RedstoneAnimation.java b/src/main/java/me/trouper/clonedupecore/server/trims/animations/RedstoneAnimation.java index ba2c561..86e22b1 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trims/animations/RedstoneAnimation.java +++ b/src/main/java/me/trouper/clonedupecore/server/trims/animations/RedstoneAnimation.java @@ -4,10 +4,7 @@ import me.trouper.alias.server.systems.visual.DisplayUtils; import me.trouper.alias.server.systems.visual.ParticleUtils; import me.trouper.clonedupecore.server.trims.MaterialAnimation; import me.trouper.clonedupecore.server.trims.ValidMaterial; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Particle; +import org.bukkit.*; import org.bukkit.entity.Player; import java.util.Set; @@ -124,5 +121,5 @@ public class RedstoneAnimation extends MaterialAnimation { } @Override - public void onRemove(Player player) {} + public void onRemove(OfflinePlayer player) {} } \ No newline at end of file diff --git a/src/main/java/me/trouper/clonedupecore/server/trolls/LiarTroll.java b/src/main/java/me/trouper/clonedupecore/server/trolls/LiarTroll.java index 82c9208..7e686b2 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trolls/LiarTroll.java +++ b/src/main/java/me/trouper/clonedupecore/server/trolls/LiarTroll.java @@ -6,6 +6,7 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSe import io.github.retrooper.packetevents.util.SpigotConversionUtil; import me.trouper.alias.server.systems.Text; import me.trouper.alias.utils.ItemBuilder; +import me.trouper.alias.utils.SoundPlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextDecoration; @@ -90,10 +91,10 @@ public class LiarTroll implements TrollFeature { Title.Times.times(Duration.of(0, ChronoUnit.SECONDS),Duration.of(1, ChronoUnit.SECONDS),Duration.of(0, ChronoUnit.SECONDS))) ; ItemStack pants = displayItem.withType(Material.WHITE_WOOL); - target.getWorld().playSound(target.getLocation(), Sound.BLOCK_NOTE_BLOCK_BIT, SoundCategory.MASTER,10,2F); + SoundPlayer.play(target, Sound.BLOCK_NOTE_BLOCK_BIT, 10,2F); packet.setStack(SpigotConversionUtil.fromBukkitItemStack(pants)); } else { - target.getWorld().playSound(target.getLocation(), Sound.BLOCK_NOTE_BLOCK_BIT, SoundCategory.MASTER,10,1.5F); + SoundPlayer.play(target, Sound.BLOCK_NOTE_BLOCK_BIT, 10,1.5F); } t.sendPacket(packet); diff --git a/src/main/java/me/trouper/clonedupecore/server/trolls/OrbitalTrollWand.java b/src/main/java/me/trouper/clonedupecore/server/trolls/OrbitalTrollWand.java index 4c49325..a1d05d6 100644 --- a/src/main/java/me/trouper/clonedupecore/server/trolls/OrbitalTrollWand.java +++ b/src/main/java/me/trouper/clonedupecore/server/trolls/OrbitalTrollWand.java @@ -17,6 +17,7 @@ import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.*; import org.bukkit.command.CommandSender; import org.bukkit.entity.BlockDisplay; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitRunnable; @@ -79,6 +80,7 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { private final Component SUCCESS_AIM = Component.text("You can now aim the Ion Cannon."); private final Component ERROR_NOT_CONTROLLING = Component.text("You are not controlling the Ion Cannon."); private final Component SUCCESS_DEACTIVATED = Component.text("Deactivated Ion Cannon Safely."); + private final Integer MAX_POWER = 30; private boolean undoHistory(Player player) { Stack history = playerHistory.get(player.getUniqueId()); @@ -101,6 +103,9 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { if (undoHistory(player)) { Text.message(Text.Pallet.SUCCESS, false, player, SUCCESS_RESTORE); SoundPlayer.play(player, Sound.ENTITY_ILLUSIONER_PREPARE_BLINDNESS, 10, 1); + } else if (cannonMap.containsKey(player.getUniqueId())) { + cannonMap.get(player.getUniqueId()).destroy(); + Text.message(Text.Pallet.SUCCESS, false, player, SUCCESS_DEACTIVATED); } else { Text.message(Text.Pallet.ERROR, false, player, ERROR_EMPTY_STACK); } @@ -118,11 +123,9 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { if (playerCannon != null) { if (playerCannon.getFireTask() != null || playerCannon.getChargeTask() != null) { Text.message(Text.Pallet.ERROR, false, player, ERROR_ALREADY_CHARGING); - cannonMap.remove(playerId); return; } playerCannon.charge(); - cannonMap.remove(playerId); Text.message(Text.Pallet.SUCCESS, false, player, SUCCESS_CHARGING); return; } @@ -175,13 +178,7 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { return; } - if (cannon.getPower() >= 50) { - SoundPlayer.play(player, Sound.BLOCK_NOTE_BLOCK_HAT, 1, 1.3F); - cannon.setPower(49); - return; - } - - cannon.setPower(Math.min(50, cannon.getPower() + 5)); + cannon.setPower(Math.min(MAX_POWER, cannon.getPower() + 5)); SoundPlayer.play(player, Sound.BLOCK_NOTE_BLOCK_HAT, 1, 0.8F); player.sendActionBar(Text.format(Text.Pallet.INFO, "Set ion cannon power to {0}.", cannon.getPower())); @@ -201,25 +198,41 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { private int power; private ExplosionResult explosionResult; - private final BukkitTask tickTask = new BukkitRunnable() { + private BukkitTask tickTask = new BukkitRunnable() { + + final int expireTicks = 20 * 60; + int ticksElapsed = 0; + @Override public void run() { - if (owner == null || !owner.isOnline()) { + try { + if (owner == null || !owner.isOnline() || ticksElapsed > expireTicks || (getExplosionResult() != null && (getExplosionResult().getPreviousState() == null || explosionResult.getPreviousState().isClosed()))) { + destroy(); + this.cancel(); + return; + } + } catch (Exception e) { + e.printStackTrace(); destroy(); + this.cancel(); return; } + updateOrbitLocation(); setSkyRenderLocation(getSimulatedOrbit().getRenderLocation(getTargetLocation())); - setSkyTraceLocation(CustomDisplayRaytracer.blocksInFrontOf(getTargetLocation(), getSimulatedOrbit().getNormalToSatellite(getTargetLocation().toVector()), 20, false).getLoc()); + setSkyTraceLocation(CustomDisplayRaytracer.blocksInFrontOf(getTargetLocation(), getSimulatedOrbit().getNormalToSatellite(getTargetLocation().toVector()), Math.max(5,power), false).getLoc()); if (aimTask != null && !aimTask.isCancelled()) { setTargetLocation(traceTargets(getOwner())); - setGroundTraced(CustomDisplayRaytracer.trace(getSkyTraceLocation(), getTargetLocation(), 5, (point) -> { - Material type = point.getLoc().getBlock().getType(); - return type.isCollidable(); - }).getLoc()); } + + setGroundTraced(CustomDisplayRaytracer.trace(getSkyTraceLocation(), getTargetLocation().clone().toVector().subtract(getSkyTraceLocation().clone().toVector()),Math.max(5,power), 5, (point) -> { + Material type = point.getLoc().getBlock().getType(); + return type.isCollidable(); + }).getLoc()); + + ticksElapsed++; } }.runTaskTimer(main.getPlugin(), 0, 1); @@ -228,7 +241,7 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { this.ownerId = owner.getUniqueId(); this.targetLocation = target; this.power = 20; - this.simulatedOrbit = new OrbitalConfiguration(target.toVector()); + this.simulatedOrbit = new OrbitalConfiguration(target.toVector().clone().add(new Vector(random().nextInt(-30_000_000,30_000_000),target.getY(),random().nextInt(-30_000_000,30_000_000)))); this.setAimTask(aimRunnable.runTaskTimer(main.getPlugin(), 0, 1)); } @@ -237,7 +250,7 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { @Override public void run() { - if (ticksElapsed >= 120) { + if (ticksElapsed >= 120 + getPower() * 2) { if (getExplosionResult() != null && getExplosionResult().getTaskManager() != null && !getExplosionResult().getTaskManager().isClosed()) { getExplosionResult().getTaskManager().close(); } @@ -255,8 +268,8 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { if (ticksElapsed == 0) { ExplosionOptions options = new ExplosionOptions() .setMaxBurnRadius(getPower()) - .setFalloffRadius((double) getPower() / 3) - .setCoreRadius(((double) getPower() / 3) / 1.2) + .setFalloffRadius((double) getPower() / 2) + .setCoreRadius(((double) getPower() / 2.5)) .setBaseDamage(120) .setBurnDelay(0) .setDestructionDelay(1); @@ -278,7 +291,9 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { final int delay = 40; if (ticksElapsed >= delay) { setFireTask(fireRunnable.runTaskTimer(main.getPlugin(), 0, 1)); + cannonMap.remove(ownerId); this.cancel(); + chargeTask = null; return; } @@ -309,6 +324,7 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { public void run() { if (getChargeTask() != null) { this.cancel(); + aimTask = null; return; } @@ -334,10 +350,22 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { } private void destroy() { - if (tickTask != null && !tickTask.isCancelled()) tickTask.cancel(); - if (fireTask != null && !fireTask.isCancelled()) fireTask.cancel(); - if (chargeTask != null && !chargeTask.isCancelled()) chargeTask.cancel(); - if (aimTask != null && !aimTask.isCancelled()) aimTask.cancel(); + if (tickTask != null && !tickTask.isCancelled()) { + tickTask.cancel(); + tickTask = null; + } + if (fireTask != null && !fireTask.isCancelled()) { + fireTask.cancel(); + fireTask = null; + } + if (chargeTask != null && !chargeTask.isCancelled()) { + chargeTask.cancel(); + chargeTask = null; + } + if (aimTask != null && !aimTask.isCancelled()) { + aimTask.cancel(); + aimTask = null; + } cannonMap.remove(ownerId); } @@ -387,8 +415,10 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { new Vector(-60_000_000, 0, 60_000_000) // negXPosZ }; - private final Vector tempVector1 = new Vector(); + private final int SPEED_MULTIPLIER = 1; + private final Vector tempVector1 = new Vector(2_500 * SPEED_MULTIPLIER,0,762 * SPEED_MULTIPLIER); private final Vector tempVector2 = new Vector(); + private final Vector tempVector3 = new Vector(); private final Vector[] satellites = new Vector[9]; public OrbitalConfiguration(Vector center) { @@ -401,12 +431,10 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { public void tick() { Vector orbitalLocation = getBaseSatellite(); if (orbitalLocation.getX() > 30_000_000 || orbitalLocation.getZ() > 30_000_000) { - setBaseSatellite(tempVector1.setX(-orbitalLocation.getX()).setY(orbitalLocation.getY()).setZ(-orbitalLocation.getZ())); - return; + baseSatellite.setX(-orbitalLocation.getX()).setY(11_368_121).setZ(-orbitalLocation.getZ()); + } else { + baseSatellite.add(tempVector1).setY(11_368_121); } - - tempVector1.setX(2_500).setY(0).setZ(762); - setBaseSatellite(orbitalLocation.clone().add(tempVector1)); } public Location getRenderLocation(Location center) { @@ -422,7 +450,7 @@ public class OrbitalTrollWand extends AbstractWand implements TrollFeature { public Vector getNormalToTarget(Vector target) { Vector closestSatellite = getClosestSatellite(target); - return tempVector2.copy(target).subtract(closestSatellite).normalize(); + return tempVector3.copy(target).subtract(closestSatellite).normalize(); } public Vector getClosestSatellite(Vector location) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ae4a980..25e065e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -24,6 +24,9 @@ commands: clonedupecore: usage: /clonedupecore permission: clonedupe.admin + aliases: + - admin + - cdc offend: usage: "/offend " permission: clonedupe.offend @@ -31,7 +34,38 @@ commands: - punish trimeffect: usage: /trimeffect + statedit: + usage: /statedit + permission: clonedupe.statedit + freeze: + usage: /freeze + permission: clonedupe.freeze + aliases: + - unfreeze + - screenshare + - ss + - unscreenshare + - setscreenshare + - setfreeze + wand: + usage: /wand + permission: clonedupe.getwand permissions: + clonedupe.getwand: + default: op + description: Get any AbstractWand registered. + clonedupe.dash: + default: op + description: Allows player to use a feather to dash. + clonedupe.freeze: + default: op + description: allows staff to freeze players with an auto-ban on leave. + clonedupe.setfreeze: + default: op + description: allows you to set a fixed freeze locations players get teleported to. + clonedupe.statedit: + default: op + description: Edit Statistics clonedupe.troll: default: op description: Allows a player to use troll features and the troll wand.