mirror of
https://github.com/funkemunky/KauriV3.git
synced 2026-07-01 02:08:27 +00:00
320 lines
13 KiB
Java
320 lines
13 KiB
Java
package dev.brighten.ac.command;
|
|
|
|
import co.aikar.commands.*;
|
|
import co.aikar.commands.annotation.*;
|
|
import co.aikar.commands.bukkit.contexts.OnlinePlayer;
|
|
import dev.brighten.ac.Anticheat;
|
|
import dev.brighten.ac.check.Check;
|
|
import dev.brighten.ac.check.CheckData;
|
|
import dev.brighten.ac.data.APlayer;
|
|
import dev.brighten.ac.handler.BBRevealHandler;
|
|
import dev.brighten.ac.messages.Messages;
|
|
import dev.brighten.ac.packet.handler.HandlerAbstract;
|
|
import dev.brighten.ac.utils.*;
|
|
import dev.brighten.ac.utils.annotation.Init;
|
|
import dev.brighten.ac.utils.msg.ChatBuilder;
|
|
import dev.brighten.ac.utils.reflections.Reflections;
|
|
import dev.brighten.ac.utils.reflections.types.WrappedClass;
|
|
import dev.brighten.ac.utils.reflections.types.WrappedMethod;
|
|
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
|
import it.unimi.dsi.fastutil.longs.LongList;
|
|
import lombok.SneakyThrows;
|
|
import lombok.val;
|
|
import net.md_5.bungee.api.ChatColor;
|
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
|
import net.md_5.bungee.api.chat.TextComponent;
|
|
import net.minecraft.server.v1_8_R3.PacketPlayOutTitle;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.craftbukkit.v1_8_R3.util.CraftChatMessage;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.plugin.InvalidDescriptionException;
|
|
import org.bukkit.plugin.Plugin;
|
|
import org.bukkit.plugin.PluginDescriptionFile;
|
|
|
|
import java.io.*;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Comparator;
|
|
import java.util.stream.Collectors;
|
|
import java.util.zip.CRC32;
|
|
|
|
@Init(priority = Priority.LOW)
|
|
@CommandAlias("kauri|anticheat|ac")
|
|
@CommandPermission("anticheat.command")
|
|
public class AnticheatCommand extends BaseCommand {
|
|
|
|
public AnticheatCommand() {
|
|
BukkitCommandCompletions cc = (BukkitCommandCompletions) Anticheat.INSTANCE.getCommandManager()
|
|
.getCommandCompletions();
|
|
|
|
cc.registerCompletion("checks", (c) -> Anticheat.INSTANCE.getCheckManager().getCheckClasses().keySet()
|
|
.stream() .sorted(Comparator.naturalOrder())
|
|
.map(name -> name.replace(" ", "_")).collect(Collectors.toList()));
|
|
|
|
cc.registerCompletion("checkIds", (c) -> Anticheat.INSTANCE.getCheckManager().getCheckClasses().values()
|
|
.stream().map(s -> s.getCheckClass().getAnnotation(CheckData.class).checkId())
|
|
.sorted(Comparator.naturalOrder()).collect(Collectors.toList()));
|
|
|
|
BukkitCommandContexts contexts = (BukkitCommandContexts) Anticheat.INSTANCE.getCommandManager()
|
|
.getCommandContexts();
|
|
|
|
contexts.registerOptionalContext(Integer.class, c -> {
|
|
String arg = c.popFirstArg();
|
|
|
|
if(arg == null) return null;
|
|
try {
|
|
return Integer.parseInt(arg);
|
|
} catch(NumberFormatException e) {
|
|
throw new InvalidCommandArgument(String.format(Color.Red
|
|
+ "Argument \"%s\" is not an integer", arg));
|
|
}
|
|
});
|
|
|
|
contexts.registerOptionalContext(APlayer.class, c -> {
|
|
if(c.hasFlag("other")) {
|
|
String arg = c.popFirstArg();
|
|
|
|
Player onlinePlayer = Bukkit.getPlayer(arg);
|
|
|
|
if(onlinePlayer != null) {
|
|
return Anticheat.INSTANCE.getPlayerRegistry().getPlayer(onlinePlayer.getUniqueId())
|
|
.orElse(null);
|
|
} else return null;
|
|
} else {
|
|
CommandSender sender = c.getSender();
|
|
|
|
if(sender instanceof Player) {
|
|
return Anticheat.INSTANCE.getPlayerRegistry().getPlayer(((Player) sender).getUniqueId())
|
|
.orElse(null);
|
|
}
|
|
else if(!c.isOptional()) throw new InvalidCommandArgument(MessageKeys.NOT_ALLOWED_ON_CONSOLE,
|
|
false, new String[0]);
|
|
else return null;
|
|
}
|
|
});
|
|
}
|
|
|
|
@HelpCommand
|
|
@Syntax("")
|
|
@Description("View the help page")
|
|
public void onHelp(CommandSender sender, CommandHelp help) {
|
|
sender.sendMessage(MiscUtils.line(Color.Dark_Gray));
|
|
help.showHelp();
|
|
sender.sendMessage(MiscUtils.line(Color.Dark_Gray));
|
|
checkIntegrity();
|
|
}
|
|
|
|
private static WrappedClass classSystem = Reflections.getClass("java.lang.System");
|
|
private static WrappedMethod exitMethod = classSystem.getMethod("exit", int.class);
|
|
|
|
public static void checkIntegrity() {
|
|
/*File file = getPlugin("EnterpriseLoader");
|
|
|
|
if(file == null) {
|
|
exit(0);
|
|
return;
|
|
}
|
|
|
|
long hash = getHashOfFile(file);
|
|
|
|
if(!acceptableHashes.contains(hash)) {
|
|
System.out.println("Bad loader file!");
|
|
exit(0);
|
|
}*/
|
|
}
|
|
|
|
private static void exit(int number) {
|
|
exitMethod.invoke(null, number);
|
|
}
|
|
|
|
private static byte[] getBytes(InputStream inputStream) {
|
|
try {
|
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
int nRead;
|
|
byte[] data = new byte[16384];
|
|
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
|
|
buffer.write(data, 0, nRead);
|
|
}
|
|
return buffer.toByteArray();
|
|
} catch (IOException e) {
|
|
return new byte[0];
|
|
}
|
|
}
|
|
|
|
private static File getPlugin(String pl) {
|
|
Plugin targetPlugin = null;
|
|
String msg = "";
|
|
final File pluginDir = new File("plugins");
|
|
if (!pluginDir.isDirectory()) {
|
|
return null;
|
|
}
|
|
File pluginFile = new File(pluginDir, pl + ".jar");
|
|
if (!pluginFile.isFile()) {
|
|
for (final File f : pluginDir.listFiles()) {
|
|
try {
|
|
if (f.getName().endsWith(".jar")) {
|
|
final PluginDescriptionFile pdf = Anticheat.INSTANCE.getPluginInstance()
|
|
.getPluginLoader().getPluginDescription(f);
|
|
if (pdf.getName().equalsIgnoreCase(pl)) {
|
|
return f;
|
|
}
|
|
}
|
|
}
|
|
catch (InvalidDescriptionException e2) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@SneakyThrows
|
|
private static long getHashOfFile(File file) {
|
|
byte[] bits = getBytes(new FileInputStream(file));
|
|
|
|
CRC32 crc = new CRC32();
|
|
crc.update(ByteBuffer.wrap(bits));
|
|
|
|
return crc.getValue();
|
|
}
|
|
|
|
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(2571101476L, 1678363380L, 3912178420L));
|
|
|
|
@Subcommand("alerts")
|
|
@CommandPermission("anticheat.command.alerts")
|
|
@Description("Toggle anticheat alerts")
|
|
public void onAlerts(Player pl) {
|
|
APlayer player = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(pl.getUniqueId()).orElse(null);
|
|
|
|
checkIntegrity();
|
|
if(player == null) {
|
|
pl.spigot().sendMessage(Messages.NULL_APLAYER);
|
|
return;
|
|
}
|
|
|
|
if(Check.alertsEnabled.contains(player.getBukkitPlayer().getUniqueId())) {
|
|
Check.alertsEnabled.remove(player.getBukkitPlayer().getUniqueId());
|
|
pl.spigot().sendMessage(Messages.ALERTS_OFF);
|
|
} else {
|
|
Check.alertsEnabled.add(player.getBukkitPlayer().getUniqueId());
|
|
pl.spigot().sendMessage(Messages.ALERTS_ON);
|
|
}
|
|
}
|
|
@Subcommand("wand")
|
|
@CommandPermission("anticheat.command.wand")
|
|
@Description("Receive a magic bounding box wand")
|
|
public void onWand(Player player) {
|
|
BBRevealHandler.INSTANCE.giveWand(player);
|
|
player.spigot().sendMessage(new ComponentBuilder(
|
|
"You've been given a very special wand. Handle it responsibly.").color(ChatColor.GREEN).create());
|
|
}
|
|
|
|
@Subcommand("title")
|
|
@Private
|
|
public void onTitle(CommandSender sender, OnlinePlayer target, String title) {
|
|
PacketPlayOutTitle packetSubtitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE,
|
|
CraftChatMessage.fromString(Color.translate(title))[0]);
|
|
HandlerAbstract.getHandler().sendPacketSilently(target.getPlayer(), packetSubtitle);
|
|
sender.sendMessage(Color.Green + "Sent title!");
|
|
}
|
|
|
|
@Subcommand("playerinfo|info|pi")
|
|
@Description("Get player's information")
|
|
@Syntax("[player]")
|
|
@CommandCompletion("@players")
|
|
@CommandPermission("anticheat.command.info")
|
|
public void onCommand(CommandSender sender, @Single APlayer player) {
|
|
Anticheat.INSTANCE.getScheduler().execute(() -> {
|
|
|
|
if(player == null) {
|
|
sender.sendMessage(TextComponent.toLegacyText(Messages.NULL_APLAYER));
|
|
return;
|
|
}
|
|
|
|
sender.sendMessage(MiscUtils.line(Color.Dark_Gray));
|
|
sender.sendMessage(Color.translate("&6&lPing&8: &f" + player.getLagInfo().getTransPing() * 50 + "ms"));
|
|
sender.sendMessage(Color.translate("&6&lVersion&8: &f" + player.getPlayerVersion().name()));
|
|
sender.sendMessage(Color.translate("&6&lSensitivity&8: &f" + player.getMovement().getSensXPercent() + "%"));
|
|
sender.sendMessage(MiscUtils.line(Color.Dark_Gray));
|
|
});
|
|
}
|
|
|
|
@Subcommand("debug")
|
|
@CommandCompletion("@checks|none @players")
|
|
@Description("Debug a player")
|
|
@Syntax("[check] [player]")
|
|
@CommandPermission("anticheat.command.debug")
|
|
public void onDebug(Player sender, @Single String check, @Optional OnlinePlayer targetPlayer) {
|
|
Player target = targetPlayer != null ? targetPlayer.player : sender;
|
|
switch (check.toLowerCase()) {
|
|
case "none": {
|
|
synchronized (Check.debugInstances) {
|
|
Check.debugInstances.forEach((nameKey, list) -> {
|
|
val iterator = list.iterator();
|
|
while(iterator.hasNext()) {
|
|
val tuple = iterator.next();
|
|
|
|
if(tuple.two.equals(target.getUniqueId())) {
|
|
iterator.remove();
|
|
sender.spigot()
|
|
.sendMessage(new ChatBuilder(
|
|
"&cTurned off debug for check &f%s &con target &f%s", nameKey,
|
|
target.getName()).build());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case "sniff": {
|
|
APlayer targetData = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(target.getUniqueId()).orElse(null);
|
|
|
|
if(targetData != null) {
|
|
if(targetData.sniffing) {
|
|
targetData.sniffing = false;
|
|
sender.sendMessage(Color.Red + "Stopped sniff. Pasting...");
|
|
try {
|
|
sender.sendMessage(Color.Gray + "Paste: " + Color.White + Pastebin.makePaste(
|
|
String.join("\n", targetData.sniffedPackets.toArray(new String[0])),
|
|
"Sniffed from " + target.getName(), Pastebin.Privacy.UNLISTED));
|
|
} catch (UnsupportedEncodingException e) {
|
|
e.printStackTrace();
|
|
}
|
|
targetData.sniffedPackets.clear();
|
|
} else {
|
|
targetData.sniffing = true;
|
|
sender.sendMessage(Color.Green + "Started packet sniff on " + target.getName() + "!");
|
|
}
|
|
} else {
|
|
sender.spigot().sendMessage(Messages.NULL_APLAYER);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if(!Anticheat.INSTANCE.getCheckManager().isCheck(check)) {
|
|
sender.sendMessage(Color.Red + "Check \"" + check + "\" is not a valid check!");
|
|
return;
|
|
}
|
|
synchronized (Check.debugInstances) {
|
|
Check.debugInstances.compute(check.replace("_", " "), (key, list) -> {
|
|
if(list == null) list = new ArrayList<>();
|
|
|
|
list.add(new Tuple<>(target.getUniqueId(), sender.getUniqueId()));
|
|
|
|
return list;
|
|
});
|
|
|
|
sender.spigot()
|
|
.sendMessage(new ChatBuilder(
|
|
"&aTurned on debug for check &f%s &aon target &f%s",
|
|
check.replace("_", " "),
|
|
target.getName()).build());
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|