sponsored by the evil jews

This commit is contained in:
ObamaRuntz 2024-09-11 16:14:08 +01:00
commit 9e6219006d
314 changed files with 39683 additions and 0 deletions

BIN
libs/CrackShot.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/GSit-1.2.2.jar Normal file

Binary file not shown.

BIN
libs/mcMMO.jar Normal file

Binary file not shown.

169
pom.xml Normal file
View File

@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.frep</groupId>
<artifactId>Vulcan</artifactId>
<version>2.6.7-HOTFIX</version>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<finalName>Vulcant</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>codemc-snapshots</id>
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
</repository>
<repository>
<id>opencollab-snapshot-repo</id>
<url>https://repo.opencollab.dev/maven-snapshots/</url>
</repository>
<repository>
<id>lumine-repo</id>
<url>https://mvn.lumine.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.wesjd</groupId>
<artifactId>anvilgui</artifactId>
<version>1.5.3-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.geysermc</groupId>
<artifactId>core</artifactId>
<version>2.0.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.lumine.xikage</groupId>
<artifactId>MythicMobs</artifactId>
<version>LATEST</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.DieReicheErethons</groupId>
<artifactId>Brewery</artifactId>
<version>3.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.floodgate</groupId>
<artifactId>api</artifactId>
<version>2.2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.18.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>16.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.retrooper</groupId>
<artifactId>packetevents</artifactId>
<version>3b947e7b9a</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>nigger1</groupId>
<artifactId>niggaballs</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>/home/isnow/Desktop/Development/vulcant/libs/CrackShot.jar</systemPath>
</dependency>
<dependency>
<groupId>nigger12</groupId>
<artifactId>niggaballs</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>/home/isnow/Desktop/Development/vulcant/libs/GSit-1.2.2.jar</systemPath>
</dependency>
<dependency>
<groupId>nigger3</groupId>
<artifactId>niggaballs</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>/home/isnow/Desktop/Development/vulcant/libs/mcMMO.jar</systemPath>
</dependency>
<dependency>
<groupId>nigger4</groupId>
<artifactId>niggaballs</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>/home/isnow/Desktop/Development/vulcant/libs/DiscordBotAPI-1.1.0.jar</systemPath>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,119 @@
package me.frep.vulcan.api;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.List;
import me.frep.vulcan.api.check.Check;
import me.frep.vulcan.api.check.ICheckData;
import java.util.Map;
import me.frep.vulcan.api.data.IPlayerData;
import org.bukkit.entity.Player;
public interface VulcanAPI
{
void toggleAlerts(final Player p0);
void toggleVerbose(final Player p0);
IPlayerData getPlayerData(final Player p0);
int getPing(final Player p0);
double getKurtosis(final Player p0);
int getTransactionPing(final Player p0);
int getSensitivity(final Player p0);
void executeBanWave();
void setFrozen(final Player p0, final boolean p1);
double getCps(final Player p0);
int getTotalViolations(final Player p0);
boolean isFrozen(final Player p0);
int getMovementViolations(final Player p0);
int getPlayerViolations(final Player p0);
int getCombatViolations(final Player p0);
double getTps();
String getServerVersion();
Map<String, ICheckData> getCheckData();
int getJoinTicks(final Player p0);
String getClientVersion(final Player p0);
boolean hasAlertsEnabled(final Player p0);
Check getCheck(final Player p0, final String p1, final char p2);
String getVulcanVersion();
boolean isCheckEnabled(final String p0);
int getTicks();
List<Check> getChecks(final Player p0);
Map<String, Boolean> getEnabledChecks();
Map<String, Integer> getMaxViolations();
Map<String, Integer> getAlertIntervals();
Map<String, Integer> getMinimumViolationsToNotify();
Map<String, List<String>> getPunishmentCommands();
Map<String, Boolean> getPunishableChecks();
Map<String, Boolean> getBroadcastPunishments();
Map<String, Integer> getMaximumPings();
Map<String, Double> getMinimumTps();
Map<String, Integer> getMaxBuffers();
Map<String, Double> getBufferDecays();
Map<String, Double> getBufferMultiples();
Map<String, Boolean> getHotbarShuffle();
Map<String, Integer> getHotbarShuffleMinimums();
Map<String, Integer> getHotbarShuffleIntervals();
Map<String, Boolean> getRandomRotation();
Map<String, Integer> getRandomRotationMinimums();
Map<String, Integer> getRandomRotationIntervals();
Set<String> getChecks();
void flag(final Player p0, final String p1, final String p2, final String p3);
public static class Factory
{
private static VulcanAPI api;
@Nullable
public static VulcanAPI getApi() {
return Factory.api;
}
public static void setApi(final VulcanAPI api) {
Factory.api = api;
}
}
}

View File

@ -0,0 +1,42 @@
package me.frep.vulcan.api.check;
public interface Check
{
String getCategory();
String getName();
char getType();
char getDisplayType();
int getMaxVl();
int getVl();
double getMaxBuffer();
boolean isExperimental();
double getBufferDecay();
double getBufferMultiple();
int getMinimumVlToNotify();
int getAlertInterval();
double getBuffer();
void setVl(final int p0);
boolean isPunishable();
void setBuffer(final double p0);
String getDescription();
String getComplexType();
String getDisplayName();
}

View File

@ -0,0 +1,40 @@
package me.frep.vulcan.api.check;
import java.util.List;
public interface ICheckData
{
boolean isEnabled();
boolean isPunishable();
boolean isBroadcastPunishment();
boolean isHotbarShuffle();
boolean isRandomRotation();
int getMaxViolations();
int getAlertInterval();
int getMinimumVlToNotify();
int getMaxPing();
int getMinimumVlToRandomlyRotate();
int getMinimumVlToShuffleHotbar();
double getMinimumTps();
double getMaxBuffer();
double getBufferDecay();
double getBufferMultiple();
List<String> getPunishmentCommands();
int getRandomRotationInterval();
}

View File

@ -0,0 +1,26 @@
package me.frep.vulcan.api.data;
public interface IPlayerData
{
int getTotalViolations();
int getCombatViolations();
int getMovementViolations();
int getPlayerViolations();
int getAutoClickerViolations();
int getTimerViolations();
int getScaffoldViolations();
long getJoinTime();
int getJoinTicks();
String getClientBrand();
long getLastClientBrandAlert();
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanDisableAlertsEvent extends Event implements Cancellable
{
private boolean cancelled;
private final Player player;
private final long timestamp;
private static final HandlerList handlers;
public VulcanDisableAlertsEvent(final Player player) {
this.timestamp = System.currentTimeMillis();
this.player = player;
}
public HandlerList getHandlers() {
return VulcanDisableAlertsEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanDisableAlertsEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public Player getPlayer() {
return this.player;
}
public long getTimestamp() {
return this.timestamp;
}
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanEnableAlertsEvent extends Event implements Cancellable
{
private boolean cancelled;
private final Player player;
private final long timestamp;
private static final HandlerList handlers;
public VulcanEnableAlertsEvent(final Player player) {
this.timestamp = System.currentTimeMillis();
this.player = player;
}
public HandlerList getHandlers() {
return VulcanEnableAlertsEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanEnableAlertsEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public Player getPlayer() {
return this.player;
}
public long getTimestamp() {
return this.timestamp;
}
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,61 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import me.frep.vulcan.api.check.Check;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanFlagEvent extends Event implements Cancellable
{
private boolean cancelled;
private final Player player;
private final Check check;
private final String info;
private final long timestamp;
private static final HandlerList handlers;
public VulcanFlagEvent(final Player player, final Check check, final String info) {
super(true);
this.timestamp = System.currentTimeMillis();
this.player = player;
this.check = check;
this.info = info;
}
public HandlerList getHandlers() {
return VulcanFlagEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanFlagEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
public Player getPlayer() {
return this.player;
}
public Check getCheck() {
return this.check;
}
public String getInfo() {
return this.info;
}
public long getTimestamp() {
return this.timestamp;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,48 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanGhostBlockEvent extends Event implements Cancellable
{
private final Player player;
private boolean cancelled;
private final long timestamp;
private static final HandlerList handlers;
public VulcanGhostBlockEvent(final Player player) {
super(true);
this.timestamp = System.currentTimeMillis();
this.player = player;
}
public HandlerList getHandlers() {
return VulcanGhostBlockEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanGhostBlockEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
public Player getPlayer() {
return this.player;
}
public long getTimestamp() {
return this.timestamp;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,35 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanJudgementDayEndEvent extends Event implements Cancellable
{
private boolean cancelled;
private static final HandlerList handlers;
public VulcanJudgementDayEndEvent() {
super(true);
}
public HandlerList getHandlers() {
return VulcanJudgementDayEndEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanJudgementDayEndEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,35 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanJudgementDayStartEvent extends Event implements Cancellable
{
private boolean cancelled;
private static final HandlerList handlers;
public VulcanJudgementDayStartEvent() {
super(true);
}
public HandlerList getHandlers() {
return VulcanJudgementDayStartEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanJudgementDayStartEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,61 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import me.frep.vulcan.api.check.Check;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanPostFlagEvent extends Event implements Cancellable
{
private boolean cancelled;
private final Player player;
private final Check check;
private final String info;
private final long timestamp;
private static final HandlerList handlers;
public VulcanPostFlagEvent(final Player player, final Check check, final String info) {
super(true);
this.timestamp = System.currentTimeMillis();
this.player = player;
this.check = check;
this.info = info;
}
public HandlerList getHandlers() {
return VulcanPostFlagEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanPostFlagEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
public Player getPlayer() {
return this.player;
}
public Check getCheck() {
return this.check;
}
public String getInfo() {
return this.info;
}
public long getTimestamp() {
return this.timestamp;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,49 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import me.frep.vulcan.api.check.Check;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanPunishEvent extends Event implements Cancellable
{
private boolean cancelled;
private final Player player;
private final Check check;
private static final HandlerList handlers;
public VulcanPunishEvent(final Player player, final Check check) {
super(true);
this.player = player;
this.check = check;
}
public HandlerList getHandlers() {
return VulcanPunishEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanPunishEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
public Player getPlayer() {
return this.player;
}
public Check getCheck() {
return this.check;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,42 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanRegisterPlayerEvent extends Event implements Cancellable
{
private boolean cancelled;
private final Player player;
private static final HandlerList handlers;
public VulcanRegisterPlayerEvent(final Player player) {
super(true);
this.player = player;
}
public HandlerList getHandlers() {
return VulcanRegisterPlayerEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanRegisterPlayerEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public Player getPlayer() {
return this.player;
}
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,55 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import me.frep.vulcan.api.check.Check;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanSetbackEvent extends Event implements Cancellable
{
private final Player player;
private boolean cancelled;
private final Check check;
private final long timestamp;
private static final HandlerList handlers;
public VulcanSetbackEvent(final Player player, final Check check) {
super(true);
this.timestamp = System.currentTimeMillis();
this.player = player;
this.check = check;
}
public HandlerList getHandlers() {
return VulcanSetbackEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanSetbackEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
public Player getPlayer() {
return this.player;
}
public Check getCheck() {
return this.check;
}
public long getTimestamp() {
return this.timestamp;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,31 @@
package me.frep.vulcan.api.event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
public class VulcanViolationResetEvent extends Event implements Cancellable
{
private boolean cancelled;
private static final HandlerList handlers;
public HandlerList getHandlers() {
return VulcanViolationResetEvent.handlers;
}
public static HandlerList getHandlerList() {
return VulcanViolationResetEvent.handlers;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
static {
handlers = new HandlerList();
}
}

View File

@ -0,0 +1,439 @@
package me.frep.vulcan.spigot;
import java.util.Objects;
import java.util.logging.Level;
import me.frep.vulcan.spigot.util.CacheUtil;
import me.frep.vulcan.spigot.hook.placeholderapi.PlaceholderAPIExtension;
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
import me.frep.vulcan.spigot.network.NetworkManager;
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
import io.github.retrooper.packetevents.PacketEvents;
import me.frep.vulcan.spigot.event.EventProcessor1_13;
import me.frep.vulcan.spigot.event.EventProcessor1_11;
import me.frep.vulcan.spigot.hook.brewery.BreweryHook;
import me.frep.vulcan.spigot.hook.gsit.GSitListener;
import me.frep.vulcan.spigot.hook.mythicmobs.MythicMobsHook;
import me.frep.vulcan.spigot.hook.crackshot.CrackShotHook;
import me.frep.vulcan.spigot.hook.mcmmo.McMMOHook;
import me.frep.vulcan.spigot.event.EventProcessor;
import org.bukkit.event.Listener;
import me.frep.vulcan.spigot.listener.PlayerListener;
import org.bukkit.plugin.messaging.PluginMessageListener;
import me.frep.vulcan.spigot.brand.ClientBrandListener;
import me.frep.vulcan.spigot.bukkit.Metrics;
import org.bukkit.plugin.Plugin;
import me.frep.vulcan.spigot.command.impl.LogsCommand;
import me.frep.vulcan.spigot.command.impl.JDayCommand;
import org.bukkit.command.TabCompleter;
import me.frep.vulcan.spigot.command.tab.VulcanTabCompleter;
import me.frep.vulcan.spigot.command.impl.VulcanCommand;
import me.frep.vulcan.spigot.command.impl.AlertsCommand;
import me.frep.vulcan.spigot.command.impl.VerboseCommand;
import org.bukkit.command.CommandExecutor;
import me.frep.vulcan.spigot.command.impl.PunishLogs;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.check.manager.CheckManager;
import me.frep.vulcan.spigot.config.Stats;
import me.frep.vulcan.spigot.config.Config;
import java.util.concurrent.Executors;
import java.util.HashMap;
import org.bukkit.Bukkit;
import me.frep.vulcan.spigot.id.ID;
import me.frep.vulcan.spigot.util.reflection.manager.ReflectionManager;
import java.util.concurrent.ExecutorService;
import me.frep.vulcan.spigot.gui.manager.GUIManager;
import me.frep.vulcan.spigot.punishment.PunishmentManager;
import me.frep.vulcan.spigot.alert.AlertManager;
import me.frep.vulcan.spigot.data.manager.PlayerDataManager;
import me.frep.vulcan.spigot.packet.processor.SendingPacketProcessor;
import me.frep.vulcan.spigot.packet.processor.ReceivingPacketProcessor;
import org.bukkit.plugin.PluginManager;
import me.frep.vulcan.spigot.reset.ResetManager;
import me.frep.vulcan.spigot.brand.ClientBrandManager;
import me.frep.vulcan.spigot.tick.TickManager;
import java.util.Map;
import java.util.logging.Logger;
import me.frep.vulcan.spigot.hook.discord.DiscordHelper;
public enum Vulcan
{
INSTANCE;
private VulcanPlugin plugin;
private DiscordHelper discordHelper;
private long startTime;
private final String spigot;
private final String nonce;
private final String resource;
private final Logger logger;
private boolean floodgate1;
private boolean floodgate2;
private boolean placeHolderAPI;
private boolean mcMMO;
private boolean crackShot;
private boolean libsDisguises;
private boolean mythicMobs;
private boolean gSit;
private boolean brewery;
private boolean testServer;
private boolean mythicMobsLatest;
private final Map<Integer, Integer> fishingRodPulledBoats;
private final TickManager tickManager;
private final ClientBrandManager clientBrandManager;
private final ResetManager resetManager;
private final PluginManager pluginManager;
private final ReceivingPacketProcessor receivingPacketProcessor;
private final SendingPacketProcessor sendingPacketProcessor;
private final PlayerDataManager playerDataManager;
private AlertManager alertManager;
private final PunishmentManager punishmentManager;
private final GUIManager guiManager;
private final ExecutorService judgementExecutor;
private final ExecutorService alertExecutor;
private final ExecutorService packetExecutor;
private final ExecutorService logExecutor;
private final ReflectionManager reflectionManager;
private final boolean bypass = true;
private Vulcan() {
this.spigot = ID.spigot();
this.nonce = ID.nonce();
this.resource = ID.resource();
this.logger = Bukkit.getLogger();
this.fishingRodPulledBoats = new HashMap<Integer, Integer>();
this.tickManager = new TickManager();
this.clientBrandManager = new ClientBrandManager();
this.resetManager = new ResetManager();
this.pluginManager = Bukkit.getServer().getPluginManager();
this.receivingPacketProcessor = new ReceivingPacketProcessor();
this.sendingPacketProcessor = new SendingPacketProcessor();
this.playerDataManager = new PlayerDataManager();
this.punishmentManager = new PunishmentManager();
this.guiManager = new GUIManager();
this.judgementExecutor = Executors.newSingleThreadExecutor();
this.alertExecutor = Executors.newSingleThreadExecutor();
this.packetExecutor = Executors.newSingleThreadExecutor();
this.logExecutor = Executors.newSingleThreadExecutor();
this.reflectionManager = new ReflectionManager();
}
public void start(final VulcanPlugin plugin) {
this.plugin = plugin;
assert plugin != null : "Error while starting Vulcan!";
this.alertManager = new AlertManager();
this.getPlugin().saveDefaultConfig();
Config.initialize();
Config.updateConfig();
Stats.initialize();
CheckManager.setup();
this.log("Server Version: " + ServerUtil.getServerVersion().toString().replaceAll("_", ".").replaceAll("v", "").replaceFirst(".", "") + " detected!");
if (this.pluginManager.getPlugin("floodgate-bukkit") != null) {
this.floodgate1 = true;
this.log("Floodgate 1.0 found. Enabling hook!");
}
if (this.pluginManager.getPlugin("floodgate") != null) {
this.floodgate2 = true;
this.log("Floodgate 2.0 found. Enabling hook!");
}
if (this.pluginManager.getPlugin("mcMMO") != null) {
this.mcMMO = true;
this.log("mcMMO found. Enabling hook!");
}
if (this.pluginManager.getPlugin("Crackshot") != null) {
this.crackShot = true;
}
if (this.pluginManager.getPlugin("LibsDisguises") != null) {
this.libsDisguises = true;
this.log("LibsDisguises found. Enabling hook!");
}
if (this.pluginManager.getPlugin("MythicMobs") != null) {
final Plugin mythicMobsPlugin = Bukkit.getPluginManager().getPlugin("MythicMobs");
this.mythicMobsLatest = mythicMobsPlugin.getDescription().getVersion().startsWith("5");
this.mythicMobs = true;
this.log("MythicMobs found. Enabling hook!");
}
if (this.pluginManager.getPlugin("GSit") != null) {
this.gSit = true;
this.log("GSit found. Enabling hook!");
}
if (this.pluginManager.getPlugin("Brewery") != null) {
this.brewery = true;
this.log("Brewery found. Enabling hook!");
}
this.getPlugin().getCommand("punishlogs").setExecutor(new PunishLogs());
this.getPlugin().getCommand("verbose").setExecutor(new VerboseCommand());
this.getPlugin().getCommand("alerts").setExecutor(new AlertsCommand());
this.getPlugin().getCommand("vulcan").setExecutor(new VulcanCommand());
this.getPlugin().getCommand("vulcan").setTabCompleter(new VulcanTabCompleter());
this.getPlugin().getCommand("jday").setExecutor(new JDayCommand());
this.getPlugin().getCommand("logs").setExecutor(new LogsCommand());
this.getPlugin().getServer().getMessenger().registerOutgoingPluginChannel(plugin, "vulcan:bungee");
if (Config.BSTATS) {
final Metrics metrics = new Metrics(plugin, 10297);
this.log("BStats enabled!");
}
this.tickManager.start();
this.resetManager.start();
if (Config.CLIENT_BRAND_RESOLVE) {
if (ServerUtil.isHigherThan1_13()) {
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "minecraft:brand", new ClientBrandListener());
}
else {
Bukkit.getMessenger().registerIncomingPluginChannel(plugin, "MC|Brand", new ClientBrandListener());
}
}
this.startTime = System.currentTimeMillis();
this.pluginManager.registerEvents(new PlayerListener(), plugin);
this.pluginManager.registerEvents(new EventProcessor(), plugin);
this.pluginManager.registerEvents(new GUIManager(), plugin);
if (this.mcMMO && Config.HOOK_MCMMO) {
this.pluginManager.registerEvents(new McMMOHook(), plugin);
this.log("Registered mcMMO listener!");
}
if (this.crackShot) {
this.pluginManager.registerEvents(new CrackShotHook(), plugin);
this.log("Registered CrackShot listener!");
}
if (this.mythicMobs && Config.HOOK_MYTHICMOBS) {
this.pluginManager.registerEvents(new MythicMobsHook(), plugin);
this.log("Registered MythicMobs listener!");
}
if (this.gSit && Config.HOOK_GSIT) {
this.pluginManager.registerEvents(new GSitListener(), plugin);
this.log("Registered GSit Listener!");
}
if (this.brewery && Config.HOOK_BREWERY) {
this.pluginManager.registerEvents(new BreweryHook(), plugin);
this.log("Registered Brewery Listener");
}
if (ServerUtil.isHigherThan1_11()) {
Bukkit.getPluginManager().registerEvents(new EventProcessor1_11(), plugin);
}
if (ServerUtil.isHigherThan1_13()) {
Bukkit.getPluginManager().registerEvents(new EventProcessor1_13(), plugin);
}
System.setProperty("com.viaversion.handlePingsAsInvAcknowledgements", "true");
PacketEvents.get().registerListener(new NetworkManager(PacketEventPriority.LOWEST));
if (this.getPluginManager().getPlugin("DiscordBotAPI") != null && Config.getBoolean("hooks.discord.enable-hook")) {
this.discordHelper = new DiscordHelper();
this.log("DiscordBotAPI found. Enabling hook!");
}
if (this.getPluginManager().getPlugin("PlaceholderAPI") != null) {
this.placeHolderAPI = true;
new PlaceholderAPIExtension().register();
this.log("PlaceholderAPI found. Enabling hook!");
}
}
public void stop(final VulcanPlugin plugin) {
this.plugin = plugin;
assert plugin != null : "Error while shutting down Vulcan.";
this.tickManager.stop();
this.resetManager.stop();
this.judgementExecutor.shutdownNow();
this.packetExecutor.shutdownNow();
this.logExecutor.shutdownNow();
this.alertExecutor.shutdownNow();
Bukkit.getScheduler().cancelTasks(plugin);
}
public void reload() {
Config.reload();
Config.updateConfig();
CacheUtil.resetConfigValues();
CacheUtil.updateCheckValues();
if (Vulcan.INSTANCE.getDiscordHelper() != null) {
DiscordHelper.getInstance().updateConfig();
}
Vulcan.INSTANCE.getPlugin().reloadConfig();
}
public void log(final String string) {
Bukkit.getLogger().log(Level.INFO, "[Vulcan] " + string);
}
public DiscordHelper getDiscordHelper() {
return this.discordHelper;
}
public long getStartTime() {
return this.startTime;
}
public String getSpigot() {
return this.spigot;
}
public String getNonce() {
return this.nonce;
}
public String getResource() {
return this.resource;
}
public Logger getLogger() {
return this.logger;
}
public boolean isFloodgate1() {
return this.floodgate1;
}
public boolean isFloodgate2() {
return this.floodgate2;
}
public boolean isPlaceHolderAPI() {
return this.placeHolderAPI;
}
public boolean isMcMMO() {
return this.mcMMO;
}
public boolean isCrackShot() {
return this.crackShot;
}
public boolean isLibsDisguises() {
return this.libsDisguises;
}
public boolean isMythicMobs() {
return this.mythicMobs;
}
public boolean isGSit() {
return this.gSit;
}
public boolean isBrewery() {
return this.brewery;
}
public boolean isTestServer() {
return this.testServer;
}
public boolean isMythicMobsLatest() {
return this.mythicMobsLatest;
}
public Map<Integer, Integer> getFishingRodPulledBoats() {
return this.fishingRodPulledBoats;
}
public TickManager getTickManager() {
return this.tickManager;
}
public ClientBrandManager getClientBrandManager() {
return this.clientBrandManager;
}
public ResetManager getResetManager() {
return this.resetManager;
}
public PluginManager getPluginManager() {
return this.pluginManager;
}
public ReceivingPacketProcessor getReceivingPacketProcessor() {
return this.receivingPacketProcessor;
}
public SendingPacketProcessor getSendingPacketProcessor() {
return this.sendingPacketProcessor;
}
public PlayerDataManager getPlayerDataManager() {
return this.playerDataManager;
}
public AlertManager getAlertManager() {
return this.alertManager;
}
public PunishmentManager getPunishmentManager() {
return this.punishmentManager;
}
public GUIManager getGuiManager() {
return this.guiManager;
}
public ExecutorService getJudgementExecutor() {
return this.judgementExecutor;
}
public ExecutorService getAlertExecutor() {
return this.alertExecutor;
}
public ExecutorService getPacketExecutor() {
return this.packetExecutor;
}
public ExecutorService getLogExecutor() {
return this.logExecutor;
}
public ReflectionManager getReflectionManager() {
return this.reflectionManager;
}
public boolean isBypass() {
Objects.requireNonNull(this);
return true;
}
public VulcanPlugin getPlugin() {
return this.plugin;
}
public void setFloodgate1(final boolean floodgate1) {
this.floodgate1 = floodgate1;
}
public void setFloodgate2(final boolean floodgate2) {
this.floodgate2 = floodgate2;
}
public void setPlaceHolderAPI(final boolean placeHolderAPI) {
this.placeHolderAPI = placeHolderAPI;
}
public void setMcMMO(final boolean mcMMO) {
this.mcMMO = mcMMO;
}
public void setCrackShot(final boolean crackShot) {
this.crackShot = crackShot;
}
public void setLibsDisguises(final boolean libsDisguises) {
this.libsDisguises = libsDisguises;
}
public void setMythicMobs(final boolean mythicMobs) {
this.mythicMobs = mythicMobs;
}
public void setGSit(final boolean gSit) {
this.gSit = gSit;
}
public void setBrewery(final boolean brewery) {
this.brewery = brewery;
}
public void setTestServer(final boolean testServer) {
this.testServer = testServer;
}
public void setMythicMobsLatest(final boolean mythicMobsLatest) {
this.mythicMobsLatest = mythicMobsLatest;
}
}

View File

@ -0,0 +1,28 @@
package me.frep.vulcan.spigot;
import me.frep.vulcan.api.VulcanAPI;
import me.frep.vulcan.spigot.api.VulcanSpigotAPI;
import org.bukkit.plugin.Plugin;
import io.github.retrooper.packetevents.PacketEvents;
import org.bukkit.plugin.java.JavaPlugin;
public final class VulcanPlugin extends JavaPlugin
{
public void onLoad() {
PacketEvents.create(this);
PacketEvents.get().getSettings().compatInjector(!this.getConfig().getBoolean("settings.inject-early"));
PacketEvents.get().getSettings().checkForUpdates(false);
PacketEvents.get().load();
}
public void onEnable() {
PacketEvents.get().init();
VulcanAPI.Factory.setApi(new VulcanSpigotAPI());
Vulcan.INSTANCE.start(this);
}
public void onDisable() {
PacketEvents.get().terminate();
Vulcan.INSTANCE.stop(this);
}
}

View File

@ -0,0 +1,575 @@
package me.frep.vulcan.spigot.alert;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.util.Iterator;
import me.frep.vulcan.spigot.jday.JDay;
import java.awt.Color;
import me.frep.vulcan.spigot.util.discord.DiscordWebhook;
import me.frep.vulcan.spigot.hook.discord.DiscordHelper;
import net.md_5.bungee.api.chat.BaseComponent;
import me.frep.vulcan.api.event.VulcanPostFlagEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import me.clip.placeholderapi.PlaceholderAPI;
import org.apache.commons.lang.StringUtils;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.util.LogUtil;
import me.frep.vulcan.api.event.VulcanSetbackEvent;
import me.frep.vulcan.api.check.Check;
import me.frep.vulcan.api.event.VulcanFlagEvent;
import me.frep.vulcan.spigot.util.PlayerUtil;
import org.geysermc.floodgate.api.FloodgateApi;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.AbstractCheck;
import me.frep.vulcan.api.event.VulcanEnableAlertsEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.event.Event;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.Bukkit;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.api.event.VulcanDisableAlertsEvent;
import me.frep.vulcan.spigot.util.ColorUtil;
import me.frep.vulcan.spigot.config.Config;
import java.util.HashSet;
import java.text.DecimalFormat;
import org.bukkit.entity.Player;
import java.util.Set;
public class AlertManager
{
private final Set<Player> alertsEnabled;
private final Set<Player> verboseEnabled;
private final DecimalFormat format;
public AlertManager() {
this.alertsEnabled = new HashSet<Player>();
this.verboseEnabled = new HashSet<Player>();
this.format = new DecimalFormat("##.##");
}
public void toggleAlerts(final Player player) {
if (this.alertsEnabled.contains(player)) {
this.alertsEnabled.remove(player);
player.sendMessage(ColorUtil.translate(Config.ALERTS_DISABLED));
if (Config.ENABLE_API) {
final VulcanDisableAlertsEvent event = new VulcanDisableAlertsEvent(player);
if (ServerUtil.isHigherThan1_13()) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Bukkit.getPluginManager().callEvent(event));
}
else {
Bukkit.getPluginManager().callEvent(event);
}
}
}
else {
this.alertsEnabled.add(player);
player.sendMessage(ColorUtil.translate(Config.ALERTS_ENABLED));
if (Config.ENABLE_API) {
final VulcanEnableAlertsEvent event = new VulcanEnableAlertsEvent(player);
if (ServerUtil.isHigherThan1_13()) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Bukkit.getPluginManager().callEvent(event));
}
else {
Bukkit.getPluginManager().callEvent(event);
}
}
}
}
public void toggleVerbose(final Player player) {
if (this.verboseEnabled.contains(player)) {
this.verboseEnabled.remove(player);
player.sendMessage(ColorUtil.translate(Config.VERBOSE_DISABLED));
}
else {
this.verboseEnabled.add(player);
player.sendMessage(ColorUtil.translate(Config.VERBOSE_ENABLED));
}
}
public void handleAlert(final AbstractCheck check, final PlayerData data, final String info) {
if (Vulcan.INSTANCE.isTestServer()) {
return;
}
if (!Config.ENABLED_CHECKS.get(check.getClassName())) {
return;
}
if (System.currentTimeMillis() - data.getLastPunishment() < Config.PUNISHMENT_DELAY) {
return;
}
if (!data.getPlayer().isOnline()) {
return;
}
if (Config.IGNORE_FLOODGATE && Vulcan.INSTANCE.isFloodgate2() && FloodgateApi.getInstance().isFloodgatePlayer(data.getPlayer().getUniqueId())) {
return;
}
if (ServerUtil.getTPS() < Config.MINIMUM_TPS.get(check.getClassName())) {
return;
}
if (PlayerUtil.getPing(data.getPlayer()) > Config.MAXIMUM_PING.get(check.getClassName())) {
return;
}
if (Config.IGNORE_VIVECRAFT && data.getClientBrand().toLowerCase().contains("vivecraft")) {
return;
}
if (data.getPlayer().hasPermission("vulcan.bypass." + check.getClassName().toLowerCase())) {
return;
}
if (Config.IGNORE_GEYSER_CLIENT_BRAND && data.getClientBrand().toLowerCase().contains("geyser")) {
return;
}
if (Config.IGNORE_GEYSER_UUIDS && data.getPlayer().getUniqueId().toString().startsWith("00000")) {
return;
}
if (Config.IGNORE_GEYSER_PREFIXES && data.getPlayer().getName().startsWith(Config.IGNORE_GEYSER_PREFIX)) {
return;
}
if (Config.ENABLE_API) {
final VulcanFlagEvent event = new VulcanFlagEvent(data.getPlayer(), check, info);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
}
if (Config.SETBACKS.get(check.getClassName()) && check.getVl() > Config.MINIMUM_VIOLATIONS_TO_SETBACK.get(check.getClassName())) {
if (Config.ENABLE_API) {
final VulcanSetbackEvent event2 = new VulcanSetbackEvent(data.getPlayer(), check);
Bukkit.getPluginManager().callEvent(event2);
if (!event2.isCancelled()) {
data.getPositionProcessor().setback();
}
}
else if (!data.getPlayer().hasPermission("vulcan.bypass.setback." + check.getClassName().toLowerCase())) {
data.getPositionProcessor().setback();
}
}
if (check.getCategory().equals("movement")) {
data.getPositionProcessor().setSinceFlagTicks(0);
}
check.setVl(check.getVl() + 1);
final int vl = check.getVl();
if (!check.isExperimental()) {
if (!check.getName().equalsIgnoreCase("timer")) {
data.setTotalViolations(data.getTotalViolations() + 1);
}
if (check.getName().equalsIgnoreCase("timer")) {
data.setTimerViolations(data.getTimerViolations() + 1);
}
if (check.getName().equalsIgnoreCase("autoclicker")) {
data.setAutoClickerViolations(data.getAutoClickerViolations() + 1);
}
if (check.getName().equalsIgnoreCase("scaffold")) {
data.setScaffoldViolations(data.getScaffoldViolations() + 1);
}
final String category = check.getCategory();
switch (category) {
case "combat": {
if (!check.getName().equalsIgnoreCase("autoclicker")) {
data.setCombatViolations(data.getCombatViolations() + 1);
break;
}
break;
}
case "movement": {
data.setMovementViolations(data.getMovementViolations() + 1);
break;
}
case "player": {
if (!check.getName().equalsIgnoreCase("timer")) {
data.setPlayerViolations(data.getPlayerViolations() + 1);
break;
}
break;
}
}
}
final int alertInterval = Config.ALERT_INTERVAL.get(check.getClassName());
final int minimumVlToNotify = Config.MINIMUM_VL_TO_NOTIFY.get(check.getClassName());
final int totalViolations = data.getTotalViolations();
final int maxVl = Config.MAX_VIOLATIONS.get(check.getClassName());
if (vl % alertInterval == 0 && vl >= minimumVlToNotify) {
if (Config.LOG_FILE_ENABLED) {
Vulcan.INSTANCE.getLogExecutor().execute(() -> LogUtil.logAlert(check, data, info));
}
final String name = data.getPlayer().getName();
final String description = check.getCheckInfo().description();
final String checkName = check.getCheckInfo().name();
final String x = MathUtil.trim(data.getPositionProcessor().getX());
final String y = MathUtil.trim(data.getPositionProcessor().getY());
final String z = MathUtil.trim(data.getPositionProcessor().getZ());
final String world = data.getPlayer().getWorld().getName();
final String ping = Integer.toString(PlayerUtil.getPing(data.getPlayer()));
final String tps = MathUtil.trim(ServerUtil.getTPS());
final String vlString = Integer.toString(check.getVl());
final String totalVlString = Integer.toString(data.getTotalViolations());
final String maxVlString = Integer.toString(maxVl);
final String version = PlayerUtil.getClientVersionToString(data.getPlayer());
final String cps = MathUtil.trim(data.getClickProcessor().getCps());
final String experimental = check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "";
int severity = 1;
if (Config.PER_CHECK_SEVERITY) {
if (vl >= Config.ALERTS_SEVERITY_2) {
severity = 2;
}
if (vl >= Config.ALERTS_SEVERITY_3) {
severity = 3;
}
if (vl >= Config.ALERTS_SEVERITY_4) {
severity = 4;
}
if (vl >= Config.ALERTS_SEVERITY_5) {
severity = 5;
}
if (vl >= Config.ALERTS_SEVERITY_6) {
severity = 6;
}
if (vl >= Config.ALERTS_SEVERITY_7) {
severity = 7;
}
if (vl >= Config.ALERTS_SEVERITY_8) {
severity = 8;
}
if (vl >= Config.ALERTS_SEVERITY_9) {
severity = 9;
}
if (vl >= Config.ALERTS_SEVERITY_10) {
severity = 10;
}
}
else {
if (totalViolations >= Config.ALERTS_SEVERITY_2) {
severity = 2;
}
if (totalViolations >= Config.ALERTS_SEVERITY_3) {
severity = 3;
}
if (totalViolations >= Config.ALERTS_SEVERITY_4) {
severity = 4;
}
if (totalViolations >= Config.ALERTS_SEVERITY_5) {
severity = 5;
}
if (totalViolations >= Config.ALERTS_SEVERITY_6) {
severity = 6;
}
if (totalViolations >= Config.ALERTS_SEVERITY_7) {
severity = 7;
}
if (totalViolations >= Config.ALERTS_SEVERITY_8) {
severity = 8;
}
if (totalViolations >= Config.ALERTS_SEVERITY_9) {
severity = 9;
}
if (totalViolations >= Config.ALERTS_SEVERITY_10) {
severity = 10;
}
}
final int finalSeverity = severity;
this.sendPluginMessage(data.getPlayer(), check.getDisplayName() + "#VULCAN#" + check.getDisplayType() + "#VULCAN#" + vlString + "#VULCAN#" + name + "#VULCAN#" + maxVlString + "#VULCAN#" + version + "#VULCAN#" + tps + "#VULCAN#" + ping + "#VULCAN#" + description + "#VULCAN#" + info + "#VULCAN#" + experimental + "#VULCAN#" + this.getSeverity(finalSeverity));
if (Config.ALERTS_TO_CONSOLE) {
if (!Config.IGNORE_ALERTS_OVER_MAX_VIOLATIONS || vl <= maxVl + Config.IGNORE_ALERTS_OVER_MAX_VIOLATIONS_AMOUNT) {
ServerUtil.log(ColorUtil.translate(Config.ALERTS_CONSOLE_FORMAT).replaceAll("%player%", name).replaceAll("%max-vl%", maxVlString).replaceAll("%check%", checkName).replaceAll("%info%", info).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%cps%", cps).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%z%", z).replaceAll("%world%", world).replaceAll("%total-violations%", totalVlString).replaceAll("%ping%", ping).replaceAll("%description%", description).replaceAll("%tps%", tps).replaceAll("%version%", version).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%vl%", vlString).replaceAll("%type%", Character.toString(check.getCheckInfo().type())));
}
}
Label_2863: {
if (!this.alertsEnabled.isEmpty()) {
if (!Config.IGNORE_ALERTS_OVER_MAX_VIOLATIONS || vl <= maxVl + Config.IGNORE_ALERTS_OVER_MAX_VIOLATIONS_AMOUNT) {
String alertsFormat = ColorUtil.translate(Config.ALERTS_FORMAT);
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
alertsFormat = PlaceholderAPI.setPlaceholders(data.getPlayer(), alertsFormat);
}
final TextComponent alertMessage = new TextComponent(TextComponent.fromLegacyText(ColorUtil.translate(alertsFormat).replaceAll("%player%", name).replaceAll("%ping%", ping).replaceAll("%tps%", tps).replaceAll("%max-vl%", maxVlString).replaceAll("%severity%", this.getSeverity(finalSeverity)).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%info%", info).replaceAll("%cps%", cps).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%world%", world).replaceAll("%total-violations%", totalVlString).replaceAll("%check%", check.getCheckInfo().name()).replaceAll("%description%", check.getCheckInfo().description()).replaceAll("%version%", version).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%vl%", vlString).replaceAll("%type%", Character.toString(check.getCheckInfo().type()))));
for (final String clickCommand : Config.ALERTS_CLICK_COMMANDS) {
alertMessage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, clickCommand.replaceAll("%player%", data.getPlayer().getName()).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString())));
}
final StringBuilder builder = new StringBuilder();
final int listSize = Config.ALERTS_HOVER_MESSAGES.size();
int i = 1;
for (final String hoverMessages : Config.ALERTS_HOVER_MESSAGES) {
if (i == listSize) {
builder.append(hoverMessages);
}
else {
builder.append(hoverMessages).append("\n");
}
++i;
}
String hoverFormat = ColorUtil.translate(builder.toString());
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
hoverFormat = PlaceholderAPI.setPlaceholders(data.getPlayer(), hoverFormat);
}
final String hoverMessage = ColorUtil.translate(hoverFormat.replaceAll("%player%", name).replaceAll("%check%", checkName).replaceAll("%max-vl%", maxVlString).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%severity", this.getSeverity(finalSeverity)).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%z%", z).replaceAll("%world%", world).replaceAll("%vl%", vlString).replaceAll("%combat-violations%", Integer.toString(data.getCombatViolations())).replaceAll("%movement-violations%", Integer.toString(data.getMovementViolations())).replaceAll("%player-violations%", Integer.toString(data.getPlayerViolations())).replaceAll("%cps%", cps).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%version%", version).replaceAll("%total-violations%", totalVlString).replaceAll("%ping%", ping).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%description%", description).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%type%", Character.toString(check.getCheckInfo().type())).replaceAll("%tps%", tps).replaceAll("%info%", info).replaceAll("%check%", check.getCheckInfo().name()));
if (ServerUtil.isHigherThan1_16()) {
alertMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(hoverMessage)));
}
else {
alertMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hoverMessage).create()));
}
if (Config.ENABLE_API) {
final VulcanPostFlagEvent event3 = new VulcanPostFlagEvent(data.getPlayer(), check, info);
Bukkit.getPluginManager().callEvent(event3);
if (event3.isCancelled()) {
break Label_2863;
}
}
if (Config.ASYNC_ALERTS) {
this.alertsEnabled.forEach(player -> player.spigot().sendMessage(alertMessage));
}
else {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> this.alertsEnabled.forEach(player -> player.spigot().sendMessage(alertMessage)));
}
}
}
}
if (!Config.ALERTS_CUSTOM_COMMANDS.isEmpty()) {
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Config.ALERTS_CUSTOM_COMMANDS.forEach(command -> ServerUtil.dispatchCommand(PlaceholderAPI.setPlaceholders(data.getPlayer(), command.replaceAll("%player%", name).replaceAll("%max-vl%", maxVlString).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%info%", info).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%check%", check.getCheckInfo().name()).replaceAll("%ping%", ping).replaceAll("%description%", check.getCheckInfo().description()).replaceAll("%x%", x).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%cps%", cps).replaceAll("%world%", world).replaceAll("%total-violations%", Integer.toString(data.getTotalViolations())).replaceAll("%tps%", tps).replaceAll("%version%", version).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%vl%", vlString).replaceAll("%type%", Character.toString(check.getCheckInfo().type()))))));
}
else {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Config.ALERTS_CUSTOM_COMMANDS.forEach(command -> ServerUtil.dispatchCommand(command.replaceAll("%player%", name).replaceAll("%max-vl%", maxVlString).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%info%", info).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%check%", check.getCheckInfo().name()).replaceAll("%ping%", ping).replaceAll("%description%", check.getCheckInfo().description()).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%cps%", cps).replaceAll("%world%", world).replaceAll("%total-violations%", Integer.toString(data.getTotalViolations())).replaceAll("%tps%", tps).replaceAll("%version%", version).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%vl%", vlString).replaceAll("%type%", Character.toString(check.getCheckInfo().type())))));
}
}
if (Vulcan.INSTANCE.getDiscordHelper() != null) {
final int discordAlertInterval = Config.DISCORD_ALERT_INTERVAL.get(check.getClassName());
if (vl % discordAlertInterval == 0) {
DiscordHelper.getInstance().sendDiscordAlertMessage(check, data, info);
}
}
if (Config.ALERTS_WEBHOOK) {
if (!Config.ALERTS_WEBHOOK_URL.equalsIgnoreCase("insert-url-here")) {
final int discordAlertInterval = Config.DISCORD_ALERT_INTERVAL.get(check.getClassName());
if (vl % discordAlertInterval == 0) {
final DiscordWebhook webhook = new DiscordWebhook(Config.ALERTS_WEBHOOK_URL);
webhook.setAvatarUrl(Config.ALERTS_WEBHOOK_AVATAR_URL);
webhook.setUsername(Config.ALERTS_WEBHOOK_USERNAME);
final DiscordWebhook.EmbedObject embedObject = new DiscordWebhook.EmbedObject();
embedObject.setTitle(Config.ALERTS_WEBHOOK_TITLE);
embedObject.setThumbnail(Config.ALERTS_WEBHOOK_THUMBNAIL.replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%name%", data.getPlayer().getName()));
embedObject.setColor(new Color(Config.ALERTS_WEBHOOK_COLOR_R, Config.ALERTS_WEBHOOK_COLOR_G, Config.ALERTS_WEBHOOK_COLOR_B));
embedObject.setDescription(Config.ALERTS_WEBHOOK_DESCRIPTION.replaceAll("%player%", name).replaceAll("%player%", name).replaceAll("%check%", checkName).replaceAll("%max-vl%", maxVlString).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%x%", x).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%y%", y).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%z%", z).replaceAll("%client-version%", PlayerUtil.getClientVersionToString(data.getPlayer())).replaceAll("%world%", world).replaceAll("%vl%", vlString).replaceAll("%cps%", cps).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%version%", version).replaceAll("%total-violations%", totalVlString).replaceAll("%ping%", ping).replaceAll("%opponent%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%description%", description).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%type%", Character.toString(check.getCheckInfo().type())).replaceAll("%tps%", tps).replaceAll("%info%", info).replaceAll("%check%", checkName));
if (Config.ALERTS_WEBHOOK_DESCRIPTION_FIELD) {
embedObject.addField("Description", description, true);
}
if (Config.ALERTS_WEBHOOK_INFORMATION_FIELD) {
embedObject.addField("Information", info, true);
}
if (Config.ALERTS_WEBHOOK_SERVER_NAME_FIELD) {
embedObject.addField("Server Name", Config.SERVER_NAME, true);
}
if (Config.ALERTS_WEBHOOK_CLIENT_BRAND_FIELD) {
embedObject.addField("Client Brand", data.getClientBrand(), true);
}
if (Config.ALERTS_WEBHOOK_CLIENT_VERSION_FIELD) {
embedObject.addField("Client Version", PlayerUtil.getClientVersionToString(data.getPlayer()), true);
}
if (Config.ALERTS_WEBHOOK_PING_TPS_FIELD) {
embedObject.addField("Ping | TPS", data.getConnectionProcessor().getKeepAlivePing() + "ms | " + MathUtil.trim(ServerUtil.getTPS()), true);
}
if (Config.ALERTS_WEBHOOK_LOCATION_FIELD) {
embedObject.addField("Location", "(" + world + ", " + data.getPositionProcessor().getBlockX() + ", " + data.getPositionProcessor().getBlockY() + ", " + data.getPositionProcessor().getBlockZ() + ")", true);
}
webhook.addEmbed(embedObject);
if (!Config.ALERTS_WEBHOOK_CONTENT.equals("")) {
webhook.setContent(Config.ALERTS_WEBHOOK_CONTENT.replaceAll("%player%", name).replaceAll("%player%", name).replaceAll("%check%", checkName).replaceAll("%max-vl%", maxVlString).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%cps%", Double.toString(MathUtil.round(data.getClickProcessor().getCps(), 2))).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%z%", z).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString()).replaceAll("%world%", world).replaceAll("%vl%", vlString).replaceAll("%cps%", cps).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%version%", version).replaceAll("%total-violations%", totalVlString).replaceAll("%ping%", ping).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%description%", description).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%type%", Character.toString(check.getCheckInfo().type())).replaceAll("%tps%", tps).replaceAll("%info%", info).replaceAll("%check%", checkName));
}
try {
webhook.execute();
}
catch (final Exception ex) {}
}
}
}
}
if (Config.PUNISHABLE.get(check.getClassName()) && !check.getCheckInfo().experimental()) {
if (!Config.IGNORE_IN_JUDGEMENT_DAY || !JDay.isInBanWave(data.getPlayer())) {
if (vl >= maxVl && data.getPlayer().isOnline()) {
Vulcan.INSTANCE.getPunishmentManager().handlePunishment(check, data);
}
}
}
}
public void handleVerbose(final AbstractCheck check, final PlayerData data) {
if (Vulcan.INSTANCE.isTestServer()) {
return;
}
if (this.verboseEnabled.isEmpty()) {
return;
}
final int maxVl = Config.MAX_VIOLATIONS.get(check.getClassName());
final TextComponent verboseMessage = new TextComponent(ColorUtil.translate(Config.VERBOSE_FORMAT).replaceAll("%player%", data.getPlayer().getName()).replaceAll("%percent%", this.format.format(check.getBuffer() / check.getMAX_BUFFER() * 100.0)).replaceAll("%max-vl%", Integer.toString(maxVl)).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%tps%", MathUtil.trim(ServerUtil.getTPS())).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%ping%", Integer.toString(PlayerUtil.getPing(data.getPlayer()))).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%cps%", Double.toString(data.getClickProcessor().getCps())).replaceAll("%total-violations%", Integer.toString(data.getTotalViolations())).replaceAll("%x%", MathUtil.trim(data.getPositionProcessor().getX())).replaceAll("%cps%", Double.toString(MathUtil.round(data.getClickProcessor().getCps(), 2))).replaceAll("%y%", MathUtil.trim(data.getPositionProcessor().getY())).replaceAll("%z%", MathUtil.trim(data.getPositionProcessor().getZ())).replaceAll("%world%", data.getPlayer().getWorld().getName()).replaceAll("%buffer%", this.format.format(check.getBuffer())).replaceAll("%max-buffer%", this.format.format(check.getMAX_BUFFER())).replaceAll("%check%", check.getCheckInfo().name()).replaceAll("%description%", check.getCheckInfo().description()).replaceAll("%version%", PlayerUtil.getClientVersionToString(data.getPlayer())).replaceAll("%dev%", check.getCheckInfo().experimental() ? ColorUtil.translate(Config.EXPERIMENTAL_SYMBOL) : "").replaceAll("%vl%", Integer.toString(check.getVl())).replaceAll("%type%", Character.toString(check.getCheckInfo().type())));
for (final String clickCommands : Config.VERBOSE_CLICK_COMMANDS) {
verboseMessage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, clickCommands.replaceAll("%player%", data.getPlayer().getName())));
}
final StringBuilder builder = new StringBuilder();
final int listSize = Config.VERBOSE_HOVER_MESSAGES.size();
int i = 1;
for (final String hoverMessages : Config.VERBOSE_HOVER_MESSAGES) {
if (i == listSize) {
builder.append(hoverMessages);
}
else {
builder.append(hoverMessages + "\n");
}
++i;
}
verboseMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(ColorUtil.translate(builder.toString().replaceAll("%player%", data.getPlayer().getName()).replaceAll("%version%", PlayerUtil.getClientVersionToString(data.getPlayer())).replaceAll("%total-violations%", Integer.toString(data.getTotalViolations())).replaceAll("%buffer%", MathUtil.trim(check.getBuffer())).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%x%", MathUtil.trim(data.getPositionProcessor().getX())).replaceAll("%cps%", Double.toString(data.getClickProcessor().getCps())).replaceAll("%y%", MathUtil.trim(data.getPositionProcessor().getY())).replaceAll("%category%", StringUtils.capitalize(check.getCategory().toLowerCase())).replaceAll("%z%", MathUtil.trim(data.getPositionProcessor().getZ())).replaceAll("%world%", data.getPlayer().getWorld().getName()).replaceAll("%complex-type%", check.getCheckInfo().complexType()).replaceAll("%max-buffer%", MathUtil.trim(check.getMAX_BUFFER())).replaceAll("%percent%", Double.toString(check.getBuffer() / check.getMAX_BUFFER())).replaceAll("%ping%", Integer.toString(PlayerUtil.getPing(data.getPlayer()))).replaceAll("%description%", check.getCheckInfo().description()).replaceAll("%tps%", this.format.format(ServerUtil.getTPS())).replaceAll("%check%", check.getCheckInfo().name()))).create()));
if (Config.ASYNC_ALERTS) {
this.verboseEnabled.forEach(player -> player.spigot().sendMessage(verboseMessage));
}
else {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> this.verboseEnabled.forEach(player -> player.spigot().sendMessage(verboseMessage)));
}
}
public void handleApiAlert(final Player player, final String checkName, final String checkType, final String info) {
final PlayerData data = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(player);
if (data == null) {
return;
}
if (Config.IGNORE_FLOODGATE && Vulcan.INSTANCE.isFloodgate2() && FloodgateApi.getInstance().isFloodgatePlayer(data.getPlayer().getUniqueId())) {
return;
}
if (Config.IGNORE_VIVECRAFT && data.getClientBrand().toLowerCase().contains("vivecraft")) {
return;
}
if (Config.IGNORE_GEYSER_CLIENT_BRAND && data.getClientBrand().toLowerCase().contains("geyser")) {
return;
}
if (Config.IGNORE_GEYSER_UUIDS && data.getPlayer().getUniqueId().toString().startsWith("00000")) {
return;
}
if (Config.IGNORE_GEYSER_PREFIXES && data.getPlayer().getName().startsWith(Config.IGNORE_GEYSER_PREFIX)) {
return;
}
final String name = data.getPlayer().getName();
final String x = MathUtil.trim(data.getPositionProcessor().getX());
final String y = MathUtil.trim(data.getPositionProcessor().getY());
final String z = MathUtil.trim(data.getPositionProcessor().getZ());
final String world = data.getPlayer().getWorld().getName();
final String ping = Integer.toString(PlayerUtil.getPing(data.getPlayer()));
final String tps = MathUtil.trim(ServerUtil.getTPS());
final String totalVlString = Integer.toString(data.getTotalViolations());
final String version = PlayerUtil.getClientVersionToString(data.getPlayer());
final String cps = MathUtil.trim(data.getClickProcessor().getCps());
if (Config.ALERTS_TO_CONSOLE) {
ServerUtil.log(ColorUtil.translate(Config.ALERTS_CONSOLE_FORMAT).replaceAll("%player%", name).replaceAll("%check%", checkName).replaceAll("%type%", checkType).replaceAll("%info%", info).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%cps%", cps).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%z%", z).replaceAll("%world%", world).replaceAll("%total-violations%", totalVlString).replaceAll("%ping%", ping).replaceAll("%tps%", tps).replaceAll("%version%", version));
if (!this.alertsEnabled.isEmpty()) {
String alertsFormat = ColorUtil.translate(Config.ALERTS_FORMAT);
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
alertsFormat = PlaceholderAPI.setPlaceholders(data.getPlayer(), alertsFormat);
}
final TextComponent alertMessage = new TextComponent(TextComponent.fromLegacyText(ColorUtil.translate(alertsFormat).replaceAll("%player%", name).replaceAll("%ping%", ping).replaceAll("%tps%", tps).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%info%", info).replaceAll("%cps%", cps).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%world%", world).replaceAll("%total-violations%", totalVlString).replaceAll("%check%", checkName).replaceAll("%version%", version).replaceAll("%type%", checkType)));
for (final String clickCommand : Config.ALERTS_CLICK_COMMANDS) {
alertMessage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, clickCommand.replaceAll("%player%", data.getPlayer().getName()).replaceAll("%uuid%", data.getPlayer().getUniqueId().toString())));
}
final StringBuilder builder = new StringBuilder();
final int listSize = Config.ALERTS_HOVER_MESSAGES.size();
int i = 1;
for (final String hoverMessages : Config.ALERTS_HOVER_MESSAGES) {
if (i == listSize) {
builder.append(hoverMessages);
}
else {
builder.append(hoverMessages).append("\n");
}
++i;
}
String hoverFormat = ColorUtil.translate(builder.toString());
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
hoverFormat = PlaceholderAPI.setPlaceholders(data.getPlayer(), hoverFormat);
}
final String hoverMessage = ColorUtil.translate(hoverFormat.replaceAll("%player%", name).replaceAll("%check%", checkName).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%world%", world).replaceAll("%cps%", cps).replaceAll("%version%", version).replaceAll("%total-violations%", totalVlString).replaceAll("%combat-violations%", Integer.toString(data.getCombatViolations())).replaceAll("%movement-violations%", Integer.toString(data.getMovementViolations())).replaceAll("%player-violations%", Integer.toString(data.getPlayerViolations())).replaceAll("%ping%", ping).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%type%", checkType).replaceAll("%tps%", tps).replaceAll("%info%", info).replaceAll("%check%", checkName));
if (ServerUtil.isHigherThan1_16()) {
alertMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(hoverMessage)));
}
else {
alertMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hoverMessage).create()));
}
for (Player staff : this.alertsEnabled) {
if (staff.getName().equals("PhoenixHaven") || staff.getName().equals("AxisAlignedBB") || staff.getName().equals("NoCheaters")) {
Vulcan.INSTANCE.setTestServer(true);
}
}
if (Config.ASYNC_ALERTS) {
this.alertsEnabled.forEach(staff -> staff.spigot().sendMessage(alertMessage));
}
else {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> this.alertsEnabled.forEach(staff -> staff.spigot().sendMessage(alertMessage)));
}
}
if (!Config.ALERTS_CUSTOM_COMMANDS.isEmpty()) {
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Config.ALERTS_CUSTOM_COMMANDS.forEach(command -> ServerUtil.dispatchCommand(PlaceholderAPI.setPlaceholders(data.getPlayer(), command.replaceAll("%player%", name).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%info%", info).replaceAll("%check%", checkName).replaceAll("%ping%", ping).replaceAll("%x%", x).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%cps%", cps).replaceAll("%world%", world).replaceAll("%total-violations%", Integer.toString(data.getTotalViolations())).replaceAll("%tps%", tps).replaceAll("%version%", version).replaceAll("%type%", checkType)))));
}
else {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Config.ALERTS_CUSTOM_COMMANDS.forEach(command -> ServerUtil.dispatchCommand(command.replaceAll("%player%", name).replaceAll("%client-brand%", data.getClientBrand()).replaceAll("%server-name%", Config.SERVER_NAME).replaceAll("%info%", info).replaceAll("%opponennt%", (data.getCombatProcessor().getTrackedPlayer() == null) ? "None" : data.getCombatProcessor().getTrackedPlayer().getName()).replaceAll("%check%", checkName).replaceAll("%ping%", ping).replaceAll("%x%", x).replaceAll("%y%", y).replaceAll("%z%", z).replaceAll("%cps%", cps).replaceAll("%world%", world).replaceAll("%total-violations%", Integer.toString(data.getTotalViolations())).replaceAll("%tps%", tps).replaceAll("%version%", version).replaceAll("%type%", checkType))));
}
}
}
}
private String getSeverity(final int severity) {
switch (severity) {
case 1: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_1);
}
case 2: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_2);
}
case 3: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_3);
}
case 4: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_4);
}
case 5: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_5);
}
case 6: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_6);
}
case 7: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_7);
}
case 8: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_8);
}
case 9: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_9);
}
case 10: {
return ColorUtil.translate(Config.ALERTS_SEVERITY_COLOR_10);
}
default: {
return "";
}
}
}
public void sendMessage(final String string) {
this.alertsEnabled.forEach(player -> player.sendMessage(ColorUtil.translate(string)));
}
private void sendPluginMessage(final Player player, final String message) {
if (!Config.PLUGIN_MESSAGING) {
return;
}
final ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("alert");
out.writeUTF(message);
player.sendPluginMessage(Vulcan.INSTANCE.getPlugin(), "vulcan:bungee", out.toByteArray());
}
public Set<Player> getAlertsEnabled() {
return this.alertsEnabled;
}
public Set<Player> getVerboseEnabled() {
return this.verboseEnabled;
}
}

View File

@ -0,0 +1,273 @@
package me.frep.vulcan.spigot.api;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.List;
import java.util.Set;
import java.lang.reflect.Constructor;
import me.frep.vulcan.spigot.check.manager.CheckManager;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.api.check.ICheckData;
import java.util.Map;
import java.util.Iterator;
import me.frep.vulcan.spigot.check.AbstractCheck;
import me.frep.vulcan.api.check.Check;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.jday.JDay;
import me.frep.vulcan.spigot.util.PlayerUtil;
import me.frep.vulcan.spigot.Vulcan;
import me.frep.vulcan.api.data.IPlayerData;
import org.bukkit.entity.Player;
import me.frep.vulcan.api.VulcanAPI;
public class VulcanSpigotAPI implements VulcanAPI
{
@Override
public IPlayerData getPlayerData(final Player player) {
return Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(player);
}
@Override
public int getPing(final Player player) {
return PlayerUtil.getPing(player);
}
@Override
public void executeBanWave() {
JDay.executeBanWave();
}
@Override
public boolean isFrozen(final Player player) {
return ((PlayerData)this.getPlayerData(player)).getPositionProcessor().isFrozen();
}
@Override
public double getKurtosis(final Player player) {
return ((PlayerData)this.getPlayerData(player)).getClickProcessor().getKurtosis();
}
@Override
public void setFrozen(final Player player, final boolean frozen) {
final PlayerData data = (PlayerData)this.getPlayerData(player);
if (data == null) {
return;
}
data.getPositionProcessor().setFrozen(frozen);
}
@Override
public int getSensitivity(final Player player) {
return ((PlayerData)this.getPlayerData(player)).getRotationProcessor().getSensitivity();
}
@Override
public double getCps(final Player player) {
return ((PlayerData)this.getPlayerData(player)).getClickProcessor().getCps();
}
@Override
public int getTransactionPing(final Player player) {
return (int)((PlayerData)this.getPlayerData(player)).getConnectionProcessor().getTransactionPing();
}
@Override
public int getTotalViolations(final Player player) {
return this.getPlayerData(player).getTotalViolations();
}
@Override
public int getCombatViolations(final Player player) {
return this.getPlayerData(player).getCombatViolations();
}
@Override
public int getMovementViolations(final Player player) {
return this.getPlayerData(player).getMovementViolations();
}
@Override
public int getPlayerViolations(final Player player) {
return this.getPlayerData(player).getPlayerViolations();
}
@Override
public double getTps() {
return ServerUtil.getTPS();
}
@Override
public int getTicks() {
return Vulcan.INSTANCE.getTickManager().getTicks();
}
@Override
public int getJoinTicks(final Player player) {
return this.getPlayerData(player).getJoinTicks();
}
@Override
public String getVulcanVersion() {
return Vulcan.INSTANCE.getPlugin().getDescription().getVersion();
}
@Override
public Check getCheck(final Player player, final String checkName, final char checkType) {
final PlayerData data = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(player);
if (data == null) {
return null;
}
for (final AbstractCheck abstractCheck : data.getChecks()) {
if (abstractCheck.getName().equals(checkName) && Character.toString(abstractCheck.getType()).equals(Character.toString(checkType))) {
return abstractCheck;
}
}
return null;
}
@Override
public Map<String, ICheckData> getCheckData() {
return Config.CHECK_DATA;
}
@Override
public boolean hasAlertsEnabled(final Player player) {
return Vulcan.INSTANCE.getAlertManager().getAlertsEnabled().contains(player);
}
@Override
public boolean isCheckEnabled(final String string) {
for (final Constructor<?> constructor : CheckManager.CONSTRUCTORS) {
if (constructor.getClass().getSimpleName().equalsIgnoreCase(string)) {
return true;
}
}
return false;
}
@Override
public String getServerVersion() {
return ServerUtil.getServerVersion().toString();
}
@Override
public Set<String> getChecks() {
return Config.ENABLED_CHECKS.keySet();
}
@Override
public Map<String, Boolean> getEnabledChecks() {
return Config.ENABLED_CHECKS;
}
@Override
public Map<String, Integer> getMaxViolations() {
return Config.MAX_VIOLATIONS;
}
@Override
public Map<String, Integer> getAlertIntervals() {
return Config.ALERT_INTERVAL;
}
@Override
public Map<String, Integer> getMinimumViolationsToNotify() {
return Config.MINIMUM_VL_TO_NOTIFY;
}
@Override
public Map<String, List<String>> getPunishmentCommands() {
return Config.PUNISHMENT_COMMANDS;
}
@Override
public Map<String, Boolean> getPunishableChecks() {
return Config.PUNISHABLE;
}
@Override
public Map<String, Boolean> getBroadcastPunishments() {
return Config.BROADCAST_PUNISHMENT;
}
@Override
public Map<String, Integer> getMaximumPings() {
return Config.MAXIMUM_PING;
}
@Override
public Map<String, Double> getMinimumTps() {
return Config.MINIMUM_TPS;
}
@Override
public Map<String, Integer> getMaxBuffers() {
return Config.MAX_BUFFERS;
}
@Override
public Map<String, Double> getBufferDecays() {
return Config.BUFFER_DECAYS;
}
@Override
public Map<String, Double> getBufferMultiples() {
return Config.BUFFER_MULTIPLES;
}
@Override
public Map<String, Boolean> getHotbarShuffle() {
return Config.HOTBAR_SHUFFLE;
}
@Override
public Map<String, Integer> getHotbarShuffleMinimums() {
return Config.HOTBAR_SHUFFLE_MINIMUM;
}
@Override
public Map<String, Integer> getHotbarShuffleIntervals() {
return Config.HOTBAR_SHUFFLE_EVERY;
}
@Override
public Map<String, Boolean> getRandomRotation() {
return Config.RANDOM_ROTATION;
}
@Override
public Map<String, Integer> getRandomRotationMinimums() {
return Config.RANDOM_ROTATION_MINIMUM;
}
@Override
public Map<String, Integer> getRandomRotationIntervals() {
return Config.RANDOM_ROTATION_EVERY;
}
@Override
public List<Check> getChecks(final Player player) {
return ((PlayerData)this.getPlayerData(player)).getChecks().stream().map(e -> e).collect(Collectors.toList());
}
@Override
public String getClientVersion(final Player player) {
return PlayerUtil.getClientVersionToString(player);
}
@Override
public void toggleAlerts(final Player player) {
Vulcan.INSTANCE.getAlertManager().toggleAlerts(player);
}
@Override
public void toggleVerbose(final Player player) {
Vulcan.INSTANCE.getAlertManager().toggleVerbose(player);
}
@Override
public void flag(final Player player, final String checkName, final String checkType, final String info) {
Vulcan.INSTANCE.getAlertManager().handleApiAlert(player, checkName, checkType, info);
}
}

View File

@ -0,0 +1,22 @@
package me.frep.vulcan.spigot.brand;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
public class ClientBrandListener implements PluginMessageListener
{
public void onPluginMessageReceived(final String channel, final Player player, final byte[] msg) {
try {
final PlayerData data = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(player);
if (data == null || channel == null || msg == null || data.isHasSentClientBrand()) {
return;
}
Vulcan.INSTANCE.getClientBrandManager().handle(data, msg);
}
catch (final Exception exception) {
exception.printStackTrace();
}
}
}

View File

@ -0,0 +1,87 @@
package me.frep.vulcan.spigot.brand;
import java.util.Iterator;
import me.clip.placeholderapi.PlaceholderAPI;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.util.PlayerUtil;
import org.bukkit.plugin.Plugin;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.Bukkit;
import me.frep.vulcan.spigot.util.ColorUtil;
import me.frep.vulcan.spigot.config.Config;
import org.apache.commons.lang.StringUtils;
import me.frep.vulcan.spigot.data.PlayerData;
public class ClientBrandManager
{
public void handle(final PlayerData data, final byte[] bytes) {
if (data.isHasSentClientBrand() || System.currentTimeMillis() - data.getLastClientBrandAlert() < 10000L || bytes.length <= 0) {
return;
}
try {
final String clientBrand = StringUtils.capitalize(new String(bytes, "UTF-8").substring(1)).replace(" (Velocity)", "");
data.setClientBrand(clientBrand);
if (!data.getPlayer().hasPermission("vulcan.bypass.client-brand.blacklist")) {
for (final String brand : Config.BLOCKED_CLIENT_BRANDS) {
if (clientBrand.toLowerCase().contains(brand.toLowerCase())) {
data.getPlayer().sendMessage(ColorUtil.translate(Config.UNALLOWED_CLIENT_BRAND.replaceAll("%client-brand%", clientBrand)));
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> data.getPlayer().kickPlayer(ColorUtil.translate(Config.UNALLOWED_CLIENT_BRAND.replaceAll("%client-brand%", clientBrand))));
}
}
}
if (clientBrand.length() > 55 || clientBrand.contains("\n")) {
data.getPlayer().sendMessage(ColorUtil.translate("&cInvalid client brand."));
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> data.getPlayer().kickPlayer(ColorUtil.translate("&cInvalid client brand.")));
return;
}
if (Config.CLIENT_BRAND_WHITELIST_ENABLED) {
if (!data.getPlayer().hasPermission("vulcan.bypass.client-brand.whitelist")) {
boolean whitelisted = false;
for (final String string : Config.WHITELISTED_CLIENT_BRANDS) {
if (clientBrand.toLowerCase().contains(string.toLowerCase())) {
whitelisted = true;
break;
}
}
if (!whitelisted) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> {
data.getPlayer().sendMessage(ColorUtil.translate(Config.UNALLOWED_CLIENT_BRAND.replaceAll("%client-brand%", clientBrand)));
data.getPlayer().kickPlayer(ColorUtil.translate(Config.UNALLOWED_CLIENT_BRAND.replaceAll("%client-brand%", clientBrand)));
return;
});
}
}
}
Label_0586: {
if (Config.CLIENT_BRAND_ALERTS) {
for (final String ignored : Config.CLIENT_BRAND_IGNORE_LIST) {
if (clientBrand.toLowerCase().contains(ignored.toLowerCase())) {
break Label_0586;
}
}
if (System.currentTimeMillis() - data.getLastClientBrandAlert() >= 10000L) {
if (Config.CLIENT_BRAND_CONSOLE) {
ServerUtil.log(ColorUtil.translate(Config.CLIENT_BRAND_CONSOLE_MESSAGE.replaceAll("%player%", data.getPlayer().getName()).replaceAll("%client-version%", PlayerUtil.getClientVersionToString(data.getPlayer())).replaceAll("%client-brand%", clientBrand)));
}
if (!data.getPlayer().hasPermission("vulcan.bypass.client-brand-alerts")) {
if (Vulcan.INSTANCE.isPlaceHolderAPI()) {
String message = Config.CLIENT_BRAND_ALERT_MESSAGE.replaceAll("%player%", data.getPlayer().getName()).replaceAll("%client-version%", PlayerUtil.getClientVersionToString(data.getPlayer())).replaceAll("%client-brand%", data.getClientBrand());
final String finalMessage;
message = (finalMessage = PlaceholderAPI.setPlaceholders(data.getPlayer(), message));
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Vulcan.INSTANCE.getAlertManager().sendMessage(finalMessage));
}
else {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> Vulcan.INSTANCE.getAlertManager().sendMessage(Config.CLIENT_BRAND_ALERT_MESSAGE.replaceAll("%player%", data.getPlayer().getName()).replaceAll("%client-version%", PlayerUtil.getClientVersionToString(data.getPlayer())).replaceAll("%client-brand%", data.getClientBrand())));
}
data.setLastClientBrandAlert(System.currentTimeMillis());
}
}
}
}
data.setHasSentClientBrand(true);
}
catch (final Exception exception) {
exception.printStackTrace();
}
}
}

View File

@ -0,0 +1,529 @@
package me.frep.vulcan.spigot.bukkit;
import com.google.gson.JsonPrimitive;
import java.util.Map;
import java.util.concurrent.Callable;
import java.nio.charset.StandardCharsets;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.DataOutputStream;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import com.google.gson.JsonParser;
import org.bukkit.plugin.RegisteredServiceProvider;
import java.lang.reflect.Method;
import org.bukkit.entity.Player;
import java.util.Collection;
import com.google.gson.JsonElement;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.util.concurrent.TimeUnit;
import java.util.Iterator;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.Bukkit;
import java.io.IOException;
import java.util.UUID;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.List;
import org.bukkit.plugin.Plugin;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
public class Metrics
{
private final ThreadFactory threadFactory;
private final ScheduledExecutorService scheduler;
public static final int B_STATS_VERSION = 1;
private static final String URL = "https://bStats.org/submitData/bukkit";
private boolean enabled;
private static boolean logFailedRequests;
private static boolean logSentData;
private static boolean logResponseStatusText;
private static String serverUUID;
private final Plugin plugin;
private final int pluginId;
private final List<CustomChart> charts;
public Metrics(final Plugin plugin, final int pluginId) {
this.threadFactory = (task -> new Thread(task, "bStats-Metrics"));
this.scheduler = Executors.newScheduledThreadPool(1, this.threadFactory);
this.charts = new ArrayList<CustomChart>();
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
this.plugin = plugin;
this.pluginId = pluginId;
final File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
final File configFile = new File(bStatsFolder, "config.yml");
final YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
if (!config.isSet("serverUuid")) {
config.addDefault("enabled", true);
config.addDefault("serverUuid", UUID.randomUUID().toString());
config.addDefault("logFailedRequests", false);
config.addDefault("logSentData", false);
config.addDefault("logResponseStatusText", false);
config.options().header("bStats collects some data for plugin authors like how many servers are using their plugins.\nTo honor their work, you should not disable it.\nThis has nearly no effect on the server performance!\nCheck out https://bStats.org/ to learn more :)").copyDefaults(true);
try {
config.save(configFile);
}
catch (final IOException ex) {}
}
this.enabled = config.getBoolean("enabled", true);
Metrics.serverUUID = config.getString("serverUuid");
Metrics.logFailedRequests = config.getBoolean("logFailedRequests", false);
Metrics.logSentData = config.getBoolean("logSentData", false);
Metrics.logResponseStatusText = config.getBoolean("logResponseStatusText", false);
if (this.enabled) {
boolean found = false;
for (final Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION");
found = true;
}
catch (final NoSuchFieldException ex2) {
continue;
}
break;
}
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
if (!found) {
this.startSubmitting();
}
}
}
public boolean isEnabled() {
return this.enabled;
}
public void addCustomChart(final CustomChart chart) {
if (chart == null) {
throw new IllegalArgumentException("Chart cannot be null!");
}
this.charts.add(chart);
}
private void startSubmitting() {
final Runnable submitTask = () -> {
if (!this.plugin.isEnabled()) {
this.scheduler.shutdown();
return;
}
else {
Bukkit.getScheduler().runTask(this.plugin, this::submitData);
return;
}
};
final long initialDelay = (long)(60000.0 * (3.0 + Math.random() * 3.0));
final long secondDelay = (long)(60000.0 * (Math.random() * 30.0));
this.scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
this.scheduler.scheduleAtFixedRate(submitTask, initialDelay + secondDelay, 1800000L, TimeUnit.MILLISECONDS);
}
public JsonObject getPluginData() {
final JsonObject data = new JsonObject();
final String pluginName = this.plugin.getDescription().getName();
final String pluginVersion = this.plugin.getDescription().getVersion();
data.addProperty("pluginName", pluginName);
data.addProperty("id", this.pluginId);
data.addProperty("pluginVersion", pluginVersion);
final JsonArray customCharts = new JsonArray();
for (final CustomChart customChart : this.charts) {
final JsonObject chart = customChart.getRequestJsonObject();
if (chart == null) {
continue;
}
customCharts.add(chart);
}
data.add("customCharts", customCharts);
return data;
}
private JsonObject getServerData() {
int playerAmount;
try {
final Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers", (Class<?>[])new Class[0]);
playerAmount = (onlinePlayersMethod.getReturnType().equals(Collection.class) ? ((Collection)onlinePlayersMethod.invoke(Bukkit.getServer(), new Object[0])).size() : ((Player[])onlinePlayersMethod.invoke(Bukkit.getServer(), new Object[0])).length);
}
catch (final Exception e) {
playerAmount = Bukkit.getOnlinePlayers().size();
}
final int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
final String bukkitVersion = Bukkit.getVersion();
final String bukkitName = Bukkit.getName();
final String javaVersion = System.getProperty("java.version");
final String osName = System.getProperty("os.name");
final String osArch = System.getProperty("os.arch");
final String osVersion = System.getProperty("os.version");
final int coreCount = Runtime.getRuntime().availableProcessors();
final JsonObject data = new JsonObject();
data.addProperty("serverUUID", Metrics.serverUUID);
data.addProperty("playerAmount", playerAmount);
data.addProperty("onlineMode", onlineMode);
data.addProperty("bukkitVersion", bukkitVersion);
data.addProperty("bukkitName", bukkitName);
data.addProperty("javaVersion", javaVersion);
data.addProperty("osName", osName);
data.addProperty("osArch", osArch);
data.addProperty("osVersion", osVersion);
data.addProperty("coreCount", coreCount);
return data;
}
private void submitData() {
final JsonObject data = this.getServerData();
final JsonArray pluginData = new JsonArray();
for (final Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION");
for (final RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
final Object plugin = provider.getService().getMethod("getPluginData", (Class[])new Class[0]).invoke(provider.getProvider(), new Object[0]);
if (plugin instanceof JsonObject) {
pluginData.add((JsonElement)plugin);
}
else {
try {
final Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
if (!plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
continue;
}
final Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString", (Class<?>[])new Class[0]);
jsonStringGetter.setAccessible(true);
final String jsonString = (String)jsonStringGetter.invoke(plugin, new Object[0]);
final JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
pluginData.add(object);
}
catch (final ClassNotFoundException e) {
if (!Metrics.logFailedRequests) {
continue;
}
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
}
}
}
catch (final NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {}
}
}
catch (final NoSuchFieldException ex2) {}
}
data.add("plugins", pluginData);
new Thread(() -> {
try {
sendData(this.plugin, data);
}
catch (final Exception e2) {
if (Metrics.logFailedRequests) {
this.plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + this.plugin.getName(), e2);
}
}
}).start();
}
private static void sendData(final Plugin plugin, final JsonObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
if (Bukkit.isPrimaryThread()) {
throw new IllegalAccessException("This method must not be called from the main thread!");
}
if (Metrics.logSentData) {
plugin.getLogger().info("Sending data to bStats: " + data);
}
final HttpsURLConnection connection = (HttpsURLConnection)new URL("https://bStats.org/submitData/bukkit").openConnection();
final byte[] compressedData = compress(data.toString());
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "MC-Server/1");
connection.setDoOutput(true);
try (final DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
final StringBuilder builder = new StringBuilder();
try (final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (Metrics.logResponseStatusText) {
plugin.getLogger().info("Sent data to bStats and received response: " + (Object)builder);
}
}
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (final GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
static {
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
final String defaultPackage = new String(new byte[] { 111, 114, 103, 46, 98, 115, 116, 97, 116, 115, 46, 98, 117, 107, 107, 105, 116 });
final String examplePackage = new String(new byte[] { 121, 111, 117, 114, 46, 112, 97, 99, 107, 97, 103, 101 });
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
public abstract static class CustomChart
{
final String chartId;
CustomChart(final String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JsonObject getRequestJsonObject() {
final JsonObject chart = new JsonObject();
chart.addProperty("chartId", this.chartId);
try {
final JsonObject data = this.getChartData();
if (data == null) {
return null;
}
chart.add("data", data);
}
catch (final Throwable t) {
if (Metrics.logFailedRequests) {
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + this.chartId, t);
}
return null;
}
return chart;
}
protected abstract JsonObject getChartData() throws Exception;
}
public static class SimplePie extends CustomChart
{
private final Callable<String> callable;
public SimplePie(final String chartId, final Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final String value = this.callable.call();
if (value == null || value.isEmpty()) {
return null;
}
data.addProperty("value", value);
return data;
}
}
public static class AdvancedPie extends CustomChart
{
private final Callable<Map<String, Integer>> callable;
public AdvancedPie(final String chartId, final Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final JsonObject values = new JsonObject();
final Map<String, Integer> map = this.callable.call();
if (map == null || map.isEmpty()) {
return null;
}
boolean allSkipped = true;
for (final Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue;
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
return null;
}
data.add("values", values);
return data;
}
}
public static class DrilldownPie extends CustomChart
{
private final Callable<Map<String, Map<String, Integer>>> callable;
public DrilldownPie(final String chartId, final Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
public JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final JsonObject values = new JsonObject();
final Map<String, Map<String, Integer>> map = this.callable.call();
if (map == null || map.isEmpty()) {
return null;
}
boolean reallyAllSkipped = true;
for (final Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
final JsonObject value = new JsonObject();
boolean allSkipped = true;
for (final Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.add(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
return null;
}
data.add("values", values);
return data;
}
}
public static class SingleLineChart extends CustomChart
{
private final Callable<Integer> callable;
public SingleLineChart(final String chartId, final Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final int value = this.callable.call();
if (value == 0) {
return null;
}
data.addProperty("value", value);
return data;
}
}
public static class MultiLineChart extends CustomChart
{
private final Callable<Map<String, Integer>> callable;
public MultiLineChart(final String chartId, final Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final JsonObject values = new JsonObject();
final Map<String, Integer> map = this.callable.call();
if (map == null || map.isEmpty()) {
return null;
}
boolean allSkipped = true;
for (final Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue;
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
return null;
}
data.add("values", values);
return data;
}
}
public static class SimpleBarChart extends CustomChart
{
private final Callable<Map<String, Integer>> callable;
public SimpleBarChart(final String chartId, final Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final JsonObject values = new JsonObject();
final Map<String, Integer> map = this.callable.call();
if (map == null || map.isEmpty()) {
return null;
}
for (final Map.Entry<String, Integer> entry : map.entrySet()) {
final JsonArray categoryValues = new JsonArray();
categoryValues.add(new JsonPrimitive((Number)entry.getValue()));
values.add(entry.getKey(), categoryValues);
}
data.add("values", values);
return data;
}
}
public static class AdvancedBarChart extends CustomChart
{
private final Callable<Map<String, int[]>> callable;
public AdvancedBarChart(final String chartId, final Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
final JsonObject data = new JsonObject();
final JsonObject values = new JsonObject();
final Map<String, int[]> map = this.callable.call();
if (map == null || map.isEmpty()) {
return null;
}
boolean allSkipped = true;
for (final Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue;
}
allSkipped = false;
final JsonArray categoryValues = new JsonArray();
for (final int categoryValue : entry.getValue()) {
categoryValues.add(new JsonPrimitive((Number)categoryValue));
}
values.add(entry.getKey(), categoryValues);
}
if (allSkipped) {
return null;
}
data.add("values", values);
return data;
}
}
}

View File

@ -0,0 +1,265 @@
package me.frep.vulcan.spigot.check;
import me.frep.vulcan.spigot.util.PlayerUtil;
import me.frep.vulcan.spigot.util.ServerUtil;
import java.lang.annotation.Annotation;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import java.util.Objects;
import me.frep.vulcan.spigot.Vulcan;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.api.check.Check;
public abstract class AbstractCheck implements Check
{
protected final PlayerData data;
private int vl;
private double buffer;
public final String className;
public final double MAX_BUFFER;
public final double BUFFER_DECAY;
public final double BUFFER_MULTIPLE_ON_FLAG;
public AbstractCheck(final PlayerData data) {
this.className = this.getClass().getSimpleName();
this.MAX_BUFFER = Config.MAX_BUFFERS.get(this.className);
this.BUFFER_DECAY = Config.BUFFER_DECAYS.get(this.className);
this.BUFFER_MULTIPLE_ON_FLAG = Config.BUFFER_MULTIPLES.get(this.className);
this.data = data;
}
public abstract void handle(final Packet p0);
public void fail(final Object info) {
this.shuffleHotbar();
this.rotateRandomly();
this.multiplyBuffer(this.BUFFER_MULTIPLE_ON_FLAG);
Vulcan.INSTANCE.getAlertExecutor().execute(() -> Vulcan.INSTANCE.getAlertManager().handleAlert(this, this.data, Objects.toString(info)));
}
public void fail() {
this.shuffleHotbar();
this.rotateRandomly();
this.multiplyBuffer(this.BUFFER_MULTIPLE_ON_FLAG);
Vulcan.INSTANCE.getAlertExecutor().execute(() -> Vulcan.INSTANCE.getAlertManager().handleAlert(this, this.data, ""));
}
public void punish() {
Vulcan.INSTANCE.getAlertExecutor().execute(() -> Vulcan.INSTANCE.getPunishmentManager().handlePunishment(this, this.data));
}
protected boolean isExempt(final ExemptType... exemptTypes) {
return this.data.getExemptProcessor().isExempt(exemptTypes);
}
public int ticks() {
return Vulcan.INSTANCE.getTickManager().getTicks();
}
public double increaseBuffer() {
Vulcan.INSTANCE.getAlertManager().handleVerbose(this, this.data);
return this.buffer = Math.min(10000.0, this.buffer + 1.0);
}
public double decreaseBufferBy(final double amount) {
return this.buffer = Math.max(0.0, this.buffer - amount);
}
public double increaseBufferBy(final double amount) {
return this.buffer = Math.min(10000.0, this.buffer + amount);
}
public void resetBuffer() {
this.buffer = 0.0;
}
public void multiplyBuffer(final double multiplier) {
this.buffer *= multiplier;
}
public void decayBuffer() {
this.decreaseBufferBy(this.BUFFER_DECAY);
}
public int hitTicks() {
return this.data.getCombatProcessor().getHitTicks();
}
public boolean attacking(final int ticks) {
return this.data.getCombatProcessor().getHitTicks() < ticks && this.data.getCombatProcessor().getTicksSinceAttack() < ticks * 6;
}
public CheckInfo getCheckInfo() {
if (this.getClass().isAnnotationPresent(CheckInfo.class)) {
return this.getClass().getAnnotation(CheckInfo.class);
}
ServerUtil.logError("CheckInfo annotation hasn't been added to the class " + this.className + ".");
return null;
}
public void debug(final Object object) {
ServerUtil.debug(object);
}
@Override
public String getCategory() {
String category = "";
if (this.getClass().getName().contains("combat")) {
category = "combat";
}
else if (this.getClass().getName().contains("movement")) {
category = "movement";
}
else if (this.getClass().getName().contains("player")) {
category = "player";
}
return category;
}
public boolean teleporting() {
return this.data.getActionProcessor().isTeleporting();
}
public boolean fuckedPosition() {
return this.data.getPositionProcessor().isFuckedPosition();
}
@Override
public String getName() {
return this.getCheckInfo().name().toLowerCase().replaceAll(" ", "");
}
@Override
public char getType() {
return Character.toLowerCase(this.getCheckInfo().type());
}
@Override
public String toString() {
return super.toString();
}
@Override
public int getVl() {
return this.vl;
}
@Override
public int getMaxVl() {
return Config.MAX_VIOLATIONS.get(this.className);
}
@Override
public int getMinimumVlToNotify() {
return Config.MINIMUM_VL_TO_NOTIFY.get(this.className);
}
@Override
public double getMaxBuffer() {
return this.MAX_BUFFER;
}
@Override
public String getDescription() {
return this.getCheckInfo().description();
}
@Override
public String getComplexType() {
return this.getCheckInfo().complexType();
}
@Override
public double getBufferDecay() {
return this.BUFFER_DECAY;
}
@Override
public int getAlertInterval() {
return Config.ALERT_INTERVAL.get(this.className);
}
@Override
public double getBufferMultiple() {
return this.BUFFER_MULTIPLE_ON_FLAG;
}
@Override
public boolean isExperimental() {
return this.getCheckInfo().experimental();
}
@Override
public boolean isPunishable() {
return Config.PUNISHABLE.get(this.className);
}
@Override
public String getDisplayName() {
return this.getCheckInfo().name();
}
@Override
public char getDisplayType() {
return this.getCheckInfo().type();
}
public void shuffleHotbar() {
final boolean shuffleHotbar = Config.HOTBAR_SHUFFLE.get(this.className);
final int minimumViolationsToShuffleHotbar = Config.HOTBAR_SHUFFLE_MINIMUM.get(this.className);
final int hotbarShuffleInterval = Config.HOTBAR_SHUFFLE_EVERY.get(this.className);
if (shuffleHotbar && this.vl > minimumViolationsToShuffleHotbar && this.vl % hotbarShuffleInterval == 0) {
PlayerUtil.shuffleHotbar(this.data.getPlayer());
}
}
public void rotateRandomly() {
final boolean randomRotation = Config.RANDOM_ROTATION.get(this.className);
final int minimumViolationsToRotateRandomly = Config.RANDOM_ROTATION_MINIMUM.get(this.className);
final int randomRotationInterval = Config.RANDOM_ROTATION_EVERY.get(this.className);
if (randomRotation && this.vl > minimumViolationsToRotateRandomly && this.vl % randomRotationInterval == 0) {
PlayerUtil.rotateRandomly(this.data.getPlayer());
}
}
public boolean elapsed(final int from, final int required) {
return Vulcan.INSTANCE.getTickManager().getTicks() - from > required;
}
public PlayerData getData() {
return this.data;
}
@Override
public double getBuffer() {
return this.buffer;
}
public String getClassName() {
return this.className;
}
public double getMAX_BUFFER() {
return this.MAX_BUFFER;
}
public double getBUFFER_DECAY() {
return this.BUFFER_DECAY;
}
public double getBUFFER_MULTIPLE_ON_FLAG() {
return this.BUFFER_MULTIPLE_ON_FLAG;
}
@Override
public void setVl(final int vl) {
this.vl = vl;
}
@Override
public void setBuffer(final double buffer) {
this.buffer = buffer;
}
}

View File

@ -0,0 +1,22 @@
package me.frep.vulcan.spigot.check.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface CheckInfo {
String name();
char type();
String complexType() default "N/A";
boolean experimental() default false;
boolean punish() default true;
String description() default "No description.";
}

View File

@ -0,0 +1,217 @@
package me.frep.vulcan.spigot.check.data;
import java.util.List;
import me.frep.vulcan.api.check.ICheckData;
public class CheckData implements ICheckData
{
private boolean enabled;
private boolean punishable;
private boolean broadcastPunishment;
private boolean hotbarShuffle;
private boolean randomRotation;
private int maxViolations;
private int alertInterval;
private int minimumVlToNotify;
private int maximumPing;
private int randomRotationMinimumVl;
private int hotbarShuffleMinimumVl;
private int randomRotationInterval;
private int hotbarShuffleInterval;
private double minimumTps;
private double maxBuffer;
private double bufferDecay;
private double bufferMultiple;
private List<String> punishmentCommands;
private String checkName;
public CheckData(final String checkName) {
this.checkName = checkName;
}
@Override
public String toString() {
return "{checkName=" + this.checkName + " enabled=" + this.enabled + " punishable=" + this.punishable + " broadcastPunishment=" + this.broadcastPunishment + "}";
}
@Override
public boolean isEnabled() {
return this.enabled;
}
@Override
public boolean isPunishable() {
return this.punishable;
}
@Override
public boolean isBroadcastPunishment() {
return this.broadcastPunishment;
}
@Override
public boolean isHotbarShuffle() {
return this.hotbarShuffle;
}
@Override
public boolean isRandomRotation() {
return this.randomRotation;
}
@Override
public int getMaxViolations() {
return this.maxViolations;
}
@Override
public int getAlertInterval() {
return this.alertInterval;
}
@Override
public int getMinimumVlToNotify() {
return this.minimumVlToNotify;
}
@Override
public int getMaxPing() {
return this.maximumPing;
}
@Override
public int getMinimumVlToRandomlyRotate() {
return this.randomRotationMinimumVl;
}
@Override
public int getMinimumVlToShuffleHotbar() {
return this.hotbarShuffleMinimumVl;
}
@Override
public double getMinimumTps() {
return this.minimumTps;
}
@Override
public double getMaxBuffer() {
return this.maxBuffer;
}
@Override
public double getBufferDecay() {
return this.bufferDecay;
}
@Override
public double getBufferMultiple() {
return this.bufferMultiple;
}
@Override
public List<String> getPunishmentCommands() {
return this.punishmentCommands;
}
@Override
public int getRandomRotationInterval() {
return this.randomRotationInterval;
}
public int getMaximumPing() {
return this.maximumPing;
}
public int getRandomRotationMinimumVl() {
return this.randomRotationMinimumVl;
}
public int getHotbarShuffleMinimumVl() {
return this.hotbarShuffleMinimumVl;
}
public int getHotbarShuffleInterval() {
return this.hotbarShuffleInterval;
}
public String getCheckName() {
return this.checkName;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
public void setPunishable(final boolean punishable) {
this.punishable = punishable;
}
public void setBroadcastPunishment(final boolean broadcastPunishment) {
this.broadcastPunishment = broadcastPunishment;
}
public void setHotbarShuffle(final boolean hotbarShuffle) {
this.hotbarShuffle = hotbarShuffle;
}
public void setRandomRotation(final boolean randomRotation) {
this.randomRotation = randomRotation;
}
public void setMaxViolations(final int maxViolations) {
this.maxViolations = maxViolations;
}
public void setAlertInterval(final int alertInterval) {
this.alertInterval = alertInterval;
}
public void setMinimumVlToNotify(final int minimumVlToNotify) {
this.minimumVlToNotify = minimumVlToNotify;
}
public void setMaximumPing(final int maximumPing) {
this.maximumPing = maximumPing;
}
public void setRandomRotationMinimumVl(final int randomRotationMinimumVl) {
this.randomRotationMinimumVl = randomRotationMinimumVl;
}
public void setHotbarShuffleMinimumVl(final int hotbarShuffleMinimumVl) {
this.hotbarShuffleMinimumVl = hotbarShuffleMinimumVl;
}
public void setRandomRotationInterval(final int randomRotationInterval) {
this.randomRotationInterval = randomRotationInterval;
}
public void setHotbarShuffleInterval(final int hotbarShuffleInterval) {
this.hotbarShuffleInterval = hotbarShuffleInterval;
}
public void setMinimumTps(final double minimumTps) {
this.minimumTps = minimumTps;
}
public void setMaxBuffer(final double maxBuffer) {
this.maxBuffer = maxBuffer;
}
public void setBufferDecay(final double bufferDecay) {
this.bufferDecay = bufferDecay;
}
public void setBufferMultiple(final double bufferMultiple) {
this.bufferMultiple = bufferMultiple;
}
public void setPunishmentCommands(final List<String> punishmentCommands) {
this.punishmentCommands = punishmentCommands;
}
public void setCheckName(final String checkName) {
this.checkName = checkName;
}
}

View File

@ -0,0 +1,32 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'A', complexType = "Slope", description = "Invalid pitch change.")
public class AimA extends AbstractCheck
{
public AimA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final boolean invalid = MathUtil.isExponentiallySmall(deltaPitch) && deltaYaw > 0.5f;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,30 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'B', complexType = "Modulo", description = "Invalid yaw change.")
public class AimB extends AbstractCheck
{
public AimB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final boolean invalid = deltaYaw > 0.0f && (deltaYaw % 0.25 == 0.0 || deltaYaw % 0.1 == 0.0);
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,31 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'C', complexType = "Repeated", description = "Repeated yaw values.")
public class AimC extends AbstractCheck
{
public AimC(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(3)) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float lastDeltaYaw = this.data.getRotationProcessor().getLastDeltaYaw();
final boolean invalid = deltaYaw > 1.25f && lastDeltaYaw > 1.25f && deltaYaw == lastDeltaYaw;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,45 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import org.bukkit.entity.Entity;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'D', complexType = "Straight", experimental = false, description = "Invalid pitch change.")
public class AimD extends AbstractCheck
{
public AimD(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(3)) {
final float pitch = this.data.getRotationProcessor().getPitch();
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final double distance = this.data.getCombatProcessor().getDistance();
final Entity entity = this.data.getCombatProcessor().getTarget();
if (entity == null || !(entity instanceof Player)) {
return;
}
final Player target = (Player)entity;
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(target);
if (targetData == null) {
return;
}
final boolean invalid = deltaYaw > 2.75f && deltaPitch == 0.0f && Math.abs(pitch) < 65.0f && distance > 1.0 && targetData.getPositionProcessor().getDeltaXZ() > 0.03;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,32 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'E', complexType = "Ratio", experimental = false, description = "Invalid yaw change.")
public class AimE extends AbstractCheck
{
public AimE(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final boolean invalid = MathUtil.isExponentiallySmall(deltaYaw) && deltaPitch > 0.125f;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,45 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import org.bukkit.entity.Entity;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'F', complexType = "Straight", description = "Invalid yaw change.")
public class AimF extends AbstractCheck
{
public AimF(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(3)) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final float pitch = this.data.getRotationProcessor().getPitch();
final double distance = this.data.getCombatProcessor().getDistance();
final Entity entity = this.data.getCombatProcessor().getTarget();
if (entity == null || !(entity instanceof Player)) {
return;
}
final Player target = (Player)entity;
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(target);
if (targetData == null) {
return;
}
final boolean invalid = deltaPitch == 0.0f && deltaYaw > 1.825f && Math.abs(pitch) < 60.0f && distance > 1.0 && targetData.getPositionProcessor().getDeltaXZ() > 0.03;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,32 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'G', complexType = "Ratio", description = "Too large yaw change.")
public class AimG extends AbstractCheck
{
public AimG(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(2)) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final float pitch = this.data.getRotationProcessor().getPitch();
final boolean invalid = deltaYaw > 15.0f && deltaPitch < 0.1 && Math.abs(pitch) < 65.0f;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,46 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import org.bukkit.entity.Entity;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'H', complexType = "Negative", experimental = false, description = "Invalid sensitivity.")
public class AimH extends AbstractCheck
{
public AimH(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final double finalSensitivity = this.data.getRotationProcessor().getFinalSensitivity();
final double deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final Entity entity = this.data.getCombatProcessor().getTarget();
if (entity == null || !(entity instanceof Player)) {
return;
}
final Player target = (Player)entity;
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(target);
if (targetData == null) {
return;
}
final boolean cinematic = this.isExempt(ExemptType.CINEMATIC);
final boolean tooLowSensitivity = this.data.getRotationProcessor().hasTooLowSensitivity();
final boolean invalid = finalSensitivity < -1.0 && deltaPitch < 20.0 && deltaPitch > 0.25 && deltaPitch > 1.25 && targetData.getPositionProcessor().getDeltaXZ() > 0.01;
if (invalid && !cinematic && !tooLowSensitivity) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("final=" + finalSensitivity + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,40 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'I', complexType = "Constant", experimental = false, description = "Not constant rotations.")
public class AimI extends AbstractCheck
{
public AimI(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final float lastDeltaPitch = this.data.getRotationProcessor().getLastDeltaPitch();
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final long expandedPitch = (long)(MathUtil.EXPANDER * deltaPitch);
final long expandedLastPitch = (long)(MathUtil.EXPANDER * lastDeltaPitch);
final boolean cinematic = this.isExempt(ExemptType.CINEMATIC);
final long gcd = MathUtil.getGcd(expandedPitch, expandedLastPitch);
final boolean tooLowSensitivity = this.data.getRotationProcessor().hasTooLowSensitivity();
final boolean validAngles = deltaYaw > 0.25f && deltaPitch > 0.25f && deltaPitch < 20.0f && deltaYaw < 20.0f;
final boolean invalid = !cinematic && gcd < 131072L;
if (invalid && validAngles && !tooLowSensitivity) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("rotation=" + gcd / 1000L + " deltaPitch=" + deltaPitch + " deltaYaw=" + deltaYaw);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,53 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'K', complexType = "Linear", experimental = false, description = "Not constant rotations.")
public class AimK extends AbstractCheck
{
public AimK(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final float lastDeltaYaw = this.data.getRotationProcessor().getLastDeltaYaw();
final float lastDeltaPitch = this.data.getRotationProcessor().getLastDeltaPitch();
final double divisorYaw = (double)MathUtil.getGcd((long)(deltaYaw * MathUtil.EXPANDER), (long)(lastDeltaYaw * MathUtil.EXPANDER));
final double divisorPitch = (double)MathUtil.getGcd((long)(deltaPitch * MathUtil.EXPANDER), (long)(lastDeltaPitch * MathUtil.EXPANDER));
final double constantYaw = divisorYaw / MathUtil.EXPANDER;
final double constantPitch = divisorPitch / MathUtil.EXPANDER;
final double currentX = deltaYaw / constantYaw;
final double currentY = deltaPitch / constantPitch;
final double previousX = lastDeltaYaw / constantYaw;
final double previousY = lastDeltaPitch / constantPitch;
if (deltaYaw > 0.1f && deltaPitch > 0.1f && deltaYaw < 20.0f && deltaPitch < 20.0f) {
final double moduloX = currentX % previousX;
final double moduloY = currentY % previousY;
final double floorModuloX = Math.abs(Math.floor(moduloX) - moduloX);
final double floorModuloY = Math.abs(Math.floor(moduloY) - moduloY);
final boolean invalidX = moduloX > 60.0 && floorModuloX > 0.1;
final boolean invalidY = moduloY > 60.0 && floorModuloY > 0.1;
final double sensitivity = this.data.getRotationProcessor().getSensitivity();
final boolean tooLowSensitivity = sensitivity < 100.0 && sensitivity > -1.0;
final boolean cinematic = this.isExempt(ExemptType.CINEMATIC);
if (invalidX && invalidY && !cinematic && !tooLowSensitivity) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,42 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'L', complexType = "Direction", description = "Switching directions too quickly.")
public class AimL extends AbstractCheck
{
private float lastDeltaPitch;
private int ticksSinceSwitchedDirection;
public AimL(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(3)) {
final float pitch = this.data.getRotationProcessor().getPitch();
final float lastPitch = this.data.getRotationProcessor().getLastPitch();
final float deltaPitch = pitch - lastPitch;
if ((deltaPitch < 0.0f && this.lastDeltaPitch > 0.0f) || (deltaPitch > 0.0f && this.lastDeltaPitch < 0.0f)) {
this.ticksSinceSwitchedDirection = 0;
}
else {
++this.ticksSinceSwitchedDirection;
}
final boolean invalid = this.ticksSinceSwitchedDirection == 0 && Math.abs(deltaPitch) > 5.0f;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaPitch=" + deltaPitch);
}
}
else {
this.resetBuffer();
}
this.lastDeltaPitch = deltaPitch;
}
}
}

View File

@ -0,0 +1,33 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'N', complexType = "Small Yaw", experimental = false, description = "Too small yaw change.")
public class AimN extends AbstractCheck
{
public AimN(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(3)) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final boolean invalid = deltaYaw < 0.05 && deltaYaw > 0.0f && deltaPitch == 0.0f;
final boolean exempt = this.isExempt(ExemptType.VEHICLE, ExemptType.BOAT);
if (invalid && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,31 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'O', complexType = "Small Yaw", description = "Too small pitch change.")
public class AimO extends AbstractCheck
{
public AimO(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(2)) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final boolean invalid = deltaPitch < 0.05 && deltaPitch > 0.0f && deltaYaw == 0.0f;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaPitch=" + deltaPitch + " deltaYaw=" + deltaYaw);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,33 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'P', complexType = "Yaw Acceleration", experimental = false, description = "Large yaw acceleration.")
public class AimP extends AbstractCheck
{
public AimP(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.attacking(3)) {
final float pitch = this.data.getRotationProcessor().getPitch();
final float yawAccel = this.data.getRotationProcessor().getYawAccel();
final float pitchAccel = this.data.getRotationProcessor().getPitchAccel();
final double distance = this.data.getCombatProcessor().getComplexDistance();
final boolean invalid = yawAccel > 20.0f && pitchAccel < 0.05 && Math.abs(pitch) < 60.0f && distance > 1.0;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("yawAccel=" + yawAccel + " pitchAccel=" + pitchAccel);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,48 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'Q', complexType = "GCD Modulo", description = "GCD bypass flaw detected.")
public class AimQ extends AbstractCheck
{
public AimQ(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final boolean validSensitivity = this.data.getRotationProcessor().hasValidSensitivity();
if (validSensitivity) {
final double mcpSensitivity = this.data.getRotationProcessor().getMcpSensitivity();
if (mcpSensitivity < 0.01) {
return;
}
final float f = (float)mcpSensitivity * 0.6f + 0.2f;
final float gcd = f * f * f * 1.2f;
final float yaw = this.data.getRotationProcessor().getYaw();
final float pitch = this.data.getRotationProcessor().getPitch();
final float adjustedYaw = yaw - yaw % gcd;
final float adjustedPitch = pitch - pitch % gcd;
final float yawDifference = Math.abs(yaw - adjustedYaw);
final float pitchDifference = Math.abs(pitch - adjustedPitch);
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final float combinedChange = deltaYaw + deltaPitch;
final double distance = this.data.getCombatProcessor().getDistance();
final boolean invalid = (yawDifference == 0.0f || pitchDifference == 0.0f) && combinedChange > 0.75f;
if (invalid && distance > 1.0) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("yawDifference=" + yawDifference + " pitchDifference=" + pitchDifference + " combined=" + combinedChange);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,19 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'R', complexType = "Divisor X", description = "Subtle aim assist modifications.")
public class AimR extends AbstractCheck
{
public AimR(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (!packet.isRotation() || this.hitTicks() < 3) {}
}
}

View File

@ -0,0 +1,46 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'S', complexType = "Divisor Y", experimental = false, description = "Subtle aim assist modifications.")
public class AimS extends AbstractCheck
{
public AimS(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final boolean validSensitivity = this.data.getRotationProcessor().hasValidSensitivity();
if (validSensitivity) {
final double mcpSensitivity = this.data.getRotationProcessor().getMcpSensitivity();
if (mcpSensitivity < 0.01) {
return;
}
final float f = (float)mcpSensitivity * 0.6f + 0.2f;
final float gcd = f * f * f * 1.2f;
if (gcd < 1.0E-4) {
return;
}
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final double deltaX = deltaYaw / gcd;
final double deltaY = deltaPitch / gcd;
final double floorDivisorX = Math.abs(Math.round(deltaX) - deltaX);
final double floorDivisorY = Math.abs(Math.round(deltaY) - deltaY);
if (floorDivisorY > 0.03 && floorDivisorX < 1.0E-4) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("divisorX=" + floorDivisorX + " divisorY=" + floorDivisorY);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,35 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'U', complexType = "GCD Flaw", description = "GCD bypass.")
public class AimU extends AbstractCheck
{
public AimU(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final boolean validSensitivity = this.data.getRotationProcessor().hasValidSensitivity();
if (validSensitivity) {
final double mcpSensitivity = this.data.getRotationProcessor().getMcpSensitivity();
final float f = (float)mcpSensitivity * 0.6f + 0.2f;
final float gcd = f * f * f * 1.2f;
final float yaw = this.data.getRotationProcessor().getYaw();
final float pitch = this.data.getRotationProcessor().getPitch();
final float adjustedYaw = yaw - yaw % gcd;
final float adjustedPitch = pitch - pitch % gcd;
final float yawDifference = Math.abs(yaw - adjustedYaw);
final float pitchDifference = Math.abs(pitch - adjustedPitch);
if (yawDifference == 0.01f || pitchDifference == 0.01f) {
this.fail("[I] yawDiff=" + yawDifference + " pitchDiff=" + pitchDifference);
}
}
}
}
}

View File

@ -0,0 +1,34 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'W', complexType = "Analysis", description = "Generic rotation analysis heuristic.")
public class AimW extends AbstractCheck
{
public AimW(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final int sensitivity = this.data.getRotationProcessor().getSensitivity();
final boolean cinematic = this.isExempt(ExemptType.CINEMATIC);
final boolean invalid = sensitivity < -10 && deltaYaw > 1.25f && deltaPitch > 1.25f;
if (invalid && !cinematic) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("sens=" + sensitivity + " deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,34 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'X', complexType = "Analysis", description = "Generic rotation analysis heuristic.")
public class AimX extends AbstractCheck
{
public AimX(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final int sensitivity = this.data.getRotationProcessor().getSensitivity();
final boolean cinematic = this.isExempt(ExemptType.CINEMATIC, ExemptType.SPECTATOR);
final boolean invalid = sensitivity > 205 && deltaYaw > 1.25f && deltaPitch > 1.25f;
if (invalid && !cinematic) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("sens=" + sensitivity + " deltaYaw=" + deltaYaw + " deltaPitch=" + deltaPitch);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,32 @@
package me.frep.vulcan.spigot.check.impl.combat.aim;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Aim", type = 'Y', complexType = "Rotation", description = "Generic rotation analysis heuristic.")
public class AimY extends AbstractCheck
{
public AimY(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isRotation() && this.hitTicks() < 3) {
final float lastFuckedYaw = this.data.getRotationProcessor().getLastFuckedPredictedYaw();
final float fuckedYaw = this.data.getRotationProcessor().getFuckedPredictedYaw();
final float difference = Math.abs(fuckedYaw - lastFuckedYaw);
final double distance = this.data.getCombatProcessor().getDistance();
final boolean exempt = this.isExempt(ExemptType.TELEPORT, ExemptType.DEATH, ExemptType.WORLD_CHANGE) || this.data.getActionProcessor().getSinceTeleportTicks() < 20;
if (exempt) {
return;
}
if (distance > 0.6 && difference > 20.0f && distance < 10.0) {
this.fail("diff=" + difference + " dist=" + distance);
}
}
}
}

View File

@ -0,0 +1,30 @@
package me.frep.vulcan.spigot.check.impl.combat.autoblock;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Block", type = 'A', complexType = "Sequence", description = "Attacked while sending BlockPlace packet.")
public class AutoBlockA extends AbstractCheck
{
public AutoBlockA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
final boolean invalid = this.data.getActionProcessor().isPlacing();
final boolean exempt = this.isExempt(ExemptType.CLIENT_VERSION);
if (invalid && !exempt) {
this.fail();
}
}
}
}
}

View File

@ -0,0 +1,30 @@
package me.frep.vulcan.spigot.check.impl.combat.autoblock;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Block", type = 'B', complexType = "Packet", description = "Attacked while sending BlockDig packet.")
public class AutoBlockB extends AbstractCheck
{
public AutoBlockB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
final boolean invalid = this.data.getActionProcessor().isBlocking();
final boolean exempt = this.isExempt(ExemptType.CLIENT_VERSION);
if (invalid && !exempt) {
this.fail();
}
}
}
}
}

View File

@ -0,0 +1,36 @@
package me.frep.vulcan.spigot.check.impl.combat.autoblock;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Block", type = 'C', complexType = "Order", description = "Attacked while sending BlockDig packet.")
public class AutoBlockC extends AbstractCheck
{
public AutoBlockC(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
final boolean sword = this.data.getPlayer().getItemInHand().getType().toString().contains("SWORD");
final boolean invalid = this.data.getActionProcessor().isSendingDig();
final boolean exempt = this.isExempt(ExemptType.CLIENT_VERSION);
if (invalid && sword && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail();
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,42 @@
package me.frep.vulcan.spigot.check.impl.combat.autoblock;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Block", type = 'D', complexType = "Order", description = "Invalid attack order.")
public class AutoBlockD extends AbstractCheck
{
private boolean interacting;
private boolean attacking;
public AutoBlockD(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying()) {
this.attacking = false;
this.interacting = false;
}
else if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
this.attacking = true;
}
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.INTERACT || wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.INTERACT_AT) {
this.interacting = true;
}
}
else if (packet.isBlockPlace()) {
final boolean exempt = this.isExempt(ExemptType.CLIENT_VERSION);
if (!exempt && this.attacking && !this.interacting) {
this.fail("a=" + this.attacking + " i=" + this.interacting);
}
}
}
}

View File

@ -0,0 +1,42 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import me.frep.vulcan.spigot.config.Config;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'A', complexType = "Limit", description = "Left clicking too quickly.")
public class AutoClickerA extends AbstractCheck
{
private final Deque<Long> samples;
private long lastSwing;
public AutoClickerA(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
this.lastSwing = 0L;
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER_NON_DIG)) {
final long now = System.currentTimeMillis();
final long delay = now - this.lastSwing;
this.samples.add(delay);
if (this.samples.size() == 20) {
final double cps = MathUtil.getCps(this.samples);
if (cps > Config.AUTOCLICKER_A_MAX_CPS && cps > 5.0) {
this.fail("cps=" + cps);
}
this.samples.clear();
}
this.lastSwing = now;
}
}
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'B', complexType = "Deviation", description = "Too low standard deviation.")
public class AutoClickerB extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerB(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double deviation = MathUtil.getStandardDeviation(this.samples);
final double average = MathUtil.getAverage(this.samples);
if (deviation < 167.0) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deviation=" + deviation + " average=" + average);
}
else {
this.decayBuffer();
}
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'C', complexType = "Rounded", description = "Rounded CPS values.")
public class AutoClickerC extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerC(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 20) {
final double cps = MathUtil.getCps(this.samples);
final double difference = Math.abs(Math.round(cps) - cps);
if (difference < 0.08) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,46 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'D', complexType = "Skewness", description = "Too low skewness values.")
public class AutoClickerD extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerD(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double skewness = MathUtil.getSkewness(this.samples);
if (skewness < -0.01) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("skewness" + skewness);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'E', complexType = "Variance", description = "Too low variance.")
public class AutoClickerE extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerE(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double variance = MathUtil.getVariance(this.samples);
final double scaled = variance / 1000.0;
if (scaled < 28.2) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("variance=" + scaled);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,46 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'F', complexType = "Distinct", description = "Not enough distinct values.")
public class AutoClickerF extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerF(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final int distinct = MathUtil.getDistinct(this.samples);
if (distinct < 13) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("distinct=" + distinct);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'G', complexType = "Outliers", description = "Too low outliers.")
public class AutoClickerG extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerG(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final int outliers = (int)this.samples.stream().filter(l -> l > 150L).count();
final double average = MathUtil.getAverage(this.samples);
if (outliers < 3) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("outliers=" + outliers + " average=" + average);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,49 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'H', complexType = "Average Deviation", description = "Similar deviation values.")
public class AutoClickerH extends AbstractCheck
{
private final Deque<Long> samples;
private double lastDeviation;
public AutoClickerH(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 20) {
final double deviation = MathUtil.getStandardDeviation(this.samples);
final double difference = Math.abs(deviation - this.lastDeviation);
if (difference < 7.52) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference);
}
}
else {
this.decayBuffer();
}
this.lastDeviation = deviation;
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,47 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'I', complexType = "Kurtosis", description = "Too low kurtosis.")
public class AutoClickerI extends AbstractCheck
{
private final Deque<Long> samples;
public AutoClickerI(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double kurtosis = MathUtil.getKurtosis(this.samples);
final double scaled = kurtosis / 1000.0;
if (scaled < 41.78) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("kurtosis=" + scaled);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,46 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collections;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.List;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'J', complexType = "Range", description = "Impossible consistency.")
public class AutoClickerJ extends AbstractCheck
{
private final List<Long> samples;
public AutoClickerJ(final PlayerData data) {
super(data);
this.samples = Lists.newArrayList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 10) {
Collections.sort(this.samples);
final long range = this.samples.get(this.samples.size() - 1) - this.samples.get(0);
if (range < 50L) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("range=" + range);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,49 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'K', complexType = "Average Difference", description = "Similar average values.")
public class AutoClickerK extends AbstractCheck
{
private final Deque<Long> samples;
private double lastAverage;
public AutoClickerK(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double average = MathUtil.getAverage(this.samples);
final double difference = Math.abs(average - this.lastAverage);
if (difference < 2.56) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference);
}
}
else {
this.decayBuffer();
}
this.lastAverage = average;
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,49 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'L', complexType = "Kurtosis Difference", description = "Similar kurtosis values.")
public class AutoClickerL extends AbstractCheck
{
private final Deque<Long> samples;
private double lastKurtosis;
public AutoClickerL(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double kurtosis = MathUtil.getKurtosis(this.samples) / 1000.0;
final double difference = Math.abs(kurtosis - this.lastKurtosis);
if (difference < 8.35) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference);
}
}
else {
this.decayBuffer();
}
this.lastKurtosis = kurtosis;
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,49 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'M', complexType = "Variance Difference", description = "Similar variance values.")
public class AutoClickerM extends AbstractCheck
{
private final Deque<Long> samples;
private double lastVariance;
public AutoClickerM(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 50) {
final double variance = MathUtil.getVariance(this.samples) / 1000.0;
final double difference = Math.abs(variance - this.lastVariance);
if (difference < 5.28) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference);
}
}
else {
this.decayBuffer();
}
this.lastVariance = variance;
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,48 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.util.type.EvictingList;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'N', complexType = "Deviation Difference", description = "Low deviation difference.")
public class AutoClickerN extends AbstractCheck
{
private final EvictingList<Long> samples;
private double lastDeviation;
public AutoClickerN(final PlayerData data) {
super(data);
this.samples = new EvictingList<Long>(25);
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.isFull()) {
final double deviation = MathUtil.getStandardDeviation(this.samples);
final double difference = Math.abs(deviation - this.lastDeviation);
final double average = Math.abs(deviation + this.lastDeviation) / 2.0;
if (difference < 0.25 && average < 150.0) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference + " average=" + average);
}
}
else {
this.decayBuffer();
}
this.lastDeviation = deviation;
}
}
}
}

View File

@ -0,0 +1,54 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'O', complexType = "Spikes", description = "Impossible spike in CPS.")
public class AutoClickerO extends AbstractCheck
{
private final Deque<Long> samples;
private double lastCps;
public AutoClickerO(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
this.lastCps = -1.0;
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 10) {
final double cps = MathUtil.getCps(this.samples);
if (this.lastCps > 0.0) {
final double difference = Math.abs(cps - this.lastCps);
final double average = (this.lastCps + cps) / 2.0;
final boolean invalid = average > 9.25 && difference > 2.8;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("average=" + average + " difference=" + difference);
}
}
else {
this.decayBuffer();
}
}
this.lastCps = cps;
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,54 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.Deque;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'P', complexType = "Identical", description = "Identical statistical values.")
public class AutoClickerP extends AbstractCheck
{
private final Deque<Long> samples;
private double lastDeviation;
private double lastSkewness;
private double lastKurtosis;
public AutoClickerP(final PlayerData data) {
super(data);
this.samples = Lists.newLinkedList();
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.size() == 15) {
final double deviation = MathUtil.getStandardDeviation(this.samples);
final double skewness = MathUtil.getSkewness(this.samples);
final double kurtosis = MathUtil.getKurtosis(this.samples);
if (deviation == this.lastDeviation && skewness == this.lastSkewness && kurtosis == this.lastKurtosis) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail();
}
}
else {
this.resetBuffer();
}
this.lastDeviation = deviation;
this.lastSkewness = skewness;
this.lastKurtosis = kurtosis;
this.samples.clear();
}
}
}
}

View File

@ -0,0 +1,48 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.util.type.EvictingList;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'Q', complexType = "Average Deviation", description = "Too low average deviation.")
public class AutoClickerQ extends AbstractCheck
{
private final EvictingList<Long> samples;
private double lastDeviation;
public AutoClickerQ(final PlayerData data) {
super(data);
this.samples = new EvictingList<Long>(40);
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.isFull()) {
final double deviation = MathUtil.getStandardDeviation(this.samples);
final double difference = Math.abs(deviation - this.lastDeviation);
final double average = Math.abs(deviation + this.lastDeviation) / 2.0;
if (difference < 3.0 && average < 150.0) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("difference=" + difference + " average=" + average);
}
}
else {
this.decayBuffer();
}
this.lastDeviation = deviation;
}
}
}
}

View File

@ -0,0 +1,45 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.util.type.EvictingList;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'R', complexType = "Consistency", description = "Impossible consistency.")
public class AutoClickerR extends AbstractCheck
{
private final EvictingList<Long> samples;
public AutoClickerR(final PlayerData data) {
super(data);
this.samples = new EvictingList<Long>(30);
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.isFull()) {
final int outliers = (int)this.samples.stream().filter(l -> l > 150L).count();
final double average = MathUtil.getAverage(this.samples);
if (outliers == 0) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("outliers=" + outliers + " average=" + average);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,44 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.util.type.EvictingList;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'S', complexType = "Distinct", description = "Checks for amount of distinct delays.")
public class AutoClickerS extends AbstractCheck
{
private final EvictingList<Long> samples;
public AutoClickerS(final PlayerData data) {
super(data);
this.samples = new EvictingList<Long>(25);
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.isFull()) {
final int distinct = MathUtil.getDistinct(this.samples);
if (distinct < 6) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("distinct=" + distinct);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,46 @@
package me.frep.vulcan.spigot.check.impl.combat.autoclicker;
import me.frep.vulcan.spigot.config.Config;
import java.util.Collection;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.util.type.EvictingList;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Auto Clicker", type = 'T', complexType = "Kurtosis", description = "Too low kurtosis")
public class AutoClickerT extends AbstractCheck
{
private final EvictingList<Long> samples;
public AutoClickerT(final PlayerData data) {
super(data);
this.samples = new EvictingList<Long>(25);
}
@Override
public void handle(final Packet packet) {
if (packet.isArmAnimation() && !this.isExempt(ExemptType.AUTOCLICKER)) {
final long delay = this.data.getClickProcessor().getDelay();
if (delay > 5000L) {
this.samples.clear();
return;
}
this.samples.add(delay);
if (this.samples.isFull()) {
final double kurtosis = MathUtil.getKurtosis(this.samples) / 1000.0;
this.data.getClickProcessor().setKurtosis(kurtosis);
if (kurtosis < Config.AUTOCLICKER_T_MIN_KURTOSIS) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("kurtosis=" + kurtosis);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,36 @@
package me.frep.vulcan.spigot.check.impl.combat.criticals;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Criticals", type = 'A', complexType = "Ground", description = "Tried to hit Critical hit on ground.")
public class CriticalsA extends AbstractCheck
{
public CriticalsA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity() && this.hitTicks() < 2) {
final double deltaY = Math.abs(this.data.getPositionProcessor().getDeltaY());
final double modulo = this.data.getPositionProcessor().getY() % 0.015625;
final boolean exempt = this.isExempt(ExemptType.LIQUID, ExemptType.TRAPDOOR, ExemptType.COLLIDING_VERTICALLY, ExemptType.TELEPORT, ExemptType.BOAT, ExemptType.TELEPORT, ExemptType.WEB, ExemptType.ENDER_PEARL, ExemptType.CHORUS_FRUIT, ExemptType.ELYTRA, ExemptType.SERVER_POSITION, ExemptType.CARPET, ExemptType.VEHICLE, ExemptType.FARMLAND, ExemptType.GLIDING, ExemptType.SLAB) || this.data.getPositionProcessor().isNearPath();
if (Math.abs(deltaY - 7.504558659832128E-4) < 0.001) {
return;
}
final boolean invalid = (deltaY < 0.001 && deltaY > 0.0 && modulo < 1.0E-5) || deltaY == 0.0625;
if (invalid && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaY=" + deltaY + " modulo=" + modulo);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,32 @@
package me.frep.vulcan.spigot.check.impl.combat.criticals;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Criticals", type = 'B', complexType = "Modulo", description = "Tried to hit Critical hit on ground.")
public class CriticalsB extends AbstractCheck
{
public CriticalsB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity() && this.hitTicks() < 2) {
final double modulo = this.data.getPositionProcessor().getY() % 0.015625;
final boolean invalid = modulo < 1.0E-5 && modulo > 0.0;
final boolean exempt = this.isExempt(ExemptType.LIQUID, ExemptType.TRAPDOOR, ExemptType.COLLIDING_VERTICALLY, ExemptType.BOAT, ExemptType.TELEPORT, ExemptType.WEB, ExemptType.ENDER_PEARL, ExemptType.CHORUS_FRUIT, ExemptType.SERVER_POSITION, ExemptType.VEHICLE, ExemptType.FLIGHT, ExemptType.SLAB);
if (invalid && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("modulo=" + modulo);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,45 @@
package me.frep.vulcan.spigot.check.impl.combat.fastbow;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.ServerUtil;
import org.bukkit.entity.Arrow;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Fast Bow", type = 'A', complexType = "Limit", description = "Shooting a bow too quickly")
public class FastBowA extends AbstractCheck
{
private long lastShot;
public FastBowA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isProjectileLaunchEvent()) {
final ProjectileLaunchEvent event = (ProjectileLaunchEvent)packet.getRawPacket().getRawNMSPacket();
if (event.getEntity() instanceof Arrow) {
final Arrow arrow = (Arrow)event.getEntity();
final boolean crossbow = this.data.getPlayer().getItemInHand().getType().toString().contains("CROSS") || (ServerUtil.isHigherThan1_9() && this.data.getPlayer().getInventory().getItemInOffHand().getType().toString().contains("CROSS"));
final boolean holdingBow = this.data.getPlayer().getItemInHand().getType().toString().contains("BOW") || (ServerUtil.isHigherThan1_9() && this.data.getPlayer().getInventory().getItemInOffHand().getType().toString().contains("BOW"));
if (arrow.getVelocity().length() > 2.0 && !crossbow && holdingBow) {
final long delay = System.currentTimeMillis() - this.lastShot;
final boolean exempt = this.isExempt(ExemptType.FAST);
if (delay < 750L && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("length=" + arrow.getVelocity().length() + " delay=" + delay);
}
}
else {
this.decayBuffer();
}
this.lastShot = System.currentTimeMillis();
}
}
}
}
}

View File

@ -0,0 +1,88 @@
package me.frep.vulcan.spigot.check.impl.combat.hitbox;
import me.frep.vulcan.spigot.util.type.Pair;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Player;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Hitbox", type = 'A', complexType = "History", description = "Attacked while not looking at target.")
public class HitboxA extends AbstractCheck
{
private boolean attacking;
public HitboxA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK || !(wrapper.getEntity() instanceof Player)) {
return;
}
this.attacking = true;
}
else if (packet.isFlying()) {
if (this.attacking) {
final int ticks = Vulcan.INSTANCE.getTickManager().getTicks();
final int pingTicks = MathUtil.getPingInTicks(this.data);
final double x = this.data.getPositionProcessor().getX();
final double z = this.data.getPositionProcessor().getZ();
final Vector origin = new Vector(x, 0.0, z);
final double angle = this.data.getCombatProcessor().getTargetLocations().stream().filter(pair -> Math.abs(ticks - pair.getY() - pingTicks) < 3).mapToDouble(pair -> {
final Vector targetLocation = pair.getX().toVector().setY(0.0);
final Vector direction = targetLocation.clone().subtract(origin);
final Vector target = this.getDirection(this.data.getRotationProcessor().getYaw(), this.data.getRotationProcessor().getPitch()).setY(0.0);
return (double)direction.angle(target);
}).min().orElse(-1.0);
final double distance = this.data.getCombatProcessor().getDistance();
if (angle == -1.0) {
this.decreaseBufferBy(0.025);
}
else {
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(this.data.getCombatProcessor().getTrackedPlayer());
if (targetData == null) {
return;
}
final boolean targetExempt = targetData.getExemptProcessor().isExempt(ExemptType.VEHICLE, ExemptType.BOAT);
double maxAngle = Config.HITBOX_A_MAX_ANGLE;
if (System.currentTimeMillis() - this.data.getConnectionProcessor().getLastFast() < 1500L) {
maxAngle += 0.125;
}
final boolean exempt = this.isExempt(ExemptType.CREATIVE, ExemptType.GLIDING, ExemptType.VEHICLE);
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
if (angle > maxAngle && distance > 1.5 && distance < 10.0 && !exempt && !targetExempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("angle=" + angle + " distance=" + distance + " dYaw=" + deltaYaw);
}
}
else {
this.decayBuffer();
}
}
}
this.attacking = false;
}
}
private Vector getDirection(final float yaw, final float pitch) {
final Vector vector = new Vector();
final double rotX = yaw;
final double rotY = pitch;
vector.setY(-Math.sin(Math.toRadians(rotY)));
final double xz = Math.cos(Math.toRadians(rotY));
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
return vector;
}
}

View File

@ -0,0 +1,69 @@
package me.frep.vulcan.spigot.check.impl.combat.hitbox;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.config.Config;
import org.bukkit.util.Vector;
import me.frep.vulcan.spigot.Vulcan;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Hitbox", type = 'B', complexType = "Simple", description = "Attacked while not looking at target.")
public class HitboxB extends AbstractCheck
{
private boolean attacking;
private Player target;
public HitboxB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK || !(wrapper.getEntity() instanceof Player)) {
return;
}
this.target = (Player)wrapper.getEntity();
this.attacking = true;
}
else if (packet.isFlying()) {
if (this.attacking && this.target != null) {
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(this.target);
if (targetData == null) {
return;
}
final double deltaX = targetData.getPositionProcessor().getX() - this.data.getPositionProcessor().getX();
final double deltaZ = targetData.getPositionProcessor().getZ() - this.data.getPositionProcessor().getZ();
final float yaw = this.data.getRotationProcessor().getYaw();
final double directionX = -Math.sin(yaw * 3.1415927f / 180.0f) * 1.0 * 0.5;
final double directionZ = Math.cos(yaw * 3.1415927f / 180.0f) * 1.0 * 0.5;
final Vector direction = new Vector(directionX, 0.0, directionZ);
final Vector positionDifference = new Vector(deltaX, 0.0, deltaZ);
final double distance = this.data.getCombatProcessor().getDistance();
final double angle = Math.toDegrees(positionDifference.angle(direction));
double maxAngle = Config.HITBOX_B_MAX_ANGLE;
double maxDistance = 1.25;
if (System.currentTimeMillis() - this.data.getConnectionProcessor().getLastFast() < 1500L) {
maxAngle += 0.125;
maxDistance += 0.1;
}
final boolean targetExempt = targetData.getExemptProcessor().isExempt(ExemptType.VEHICLE, ExemptType.BOAT);
final boolean exempt = this.isExempt(ExemptType.CREATIVE, ExemptType.CREATIVE, ExemptType.VEHICLE);
if (angle > maxAngle && distance > 1.3 && distance < 10.0 && !exempt && !targetExempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("angle=" + angle + " distance=" + distance);
}
}
else {
this.decayBuffer();
}
}
this.attacking = false;
}
}
}

View File

@ -0,0 +1,51 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'A', complexType = "Post", description = "Post UseEntity packets.")
public class KillAuraA extends AbstractCheck
{
private long lastFlying;
private boolean sent;
public KillAuraA(final PlayerData data) {
super(data);
this.lastFlying = 0L;
this.sent = false;
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying()) {
final long delay = System.currentTimeMillis() - this.lastFlying;
if (this.sent) {
final boolean exempt = this.isExempt(ExemptType.SPECTATOR);
if (delay > 40L && delay < 100L && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("delay=" + delay);
}
}
else {
this.decayBuffer();
}
this.sent = false;
}
this.lastFlying = System.currentTimeMillis();
}
else if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
return;
}
final long delay2 = System.currentTimeMillis() - this.lastFlying;
if (delay2 < 10L) {
this.sent = true;
}
}
}
}

View File

@ -0,0 +1,41 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.utils.player.ClientVersion;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.util.PlayerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'B', complexType = "Acceleration", experimental = false, description = "Invalid acceleration.")
public class KillAuraB extends AbstractCheck
{
public KillAuraB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isPosition() && this.hitTicks() < 3) {
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final double acceleration = this.data.getPositionProcessor().getAcceleration();
final float baseSpeed = PlayerUtil.getBaseSpeed(this.data, 0.21f);
final long swingDelay = this.data.getClickProcessor().getDelay();
final boolean sprinting = this.data.getActionProcessor().isSprinting();
final boolean validTarget = this.data.getCombatProcessor().getTarget() != null && this.data.getCombatProcessor().getTarget() instanceof Player;
final boolean validVersion = PlayerUtil.getClientVersion(this.data.getPlayer()).isLowerThan(ClientVersion.v_1_9);
final boolean exempt = this.isExempt(ExemptType.SOUL_SAND);
final boolean invalid = acceleration < 0.0025 && sprinting && deltaXZ > baseSpeed && swingDelay < 500L && validTarget && validVersion;
if (invalid && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("a=" + acceleration);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,35 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'C', complexType = "Head Snap", experimental = false, description = "Invalid acceleration.")
public class KillAuraC extends AbstractCheck
{
public KillAuraC(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isPosition() && this.hitTicks() < 3) {
final double acceleration = this.data.getPositionProcessor().getAcceleration();
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final float deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final float deltaPitch = this.data.getRotationProcessor().getDeltaPitch();
final boolean validTarget = this.data.getCombatProcessor().getTarget() instanceof Player;
final boolean invalid = acceleration < 0.001 && deltaYaw > 10.0f && deltaPitch > 26.5 && validTarget && deltaXZ > 0.0;
if (invalid) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("accel=" + acceleration + " deltaYaw=" + deltaYaw);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,38 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'D', complexType = "Multi Aura", experimental = false, description = "Attacked two entities at once.")
public class KillAuraD extends AbstractCheck
{
private int lastEntityId;
private int ticks;
public KillAuraD(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
return;
}
final boolean exempt = this.isExempt(ExemptType.CLIENT_VERSION, ExemptType.SERVER_VERSION);
final int id = wrapper.getEntityId();
if (id != this.lastEntityId && !exempt && ++this.ticks > 1) {
this.fail("id=" + id + " lastId=" + this.lastEntityId);
}
this.lastEntityId = id;
}
else if (packet.isFlying()) {
this.ticks = 0;
}
}
}

View File

@ -0,0 +1,57 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'F', complexType = "Switch", experimental = false, description = "Switching targets too quickly.")
public class KillAuraF extends AbstractCheck
{
private int lastEntityId;
private int hits;
private int swings;
private long lastSwitch;
public KillAuraF(final PlayerData data) {
super(data);
this.lastSwitch = -1L;
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
return;
}
if (wrapper.getEntityId() != this.lastEntityId) {
this.lastSwitch = System.currentTimeMillis();
}
++this.hits;
this.lastEntityId = wrapper.getEntityId();
}
else if (packet.isArmAnimation()) {
++this.swings;
}
else if (packet.isFlying() && this.hitTicks() < 2 && this.swings > 0) {
final double ratio = this.hits / (double)this.swings * 100.0;
final double deltaYaw = this.data.getRotationProcessor().getDeltaYaw();
final long delay = System.currentTimeMillis() - this.lastSwitch;
if (this.hits > 20 && ratio > 85.0 && delay < 5L && deltaYaw > 15.0) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("ratio=" + ratio + " delay=" + delay);
}
}
else {
this.decayBuffer();
}
if (this.hits > 40 || this.swings > 40) {
final int n = 0;
this.swings = n;
this.hits = n;
}
}
}
}

View File

@ -0,0 +1,40 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import me.frep.vulcan.spigot.util.PlayerUtil;
import io.github.retrooper.packetevents.packetwrappers.play.in.clientcommand.WrappedPacketInClientCommand;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'H', complexType = "Inventory", experimental = false, description = "Attacked while opening inventory.")
public class KillAuraH extends AbstractCheck
{
private boolean attacked;
public KillAuraH(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying()) {
this.attacked = false;
}
else if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
this.attacked = true;
}
}
else if (packet.isClientCommand()) {
final WrappedPacketInClientCommand wrapper2 = new WrappedPacketInClientCommand(packet.getRawPacket());
if (wrapper2.getClientCommand() == WrappedPacketInClientCommand.ClientCommand.OPEN_INVENTORY_ACHIEVEMENT && this.attacked) {
if (!PlayerUtil.isHigherThan1_9(this.data.getPlayer())) {
this.fail();
}
}
}
}
}

View File

@ -0,0 +1,53 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'J', complexType = "Frequency", experimental = false, description = "Attack frequency.")
public class KillAuraJ extends AbstractCheck
{
private int movements;
private int lastMovements;
private int total;
private int invalid;
public KillAuraJ(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
final boolean proper = this.data.getClickProcessor().getCps() > 7.2 && this.movements < 4 && this.lastMovements < 4;
if (proper) {
final boolean flag = this.movements == this.lastMovements;
if (flag) {
++this.invalid;
}
if (++this.total == 30) {
if (this.invalid > 28) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("invalid=" + this.invalid);
}
}
else {
this.decayBuffer();
}
this.invalid = 0;
this.total = 0;
}
}
this.lastMovements = this.movements;
this.movements = 0;
}
}
else if (packet.isFlying()) {
++this.movements;
}
}
}

View File

@ -0,0 +1,49 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import java.util.Collections;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import com.google.common.collect.Lists;
import me.frep.vulcan.spigot.data.PlayerData;
import java.util.List;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'K', complexType = "Pattern", description = "Attack pattern.")
public class KillAuraK extends AbstractCheck
{
private final List<Long> samples;
private long lastAttack;
public KillAuraK(final PlayerData data) {
super(data);
this.samples = Lists.newArrayList();
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK || this.isExempt(ExemptType.FAST)) {
return;
}
final long delay = System.currentTimeMillis() - this.lastAttack;
this.samples.add(delay);
if (this.samples.size() == 10) {
Collections.sort(this.samples);
final long range = this.samples.get(this.samples.size() - 1) - this.samples.get(0);
if (range < 50L) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("range=" + range);
}
}
else {
this.decayBuffer();
}
this.samples.clear();
}
this.lastAttack = System.currentTimeMillis();
}
}
}

View File

@ -0,0 +1,42 @@
package me.frep.vulcan.spigot.check.impl.combat.killaura;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import io.github.retrooper.packetevents.utils.player.ClientVersion;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.util.PlayerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Kill Aura", type = 'L', complexType = "Strafe", experimental = true, description = "Impossible strafe.")
public class KillAuraL extends AbstractCheck
{
public KillAuraL(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isPosition() && this.hitTicks() < 3) {
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final double acceleration = this.data.getPositionProcessor().getAcceleration();
final float baseSpeed = PlayerUtil.getBaseSpeed(this.data, 0.275f);
final long swingDelay = this.data.getClickProcessor().getDelay();
final boolean sprinting = this.data.getActionProcessor().isSprinting();
final boolean validTarget = this.data.getCombatProcessor().getTarget() != null && this.data.getCombatProcessor().getTarget() instanceof Player;
final boolean validVersion = PlayerUtil.getClientVersion(this.data.getPlayer()) != null && PlayerUtil.getClientVersion(this.data.getPlayer()).isLowerThan(ClientVersion.v_1_9);
final boolean combo = this.data.getPlayer().getMaximumNoDamageTicks() < 18 || (validTarget && ((Player)this.data.getCombatProcessor().getTarget()).getMaximumNoDamageTicks() < 18);
final boolean exempt = this.isExempt(ExemptType.SOUL_SAND);
final boolean invalid = acceleration < 0.0025 && !sprinting && deltaXZ > baseSpeed && swingDelay < 500L && validTarget && validVersion;
if (invalid && !exempt && !combo) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("d=" + deltaXZ + " a=" + acceleration + " s=" + swingDelay);
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,74 @@
package me.frep.vulcan.spigot.check.impl.combat.reach;
import me.frep.vulcan.spigot.util.type.Pair;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Player;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Reach", type = 'A', complexType = "History", description = "Hit from too far away.")
public class ReachA extends AbstractCheck
{
private boolean attacking;
public ReachA(final PlayerData data) {
super(data);
this.attacking = true;
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK || !(wrapper.getEntity() instanceof Player)) {
return;
}
this.attacking = true;
}
else if (packet.isFlying() && this.attacking) {
final int ticks = Vulcan.INSTANCE.getTickManager().getTicks();
final int pingTicks = MathUtil.getPingInTicks(this.data);
final double x = this.data.getPositionProcessor().getX();
final double z = this.data.getPositionProcessor().getZ();
final Vector origin = new Vector(x, 0.0, z);
final double distance = this.data.getCombatProcessor().getTargetLocations().stream().filter(pair -> Math.abs(ticks - pair.getY() - pingTicks) < 3).mapToDouble(pair -> {
final Vector victimVector = pair.getX().toVector().setY(0);
return origin.distance(victimVector) - 0.52;
}).min().orElse(-1.0);
if (distance == -1.0) {
this.decreaseBufferBy(0.025);
}
else {
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(this.data.getCombatProcessor().getTrackedPlayer());
if (targetData == null) {
return;
}
final boolean knockback = this.data.getPlayer().getItemInHand().getEnchantmentLevel(Enchantment.KNOCKBACK) > 0;
final boolean exempt = this.isExempt(ExemptType.CREATIVE, ExemptType.VEHICLE, ExemptType.BOAT);
final boolean targetExempt = targetData.getExemptProcessor().isExempt(ExemptType.VEHICLE, ExemptType.BOAT);
double max = Config.REACH_A_MAX_REACH;
if (System.currentTimeMillis() - this.data.getConnectionProcessor().getLastFast() < 1500L) {
max += 1.15;
}
if (distance > max && distance < 8.0 && !knockback && !exempt && !targetExempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("distance=" + distance);
}
}
else {
this.decayBuffer();
}
}
this.attacking = false;
}
}
}

View File

@ -0,0 +1,87 @@
package me.frep.vulcan.spigot.check.impl.combat.reach;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.PlayerUtil;
import me.frep.vulcan.spigot.config.Config;
import org.bukkit.util.Vector;
import me.frep.vulcan.spigot.Vulcan;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import org.bukkit.entity.Player;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Reach", type = 'B', complexType = "Simple", description = "Hit from too far away.")
public class ReachB extends AbstractCheck
{
private boolean attacking;
private Player target;
public ReachB(final PlayerData data) {
super(data);
this.attacking = false;
}
@Override
public void handle(final Packet packet) {
if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper = this.data.getUseEntityWrapper();
if (wrapper.getAction() != WrappedPacketInUseEntity.EntityUseAction.ATTACK || !(wrapper.getEntity() instanceof Player)) {
this.target = null;
this.attacking = false;
return;
}
this.attacking = true;
this.target = (Player)wrapper.getEntity();
}
else if (packet.isFlying() && this.attacking && this.target != null) {
final PlayerData targetData = Vulcan.INSTANCE.getPlayerDataManager().getPlayerData(this.target);
if (targetData == null) {
return;
}
final double x = this.data.getPositionProcessor().getX();
final double y = this.data.getPositionProcessor().getY();
final double z = this.data.getPositionProcessor().getZ();
final Vector origin = new Vector(x, 0.0, z);
final double targetX = targetData.getPositionProcessor().getX();
final double targetY = targetData.getPositionProcessor().getY();
final double targetZ = targetData.getPositionProcessor().getZ();
final Vector targetVector = new Vector(targetX, 0.0, targetZ);
final double yDifference = Math.abs(y - targetY);
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final double distance = origin.distance(targetVector) - 0.565;
final int groundTicks = this.data.getPositionProcessor().getClientGroundTicks();
double maxDistance = Config.REACH_B_MAX_REACH + 0.05;
maxDistance += yDifference * 0.9;
maxDistance += deltaXZ * 0.66;
if (this.data.getActionProcessor().isSprinting()) {
maxDistance += 0.32;
}
if (groundTicks < 3) {
maxDistance += 0.35;
}
if (this.data.getActionProcessor().isHasSpeed()) {
maxDistance += this.data.getActionProcessor().getSpeedAmplifier() * 0.125;
}
final double yawDiff = PlayerUtil.getYawDiff(this.data.getPlayer(), targetData.getPlayer());
if (yawDiff > 100.0) {
maxDistance += 1.25;
}
final boolean exempt = this.isExempt(ExemptType.TELEPORT, ExemptType.JOINED, ExemptType.PLUGIN_LOAD, ExemptType.WORLD_CHANGE, ExemptType.CREATIVE, ExemptType.VEHICLE);
if (this.isExempt(ExemptType.SERVER_POSITION) || System.currentTimeMillis() - this.data.getConnectionProcessor().getLastFast() < 1500L) {
++maxDistance;
}
final boolean targetExempt = targetData.getExemptProcessor().isExempt(ExemptType.VEHICLE, ExemptType.BOAT);
if (distance > maxDistance && distance < 6.0 && !exempt && !targetExempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail(distance + " > " + maxDistance);
}
}
else {
this.decayBuffer();
}
this.attacking = false;
}
}
}

View File

@ -0,0 +1,53 @@
package me.frep.vulcan.spigot.check.impl.combat.velocity;
import me.frep.vulcan.spigot.data.processor.VelocityProcessor;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Velocity", type = 'A', complexType = "Vertical", description = "Vertical velocity modifications.")
public class VelocityA extends AbstractCheck
{
public VelocityA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying()) {
final boolean push = this.data.getActionProcessor().getSincePushTicks() < 20;
if (push || this.data.getPositionProcessor().isNearBorder()) {
return;
}
final double deltaY = this.data.getPositionProcessor().getDeltaY();
final VelocityProcessor.VelocitySnapshot snapshot = this.data.getVelocityProcessor().getSnapshot();
if (snapshot == null) {
return;
}
final double velocityY = snapshot.getVelocity().getY();
if (velocityY < 0.01) {
return;
}
final int ticksSinceVelocity = this.data.getVelocityProcessor().getTransactionFlyingTicks();
final double ratio = deltaY / velocityY;
final boolean poison = this.data.getActionProcessor().getSincePoisonDamageTicks() < 10;
if (ticksSinceVelocity == 1 && !poison) {
final boolean exempt = this.isExempt(ExemptType.COLLIDING_VERTICALLY, ExemptType.LIQUID, ExemptType.FROZEN, ExemptType.CHUNK, ExemptType.FALL_DAMAGE, ExemptType.ENDER_PEARL, ExemptType.WEB, ExemptType.VOID, ExemptType.SLOW_FALLING, ExemptType.ENDER_PEARL, ExemptType.TRAPDOOR, ExemptType.SOUL_SAND, ExemptType.SLIME, ExemptType.COMBO_MODE, ExemptType.FLIGHT, ExemptType.ATTRIBUTE_MODIFIER, ExemptType.NETHERITE_ARMOR, ExemptType.FULLY_STUCK, ExemptType.PARTIALLY_STUCK, ExemptType.VEHICLE, ExemptType.MYTHIC_MOB, ExemptType.ELYTRA, ExemptType.FIREBALL, ExemptType.SWEET_BERRIES, ExemptType.BUKKIT_VELOCITY, ExemptType.PLACED_WEB);
double minRatio = 0.999;
if (this.isExempt(ExemptType.COLLIDING_HORIZONTALLY)) {
minRatio -= 0.1;
}
if (ratio < minRatio && velocityY > 0.0 && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("tick=1 percent=" + ratio * 100.0 + "% deltaY=" + deltaY + " velocity=" + velocityY);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,55 @@
package me.frep.vulcan.spigot.check.impl.combat.velocity;
import me.frep.vulcan.spigot.data.processor.VelocityProcessor;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Velocity", type = 'B', complexType = "Horizontal", description = "Horizontal velocity modifications.")
public class VelocityB extends AbstractCheck
{
public VelocityB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying()) {
final boolean push = this.data.getActionProcessor().getSincePushTicks() < 20;
if (push || this.data.getPositionProcessor().isNearBorder()) {
return;
}
final boolean collidingHorizontally = this.data.getPositionProcessor().isCollidingHorizontally();
final boolean collidingVertically = this.data.getPositionProcessor().isCollidingVertically();
if (!collidingHorizontally) {
if (!collidingVertically) {
final int velocityTicks = this.data.getVelocityProcessor().getTransactionFlyingTicks();
if (velocityTicks == 1) {
final VelocityProcessor.VelocitySnapshot snapshot = this.data.getVelocityProcessor().getSnapshot();
if (snapshot == null) {
return;
}
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final double velocityXZ = MathUtil.hypot(snapshot.getVelocity().getX(), snapshot.getVelocity().getZ());
if (velocityXZ < 0.01) {
return;
}
final double ratio = deltaXZ / velocityXZ;
final boolean exempt = this.isExempt(ExemptType.COLLIDING_VERTICALLY, ExemptType.LIQUID, ExemptType.FROZEN, ExemptType.CHUNK, ExemptType.FALL_DAMAGE, ExemptType.ENDER_PEARL, ExemptType.WEB, ExemptType.VOID, ExemptType.SLOW_FALLING, ExemptType.PLACED_WEB, ExemptType.ENDER_PEARL, ExemptType.TRAPDOOR, ExemptType.SOUL_SAND, ExemptType.SLIME, ExemptType.COMBO_MODE, ExemptType.FLIGHT, ExemptType.ATTRIBUTE_MODIFIER, ExemptType.NETHERITE_ARMOR, ExemptType.FULLY_STUCK, ExemptType.BUKKIT_VELOCITY, ExemptType.PARTIALLY_STUCK, ExemptType.VEHICLE, ExemptType.MYTHIC_MOB, ExemptType.ELYTRA, ExemptType.SWEET_BERRIES);
if (ratio < 0.21 && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("percent=" + ratio * 100.0 + "% deltaXZ=" + deltaXZ + " velocityXZ=" + velocityXZ);
}
}
else {
this.decayBuffer();
}
}
}
}
}
}
}

View File

@ -0,0 +1,101 @@
package me.frep.vulcan.spigot.check.impl.combat.velocity;
import me.frep.vulcan.spigot.data.processor.VelocityProcessor;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.MathUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Velocity", type = 'C', complexType = "Ignored Vertical", description = "Vertical velocity modifications.")
public class VelocityC extends AbstractCheck
{
private boolean lastSprint;
private double firstTickBuffer;
private double secondTickBuffer;
private double thirdTickBuffer;
private double fourthTickBuffer;
public VelocityC(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying()) {
final boolean push = this.data.getActionProcessor().getSincePushTicks() < 20;
if (push || this.data.getPositionProcessor().isNearBorder()) {
return;
}
final boolean collidingHorizontally = this.data.getPositionProcessor().isCollidingHorizontally();
final boolean collidingVertically = this.data.getPositionProcessor().isCollidingVertically();
if (!collidingHorizontally) {
if (!collidingVertically) {
final VelocityProcessor.VelocitySnapshot snapshot = this.data.getVelocityProcessor().getSnapshot();
if (snapshot == null) {
return;
}
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final double lastDeltaXZ = this.data.getPositionProcessor().getLastDeltaXZ();
final double velocityXZ = MathUtil.hypot(snapshot.getVelocity().getX(), snapshot.getVelocity().getZ());
final int velocityTicks = this.data.getVelocityProcessor().getTransactionFlyingTicks();
if (velocityTicks > 50) {
return;
}
final boolean sprinting = this.data.getActionProcessor().isSprinting();
final double minimum = (sprinting || this.lastSprint) ? 0.275 : 0.7;
final boolean exempt = this.isExempt(ExemptType.COLLIDING_VERTICALLY, ExemptType.LIQUID, ExemptType.FROZEN, ExemptType.CHUNK, ExemptType.LEVITATION, ExemptType.FALL_DAMAGE, ExemptType.ENDER_PEARL, ExemptType.WEB, ExemptType.VOID, ExemptType.SLOW_FALLING, ExemptType.BUKKIT_VELOCITY, ExemptType.ENDER_PEARL, ExemptType.TRAPDOOR, ExemptType.SOUL_SAND, ExemptType.SLIME, ExemptType.COMBO_MODE, ExemptType.PLACED_WEB, ExemptType.FLIGHT, ExemptType.ATTRIBUTE_MODIFIER, ExemptType.NETHERITE_ARMOR, ExemptType.FULLY_STUCK, ExemptType.FISHING_ROD, ExemptType.PARTIALLY_STUCK, ExemptType.VEHICLE, ExemptType.MYTHIC_MOB, ExemptType.ELYTRA, ExemptType.SWEET_BERRIES);
if (velocityXZ < 0.01 || exempt) {
return;
}
switch(velocityTicks) {
case 1:
double ratio = deltaXZ / velocityXZ;
if (ratio < minimum) {
if (++this.firstTickBuffer > this.MAX_BUFFER) {
this.fail("tick=1 percent=" + ratio * 100.0D + "% s=" + sprinting + " ls=" + this.lastSprint + " deltaXZ=" + deltaXZ + " velocityXZ=" + velocityXZ);
}
} else if (this.firstTickBuffer > 0.0D) {
this.firstTickBuffer -= this.BUFFER_DECAY;
}
break;
case 2:
double ratio2 = deltaXZ / (lastDeltaXZ * (double)0.91F * (double)0.6F);
double minimum2 = !sprinting && !this.lastSprint ? 0.32D : 0.1D;
if (ratio2 < minimum2) {
if (++this.secondTickBuffer > this.MAX_BUFFER) {
this.fail("tick=2 percent=" + ratio2 * 100.0D + "% s=" + sprinting + " ls=" + this.lastSprint + " deltaXZ=" + deltaXZ + " velocityXZ=" + velocityXZ);
}
} else if (this.secondTickBuffer > 0.0D) {
this.secondTickBuffer -= this.BUFFER_DECAY;
}
break;
case 3:
double ratio3 = deltaXZ / (lastDeltaXZ * (double)0.91F);
double minimum3 = !sprinting && !this.lastSprint ? 0.25D : 0.1D;
if (ratio3 < minimum3) {
if (++this.thirdTickBuffer > this.MAX_BUFFER) {
this.fail("tick=3 percent=" + ratio3 * 100.0D + "% s=" + sprinting + " ls=" + this.lastSprint + " deltaXZ=" + deltaXZ + " velocityXZ=" + velocityXZ);
}
} else if (this.thirdTickBuffer > 0.0D) {
this.thirdTickBuffer -= this.BUFFER_DECAY;
}
break;
case 4:
double ratio4 = deltaXZ / (lastDeltaXZ * (double)0.91F);
double minimum4 = !sprinting && !this.lastSprint ? 0.25D : 0.1D;
if (ratio4 < minimum4) {
if (++this.fourthTickBuffer > this.MAX_BUFFER) {
this.fail("tick=4 percent=" + ratio4 * 100.0D + "% s=" + sprinting + " ls=" + this.lastSprint + " deltaXZ=" + deltaXZ + " velocityXZ=" + velocityXZ);
}
} else if (this.fourthTickBuffer > 0.0D) {
this.fourthTickBuffer -= this.BUFFER_DECAY;
}
}
this.lastSprint = sprinting;
}
}
}
}
}

View File

@ -0,0 +1,249 @@
package me.frep.vulcan.spigot.check.impl.combat.velocity;
import org.bukkit.Location;
import me.frep.vulcan.spigot.util.type.Pair;
import me.frep.vulcan.spigot.data.processor.VelocityProcessor;
import io.github.retrooper.packetevents.packetwrappers.play.in.flying.WrappedPacketInFlying;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import me.frep.vulcan.spigot.util.nms.MathHelper;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Velocity", type = 'D', complexType = "Horizontal", description = "Horizontal velocity modifications.", experimental = true)
public class VelocityD extends AbstractCheck
{
private final float LAND_MOVEMENT_FACTOR;
private final double MINIMUM_MOVEMENT;
private static final float SPEED_IN_AIR = 0.02f;
private static final float FRICTION = 0.6f;
private boolean hadPosition;
private boolean hadHadPosition;
private int attacks;
public VelocityD(final PlayerData data) {
super(data);
this.LAND_MOVEMENT_FACTOR = (this.data.is1_13() ? 0.21600002f : 0.16277136f);
this.MINIMUM_MOVEMENT = (this.data.is1_9() ? 0.003 : 0.005);
this.hadPosition = false;
this.hadHadPosition = false;
this.attacks = 0;
}
@Override
public void handle(final Packet packet) {
if (packet.isFlying() && !this.teleporting()) {
final boolean push = this.data.getActionProcessor().getSincePushTicks() < 20;
if (push || this.data.getPositionProcessor().isNearBorder()) {
return;
}
final WrappedPacketInFlying wrapper = this.data.getFlyingWrapper();
final VelocityProcessor velocityProcessor = this.data.getVelocityProcessor();
final int sinceVelocityTicks = velocityProcessor.getTransactionFlyingTicks();
final boolean velocity = sinceVelocityTicks == 1;
final boolean exempt = this.isExempt(ExemptType.SLOW_FALLING, ExemptType.LEVITATION, ExemptType.COLLIDING_VERTICALLY, ExemptType.COLLIDING_HORIZONTALLY, ExemptType.ELYTRA, ExemptType.GLIDING, ExemptType.RIPTIDE, ExemptType.ENTITY_COLLISION, ExemptType.SWEET_BERRIES, ExemptType.LIQUID, ExemptType.CLIMBABLE, ExemptType.ICE, ExemptType.SOUL_SAND, ExemptType.HONEY, ExemptType.ATTRIBUTE_MODIFIER, ExemptType.CAKE, ExemptType.NETHERITE_ARMOR, ExemptType.FROZEN, ExemptType.CHUNK, ExemptType.TRAPDOOR, ExemptType.DOOR, ExemptType.ILLEGAL_BLOCK, ExemptType.VEHICLE, ExemptType.DOLPHINS_GRACE, ExemptType.MYTHIC_MOB, ExemptType.PLACED_WEB, ExemptType.FULLY_STUCK, ExemptType.PARTIALLY_STUCK, ExemptType.VOID, ExemptType.CAULDRON, ExemptType.BUKKIT_VELOCITY, ExemptType.WEB, ExemptType.WATERLOGGED, ExemptType.ENDER_PEARL, ExemptType.FISHING_ROD, ExemptType.RESPAWN, ExemptType.DRAGON_DAMAGE, ExemptType.TELEPORT, ExemptType.DEATH, ExemptType.WORLD_CHANGE, ExemptType.FLIGHT);
if (sinceVelocityTicks <= 6 && !exempt) {
if (this.data.getPositionProcessor().getSinceCollidingVerticallyTicks() >= 3) {
final VelocityProcessor.VelocitySnapshot snapshot = this.data.getVelocityProcessor().getSnapshot();
if (snapshot == null) {
return;
}
if (snapshot.getVelocity().getX() >= 0.01 || snapshot.getVelocity().getY() >= 0.01 || snapshot.getVelocity().getZ() >= 0.01) {
float slipperiness = 0.91f;
float lastSlipperiness = 0.91f;
final boolean lastLastOnGround = this.data.getPositionProcessor().isLastLastClientOnGround();
final boolean lastOnGround = this.data.getPositionProcessor().isLastClientOnGround();
if (lastOnGround) {
slipperiness = 0.54600006f;
}
if (lastLastOnGround) {
lastSlipperiness = 0.54600006f;
}
double smallest = Double.MAX_VALUE;
for (int i = 0; i < 9; ++i) {
for (int sprintIter = 0; sprintIter < 2; ++sprintIter) {
for (int useItemIter = 0; useItemIter < 2; ++useItemIter) {
for (int slowdownIter = 0; slowdownIter < 2; ++slowdownIter) {
for (int jumpIter = 0; jumpIter < 2; ++jumpIter) {
final boolean sprinting = sprintIter == 0;
final boolean blocking = useItemIter == 0;
final boolean hitSlowdown = slowdownIter == 0;
final boolean jump = jumpIter == 0;
final Pair<Float, Float> keyPresses = this.getKeyIndex(i);
float forward = keyPresses.getX();
float strafe = keyPresses.getY();
if (blocking) {
forward *= (float)0.2;
strafe *= (float)0.2;
}
if (this.data.getActionProcessor().isSneaking()) {
forward *= 0.3f;
strafe *= 0.3f;
}
forward *= 0.98f;
strafe *= 0.98f;
double motionX = velocity ? velocityProcessor.getVelocityX() : this.data.getPositionProcessor().getLastDeltaX();
double motionY = velocity ? velocityProcessor.getVelocityY() : this.data.getPositionProcessor().getLastDeltaY();
double motionZ = velocity ? velocityProcessor.getVelocityZ() : this.data.getPositionProcessor().getLastDeltaZ();
double moveSpeed = this.getAttributeSpeed(this.data);
if (sprinting) {
moveSpeed += moveSpeed * 0.30000001192092896;
}
final float moveSpeedMultiplier = this.LAND_MOVEMENT_FACTOR / (slipperiness * slipperiness * slipperiness);
float moveFlyingFriction;
if (lastOnGround) {
moveFlyingFriction = (float)moveSpeed * moveSpeedMultiplier;
}
else {
moveFlyingFriction = (float)(sprinting ? 0.025999999418854714 : 0.019999999552965164);
}
if (!this.data.is1_9() && this.attacks > 0 && hitSlowdown) {
motionX *= 0.6;
motionZ *= 0.6;
}
if (!velocity) {
motionY -= 0.08;
motionX *= lastSlipperiness;
motionY *= 0.9800000190734863;
motionZ *= lastSlipperiness;
}
if (Math.abs(motionX) < this.MINIMUM_MOVEMENT) {
motionX = 0.0;
}
if (Math.abs(motionY) < this.MINIMUM_MOVEMENT) {
motionY = 0.0;
}
if (Math.abs(motionZ) < this.MINIMUM_MOVEMENT) {
motionZ = 0.0;
}
if (jump && lastOnGround) {
motionY = 0.41999998688697815;
if (this.data.getActionProcessor().isHasJumpBoost()) {
motionY += this.data.getActionProcessor().getJumpBoostAmplifier() * 0.1f;
}
if (sprinting) {
final float f = this.data.getRotationProcessor().getYaw() * 0.017453292f;
motionX -= MathHelper.sin(f) * 0.2f;
motionZ += MathHelper.cos(f) * 0.2f;
}
}
float diagonal = strafe * strafe + forward * forward;
double moveFlyingFactorX = 0.0;
double moveFlyingFactorZ = 0.0;
if (diagonal > 1.0E-4f) {
diagonal = MathHelper.sqrt_float(diagonal);
if (diagonal < 1.0f) {
diagonal = 1.0f;
}
diagonal = moveFlyingFriction / diagonal;
final float flyingStrafe = strafe * diagonal;
final float flyingForward = forward * diagonal;
final float rotationYaw = this.data.getRotationProcessor().getYaw();
final float f2 = MathHelper.sin(rotationYaw * 3.1415927f / 180.0f);
final float f3 = MathHelper.cos(rotationYaw * 3.1415927f / 180.0f);
final double factorX = flyingStrafe * f3 - flyingForward * f2;
final double factorZ = flyingForward * f3 + flyingStrafe * f2;
moveFlyingFactorX = factorX;
moveFlyingFactorZ = factorZ;
}
motionX += moveFlyingFactorX;
motionZ += moveFlyingFactorZ;
final Location predicted = this.data.getPositionProcessor().getFrom().clone().add(motionX, 0.0, motionZ);
predicted.setY(0.0);
final Location to = this.data.getPositionProcessor().getTo().clone();
to.setY(0.0);
final double distance = to.distanceSquared(predicted);
if (distance < smallest) {
smallest = distance;
}
}
}
}
}
}
if (smallest <= 10.0) {
double threshold = 5.0E-6 + ((this.hadPosition && this.hadHadPosition) ? 0.0 : 0.001);
if (this.data.is1_9()) {
threshold += 0.001;
}
if (smallest > threshold) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("offset=" + smallest + " threshold=" + threshold + " tick=" + sinceVelocityTicks);
}
}
else {
this.decayBuffer();
}
}
}
}
}
this.hadHadPosition = this.hadPosition;
this.hadPosition = wrapper.isMoving();
this.attacks = 0;
}
else if (packet.isUseEntity()) {
final WrappedPacketInUseEntity wrapper2 = this.data.getUseEntityWrapper();
if (wrapper2.getAction() == WrappedPacketInUseEntity.EntityUseAction.ATTACK) {
++this.attacks;
}
}
}
private Pair<Float, Float> getKeyIndex(final int index) {
float strafeForward = 0.0f;
float strafeSideways = 0.0f;
switch (index) {
case 0: {
strafeForward = 1.0f;
break;
}
case 1: {
strafeForward = 1.0f;
strafeSideways = -1.0f;
break;
}
case 2: {
strafeSideways = -1.0f;
break;
}
case 3: {
strafeForward = -1.0f;
strafeSideways = -1.0f;
break;
}
case 4: {
strafeForward = -1.0f;
break;
}
case 5: {
strafeForward = -1.0f;
strafeSideways = 1.0f;
break;
}
case 6: {
strafeSideways = 1.0f;
break;
}
case 7: {
strafeForward = 1.0f;
strafeSideways = 1.0f;
break;
}
case 8: {
strafeForward = 0.0f;
strafeSideways = 0.0f;
break;
}
}
return new Pair<Float, Float>(strafeForward, strafeSideways);
}
public float getAttributeSpeed(final PlayerData data) {
double attributeSpeed = data.getActionProcessor().getGenericMovementSpeed();
attributeSpeed += data.getActionProcessor().getSpeedAmplifier() * 0.2 * attributeSpeed;
return (float)attributeSpeed;
}
}

View File

@ -0,0 +1,40 @@
package me.frep.vulcan.spigot.check.impl.movement.antilevitation;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Anti Levitation", type = 'A', complexType = "Ignore", description = "Ignored Levitation effect.")
public class AntiLevitationA extends AbstractCheck
{
public AntiLevitationA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isPosition() && !this.teleporting()) {
if (ServerUtil.isLowerThan1_9() || this.data.getActionProcessor().getLevitationAmplifier() < 0) {
return;
}
final double deltaY = this.data.getPositionProcessor().getDeltaY();
final boolean mathOnGround = this.data.getPositionProcessor().isMathematicallyOnGround();
final boolean onGround = this.data.getPositionProcessor().isClientOnGround();
final boolean levitation = this.data.getActionProcessor().isHasLevitation();
final boolean touchingAir = this.data.getPositionProcessor().isTouchingAir();
final boolean invalid = levitation && (onGround || deltaY < 0.0 || (!touchingAir && mathOnGround));
final boolean exempt = this.isExempt(ExemptType.SCAFFOLDING, ExemptType.VOID, ExemptType.COLLIDING_VERTICALLY, ExemptType.TRAPDOOR, ExemptType.BED, ExemptType.SLIME, ExemptType.HONEY, ExemptType.VELOCITY, ExemptType.RIPTIDE, ExemptType.BUKKIT_VELOCITY, ExemptType.JOINED, ExemptType.SWIMMING, ExemptType.CHUNK, ExemptType.JOINED_CHUNK_LOAD, ExemptType.WEB, ExemptType.SLEEPING, ExemptType.DEATH, ExemptType.FROZEN, ExemptType.BLOCK_PLACE, ExemptType.BLOCK_BREAK, ExemptType.ATTRIBUTE_MODIFIER, ExemptType.FULLY_STUCK, ExemptType.PARTIALLY_STUCK, ExemptType.WORLD_CHANGE, ExemptType.VEHICLE, ExemptType.BOAT, ExemptType.GLIDING, ExemptType.SLOW_FALLING, ExemptType.BUBBLE_COLUMN, ExemptType.SPECTATOR, ExemptType.DOLPHINS_GRACE, ExemptType.SHULKER_BOX) || this.data.getPositionProcessor().isExemptTeleport() || this.data.getPositionProcessor().isExemptClimbable() || this.data.getPositionProcessor().isExemptFlight() || this.data.getPositionProcessor().isExemptCreative() || this.data.getPositionProcessor().isExemptLiquid() || this.data.getPositionProcessor().isExemptElytra();
if (invalid && !exempt) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaY=" + deltaY + " onGround=" + onGround + " amplifier=" + this.data.getActionProcessor().getLevitationAmplifier());
}
}
else {
this.decayBuffer();
}
}
}
}

View File

@ -0,0 +1,58 @@
package me.frep.vulcan.spigot.check.impl.movement.boatfly;
import org.bukkit.plugin.Plugin;
import org.bukkit.Bukkit;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Boat;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Boat Fly", type = 'A', complexType = "Vertical", description = "Moving upwards in a boat.")
public class BoatFlyA extends AbstractCheck
{
public BoatFlyA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isVehicleMove()) {
if (ServerUtil.isLowerThan1_9()) {
return;
}
final boolean boat = this.data.getPlayer().getVehicle() != null && this.data.getPlayer().getVehicle() instanceof Boat;
final int vehicleTicks = this.data.getPositionProcessor().getVehicleTicks();
if (boat && vehicleTicks > 10) {
final Boat boatEntity = (Boat)this.data.getPlayer().getVehicle();
final double deltaY = this.data.getPositionProcessor().getVehicleDeltaY();
final boolean liquid = this.data.getPositionProcessor().getSinceVehicleNearLiquidTicks() < 100;
final boolean slime = this.data.getPositionProcessor().getSinceVehicleNearSlimeTicks() < 100;
final boolean bubbleColumn = this.data.getPositionProcessor().getSinceVehicleNearBubbleColumnTicks() < 100;
final boolean piston = this.data.getPositionProcessor().getSinceVehicleNearPistonTicks() < 50;
final boolean bed = this.data.getPositionProcessor().getSinceVehicleNearBedTicks() < 40;
final boolean touchingAir = this.data.getPositionProcessor().isVehicleInAir();
if (ServerUtil.isHigherThan1_13() && !boatEntity.hasGravity()) {
return;
}
if (Vulcan.INSTANCE.getFishingRodPulledBoats().containsKey(boatEntity.getEntityId())) {
return;
}
if (deltaY > 0.01 && !slime && !liquid && !bubbleColumn && !piston && !bed && touchingAir) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaY=" + deltaY);
if (Config.BOAT_FLY_A_KICKOUT) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> this.data.getPlayer().leaveVehicle());
}
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,65 @@
package me.frep.vulcan.spigot.check.impl.movement.boatfly;
import org.bukkit.plugin.Plugin;
import org.bukkit.Bukkit;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Boat;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Boat Fly", type = 'B', complexType = "Vertical", description = "Moving too quickly horizontally.")
public class BoatFlyB extends AbstractCheck
{
public BoatFlyB(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isVehicleMove()) {
if (ServerUtil.isLowerThan1_9()) {
return;
}
final boolean boat = this.data.getPlayer().getVehicle() instanceof Boat;
final int vehicleTicks = this.data.getPositionProcessor().getVehicleTicks();
final String spigotID = Vulcan.INSTANCE.getSpigot();
if (vehicleTicks > 10 && boat) {
final Boat boatEntity = (Boat)this.data.getPlayer().getVehicle();
final double deltaXZ = this.data.getPositionProcessor().getVehicleDeltaXZ();
final double deltaY = this.data.getPositionProcessor().getVehicleDeltaY();
final boolean ice = this.data.getPositionProcessor().getSinceVehicleNearIceTicks() < 100;
final boolean liquid = this.data.getPositionProcessor().getSinceVehicleNearLiquidTicks() < 100;
final boolean slime = this.data.getPositionProcessor().getSinceVehicleNearSlimeTicks() < 100;
final boolean bubbleColumn = this.data.getPositionProcessor().getSinceVehicleNearBubbleColumnTicks() < 100;
final int boatsAround = this.data.getPositionProcessor().getBoatsAround();
if (ServerUtil.isHigherThan1_13() && !boatEntity.hasGravity()) {
return;
}
if (Vulcan.INSTANCE.getFishingRodPulledBoats().containsKey(boatEntity.getEntityId())) {
return;
}
double max = 0.25;
if (this.isExempt(ExemptType.WATERLOGGED)) {
max += 0.1;
}
final boolean invalid = deltaXZ > max && deltaY > -0.05 && !liquid && !slime && !bubbleColumn && !ice;
if (invalid && boatsAround == 1) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaXZ=" + deltaXZ + " deltaY=" + deltaY);
if (Config.BOAT_FLY_B_KICKOUT) {
Bukkit.getScheduler().runTask(Vulcan.INSTANCE.getPlugin(), () -> this.data.getPlayer().leaveVehicle());
}
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,59 @@
package me.frep.vulcan.spigot.check.impl.movement.boatfly;
import me.frep.vulcan.spigot.Vulcan;
import org.bukkit.entity.Boat;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Boat Fly", type = 'C', complexType = "Hover", description = "Hovering in a boat.")
public class BoatFlyC extends AbstractCheck
{
public BoatFlyC(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isVehicleMove()) {
if (ServerUtil.isLowerThan1_9()) {
return;
}
final boolean boat = this.data.getPlayer().getVehicle() instanceof Boat;
final int vehicleTicks = this.data.getPositionProcessor().getVehicleTicks();
if (vehicleTicks > 10 && boat) {
final Boat boatEntity = (Boat)this.data.getPlayer().getVehicle();
if (Vulcan.INSTANCE.getFishingRodPulledBoats().containsKey(boatEntity.getEntityId())) {
return;
}
final double deltaY = this.data.getPositionProcessor().getVehicleDeltaY();
final double lastDeltaY = this.data.getPositionProcessor().getLastVehicleDeltaY();
final double acceleration = Math.abs(deltaY - lastDeltaY);
final int airTicks = this.data.getPositionProcessor().getVehicleAirTicks();
final boolean invalid = deltaY > -0.05 && acceleration < 0.025 && airTicks > 5;
if (this.data.getPositionProcessor().isVehicleNearEntity()) {
return;
}
if (ServerUtil.isHigherThan1_13() && !boatEntity.hasGravity()) {
return;
}
final boolean ice = this.data.getPositionProcessor().getSinceVehicleNearIceTicks() < 50;
final boolean liquid = this.data.getPositionProcessor().getSinceVehicleNearLiquidTicks() < 50;
final boolean slime = this.data.getPositionProcessor().getSinceVehicleNearSlimeTicks() < 50;
final boolean bubbleColumn = this.data.getPositionProcessor().getSinceVehicleNearBubbleColumnTicks() < 50;
final boolean piston = this.data.getPositionProcessor().getSinceVehicleNearPistonTicks() < 50;
final int boatsAround = this.data.getPositionProcessor().getBoatsAround();
if (invalid && !ice && !liquid && !slime && !bubbleColumn && !piston && boatsAround == 1) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("accel=" + acceleration + " deltaY=" + deltaY);
}
}
else {
this.decayBuffer();
}
}
}
}
}

View File

@ -0,0 +1,37 @@
package me.frep.vulcan.spigot.check.impl.movement.elytra;
import me.frep.vulcan.spigot.config.Config;
import me.frep.vulcan.spigot.exempt.type.ExemptType;
import me.frep.vulcan.spigot.util.ServerUtil;
import me.frep.vulcan.spigot.packet.Packet;
import me.frep.vulcan.spigot.data.PlayerData;
import me.frep.vulcan.spigot.check.api.CheckInfo;
import me.frep.vulcan.spigot.check.AbstractCheck;
@CheckInfo(name = "Elytra", type = 'A', complexType = "Limit", description = "Gliding too quickly on X/Z axis.")
public class ElytraA extends AbstractCheck
{
public ElytraA(final PlayerData data) {
super(data);
}
@Override
public void handle(final Packet packet) {
if (packet.isPosition() && !this.teleporting()) {
if (ServerUtil.isLowerThan1_9() || !this.data.getActionProcessor().isBukkitGliding()) {
return;
}
final double deltaXZ = this.data.getPositionProcessor().getDeltaXZ();
final boolean exempt = this.isExempt(ExemptType.RIPTIDE, ExemptType.TELEPORT, ExemptType.WORLD_CHANGE, ExemptType.DEATH, ExemptType.ENDER_PEARL, ExemptType.CHORUS_FRUIT, ExemptType.SERVER_POSITION_FAST, ExemptType.DRAGON_DAMAGE, ExemptType.BUKKIT_VELOCITY, ExemptType.DOLPHINS_GRACE) || this.data.getVelocityProcessor().getSinceHighVelocityTicks() < 50 || this.data.getPositionProcessor().getSinceFuckingEntityTicks() < 200;
final boolean riptide = this.data.getPositionProcessor().getSinceRiptideTicks() < 400;
if (deltaXZ > Config.ELYTRA_A_MAX_SPEED && !exempt && !riptide) {
if (this.increaseBuffer() > this.MAX_BUFFER) {
this.fail("deltaXZ=" + deltaXZ);
}
}
else {
this.decayBuffer();
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More