Added auto-updater, started to transfer Skript over, did the feather and freeze.

This commit is contained in:
wolf
2025-06-28 23:36:11 -04:00
parent d9967516b6
commit 0402d95f56
44 changed files with 1024 additions and 231 deletions

18
Uploader/build.gradle.kts Normal file
View File

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

View File

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

View File

@@ -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]
}

View File

@@ -1 +1,3 @@
rootProject.name = 'CloneDupeCore'
include 'Uploader'

View File

@@ -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() {

View File

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

View File

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

View File

@@ -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<Config> {
"screen"
));
public List<String> allowedFreezeCommands = new ArrayList<>(List.of("discord","unfreeze","unscreenshare"));
public List<String> freezeCommandsOnQuit = new ArrayList<>(List.of("punish {0} screen"));
public List<String> noStats = new ArrayList<>(List.of("CrystalEvent","Event"));
public List<String> getBanTemplateNames() {
return new ArrayList<>(banTemplates);
}
public SerialLocation freezeLocation = new SerialLocation("unset",0,64,0,0,0);
}

View File

@@ -14,7 +14,7 @@ public class NBTConfig implements JsonSerializable<NBTConfig> {
@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();

View File

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

View File

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

View File

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

View File

@@ -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 <player> <query|punish> [template]",
usage = "/offend <player> [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<String> 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<String> 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<WrappedEntry> allBans = liteBansManager.getPlayerBans(target);

View File

@@ -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 <player> <statistic> <add|subtract|set|get> [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 <player> <add|remove|set|get>"));
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")
)
)
);
}
}

View File

@@ -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 <global|self>",
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);
}
}

View File

@@ -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 <name>",
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<AbstractWand> 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()))
);
}
}

View File

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

View File

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

View File

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

View File

@@ -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("<green>Enabled</green>")
.build();
public ItemStack DISABLED = ItemBuilder.of(Material.RED_STAINED_GLASS_PANE)
.displayName("<red>Disabled</red>")
.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, "<blue><bold>Toggle Global", onToggleGlobal());
builder.itemMini(15, Material.ENDER_CHEST, "<blue><bold>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());
};
}
}

View File

@@ -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<UUID, FrozenPlayer> 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<UUID, FrozenPlayer> 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<OfflinePlayer> onQuit;
private final Consumer<Player> onMove;
public FrozenPlayer(JavaPlugin plugin, UUID uuid) {
public FrozenPlayer(UUID uuid, Location backLocation, Consumer<OfflinePlayer> onQuit, Consumer<Player> 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<Player> getOnMove() {
return onMove;
}
public Consumer<OfflinePlayer> getOnQuit() {
return onQuit;
}
public void teleportBack() {
Player player = Bukkit.getPlayer(uuid);
if (player == null) return;
player.teleport(backLocation);
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<Entity, ScheduledTask> entry : cleanupList.entrySet()) {
entry.getValue().cancel();
entry.getKey().remove();

View File

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

View File

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

View File

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

View File

@@ -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<Player> viewers, long loopTime);
public abstract void tickStationary(Player player, Set<Player> viewers, long loopTime);
public abstract void onRemove(Player player);
public abstract void onRemove(OfflinePlayer player);
}

View File

@@ -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<ValidMaterial, MaterialAnimation> animations = new EnumMap<>(ValidMaterial.class);
private final Map<UUID, ActiveTrim> 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());
}
}

View File

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

View File

@@ -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<BlockDisplay> displays = activeDisplays.remove(player.getUniqueId());
if (displays != null) {
for (BlockDisplay display : displays) {

View File

@@ -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<BlockDisplay> displays = activeDisplays.remove(player.getUniqueId());
if (displays != null) {
for (BlockDisplay display : displays) {

View File

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

View File

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

View File

@@ -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<ItemDisplay> displays = activeDisplays.remove(player.getUniqueId());
if (displays != null) {
for (ItemDisplay display : displays) {

View File

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

View File

@@ -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<BlockDisplay> displays = activeDisplays.remove(player.getUniqueId());
if (displays != null) {
for (BlockDisplay display : displays) {

View File

@@ -83,5 +83,5 @@ public class QuartzAnimation extends MaterialAnimation {
}
@Override
public void onRemove(Player player) {}
public void onRemove(OfflinePlayer player) {}
}

View File

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

View File

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

View File

@@ -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<ExplosionResult> 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) {

View File

@@ -24,6 +24,9 @@ commands:
clonedupecore:
usage: /clonedupecore <subcommand>
permission: clonedupe.admin
aliases:
- admin
- cdc
offend:
usage: "/offend <player> <query|punish> <offense>"
permission: clonedupe.offend
@@ -31,7 +34,38 @@ commands:
- punish
trimeffect:
usage: /trimeffect <global|self>
statedit:
usage: /statedit <player> <statistic> <value>
permission: clonedupe.statedit
freeze:
usage: /freeze <player>
permission: clonedupe.freeze
aliases:
- unfreeze
- screenshare
- ss
- unscreenshare
- setscreenshare
- setfreeze
wand:
usage: /wand <name>
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.